1
0
Files
sashinexists/node_modules/@weborigami/language/test/runtime/evaluate.test.js
2024-12-07 13:18:31 +11:00

86 lines
2.4 KiB
JavaScript

import { ObjectTree } from "@weborigami/async-tree";
import assert from "node:assert";
import { describe, test } from "node:test";
import * as ops from "../../src/runtime/ops.js";
import evaluate from "../../src/runtime/evaluate.js";
describe("evaluate", () => {
test("can retrieve values from scope", async () => {
const code = createCode([ops.scope, "message"]);
const parent = new ObjectTree({
message: "Hello",
});
const tree = new ObjectTree({});
tree.parent = parent;
const result = await evaluate.call(tree, code);
assert.equal(result, "Hello");
});
test("can invoke functions in scope", async () => {
// Match the array representation of code generated by the parser.
const code = createCode([
[ops.scope, "greet"],
[ops.scope, "name"],
]);
const tree = new ObjectTree({
async greet(name) {
return `Hello ${name}`;
},
name: "world",
});
const result = await evaluate.call(tree, code);
assert.equal(result, "Hello world");
});
test("passes context to invoked functions", async () => {
const code = createCode([ops.scope, "fn"]);
const tree = new ObjectTree({
async fn() {
assert.equal(this, tree);
},
});
await evaluate.call(tree, code);
});
test("evaluates a function with fixed number of arguments", async () => {
const fn = (x, y) => ({
c: `${x}${y}c`,
});
const code = createCode([ops.traverse, fn, "a", "b", "c"]);
assert.equal(await evaluate.call(null, code), "abc");
});
test("if object in function position isn't a function, can unpack it", async () => {
const fn = (...args) => args.join(",");
const packed = new String();
/** @type {any} */ (packed).unpack = async () => fn;
const code = createCode([packed, "a", "b", "c"]);
const result = await evaluate.call(null, code);
assert.equal(result, "a,b,c");
});
test("by defalut sets the parent of a returned tree to the current tree", async () => {
const fn = () => new ObjectTree({});
const code = createCode([fn]);
const tree = new ObjectTree({});
const result = await evaluate.call(tree, code);
assert.equal(result.parent, tree);
});
});
/**
* @returns {import("../../index.ts").Code}
*/
function createCode(array) {
const code = array;
/** @type {any} */ (code).location = {
source: {
text: "",
},
};
return code;
}