as-test 0.4.4 → 0.5.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.
Files changed (67) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/README.md +196 -82
  3. package/as-test.config.schema.json +137 -0
  4. package/assembly/coverage.ts +19 -0
  5. package/assembly/index.ts +172 -85
  6. package/assembly/src/expectation.ts +263 -199
  7. package/assembly/src/log.ts +1 -9
  8. package/assembly/src/suite.ts +61 -25
  9. package/assembly/src/tests.ts +2 -0
  10. package/assembly/util/wipc.ts +286 -0
  11. package/bin/build.js +86 -41
  12. package/bin/index.js +337 -68
  13. package/bin/init.js +441 -183
  14. package/bin/reporter.js +1 -1
  15. package/bin/reporters/default.js +379 -0
  16. package/bin/reporters/types.js +1 -0
  17. package/bin/run.js +882 -194
  18. package/bin/types.js +14 -7
  19. package/bin/util.js +54 -3
  20. package/package.json +34 -16
  21. package/transform/lib/builder.js +169 -169
  22. package/transform/lib/builder.js.map +1 -1
  23. package/transform/lib/coverage.js +47 -1
  24. package/transform/lib/coverage.js.map +1 -1
  25. package/transform/lib/index.js +70 -0
  26. package/transform/lib/index.js.map +1 -1
  27. package/transform/lib/location.js +20 -0
  28. package/transform/lib/location.js.map +1 -0
  29. package/transform/lib/log.js +118 -0
  30. package/transform/lib/log.js.map +1 -0
  31. package/transform/lib/mock.js +2 -2
  32. package/transform/lib/mock.js.map +1 -1
  33. package/transform/lib/util.js +3 -3
  34. package/transform/lib/util.js.map +1 -1
  35. package/.github/workflows/as-test.yml +0 -26
  36. package/.prettierrc +0 -3
  37. package/as-test.config.json +0 -19
  38. package/assembly/__tests__/array.spec.ts +0 -25
  39. package/assembly/__tests__/math.spec.ts +0 -16
  40. package/assembly/__tests__/mock.spec.ts +0 -22
  41. package/assembly/__tests__/mock.ts +0 -7
  42. package/assembly/__tests__/sleep.spec.ts +0 -28
  43. package/assembly/tsconfig.json +0 -97
  44. package/assets/img/screenshot.png +0 -0
  45. package/cli/build.ts +0 -117
  46. package/cli/index.ts +0 -190
  47. package/cli/init.ts +0 -247
  48. package/cli/reporter.ts +0 -1
  49. package/cli/run.ts +0 -286
  50. package/cli/tsconfig.json +0 -9
  51. package/cli/types.ts +0 -29
  52. package/cli/util.ts +0 -65
  53. package/run/package.json +0 -27
  54. package/tests/array.run.js +0 -7
  55. package/tests/math.run.js +0 -7
  56. package/tests/mock.run.js +0 -14
  57. package/tests/sleep.run.js +0 -7
  58. package/transform/src/builder.ts +0 -1474
  59. package/transform/src/coverage.ts +0 -580
  60. package/transform/src/index.ts +0 -73
  61. package/transform/src/linker.ts +0 -41
  62. package/transform/src/mock.ts +0 -163
  63. package/transform/src/range.ts +0 -12
  64. package/transform/src/types.ts +0 -35
  65. package/transform/src/util.ts +0 -81
  66. package/transform/src/visitor.ts +0 -744
  67. package/transform/tsconfig.json +0 -10
package/CHANGELOG.md CHANGED
@@ -1,5 +1,45 @@
1
1
  # Change Log
2
2
 
