Files
GDevelop/GDevelop.js/__tests__/GDJSBehaviorCodeGenerationIntegrationTests.js
T
2023-03-16 18:12:32 +01:00

166 lines
4.8 KiB
JavaScript

const initializeGDevelopJs = require('../../Binaries/embuild/GDevelop.js/libGD.js');
const { makeMinimalGDJSMock } = require('../TestUtils/GDJSMocks');
describe('libGD.js - GDJS Behavior Code Generation integration tests', function () {
let gd = null;
beforeAll((done) =>
initializeGDevelopJs().then((module) => {
gd = module;
done();
})
);
it('generates a working empty behavior', function () {
// Create an empty behavior
const project = new gd.ProjectHelper.createNewGDJSProject();
const eventsBasedBehavior = new gd.EventsBasedBehavior();
eventsBasedBehavior.setName('MyBehavior');
eventsBasedBehavior.setFullName('My descriptive name');
eventsBasedBehavior.setDescription('My description');
const makeCompiledRuntimeBehavior = generateCompiledRuntimeBehaviorMaker(
gd,
project,
eventsBasedBehavior
);
eventsBasedBehavior.delete();
project.delete();
// Instantiate the behavior
const { gdjs, runtimeScene } = makeMinimalGDJSMock();
const CompiledRuntimeBehavior = makeCompiledRuntimeBehavior(gdjs);
const behaviorData = {};
const ownerRuntimeObject = {};
const behavior = new CompiledRuntimeBehavior(
runtimeScene,
behaviorData,
ownerRuntimeObject
);
// Check that doStepPreEvents is always defined
expect(behavior.doStepPreEvents).not.toBeUndefined();
});
it('generates a working behavior with doStepPreEvents using "Trigger Once" condition', function () {
// Create a new behavior with events in doStepPreEvents
const project = new gd.ProjectHelper.createNewGDJSProject();
const eventsBasedBehavior = new gd.EventsBasedBehavior();
eventsBasedBehavior.setName('MyBehavior');
eventsBasedBehavior.setFullName('My descriptive name');
eventsBasedBehavior.setDescription('My description');
const eventsSerializerElement = gd.Serializer.fromJSObject([
{
type: 'BuiltinCommonInstructions::Standard',
conditions: [
{
type: {
value: 'BuiltinCommonInstructions::Once',
},
parameters: [],
},
],
actions: [
{
type: { value: 'ModVarScene' },
parameters: ['SuccessVariable', '+', '1'],
},
],
},
]);
eventsBasedBehavior
.getEventsFunctions()
.insertNewEventsFunction('doStepPreEvents', 0)
.getEvents()
.unserializeFrom(project, eventsSerializerElement);
// Instantiate the behavior twice
const makeCompiledRuntimeBehavior = generateCompiledRuntimeBehaviorMaker(
gd,
project,
eventsBasedBehavior
);
eventsBasedBehavior.delete();
project.delete();
const { gdjs, runtimeScene } = makeMinimalGDJSMock();
const CompiledRuntimeBehavior = makeCompiledRuntimeBehavior(gdjs);
const behaviorData = {};
const ownerRuntimeObject = {};
const behavior = new CompiledRuntimeBehavior(
runtimeScene,
behaviorData,
ownerRuntimeObject
);
const behavior2 = new CompiledRuntimeBehavior(
runtimeScene,
behaviorData,
ownerRuntimeObject
);
// Check that Trigger once is working, separately handled by each behavior instance:
expect(behavior.doStepPreEvents).not.toBeUndefined();
behavior.doStepPreEvents();
behavior2.doStepPreEvents();
expect(runtimeScene.getVariables().has('SuccessVariable')).toBe(true);
expect(
runtimeScene.getVariables().get('SuccessVariable').getAsNumber()
).toBe(2);
behavior.doStepPreEvents();
behavior2.doStepPreEvents();
expect(
runtimeScene.getVariables().get('SuccessVariable').getAsNumber()
).toBe(2);
});
});
function generateCompiledRuntimeBehaviorMaker(
gd,
project,
eventsBasedBehavior
) {
const includeFiles = new gd.SetString();
const codeNamespace = 'behaviorNamespace';
const behaviorCodeGenerator = new gd.BehaviorCodeGenerator(project);
// Generate "mangled names" as required by the code generation
const behaviorMethodMangledNames = new gd.MapStringString();
for (
let i = 0;
i < eventsBasedBehavior.getEventsFunctions().getEventsFunctionsCount();
i++
) {
const eventsFunction = eventsBasedBehavior
.getEventsFunctions()
.getEventsFunctionAt(i);
behaviorMethodMangledNames.set(
eventsFunction.getName(),
eventsFunction.getName()
);
}
const code = behaviorCodeGenerator.generateRuntimeBehaviorCompleteCode(
'MyExtension',
eventsBasedBehavior,
codeNamespace,
behaviorMethodMangledNames,
includeFiles,
true
);
// Create a function returning the generated behavior.
const makeCompiledBehavior = new Function(
'gdjs',
`let behaviorNamespace = {};
let Hashtable = gdjs.Hashtable;
${code}
return behaviorNamespace.MyBehavior;`
);
includeFiles.delete();
return makeCompiledBehavior;
}