Spaces:
Running
Running
const test = require('tap').test; | |
const Thread = require('../../src/engine/thread'); | |
const RenderedTarget = require('../../src/sprites/rendered-target'); | |
const Sprite = require('../../src/sprites/sprite'); | |
const Runtime = require('../../src/engine/runtime'); | |
test('spec', t => { | |
t.type(Thread, 'function'); | |
const th = new Thread('arbitraryString'); | |
t.type(th, 'object'); | |
t.ok(th instanceof Thread); | |
t.type(th.pushStack, 'function'); | |
t.type(th.reuseStackForNextBlock, 'function'); | |
t.type(th.popStack, 'function'); | |
t.type(th.stopThisScript, 'function'); | |
t.type(th.peekStack, 'function'); | |
t.type(th.peekStackFrame, 'function'); | |
t.type(th.peekParentStackFrame, 'function'); | |
t.type(th.pushReportedValue, 'function'); | |
t.type(th.initParams, 'function'); | |
t.type(th.pushParam, 'function'); | |
t.type(th.peekStack, 'function'); | |
t.type(th.getParam, 'function'); | |
t.type(th.atStackTop, 'function'); | |
t.type(th.goToNextBlock, 'function'); | |
t.type(th.isRecursiveCall, 'function'); | |
t.end(); | |
}); | |
test('pushStack', t => { | |
const th = new Thread('arbitraryString'); | |
th.pushStack('arbitraryString'); | |
t.end(); | |
}); | |
test('popStack', t => { | |
const th = new Thread('arbitraryString'); | |
th.pushStack('arbitraryString'); | |
t.strictEquals(th.popStack(), 'arbitraryString'); | |
t.strictEquals(th.popStack(), undefined); | |
t.end(); | |
}); | |
test('atStackTop', t => { | |
const th = new Thread('arbitraryString'); | |
th.pushStack('arbitraryString'); | |
th.pushStack('secondString'); | |
t.strictEquals(th.atStackTop(), false); | |
th.popStack(); | |
t.strictEquals(th.atStackTop(), true); | |
t.end(); | |
}); | |
test('reuseStackForNextBlock', t => { | |
const th = new Thread('arbitraryString'); | |
th.pushStack('arbitraryString'); | |
th.reuseStackForNextBlock('secondString'); | |
t.strictEquals(th.popStack(), 'secondString'); | |
t.end(); | |
}); | |
test('peekStackFrame', t => { | |
const th = new Thread('arbitraryString'); | |
th.pushStack('arbitraryString'); | |
t.strictEquals(th.peekStackFrame().warpMode, false); | |
th.popStack(); | |
t.strictEquals(th.peekStackFrame(), null); | |
t.end(); | |
}); | |
test('peekParentStackFrame', t => { | |
const th = new Thread('arbitraryString'); | |
th.pushStack('arbitraryString'); | |
th.peekStackFrame().warpMode = true; | |
t.strictEquals(th.peekParentStackFrame(), null); | |
th.pushStack('secondString'); | |
t.strictEquals(th.peekParentStackFrame().warpMode, true); | |
t.end(); | |
}); | |
test('pushReportedValue', t => { | |
const th = new Thread('arbitraryString'); | |
th.pushStack('arbitraryString'); | |
th.pushStack('secondString'); | |
th.pushReportedValue('value'); | |
t.strictEquals(th.justReported, 'value'); | |
t.end(); | |
}); | |
test('peekStack', t => { | |
const th = new Thread('arbitraryString'); | |
th.pushStack('arbitraryString'); | |
t.strictEquals(th.peekStack(), 'arbitraryString'); | |
th.popStack(); | |
t.strictEquals(th.peekStack(), null); | |
t.end(); | |
}); | |
test('PushGetParam', t => { | |
const th = new Thread('arbitraryString'); | |
th.pushStack('arbitraryString'); | |
th.initParams(); | |
th.pushParam('testParam', 'testValue'); | |
t.strictEquals(th.peekStackFrame().params.testParam, 'testValue'); | |
t.strictEquals(th.getParam('testParam'), 'testValue'); | |
// Params outside of define stack always evaluate to null | |
t.strictEquals(th.getParam('nonExistentParam'), null); | |
t.end(); | |
}); | |
test('goToNextBlock', t => { | |
const th = new Thread('arbitraryString'); | |
const r = new Runtime(); | |
const s = new Sprite(null, r); | |
const rt = new RenderedTarget(s, r); | |
const block1 = {fields: Object, | |
id: 'arbitraryString', | |
inputs: Object, | |
STEPS: Object, | |
block: 'fakeBlock', | |
name: 'STEPS', | |
next: 'secondString', | |
opcode: 'motion_movesteps', | |
parent: null, | |
shadow: false, | |
topLevel: true, | |
x: 0, | |
y: 0 | |
}; | |
const block2 = {fields: Object, | |
id: 'secondString', | |
inputs: Object, | |
STEPS: Object, | |
block: 'fakeBlock', | |
name: 'STEPS', | |
next: null, | |
opcode: 'procedures_call', | |
mutation: {proccode: 'fakeCode'}, | |
parent: null, | |
shadow: false, | |
topLevel: true, | |
x: 0, | |
y: 0 | |
}; | |
rt.blocks.createBlock(block1); | |
rt.blocks.createBlock(block2); | |
rt.blocks.createBlock(block2); | |
th.target = rt; | |
t.strictEquals(th.peekStack(), null); | |
th.pushStack('secondString'); | |
t.strictEquals(th.peekStack(), 'secondString'); | |
th.goToNextBlock(); | |
t.strictEquals(th.peekStack(), null); | |
th.pushStack('secondString'); | |
th.pushStack('arbitraryString'); | |
t.strictEquals(th.peekStack(), 'arbitraryString'); | |
th.goToNextBlock(); | |
t.strictEquals(th.peekStack(), 'secondString'); | |
th.goToNextBlock(); | |
t.strictEquals(th.peekStack(), null); | |
t.end(); | |
}); | |
test('stopThisScript', t => { | |
const th = new Thread('arbitraryString'); | |
const r = new Runtime(); | |
const s = new Sprite(null, r); | |
const rt = new RenderedTarget(s, r); | |
const block1 = {fields: Object, | |
id: 'arbitraryString', | |
inputs: Object, | |
STEPS: Object, | |
block: 'fakeBlock', | |
name: 'STEPS', | |
next: null, | |
opcode: 'motion_movesteps', | |
parent: null, | |
shadow: false, | |
topLevel: true, | |
x: 0, | |
y: 0 | |
}; | |
const block2 = {fields: Object, | |
id: 'secondString', | |
inputs: Object, | |
STEPS: Object, | |
block: 'fakeBlock', | |
name: 'STEPS', | |
next: null, | |
opcode: 'procedures_call', | |
mutation: {proccode: 'fakeCode'}, | |
parent: null, | |
shadow: false, | |
topLevel: true, | |
x: 0, | |
y: 0 | |
}; | |
rt.blocks.createBlock(block1); | |
rt.blocks.createBlock(block2); | |
th.target = rt; | |
th.stopThisScript(); | |
t.strictEquals(th.peekStack(), null); | |
th.pushStack('arbitraryString'); | |
t.strictEquals(th.peekStack(), 'arbitraryString'); | |
th.stopThisScript(); | |
t.strictEquals(th.peekStack(), null); | |
th.pushStack('arbitraryString'); | |
th.pushStack('secondString'); | |
th.stopThisScript(); | |
t.strictEquals(th.peekStack(), 'secondString'); | |
t.end(); | |
}); | |
test('isRecursiveCall', t => { | |
const th = new Thread('arbitraryString'); | |
const r = new Runtime(); | |
const s = new Sprite(null, r); | |
const rt = new RenderedTarget(s, r); | |
const block1 = {fields: Object, | |
id: 'arbitraryString', | |
inputs: Object, | |
STEPS: Object, | |
block: 'fakeBlock', | |
name: 'STEPS', | |
next: null, | |
opcode: 'motion_movesteps', | |
parent: null, | |
shadow: false, | |
topLevel: true, | |
x: 0, | |
y: 0 | |
}; | |
const block2 = {fields: Object, | |
id: 'secondString', | |
inputs: Object, | |
STEPS: Object, | |
block: 'fakeBlock', | |
name: 'STEPS', | |
next: null, | |
opcode: 'procedures_call', | |
mutation: {proccode: 'fakeCode'}, | |
parent: null, | |
shadow: false, | |
topLevel: true, | |
x: 0, | |
y: 0 | |
}; | |
rt.blocks.createBlock(block1); | |
rt.blocks.createBlock(block2); | |
th.target = rt; | |
t.strictEquals(th.isRecursiveCall('fakeCode'), false); | |
th.pushStack('secondString'); | |
t.strictEquals(th.isRecursiveCall('fakeCode'), false); | |
th.pushStack('arbitraryString'); | |
t.strictEquals(th.isRecursiveCall('fakeCode'), true); | |
th.pushStack('arbitraryString'); | |
t.strictEquals(th.isRecursiveCall('fakeCode'), true); | |
th.popStack(); | |
t.strictEquals(th.isRecursiveCall('fakeCode'), true); | |
th.popStack(); | |
t.strictEquals(th.isRecursiveCall('fakeCode'), false); | |
th.popStack(); | |
t.strictEquals(th.isRecursiveCall('fakeCode'), false); | |
t.end(); | |
}); | |