3
+ ## 2026-02-16 - v0.5.0
4
+
5
+ ### CLI & Runtime
6
+
7
+ - feat: `ast test` supports selectors by name, path, or glob and resolves bare names against configured spec directories.
8
+ - feat: `ast test` now runs per-file sequentially (`build #1 -> run #1 -> ...`) and prints one aggregated final summary.
9
+ - fix: `ast test` exits non-zero when no `.spec.ts` files match selectors/config input.
10
+ - fix: `ast build` is silent on success and only prints concise stderr details on failure.
11
+ - feat: add `--verbose` mode for expanded live suite/test status output without collapsing nodes.
12
+ - fix: suppress noisy Node WASI experimental warning lines during test execution.
13
+ - refactor: runtime config is `runOptions.runtime.cmd` (legacy `runtime.run` and `runOptions.run` remain supported).
14
+ - fix: if the configured runtime script path is missing, automatically fall back to the target default runner.
15
+
16
+ ### Reporter & API
17
+
18
+ - feat: add skip helpers `xdescribe`, `xtest`, `xit`, and `xexpect`.
19
+ - feat: include skipped counts for files, suites, and tests in final summaries.
20
+ - feat: add string boundary matchers `toStartWith()` and `toEndWith()`.
21
+ - feat: add `toBeTruthy()`, `toBeFalsy()`, `toBeCloseTo()`, `toMatch()`, optional message support in `expect(value, message)`, and snapshot matcher `toMatchSnapshot(name?)`.
22
+ - fix: improve assertion correctness across `.not`, type matcher labels, hook execution frequency, non-primitive `toBe()` handling, and failure source locations.
23
+
24
+ ### Coverage
25
+
26
+ - feat: add `--show-coverage` and support object-style coverage config (`{ enabled, includeSpecs }`).
27
+ - fix: limit coverage to source files (`.ts`/`.as`), excluding `node_modules` and AssemblyScript stdlib paths.
28
+ - fix: skip writing coverage artifacts when no valid source files remain after filtering.
29
+ - fix: dedupe identical coverage points across sequential runs and stabilize point/file ordering in reports.
30
+
31
+ ### Init, Config & Docs
32
+
33
+ - feat: `init` supports positional install directory (`as-test init ./path`) in addition to `--dir`.
34
+ - feat: `init` supports example modes (`minimal`, `full`, `none`) and scaffolds target-specific local runners.
35
+ - feat: WASI init adds `@assemblyscript/wasi-shim`; bindings init scaffolds `.as-test/runners/default.run.js`.
36
+ - refactor: default WASI runtime path is `./.as-test/runners/default.wasi.js`; generated runners are ESM-only.
37
+ - docs: refresh README and schema docs for current CLI behavior, config fields, runtime fallback, coverage, and reporter usage.
38
+
39
+ ### Tooling
40
+
41
+ - chore: add release validation workflow via `release:check` and tighten package publish file selection.
42
+
3
43
  ## 2025-05-28 - v0.4.4
4
44
 
5
45
  - deps: update json-as to `v1.1.13`
package/README.md CHANGED
@@ -1,138 +1,252 @@
1
- <h5 align="center">
2
- <pre>
3
- <span style="font-size: 0.8em;"> █████ ███████ ████████ ███████ ███████ ████████
4
- ██ ██ ██ ██ ██ ██ ██
5
- ███████ ███████ █████ ██ █████ ███████ ██
6
- ██ ██ ██ ██ ██ ██ ██
7
- ██ ██ ███████ ██ ███████ ███████ ██
8
- </span>
9
- AssemblyScript - v0.4.3
10
- </pre>
11
- </h5>
1
+ <h1 align="center"><pre>╔═╗ ╔═╗ ╔═╗ ╔═╗ ╔═╗ ╔═╗
2
+ ╠═╣ ╚═╗ ══ ║ ╠═ ╚═╗ ║
3
+ ╚═╝ ╩ ╚═╝ ╚═╝ </pre></h1>
12
4
 
13
- A lightweight testing framework for AssemblyScript.
5
+ <details>
6
+ <summary>Table of Contents</summary>
14
7
 
