as-test 1.0.15 → 1.1.0
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/CHANGELOG.md +53 -1
- package/README.md +45 -4
- package/as-test.config.schema.json +5 -0
- package/assembly/util/wipc.ts +11 -4
- package/bin/commands/clean-core.js +92 -0
- package/bin/commands/clean.js +6 -0
- package/bin/commands/init-core.js +33 -225
- package/bin/commands/run-core.js +433 -289
- package/bin/commands/web-runner-source.js +14 -700
- package/bin/commands/web-session.js +1144 -0
- package/bin/index.js +390 -78
- package/bin/types.js +1 -0
- package/bin/util.js +87 -16
- package/lib/build/index.d.ts +1 -0
- package/lib/build/index.js +1098 -0
- package/lib/build/web-runner/client.d.ts +1 -0
- package/lib/build/web-runner/client.js +167 -0
- package/lib/build/web-runner/html.d.ts +1 -0
- package/lib/build/web-runner/html.js +201 -0
- package/lib/build/web-runner/worker.d.ts +1 -0
- package/lib/build/web-runner/worker.js +271 -0
- package/lib/src/index.ts +1248 -0
- package/package.json +14 -4
- package/transform/lib/mock.js +50 -27
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "as-test",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"author": "Jairus Tanaka",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -32,6 +32,12 @@
|
|
|
32
32
|
"as-test": "./bin/index.js",
|
|
33
33
|
"ast": "./bin/index.js"
|
|
34
34
|
},
|
|
35
|
+
"exports": {
|
|
36
|
+
".": "./index.ts",
|
|
37
|
+
"./lib": "./lib/build/index.js",
|
|
38
|
+
"./transform": "./transform/lib/index.js",
|
|
39
|
+
"./package.json": "./package.json"
|
|
40
|
+
},
|
|
35
41
|
"bugs": {
|
|
36
42
|
"url": "https://github.com/JairusSW/as-test/issues"
|
|
37
43
|
},
|
|
@@ -43,6 +49,8 @@
|
|
|
43
49
|
"!assembly/__tests__/**",
|
|
44
50
|
"!assembly/tsconfig.json",
|
|
45
51
|
"bin/**/*.js",
|
|
52
|
+
"lib/**/*.js",
|
|
53
|
+
"lib/**/*.d.ts",
|
|
46
54
|
"templates/**/*.js",
|
|
47
55
|
"transform/lib/**/*.js",
|
|
48
56
|
"transform/package.json",
|
|
@@ -66,6 +74,7 @@
|
|
|
66
74
|
},
|
|
67
75
|
"scripts": {
|
|
68
76
|
"test": "node ./bin/index.js test --parallel",
|
|
77
|
+
"test:integration": "npm run build:cli && npm run build:lib && node --test tests/*.test.mjs",
|
|
69
78
|
"test:ci": "node ./bin/index.js test --parallel --tap --config ./as-test.ci.config.json",
|
|
70
79
|
"fuzz": "node ./bin/index.js fuzz",
|
|
71
80
|
"bench:seed": "node ./bin/index.js fuzz --config ./as-test.bench.config.json --clean",
|
|
@@ -75,8 +84,9 @@
|
|
|
75
84
|
"ci:act:pr": "bash ./tools/act.sh pull_request",
|
|
76
85
|
"ci:act:tests": "act push -W .github/workflows/as-test.yml",
|
|
77
86
|
"ci:act:examples": "act push -W .github/workflows/examples.yml",
|
|
78
|
-
"typecheck": "tsc -p cli --noEmit && tsc -p transform --noEmit",
|
|
87
|
+
"typecheck": "tsc -p cli --noEmit && tsc -p tsconfig.lib.json --noEmit && tsc -p transform --noEmit",
|
|
79
88
|
"lint": "eslint transform/src/**/*.ts tools/**/*.js eslint.config.js",
|
|
89
|
+
"build:lib": "tsc -p ./tsconfig.lib.json",
|
|
80
90
|
"build:transform": "tsc -p ./transform",
|
|
81
91
|
"build:cli": "tsc -p cli",
|
|
82
92
|
"build:run": "npm run build:cli",
|
|
@@ -84,8 +94,8 @@
|
|
|
84
94
|
"docs:build": "vitepress build docs",
|
|
85
95
|
"docs:preview": "vitepress preview docs",
|
|
86
96
|
"format": "prettier -w .",
|
|
87
|
-
"release:check": "npm run build:cli && npm run build:transform && npm run test && npm run test:examples && npm pack --dry-run --cache /tmp/as-test-npm-cache",
|
|
88
|
-
"prepublishOnly": "npm run build:cli && npm run build:transform && npm run test"
|
|
97
|
+
"release:check": "npm run build:cli && npm run build:lib && npm run build:transform && npm run test && npm run test:integration && npm run test:examples && npm pack --dry-run --cache /tmp/as-test-npm-cache",
|
|
98
|
+
"prepublishOnly": "npm run build:cli && npm run build:lib && npm run build:transform && npm run test && npm run test:integration"
|
|
89
99
|
},
|
|
90
100
|
"type": "module"
|
|
91
101
|
}
|
package/transform/lib/mock.js
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
import { Node,
|
|
1
|
+
import { Node, IdentifierExpression, } from "assemblyscript/dist/assemblyscript.js";
|
|
2
2
|
import { Visitor } from "./visitor.js";
|
|
3
3
|
import { toString } from "./util.js";
|
|
4
4
|
export class MockTransform extends Visitor {
|
|
5
5
|
srcCurrent = null;
|
|
6
6
|
globalStatements = [];
|
|
7
7
|
mocked = new Set();
|
|
8
|
-
importFns = [];
|
|
9
8
|
importMocked = new Set();
|
|
10
9
|
visitCallExpression(node) {
|
|
11
10
|
super.visitCallExpression(node);
|
|
12
|
-
const name = normalizeName(
|
|
11
|
+
const name = normalizeName(expressionName(node.expression));
|
|
13
12
|
if (this.mocked.has(name + "_mock")) {
|
|
14
13
|
node.expression = Node.createIdentifierExpression(name + "_mock", node.expression.range);
|
|
15
14
|
return;
|
|
@@ -25,7 +24,7 @@ export class MockTransform extends Visitor {
|
|
|
25
24
|
const oldFn = node.args[0];
|
|
26
25
|
if (!oldFn)
|
|
27
26
|
return;
|
|
28
|
-
this.mocked.delete(normalizeName(
|
|
27
|
+
this.mocked.delete(normalizeName(expressionName(oldFn)) + "_mock");
|
|
29
28
|
return;
|
|
30
29
|
}
|
|
31
30
|
if (name == "unmockImport") {
|
|
@@ -33,10 +32,12 @@ export class MockTransform extends Visitor {
|
|
|
33
32
|
}
|
|
34
33
|
if (name != "mockFn")
|
|
35
34
|
return;
|
|
36
|
-
const
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
35
|
+
const oldValue = node.args[0];
|
|
36
|
+
const callback = node.args[1];
|
|
37
|
+
if (!oldValue || !callback)
|
|
38
|
+
return;
|
|
39
|
+
const newName = normalizeName(expressionName(oldValue));
|
|
40
|
+
const newFn = Node.createFunctionDeclaration(Node.createIdentifierExpression(newName + "_mock", callback.range), callback.declaration.decorators, 0, callback.declaration.typeParameters, callback.declaration.signature, callback.declaration.body, callback.declaration.arrowKind, callback.range);
|
|
40
41
|
const currentSource = this.srcCurrent;
|
|
41
42
|
if (!currentSource)
|
|
42
43
|
return;
|
|
@@ -55,20 +56,23 @@ export class MockTransform extends Visitor {
|
|
|
55
56
|
this.mocked.add(newFn.name.text);
|
|
56
57
|
}
|
|
57
58
|
visitFunctionDeclaration(node, isDefault) {
|
|
58
|
-
if (
|
|
59
|
-
|
|
59
|
+
if (this.mocked.has(node.name.text))
|
|
60
|
+
return;
|
|
60
61
|
super.visitFunctionDeclaration(node, isDefault);
|
|
61
62
|
}
|
|
62
63
|
visitSource(node) {
|
|
63
64
|
this.mocked = new Set();
|
|
64
65
|
this.srcCurrent = node;
|
|
65
|
-
this.importFns = [];
|
|
66
66
|
super.visitSource(node);
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
67
|
+
const currentSource = this.srcCurrent;
|
|
68
|
+
if (!currentSource)
|
|
69
|
+
return;
|
|
70
|
+
const stmts = currentSource.statements;
|
|
71
|
+
for (let index = 0; index < stmts.length; index++) {
|
|
72
|
+
const node = stmts[index];
|
|
73
|
+
if (!isBodylessTopLevelFunction(node))
|
|
71
74
|
continue;
|
|
75
|
+
let path;
|
|
72
76
|
const dec = node.decorators?.find((v) => v.name.text == "external");
|
|
73
77
|
const decArgs = dec?.args ?? [];
|
|
74
78
|
if (!dec) {
|
|
@@ -85,24 +89,13 @@ export class MockTransform extends Visitor {
|
|
|
85
89
|
decArgs[0].value;
|
|
86
90
|
else
|
|
87
91
|
path = currentSource.simplePath + "." + node.name.text;
|
|
88
|
-
const stmts = currentSource.statements;
|
|
89
|
-
let index = -1;
|
|
90
|
-
for (let i = 0; i < stmts.length; i++) {
|
|
91
|
-
const stmt = stmts[i];
|
|
92
|
-
if (stmt instanceof FunctionDeclaration &&
|
|
93
|
-
stmt.name.text === node.name.text) {
|
|
94
|
-
index = i;
|
|
95
|
-
break;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
if (index === -1)
|
|
99
|
-
continue;
|
|
100
92
|
const registerImportTarget = Node.createExpressionStatement(Node.createCallExpression(Node.createPropertyAccessExpression(Node.createIdentifierExpression("__mock_import_target_by_index", node.range), Node.createIdentifierExpression("set", node.range), node.range), null, [
|
|
101
93
|
Node.createPropertyAccessExpression(Node.createIdentifierExpression(node.name.text, node.range), Node.createIdentifierExpression("index", node.range), node.range),
|
|
102
94
|
Node.createStringLiteralExpression(path, node.range),
|
|
103
95
|
], node.range));
|
|
104
96
|
if (!this.importMocked.has(path)) {
|
|
105
97
|
stmts.splice(index + 1, 0, registerImportTarget);
|
|
98
|
+
index++;
|
|
106
99
|
continue;
|
|
107
100
|
}
|
|
108
101
|
const args = [
|
|
@@ -115,9 +108,18 @@ export class MockTransform extends Visitor {
|
|
|
115
108
|
Node.createReturnStatement(Node.createCallExpression(Node.createIdentifierExpression("call_indirect", node.range), null, args, node.range), node.range),
|
|
116
109
|
], node.range), 0, node.range);
|
|
117
110
|
stmts.splice(index, 1, newFn, registerImportTarget);
|
|
111
|
+
index++;
|
|
118
112
|
}
|
|
119
113
|
}
|
|
120
114
|
}
|
|
115
|
+
function isBodylessTopLevelFunction(node) {
|
|
116
|
+
const candidate = node;
|
|
117
|
+
return (candidate != null &&
|
|
118
|
+
typeof candidate == "object" &&
|
|
119
|
+
candidate.name instanceof IdentifierExpression &&
|
|
120
|
+
"signature" in candidate &&
|
|
121
|
+
candidate.body == null);
|
|
122
|
+
}
|
|
121
123
|
function normalizeName(value) {
|
|
122
124
|
return value
|
|
123
125
|
.replaceAll(".", "_")
|
|
@@ -125,3 +127,24 @@ function normalizeName(value) {
|
|
|
125
127
|
.replaceAll("]", "_")
|
|
126
128
|
.replace(/[^A-Za-z0-9_]/g, "_");
|
|
127
129
|
}
|
|
130
|
+
function expressionName(node) {
|
|
131
|
+
const candidate = node;
|
|
132
|
+
if (!candidate || typeof candidate != "object")
|
|
133
|
+
return "";
|
|
134
|
+
if (typeof candidate.text == "string")
|
|
135
|
+
return candidate.text;
|
|
136
|
+
const propertyText = candidate.property?.text;
|
|
137
|
+
if (propertyText && candidate.expression) {
|
|
138
|
+
const left = expressionName(candidate.expression);
|
|
139
|
+
return left.length ? `${left}.${propertyText}` : propertyText;
|
|
140
|
+
}
|
|
141
|
+
const sourceText = candidate.range?.source?.text;
|
|
142
|
+
if (typeof sourceText == "string") {
|
|
143
|
+
const raw = sourceText
|
|
144
|
+
.slice(candidate.range.start, candidate.range.end)
|
|
145
|
+
.trim();
|
|
146
|
+
if (raw.length)
|
|
147
|
+
return raw;
|
|
148
|
+
}
|
|
149
|
+
return toString(candidate);
|
|
150
|
+
}
|