vitest-pool-assemblyscript 0.2.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/BINARYEN_VERSION +1 -0
- package/LICENSE +53 -0
- package/README.md +607 -0
- package/assembly/compare.ts +219 -0
- package/assembly/describe.ts +104 -0
- package/assembly/expect.ts +335 -0
- package/assembly/index.ts +14 -0
- package/assembly/options.ts +198 -0
- package/assembly/test.ts +147 -0
- package/assembly/tsconfig.json +6 -0
- package/binding.gyp +62 -0
- package/dist/ast-visitor-DC3SuTzs.mjs +310 -0
- package/dist/ast-visitor-DC3SuTzs.mjs.map +1 -0
- package/dist/compile-runner-8h0dBwG2.mjs +80 -0
- package/dist/compile-runner-8h0dBwG2.mjs.map +1 -0
- package/dist/compiler/transforms/strip-inline.d.mts +18 -0
- package/dist/compiler/transforms/strip-inline.d.mts.map +1 -0
- package/dist/compiler/transforms/strip-inline.mjs +38 -0
- package/dist/compiler/transforms/strip-inline.mjs.map +1 -0
- package/dist/compiler-CN6BRK_N.mjs +295 -0
- package/dist/compiler-CN6BRK_N.mjs.map +1 -0
- package/dist/config/index-v3.d.mts +111 -0
- package/dist/config/index-v3.d.mts.map +1 -0
- package/dist/config/index-v3.mjs +11 -0
- package/dist/config/index-v3.mjs.map +1 -0
- package/dist/config/index.d.mts +4 -0
- package/dist/config/index.mjs +8 -0
- package/dist/constants-CA50WBdr.mjs +130 -0
- package/dist/constants-CA50WBdr.mjs.map +1 -0
- package/dist/coverage-merge-0WqdC-dq.mjs +22 -0
- package/dist/coverage-merge-0WqdC-dq.mjs.map +1 -0
- package/dist/coverage-provider/index.d.mts +15 -0
- package/dist/coverage-provider/index.d.mts.map +1 -0
- package/dist/coverage-provider/index.mjs +535 -0
- package/dist/coverage-provider/index.mjs.map +1 -0
- package/dist/custom-provider-options-CF5C1kXb.d.mts +26 -0
- package/dist/custom-provider-options-CF5C1kXb.d.mts.map +1 -0
- package/dist/debug-IeEHsxy0.mjs +195 -0
- package/dist/debug-IeEHsxy0.mjs.map +1 -0
- package/dist/index-internal.d.mts +23 -0
- package/dist/index-internal.d.mts.map +1 -0
- package/dist/index-internal.mjs +4 -0
- package/dist/index-v3.d.mts +7 -0
- package/dist/index-v3.d.mts.map +1 -0
- package/dist/index-v3.mjs +206 -0
- package/dist/index-v3.mjs.map +1 -0
- package/dist/index.d.mts +3 -0
- package/dist/index.mjs +8 -0
- package/dist/load-user-imports-J9eaAW0_.mjs +801 -0
- package/dist/load-user-imports-J9eaAW0_.mjs.map +1 -0
- package/dist/pool-runner-init-CEwLyNI3.d.mts +8 -0
- package/dist/pool-runner-init-CEwLyNI3.d.mts.map +1 -0
- package/dist/pool-runner-init-d5qScS41.mjs +400 -0
- package/dist/pool-runner-init-d5qScS41.mjs.map +1 -0
- package/dist/pool-thread/compile-worker-thread.d.mts +7 -0
- package/dist/pool-thread/compile-worker-thread.d.mts.map +1 -0
- package/dist/pool-thread/compile-worker-thread.mjs +42 -0
- package/dist/pool-thread/compile-worker-thread.mjs.map +1 -0
- package/dist/pool-thread/test-worker-thread.d.mts +7 -0
- package/dist/pool-thread/test-worker-thread.d.mts.map +1 -0
- package/dist/pool-thread/test-worker-thread.mjs +39 -0
- package/dist/pool-thread/test-worker-thread.mjs.map +1 -0
- package/dist/pool-thread/v3-tinypool-thread.d.mts +7 -0
- package/dist/pool-thread/v3-tinypool-thread.d.mts.map +1 -0
- package/dist/pool-thread/v3-tinypool-thread.mjs +57 -0
- package/dist/pool-thread/v3-tinypool-thread.mjs.map +1 -0
- package/dist/resolve-config-as1w-Qyz.mjs +65 -0
- package/dist/resolve-config-as1w-Qyz.mjs.map +1 -0
- package/dist/test-runner-B2BpyPNK.mjs +142 -0
- package/dist/test-runner-B2BpyPNK.mjs.map +1 -0
- package/dist/types-8KKo9Hbf.d.mts +228 -0
- package/dist/types-8KKo9Hbf.d.mts.map +1 -0
- package/dist/vitest-file-tasks-BUwzh375.mjs +61 -0
- package/dist/vitest-file-tasks-BUwzh375.mjs.map +1 -0
- package/dist/vitest-tasks-BKS7689f.mjs +319 -0
- package/dist/vitest-tasks-BKS7689f.mjs.map +1 -0
- package/dist/worker-rpc-channel-lbhK7Qz8.mjs +25 -0
- package/dist/worker-rpc-channel-lbhK7Qz8.mjs.map +1 -0
- package/package.json +112 -0
- package/prebuilds/linux-x64/vitest-pool-assemblyscript.glibc.node +0 -0
- package/scripts/install.js +91 -0
- package/scripts/setup-binaryen.js +179 -0
- package/src/native-instrumentation/addon.cpp +788 -0
package/BINARYEN_VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
version_124
|
package/LICENSE
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 - 2026 Matt Ritter
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
|
23
|
+
===============================================================================
|
|
24
|
+
|
|
25
|
+
Portions of this software have been derived from third-party works which are
|
|
26
|
+
licenced under different terms. Individual code contributions have been
|
|
27
|
+
noted where applicable and are accompanied by their respective licenses.
|
|
28
|
+
|
|
29
|
+
Additionally, the following third-party works are utilized:
|
|
30
|
+
|
|
31
|
+
* AssemblyScript: https://github.com/AssemblyScript/assemblyscript
|
|
32
|
+
|
|
33
|
+
Apache License, Version 2.0 (https://opensource.org/licenses/Apache-2.0)
|
|
34
|
+
|
|
35
|
+
* TypeScript: https://github.com/Microsoft/TypeScript
|
|
36
|
+
|
|
37
|
+
Copyright (c) Microsoft Corporation
|
|
38
|
+
Apache License, Version 2.0 (https://opensource.org/licenses/Apache-2.0)
|
|
39
|
+
|
|
40
|
+
* Binaryen: https://github.com/WebAssembly/binaryen
|
|
41
|
+
|
|
42
|
+
Copyright (c) WebAssembly Community Group participants
|
|
43
|
+
Apache License, Version 2.0 (https://opensource.org/licenses/Apache-2.0)
|
|
44
|
+
|
|
45
|
+
* source-map: https://github.com/mozilla/source-map
|
|
46
|
+
|
|
47
|
+
Copyright (c) 2009-2011, Mozilla Foundation and contributors
|
|
48
|
+
BSD Licence, 3-Clause Version (https://opensource.org/license/bsd-3-clause)
|
|
49
|
+
|
|
50
|
+
* istanbul-lib-coverage: https://github.com/istanbuljs/istanbuljs
|
|
51
|
+
|
|
52
|
+
Copyright 2012-2015 Yahoo! Inc.
|
|
53
|
+
BSD Licence, 3-Clause Version (https://opensource.org/license/bsd-3-clause)
|
package/README.md
ADDED
|
@@ -0,0 +1,607 @@
|
|
|
1
|
+
# vitest-pool-assemblyscript
|
|
2
|
+
|
|
3
|
+
AssemblyScript unit testing for your Vitest workflow: Simple, fast, familiar, AS-native.
|
|
4
|
+
|
|
5
|
+
This is a [Vitest](https://vitest.dev) ["custom pool"](https://vitest.dev/guide/advanced/pool.html) which knows how to compile AssemblyScript to WASM, harness WASM to run tests, and report those results to vitest. It co-exists with existing JavaScript/TypeScript tests, and is designed for incremental adoption.
|
|
6
|
+
|
|
7
|
+
- [Quickstart](#quickstart)
|
|
8
|
+
- [Features](#features)
|
|
9
|
+
- [Configuration](#configuration)
|
|
10
|
+
- [Writing Tests](#writing-tests)
|
|
11
|
+
- [Matcher API](#matcher-api)
|
|
12
|
+
- [Project Status & Expectations](#project-status--expectations)
|
|
13
|
+
- [Installation Guide (Development Preview)](#installation-guide-development-preview)
|
|
14
|
+
|
|
15
|
+
**Note: 🚧 This project is currently *Pre-Release, Pre-v1, Under Active Development* 🚧**
|
|
16
|
+
- See [Project Status & Expectations](#project-status--expectations) for what's working now, and to see what's planned!
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Quickstart
|
|
21
|
+
|
|
22
|
+
Coming Soon!
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Features
|
|
27
|
+
|
|
28
|
+
### Vitest Integration
|
|
29
|
+
- Use familiar `vitest` commands, CLI spec and test filtering, watch mode
|
|
30
|
+
- Works with Vitest UI, reporters, and coverage tools
|
|
31
|
+
- Project (workspace) config allows coexisting AssemblyScript pools and JavaScript pools
|
|
32
|
+
- Hybrid Coverage Provider unifies test reports from multiple pools (delegating to v8 for JS/TS coverage)
|
|
33
|
+
- Coverage reporting using any vitest reporter (`html`, `lcov`, `json`, etc)
|
|
34
|
+
- Dual vitest 3.x / 4.x support
|
|
35
|
+
|
|
36
|
+
### Per-Test WASM Isolation
|
|
37
|
+
- Each AssemblyScript test file is compiled to a WASM binary once
|
|
38
|
+
- Each test case runs in a fresh WASM instance (reusing the compiled binary)
|
|
39
|
+
- One crashing test doesn't kill the rest within the same suite
|
|
40
|
+
- `toThrowError()` matcher can be used to catch and expect specific errors (which trap and abort)
|
|
41
|
+
|
|
42
|
+
### Familiar Developer Experience
|
|
43
|
+
- Suite and test definition using `describe()` and `test()` in AssemblyScript
|
|
44
|
+
- Inline test option configuration for common vitest options: `timeout`, `retry`, `skip`, `only`, `fails`
|
|
45
|
+
- Assertion matching API based on vitest/jest `expect()` API. See [Matcher API](#matcher-api) for the set of supported matchers and differences from JavaScript
|
|
46
|
+
- Highlighted diffs for assertion and runtime failures, which point to source code
|
|
47
|
+
- Source-mapped WASM error stack traces (accurate source `function file:line:column`)
|
|
48
|
+
- AssemblyScript console output captured and provided to vitest for display
|
|
49
|
+
- No boilerplate patterns for: `run()`, `endTest()`, `fs.readFile`, `WebAssembly.Instance`, etc
|
|
50
|
+
|
|
51
|
+
### Performance & Customization
|
|
52
|
+
- Parallel execution thread pool
|
|
53
|
+
- Lightweight coverage instrumentation using separate memory
|
|
54
|
+
- In-memory binaries and source maps for minimal file I/O
|
|
55
|
+
- Coverage for inlined (`@inline`) code
|
|
56
|
+
- Enforced hard timeouts for long-running WASM via thread termination, with intelligent resume
|
|
57
|
+
- Configurable AssemblyScript compiler options
|
|
58
|
+
- Configurable test memory size
|
|
59
|
+
- Configurable WASM imports with access to memory
|
|
60
|
+
|
|
61
|
+
### Why This Over [Alternative]?
|
|
62
|
+
|
|
63
|
+
There are other standalone testing frameworks for AssemblyScript testing, including:
|
|
64
|
+
- [assemblyscript-unittest-framework](https://github.com/wasm-ecosystem/assemblyscript-unittest-framework): A full-featured AS test framework
|
|
65
|
+
- Many thanks owed to this project for inspiring parts of our discovery and instrumentation approach
|
|
66
|
+
- [as-test](https://github.com/JairusSW/as-test): A minimal and fast AssemblyScript test framework and runner
|
|
67
|
+
- [Built with AssemblyScript - Testing & Benchmarking](https://www.assemblyscript.org/built-with-assemblyscript.html#testing-benchmarking) may track more
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Configuration
|
|
72
|
+
|
|
73
|
+
In your project's `vitest.config.ts`:
|
|
74
|
+
- The `test` project configuration helpers needed depend on which version of vitest you're using.
|
|
75
|
+
- The `coverage` configuration is the same across versions (shown in the first example below).
|
|
76
|
+
|
|
77
|
+
### vitest 4.x.x Multiple-Project Config:
|
|
78
|
+
```typescript
|
|
79
|
+
import { defineConfig, defineProject } from 'vitest/config';
|
|
80
|
+
import { createAssemblyScriptPool } from 'vitest-pool-assemblyscript/config';
|
|
81
|
+
|
|
82
|
+
export default defineConfig({
|
|
83
|
+
test: {
|
|
84
|
+
projects: [
|
|
85
|
+
// AssemblyScript project
|
|
86
|
+
defineProject({
|
|
87
|
+
test: {
|
|
88
|
+
name: {
|
|
89
|
+
label: 'assemblyscript-tests',
|
|
90
|
+
color: 'yellow'
|
|
91
|
+
},
|
|
92
|
+
include: ['test/assembly/**/*.as.{test,spec}.ts'],
|
|
93
|
+
|
|
94
|
+
// supported vitest options
|
|
95
|
+
bail: 2, // stop test run after this many failures
|
|
96
|
+
retry: 0, // number of retries to attempt after initial failure
|
|
97
|
+
testTimeout: 500, // ms to wait before terminating test
|
|
98
|
+
// allowOnly: true, // whether or not to respect test.only and describe.only
|
|
99
|
+
// maxWorkers: 8, // concurrent file execution threads (default: available parallelism)
|
|
100
|
+
|
|
101
|
+
// configure vitest to use this custom pool for test files in `include`
|
|
102
|
+
pool: createAssemblyScriptPool({
|
|
103
|
+
stripInline: true, // true to remove @inline decorators for coverage (default: true)
|
|
104
|
+
testMemoryPagesInitial: 2, // initial WASM memory size in pages (default: 1)
|
|
105
|
+
testMemoryPagesMax: 4, // maximum WASM memory size in pages (default: undefined)
|
|
106
|
+
extraCompilerFlags: ['--runtime', 'incremental'], // additional asc flags to customize AS compilation
|
|
107
|
+
wasmImportsFactory: 'test-helpers/create-imports.js', // factory function to create your own WASM imports
|
|
108
|
+
}),
|
|
109
|
+
}
|
|
110
|
+
}),
|
|
111
|
+
|
|
112
|
+
// JavaScript/TypeScript project
|
|
113
|
+
defineProject({
|
|
114
|
+
test: {
|
|
115
|
+
name: {
|
|
116
|
+
label: 'javascript-typescript-tests',
|
|
117
|
+
color: 'blue'
|
|
118
|
+
},
|
|
119
|
+
include: ['test/js/*.{test,spec}.{ts,js}'],
|
|
120
|
+
}
|
|
121
|
+
}),
|
|
122
|
+
]
|
|
123
|
+
},
|
|
124
|
+
|
|
125
|
+
// Coverage config must be at root level (applies to all projects).
|
|
126
|
+
// The "hybrid" provider delegates JS to v8, and merges AS coverage into the final report
|
|
127
|
+
coverage: {
|
|
128
|
+
provider: 'custom',
|
|
129
|
+
customProviderModule: 'vitest-pool-assemblyscript/coverage',
|
|
130
|
+
assemblyScriptInclude: ['assembly/**/*.ts'], // example, include AS sources to report on
|
|
131
|
+
assemblyScriptExclude: ['assembly/helpers/*.ts'], // example, exclude AS sources from reporting
|
|
132
|
+
|
|
133
|
+
// all other v8 coverage options will be passed through to delegated v8 provider
|
|
134
|
+
enabled: true,
|
|
135
|
+
cleanOnRerun: true,
|
|
136
|
+
reportsDirectory: './coverage',
|
|
137
|
+
reporter: ['text', 'lcov', 'html'],
|
|
138
|
+
include: ['src/**/*.ts'], // example, include JS/TS sources to report on
|
|
139
|
+
},
|
|
140
|
+
});
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### vitest 4.x.x Single-Project Config:
|
|
144
|
+
```typescript
|
|
145
|
+
import { defineConfig } from 'vitest/config';
|
|
146
|
+
import { createAssemblyScriptPool } from 'vitest-pool-assemblyscript/config';
|
|
147
|
+
|
|
148
|
+
export default defineConfig({
|
|
149
|
+
test: {
|
|
150
|
+
pool: createAssemblyScriptPool({
|
|
151
|
+
// no change to available options (stripInline, testMemoryPagesInitial, etc)
|
|
152
|
+
}),
|
|
153
|
+
},
|
|
154
|
+
coverage: {
|
|
155
|
+
// no change to available options
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### vitest 3.2.x Multiple-Project Config:
|
|
161
|
+
```typescript
|
|
162
|
+
import { defineConfig, defineProject } from 'vitest/config';
|
|
163
|
+
import { defineAssemblyScriptProject } from 'vitest-pool-assemblyscript/config';
|
|
164
|
+
|
|
165
|
+
export default defineConfig({
|
|
166
|
+
test: {
|
|
167
|
+
projects: [
|
|
168
|
+
defineProject({
|
|
169
|
+
test: {
|
|
170
|
+
// JS/TS project config...
|
|
171
|
+
}
|
|
172
|
+
}),
|
|
173
|
+
defineAssemblyScriptProject({
|
|
174
|
+
test: {
|
|
175
|
+
// AS project config... (standard name/label, include, etc)
|
|
176
|
+
|
|
177
|
+
pool: 'vitest-pool-assemblyscript/v3', // in v3, point to the module
|
|
178
|
+
poolOptions: {
|
|
179
|
+
assemblyScript: {
|
|
180
|
+
// same available options as v4 createAssemblyScriptPool are passed here
|
|
181
|
+
|
|
182
|
+
// Additonal - v3 Only
|
|
183
|
+
// maxThreadsV3: 8 // concurrent test file threads to execute (default: availableParallelism - 1)
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
})
|
|
188
|
+
]
|
|
189
|
+
},
|
|
190
|
+
|
|
191
|
+
});
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### vitest 3.2.x Single-Project Config:
|
|
195
|
+
```typescript
|
|
196
|
+
import { defineAssemblyScriptConfig } from 'vitest-pool-assemblyscript/config';
|
|
197
|
+
|
|
198
|
+
export default defineAssemblyScriptConfig({
|
|
199
|
+
test: {
|
|
200
|
+
pool: 'vitest-pool-assemblyscript/v3',
|
|
201
|
+
poolOptions: {
|
|
202
|
+
assemblyScript: {
|
|
203
|
+
// same available options as v4 createAssemblyScriptPool and v3 multi-project
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
},
|
|
207
|
+
});
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### Framework-Provided Imports
|
|
211
|
+
|
|
212
|
+
**`console`**
|
|
213
|
+
The pool provides the full implementation of the [AssemblyScript `console` interface](https://www.assemblyscript.org/stdlib/console.html). This means you can transparently use `console.log("some string")` in your tests, and the output will be fed to vitest and displayed with the test results.
|
|
214
|
+
|
|
215
|
+
If you prefer to do something else with your test console output, you may provide your own versions of these functions to the "env" module - See the next section for details on how to do this.
|
|
216
|
+
|
|
217
|
+
**`trace`**
|
|
218
|
+
The pool also provides an implementation for `trace`, which passes through to Node `console.trace()` immediately for debugging.
|
|
219
|
+
|
|
220
|
+
**`abort`**
|
|
221
|
+
The pool handles assertion errors, runtime errors, and expected throws by providing an abort handler. This cannot be user-overridden.
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
### User-Provided Imports with `WasmImportsFactory`
|
|
225
|
+
To provide your own WebAssembly imports, configure `wasmImportsFactory` to point to an ES module which exports a factory function to create your imports:
|
|
226
|
+
```typescript
|
|
227
|
+
// v4
|
|
228
|
+
// ...
|
|
229
|
+
pool: createAssemblyScriptPool({
|
|
230
|
+
wasmImportsFactory: 'test-helpers/create-imports.js',
|
|
231
|
+
})
|
|
232
|
+
// ...
|
|
233
|
+
|
|
234
|
+
// v3
|
|
235
|
+
// ...
|
|
236
|
+
poolOptions: {
|
|
237
|
+
assemblyScript: {
|
|
238
|
+
wasmImportsFactory: 'test-helpers/create-imports.js',
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
// ...
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
The type signature for this function looks like this:
|
|
245
|
+
```typescript
|
|
246
|
+
type WasmImportsFactory = (moduleInfo: WasmImportsFactoryInfo) => WebAssembly.Imports;
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
And the `moduleInfo` argument that it is provided with looks like this:
|
|
250
|
+
```typescript
|
|
251
|
+
interface WasmImportsFactoryInfo {
|
|
252
|
+
module: WebAssembly.Module;
|
|
253
|
+
memory: WebAssembly.Memory;
|
|
254
|
+
utils: {
|
|
255
|
+
// convenience function for extracting returned strings from WASM memory
|
|
256
|
+
liftString: (stringPtr: number) => string | undefined;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
You may provide imports for any module name you wish. Here is an example factory function which uses the "env" module:
|
|
262
|
+
```js
|
|
263
|
+
export default function createWasmImports({ memory, module, utils }) {
|
|
264
|
+
return {
|
|
265
|
+
env: {
|
|
266
|
+
parseIntStringFunction: (inputStrPtr) => {
|
|
267
|
+
return parseInt(utils.liftString(inputStrPtr));
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
Example AssemblyScript source code which uses this imported function (the "env" module name is specified):
|
|
275
|
+
```typescript
|
|
276
|
+
@external("env", "parseIntStringFunction")
|
|
277
|
+
declare function parseIntStringFunction(input: string): i32;
|
|
278
|
+
|
|
279
|
+
export function runParseIntStringFunction(input: string): i32 {
|
|
280
|
+
return parseIntStringFunction(input);
|
|
281
|
+
}
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
#### Module Names
|
|
285
|
+
If you omit the module name in `@external` (e.g. `@external("parseIntStringFunction")`) or omit `@external` entirely, AssemblyScript uses the source file's own name (without the last file extension) as the module name, making it impractical to provide matching imports to every source file independently if you use imported functions across multiple places in your source. It is recommended to always specify a shared module name (such as "env") for this reason.
|
|
286
|
+
|
|
287
|
+
Conversely, if you need to provide imports targeted to a specific source file, this behavior provides a way to do that as well. For example, if you have a source AS file called `my-file.as.ts` with `declare function myFunc(input: string): i32;` in it and omit the `@external` decorator, then you can import the function *only to this file* with:
|
|
288
|
+
```js
|
|
289
|
+
export default function createWasmImports({ utils }) {
|
|
290
|
+
return {
|
|
291
|
+
// default source file module name (omits the .ts extension)
|
|
292
|
+
'my-file.as': {
|
|
293
|
+
myFunc: (inputStrPtr) => {
|
|
294
|
+
return parseInt(utils.liftString(inputStrPtr));
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
## Writing Tests
|
|
304
|
+
|
|
305
|
+
Import `test`, `describe`, `expect` (and `TestOptions` if needed) from `vitest-pool-assemblyscript/assembly`.
|
|
306
|
+
|
|
307
|
+
`it` is available as an alias for `test`.
|
|
308
|
+
|
|
309
|
+
```typescript
|
|
310
|
+
import { test, it, describe, expect, TestOptions } from "vitest-pool-assemblyscript/assembly";
|
|
311
|
+
import { add } from "../assembly/math.ts";
|
|
312
|
+
|
|
313
|
+
test("a test", () => {
|
|
314
|
+
expect(1 + 1).toBe(2);
|
|
315
|
+
expect(add(3, 2)).toBe(5);
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
describe("a suite of math operations", () => {
|
|
319
|
+
test("another test", () => {
|
|
320
|
+
expect(3 - 1).toBe(2);
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
describe("a nested suite of float operations", () => {
|
|
324
|
+
it("tests something else", () => {
|
|
325
|
+
expect(0.1 + 0.2).toBeCloseTo(0.3);
|
|
326
|
+
});
|
|
327
|
+
});
|
|
328
|
+
});
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
### Modifiers: `.skip`, `.only`, `.fails`
|
|
332
|
+
|
|
333
|
+
```typescript
|
|
334
|
+
test.skip("not ready yet", () => { /* ... */ });
|
|
335
|
+
|
|
336
|
+
test.only("run only this test", () => { /* ... */ });
|
|
337
|
+
|
|
338
|
+
test.fails("expected to fail, so will actually pass", () => {
|
|
339
|
+
expect(false).toBeTruthy();
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
describe.skip("entire suite skipped", () => { /* ... */ });
|
|
343
|
+
|
|
344
|
+
describe.only("only this suite runs", () => { /* ... */ });
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
### Inline Test Options
|
|
348
|
+
|
|
349
|
+
`TestOptions` provides chainable configuration for `timeout`, `retry`, `skip`, `only`, and `fails`. Options can be placed before or after the callback, and suite options are inherited by nested tests and suites.
|
|
350
|
+
|
|
351
|
+
```typescript
|
|
352
|
+
// options before callback
|
|
353
|
+
test("with timeout", TestOptions.timeout(500), () => { /* ... */ });
|
|
354
|
+
|
|
355
|
+
// options after callback
|
|
356
|
+
test("with retry", () => { /* ... */ }, TestOptions.retry(3));
|
|
357
|
+
|
|
358
|
+
// chained options
|
|
359
|
+
test("with both", TestOptions.timeout(500).retry(2), () => { /* ... */ });
|
|
360
|
+
|
|
361
|
+
// suite-level options are inherited by nested tests
|
|
362
|
+
describe("slow tests", TestOptions.timeout(1000), () => {
|
|
363
|
+
test("inherits suite timeout", () => { /* ... */ });
|
|
364
|
+
|
|
365
|
+
// test-level options override suite options
|
|
366
|
+
test("custom retry", TestOptions.retry(5), () => { /* ... */ });
|
|
367
|
+
});
|
|
368
|
+
|
|
369
|
+
// modifiers and options can be combined
|
|
370
|
+
test.fails("expected failure with retry", TestOptions.retry(3), () => {
|
|
371
|
+
expect(false).toBeTruthy();
|
|
372
|
+
});
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
---
|
|
376
|
+
|
|
377
|
+
## Matcher API
|
|
378
|
+
|
|
379
|
+
This project aims to follow the [vitest/jest `expect()` API](https://vitest.dev/api/expect.html) as closely as possible, with some necessary differences given AssemblyScript's static-typing.
|
|
380
|
+
|
|
381
|
+
The following subset of vitest/jest expect matchers are currently supported:
|
|
382
|
+
|
|
383
|
+
### `.not`
|
|
384
|
+
Inverts the matcher that follows. Can be chained.
|
|
385
|
+
```typescript
|
|
386
|
+
expect(1).not.toBe(2);
|
|
387
|
+
expect("hello").not.toBeNull();
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
### `toBe()`
|
|
391
|
+
Checks that a value is what you expect. Primitives and strings are compared directly, and references are checked for reference equality only (including objects and arrays). These comparisons are done using `==`, although it is forgiving of numeric type differences.
|
|
392
|
+
|
|
393
|
+
Don't use `toBe` with floating-point numbers - see `toBeCloseTo()` instead.
|
|
394
|
+
```typescript
|
|
395
|
+
expect(1 + 1).toBe(2);
|
|
396
|
+
expect("hello").toBe("hello");
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
### `toBeCloseTo()`
|
|
400
|
+
Checks if a floating point value is close to what you expect. Using exact equality with floating point numbers often doesn't work correctly, because small internal rounding occurs to be able to represent floats in binary. This rounding means intuitive comparisons will often fail.
|
|
401
|
+
|
|
402
|
+
Comparing strings, integers, or references will fall back to using a `toBe` comparison.
|
|
403
|
+
|
|
404
|
+
Accepts an additional `precision: i32` argument - Number of decimal places that must match for values to be considered close. Defaults to 2 digits, meaning effectively that values must be within 0.005 of each other.
|
|
405
|
+
```typescript
|
|
406
|
+
expect(0.1 + 0.2).toBeCloseTo(0.3);
|
|
407
|
+
expect(1.005).toBeCloseTo(1.0, 1);
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
### `toEqual()`
|
|
411
|
+
Checks that two values have the same value (deep equality). Currently supports checking equality of Arrays, Sets, Maps, and nulls. Values inside arrays are compared using `toEqual()` also, while Maps and Sets use their respective rules for membership.
|
|
412
|
+
|
|
413
|
+
Primitives, strings, and other object references are compared with `toBe()` rules.
|
|
414
|
+
|
|
415
|
+
> ⚠️ Warning: Does not yet support user-defined object deep equality checking
|
|
416
|
+
```typescript
|
|
417
|
+
expect([1, 2, 3]).toEqual([1, 2, 3]);
|
|
418
|
+
expect(["one", "two", "three"]).toEqual(["one", "two", "three"]);
|
|
419
|
+
|
|
420
|
+
// objects use reference equality (deep equality not yet supported)
|
|
421
|
+
const a: MyObject = new MyObject();
|
|
422
|
+
const b: MyObject = new MyObject();
|
|
423
|
+
expect([a, b]).toEqual([a, b]);
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
### `toStrictEqual()`
|
|
427
|
+
Alias for `toEqual()`. Currently no differences in AssemblyScript.
|
|
428
|
+
|
|
429
|
+
### `toBeTruthy()` & `toBeFalsey()`
|
|
430
|
+
Check that a value is truthy or falsey. Falsey values are `0`, `false`, `""`, and `null`.
|
|
431
|
+
```typescript
|
|
432
|
+
expect(1).toBeTruthy();
|
|
433
|
+
expect(0).toBeFalsey();
|
|
434
|
+
expect("hello").toBeTruthy();
|
|
435
|
+
expect("").toBeFalsey();
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
### `toBeNull()`
|
|
439
|
+
Checks that a value is null (`usize(0)` in AssemblyScript).
|
|
440
|
+
```typescript
|
|
441
|
+
const val: string | null = null;
|
|
442
|
+
expect(val).toBeNull();
|
|
443
|
+
expect("hello").not.toBeNull();
|
|
444
|
+
expect(0).not.toBeNull();
|
|
445
|
+
expect(false).not.toBeNull();
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
### `toBeNullable()`
|
|
449
|
+
Checks that the type of the value is nullable (can hold `null`). This is a type-level check, not a value check — use `toBeNull()` to check if a value *is* null.
|
|
450
|
+
```typescript
|
|
451
|
+
const val: string | null = null;
|
|
452
|
+
expect(val).toBeNullable();
|
|
453
|
+
expect("hello").not.toBeNullable();
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
### `toBeNaN()`
|
|
457
|
+
Checks that a floating point value is `NaN`.
|
|
458
|
+
```typescript
|
|
459
|
+
expect(NaN).toBeNaN();
|
|
460
|
+
expect(1.0).not.toBeNaN();
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
### `toHaveLength()`
|
|
464
|
+
Checks that an array or array-like value has the expected length.
|
|
465
|
+
```typescript
|
|
466
|
+
expect([1, 2, 3]).toHaveLength(3);
|
|
467
|
+
expect([]).toHaveLength(0);
|
|
468
|
+
expect("hello world").toHaveLength(11);
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
### `toThrowError()`
|
|
472
|
+
Checks that a function throws an error when called. Optionally checks that the error message matches the provided string. Also available as `toThrow()`.
|
|
473
|
+
|
|
474
|
+
>⚠️ Important: You must provide a void callback to expect() when using `toThrowError()`
|
|
475
|
+
|
|
476
|
+
>ℹ️ Note: `toThrowError()` does not accept inversion using `expect().not.toThrowError()`
|
|
477
|
+
```typescript
|
|
478
|
+
expect(() => { throw new Error("boom"); }).toThrowError();
|
|
479
|
+
expect(() => { throw new Error("boom"); }).toThrowError("boom");
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
### Planned Matchers
|
|
483
|
+
`toBeDefined`, `toBeUndefined`, `toBeGreaterThan`, `toBeGreaterThanOrEqual`, `toBeLessThan`, `toBeLessThanOrEqual`, `toContain`, `toContainEqual`
|
|
484
|
+
|
|
485
|
+
### Likely Matchers
|
|
486
|
+
`toBeOneOf`, `toBeTypeOf`, `toBeInstanceOf`, `toHaveProperty`, `toMatch`
|
|
487
|
+
|
|
488
|
+
---
|
|
489
|
+
|
|
490
|
+
## Project Status & Expectations
|
|
491
|
+
|
|
492
|
+
**This is a pre-v1 project** being developed in the open by an interested individual. Most core functionality is working, with a long list of planned features and polish to be added as time allows.
|
|
493
|
+
|
|
494
|
+
*(Note: Not yet published to npm - currently development only)*
|
|
495
|
+
|
|
496
|
+
### Current State
|
|
497
|
+
|
|
498
|
+
All features listed in the [Features](#features) section are working and assumed to be bug-free. Please [report a bug](https://github.com/themattspiral/vitest-pool-assemblyscript/issues/new) if you encounter one.
|
|
499
|
+
|
|
500
|
+
**⚠️ Known Limitations - Coming Soon:**
|
|
501
|
+
- **Function-level coverage only**: No statement, branch, or line coverage yet
|
|
502
|
+
- **No lifecycle hooks**: No setup/teardown hooks yet
|
|
503
|
+
- **Watch mode specs only**: Re-runs test files when they are directly changed, but not yet based on changed source files
|
|
504
|
+
- **`toEqual` doesn't reflect**: Doesn't yet support deep inspection of user-defined objects
|
|
505
|
+
|
|
506
|
+
### Near Future Roadmap
|
|
507
|
+
|
|
508
|
+
**Epic: Enhanced block-level coverage**
|
|
509
|
+
- Block-level statement coverage (line granularity)
|
|
510
|
+
- Branch coverage using CFG analysis
|
|
511
|
+
- All 4 coverage types (function, statement, branch, line)
|
|
512
|
+
|
|
513
|
+
**Epic: Testing DX**
|
|
514
|
+
- Lifecycle hooks (`beforeEach`, `afterEach`, `beforeAll`, `afterAll`)
|
|
515
|
+
- Watch mode optimization
|
|
516
|
+
- `toEqual` reflection
|
|
517
|
+
- expect.soft
|
|
518
|
+
- Allow delegating JS/TS to istanbul coverage provider
|
|
519
|
+
- Per-file compilation setting override?
|
|
520
|
+
|
|
521
|
+
**Epic: Expand expect matcher API**
|
|
522
|
+
- Planned: `toBeDefined`, `toBeUndefined`, `toBeGreaterThan`, `toBeGreaterThanOrEqual`, `toBeLessThan`, `toBeLessThanOrEqual`, `toContain`, `toContainEqual`
|
|
523
|
+
- Probably: `toBeOneOf`, `toBeTypeOf`, `toBeInstanceOf`, `toHaveProperty`, `toMatch`
|
|
524
|
+
|
|
525
|
+
**Epic: Spy and Mock**
|
|
526
|
+
- TBD
|
|
527
|
+
|
|
528
|
+
**✖️ Out of Scope (Currently):**
|
|
529
|
+
- Compiler integration with other compile-to-WASM languages (Rust, C++)
|
|
530
|
+
- I would LOVE to expand this project to a more generic wasm pool, supporting pluggable compilers and ast parsing for different WASM ecosystems and toolchains
|
|
531
|
+
- Not in scope now because of time and effort. If you want to pay me to work on this [get in touch](https://github.com/themattspiral)!
|
|
532
|
+
- Generic JS-harness testing of any precompiled WASM binary
|
|
533
|
+
|
|
534
|
+
---
|
|
535
|
+
|
|
536
|
+
## Installation Guide (Development Preview)
|
|
537
|
+
|
|
538
|
+
**⚠️ Important:** This project is under active development. Features and APIs may change without notice. No guarantees are made about stability or functionality.
|
|
539
|
+
|
|
540
|
+
**Feedback Welcome:** If you try this out, please open an issue on GitHub with your experience, bugs, or suggestions!
|
|
541
|
+
|
|
542
|
+
### Prerequisites
|
|
543
|
+
- Node.js 20.0.0+ (required due to our multi-memory coverage approach)
|
|
544
|
+
- Vitest 3.2.0+ or 4.0.0+
|
|
545
|
+
- AssemblyScript 0.28+
|
|
546
|
+
- C++ build tools (dev only - distributed package will include prebuilds):
|
|
547
|
+
- GCC 7+ or Clang 5+ (C++17 support required)
|
|
548
|
+
- Python 3.x (required by node-gyp)
|
|
549
|
+
|
|
550
|
+
### Setup
|
|
551
|
+
|
|
552
|
+
1. **Clone the repository:**
|
|
553
|
+
```bash
|
|
554
|
+
git clone https://github.com/themattspiral/vitest-pool-assemblyscript.git
|
|
555
|
+
cd vitest-pool-assemblyscript
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
2. **Install Binaryen C++ dependencies, then npm deps**
|
|
559
|
+
```bash
|
|
560
|
+
npm run setup-binaryen
|
|
561
|
+
npm install
|
|
562
|
+
```
|
|
563
|
+
The `setup-binaryen` script downloads prebuilt Binaryen libraries and C++ headers to `third_party/binaryen/`. These are used to build the native addon that extracts debug info from WASM binaries.
|
|
564
|
+
|
|
565
|
+
3. **Build Native Addon**
|
|
566
|
+
```bash
|
|
567
|
+
npm run build:native
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
4. **Build Pool**
|
|
571
|
+
```bash
|
|
572
|
+
npm run build
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
5. **Link the pool to your project:**
|
|
576
|
+
```bash
|
|
577
|
+
# In vitest-pool-assemblyscript:
|
|
578
|
+
npm link
|
|
579
|
+
|
|
580
|
+
# In your project directory:
|
|
581
|
+
npm link vitest-pool-assemblyscript
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
6. **Configure Vitest**
|
|
585
|
+
|
|
586
|
+
See the [Configuration](#configuration) section.
|
|
587
|
+
|
|
588
|
+
7. **Write your tests**
|
|
589
|
+
See the [Writing Tests](#writing-tests) section.
|
|
590
|
+
|
|
591
|
+
8. **Run your tests:**
|
|
592
|
+
```bash
|
|
593
|
+
# Run all tests once
|
|
594
|
+
npx vitest run
|
|
595
|
+
|
|
596
|
+
# Run specific test file
|
|
597
|
+
npx vitest run example.as.test.ts
|
|
598
|
+
|
|
599
|
+
# Run specific test in specific file
|
|
600
|
+
npx vitest run example.as.test.ts -t "my test name"
|
|
601
|
+
```
|
|
602
|
+
|
|
603
|
+
---
|
|
604
|
+
|
|
605
|
+
## License
|
|
606
|
+
|
|
607
|
+
[MIT](LICENSE)
|