198 lines
3.8 KiB
JavaScript
198 lines
3.8 KiB
JavaScript
|
import {expect, test} from 'vitest';
|
||
|
|
||
|
import {parse} from '@swc/core';
|
||
|
import Sandbox from '@/swcx/sandbox.js';
|
||
|
|
||
|
test('declares variables', async () => {
|
||
|
const sandbox = new Sandbox(
|
||
|
await parse(`
|
||
|
const scalar = 1;
|
||
|
const asyncScalar = await 2;
|
||
|
const array = [3, 4, 5];
|
||
|
const asyncArray = await [6, 7, 8];
|
||
|
const object = {9: '10'};
|
||
|
const asyncObject = await {11: '12'};
|
||
|
`),
|
||
|
);
|
||
|
let result;
|
||
|
do {
|
||
|
result = sandbox.step();
|
||
|
if (result.value?.async) {
|
||
|
await result.value.async;
|
||
|
}
|
||
|
} while (!result.done);
|
||
|
expect(sandbox.context)
|
||
|
.to.deep.equal({
|
||
|
scalar: 1,
|
||
|
asyncScalar: 2,
|
||
|
array: [3, 4, 5],
|
||
|
asyncArray: [6, 7, 8],
|
||
|
object: {9: '10'},
|
||
|
asyncObject: {11: '12'},
|
||
|
});
|
||
|
});
|
||
|
|
||
|
test('destructures variables', async () => {
|
||
|
const sandbox = new Sandbox(
|
||
|
await parse(`
|
||
|
const [a, , c] = [1, 2, 3];
|
||
|
const {x: x1, y, z: {zz}} = {x: 4, y: 5, z: {zz: 6}};
|
||
|
const [d, e] = await [7, 8];
|
||
|
const {t, u: {uu}} = {t: 9, u: {uu: await 10}};
|
||
|
`),
|
||
|
);
|
||
|
let result;
|
||
|
do {
|
||
|
result = sandbox.step();
|
||
|
if (result.value?.async) {
|
||
|
await result.value.value;
|
||
|
}
|
||
|
} while (!result.done);
|
||
|
expect(sandbox.context)
|
||
|
.to.deep.equal({
|
||
|
a: 1,
|
||
|
c: 3,
|
||
|
x1: 4,
|
||
|
y: 5,
|
||
|
zz: 6,
|
||
|
d: 7,
|
||
|
e: 8,
|
||
|
t: 9,
|
||
|
uu: 10,
|
||
|
});
|
||
|
});
|
||
|
|
||
|
test('runs arbitrary number of ops', async () => {
|
||
|
const sandbox = new Sandbox(
|
||
|
await parse(`
|
||
|
const foo = [];
|
||
|
for (let i = 0; i < 1500; ++i) {
|
||
|
foo.push(i);
|
||
|
}
|
||
|
`),
|
||
|
);
|
||
|
sandbox.run(1000);
|
||
|
expect(sandbox.context.foo.length)
|
||
|
.to.equal(1000);
|
||
|
sandbox.run(1000);
|
||
|
expect(sandbox.context.foo.length)
|
||
|
.to.equal(1500);
|
||
|
expect(true)
|
||
|
.to.be.true;
|
||
|
});
|
||
|
|
||
|
test('evaluates conditional branches', async () => {
|
||
|
const sandbox = new Sandbox(
|
||
|
await parse(`
|
||
|
let foo, bar;
|
||
|
if (true) {
|
||
|
foo = 1;
|
||
|
}
|
||
|
else {
|
||
|
foo = 2;
|
||
|
}
|
||
|
if (await false) {
|
||
|
bar = 1;
|
||
|
}
|
||
|
else {
|
||
|
bar = 2;
|
||
|
}
|
||
|
`),
|
||
|
);
|
||
|
let result;
|
||
|
do {
|
||
|
result = sandbox.step();
|
||
|
if (result.value?.async) {
|
||
|
await result.value.value;
|
||
|
}
|
||
|
} while (!result.done);
|
||
|
expect(sandbox.context)
|
||
|
.to.deep.equal({
|
||
|
foo: 1,
|
||
|
bar: 2,
|
||
|
});
|
||
|
});
|
||
|
|
||
|
test('evaluates loops', async () => {
|
||
|
const sandbox = new Sandbox(
|
||
|
await parse(`
|
||
|
let x = 0, y = 0, a = 0, b = 0, c = 0;
|
||
|
for (let i = 0; i < 3; ++i) {
|
||
|
x += 1;
|
||
|
}
|
||
|
for (let i = await 0; i < await 3; i = 1 + await i) {
|
||
|
y += 1;
|
||
|
}
|
||
|
do {
|
||
|
a += 1;
|
||
|
} while (a < 3);
|
||
|
do {
|
||
|
b += 1;
|
||
|
} while (await b < 3);
|
||
|
while (c < 3) {
|
||
|
c += 1;
|
||
|
}
|
||
|
`),
|
||
|
);
|
||
|
let result;
|
||
|
do {
|
||
|
result = sandbox.step();
|
||
|
if (result.value?.async) {
|
||
|
await result.value.value;
|
||
|
}
|
||
|
} while (!result.done);
|
||
|
expect(sandbox.context)
|
||
|
.to.deep.equal({
|
||
|
a: 3,
|
||
|
b: 3,
|
||
|
c: 3,
|
||
|
x: 3,
|
||
|
y: 3,
|
||
|
});
|
||
|
});
|
||
|
|
||
|
test('retuns undefined for nonexistent variables in scope', async () => {
|
||
|
const sandbox = new Sandbox(
|
||
|
await parse(`
|
||
|
const x = y
|
||
|
`),
|
||
|
);
|
||
|
sandbox.run();
|
||
|
expect(sandbox.context)
|
||
|
.to.deep.equal({
|
||
|
x: undefined,
|
||
|
});
|
||
|
});
|
||
|
|
||
|
test('sets variables in global scope', async () => {
|
||
|
const sandbox = new Sandbox(
|
||
|
await parse(`
|
||
|
x = y
|
||
|
`),
|
||
|
);
|
||
|
sandbox.run();
|
||
|
expect(sandbox.context)
|
||
|
.to.deep.equal({
|
||
|
x: undefined,
|
||
|
});
|
||
|
});
|
||
|
|
||
|
test('runs arbitrary number of ops', async () => {
|
||
|
const sandbox = new Sandbox(
|
||
|
await parse(`
|
||
|
const foo = [];
|
||
|
for (let i = 0; i < 1500; ++i) {
|
||
|
foo.push(i);
|
||
|
}
|
||
|
`),
|
||
|
);
|
||
|
sandbox.run(1000);
|
||
|
expect(sandbox.context.foo.length)
|
||
|
.to.equal(1000);
|
||
|
sandbox.run(1000);
|
||
|
expect(sandbox.context.foo.length)
|
||
|
.to.equal(1500);
|
||
|
expect(true)
|
||
|
.to.be.true;
|
||
|
});
|