@metamesh/testkit 0.18.0 → 0.19.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 +40 -0
- package/README.md +50 -47
- package/dist/docs/guides/package.md +50 -47
- package/dist/docs/manifest.json +1 -1
- package/dist/docs/reference/font-fixtures/LoadedFontFixtures.md +1 -1
- package/dist/docs/reference/font-fixtures/loadFontFixtureServices.md +1 -1
- package/dist/docs/reference/font-fixtures/loadFontFixtures.md +1 -1
- package/dist/docs/reference/fonts/FontTestFixture.md +1 -1
- package/dist/docs/reference/fonts/prepareFontTestServices.md +1 -1
- package/dist/docs/reference/index/BufferContent.md +1 -1
- package/dist/docs/reference/index/ContentMismatchError.md +1 -1
- package/dist/docs/reference/index/GeneratorModelTestInput.md +1 -1
- package/dist/docs/reference/index/GeneratorModelTestOptions.md +1 -1
- package/dist/docs/reference/index/GeneratorTestResult.md +1 -1
- package/dist/docs/reference/index/GeneratorTestRunner.md +1 -1
- package/dist/docs/reference/index/GeneratorTestRunnerOptions.md +1 -1
- package/dist/docs/reference/index/MeshContent.md +1 -1
- package/dist/docs/reference/index/MeshMeasurementExpectation.md +1 -1
- package/dist/docs/reference/index/MeshMeasurementTolerances.md +1 -1
- package/dist/docs/reference/index/RunModelOptions.md +1 -1
- package/dist/docs/reference/index/assertEqualBuffer.md +1 -1
- package/dist/docs/reference/index/assertEqualMesh.md +1 -1
- package/dist/docs/reference/index/assertMeshMeasurements.md +1 -1
- package/dist/docs/reference/index/assertValidDefaults.md +1 -1
- package/dist/docs/reference/index/assertValidDefinition.md +1 -1
- package/dist/docs/reference/index/assertValidParts.md +1 -1
- package/dist/docs/reference/index/assertValidPresets.md +1 -1
- package/dist/docs/reference/index/contentMatchers.md +1 -1
- package/dist/docs/reference/index/createGeneratorTestRunner.md +1 -1
- package/dist/docs/reference/index/getTestEngine.md +1 -1
- package/dist/docs/reference/index/runModel.md +1 -1
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,45 @@
|
|
|
1
1
|
# @metamesh/testkit
|
|
2
2
|
|
|
3
|
+
## 0.19.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- c9de510: Extend straight extrusion end finishing to concave outlines, holes, and disconnected regions.
|
|
8
|
+
Add independent-solid `join` with a feature datum and a smooth (default) or straight width/height
|
|
9
|
+
transition against validated planar, angled, and curved sampled support patches. Both profiles use
|
|
10
|
+
the same support, collar, and whole-volume containment proofs.
|
|
11
|
+
|
|
12
|
+
Breaking: compiled Generators require Modeling runtime major 12. Rebuild packages for the new
|
|
13
|
+
host contract; old compiled runtimes are rejected. Joining preserves the supplied operands and
|
|
14
|
+
does not promise a circular fillet radius or perform automatic placement.
|
|
15
|
+
|
|
16
|
+
Replace named lazy `computed` readers with eager `memo(fn, ...args)` values. Stable pure helpers
|
|
17
|
+
reuse immutable arguments and tracked current params/context reads, with bounded recent histories
|
|
18
|
+
and native geometry retention. Update Studio diagnostics to warn about fresh function identities.
|
|
19
|
+
All authored and compiled callers must use the new API; there is no compatibility surface.
|
|
20
|
+
|
|
21
|
+
- de3d234: Add runtime-neutral STL, 3MF, and GLB export under `@metamesh/modeling/export`, with isolated
|
|
22
|
+
format entry points and backpressure-aware streaming writers. All formats consume captured local
|
|
23
|
+
geometry, placement, and appearance, with independent limits, cancellation, and structured
|
|
24
|
+
information-loss diagnostics. Standard 3MF color groups carry appearance, while base materials
|
|
25
|
+
and multiproperties retain explicit material identities independently of RGB values. These
|
|
26
|
+
properties do not assign slicer filaments or physical device trays. Add `mesh.render()` for
|
|
27
|
+
shared crease-aware display buffers that preserve exact triangle coordinates.
|
|
28
|
+
|
|
29
|
+
Breaking: remove `export3mf` and export types from `/engine`, remove SDK export request protocols
|
|
30
|
+
and `toWorldMeshes`, and return owned `Uint8Array` bytes with format metadata from the shared
|
|
31
|
+
exporters. Studio uses one export worker for every format. CLI captures use format version 3;
|
|
32
|
+
replace `run --export-3mf` with `metamesh export RUN_DIRECTORY --format 3mf --output model.3mf`.
|
|
33
|
+
Captured-run export also supports STL and GLB without rerunning source. No legacy export paths
|
|
34
|
+
or capture readers are retained.
|
|
35
|
+
|
|
36
|
+
### Patch Changes
|
|
37
|
+
|
|
38
|
+
- Updated dependencies [c9de510]
|
|
39
|
+
- Updated dependencies [de3d234]
|
|
40
|
+
- @metamesh/modeling@0.19.0
|
|
41
|
+
- @metamesh/generator-sdk@0.19.0
|
|
42
|
+
|
|
3
43
|
## 0.18.0
|
|
4
44
|
|
|
5
45
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
# `@metamesh/testkit`
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
Check that your MetaMesh models produce the geometry you expect. Run models and Generators with
|
|
4
|
+
the production engine, check their measurements, and test definitions and presets with your
|
|
5
|
+
preferred test runner.
|
|
5
6
|
|
|
6
7
|
> **Preview:** `0.x` minor releases may break compatibility. Patches remain compatible within the
|
|
7
8
|
> same minor line.
|
|
8
9
|
|
|
9
10
|
## Installation
|
|
10
11
|
|
|
11
|
-
Install matching SDK, Modeling, and Testkit releases
|
|
12
|
+
Install matching SDK, Modeling, and Testkit releases, with Testkit as a development dependency:
|
|
12
13
|
|
|
13
14
|
```bash
|
|
14
15
|
pnpm add @metamesh/generator-sdk @metamesh/modeling
|
|
@@ -18,45 +19,44 @@ pnpm add -D @metamesh/testkit
|
|
|
18
19
|
The package publishes ES modules only. Use Node.js 24 or newer. TypeScript consumers need
|
|
19
20
|
TypeScript 6.0 or newer, `strict` checking, and `NodeNext` or `Bundler` module resolution.
|
|
20
21
|
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
The assertions work without a test framework and don't register globals. Testkit has no compiler,
|
|
23
|
+
renderer, or browser dependency. Use the [CLI](https://github.com/JasonKoolman/metamesh/blob/main/packages/cli/README.md)
|
|
24
|
+
to check source files, save captured runs, or render images.
|
|
23
25
|
|
|
24
26
|
## Test a model
|
|
25
27
|
|
|
26
|
-
Build a plate, check its volume and shell count, then
|
|
28
|
+
Build a plate, check its volume and shell count, then check that its meshes reconstruct correctly:
|
|
27
29
|
|
|
28
30
|
```ts
|
|
29
31
|
import { box } from "@metamesh/modeling";
|
|
30
32
|
import { assertMeshMeasurements, assertValidParts, runModel } from "@metamesh/testkit";
|
|
31
33
|
|
|
32
|
-
const
|
|
34
|
+
const result = await runModel<{ width: number }>(
|
|
33
35
|
({ params, part }) => part("plate", box({ size: [params.width, 20, 4] })),
|
|
34
36
|
{ width: 30 }
|
|
35
37
|
);
|
|
36
38
|
|
|
37
39
|
assertMeshMeasurements(
|
|
38
|
-
|
|
40
|
+
result.part("plate"),
|
|
39
41
|
{ signedVolume: 2400, shellCount: 1 },
|
|
40
42
|
{ signedVolume: 0.05 }
|
|
41
43
|
);
|
|
42
|
-
await assertValidParts(
|
|
44
|
+
await assertValidParts(result.parts);
|
|
43
45
|
```
|
|
44
46
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
Use `model.part(id)` for a required semantic part or `model.parts` for iteration and export.
|
|
47
|
+
`runModel` returns immutable parts, measurements, diagnostics, and dependencies. Results need no
|
|
48
|
+
cleanup. Use `result.part(id)` to find a required part by its ID, or iterate over `result.parts`.
|
|
48
49
|
|
|
49
|
-
Always await `assertValidParts(parts
|
|
50
|
-
|
|
51
|
-
It
|
|
52
|
-
|
|
53
|
-
A valid local mesh cannot conceal corrupted or inconsistent world-space output.
|
|
50
|
+
Always await `assertValidParts(parts)`. It checks the world-space buffers for closed topology,
|
|
51
|
+
then reconstructs each part from its local geometry and rigid transform and compares the positions
|
|
52
|
+
and indices exactly. It resolves to the same parts or rejects on failure. Pass an engine as the
|
|
53
|
+
second argument to reuse one you own; otherwise, the shared test engine initializes when needed.
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
program and parameter types as `engine.run`.
|
|
57
|
-
|
|
55
|
+
You can pass an existing Modeling program: `await runModel(program, parameters)` uses the same
|
|
56
|
+
program and parameter types as `engine.run`. For a small test, pass a synchronous callback
|
|
57
|
+
directly. Without parameters, no type argument or wrapper is needed:
|
|
58
58
|
`await runModel(({ part }) => part("cube", box({ size: 2 })))`.
|
|
59
|
-
Parameters
|
|
59
|
+
Parameters keep the program or callback's declared type. Use
|
|
60
60
|
`GenerateCallback<Parameters, Services>` for a reusable callback or supply
|
|
61
61
|
`runModel<Parameters, Services>` inline. Options stay in the third argument; use `undefined` for
|
|
62
62
|
omitted parameters when supplying an engine, limits, or prepared services.
|
|
@@ -80,48 +80,51 @@ Measurement tolerances are absolute: millimetres for bounds, mm² for area, and
|
|
|
80
80
|
They default to zero; shell counts are exact. Matching measurements do not prove geometric
|
|
81
81
|
equivalence or rule out self-intersections. Use native reconstruction checks alongside them.
|
|
82
82
|
|
|
83
|
-
Use `assertEqualBuffer(actual, expected)` or `assertEqualMesh(actual, expected)`
|
|
84
|
-
|
|
83
|
+
Use `assertEqualBuffer(actual, expected)` or `assertEqualMesh(actual, expected)` for exact content
|
|
84
|
+
comparisons. They read `length` and `at(index)` without copying storage and throw
|
|
85
85
|
`ContentMismatchError` with the first differing index or length. Malformed representations throw
|
|
86
86
|
`TypeError`; reader failures propagate. Numeric equality uses `Object.is`: `NaN` equals `NaN` and
|
|
87
87
|
signed zero differs. Mesh comparisons ignore metadata and require identical position and index
|
|
88
88
|
contents. Geometrically equivalent meshes with different triangulation or ordering can fail.
|
|
89
89
|
|
|
90
|
-
Register
|
|
90
|
+
Register `contentMatchers` with your runner's `expect.extend(contentMatchers)` to use
|
|
91
91
|
`toEqualBuffer` and `toEqualMesh`, including `.not`. Only `ContentMismatchError` becomes a failed
|
|
92
92
|
matcher result; invalid inputs and unexpected errors still throw. Follow your runner's
|
|
93
93
|
[matcher extension guidance](https://vitest.dev/guide/extending-matchers) for TypeScript declarations.
|
|
94
94
|
|
|
95
95
|
## Test Generators and repeated edits
|
|
96
96
|
|
|
97
|
-
For a
|
|
98
|
-
`runModel({ definition, runtime }, parameters)`.
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
`getDefaultParameters(definition)` and
|
|
103
|
-
|
|
104
|
-
parameters pass through directly.
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
97
|
+
For a Generator, import its definition and default runtime, then call
|
|
98
|
+
`runModel({ definition, runtime }, parameters)`. This validates the inputs and prepares services
|
|
99
|
+
before generation. Omit parameters or pass `undefined` to use defaults. Supplied inputs use the
|
|
100
|
+
definition's inferred types and must form a complete canonical map.
|
|
101
|
+
|
|
102
|
+
To change one value, spread `getDefaultParameters(definition)` and apply your override. The runner
|
|
103
|
+
doesn't merge defaults into supplied values. Use SDK `normalizeParameters` when recovering saved
|
|
104
|
+
values. Plain model parameters pass through directly.
|
|
105
|
+
|
|
106
|
+
Import the actual Generator entry point in integration tests so they exercise its input handling
|
|
107
|
+
and model together. Direct callbacks are useful for testing construction helpers or mesh reconstruction.
|
|
108
108
|
For a deliberate schema bypass, `runModel(runtime, parameters, { services })` executes
|
|
109
109
|
the Generator's model behavior without claiming those values pass its parameter schema.
|
|
110
110
|
See the [SDK example](https://github.com/JasonKoolman/metamesh/blob/main/packages/generator-sdk/README.md#define-controls).
|
|
111
111
|
|
|
112
|
-
Use `createGeneratorTestRunner(definition, runtime)` for repeated parameter cases
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
112
|
+
Use `createGeneratorTestRunner(definition, runtime)` for repeated parameter cases. Its `run` method
|
|
113
|
+
returns a generated result or a structured validation failure. Call `runner.run(record)` to test
|
|
114
|
+
unknown keys, missing fields, or wrong value types. Use `check` to test declarations and reached
|
|
115
|
+
assertions without finalizing parts; geometry observations can still require the engine.
|
|
116
|
+
Dispose the runner in `finally`; returned results remain usable.
|
|
116
117
|
Use `check(parameters, { validateInput: false })` only to probe model assertions with deliberately
|
|
117
118
|
invalid typed values, bypassing the parameter schema.
|
|
118
119
|
|
|
119
|
-
|
|
120
|
+
### Check cache reuse
|
|
121
|
+
|
|
122
|
+
For models using `memo`, include repeated-edit tests with `{ verifyCache: true }` on the runner.
|
|
120
123
|
Change geometry inputs and placement inputs independently. Verification reruns cached calculations
|
|
121
|
-
and rejects changed results
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
124
|
+
and rejects changed results for unchanged inputs. Keep pure helpers stable and pass changing values
|
|
125
|
+
as arguments; pass the current params/context to track fields read inside the helper.
|
|
126
|
+
Verification has bounded comparison work. For outputs it can't compare, use `{ cache: false }`
|
|
127
|
+
on a separate runner and compare the resulting geometry. Neither check proves arbitrary JavaScript pure.
|
|
125
128
|
Keep prepared service identity stable for unchanged assets; replacing services creates a new session
|
|
126
129
|
and prevents testing cache reuse. Isolated `runModel` calls do not verify repeated-edit correctness.
|
|
127
130
|
|
|
@@ -138,9 +141,9 @@ They accept the same physical `resolution`, `meshValidation`, and `meshTopologyM
|
|
|
138
141
|
| `@metamesh/testkit/fonts` | Prepared font services from supplied fixture bytes. |
|
|
139
142
|
| `@metamesh/testkit/font-fixtures` | Node-only JSON fixture loading with SHA-256 verification. |
|
|
140
143
|
|
|
141
|
-
Font
|
|
142
|
-
checked-in bytes without CDN access; retain their licenses. Font preparation
|
|
143
|
-
optional `fontkit` peer, plus `woff2-encoder` for WOFF2 fixtures.
|
|
144
|
+
For a Generator with Font parameters, supply `prepareServices` to prepare its font services before
|
|
145
|
+
generation. Tests use checked-in bytes without CDN access; retain their licenses. Font preparation
|
|
146
|
+
needs Modeling's optional `fontkit` peer, plus `woff2-encoder` for WOFF2 fixtures.
|
|
144
147
|
|
|
145
148
|
## Documentation
|
|
146
149
|
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
# `@metamesh/testkit`
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
Check that your MetaMesh models produce the geometry you expect. Run models and Generators with
|
|
4
|
+
the production engine, check their measurements, and test definitions and presets with your
|
|
5
|
+
preferred test runner.
|
|
5
6
|
|
|
6
7
|
> **Preview:** `0.x` minor releases may break compatibility. Patches remain compatible within the
|
|
7
8
|
> same minor line.
|
|
8
9
|
|
|
9
10
|
## Installation
|
|
10
11
|
|
|
11
|
-
Install matching SDK, Modeling, and Testkit releases
|
|
12
|
+
Install matching SDK, Modeling, and Testkit releases, with Testkit as a development dependency:
|
|
12
13
|
|
|
13
14
|
```bash
|
|
14
15
|
pnpm add @metamesh/generator-sdk @metamesh/modeling
|
|
@@ -18,45 +19,44 @@ pnpm add -D @metamesh/testkit
|
|
|
18
19
|
The package publishes ES modules only. Use Node.js 24 or newer. TypeScript consumers need
|
|
19
20
|
TypeScript 6.0 or newer, `strict` checking, and `NodeNext` or `Bundler` module resolution.
|
|
20
21
|
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
The assertions work without a test framework and don't register globals. Testkit has no compiler,
|
|
23
|
+
renderer, or browser dependency. Use the [CLI](https://github.com/JasonKoolman/metamesh/blob/main/packages/cli/README.md)
|
|
24
|
+
to check source files, save captured runs, or render images.
|
|
23
25
|
|
|
24
26
|
## Test a model
|
|
25
27
|
|
|
26
|
-
Build a plate, check its volume and shell count, then
|
|
28
|
+
Build a plate, check its volume and shell count, then check that its meshes reconstruct correctly:
|
|
27
29
|
|
|
28
30
|
```ts
|
|
29
31
|
import { box } from "@metamesh/modeling";
|
|
30
32
|
import { assertMeshMeasurements, assertValidParts, runModel } from "@metamesh/testkit";
|
|
31
33
|
|
|
32
|
-
const
|
|
34
|
+
const result = await runModel<{ width: number }>(
|
|
33
35
|
({ params, part }) => part("plate", box({ size: [params.width, 20, 4] })),
|
|
34
36
|
{ width: 30 }
|
|
35
37
|
);
|
|
36
38
|
|
|
37
39
|
assertMeshMeasurements(
|
|
38
|
-
|
|
40
|
+
result.part("plate"),
|
|
39
41
|
{ signedVolume: 2400, shellCount: 1 },
|
|
40
42
|
{ signedVolume: 0.05 }
|
|
41
43
|
);
|
|
42
|
-
await assertValidParts(
|
|
44
|
+
await assertValidParts(result.parts);
|
|
43
45
|
```
|
|
44
46
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
Use `model.part(id)` for a required semantic part or `model.parts` for iteration and export.
|
|
47
|
+
`runModel` returns immutable parts, measurements, diagnostics, and dependencies. Results need no
|
|
48
|
+
cleanup. Use `result.part(id)` to find a required part by its ID, or iterate over `result.parts`.
|
|
48
49
|
|
|
49
|
-
Always await `assertValidParts(parts
|
|
50
|
-
|
|
51
|
-
It
|
|
52
|
-
|
|
53
|
-
A valid local mesh cannot conceal corrupted or inconsistent world-space output.
|
|
50
|
+
Always await `assertValidParts(parts)`. It checks the world-space buffers for closed topology,
|
|
51
|
+
then reconstructs each part from its local geometry and rigid transform and compares the positions
|
|
52
|
+
and indices exactly. It resolves to the same parts or rejects on failure. Pass an engine as the
|
|
53
|
+
second argument to reuse one you own; otherwise, the shared test engine initializes when needed.
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
program and parameter types as `engine.run`.
|
|
57
|
-
|
|
55
|
+
You can pass an existing Modeling program: `await runModel(program, parameters)` uses the same
|
|
56
|
+
program and parameter types as `engine.run`. For a small test, pass a synchronous callback
|
|
57
|
+
directly. Without parameters, no type argument or wrapper is needed:
|
|
58
58
|
`await runModel(({ part }) => part("cube", box({ size: 2 })))`.
|
|
59
|
-
Parameters
|
|
59
|
+
Parameters keep the program or callback's declared type. Use
|
|
60
60
|
`GenerateCallback<Parameters, Services>` for a reusable callback or supply
|
|
61
61
|
`runModel<Parameters, Services>` inline. Options stay in the third argument; use `undefined` for
|
|
62
62
|
omitted parameters when supplying an engine, limits, or prepared services.
|
|
@@ -80,48 +80,51 @@ Measurement tolerances are absolute: millimetres for bounds, mm² for area, and
|
|
|
80
80
|
They default to zero; shell counts are exact. Matching measurements do not prove geometric
|
|
81
81
|
equivalence or rule out self-intersections. Use native reconstruction checks alongside them.
|
|
82
82
|
|
|
83
|
-
Use `assertEqualBuffer(actual, expected)` or `assertEqualMesh(actual, expected)`
|
|
84
|
-
|
|
83
|
+
Use `assertEqualBuffer(actual, expected)` or `assertEqualMesh(actual, expected)` for exact content
|
|
84
|
+
comparisons. They read `length` and `at(index)` without copying storage and throw
|
|
85
85
|
`ContentMismatchError` with the first differing index or length. Malformed representations throw
|
|
86
86
|
`TypeError`; reader failures propagate. Numeric equality uses `Object.is`: `NaN` equals `NaN` and
|
|
87
87
|
signed zero differs. Mesh comparisons ignore metadata and require identical position and index
|
|
88
88
|
contents. Geometrically equivalent meshes with different triangulation or ordering can fail.
|
|
89
89
|
|
|
90
|
-
Register
|
|
90
|
+
Register `contentMatchers` with your runner's `expect.extend(contentMatchers)` to use
|
|
91
91
|
`toEqualBuffer` and `toEqualMesh`, including `.not`. Only `ContentMismatchError` becomes a failed
|
|
92
92
|
matcher result; invalid inputs and unexpected errors still throw. Follow your runner's
|
|
93
93
|
[matcher extension guidance](https://vitest.dev/guide/extending-matchers) for TypeScript declarations.
|
|
94
94
|
|
|
95
95
|
## Test Generators and repeated edits
|
|
96
96
|
|
|
97
|
-
For a
|
|
98
|
-
`runModel({ definition, runtime }, parameters)`.
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
`getDefaultParameters(definition)` and
|
|
103
|
-
|
|
104
|
-
parameters pass through directly.
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
97
|
+
For a Generator, import its definition and default runtime, then call
|
|
98
|
+
`runModel({ definition, runtime }, parameters)`. This validates the inputs and prepares services
|
|
99
|
+
before generation. Omit parameters or pass `undefined` to use defaults. Supplied inputs use the
|
|
100
|
+
definition's inferred types and must form a complete canonical map.
|
|
101
|
+
|
|
102
|
+
To change one value, spread `getDefaultParameters(definition)` and apply your override. The runner
|
|
103
|
+
doesn't merge defaults into supplied values. Use SDK `normalizeParameters` when recovering saved
|
|
104
|
+
values. Plain model parameters pass through directly.
|
|
105
|
+
|
|
106
|
+
Import the actual Generator entry point in integration tests so they exercise its input handling
|
|
107
|
+
and model together. Direct callbacks are useful for testing construction helpers or mesh reconstruction.
|
|
108
108
|
For a deliberate schema bypass, `runModel(runtime, parameters, { services })` executes
|
|
109
109
|
the Generator's model behavior without claiming those values pass its parameter schema.
|
|
110
110
|
See the [SDK example](https://github.com/JasonKoolman/metamesh/blob/main/packages/generator-sdk/README.md#define-controls).
|
|
111
111
|
|
|
112
|
-
Use `createGeneratorTestRunner(definition, runtime)` for repeated parameter cases
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
112
|
+
Use `createGeneratorTestRunner(definition, runtime)` for repeated parameter cases. Its `run` method
|
|
113
|
+
returns a generated result or a structured validation failure. Call `runner.run(record)` to test
|
|
114
|
+
unknown keys, missing fields, or wrong value types. Use `check` to test declarations and reached
|
|
115
|
+
assertions without finalizing parts; geometry observations can still require the engine.
|
|
116
|
+
Dispose the runner in `finally`; returned results remain usable.
|
|
116
117
|
Use `check(parameters, { validateInput: false })` only to probe model assertions with deliberately
|
|
117
118
|
invalid typed values, bypassing the parameter schema.
|
|
118
119
|
|
|
119
|
-
|
|
120
|
+
### Check cache reuse
|
|
121
|
+
|
|
122
|
+
For models using `memo`, include repeated-edit tests with `{ verifyCache: true }` on the runner.
|
|
120
123
|
Change geometry inputs and placement inputs independently. Verification reruns cached calculations
|
|
121
|
-
and rejects changed results
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
124
|
+
and rejects changed results for unchanged inputs. Keep pure helpers stable and pass changing values
|
|
125
|
+
as arguments; pass the current params/context to track fields read inside the helper.
|
|
126
|
+
Verification has bounded comparison work. For outputs it can't compare, use `{ cache: false }`
|
|
127
|
+
on a separate runner and compare the resulting geometry. Neither check proves arbitrary JavaScript pure.
|
|
125
128
|
Keep prepared service identity stable for unchanged assets; replacing services creates a new session
|
|
126
129
|
and prevents testing cache reuse. Isolated `runModel` calls do not verify repeated-edit correctness.
|
|
127
130
|
|
|
@@ -138,9 +141,9 @@ They accept the same physical `resolution`, `meshValidation`, and `meshTopologyM
|
|
|
138
141
|
| `@metamesh/testkit/fonts` | Prepared font services from supplied fixture bytes. |
|
|
139
142
|
| `@metamesh/testkit/font-fixtures` | Node-only JSON fixture loading with SHA-256 verification. |
|
|
140
143
|
|
|
141
|
-
Font
|
|
142
|
-
checked-in bytes without CDN access; retain their licenses. Font preparation
|
|
143
|
-
optional `fontkit` peer, plus `woff2-encoder` for WOFF2 fixtures.
|
|
144
|
+
For a Generator with Font parameters, supply `prepareServices` to prepare its font services before
|
|
145
|
+
generation. Tests use checked-in bytes without CDN access; retain their licenses. Font preparation
|
|
146
|
+
needs Modeling's optional `fontkit` peer, plus `woff2-encoder` for WOFF2 fixtures.
|
|
144
147
|
|
|
145
148
|
## Documentation
|
|
146
149
|
|
package/dist/docs/manifest.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Byte-verified local font selections and a reusable Generator service-preparation adapter.
|
|
4
4
|
|
|
5
|
-
Import from `@metamesh/testkit/font-fixtures` (@metamesh/testkit@0.
|
|
5
|
+
Import from `@metamesh/testkit/font-fixtures` (@metamesh/testkit@0.19.0).
|
|
6
6
|
|
|
7
7
|
```ts
|
|
8
8
|
/** Byte-verified local font selections and a reusable Generator service-preparation adapter. */
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Fixture provider matching createGeneratorTestRunner's asynchronous service boundary.
|
|
4
4
|
|
|
5
|
-
Import from `@metamesh/testkit/font-fixtures` (@metamesh/testkit@0.
|
|
5
|
+
Import from `@metamesh/testkit/font-fixtures` (@metamesh/testkit@0.19.0).
|
|
6
6
|
|
|
7
7
|
```ts
|
|
8
8
|
/** Fixture provider matching createGeneratorTestRunner's asynchronous service boundary. */
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Node-only local descriptor loader. Paths resolve beside the descriptor; bytes never come from a catalog.
|
|
4
4
|
|
|
5
|
-
Import from `@metamesh/testkit/font-fixtures` (@metamesh/testkit@0.
|
|
5
|
+
Import from `@metamesh/testkit/font-fixtures` (@metamesh/testkit@0.19.0).
|
|
6
6
|
|
|
7
7
|
```ts
|
|
8
8
|
/** Node-only local descriptor loader. Paths resolve beside the descriptor; bytes never come from a catalog. */
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
A checked-in immutable font fixture; no catalog or network is used by the test harness.
|
|
4
4
|
|
|
5
|
-
Import from `@metamesh/testkit/fonts` (@metamesh/testkit@0.
|
|
5
|
+
Import from `@metamesh/testkit/fonts` (@metamesh/testkit@0.19.0).
|
|
6
6
|
|
|
7
7
|
```ts
|
|
8
8
|
/** A checked-in immutable font fixture; no catalog or network is used by the test harness. */
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Prepares the same synchronous text service used by Studio, from reproducible fixture bytes.
|
|
4
4
|
|
|
5
|
-
Import from `@metamesh/testkit/fonts` (@metamesh/testkit@0.
|
|
5
|
+
Import from `@metamesh/testkit/fonts` (@metamesh/testkit@0.19.0).
|
|
6
6
|
|
|
7
7
|
```ts
|
|
8
8
|
/** Prepares the same synchronous text service used by Studio, from reproducible fixture bytes. */
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Numeric contents readable without copying their storage, including immutable model buffers.
|
|
4
4
|
|
|
5
|
-
Import from `@metamesh/testkit` (@metamesh/testkit@0.
|
|
5
|
+
Import from `@metamesh/testkit` (@metamesh/testkit@0.19.0).
|
|
6
6
|
|
|
7
7
|
```ts
|
|
8
8
|
/** Numeric contents readable without copying their storage, including immutable model buffers. */
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
A difference in valid buffer contents, distinct from malformed inputs or reader failures.
|
|
4
4
|
|
|
5
|
-
Import from `@metamesh/testkit` (@metamesh/testkit@0.
|
|
5
|
+
Import from `@metamesh/testkit` (@metamesh/testkit@0.19.0).
|
|
6
6
|
|
|
7
7
|
```ts
|
|
8
8
|
/** A difference in valid buffer contents, distinct from malformed inputs or reader failures. */
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Definition and executable runtime needed to validate and prepare a Generator.
|
|
4
4
|
|
|
5
|
-
Import from `@metamesh/testkit` (@metamesh/testkit@0.
|
|
5
|
+
Import from `@metamesh/testkit` (@metamesh/testkit@0.19.0).
|
|
6
6
|
|
|
7
7
|
```ts
|
|
8
8
|
/** Definition and executable runtime needed to validate and prepare a Generator. */
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Generation policy, optional test-owned engine, and asynchronous Generator asset preparation.
|
|
4
4
|
|
|
5
|
-
Import from `@metamesh/testkit` (@metamesh/testkit@0.
|
|
5
|
+
Import from `@metamesh/testkit` (@metamesh/testkit@0.19.0).
|
|
6
6
|
|
|
7
7
|
```ts
|
|
8
8
|
/** Generation policy, optional test-owned engine, and asynchronous Generator asset preparation. */
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Parameter or assertion failure, or a durable immutable model result.
|
|
4
4
|
|
|
5
|
-
Import from `@metamesh/testkit` (@metamesh/testkit@0.
|
|
5
|
+
Import from `@metamesh/testkit` (@metamesh/testkit@0.19.0).
|
|
6
6
|
|
|
7
7
|
```ts
|
|
8
8
|
/** Parameter or assertion failure, or a durable immutable model result. */
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
A lazy reusable Generator test session; dispose only the runner's caches.
|
|
4
4
|
|
|
5
|
-
Import from `@metamesh/testkit` (@metamesh/testkit@0.
|
|
5
|
+
Import from `@metamesh/testkit` (@metamesh/testkit@0.19.0).
|
|
6
6
|
|
|
7
7
|
```ts
|
|
8
8
|
/** A lazy reusable Generator test session; dispose only the runner's caches. */
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Fixed host resources and optional asynchronous asset preparation.
|
|
4
4
|
|
|
5
|
-
Import from `@metamesh/testkit` (@metamesh/testkit@0.
|
|
5
|
+
Import from `@metamesh/testkit` (@metamesh/testkit@0.19.0).
|
|
6
6
|
|
|
7
7
|
```ts
|
|
8
8
|
/** Fixed host resources and optional asynchronous asset preparation. */
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Ordered manufacturing geometry; placement, appearance and resource identities are separate.
|
|
4
4
|
|
|
5
|
-
Import from `@metamesh/testkit` (@metamesh/testkit@0.
|
|
5
|
+
Import from `@metamesh/testkit` (@metamesh/testkit@0.19.0).
|
|
6
6
|
|
|
7
7
|
```ts
|
|
8
8
|
/** Ordered manufacturing geometry; placement, appearance and resource identities are separate. */
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Physical expectations for a closed mesh; omitted facts are not asserted.
|
|
4
4
|
|
|
5
|
-
Import from `@metamesh/testkit` (@metamesh/testkit@0.
|
|
5
|
+
Import from `@metamesh/testkit` (@metamesh/testkit@0.19.0).
|
|
6
6
|
|
|
7
7
|
```ts
|
|
8
8
|
/** Physical expectations for a closed mesh; omitted facts are not asserted. */
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Absolute nonnegative comparison allowances; each omitted tolerance defaults to zero.
|
|
4
4
|
|
|
5
|
-
Import from `@metamesh/testkit` (@metamesh/testkit@0.
|
|
5
|
+
Import from `@metamesh/testkit` (@metamesh/testkit@0.19.0).
|
|
6
6
|
|
|
7
7
|
```ts
|
|
8
8
|
/** Absolute nonnegative comparison allowances; each omitted tolerance defaults to zero. */
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Host policy and prepared services for an isolated model run; the engine remains host-owned.
|
|
4
4
|
|
|
5
|
-
Import from `@metamesh/testkit` (@metamesh/testkit@0.
|
|
5
|
+
Import from `@metamesh/testkit` (@metamesh/testkit@0.19.0).
|
|
6
6
|
|
|
7
7
|
```ts
|
|
8
8
|
/** Host policy and prepared services for an isolated model run; the engine remains host-owned. */
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Asserts exact ordered numeric contents through length and at(index), without copying storage. Uses Object.is regardless of storage type: NaN equals NaN; signed zero differs. Throws ContentMismatchError for the first difference, TypeError for malformed inputs, and preserves reader failures. This assertion does not establish valid manufacturing geometry.
|
|
4
4
|
|
|
5
|
-
Import from `@metamesh/testkit` (@metamesh/testkit@0.
|
|
5
|
+
Import from `@metamesh/testkit` (@metamesh/testkit@0.19.0).
|
|
6
6
|
|
|
7
7
|
```ts
|
|
8
8
|
/**
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Asserts identical positions and indices with buffer-specific mismatch diagnostics. Ignores metadata. Geometrically equivalent meshes with different triangulation or ordering can fail. Shares assertEqualBuffer's numeric equality, validation and error behavior without copying storage.
|
|
4
4
|
|
|
5
|
-
Import from `@metamesh/testkit` (@metamesh/testkit@0.
|
|
5
|
+
Import from `@metamesh/testkit` (@metamesh/testkit@0.19.0).
|
|
6
6
|
|
|
7
7
|
```ts
|
|
8
8
|
/**
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Analyzes current buffers, requires closed oriented edge topology, and checks selected physical facts with explicit absolute tolerances. Returns fresh measurements without initializing an engine. These facts do not prove geometric equivalence or absence of self-intersections.
|
|
4
4
|
|
|
5
|
-
Import from `@metamesh/testkit` (@metamesh/testkit@0.
|
|
5
|
+
Import from `@metamesh/testkit` (@metamesh/testkit@0.19.0).
|
|
6
6
|
|
|
7
7
|
```ts
|
|
8
8
|
/**
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Throws unless defaults strictly decode and equal the defaults derived from the definition.
|
|
4
4
|
|
|
5
|
-
Import from `@metamesh/testkit` (@metamesh/testkit@0.
|
|
5
|
+
Import from `@metamesh/testkit` (@metamesh/testkit@0.19.0).
|
|
6
6
|
|
|
7
7
|
```ts
|
|
8
8
|
/** Throws unless defaults strictly decode and equal the defaults derived from the definition. */
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Strictly parses a definition and requires its JSON round trip to retain the canonical package representation.
|
|
4
4
|
|
|
5
|
-
Import from `@metamesh/testkit` (@metamesh/testkit@0.
|
|
5
|
+
Import from `@metamesh/testkit` (@metamesh/testkit@0.19.0).
|
|
6
6
|
|
|
7
7
|
```ts
|
|
8
8
|
/** Strictly parses a definition and requires its JSON round trip to retain the canonical package representation. */
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Validates supplied world meshes and their exact agreement with reconstructed local geometry and placement. Resolves to the same parts or rejects on failure. A supplied engine is reused; otherwise the shared engine initializes lazily.
|
|
4
4
|
|
|
5
|
-
Import from `@metamesh/testkit` (@metamesh/testkit@0.
|
|
5
|
+
Import from `@metamesh/testkit` (@metamesh/testkit@0.19.0).
|
|
6
6
|
|
|
7
7
|
```ts
|
|
8
8
|
/** Validates supplied world meshes and their exact agreement with reconstructed local geometry and placement.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Checks preset metadata. Validate domain assertions through the generation test runner.
|
|
4
4
|
|
|
5
|
-
Import from `@metamesh/testkit` (@metamesh/testkit@0.
|
|
5
|
+
Import from `@metamesh/testkit` (@metamesh/testkit@0.19.0).
|
|
6
6
|
|
|
7
7
|
```ts
|
|
8
8
|
/** Checks preset metadata. Validate domain assertions through the generation test runner. */
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Creates a lazy runner for one generation program without loading assets or an engine.
|
|
4
4
|
|
|
5
|
-
Import from `@metamesh/testkit` (@metamesh/testkit@0.
|
|
5
|
+
Import from `@metamesh/testkit` (@metamesh/testkit@0.19.0).
|
|
6
6
|
|
|
7
7
|
```ts
|
|
8
8
|
/** Creates a lazy runner for one generation program without loading assets or an engine. */
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Runs a model program or synchronous callback once and returns durable immutable data. Strictly validates Generator inputs (defaults when omitted), prepares services, and returns durable data.
|
|
4
4
|
|
|
5
|
-
Import from `@metamesh/testkit` (@metamesh/testkit@0.
|
|
5
|
+
Import from `@metamesh/testkit` (@metamesh/testkit@0.19.0).
|
|
6
6
|
|
|
7
7
|
```ts
|
|
8
8
|
/** Runs a model program or synchronous callback once and returns durable immutable data. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@metamesh/testkit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.0",
|
|
4
4
|
"description": "Runner-neutral MetaMesh model and Generator testing helpers, assertions, and local font fixtures.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -41,13 +41,13 @@
|
|
|
41
41
|
"registry": "https://registry.npmjs.org/"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
|
44
|
-
"@metamesh/generator-sdk": "0.
|
|
45
|
-
"@metamesh/modeling": "0.
|
|
44
|
+
"@metamesh/generator-sdk": "0.19.0",
|
|
45
|
+
"@metamesh/modeling": "0.19.0"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"@metamesh/config": "0.0.0",
|
|
49
|
-
"@metamesh/generator-sdk": "0.
|
|
50
|
-
"@metamesh/modeling": "0.
|
|
49
|
+
"@metamesh/generator-sdk": "0.19.0",
|
|
50
|
+
"@metamesh/modeling": "0.19.0",
|
|
51
51
|
"vitest": "^5.0.5",
|
|
52
52
|
"@types/node": "^24.19.2",
|
|
53
53
|
"typescript": "6.0.3"
|