@weborigami/language 0.3.3-jse.3 → 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/main.js +1 -3
- package/package.json +3 -3
- package/src/compiler/compile.js +2 -10
- package/src/compiler/optimize.js +93 -147
- package/src/compiler/origami.pegjs +67 -171
- package/src/compiler/parse.js +946 -1810
- package/src/compiler/parserHelpers.js +58 -159
- package/src/runtime/HandleExtensionsTransform.js +1 -10
- package/src/runtime/evaluate.js +35 -28
- package/src/runtime/expressionObject.js +4 -4
- package/src/runtime/handlers.js +54 -18
- package/src/runtime/mergeTrees.js +5 -0
- package/src/runtime/ops.js +156 -101
- package/src/runtime/symbols.js +0 -1
- package/src/runtime/{templateIndent.js → taggedTemplateIndent.js} +2 -2
- package/test/compiler/codeHelpers.js +1 -3
- package/test/compiler/compile.test.js +27 -52
- package/test/compiler/optimize.test.js +23 -92
- package/test/compiler/parse.test.js +342 -574
- package/test/runtime/evaluate.test.js +20 -4
- package/test/runtime/expressionObject.test.js +4 -5
- package/test/runtime/handlers.test.js +10 -19
- package/test/runtime/mergeTrees.test.js +5 -0
- package/test/runtime/ops.test.js +82 -103
- package/test/runtime/taggedTemplateIndent.test.js +1 -1
- package/src/runtime/getHandlers.js +0 -10
- package/src/runtime/jsGlobals.js +0 -99
- package/src/runtime/templateStandard.js +0 -13
- package/test/runtime/templateText.test.js +0 -18
|
@@ -8,7 +8,7 @@ import { createCode } from "../compiler/codeHelpers.js";
|
|
|
8
8
|
|
|
9
9
|
describe("evaluate", () => {
|
|
10
10
|
test("can retrieve values from scope", async () => {
|
|
11
|
-
const code = createCode([
|
|
11
|
+
const code = createCode([ops.scope, "message"]);
|
|
12
12
|
const parent = new ObjectTree({
|
|
13
13
|
message: "Hello",
|
|
14
14
|
});
|
|
@@ -21,8 +21,8 @@ describe("evaluate", () => {
|
|
|
21
21
|
test("can invoke functions in scope", async () => {
|
|
22
22
|
// Match the array representation of code generated by the parser.
|
|
23
23
|
const code = createCode([
|
|
24
|
-
[
|
|
25
|
-
[
|
|
24
|
+
[ops.scope, "greet"],
|
|
25
|
+
[ops.scope, "name"],
|
|
26
26
|
]);
|
|
27
27
|
|
|
28
28
|
const tree = new ObjectTree({
|
|
@@ -37,7 +37,7 @@ describe("evaluate", () => {
|
|
|
37
37
|
});
|
|
38
38
|
|
|
39
39
|
test("passes context to invoked functions", async () => {
|
|
40
|
-
const code = createCode([
|
|
40
|
+
const code = createCode([ops.scope, "fn"]);
|
|
41
41
|
const tree = new ObjectTree({
|
|
42
42
|
async fn() {
|
|
43
43
|
assert.equal(this, tree);
|
|
@@ -46,6 +46,14 @@ describe("evaluate", () => {
|
|
|
46
46
|
await evaluate.call(tree, code);
|
|
47
47
|
});
|
|
48
48
|
|
|
49
|
+
test("evaluates a function with fixed number of arguments", async () => {
|
|
50
|
+
const fn = (x, y) => ({
|
|
51
|
+
c: `${x}${y}c`,
|
|
52
|
+
});
|
|
53
|
+
const code = createCode([ops.traverse, fn, "a", "b", "c"]);
|
|
54
|
+
assert.equal(await evaluate.call(null, code), "abc");
|
|
55
|
+
});
|
|
56
|
+
|
|
49
57
|
test("if object in function position isn't a function, can unpack it", async () => {
|
|
50
58
|
const fn = (...args) => args.join(",");
|
|
51
59
|
const packed = new String();
|
|
@@ -54,4 +62,12 @@ describe("evaluate", () => {
|
|
|
54
62
|
const result = await evaluate.call(null, code);
|
|
55
63
|
assert.equal(result, "a,b,c");
|
|
56
64
|
});
|
|
65
|
+
|
|
66
|
+
test("by defalut sets the parent of a returned tree to the current tree", async () => {
|
|
67
|
+
const fn = () => new ObjectTree({});
|
|
68
|
+
const code = createCode([fn]);
|
|
69
|
+
const tree = new ObjectTree({});
|
|
70
|
+
const result = await evaluate.call(tree, code);
|
|
71
|
+
assert.equal(result.parent, tree);
|
|
72
|
+
});
|
|
57
73
|
});
|
|
@@ -12,8 +12,8 @@ describe("expressionObject", () => {
|
|
|
12
12
|
});
|
|
13
13
|
|
|
14
14
|
const entries = [
|
|
15
|
-
["hello", [[
|
|
16
|
-
["world", [[
|
|
15
|
+
["hello", [[ops.scope, "upper"], "hello"]],
|
|
16
|
+
["world", [[ops.scope, "upper"], "world"]],
|
|
17
17
|
];
|
|
18
18
|
|
|
19
19
|
const object = await expressionObject(entries, scope);
|
|
@@ -40,7 +40,7 @@ describe("expressionObject", () => {
|
|
|
40
40
|
test("can instantiate an Origami tree", async () => {
|
|
41
41
|
const entries = [
|
|
42
42
|
["name", "world"],
|
|
43
|
-
["message", [ops.concat, "Hello, ", [
|
|
43
|
+
["message", [ops.concat, "Hello, ", [ops.scope, "name"], "!"]],
|
|
44
44
|
];
|
|
45
45
|
const parent = new ObjectTree({});
|
|
46
46
|
const object = await expressionObject(entries, parent);
|
|
@@ -53,8 +53,7 @@ describe("expressionObject", () => {
|
|
|
53
53
|
|
|
54
54
|
test("returned object values can be unpacked", async () => {
|
|
55
55
|
const entries = [["data.json", `{ "a": 1 }`]];
|
|
56
|
-
const parent = new ObjectTree({
|
|
57
|
-
parent.handlers = new ObjectTree({
|
|
56
|
+
const parent = new ObjectTree({
|
|
58
57
|
"json.handler": {
|
|
59
58
|
unpack: JSON.parse,
|
|
60
59
|
},
|
|
@@ -3,12 +3,6 @@ import assert from "node:assert";
|
|
|
3
3
|
import { describe, test } from "node:test";
|
|
4
4
|
import { handleExtension } from "../../src/runtime/handlers.js";
|
|
5
5
|
|
|
6
|
-
const handlers = new ObjectTree({
|
|
7
|
-
"json.handler": {
|
|
8
|
-
unpack: (buffer) => JSON.parse(String(buffer)),
|
|
9
|
-
},
|
|
10
|
-
});
|
|
11
|
-
|
|
12
6
|
describe("handlers", () => {
|
|
13
7
|
test("attaches an unpack method to a value with an extension", async () => {
|
|
14
8
|
const fixture = createFixture();
|
|
@@ -16,12 +10,7 @@ describe("handlers", () => {
|
|
|
16
10
|
assert(typeof numberValue === "number");
|
|
17
11
|
assert.equal(numberValue, 1);
|
|
18
12
|
const jsonFile = await fixture.get("bar.json");
|
|
19
|
-
const withHandler = await handleExtension(
|
|
20
|
-
fixture,
|
|
21
|
-
jsonFile,
|
|
22
|
-
"bar.json",
|
|
23
|
-
handlers
|
|
24
|
-
);
|
|
13
|
+
const withHandler = await handleExtension(fixture, jsonFile, "bar.json");
|
|
25
14
|
assert.equal(String(withHandler), `{ "bar": 2 }`);
|
|
26
15
|
const data = await withHandler.unpack();
|
|
27
16
|
assert.deepEqual(data, { bar: 2 });
|
|
@@ -30,19 +19,21 @@ describe("handlers", () => {
|
|
|
30
19
|
test("immediately unpacks if key ends in slash", async () => {
|
|
31
20
|
const fixture = createFixture();
|
|
32
21
|
const jsonFile = await fixture.get("bar.json");
|
|
33
|
-
const data = await handleExtension(
|
|
34
|
-
fixture,
|
|
35
|
-
jsonFile,
|
|
36
|
-
"bar.json/",
|
|
37
|
-
handlers
|
|
38
|
-
);
|
|
22
|
+
const data = await handleExtension(fixture, jsonFile, "bar.json/");
|
|
39
23
|
assert.deepEqual(data, { bar: 2 });
|
|
40
24
|
});
|
|
41
25
|
});
|
|
42
26
|
|
|
43
27
|
function createFixture() {
|
|
44
|
-
|
|
28
|
+
const parent = new ObjectTree({
|
|
29
|
+
"json.handler": {
|
|
30
|
+
unpack: (buffer) => JSON.parse(String(buffer)),
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
let tree = new ObjectTree({
|
|
45
34
|
foo: 1, // No extension, should be left alone
|
|
46
35
|
"bar.json": `{ "bar": 2 }`,
|
|
47
36
|
});
|
|
37
|
+
tree.parent = parent;
|
|
38
|
+
return tree;
|
|
48
39
|
}
|
|
@@ -41,6 +41,11 @@ describe("mergeTrees", () => {
|
|
|
41
41
|
});
|
|
42
42
|
});
|
|
43
43
|
|
|
44
|
+
test("if all arguments are arrays, result is an array", async () => {
|
|
45
|
+
const result = await mergeTrees.call(null, [1, 2], [3, 4]);
|
|
46
|
+
assert.deepEqual(result, [1, 2, 3, 4]);
|
|
47
|
+
});
|
|
48
|
+
|
|
44
49
|
test("merges heterogenous arguments as trees", async () => {
|
|
45
50
|
const tree = await mergeTrees.call(
|
|
46
51
|
null,
|
package/test/runtime/ops.test.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DeepObjectTree, ObjectTree
|
|
1
|
+
import { DeepObjectTree, ObjectTree } from "@weborigami/async-tree";
|
|
2
2
|
import assert from "node:assert";
|
|
3
3
|
import { describe, test } from "node:test";
|
|
4
4
|
|
|
@@ -42,6 +42,17 @@ describe("ops", () => {
|
|
|
42
42
|
assert.strictEqual(ops.bitwiseXor(5, 3), 6);
|
|
43
43
|
});
|
|
44
44
|
|
|
45
|
+
test("ops.builtin gets a value from the top of the scope chain", async () => {
|
|
46
|
+
const root = new ObjectTree({
|
|
47
|
+
a: 1,
|
|
48
|
+
});
|
|
49
|
+
const tree = new ObjectTree({});
|
|
50
|
+
tree.parent = root;
|
|
51
|
+
const code = createCode([ops.builtin, "a"]);
|
|
52
|
+
const result = await evaluate.call(tree, code);
|
|
53
|
+
assert.strictEqual(result, 1);
|
|
54
|
+
});
|
|
55
|
+
|
|
45
56
|
test("ops.comma returns the last value", async () => {
|
|
46
57
|
const code = createCode([ops.comma, 1, 2, 3]);
|
|
47
58
|
const result = await evaluate.call(null, code);
|
|
@@ -53,12 +64,7 @@ describe("ops", () => {
|
|
|
53
64
|
name: "world",
|
|
54
65
|
});
|
|
55
66
|
|
|
56
|
-
const code = createCode([
|
|
57
|
-
ops.concat,
|
|
58
|
-
"Hello, ",
|
|
59
|
-
[[ops.scope], "name"],
|
|
60
|
-
".",
|
|
61
|
-
]);
|
|
67
|
+
const code = createCode([ops.concat, "Hello, ", [ops.scope, "name"], "."]);
|
|
62
68
|
|
|
63
69
|
const result = await evaluate.call(scope, code);
|
|
64
70
|
assert.strictEqual(result, "Hello, world.");
|
|
@@ -74,22 +80,27 @@ describe("ops", () => {
|
|
|
74
80
|
assert.strictEqual(await ops.conditional(false, errorFn, trueFn), true);
|
|
75
81
|
});
|
|
76
82
|
|
|
77
|
-
test("ops.
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
const tree = new DeepObjectTree({
|
|
83
|
-
a: {
|
|
84
|
-
b: {
|
|
85
|
-
c: {},
|
|
86
|
-
},
|
|
83
|
+
test("ops.documentFunction", async () => {
|
|
84
|
+
const code = createCode([
|
|
85
|
+
ops.document,
|
|
86
|
+
{
|
|
87
|
+
a: 1,
|
|
87
88
|
},
|
|
89
|
+
[
|
|
90
|
+
ops.lambda,
|
|
91
|
+
[["_"]],
|
|
92
|
+
[
|
|
93
|
+
ops.template,
|
|
94
|
+
[ops.literal, ["a = ", ""]],
|
|
95
|
+
[ops.concat, [ops.scope, "a"]],
|
|
96
|
+
],
|
|
97
|
+
],
|
|
98
|
+
]);
|
|
99
|
+
const result = await evaluate.call(null, code);
|
|
100
|
+
assert.deepEqual(result, {
|
|
101
|
+
a: 1,
|
|
102
|
+
"@text": "a = 1",
|
|
88
103
|
});
|
|
89
|
-
const b = await Tree.traverse(tree, "a", "b");
|
|
90
|
-
const c = await b.get("c");
|
|
91
|
-
assert.equal(ops.context.call(c), c);
|
|
92
|
-
assert.equal(ops.context.call(c, 1), b);
|
|
93
104
|
});
|
|
94
105
|
|
|
95
106
|
test("ops.division divides two numbers", async () => {
|
|
@@ -112,21 +123,20 @@ describe("ops", () => {
|
|
|
112
123
|
assert.strictEqual(ops.exponentiation(2, 0), 1);
|
|
113
124
|
});
|
|
114
125
|
|
|
115
|
-
test("ops.
|
|
126
|
+
test("ops.external evaluates code and cache its result", async () => {
|
|
116
127
|
let count = 0;
|
|
117
128
|
const tree = new DeepObjectTree({
|
|
118
129
|
group: {
|
|
119
130
|
get count() {
|
|
120
|
-
|
|
121
|
-
return Promise.resolve(++count);
|
|
131
|
+
return ++count;
|
|
122
132
|
},
|
|
123
133
|
},
|
|
124
134
|
});
|
|
125
135
|
const code = createCode([
|
|
126
|
-
ops.
|
|
127
|
-
{},
|
|
136
|
+
ops.external,
|
|
128
137
|
"group/count",
|
|
129
|
-
[
|
|
138
|
+
[ops.traverse, [ops.scope, "group"], [ops.literal, "count"]],
|
|
139
|
+
{},
|
|
130
140
|
]);
|
|
131
141
|
const result = await evaluate.call(tree, code);
|
|
132
142
|
assert.strictEqual(result, 1);
|
|
@@ -134,26 +144,6 @@ describe("ops", () => {
|
|
|
134
144
|
assert.strictEqual(result2, 1);
|
|
135
145
|
});
|
|
136
146
|
|
|
137
|
-
describe("ops.flat", () => {
|
|
138
|
-
test("flattens arrays", async () => {
|
|
139
|
-
assert.deepEqual(await ops.flat(1, 2, [3]), [1, 2, 3]);
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
test("flattens treelike objects", async () => {
|
|
143
|
-
const object = {
|
|
144
|
-
a: 1,
|
|
145
|
-
b: 2,
|
|
146
|
-
};
|
|
147
|
-
const tree = new ObjectTree({
|
|
148
|
-
c: 3,
|
|
149
|
-
d: 4,
|
|
150
|
-
});
|
|
151
|
-
const array = [5, 6];
|
|
152
|
-
const result = await ops.flat(object, tree, array);
|
|
153
|
-
assert.deepEqual(result, [1, 2, 3, 4, 5, 6]);
|
|
154
|
-
});
|
|
155
|
-
});
|
|
156
|
-
|
|
157
147
|
test("ops.greaterThan", () => {
|
|
158
148
|
assert(ops.greaterThan(5, 3));
|
|
159
149
|
assert(!ops.greaterThan(3, 3));
|
|
@@ -166,6 +156,20 @@ describe("ops", () => {
|
|
|
166
156
|
assert(ops.greaterThanOrEqual("ab", "aa"));
|
|
167
157
|
});
|
|
168
158
|
|
|
159
|
+
test("ops.inherited searches inherited scope", async () => {
|
|
160
|
+
const parent = new ObjectTree({
|
|
161
|
+
a: 1, // This is the inherited value we want
|
|
162
|
+
});
|
|
163
|
+
/** @type {any} */
|
|
164
|
+
const child = new ObjectTree({
|
|
165
|
+
a: 2, // Should be ignored
|
|
166
|
+
});
|
|
167
|
+
child.parent = parent;
|
|
168
|
+
const code = createCode([ops.inherited, "a"]);
|
|
169
|
+
const result = await evaluate.call(child, code);
|
|
170
|
+
assert.strictEqual(result, 1);
|
|
171
|
+
});
|
|
172
|
+
|
|
169
173
|
test("ops.lambda defines a function with no inputs", async () => {
|
|
170
174
|
const code = createCode([ops.lambda, [], [ops.literal, "result"]]);
|
|
171
175
|
const fn = await evaluate.call(null, code);
|
|
@@ -178,7 +182,7 @@ describe("ops", () => {
|
|
|
178
182
|
message: "Hello",
|
|
179
183
|
});
|
|
180
184
|
|
|
181
|
-
const code = createCode([ops.lambda, ["_"], [
|
|
185
|
+
const code = createCode([ops.lambda, ["_"], [ops.scope, "message"]]);
|
|
182
186
|
|
|
183
187
|
const fn = await evaluate.call(scope, code);
|
|
184
188
|
const result = await fn.call(scope);
|
|
@@ -192,7 +196,7 @@ describe("ops", () => {
|
|
|
192
196
|
[ops.literal, "a"],
|
|
193
197
|
[ops.literal, "b"],
|
|
194
198
|
],
|
|
195
|
-
[ops.concat, [
|
|
199
|
+
[ops.concat, [ops.scope, "b"], [ops.scope, "a"]],
|
|
196
200
|
]);
|
|
197
201
|
const fn = await evaluate.call(null, code);
|
|
198
202
|
const result = await fn("x", "y");
|
|
@@ -246,31 +250,40 @@ describe("ops", () => {
|
|
|
246
250
|
test("ops.merge", async () => {
|
|
247
251
|
// {
|
|
248
252
|
// a: 1
|
|
249
|
-
// …
|
|
250
|
-
// c: a
|
|
253
|
+
// …fn(a)
|
|
251
254
|
// }
|
|
252
255
|
const scope = new ObjectTree({
|
|
253
|
-
|
|
256
|
+
fn: (a) => ({ b: 2 * a }),
|
|
254
257
|
});
|
|
255
258
|
const code = createCode([
|
|
259
|
+
ops.merge,
|
|
260
|
+
[ops.object, ["a", [ops.literal, 1]]],
|
|
256
261
|
[
|
|
257
|
-
ops.
|
|
258
|
-
[
|
|
259
|
-
["c", [[ops.context], "a"]],
|
|
260
|
-
[
|
|
261
|
-
"_result",
|
|
262
|
-
[
|
|
263
|
-
ops.merge,
|
|
264
|
-
[ops.object, ["a", [ops.getter, [[ops.context, 1], "a"]]]],
|
|
265
|
-
[[ops.scope], "more"],
|
|
266
|
-
[ops.object, ["c", [ops.getter, [[ops.context, 1], "c"]]]],
|
|
267
|
-
],
|
|
268
|
-
],
|
|
262
|
+
[ops.builtin, "fn"],
|
|
263
|
+
[ops.scope, "a"],
|
|
269
264
|
],
|
|
270
|
-
"_result",
|
|
271
265
|
]);
|
|
272
266
|
const result = await evaluate.call(scope, code);
|
|
273
|
-
assert.deepEqual(
|
|
267
|
+
assert.deepEqual(result, { a: 1, b: 2 });
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
test("ops.merge lets all direct properties see each other", async () => {
|
|
271
|
+
// {
|
|
272
|
+
// a: 1
|
|
273
|
+
// ...more
|
|
274
|
+
// c: a
|
|
275
|
+
// }
|
|
276
|
+
const scope = new ObjectTree({
|
|
277
|
+
more: { b: 2 },
|
|
278
|
+
});
|
|
279
|
+
const code = createCode([
|
|
280
|
+
ops.merge,
|
|
281
|
+
[ops.object, ["a", [ops.literal, 1]]],
|
|
282
|
+
[ops.scope, "more"],
|
|
283
|
+
[ops.object, ["c", [ops.scope, "a"]]],
|
|
284
|
+
]);
|
|
285
|
+
const result = await evaluate.call(scope, code);
|
|
286
|
+
assert.deepEqual(result, { a: 1, b: 2, c: 1 });
|
|
274
287
|
});
|
|
275
288
|
|
|
276
289
|
test("ops.multiplication multiplies two numbers", async () => {
|
|
@@ -280,11 +293,6 @@ describe("ops", () => {
|
|
|
280
293
|
assert.strictEqual(ops.multiplication("foo", 2), NaN);
|
|
281
294
|
});
|
|
282
295
|
|
|
283
|
-
test("ops.optionalTraverse", async () => {
|
|
284
|
-
assert.equal(await ops.optionalTraverse(null, "a"), undefined);
|
|
285
|
-
assert.equal(await ops.optionalTraverse({ a: 1 }, "a"), 1);
|
|
286
|
-
});
|
|
287
|
-
|
|
288
296
|
test("ops.notEqual", () => {
|
|
289
297
|
assert(!ops.notEqual(1, 1));
|
|
290
298
|
assert(ops.notEqual(1, 2));
|
|
@@ -317,8 +325,8 @@ describe("ops", () => {
|
|
|
317
325
|
|
|
318
326
|
const code = createCode([
|
|
319
327
|
ops.object,
|
|
320
|
-
["hello", [[
|
|
321
|
-
["world", [[
|
|
328
|
+
["hello", [[ops.scope, "upper"], "hello"]],
|
|
329
|
+
["world", [[ops.scope, "upper"], "world"]],
|
|
322
330
|
]);
|
|
323
331
|
|
|
324
332
|
const result = await evaluate.call(scope, code);
|
|
@@ -334,7 +342,7 @@ describe("ops", () => {
|
|
|
334
342
|
ops.array,
|
|
335
343
|
"Hello",
|
|
336
344
|
1,
|
|
337
|
-
[[
|
|
345
|
+
[[ops.scope, "upper"], "world"],
|
|
338
346
|
]);
|
|
339
347
|
const result = await evaluate.call(scope, code);
|
|
340
348
|
assert.deepEqual(result, ["Hello", 1, "WORLD"]);
|
|
@@ -347,35 +355,6 @@ describe("ops", () => {
|
|
|
347
355
|
assert.strictEqual(ops.remainder(-4, 2), -0);
|
|
348
356
|
});
|
|
349
357
|
|
|
350
|
-
describe("ops.scope", () => {
|
|
351
|
-
test("returns the scope of the current tree", async () => {
|
|
352
|
-
const tree = new DeepObjectTree({
|
|
353
|
-
a: {
|
|
354
|
-
b: {},
|
|
355
|
-
},
|
|
356
|
-
c: 1,
|
|
357
|
-
});
|
|
358
|
-
const a = await tree.get("a");
|
|
359
|
-
const b = await a.get("b");
|
|
360
|
-
const scope = await ops.scope.call(b);
|
|
361
|
-
assert.equal(await scope.get("c"), 1);
|
|
362
|
-
});
|
|
363
|
-
|
|
364
|
-
test("accepts an optional context", async () => {
|
|
365
|
-
const tree = new DeepObjectTree({
|
|
366
|
-
a: {
|
|
367
|
-
b: {},
|
|
368
|
-
c: 0, // shouldn't get this
|
|
369
|
-
},
|
|
370
|
-
c: 1,
|
|
371
|
-
});
|
|
372
|
-
const a = await tree.get("a");
|
|
373
|
-
const b = await a.get("b");
|
|
374
|
-
const scope = await ops.scope.call(b, tree);
|
|
375
|
-
assert.equal(await scope.get("c"), 1);
|
|
376
|
-
});
|
|
377
|
-
});
|
|
378
|
-
|
|
379
358
|
test("ops.shiftLeft", () => {
|
|
380
359
|
assert.strictEqual(ops.shiftLeft(5, 2), 20);
|
|
381
360
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import assert from "node:assert";
|
|
2
2
|
import { describe, test } from "node:test";
|
|
3
|
-
import indent from "../../src/runtime/
|
|
3
|
+
import indent from "../../src/runtime/taggedTemplateIndent.js";
|
|
4
4
|
|
|
5
5
|
describe("taggedTemplateIndent", () => {
|
|
6
6
|
test("joins strings and values together if template isn't a block template", async () => {
|
package/src/runtime/jsGlobals.js
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* The complete set of support JavaScript globals and global-like values.
|
|
5
|
-
*
|
|
6
|
-
* See
|
|
7
|
-
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects.
|
|
8
|
-
* That page lists some things like `TypedArrays` which are not globals so are
|
|
9
|
-
* omitted here.
|
|
10
|
-
*/
|
|
11
|
-
export default {
|
|
12
|
-
AggregateError,
|
|
13
|
-
Array,
|
|
14
|
-
ArrayBuffer,
|
|
15
|
-
Atomics,
|
|
16
|
-
BigInt,
|
|
17
|
-
BigInt64Array,
|
|
18
|
-
BigUint64Array,
|
|
19
|
-
Boolean,
|
|
20
|
-
DataView,
|
|
21
|
-
Date,
|
|
22
|
-
Error,
|
|
23
|
-
EvalError,
|
|
24
|
-
FinalizationRegistry,
|
|
25
|
-
Float32Array,
|
|
26
|
-
Float64Array,
|
|
27
|
-
Function,
|
|
28
|
-
Infinity,
|
|
29
|
-
Int16Array,
|
|
30
|
-
Int32Array,
|
|
31
|
-
Int8Array,
|
|
32
|
-
Intl,
|
|
33
|
-
// @ts-ignore Iterator does exist despite what TypeScript thinks
|
|
34
|
-
Iterator,
|
|
35
|
-
JSON,
|
|
36
|
-
Map,
|
|
37
|
-
Math,
|
|
38
|
-
NaN,
|
|
39
|
-
Number,
|
|
40
|
-
Object,
|
|
41
|
-
Promise,
|
|
42
|
-
Proxy,
|
|
43
|
-
RangeError,
|
|
44
|
-
ReferenceError,
|
|
45
|
-
Reflect,
|
|
46
|
-
RegExp,
|
|
47
|
-
Set,
|
|
48
|
-
SharedArrayBuffer,
|
|
49
|
-
String,
|
|
50
|
-
Symbol,
|
|
51
|
-
SyntaxError,
|
|
52
|
-
TypeError,
|
|
53
|
-
URIError,
|
|
54
|
-
Uint16Array,
|
|
55
|
-
Uint32Array,
|
|
56
|
-
Uint8Array,
|
|
57
|
-
Uint8ClampedArray,
|
|
58
|
-
WeakMap,
|
|
59
|
-
WeakRef,
|
|
60
|
-
WeakSet,
|
|
61
|
-
decodeURI,
|
|
62
|
-
decodeURIComponent,
|
|
63
|
-
encodeURI,
|
|
64
|
-
encodeURIComponent,
|
|
65
|
-
eval,
|
|
66
|
-
false: false, // treat like a global
|
|
67
|
-
fetch: fetchWrapper, // special case
|
|
68
|
-
globalThis,
|
|
69
|
-
import: importWrapper, // not a function in JS but acts like one
|
|
70
|
-
isFinite,
|
|
71
|
-
isNaN,
|
|
72
|
-
null: null, // treat like a global
|
|
73
|
-
parseFloat,
|
|
74
|
-
parseInt,
|
|
75
|
-
true: true, // treat like a global
|
|
76
|
-
undefined,
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
async function fetchWrapper(resource, options) {
|
|
80
|
-
const response = await fetch(resource, options);
|
|
81
|
-
return response.ok ? await response.arrayBuffer() : undefined;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/** @this {import("@weborigami/types").AsyncTree|null|undefined} */
|
|
85
|
-
async function importWrapper(modulePath) {
|
|
86
|
-
// Walk up parent tree looking for a FileTree or other object with a `path`
|
|
87
|
-
/** @type {any} */
|
|
88
|
-
let current = this;
|
|
89
|
-
while (current && !("path" in current)) {
|
|
90
|
-
current = current.parent;
|
|
91
|
-
}
|
|
92
|
-
if (!current) {
|
|
93
|
-
throw new TypeError(
|
|
94
|
-
"Modules can only be imported from a folder or other object with a path property."
|
|
95
|
-
);
|
|
96
|
-
}
|
|
97
|
-
const filePath = path.resolve(current.path, modulePath);
|
|
98
|
-
return import(filePath);
|
|
99
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Concatenate the strings with a standard tagged template function that works
|
|
3
|
-
* just like normal JavaScript templates. This is: a) synchronous, b) does not
|
|
4
|
-
* convert treelike objects to strings.
|
|
5
|
-
*/
|
|
6
|
-
export default function standardTemplate(strings, ...values) {
|
|
7
|
-
let result = strings[0];
|
|
8
|
-
for (let i = 0; i < values.length; i++) {
|
|
9
|
-
result += values[i];
|
|
10
|
-
result += strings[i + 1];
|
|
11
|
-
}
|
|
12
|
-
return result;
|
|
13
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert";
|
|
2
|
-
import { describe, test } from "node:test";
|
|
3
|
-
import templateText from "../../src/runtime/templateStandard.js";
|
|
4
|
-
|
|
5
|
-
describe("templateText", () => {
|
|
6
|
-
test("joins strings and values together like JavaScript", async () => {
|
|
7
|
-
const a = 1;
|
|
8
|
-
const b = 2;
|
|
9
|
-
const result = await templateText`-${a} ${b}-`;
|
|
10
|
-
assert.equal(result, "-1 2-");
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
test("renders an object like JavaScript", async () => {
|
|
14
|
-
const object = { a: 1 };
|
|
15
|
-
const result = await templateText`-${object}-`;
|
|
16
|
-
assert.equal(result, "-[object Object]-");
|
|
17
|
-
});
|
|
18
|
-
});
|