Fix Storybook and add story for NewInstructionEditorMenu

This commit is contained in:
Florian Rival
2020-02-09 22:16:09 +00:00
parent aa30052dca
commit 2cc7c8740e
7 changed files with 450 additions and 278 deletions

View File

@@ -1,18 +1,25 @@
<!-- Log the time of start -->
<script>
window['GD_STARTUP_TIMES'] = [
['previewHeadHtmlFirstScriptStarted', performance.now()],
];
</script>
<!-- GDevelop.js core -->
<script src="/libGD.js"></script>
<!-- Monaco Editor support -->
<script src="/external/monaco-editor-min/vs/loader.js"></script>
<script>
amdRequire = require;
amdRequire.config({
paths: {
"vs": "vs"
}
});
window.MonacoEnvironment = {
getWorkerUrl: function (workerId, label) {
return "external/monaco-editor-min/vs/base/worker/workerMain.js";
}
};
</script>
amdRequire = require;
amdRequire.config({
paths: {
vs: 'vs',
},
});
window.MonacoEnvironment = {
getWorkerUrl: function(workerId, label) {
return 'external/monaco-editor-min/vs/base/worker/workerMain.js';
},
};
</script>

View File

@@ -31,10 +31,6 @@ const optionalRequire = (
} catch (ex) {
if (config.rethrowException) throw ex;
console.error(
'Exception while requiring module (from optionalRequire):',
ex
);
return null;
}
};

View File

@@ -1,10 +1,43 @@
// @flow
/*::
type TestProject = {|
project: gdProject,
shapePainterObject: any,
textObject: any,
tiledSpriteObject: any,
panelSpriteObject: any,
spriteObject: gdSpriteObject,
spriteObjectWithBehaviors: gdSpriteObject,
testLayout: gdLayout,
group1: gdObjectGroup,
group2: gdObjectGroup,
testLayoutInstance1: gdInitialInstance,
testInstruction: gdInstruction,
testExternalEvents1: gdExternalEvents,
testExternalEvents2: gdExternalEvents,
emptyLayout: gdLayout,
testEventsFunction: gdEventsFunction,
testEventsFunctionsExtension: gdEventsFunctionsExtension,
testSerializedEvents: Object,
testSerializedEventsWithLotsOfObjects: Object,
testEventsBasedBehavior: gdEventsBasedBehavior,
testEmptyEventsBasedBehavior: gdEventsBasedBehavior,
testBehaviorEventsFunction: gdEventsFunction,
testBehaviorLifecycleEventsFunction: gdEventsFunction,
layerWithEffects: gdLayer,
layerWithEffectWithoutEffectType: gdLayer,
layerWithoutEffects: gdLayer,
|};
*/
/**
* Create a dummy project using libGD.js filled with a
* few elements that can be used for testing.
*
* @param gd The GD instance to use to create the project.
*/
export const makeTestProject = gd => {
export const makeTestProject = (gd /*: libGDevelop */) /*: TestProject */ => {
// Create and expose a game project
const project = gd.ProjectHelper.createNewGDJSProject();

View File

@@ -15,6 +15,8 @@ const initializeGDevelopJs = require('libGD.js-for-tests-only');
// We create the global "gd" object **synchronously** here. This is done as
// the source files are using `global.gd` as a "top level" object (after imports).
// This is a side effect, so this file must be imported before any test.
// See also GDevelopJsInitializerDecorator.js for Storybook.
global.gd = {
I_AM_NOT_YET_INITIALIZED_YOU_MUST_USE_GD_INSIDE_A_TEST_ONLY: true,
};

View File

@@ -0,0 +1,84 @@
// @flow
import * as React from 'react';
import { type StoryDecorator } from '@storybook/react';
import { makeTestExtensions } from '../fixtures/TestExtensions';
import { makeTestProject } from '../fixtures/TestProject';
import { getStartupTimesSummary } from '../Utils/StartupTimes';
const initializeGDevelopJs = global.initializeGDevelopJs;
const GD_STARTUP_TIMES = global.GD_STARTUP_TIMES || [];
// We create the global "gd" object **synchronously** here. This is done as
// the source files are using `global.gd` as a "top level" object (after imports).
// This is a side effect, so this file must be imported before any component.
// See also setupTests.js for Jest tests.
global.gd = {
I_AM_NOT_YET_INITIALIZED_YOU_MUST_USE_GD_INSIDE_A_STORY_ONLY: true,
};
// Will contain the result of makeTestProject
export let testProject: any = {
I_AM_NOT_YET_INITIALIZED_YOU_MUST_USE_TESTPROJECT_INSIDE_A_STORY_ONLY: true,
};
type GDevelopJsInitializerProps = {|
children: () => React.Node,
|};
const GDevelopJsInitializer = ({ children }: GDevelopJsInitializerProps) => {
const [isReady, setIsReady] = React.useState(
!global.gd.I_AM_NOT_YET_INITIALIZED_YOU_MUST_USE_GD_INSIDE_A_STORY_ONLY
);
React.useEffect(() => {
// Do not re-initialize the global "gd" object if already done.
if (!global.gd.I_AM_NOT_YET_INITIALIZED_YOU_MUST_USE_GD_INSIDE_A_STORY_ONLY)
return;
console.info(
'Loading GDevelop.js and creating test extensions/test project...'
);
GD_STARTUP_TIMES.push(['initializeGDevelopJsCall', performance.now()]);
initializeGDevelopJs().then(gd => {
GD_STARTUP_TIMES.push(['initializeGDevelopJsDone', performance.now()]);
// We're **updating** the global "gd" object here. This is done so that
// the source files that are using `global.gd` have the proper reference to the
// object.
delete global.gd
.I_AM_NOT_YET_INITIALIZED_YOU_MUST_USE_GD_INSIDE_A_STORY_ONLY;
for (let key in gd) {
global.gd[key] = gd[key];
}
// Prepare test extensions
makeTestExtensions(gd);
// Prepare a test project object, that we are also **updating** as stories
// already got a reference to it.
const newTestProject = makeTestProject(gd);
for (let key in newTestProject) {
testProject[key] = newTestProject[key];
}
delete testProject.I_AM_NOT_YET_INITIALIZED_YOU_MUST_USE_TESTPROJECT_INSIDE_A_STORY_ONLY;
console.info(
'Done loading GDevelop.js and created test extensions/test project.'
);
GD_STARTUP_TIMES.push([
'initializeTestExtensionsAndProject',
performance.now(),
]);
console.info('Startup times summary:', getStartupTimesSummary());
setIsReady(true);
});
}, []);
if (isReady) return children();
return <div>Loading GDevelop.js, test extensions and test project...</div>;
};
const libGDDecorator: StoryDecorator = (story, context) => (
<GDevelopJsInitializer>{() => story(context)}</GDevelopJsInitializer>
);
export default libGDDecorator;

View File

@@ -0,0 +1,31 @@
// @flow
import * as React from 'react';
type ChildrenProps = {| buttonElement: ?HTMLElement, onClose: () => void |};
type Props = {|
children: (childrenProps: ChildrenProps) => React.Node,
|};
export function PopoverButton({ children }: Props) {
const [buttonElement, setButtonElement] = React.useState(
(null: ?HTMLElement)
);
return (
<React.Fragment>
<button
onClick={event => {
setButtonElement(event.target);
}}
>
Click to open
</button>
{buttonElement &&
children({
buttonElement,
onClose: () => setButtonElement(null),
})}
</React.Fragment>
);
}

File diff suppressed because it is too large Load Diff