as-test 1.0.1 → 1.0.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/CHANGELOG.md +112 -1
- package/README.md +138 -406
- package/as-test.config.schema.json +210 -17
- package/assembly/__fuzz__/array.fuzz.ts +10 -0
- package/assembly/__fuzz__/bytes.fuzz.ts +8 -0
- package/assembly/__fuzz__/math.fuzz.ts +9 -0
- package/assembly/__fuzz__/string.fuzz.ts +21 -0
- package/assembly/index.ts +141 -86
- package/assembly/src/expectation.ts +104 -19
- package/assembly/src/fuzz.ts +723 -0
- package/assembly/src/log.ts +6 -1
- package/assembly/src/suite.ts +45 -3
- package/assembly/util/json.ts +38 -4
- package/assembly/util/wipc.ts +35 -26
- package/bin/build-worker-pool.js +149 -0
- package/bin/build-worker.js +43 -0
- package/bin/commands/build-core.js +214 -28
- package/bin/commands/build.js +1 -0
- package/bin/commands/fuzz-core.js +306 -0
- package/bin/commands/fuzz.js +10 -0
- package/bin/commands/init-core.js +129 -24
- package/bin/commands/run-core.js +525 -123
- package/bin/commands/run.js +4 -1
- package/bin/commands/test.js +8 -3
- package/bin/commands/web-runner-source.js +634 -0
- package/bin/crash-store.js +64 -0
- package/bin/index.js +1484 -169
- package/bin/reporters/default.js +281 -49
- package/bin/reporters/tap.js +83 -2
- package/bin/types.js +19 -2
- package/bin/util.js +315 -33
- package/bin/wipc.js +79 -0
- package/package.json +19 -9
- package/transform/lib/coverage.js +1 -2
- package/transform/lib/index.js +3 -3
- package/transform/lib/log.js +1 -1
package/README.md
CHANGED
|
@@ -7,17 +7,15 @@
|
|
|
7
7
|
|
|
8
8
|
- [Why as-test](#why-as-test)
|
|
9
9
|
- [Installation](#installation)
|
|
10
|
-
- [
|
|
10
|
+
- [Docs](#docs)
|
|
11
|
+
- [Project Layout](#project-layout)
|
|
11
12
|
- [Writing Tests](#writing-tests)
|
|
12
|
-
- [Setup Diagnostics](#setup-diagnostics)
|
|
13
13
|
- [Mocking](#mocking)
|
|
14
14
|
- [Snapshots](#snapshots)
|
|
15
|
-
- [
|
|
16
|
-
- [
|
|
17
|
-
- [
|
|
18
|
-
- [CLI Style Guide](#cli-style-guide)
|
|
15
|
+
- [Fuzzing](#fuzzing)
|
|
16
|
+
- [Runtimes](#runtimes)
|
|
17
|
+
- [Examples](#examples)
|
|
19
18
|
- [License](#license)
|
|
20
|
-
- [Contact](#contact)
|
|
21
19
|
|
|
22
20
|
</details>
|
|
23
21
|
|
|
@@ -34,353 +32,249 @@ Key benefits
|
|
|
34
32
|
- Production-like testing: catch runtime-specific issues early
|
|
35
33
|
- Inline mocking and snapshots
|
|
36
34
|
- Custom reporters and coverage
|
|
35
|
+
- Integrated fuzzing support
|
|
37
36
|
|
|
38
37
|
## Installation
|
|
39
38
|
|
|
40
|
-
The
|
|
41
|
-
```bash
|
|
42
|
-
npx as-test init --dir ./path-to-install
|
|
43
|
-
```
|
|
39
|
+
The easiest way to start is with the project initializer:
|
|
44
40
|
|
|
45
|
-
To scaffold and install dependencies in one step:
|
|
46
41
|
```bash
|
|
47
|
-
npx as-test init
|
|
42
|
+
npx as-test init
|
|
48
43
|
```
|
|
49
44
|
|
|
50
|
-
|
|
45
|
+
That gives you a basic config file, a sample test, and optionally a sample fuzzer.
|
|
46
|
+
|
|
47
|
+
If you already have a project and just want the package:
|
|
48
|
+
|
|
51
49
|
```bash
|
|
52
|
-
npm install
|
|
50
|
+
npm install --save-dev as-test
|
|
53
51
|
```
|
|
54
52
|
|
|
55
|
-
##
|
|
53
|
+
## Docs
|
|
56
54
|
|
|
57
|
-
Full
|
|
55
|
+
Full documentation lives at:
|
|
58
56
|
|
|
59
|
-
-
|
|
60
|
-
- complete spec files for core features
|
|
61
|
-
- import mocking and import snapshot patterns
|
|
57
|
+
<https://docs.jairus.dev/as-test>
|
|
62
58
|
|
|
63
|
-
|
|
59
|
+
## Project Layout
|
|
64
60
|
|
|
65
|
-
|
|
61
|
+
By default, `as-test` looks for:
|
|
66
62
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
63
|
+
- tests in `assembly/__tests__`
|
|
64
|
+
- fuzzers in `assembly/__fuzz__`
|
|
65
|
+
- config in `as-test.config.json`
|
|
66
|
+
|
|
67
|
+
Generated files go into `.as-test/`.
|
|
71
68
|
|
|
72
69
|
## Writing Tests
|
|
73
70
|
|
|
74
|
-
|
|
71
|
+
Tests usually live in `assembly/__tests__/*.spec.ts`.
|
|
72
|
+
|
|
73
|
+
Example:
|
|
75
74
|
|
|
76
75
|
```ts
|
|
77
|
-
import { describe,
|
|
76
|
+
import { describe, expect, test } from "as-test";
|
|
78
77
|
|
|
79
78
|
describe("math", () => {
|
|
80
|
-
test("
|
|
79
|
+
test("adds numbers", () => {
|
|
81
80
|
expect(1 + 2).toBe(3);
|
|
82
81
|
});
|
|
83
|
-
|
|
84
|
-
test("close to", () => {
|
|
85
|
-
expect(3.14159).toBeCloseTo(3.14, 2);
|
|
86
|
-
});
|
|
87
82
|
});
|
|
88
83
|
```
|
|
89
84
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
No selectors:
|
|
85
|
+
Run everything:
|
|
93
86
|
|
|
94
87
|
```bash
|
|
95
|
-
ast test
|
|
88
|
+
npx ast test
|
|
96
89
|
```
|
|
97
90
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
By name:
|
|
91
|
+
Run through the automatic worker pool:
|
|
101
92
|
|
|
102
93
|
```bash
|
|
103
|
-
ast test
|
|
94
|
+
npx ast test --parallel
|
|
104
95
|
```
|
|
105
96
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
By explicit path or glob:
|
|
97
|
+
Run one matching file:
|
|
109
98
|
|
|
110
99
|
```bash
|
|
111
|
-
ast test
|
|
112
|
-
ast test ./assembly/__tests__/*.spec.ts
|
|
100
|
+
npx ast test math
|
|
113
101
|
```
|
|
114
102
|
|
|
115
|
-
|
|
103
|
+
You do not need to learn every CLI flag to get started. Most projects can begin with `npx ast test`, then add more configuration only when they need it.
|
|
116
104
|
|
|
117
|
-
|
|
118
|
-
ast test sleep array ./assembly/__tests__/snapshot.spec.ts
|
|
119
|
-
```
|
|
105
|
+
## Mocking
|
|
120
106
|
|
|
121
|
-
|
|
107
|
+
Mocking is supported, but the idea is to use it sparingly.
|
|
122
108
|
|
|
123
|
-
|
|
124
|
-
ast test box,custom,generics,string
|
|
125
|
-
ast run box,custom,generics,string
|
|
126
|
-
ast build box,custom,generics,string
|
|
127
|
-
```
|
|
109
|
+
With `as-test`, the ideal path is to run your code against the real runtime and real imports when you can. When that is not practical, you can mock individual imports instead of rebuilding your whole environment around fake behavior.
|
|
128
110
|
|
|
129
|
-
|
|
111
|
+
For local functions, use `mockFn` and `unmockFn`. For host imports, use `mockImport` and `unmockImport`.
|
|
130
112
|
|
|
131
|
-
|
|
132
|
-
No test files matched: ...
|
|
133
|
-
```
|
|
113
|
+
That is especially useful when:
|
|
134
114
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
-
|
|
138
|
-
- `--mode <name[,name...]>`: run one or multiple named config modes (if omitted and `modes` is configured, as-test runs all configured modes)
|
|
139
|
-
- `--update-snapshots`: write snapshot updates
|
|
140
|
-
- `--no-snapshot`: disable snapshot assertions for the run
|
|
141
|
-
- `--show-coverage`: print uncovered coverage points
|
|
142
|
-
- `--enable <feature>`: enable as-test feature (`coverage`, `try-as`)
|
|
143
|
-
- `--disable <feature>`: disable as-test feature (`coverage`, `try-as`)
|
|
144
|
-
- `--verbose`: keep expanded suite/test lines and update running `....` statuses in place
|
|
145
|
-
- `--clean`: disable in-place TTY updates and print only final per-file verdict lines. Useful for CI/CD.
|
|
146
|
-
- `--list`: show resolved files, per-mode artifacts, and runtime command without executing
|
|
147
|
-
- `--list-modes`: show configured and selected modes without executing
|
|
148
|
-
- `--help` / `-h`: show command-specific help (`ast test --help`, `ast init --help`, etc.)
|
|
115
|
+
- an import talks to the outside world
|
|
116
|
+
- a host function is hard to reproduce in a test
|
|
117
|
+
- you want to force an edge case that is difficult to trigger naturally
|
|
149
118
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
```bash
|
|
153
|
-
ast build --enable try-as
|
|
154
|
-
ast test --disable coverage
|
|
155
|
-
```
|
|
119
|
+
This keeps tests focused. You can still verify the logic in your AssemblyScript code without needing every runtime dependency to be real in every test. It also pairs well with snapshots when you want to capture the output of a mocked import and make sure it stays stable over time.
|
|
156
120
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
```bash
|
|
160
|
-
ast test --list
|
|
161
|
-
ast test --list-modes
|
|
162
|
-
ast run sleep --list --mode wasi
|
|
163
|
-
ast build --list --mode wasi,bindings
|
|
164
|
-
```
|
|
121
|
+
Example:
|
|
165
122
|
|
|
166
|
-
|
|
123
|
+
```ts
|
|
124
|
+
import { describe, expect, mockFn, test, unmockFn } from "as-test";
|
|
167
125
|
|
|
168
|
-
|
|
126
|
+
function getConfig(): string {
|
|
127
|
+
return "name=prod\nmode=live";
|
|
128
|
+
}
|
|
169
129
|
|
|
170
|
-
|
|
171
|
-
ast doctor
|
|
172
|
-
```
|
|
130
|
+
mockFn(getConfig, (): string => "name=demo\nmode=test");
|
|
173
131
|
|
|
174
|
-
|
|
132
|
+
describe("config", () => {
|
|
133
|
+
test("reads mocked data", () => {
|
|
134
|
+
expect(getConfig()).toContain("demo");
|
|
135
|
+
});
|
|
136
|
+
});
|
|
175
137
|
|
|
176
|
-
|
|
177
|
-
ast doctor --config ./as-test.config.json --mode wasi,bindings
|
|
138
|
+
unmockFn(getConfig);
|
|
178
139
|
```
|
|
179
140
|
|
|
180
|
-
|
|
141
|
+
For import mocking, the same idea applies, but it is usually easier to keep the imported function in a small wrapper module and mock that import path from the spec.
|
|
181
142
|
|
|
182
|
-
|
|
183
|
-
- required dependencies (for example `assemblyscript`, `@assemblyscript/wasi-shim` for WASI targets)
|
|
184
|
-
- runtime command parsing and executable availability
|
|
185
|
-
- runtime script path existence (for script-host runtimes)
|
|
186
|
-
- test spec file discovery from configured input patterns
|
|
143
|
+
## Snapshots
|
|
187
144
|
|
|
188
|
-
|
|
145
|
+
Snapshots are useful when the output matters more than the exact step-by-step assertions.
|
|
189
146
|
|
|
190
|
-
|
|
147
|
+
They work well for:
|
|
191
148
|
|
|
192
|
-
|
|
149
|
+
- generated strings or structured text
|
|
150
|
+
- serialized values
|
|
151
|
+
- the output of mocked imports
|
|
152
|
+
- larger results that would be awkward to check field by field
|
|
193
153
|
|
|
194
|
-
|
|
195
|
-
- `unmockFn(oldFn)`: stops that rewrite for subsequent calls
|
|
196
|
-
- `mockImport("module.field", fn)`: sets the runtime mock for an external import
|
|
197
|
-
- `unmockImport("module.field")`: clears the runtime mock for an external import
|
|
198
|
-
- `snapshotImport<T = Function | string>(imp: T, version: string | i32)`: snapshots a single import mock
|
|
199
|
-
- `snapshotImport<T = Function | string>(imp: T, capture: () => unknown)`: runs `capture` and snapshots using version `"default"`
|
|
200
|
-
- `restoreImport<T = Function | string>(imp: T, version: string | i32)`: restores a single import mock
|
|
154
|
+
That lets you keep tests readable while still locking down behavior that should not change unexpectedly.
|
|
201
155
|
|
|
202
156
|
Example:
|
|
203
157
|
|
|
204
158
|
```ts
|
|
205
|
-
import {
|
|
206
|
-
expect,
|
|
207
|
-
it,
|
|
208
|
-
mockFn,
|
|
209
|
-
mockImport,
|
|
210
|
-
restoreImport,
|
|
211
|
-
run,
|
|
212
|
-
snapshotImport,
|
|
213
|
-
unmockFn,
|
|
214
|
-
unmockImport,
|
|
215
|
-
} from "as-test";
|
|
216
|
-
import { foo } from "./mock";
|
|
217
|
-
|
|
218
|
-
mockImport("mock.foo", (): string => "buz");
|
|
219
|
-
mockFn(foo, (): string => "baz " + foo());
|
|
220
|
-
|
|
221
|
-
it("mocked function", () => {
|
|
222
|
-
expect(foo()).toBe("baz buz");
|
|
223
|
-
});
|
|
159
|
+
import { describe, expect, test } from "as-test";
|
|
224
160
|
|
|
225
|
-
|
|
161
|
+
function renderReport(): string {
|
|
162
|
+
return "name=demo\nmode=test";
|
|
163
|
+
}
|
|
226
164
|
|
|
227
|
-
|
|
228
|
-
|
|
165
|
+
describe("report", () => {
|
|
166
|
+
test("matches the saved output", () => {
|
|
167
|
+
expect(renderReport()).toMatchSnapshot();
|
|
168
|
+
});
|
|
229
169
|
});
|
|
230
|
-
|
|
231
|
-
snapshotImport(foo, 1);
|
|
232
|
-
mockImport("mock.foo", (): string => "temp");
|
|
233
|
-
snapshotImport("mock.foo", "v2");
|
|
234
|
-
restoreImport(foo, 1);
|
|
235
|
-
|
|
236
|
-
snapshotImport("mock.foo", () => foo()); // snapshots to version "default"
|
|
237
|
-
restoreImport("mock.foo", "default");
|
|
238
|
-
|
|
239
|
-
unmockImport("mock.foo");
|
|
240
|
-
mockImport("mock.foo", (): string => "buz");
|
|
241
|
-
|
|
242
|
-
run();
|
|
243
170
|
```
|
|
244
171
|
|
|
245
|
-
|
|
172
|
+
The first time you run a snapshot test, create the snapshot with:
|
|
246
173
|
|
|
247
|
-
|
|
174
|
+
```bash
|
|
175
|
+
npx ast test --create-snapshots
|
|
176
|
+
```
|
|
248
177
|
|
|
249
|
-
|
|
250
|
-
- Update mode: `--update-snapshots` writes missing/mismatched snapshots
|
|
178
|
+
After that, a normal `npx ast test` will verify it.
|
|
251
179
|
|
|
252
|
-
|
|
180
|
+
If an existing snapshot legitimately changed, overwrite it with:
|
|
253
181
|
|
|
254
182
|
```bash
|
|
255
|
-
ast test --
|
|
256
|
-
ast run --update-snapshots
|
|
257
|
-
ast test --no-snapshot
|
|
183
|
+
npx ast test --overwrite-snapshots
|
|
258
184
|
```
|
|
259
185
|
|
|
260
|
-
|
|
186
|
+
## Fuzzing
|
|
187
|
+
|
|
188
|
+
Fuzzers usually live in `assembly/__fuzz__/*.fuzz.ts`.
|
|
189
|
+
|
|
190
|
+
Example:
|
|
261
191
|
|
|
262
|
-
|
|
192
|
+
```ts
|
|
193
|
+
import { expect, FuzzSeed, fuzz } from "as-test";
|
|
194
|
+
|
|
195
|
+
fuzz("bounded integer addition", (left: i32, right: i32): bool => {
|
|
196
|
+
const sum = left + right;
|
|
197
|
+
expect(sum - right).toBe(left);
|
|
198
|
+
return sum >= i32.MIN_VALUE;
|
|
199
|
+
}).generate((seed: FuzzSeed, run: (left: i32, right: i32) => bool): void => {
|
|
200
|
+
run(seed.i32({ min: -1000, max: 1000 }), seed.i32({ min: -1000, max: 1000 }));
|
|
201
|
+
});
|
|
202
|
+
```
|
|
263
203
|
|
|
264
|
-
|
|
265
|
-
Coverage reporting includes source files ending in `.ts` or `.as` only.
|
|
204
|
+
If you used `npx ast init` with a fuzzer example, the config is already there. Otherwise, add a `fuzz` block to `as-test.config.json` so `npx ast fuzz` knows what to build:
|
|
266
205
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
206
|
+
```json
|
|
207
|
+
{
|
|
208
|
+
"fuzz": {
|
|
209
|
+
"input": ["./assembly/__fuzz__/*.fuzz.ts"],
|
|
210
|
+
"target": "bindings"
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
```
|
|
271
214
|
|
|
272
|
-
|
|
215
|
+
`ast fuzz` runs fuzz files across the selected modes, reports one result per file, and keeps the final summary separate from the normal test totals. If you want one combined command, use `ast test --fuzz`.
|
|
273
216
|
|
|
274
|
-
|
|
217
|
+
Run only fuzzers:
|
|
275
218
|
|
|
276
219
|
```bash
|
|
277
|
-
ast
|
|
220
|
+
npx ast fuzz
|
|
278
221
|
```
|
|
279
222
|
|
|
280
|
-
|
|
223
|
+
Run tests and fuzzers together:
|
|
281
224
|
|
|
282
|
-
|
|
283
|
-
|
|
225
|
+
```bash
|
|
226
|
+
npx ast test --fuzz
|
|
227
|
+
```
|
|
284
228
|
|
|
285
|
-
|
|
229
|
+
Fuzzing is there when you want broader input coverage, but it does not get in the way of the normal test flow. You can start with ordinary specs and add fuzzers later.
|
|
286
230
|
|
|
287
|
-
|
|
288
|
-
- `ast test` writes per-file logs (`test.<file>.log.json`)
|
|
231
|
+
## Runtimes
|
|
289
232
|
|
|
290
|
-
|
|
233
|
+
One of the main reasons to use `as-test` is that you are not locked into a single runtime.
|
|
291
234
|
|
|
292
|
-
|
|
235
|
+
If your project runs under WASI, bindings, or a custom runner, you can point your tests at that environment instead of treating Node.js as the only way to execute them.
|
|
293
236
|
|
|
294
|
-
|
|
237
|
+
For example, a simple WASI setup in `as-test.config.json` can look like this:
|
|
295
238
|
|
|
296
239
|
```json
|
|
297
240
|
{
|
|
298
|
-
"$schema": "./as-test.config.schema.json",
|
|
299
241
|
"input": ["./assembly/__tests__/*.spec.ts"],
|
|
300
|
-
"output": "./.as-test/",
|
|
301
|
-
"config": "none",
|
|
302
|
-
"coverage": true,
|
|
303
|
-
"env": {},
|
|
304
242
|
"buildOptions": {
|
|
305
|
-
"cmd": "",
|
|
306
|
-
"args": [],
|
|
307
243
|
"target": "wasi"
|
|
308
244
|
},
|
|
309
|
-
"modes": {},
|
|
310
245
|
"runOptions": {
|
|
311
246
|
"runtime": {
|
|
312
247
|
"cmd": "node ./.as-test/runners/default.wasi.js <file>"
|
|
313
|
-
}
|
|
314
|
-
"reporter": ""
|
|
248
|
+
}
|
|
315
249
|
}
|
|
316
250
|
}
|
|
317
251
|
```
|
|
318
252
|
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
- `outDir`: compiled wasm output dir
|
|
324
|
-
- `logs`: log output dir or `"none"`
|
|
325
|
-
- `coverageDir`: coverage output dir or `"none"`
|
|
326
|
-
- `snapshotDir`: snapshot storage dir
|
|
327
|
-
- `outDir`, `logs`, `coverageDir`, and `snapshotDir` still work; when both are set, these explicit fields override `output`
|
|
328
|
-
- `env`: environment variables injected into build and runtime processes
|
|
329
|
-
- `buildOptions.cmd`: optional custom build command template; when set it replaces default build command and flags. Supports `<file>`, `<name>`, `<outFile>`, `<target>`, `<mode>`
|
|
330
|
-
- `buildOptions.target`: `wasi` or `bindings`
|
|
331
|
-
- `modes`: named overrides for command/target/args/runtime/env/artifact directories (selected via `--mode`); `mode.env` overrides top-level `env`
|
|
332
|
-
- `runOptions.runtime.cmd`: runtime command, supports `<file>` and `<name>`; if its script path is missing, as-test falls back to the default runner for the selected target
|
|
333
|
-
- `runOptions.reporter`: reporter selection as a string or object
|
|
334
|
-
|
|
335
|
-
Validation behavior:
|
|
336
|
-
|
|
337
|
-
- Config parsing is strict for `ast build`, `ast run`, `ast test`, and `ast doctor`.
|
|
338
|
-
- Invalid JSON fails early with parser details (`line`/`column` when provided by Node).
|
|
339
|
-
- Unknown properties are rejected and include a nearest-key suggestion when possible.
|
|
340
|
-
- Invalid property types are reported with their JSON path and a short fix hint.
|
|
341
|
-
- On validation failure, the command exits non-zero and prints `run "ast doctor" to check your setup.`
|
|
342
|
-
|
|
343
|
-
Example validation error:
|
|
344
|
-
|
|
345
|
-
```text
|
|
346
|
-
invalid config at ./as-test.config.json
|
|
347
|
-
1. $.inpoot: unknown property
|
|
348
|
-
fix: use "input" if that was intended, otherwise remove this property
|
|
349
|
-
2. $.runOptions.runtime.cmd: must be a string
|
|
350
|
-
fix: set to a runtime command including "<file>"
|
|
351
|
-
run "ast doctor" to check your setup.
|
|
253
|
+
Then run your tests normally:
|
|
254
|
+
|
|
255
|
+
```bash
|
|
256
|
+
npx ast test
|
|
352
257
|
```
|
|
353
258
|
|
|
354
|
-
|
|
259
|
+
If you want to keep more than one runtime around, use modes:
|
|
355
260
|
|
|
356
261
|
```json
|
|
357
262
|
{
|
|
263
|
+
"input": ["./assembly/__tests__/*.spec.ts"],
|
|
358
264
|
"modes": {
|
|
359
|
-
"wasi
|
|
360
|
-
"buildOptions": {
|
|
361
|
-
"target": "wasi",
|
|
362
|
-
"args": ["--enable", "simd"]
|
|
363
|
-
},
|
|
364
|
-
"runOptions": {
|
|
365
|
-
"runtime": {
|
|
366
|
-
"cmd": "wasmer run <file>"
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
},
|
|
370
|
-
"wasi-nosimd": {
|
|
265
|
+
"wasi": {
|
|
371
266
|
"buildOptions": {
|
|
372
267
|
"target": "wasi"
|
|
373
268
|
},
|
|
374
269
|
"runOptions": {
|
|
375
270
|
"runtime": {
|
|
376
|
-
"cmd": "
|
|
271
|
+
"cmd": "node ./.as-test/runners/default.wasi.js <file>"
|
|
377
272
|
}
|
|
378
273
|
}
|
|
379
274
|
},
|
|
380
|
-
"bindings
|
|
275
|
+
"bindings": {
|
|
381
276
|
"buildOptions": {
|
|
382
|
-
"target": "bindings"
|
|
383
|
-
"args": ["--enable", "simd"]
|
|
277
|
+
"target": "bindings"
|
|
384
278
|
},
|
|
385
279
|
"runOptions": {
|
|
386
280
|
"runtime": {
|
|
@@ -392,185 +286,23 @@ Example multi-runtime matrix:
|
|
|
392
286
|
}
|
|
393
287
|
```
|
|
394
288
|
|
|
395
|
-
Run
|
|
289
|
+
Run a specific mode with:
|
|
396
290
|
|
|
397
291
|
```bash
|
|
398
|
-
ast test --mode wasi
|
|
399
|
-
```
|
|
400
|
-
|
|
401
|
-
Summary totals:
|
|
402
|
-
|
|
403
|
-
- `Modes` in the default reporter is config-scoped (`total` is all configured modes)
|
|
404
|
-
- when selecting fewer modes with `--mode`, unselected modes are counted as `skipped`
|
|
405
|
-
- `Files` in the default reporter is also config-scoped (`total` is all files from configured input patterns)
|
|
406
|
-
- when selecting fewer files, unselected files are counted as `skipped`
|
|
407
|
-
|
|
408
|
-
When using `--mode`, compiled artifacts are emitted as:
|
|
409
|
-
|
|
410
|
-
```text
|
|
411
|
-
<test-name>.<mode>.<target>.wasm
|
|
292
|
+
npx ast test --mode wasi
|
|
412
293
|
```
|
|
413
294
|
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
```text
|
|
417
|
-
math.wasi-simd.wasi.wasm
|
|
418
|
-
math.bindings-node-simd.bindings.wasm
|
|
419
|
-
```
|
|
420
|
-
|
|
421
|
-
Bindings runner naming:
|
|
422
|
-
|
|
423
|
-
- preferred: `./.as-test/runners/default.bindings.js`
|
|
424
|
-
- deprecated but supported: `./.as-test/runners/default.run.js`
|
|
425
|
-
|
|
426
|
-
`ast init` now scaffolds both local runners:
|
|
427
|
-
|
|
428
|
-
- `.as-test/runners/default.wasi.js`
|
|
429
|
-
- `.as-test/runners/default.bindings.js`
|
|
430
|
-
|
|
431
|
-
## Custom Reporters
|
|
432
|
-
|
|
433
|
-
Built-in TAP reporter (useful for CI, including GitHub Actions):
|
|
295
|
+
or
|
|
434
296
|
|
|
435
297
|
```bash
|
|
436
|
-
ast
|
|
298
|
+
npx ast test --mode wasi,bindings
|
|
437
299
|
```
|
|
438
300
|
|
|
439
|
-
|
|
301
|
+
This is the general idea throughout the project: write tests once, then choose the runtime that matches how your code actually runs.
|
|
440
302
|
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
```json
|
|
444
|
-
{
|
|
445
|
-
"runOptions": {
|
|
446
|
-
"reporter": "tap"
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
```
|
|
450
|
-
|
|
451
|
-
Or with reporter object config:
|
|
452
|
-
|
|
453
|
-
```json
|
|
454
|
-
{
|
|
455
|
-
"runOptions": {
|
|
456
|
-
"reporter": {
|
|
457
|
-
"name": "tap",
|
|
458
|
-
"options": ["single-file"],
|
|
459
|
-
"outDir": "./.as-test/reports"
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
```
|
|
464
|
-
|
|
465
|
-
`options` supports `single-file` (default) and `per-file`.
|
|
466
|
-
|
|
467
|
-
Single-file explicit path:
|
|
468
|
-
|
|
469
|
-
```json
|
|
470
|
-
{
|
|
471
|
-
"runOptions": {
|
|
472
|
-
"reporter": {
|
|
473
|
-
"name": "tap",
|
|
474
|
-
"outFile": "./.as-test/reports/report.tap"
|
|
475
|
-
}
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
```
|
|
479
|
-
|
|
480
|
-
In GitHub Actions, failed TAP points emit `::error` annotations with file and line when available.
|
|
481
|
-
|
|
482
|
-
Example GitHub workflow (Bun + Wasmtime + TAP summary):
|
|
483
|
-
|
|
484
|
-
```yaml
|
|
485
|
-
name: Run Tests
|
|
486
|
-
|
|
487
|
-
on: [push, pull_request]
|
|
488
|
-
|
|
489
|
-
jobs:
|
|
490
|
-
build:
|
|
491
|
-
runs-on: ubuntu-latest
|
|
492
|
-
steps:
|
|
493
|
-
- uses: actions/checkout@v4
|
|
494
|
-
- uses: jcbhmr/setup-wasmtime@v2
|
|
495
|
-
- uses: oven-sh/setup-bun@v1
|
|
496
|
-
- run: bun install
|
|
497
|
-
- run: bun run test --update-snapshots --tap
|
|
498
|
-
- uses: test-summary/action@v2
|
|
499
|
-
if: always()
|
|
500
|
-
with:
|
|
501
|
-
paths: ".as-test/reports/*.tap"
|
|
502
|
-
```
|
|
503
|
-
|
|
504
|
-
Set reporter path in config:
|
|
505
|
-
|
|
506
|
-
```json
|
|
507
|
-
{
|
|
508
|
-
"runOptions": {
|
|
509
|
-
"reporter": "./tests/my-reporter.js"
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
```
|
|
513
|
-
|
|
514
|
-
It's even possible to use something like [tap-summary](https://github.com/zoubin/tap-summary) to summarize the test results!
|
|
515
|
-
|
|
516
|
-
```bash
|
|
517
|
-
npm install -g tap-summary
|
|
518
|
-
ast test --reporter tap | tap-summary
|
|
519
|
-
```
|
|
520
|
-
|
|
521
|
-
Reporter module should export `createReporter` (named or default):
|
|
522
|
-
|
|
523
|
-
```js
|
|
524
|
-
export function createReporter(context) {
|
|
525
|
-
return {
|
|
526
|
-
onRunStart(event) {},
|
|
527
|
-
onFileStart(event) {},
|
|
528
|
-
onFileEnd(event) {},
|
|
529
|
-
onSuiteStart(event) {},
|
|
530
|
-
onSuiteEnd(event) {},
|
|
531
|
-
onAssertionFail(event) {},
|
|
532
|
-
onSnapshotMissing(event) {},
|
|
533
|
-
onRunComplete(event) {},
|
|
534
|
-
};
|
|
535
|
-
}
|
|
536
|
-
```
|
|
303
|
+
## Examples
|
|
537
304
|
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
## Assertions
|
|
541
|
-
|
|
542
|
-
Skip helpers:
|
|
543
|
-
|
|
544
|
-
- `xdescribe(name, fn)`
|
|
545
|
-
- `xtest(name, fn)`
|
|
546
|
-
- `xit(name, fn)`
|
|
547
|
-
- `xexpect(value)`
|
|
548
|
-
|
|
549
|
-
Available matchers:
|
|
550
|
-
|
|
551
|
-
- `toBe(expected)`
|
|
552
|
-
- `toBeNull()`
|
|
553
|
-
- `toBeGreaterThan(value)`
|
|
554
|
-
- `toBeGreaterOrEqualTo(value)`
|
|
555
|
-
- `toBeLessThan(value)`
|
|
556
|
-
- `toBeLessThanOrEqualTo(value)`
|
|
557
|
-
- `toBeString()`
|
|
558
|
-
- `toBeBoolean()`
|
|
559
|
-
- `toBeArray()`
|
|
560
|
-
- `toBeNumber()`
|
|
561
|
-
- `toBeInteger()`
|
|
562
|
-
- `toBeFloat()`
|
|
563
|
-
- `toBeFinite()`
|
|
564
|
-
- `toBeTruthy()`
|
|
565
|
-
- `toBeFalsy()`
|
|
566
|
-
- `toBeCloseTo(expected, precision = 2)`
|
|
567
|
-
- `toMatch(substring)`
|
|
568
|
-
- `toStartWith(prefix)`
|
|
569
|
-
- `toEndWith(suffix)`
|
|
570
|
-
- `toHaveLength(length)`
|
|
571
|
-
- `toContain(itemOrSubstring)` (`toContains` alias supported)
|
|
572
|
-
- `toThrow()` (with `try-as`)
|
|
573
|
-
- `toMatchSnapshot(name?)`
|
|
305
|
+
Runnable example projects live in [examples/](./examples/README.md). They are useful if you want to see complete setups instead of isolated snippets.
|
|
574
306
|
|
|
575
307
|
## License
|
|
576
308
|
|
|
@@ -580,9 +312,9 @@ You can view the full license using the following link: [License](./LICENSE)
|
|
|
580
312
|
|
|
581
313
|
## Contact
|
|
582
314
|
|
|
583
|
-
Please send all issues to [GitHub Issues](https://github.com/JairusSW/as
|
|
315
|
+
Please send all issues to [GitHub Issues](https://github.com/JairusSW/json-as/issues) and to converse, please send me an email at [me@jairus.dev](mailto:me@jairus.dev)
|
|
584
316
|
|
|
585
317
|
- **Email:** Send me inquiries, questions, or requests at [me@jairus.dev](mailto:me@jairus.dev)
|
|
586
|
-
- **GitHub:** Visit the official GitHub repository [Here](https://github.com/JairusSW/as
|
|
318
|
+
- **GitHub:** Visit the official GitHub repository [Here](https://github.com/JairusSW/json-as)
|
|
587
319
|
- **Website:** Visit my official website at [jairus.dev](https://jairus.dev/)
|
|
588
320
|
- **Discord:** Contact me at [My Discord](https://discord.com/users/600700584038760448) or on the [AssemblyScript Discord Server](https://discord.gg/assemblyscript/)
|