119 lines
4.5 KiB
JavaScript
119 lines
4.5 KiB
JavaScript
const {test} = require('node:test');
|
|
const fs = require('node:fs');
|
|
const path = require('node:path');
|
|
const assert = require('node:assert');
|
|
const VirtualMachine = require('../../src/virtual-machine');
|
|
const Sampler = require('../../src/engine/tw-sampler');
|
|
const FakeRenderer = require('../fixtures/fake-renderer');
|
|
|
|
const fixture = fs.readFileSync(path.join(__dirname, '../fixtures/tw-sampler.sb3'));
|
|
|
|
// The runtime skips drawing when the document is hidden
|
|
global.document = {
|
|
hidden: false
|
|
};
|
|
|
|
const setup = async () => {
|
|
const vm = new VirtualMachine();
|
|
const renderer = new FakeRenderer();
|
|
vm.attachRenderer(renderer);
|
|
await vm.loadProject(fixture);
|
|
|
|
// Value of pc each time a block moved the sprite and each time the renderer drew.
|
|
// Bounded so that a broken test can't eat all memory.
|
|
const moves = [];
|
|
const draws = [];
|
|
const getPC = () => (vm.runtime.sampler.pc ? vm.runtime.sampler.pc[0] : null);
|
|
const originalUpdateDrawablePosition = renderer.updateDrawablePosition;
|
|
renderer.updateDrawablePosition = function (...args) {
|
|
if (moves.length < 100) moves.push(getPC());
|
|
return originalUpdateDrawablePosition.apply(this, args);
|
|
};
|
|
renderer.draw = () => {
|
|
if (draws.length < 100) draws.push(getPC());
|
|
};
|
|
|
|
return {vm, moves, draws};
|
|
};
|
|
|
|
test('blockToLocation is stable and per-sprite', () => {
|
|
const sampler = new Sampler(null);
|
|
const a = sampler.blockToLocation('sprite1', 'block1');
|
|
const b = sampler.blockToLocation('sprite1', 'block2');
|
|
const c = sampler.blockToLocation('sprite2', 'block1');
|
|
assert.notStrictEqual(a, b);
|
|
assert.notStrictEqual(a, c);
|
|
assert.ok(a >= 0 && b >= 0 && c >= 0);
|
|
assert.strictEqual(sampler.blockToLocation('sprite1', 'block1'), a);
|
|
assert.deepStrictEqual(sampler.locationToBlock(c), {
|
|
spriteId: 'sprite2',
|
|
blockId: 'block1'
|
|
});
|
|
assert.throws(() => sampler.locationToBlock(Sampler.IDLE));
|
|
});
|
|
|
|
test('disabled by default', async () => {
|
|
const {vm, moves, draws} = await setup();
|
|
vm.greenFlag();
|
|
vm.runtime._step();
|
|
assert.strictEqual(vm.runtime.sampler.pc, null);
|
|
assert.deepStrictEqual(moves, [null, null]);
|
|
assert.deepStrictEqual(draws, [null]);
|
|
assert.strictEqual(vm.runtime.sampler.locations.length, 0);
|
|
});
|
|
|
|
test('basic level attributes compiled scripts to RUNTIME', async () => {
|
|
const {vm, moves, draws} = await setup();
|
|
vm.runtime.sampler.setEnabled(Sampler.LEVEL_BASIC);
|
|
vm.greenFlag();
|
|
vm.runtime._step();
|
|
assert.ok(vm.runtime.threads[0].isCompiled);
|
|
assert.deepStrictEqual(moves, [Sampler.RUNTIME, Sampler.RUNTIME]);
|
|
assert.deepStrictEqual(draws, [Sampler.RENDERER]);
|
|
assert.strictEqual(vm.runtime.sampler.pc[0], Sampler.IDLE);
|
|
assert.strictEqual(vm.runtime.sampler.locations.length, 0);
|
|
});
|
|
|
|
test('commands level attributes compiled scripts to blocks', async () => {
|
|
const {vm, moves, draws} = await setup();
|
|
const sampler = vm.runtime.sampler;
|
|
sampler.setEnabled(Sampler.LEVEL_COMMANDS);
|
|
vm.greenFlag();
|
|
|
|
vm.runtime._step();
|
|
assert.ok(vm.runtime.threads[0].isCompiled);
|
|
const spriteId = vm.runtime.getSpriteTargetByName('Sprite1').id;
|
|
const changeOnce = sampler.blockToLocation(spriteId, 'b');
|
|
const changeInLoop = sampler.blockToLocation(spriteId, 'f');
|
|
assert.deepStrictEqual(moves, [changeOnce, changeInLoop]);
|
|
assert.deepStrictEqual(draws, [Sampler.RENDERER]);
|
|
assert.strictEqual(sampler.pc[0], Sampler.IDLE);
|
|
|
|
// After resuming from the loop's yield
|
|
vm.runtime._step();
|
|
assert.deepStrictEqual(moves, [changeOnce, changeInLoop, changeInLoop]);
|
|
assert.deepStrictEqual(draws, [Sampler.RENDERER, Sampler.RENDERER]);
|
|
assert.strictEqual(sampler.pc[0], Sampler.IDLE);
|
|
});
|
|
|
|
test('setEnabled(0) turns sampling back off', async () => {
|
|
const {vm, moves, draws} = await setup();
|
|
vm.runtime.sampler.setEnabled(Sampler.LEVEL_COMMANDS);
|
|
vm.runtime.sampler.setEnabled(0);
|
|
assert.strictEqual(vm.runtime.sampler.enableBasic, false);
|
|
assert.strictEqual(vm.runtime.sampler.enableCommands, false);
|
|
|
|
// pc is kept around but no longer written to
|
|
vm.runtime.sampler.pc[0] = 1234;
|
|
vm.greenFlag();
|
|
vm.runtime._step();
|
|
assert.deepStrictEqual(moves, [1234, 1234]);
|
|
assert.deepStrictEqual(draws, [1234]);
|
|
assert.strictEqual(vm.runtime.sampler.locations.length, 0);
|
|
});
|
|
|
|
test('Sampler is exported', () => {
|
|
const vm = new VirtualMachine();
|
|
assert.strictEqual(vm.exports.Sampler, Sampler);
|
|
});
|