15
- 🔹 Minimal and fast – Run your tests without unnecessary overhead.
8
+ - [Installation](#installation)
9
+ - [Writing Tests](#writing-tests)
10
+ - [Snapshots](#snapshots)
11
+ - [Coverage](#coverage)
12
+ - [Custom Reporters](#custom-reporters)
13
+ - [Assertions](#assertions)
14
+ - [License](#license)
15
+ - [Contact](#contact)
16
16
 
17
- 🔹 Familiar API – Inspired by modern JavaScript testing frameworks.
17
+ </details>
18
18
 
19
- 🔹 Powerful mocking – Easily override functions and track calls.
20
-
21
- 🔹 Seamless CI/CD integration – Works effortlessly in automation pipelines.
22
-
23
- 🔹 Universal environment – Run your tests on any platform, runtime, or bindings.
24
-
25
- ## 💾 Installation
19
+ ## Installation
26
20
 
21
+ The installation script will set everything up for you:
27
22
  ```bash
28
- npm install as-test
29
- npm intall json-as
23
+ npx as-test init --dir ./path-to-install
30
24
  ```
31
25
 
32
- Initialize your test setup with:
33
-
26
+ Alternatively, you can install it manually:
34
27
  ```bash
35
- as-test init
28
+ npm install as-test --save-dev
36
29
  ```
37
30
 
38
- This creates a test directory at `assembly/__tests__/` with a sample test file.
39
-
40
- ## 📝 Writing Tests
31
+ ## Writing Tests
41
32
 
42
- Create a new test file in `assembly/__tests__/`, for example, `math.spec.ts`:
33
+ Create `assembly/__tests__/math.spec.ts`:
43
34
 
44
- ```js
35
+ ```ts
45
36
  import { describe, test, expect, run } from "as-test";
46
37
 
47
- describe("Math operations", () => {
48
- test("Addition", () => {
38
+ describe("math", () => {
39
+ test("addition", () => {
49
40
  expect(1 + 2).toBe(3);
50
41
  });
51
42
 
52
- test("Subtraction", () => {
53
- expect(5 - 2).toBe(3);
54
- });
55
-
56
- test("Multiplication", () => {
57
- expect(3 * 3).toBe(9);
43
+ test("close to", () => {
44
+ expect(3.14159).toBeCloseTo(3.14, 2);
58
45
  });
59
46
  });
60
-
61
- run();
62
47
  ```
63
48
 
64
- ## 🔍 Examples
49
+ ### Test file selection (`ast test`)
65
50
 
66
- ### 🏗️ Mocking Functions
51
+ No selectors:
67
52
 
68
- Use `mockFn` to override functions during testing:
53
+ ```bash
54
+ ast test
55
+ ```
69
56
 
70
- ```js
71
- import { mockFn } from "as-test";
57
+ Uses configured input patterns from `as-test.config.json`.
72
58
 
73
- // Mock console.log
74
- mockFn<void>("console.log", (data: string): void => {
75
- console.log("[MOCKED]: " + data);
76
- });
59
+ By name:
77
60
 
78
- run();
61
+ ```bash
62
+ ast test sleep
79
63
  ```
80
64
 
81
- Or override imported functions with `mockImport`.
65
+ Resolves to `<configured-input-dir>/sleep.spec.ts`.
82
66
 
83
- ### ⚒️ Setup and Teardown
67
+ By explicit path or glob:
84
68
 
85
- Use `beforeAll` and `afterAll` to run code before and after a test is run.
69
+ ```bash
70
+ ast test ./assembly/__tests__/sleep.spec.ts
71
+ ast test ./assembly/__tests__/*.spec.ts
72
+ ```
86
73
 
87
- ```js
88
- import { beforeAll, afterAll } from "as-test";
74
+ Multiple selectors:
89
75
 
90
- beforeAll(() => {
91
- log("Setting up test environment...");
92
- });
76
+ ```bash
77
+ ast test sleep array ./assembly/__tests__/snapshot.spec.ts
78
+ ```
93
79
 
94
- afterAll(() => {
95
- log("Tearing down test environment...");
96
- });
80
+ If nothing matches, `ast test` exits non-zero with:
97
81
 
98
- run();
82
+ ```text
83
+ No test files matched: ...
99
84
  ```
100
85
 
101
- ### 📃 Pretty Logging
86
+ ### Useful flags
102
87
 
103
- Using `console.log` will mess up the terminal output. Instead, use the inbuilt `log` function:
88
+ - `--config <path>`: use another config file
89
+ - `--update-snapshots`: write snapshot updates
90
+ - `--no-snapshot`: disable snapshot assertions for the run
91
+ - `--show-coverage`: print uncovered coverage points
92
+ - `--verbose`: keep expanded suite/test lines and update running `....` statuses in place
104
93
 
105
- ```js
106
- import { log } from "as-test";
94
+ ## Snapshots
95
+
96
+ Snapshot assertions are enabled by default.
97
+
98
+ - Read-only mode (default): missing/mismatched snapshots fail
99
+ - Update mode: `--update-snapshots` writes missing/mismatched snapshots
107
100
 
108
- log("This is a pretty log function");
101
+ Commands:
109
102
 
110
- run();
103
+ ```bash
104
+ ast test --update-snapshots
105
+ ast run --update-snapshots
106
+ ast test --no-snapshot
111
107
  ```
112
108
 
113
- Or override all existing `console.log` calls with `log`:
109
+ Snapshot files are stored in `snapshotDir` (default `./.as-test/snapshots`).
114
110
 
115
- ```js
116
- import { mockFn, log } from "as-test";
111
+ ## Coverage
117
112
 
118
- mockFn<void>("console.log", (data: string): void => {
119
- log(data);
120
- });
113
+ Coverage is controlled by `coverage` in config.
114
+ Coverage reporting includes source files ending in `.ts` or `.as` only.
115
+
116
+ - Boolean form:
117
+ - `true` / `false`
118
+ - Object form:
119
+ - `{ "enabled": true, "includeSpecs": false }`
120
+
121
+ Default behavior includes non-spec files and excludes `*.spec.ts` files.
121
122
 
122
- run();
123
+ Show point-level misses:
124
+
125
+ ```bash
126
+ ast test --show-coverage
123
127
  ```
124
128
 
125
- ### 🔄 Running Tests in CI
129
+ Coverage artifacts:
130
+
131
+ - `ast run` writes `coverage.log.json` to `coverageDir` (if enabled and not `"none"`)
132
+ - `ast test` writes per-file coverage artifacts (`coverage.<file>.log.json`)
133
+
134
+ Log artifacts:
135
+
136
+ - `ast run` writes `test.log.json` to `logs` (if `logs` is not `"none"`)
137
+ - `ast test` writes per-file logs (`test.<file>.log.json`)
138
+
139
+ ## Configuration
140
+
141
+ Default file: `as-test.config.json`
142
+
143
+ Example:
144
+
145
+ ```json
146
+ {
147
+ "$schema": "./as-test.config.schema.json",
148
+ "input": ["./assembly/__tests__/*.spec.ts"],
149
+ "outDir": "./.as-test/build",
150
+ "logs": "./.as-test/logs",
151
+ "coverageDir": "./.as-test/coverage",
152
+ "snapshotDir": "./.as-test/snapshots",
153
+ "config": "none",
154
+ "coverage": true,
155
+ "buildOptions": {
156
+ "args": [],
157
+ "target": "wasi"
158
+ },
159
+ "runOptions": {
160
+ "runtime": {
161
+ "cmd": "node ./.as-test/runners/default.wasi.js <file>"
162
+ },
163
+ "reporter": ""
164
+ }
165
+ }
166
+ ```
126
167
 
127
- To integrate `as-test` into your CI/CD workflow, see the [example configuration](https://github.com/JairusSW/as-test/blob/main/.github/workflows/as-test.yml).
168
+ Key fields:
128
169
 
129
- `assembly/__tests__/example.spec.ts`
170
+ - `input`: glob list of spec files
171
+ - `outDir`: compiled wasm output dir
172
+ - `logs`: log output dir or `"none"`
173
+ - `coverageDir`: coverage output dir or `"none"`
174
+ - `snapshotDir`: snapshot storage dir
175
+ - `buildOptions.target`: `wasi` or `bindings`
176
+ - `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
177
+ - `runOptions.reporter`: optional custom reporter module path
130
178
 
131
- ## 📃 License
179
+ ## Custom Reporter
132
180
 
133
- This project is distributed under an open source license. You can view the full license using the following link: [License](./LICENSE)
181
+ Set reporter path in config:
182
+
183
+ ```json
184
+ {
185
+ "runOptions": {
186
+ "reporter": "./tests/my-reporter.js"
187
+ }
188
+ }
189
+ ```
190
+
191
+ Reporter module should export `createReporter` (named or default):
192
+
193
+ ```js
194
+ export function createReporter(context) {
195
+ return {
196
+ onRunStart(event) {},
197
+ onFileStart(event) {},
198
+ onFileEnd(event) {},
199
+ onSuiteStart(event) {},
200
+ onSuiteEnd(event) {},
201
+ onAssertionFail(event) {},
202
+ onSnapshotMissing(event) {},
203
+ onRunComplete(event) {},
204
+ };
205
+ }
206
+ ```
134
207
 
135
- ## 📫 Contact
208
+ ## Assertions
209
+
210
+ Skip helpers:
211
+
212
+ - `xdescribe(name, fn)`
213
+ - `xtest(name, fn)`
214
+ - `xit(name, fn)`
215
+ - `xexpect(value)`
216
+
217
+ Available matchers:
218
+
219
+ - `toBe(expected)`
220
+ - `toBeNull()`
221
+ - `toBeGreaterThan(value)`
222
+ - `toBeGreaterOrEqualTo(value)`
223
+ - `toBeLessThan(value)`
224
+ - `toBeLessThanOrEqualTo(value)`
225
+ - `toBeString()`
226
+ - `toBeBoolean()`
227
+ - `toBeArray()`
228
+ - `toBeNumber()`
229
+ - `toBeInteger()`
230
+ - `toBeFloat()`
231
+ - `toBeFinite()`
232
+ - `toBeTruthy()`
233
+ - `toBeFalsy()`
234
+ - `toBeCloseTo(expected, precision = 2)`
235
+ - `toMatch(substring)`
236
+ - `toStartWith(prefix)`
237
+ - `toEndWith(suffix)`
238
+ - `toHaveLength(length)`
239
+ - `toContain(item)`
240
+ - `toThrow()` (with `try-as`)
241
+ - `toMatchSnapshot(name?)`
242
+
243
+ ## License
244
+
245
+ This project is distributed under an open source license. Work on this project is done by passion, but if you want to support it financially, you can do so by making a donation to the project's [GitHub Sponsors](https://github.com/sponsors/JairusSW) page.
246
+
247
+ You can view the full license using the following link: [License](./LICENSE)
248
+
249
+ ## Contact
136
250
 
137
251
  Please send all issues to [GitHub Issues](https://github.com/JairusSW/as-test/issues) and to converse, please send me an email at [me@jairus.dev](mailto:me@jairus.dev)
138
252
 
@@ -0,0 +1,137 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/JairusSW/as-test/blob/main/as-test.config.schema.json",
4
+ "title": "as-test configuration",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "properties": {
8
+ "$schema": {
9
+ "type": "string",
10
+ "description": "JSON Schema reference for editor validation/autocomplete."
11
+ },
12
+ "input": {
13
+ "type": "array",
14
+ "description": "Glob patterns for test specification files.",
15
+ "items": {
16
+ "type": "string"
17
+ },
18
+ "default": ["./assembly/__tests__/*.spec.ts"]
19
+ },
20
+ "outDir": {
21
+ "type": "string",
22
+ "description": "Directory where compiled artifacts are written.",
23
+ "default": "./.as-test/build"
24
+ },
25
+ "logs": {
26
+ "description": "Directory for log artifacts, or \"none\" to disable.",
27
+ "oneOf": [
28
+ {
29
+ "type": "string"
30
+ },
31
+ {
32
+ "const": "none"
33
+ }
34
+ ],
35
+ "default": "./.as-test/logs"
36
+ },
37
+ "coverageDir": {
38
+ "description": "Directory for coverage artifacts, or \"none\" to disable writing coverage files.",
39
+ "oneOf": [
40
+ {
41
+ "type": "string"
42
+ },
43
+ {
44
+ "const": "none"
45
+ }
46
+ ],
47
+ "default": "./.as-test/coverage"
48
+ },
49
+ "snapshotDir": {
50
+ "type": "string",
51
+ "description": "Directory for snapshot files written by snapshot assertions.",
52
+ "default": "./.as-test/snapshots"
53
+ },
54
+ "config": {
55
+ "type": "string",
56
+ "description": "Reserved config field used by existing projects.",
57
+ "default": "none"
58
+ },
59
+ "coverage": {
60
+ "description": "Coverage settings. Use a boolean for quick toggle or object for options.",
61
+ "oneOf": [
62
+ {
63
+ "type": "boolean"
64
+ },
65
+ {
66
+ "type": "object",
67
+ "additionalProperties": true,
68
+ "properties": {
69
+ "enabled": {
70
+ "type": "boolean",
71
+ "default": true
72
+ },
73
+ "includeSpecs": {
74
+ "type": "boolean",
75
+ "description": "Include *.spec.ts files in coverage collection.",
76
+ "default": false
77
+ }
78
+ }
79
+ }
80
+ ],
81
+ "default": true
82
+ },
83
+ "buildOptions": {
84
+ "type": "object",
85
+ "additionalProperties": false,
86
+ "properties": {
87
+ "args": {
88
+ "type": "array",
89
+ "items": {
90
+ "type": "string"
91
+ },
92
+ "default": []
93
+ },
94
+ "target": {
95
+ "type": "string",
96
+ "enum": ["wasi", "bindings"],
97
+ "default": "wasi"
98
+ }
99
+ },
100
+ "default": {
101
+ "args": [],
102
+ "target": "wasi"
103
+ }
104
+ },
105
+ "runOptions": {
106
+ "type": "object",
107
+ "additionalProperties": false,
108
+ "properties": {
109
+ "runtime": {
110
+ "type": "object",
111
+ "additionalProperties": false,
112
+ "properties": {
113
+ "cmd": {
114
+ "type": "string",
115
+ "description": "Runtime command; supports placeholders like <file> and <name>.",
116
+ "default": "node ./.as-test/runners/default.wasi.js <file>"
117
+ }
118
+ },
119
+ "default": {
120
+ "cmd": "node ./.as-test/runners/default.wasi.js <file>"
121
+ }
122
+ },
123
+ "reporter": {
124
+ "type": "string",
125
+ "description": "Optional path to a custom reporter module.",
126
+ "default": ""
127
+ }
128
+ },
129
+ "default": {
130
+ "runtime": {
131
+ "cmd": "node ./.as-test/runners/default.wasi.js <file>"
132
+ },
133
+ "reporter": ""
134
+ }
135
+ }
136
+ }
137
+ }
@@ -8,17 +8,28 @@ export class CoverPoint {
8
8
  }
9
9
 
10
10
  export class Coverage {
11
+ public all: CoverPoint[] = [];
12
+ public allIndex: Map<string, i32> = new Map<string, i32>();
11
13
  public hashes: Map<string, CoverPoint> = new Map<string, CoverPoint>();
12
14
  public points: i32 = 0;
13
15
  static SN: Coverage = new Coverage();
14
16
  }
15
17
 
16
18
  export function __REGISTER(point: CoverPoint): void {
19
+ if (Coverage.SN.allIndex.has(point.hash)) return;
17
20
  Coverage.SN.points++;
21
+ Coverage.SN.allIndex.set(point.hash, Coverage.SN.all.length);
22
+ Coverage.SN.all.push(point);
18
23
  Coverage.SN.hashes.set(point.hash, point);
19
24
  }
20
25
 
21
26
  export function __COVER(hash: string): void {
27
+ if (Coverage.SN.allIndex.has(hash)) {
28
+ const index = Coverage.SN.allIndex.get(hash);
29
+ if (index < Coverage.SN.all.length) {
30
+ unchecked(Coverage.SN.all[index]).executed = true;
31
+ }
32
+ }
22
33
  if (Coverage.SN.hashes.has(hash)) Coverage.SN.hashes.delete(hash);
23
34
  }
24
35
 
@@ -29,3 +40,11 @@ export function __HASHES(): Map<string, CoverPoint> {
29
40
  export function __POINTS(): i32 {
30
41
  return Coverage.SN.points;
31
42
  }
43
+
44
+ export function __UNCOVERED(): i32 {
45
+ return Coverage.SN.hashes.size;
46
+ }
47
+
48
+ export function __ALL_POINTS(): CoverPoint[] {
49
+ return Coverage.SN.all;
50
+ }