@creative-introvert/tons-of-tests 2.0.0 → 3.0.0-rc.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/README.md +263 -134
- package/dist/cjs/Classify.js +6 -2
- package/dist/cjs/Classify.js.map +1 -1
- package/dist/cjs/RepositoryError.js +24 -33
- package/dist/cjs/RepositoryError.js.map +1 -1
- package/dist/cjs/Show.js +18 -0
- package/dist/cjs/Show.js.map +1 -1
- package/dist/cjs/Test.js +41 -2
- package/dist/cjs/Test.js.map +1 -1
- package/dist/cjs/Test.repository.js +8 -17
- package/dist/cjs/Test.repository.js.map +1 -1
- package/dist/cjs/TestRun.js +20 -0
- package/dist/cjs/TestRun.js.map +1 -0
- package/dist/cjs/TestValueError.js +23 -0
- package/dist/cjs/TestValueError.js.map +1 -0
- package/dist/cjs/index.js +0 -7
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/internal/Classify.js +1 -9
- package/dist/cjs/internal/Classify.js.map +1 -1
- package/dist/cjs/internal/Test.js +305 -109
- package/dist/cjs/internal/Test.js.map +1 -1
- package/dist/cjs/internal/Test.repository.sqlite.js +266 -304
- package/dist/cjs/internal/Test.repository.sqlite.js.map +1 -1
- package/dist/cjs/internal/Test.serialization.js +128 -0
- package/dist/cjs/internal/Test.serialization.js.map +1 -0
- package/dist/cjs/internal/common.js.map +1 -1
- package/dist/cjs/internal/stats.js +37 -3
- package/dist/cjs/internal/stats.js.map +1 -1
- package/dist/cjs/internal/summarize.js +155 -36
- package/dist/cjs/internal/summarize.js.map +1 -1
- package/dist/cjs/internal/test-repository-fixtures.js +31 -0
- package/dist/cjs/internal/test-repository-fixtures.js.map +1 -0
- package/dist/cjs/internal/test-repository-migrations.js +68 -0
- package/dist/cjs/internal/test-repository-migrations.js.map +1 -0
- package/dist/cjs/internal/test-result-stats.js +89 -0
- package/dist/cjs/internal/test-result-stats.js.map +1 -0
- package/dist/dts/Classify.d.ts +4 -1
- package/dist/dts/Classify.d.ts.map +1 -1
- package/dist/dts/RepositoryError.d.ts +19 -20
- package/dist/dts/RepositoryError.d.ts.map +1 -1
- package/dist/dts/Show.d.ts +8 -8
- package/dist/dts/Show.d.ts.map +1 -1
- package/dist/dts/Test.d.ts +155 -11
- package/dist/dts/Test.d.ts.map +1 -1
- package/dist/dts/Test.repository.d.ts +94 -8
- package/dist/dts/Test.repository.d.ts.map +1 -1
- package/dist/dts/TestRun.d.ts +18 -0
- package/dist/dts/TestRun.d.ts.map +1 -0
- package/dist/dts/TestValueError.d.ts +17 -0
- package/dist/dts/TestValueError.d.ts.map +1 -0
- package/dist/dts/index.d.ts +0 -1
- package/dist/dts/index.d.ts.map +1 -1
- package/dist/dts/internal/Classify.d.ts +0 -1
- package/dist/dts/internal/Classify.d.ts.map +1 -1
- package/dist/dts/internal/Test.d.ts +58 -31
- package/dist/dts/internal/Test.d.ts.map +1 -1
- package/dist/dts/internal/Test.repository.sqlite.d.ts +66 -11
- package/dist/dts/internal/Test.repository.sqlite.d.ts.map +1 -1
- package/dist/dts/internal/Test.serialization.d.ts +34 -0
- package/dist/dts/internal/Test.serialization.d.ts.map +1 -0
- package/dist/dts/internal/common.d.ts +1 -1
- package/dist/dts/internal/common.d.ts.map +1 -1
- package/dist/dts/internal/stats.d.ts +15 -1
- package/dist/dts/internal/stats.d.ts.map +1 -1
- package/dist/dts/internal/summarize.d.ts +39 -7
- package/dist/dts/internal/summarize.d.ts.map +1 -1
- package/dist/dts/internal/test-repository-fixtures.d.ts +22 -0
- package/dist/dts/internal/test-repository-fixtures.d.ts.map +1 -0
- package/dist/dts/internal/test-repository-migrations.d.ts +11 -0
- package/dist/dts/internal/test-repository-migrations.d.ts.map +1 -0
- package/dist/dts/internal/test-result-stats.d.ts +7 -0
- package/dist/dts/internal/test-result-stats.d.ts.map +1 -0
- package/dist/esm/Classify.js +5 -1
- package/dist/esm/Classify.js.map +1 -1
- package/dist/esm/RepositoryError.js +14 -29
- package/dist/esm/RepositoryError.js.map +1 -1
- package/dist/esm/Show.js +2 -2
- package/dist/esm/Show.js.map +1 -1
- package/dist/esm/Test.js +38 -1
- package/dist/esm/Test.js.map +1 -1
- package/dist/esm/Test.repository.js +7 -16
- package/dist/esm/Test.repository.js.map +1 -1
- package/dist/esm/TestRun.js +13 -0
- package/dist/esm/TestRun.js.map +1 -0
- package/dist/esm/TestValueError.js +16 -0
- package/dist/esm/TestValueError.js.map +1 -0
- package/dist/esm/index.js +0 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/internal/Classify.js +0 -7
- package/dist/esm/internal/Classify.js.map +1 -1
- package/dist/esm/internal/Test.js +299 -108
- package/dist/esm/internal/Test.js.map +1 -1
- package/dist/esm/internal/Test.repository.sqlite.js +265 -301
- package/dist/esm/internal/Test.repository.sqlite.js.map +1 -1
- package/dist/esm/internal/Test.serialization.js +119 -0
- package/dist/esm/internal/Test.serialization.js.map +1 -0
- package/dist/esm/internal/common.js.map +1 -1
- package/dist/esm/internal/stats.js +35 -2
- package/dist/esm/internal/stats.js.map +1 -1
- package/dist/esm/internal/summarize.js +155 -35
- package/dist/esm/internal/summarize.js.map +1 -1
- package/dist/esm/internal/test-repository-fixtures.js +25 -0
- package/dist/esm/internal/test-repository-fixtures.js.map +1 -0
- package/dist/esm/internal/test-repository-migrations.js +62 -0
- package/dist/esm/internal/test-repository-migrations.js.map +1 -0
- package/dist/esm/internal/test-result-stats.js +83 -0
- package/dist/esm/internal/test-result-stats.js.map +1 -0
- package/package.json +1 -1
- package/dist/cjs/Test.repository.types.js +0 -14
- package/dist/cjs/Test.repository.types.js.map +0 -1
- package/dist/cjs/internal/lib/Schema.js +0 -14
- package/dist/cjs/internal/lib/Schema.js.map +0 -1
- package/dist/dts/Test.repository.types.d.ts +0 -56
- package/dist/dts/Test.repository.types.d.ts.map +0 -1
- package/dist/dts/internal/lib/Schema.d.ts +0 -4
- package/dist/dts/internal/lib/Schema.d.ts.map +0 -1
- package/dist/esm/Test.repository.types.js +0 -7
- package/dist/esm/Test.repository.types.js.map +0 -1
- package/dist/esm/internal/lib/Schema.js +0 -7
- package/dist/esm/internal/lib/Schema.js.map +0 -1
package/README.md
CHANGED
|
@@ -26,7 +26,8 @@ A specialized test runner for predictive functions, focusing on scenarios where
|
|
|
26
26
|
|
|
27
27
|
Use Node.js 24 or newer and Effect 4. The Effect packages in this repository
|
|
28
28
|
use the same exact version. The SQLite driver uses Node's built-in SQLite.
|
|
29
|
-
|
|
29
|
+
This release requires a fresh database. Set `dbPath` to a new file and run the
|
|
30
|
+
suite again. Old database formats are not upgraded automatically.
|
|
30
31
|
|
|
31
32
|
### Installation
|
|
32
33
|
|
|
@@ -46,13 +47,21 @@ Define your test suite:
|
|
|
46
47
|
// my-test-suite.ts
|
|
47
48
|
import {Classify} from '@creative-introvert/tons-of-tests';
|
|
48
49
|
import * as CLI from '@creative-introvert/tons-of-tests-cli';
|
|
49
|
-
import {Effect} from 'effect';
|
|
50
|
+
import {Effect, Schema} from 'effect';
|
|
50
51
|
|
|
51
52
|
const myFunction = (input: number) => Promise.resolve(input * 1.7);
|
|
53
|
+
const classify = Classify.makeClassify<number, number>({
|
|
54
|
+
// Treat an absolute error of up to 0.4 as a match.
|
|
55
|
+
isEqual: (a, b) => Math.abs(b - a) <= 0.4,
|
|
56
|
+
});
|
|
52
57
|
|
|
53
58
|
CLI.run({
|
|
54
59
|
testSuite: {
|
|
55
60
|
name: 'with-cli-simple',
|
|
61
|
+
schemas: {
|
|
62
|
+
testCase: {input: Schema.Finite, expected: Schema.Finite},
|
|
63
|
+
evaluation: {result: Schema.Finite, expected: Schema.Finite},
|
|
64
|
+
},
|
|
56
65
|
testCases: [
|
|
57
66
|
{input: 0, expected: 0},
|
|
58
67
|
{input: 1, expected: 2},
|
|
@@ -60,12 +69,9 @@ CLI.run({
|
|
|
60
69
|
{input: 3, expected: 4},
|
|
61
70
|
{input: 4, expected: 5},
|
|
62
71
|
],
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
classify: Classify.makeClassify({
|
|
67
|
-
isEqual: (a, b) => Math.abs(b - a) <= 0.4,
|
|
68
|
-
}),
|
|
72
|
+
evaluate: (result, expected) => [
|
|
73
|
+
{key: 'result', result, expected, label: classify(result, expected)},
|
|
74
|
+
],
|
|
69
75
|
program: (input: number) => Effect.promise(() => myFunction(input)),
|
|
70
76
|
},
|
|
71
77
|
dbPath: 'with-cli-simple.db',
|
|
@@ -73,7 +79,18 @@ CLI.run({
|
|
|
73
79
|
});
|
|
74
80
|
```
|
|
75
81
|
|
|
76
|
-
|
|
82
|
+
Omit `evaluate` to compare the whole output with the expected value using
|
|
83
|
+
`Schema.toEquivalence`. Reuse the same schema instance for
|
|
84
|
+
`schemas.evaluation.result` and `schemas.evaluation.expected`. The default
|
|
85
|
+
evaluator returns one result with key `result`. It treats `null` and `undefined`
|
|
86
|
+
as missing values for classification.
|
|
87
|
+
|
|
88
|
+
`Classify.makeClassify` returns a label for one comparison. Use it inside
|
|
89
|
+
`evaluate` to choose other matching rules or compare values of different types.
|
|
90
|
+
|
|
91
|
+
The runner keeps the first case for each input/expected-value hash. It warns
|
|
92
|
+
and skips later duplicates before calling `program`, then continues the suite.
|
|
93
|
+
Tags do not change a case's identity; the first case's tags are kept.
|
|
77
94
|
|
|
78
95
|
`testCases` can also be an Effect `Stream`, which is useful for large or generated suites that are consumed lazily by the runner:
|
|
79
96
|
|
|
@@ -83,6 +100,10 @@ import {Stream} from 'effect';
|
|
|
83
100
|
CLI.run({
|
|
84
101
|
testSuite: {
|
|
85
102
|
name: 'with-cli-stream',
|
|
103
|
+
schemas: {
|
|
104
|
+
testCase: {input: Schema.Finite, expected: Schema.Finite},
|
|
105
|
+
evaluation: {result: Schema.Finite, expected: Schema.Finite},
|
|
106
|
+
},
|
|
86
107
|
testCases: Stream.fromIterable([
|
|
87
108
|
{input: 0, expected: 0},
|
|
88
109
|
{input: 1, expected: 2},
|
|
@@ -93,99 +114,211 @@ CLI.run({
|
|
|
93
114
|
});
|
|
94
115
|
```
|
|
95
116
|
|
|
96
|
-
|
|
117
|
+
### Multiple Results From One Test Case
|
|
118
|
+
|
|
119
|
+
Use `evaluate` to track parts of one program output separately. The runner calls
|
|
120
|
+
`program` once per test case, then passes its output and the case's expected
|
|
121
|
+
value to `evaluate`.
|
|
97
122
|
|
|
123
|
+
For a BANT inference, the evaluator can return a result for each of budget,
|
|
124
|
+
authority, need, and timeline:
|
|
125
|
+
|
|
126
|
+
```ts
|
|
127
|
+
import {Classify, type Test} from '@creative-introvert/tons-of-tests';
|
|
128
|
+
import {Array, Schema} from 'effect';
|
|
129
|
+
|
|
130
|
+
const Field = Schema.NullOr(Schema.String);
|
|
131
|
+
const Bant = Schema.Struct({
|
|
132
|
+
budget: Field,
|
|
133
|
+
authority: Field,
|
|
134
|
+
need: Field,
|
|
135
|
+
timeline: Field,
|
|
136
|
+
});
|
|
137
|
+
type Bant = typeof Bant.Type;
|
|
138
|
+
|
|
139
|
+
const fields = ['budget', 'authority', 'need', 'timeline'] as const;
|
|
140
|
+
const classify = Classify.makeClassify({isEqual: Schema.toEquivalence(Field)});
|
|
141
|
+
|
|
142
|
+
const evaluate: Test.Evaluate<Bant, Bant, string | null, string | null> = (
|
|
143
|
+
output,
|
|
144
|
+
expected,
|
|
145
|
+
) =>
|
|
146
|
+
Array.map(fields, key => ({
|
|
147
|
+
key,
|
|
148
|
+
result: output[key],
|
|
149
|
+
expected: expected[key],
|
|
150
|
+
label: classify(output[key], expected[key]),
|
|
151
|
+
}));
|
|
98
152
|
```
|
|
99
|
-
pnpx tsx my-test-suite.ts summarize
|
|
100
153
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
154
|
+
Pass `evaluate` alongside `program` in the test suite. See the runnable
|
|
155
|
+
[multiple-results.ts example](./workspace/examples/src/with-cli/multiple-results.ts)
|
|
156
|
+
for a complete suite using a fixed response in place of an LLM call.
|
|
157
|
+
|
|
158
|
+
`evaluate` is a pure function. It must return a non-empty readonly array of
|
|
159
|
+
`Test.EvaluationResult` values. Each value has a `key`, `result`, `expected`, and
|
|
160
|
+
`label`. Keys must be non-empty and unique within the case. Keep keys stable
|
|
161
|
+
across runs so the CLI can match each result to its previous value.
|
|
162
|
+
|
|
163
|
+
The CLI shows one row per result in the existing table. Rows from the same case
|
|
164
|
+
stay next to each other and share the same `hash`. The `key` column identifies
|
|
165
|
+
each result. The hash comes from the original input and expected value; each
|
|
166
|
+
result is matched across runs by that hash and its key.
|
|
167
|
+
|
|
168
|
+
For the BANT example, these columns show the shared case hash (other columns
|
|
169
|
+
are omitted here):
|
|
170
|
+
|
|
171
|
+
```text
|
|
172
|
+
┌──────────┬───────────┬───────┐
|
|
173
|
+
│ hash │ key │ label │
|
|
174
|
+
├──────────┼───────────┼───────┤
|
|
175
|
+
│ 688c8d1f │ budget │ FP │
|
|
176
|
+
├──────────┼───────────┼───────┤
|
|
177
|
+
│ 688c8d1f │ authority │ TP │
|
|
178
|
+
├──────────┼───────────┼───────┤
|
|
179
|
+
│ 688c8d1f │ need │ TP │
|
|
180
|
+
├──────────┼───────────┼───────┤
|
|
181
|
+
│ 688c8d1f │ timeline │ FN │
|
|
182
|
+
└──────────┴───────────┴───────┘
|
|
129
183
|
```
|
|
130
184
|
|
|
131
|
-
|
|
185
|
+
The statistics count cases and results separately. Labels, precision, and recall
|
|
186
|
+
count visible results. Timing statistics count each visible case once, even when
|
|
187
|
+
it has several result rows.
|
|
132
188
|
|
|
133
|
-
|
|
134
|
-
|
|
189
|
+
This suite needs a schema for the whole BANT expectation and schemas for the
|
|
190
|
+
individual field values:
|
|
135
191
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
│ 1/3 │ bd04cb2c │ 0.52ms │ │ 0 │ 0 │ TP │ │
|
|
142
|
-
├─────┼──────────┼────────┼──────┼───────┼──────────┼────────┼──────────────┤
|
|
143
|
-
│ 2/3 │ 562e2cca │ 0.41ms │ │ 1 │ 2 │ TP │ 2 => 1.7 │
|
|
144
|
-
├─────┼──────────┼────────┼──────┼───────┼──────────┼────────┼──────────────┤
|
|
145
|
-
│ 3/3 │ a5afd52f │ 0.74ms │ │ 2 │ 3 │ TP │ 3 => 3.4 │
|
|
146
|
-
├─────┼──────────┼────────┼──────┼───────┼──────────┼────────┼──────────────┤
|
|
147
|
-
│ #/∑ │ hash │ ms │ tags │ input │ expected │ label₀ │ diff result₀ │
|
|
148
|
-
└─────┴──────────┴────────┴──────┴───────┴──────────┴────────┴──────────────┘
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
┌────────────────────────────────────────────────────────────────────┐
|
|
152
|
-
│ STATS │
|
|
153
|
-
├───┬────┬────┬────┬────┬───────────┬────────┬──────────┬────────────┤
|
|
154
|
-
│ ∑ │ TP │ TN │ FP │ FN │ precision │ recall │ timeMean │ timeMedian │
|
|
155
|
-
├───┼────┼────┼────┼────┼───────────┼────────┼──────────┼────────────┤
|
|
156
|
-
│ 5 │ 3 │ 0 │ 2 │ 0 │ 0.60 │ 1.00 │ 1.23ms │ 1.28ms │
|
|
157
|
-
├───┼────┼────┼────┼────┼───────────┼────────┼──────────┼────────────┤
|
|
158
|
-
│ ∑ │ TP │ TN │ FP │ FN │ precision │ recall │ timeMean │ timeMedian │
|
|
159
|
-
└───┴────┴────┴────┴────┴───────────┴────────┴──────────┴────────────┘
|
|
192
|
+
```ts
|
|
193
|
+
const schemas = {
|
|
194
|
+
testCase: {input: Schema.String, expected: Bant},
|
|
195
|
+
evaluation: {result: Field, expected: Field},
|
|
196
|
+
};
|
|
160
197
|
```
|
|
161
198
|
|
|
162
|
-
|
|
199
|
+
### Value Schemas
|
|
200
|
+
|
|
201
|
+
Every suite requires `schemas`. The fields describe the values used at each
|
|
202
|
+
stage:
|
|
203
|
+
|
|
204
|
+
| Field | Value |
|
|
205
|
+
| --- | --- |
|
|
206
|
+
| `testCase.input` | Original input passed to `program` and saved with each result. |
|
|
207
|
+
| `testCase.expected` | Whole expected value passed to `evaluate` and used in the case hash. |
|
|
208
|
+
| `evaluation.result` | Result returned by `evaluate`. |
|
|
209
|
+
| `evaluation.expected` | Expected value returned by `evaluate`. |
|
|
210
|
+
|
|
211
|
+
The runner derives JSON codecs with Effect's `Schema.toCodecJson`. Built-in
|
|
212
|
+
schemas such as `Schema.BigInt` and `Schema.Date` provide JSON encodings.
|
|
213
|
+
Custom codecs can choose other encodings. Their encoded and decoded types may
|
|
214
|
+
differ. Schemas must not require Effect services.
|
|
215
|
+
|
|
216
|
+
`program`, `evaluate`, and fresh results keep the original values. Saved values
|
|
217
|
+
are encoded and loaded values are decoded with the same schemas. The whole
|
|
218
|
+
program output needs no storage schema when `evaluate` selects smaller values.
|
|
163
219
|
|
|
164
|
-
|
|
220
|
+
Encodings must be deterministic. The runner rejects undeclared object fields
|
|
221
|
+
and checks that decoding the JSON text restores an equivalent value according
|
|
222
|
+
to `Schema.toEquivalence`. These checks run before hashing or saving. For
|
|
223
|
+
example, an untagged bigint/string union can encode both `123n` and `"123"` as
|
|
224
|
+
the same JSON string. Use an encoding that records which type it contains.
|
|
165
225
|
|
|
226
|
+
Case hashes cover the encoded original input and whole expected value.
|
|
227
|
+
Result IDs also cover the evaluation key, label, and encoded result values.
|
|
228
|
+
Object keys are sorted; array order remains significant. Changing an encoding
|
|
229
|
+
can change hashes. Existing data is not migrated.
|
|
230
|
+
|
|
231
|
+
Tables and visual diffs display encoded JSON. Comparisons between runs use
|
|
232
|
+
schema equality on decoded values. Saved labels are not re-evaluated.
|
|
233
|
+
|
|
234
|
+
Conversion failures use `Error.TestValueError`. It includes the suite,
|
|
235
|
+
one-based case number, evaluation key when available, field, operation, and
|
|
236
|
+
original `SchemaError` cause. A failed CLI execution stays incomplete and cannot
|
|
237
|
+
be committed or reused with `--cached`.
|
|
238
|
+
|
|
239
|
+
Direct repository calls also require schemas:
|
|
240
|
+
|
|
241
|
+
```ts
|
|
242
|
+
yield* repository.withTestRun(
|
|
243
|
+
run,
|
|
244
|
+
repository.insertTestResults(results, run, schemas),
|
|
245
|
+
);
|
|
246
|
+
const saved = repository.getTestResultsStream(run, schemas);
|
|
166
247
|
```
|
|
167
|
-
|
|
248
|
+
|
|
249
|
+
`Show.summarize({testRun, schemas})` returns an Effect containing the table text.
|
|
250
|
+
`Show.prepareSummary(results, {schemas, suite})` prepares table chunks inside
|
|
251
|
+
`Effect.scoped`. Both report conversion failures in the Effect error channel.
|
|
252
|
+
The schema-free `Classify.defaultIsEqual` and `Test.makeSha256` exports have
|
|
253
|
+
been removed.
|
|
254
|
+
|
|
255
|
+
### CLI Commands
|
|
256
|
+
|
|
257
|
+
The CLI reads and compares results in batches. It writes formatted rows to a
|
|
258
|
+
temporary file, then reads them back to print the table with the correct column
|
|
259
|
+
widths. Timing statistics use temporary SQLite tables, including the exact
|
|
260
|
+
median. Temporary files and tables are removed after use or failure.
|
|
261
|
+
|
|
262
|
+
This avoids keeping both full runs and the full table text in JavaScript memory.
|
|
263
|
+
The runner still keeps one hash per distinct case to detect duplicates. Arrays
|
|
264
|
+
you supply as `testCases` also stay in memory; use a stream to read cases as
|
|
265
|
+
needed. Temporary storage grows with the report size. The existing commands,
|
|
266
|
+
flags, table layout, and statistics stay the same.
|
|
267
|
+
|
|
268
|
+
#### Summarize
|
|
269
|
+
|
|
270
|
+
```sh
|
|
271
|
+
pnpx tsx my-test-suite.ts summarize
|
|
168
272
|
```
|
|
169
273
|
|
|
170
|
-
|
|
274
|
+
#### Filter Results
|
|
275
|
+
|
|
276
|
+
Both `summarize` and `diff` accept these filters:
|
|
277
|
+
|
|
278
|
+
| Flag | Includes a result when… |
|
|
279
|
+
| --- | --- |
|
|
280
|
+
| `--keys budget,need` | Its key is `budget` or `need`. |
|
|
281
|
+
| `--labels FP,FN` | Its current label is `FP` or `FN`. |
|
|
282
|
+
| `--tags enterprise,german` | Its case has either tag. |
|
|
283
|
+
| `--all-tags enterprise,german` | Its case has both tags. |
|
|
284
|
+
|
|
285
|
+
Different flags combine with AND. For example, show budget errors from
|
|
286
|
+
enterprise cases:
|
|
171
287
|
|
|
288
|
+
```sh
|
|
289
|
+
pnpx tsx bant-suite.ts summarize --keys budget --labels FP,FN --tags enterprise
|
|
172
290
|
```
|
|
173
|
-
|
|
291
|
+
|
|
292
|
+
For the basic example, show matching results:
|
|
293
|
+
|
|
294
|
+
```sh
|
|
295
|
+
pnpx tsx my-test-suite.ts summarize --labels TP
|
|
174
296
|
```
|
|
175
297
|
|
|
176
|
-
|
|
298
|
+
Filters change the displayed rows and statistics. The CLI runs and saves all
|
|
299
|
+
evaluations before applying them, so filtering does not discard saved results
|
|
300
|
+
or reduce the number of program calls. No matches produces an empty view;
|
|
301
|
+
`summarize` also reports zero counts.
|
|
177
302
|
|
|
178
303
|
#### Summarize From Cache
|
|
179
304
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
305
|
+
After the whole suite finishes successfully, `--cached` reads its saved results
|
|
306
|
+
without re-running the program or evaluator. This also works for an empty
|
|
307
|
+
suite. If the previous attempt failed or was interrupted, the CLI clears its
|
|
308
|
+
partial results and runs the suite again.
|
|
183
309
|
|
|
184
|
-
|
|
185
|
-
|
|
310
|
+
Use the cache to inspect other keys without making another inference call:
|
|
311
|
+
|
|
312
|
+
```sh
|
|
313
|
+
pnpx tsx bant-suite.ts summarize --cached --keys budget,need
|
|
186
314
|
```
|
|
187
315
|
|
|
188
316
|
`diff --cached` behaves the same way for the current-run side of the diff.
|
|
317
|
+
The cache belongs to the suite name. It does not detect changes to the program
|
|
318
|
+
or test cases; omit `--cached` when you want to run them again.
|
|
319
|
+
|
|
320
|
+
After upgrading, use a fresh database and create a new baseline. See
|
|
321
|
+
[database setup](./MIGRATION_GUIDE_V1.md#database-setup).
|
|
189
322
|
|
|
190
323
|
#### Write Test Results
|
|
191
324
|
|
|
@@ -193,9 +326,14 @@ pnpx tsx my-test-suite.ts summarize --cached
|
|
|
193
326
|
pnpx tsx my-test-suite.ts commit
|
|
194
327
|
```
|
|
195
328
|
|
|
329
|
+
`commit` saves the current results as the baseline for later comparisons.
|
|
330
|
+
It rejects a tracked run that failed or is still running. Changing the
|
|
331
|
+
baseline and creating the next current run happen in one database transaction.
|
|
332
|
+
|
|
196
333
|
#### Diff
|
|
197
334
|
|
|
198
335
|
The diff command compares your current test results with previously committed results. This is useful when you've made changes to either:
|
|
336
|
+
|
|
199
337
|
- Your test suite's inputs or expected values
|
|
200
338
|
- The implementation of the function being tested
|
|
201
339
|
|
|
@@ -205,67 +343,40 @@ index 21cd713..ab1b6dc 100644
|
|
|
205
343
|
--- a/my-test-suite.ts
|
|
206
344
|
+++ b/my-test-suite.ts
|
|
207
345
|
@@ -1,7 +1,7 @@
|
|
208
|
-
import * as CLI from '@creative-introvert/
|
|
346
|
+
import * as CLI from '@creative-introvert/tons-of-tests-cli';
|
|
209
347
|
import {Effect} from 'effect';
|
|
210
348
|
|
|
211
349
|
-const myFunction = (input: number) => Promise.resolve(input * 1.7);
|
|
212
350
|
+const myFunction = (input: number) => Promise.resolve(input * 2);
|
|
213
351
|
|
|
214
|
-
|
|
352
|
+
CLI.run({
|
|
215
353
|
testSuite: {
|
|
216
354
|
```
|
|
217
355
|
|
|
218
|
-
```
|
|
356
|
+
```sh
|
|
219
357
|
pnpx tsx my-test-suite.ts diff
|
|
220
|
-
#
|
|
358
|
+
# Exit with code 1 when the filtered view contains differences.
|
|
221
359
|
pnpx tsx my-test-suite.ts diff --exit-on-diff
|
|
222
|
-
|
|
223
|
-
┌─────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
|
224
|
-
│ SUMMARY │
|
|
225
|
-
├─────┬──────────┬────────┬──────┬───────┬──────────┬────────┬──────────────┬─────────┬───────────────┤
|
|
226
|
-
│ #/∑ │ hash │ ms │ tags │ input │ expected │ label₀ │ diff result₀ │ label₋₁ │ diff result₋₁ │
|
|
227
|
-
├─────┼──────────┼────────┼──────┼───────┼──────────┼────────┼──────────────┼─────────┼───────────────┤
|
|
228
|
-
│ 1/4 │ 562e2cca │ 0.23ms │ │ 1 │ 2 │ TP │ │ FP │ 2 => 1.7 │
|
|
229
|
-
├─────┼──────────┼────────┼──────┼───────┼──────────┼────────┼──────────────┼─────────┼───────────────┤
|
|
230
|
-
│ 2/4 │ a5afd52f │ 3.66ms │ │ 2 │ 3 │ FP │ 3 => 4 │ FP │ 3 => 3.4 │
|
|
231
|
-
├─────┼──────────┼────────┼──────┼───────┼──────────┼────────┼──────────────┼─────────┼───────────────┤
|
|
232
|
-
│ 3/4 │ 5f7f8725 │ 1.19ms │ │ 3 │ 4 │ FP │ 4 => 6 │ FP │ 4 => 5.1 │
|
|
233
|
-
├─────┼──────────┼────────┼──────┼───────┼──────────┼────────┼──────────────┼─────────┼───────────────┤
|
|
234
|
-
│ 4/4 │ 6cc26923 │ 0.98ms │ │ 4 │ 5 │ FP │ 5 => 8 │ FP │ 5 => 6.8 │
|
|
235
|
-
├─────┼──────────┼────────┼──────┼───────┼──────────┼────────┼──────────────┼─────────┼───────────────┤
|
|
236
|
-
│ #/∑ │ hash │ ms │ tags │ input │ expected │ label₀ │ diff result₀ │ label₋₁ │ diff result₋₁ │
|
|
237
|
-
└─────┴──────────┴────────┴──────┴───────┴──────────┴────────┴──────────────┴─────────┴───────────────┘
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
┌────────────────────────────────────────────────────────────────────┐
|
|
241
|
-
│ STATS │
|
|
242
|
-
├───┬────┬────┬────┬────┬───────────┬────────┬──────────┬────────────┤
|
|
243
|
-
│ ∑ │ TP │ TN │ FP │ FN │ precision │ recall │ timeMean │ timeMedian │
|
|
244
|
-
├───┼────┼────┼────┼────┼───────────┼────────┼──────────┼────────────┤
|
|
245
|
-
│ 5 │ 2 │ 0 │ 3 │ 0 │ 0.40 │ 1.00 │ 1.30ms │ 0.98ms │
|
|
246
|
-
├───┼────┼────┼────┼────┼───────────┼────────┼──────────┼────────────┤
|
|
247
|
-
│ ∑ │ TP │ TN │ FP │ FN │ precision │ recall │ timeMean │ timeMedian │
|
|
248
|
-
└───┴────┴────┴────┴────┴───────────┴────────┴──────────┴────────────┘
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
┌────────────────────────────────────────┐
|
|
252
|
-
│ DIFF │
|
|
253
|
-
├────┬────┬────┬────┬───────────┬────────┤
|
|
254
|
-
│ TP │ TN │ FP │ FN │ precision │ recall │
|
|
255
|
-
├────┼────┼────┼────┼───────────┼────────┤
|
|
256
|
-
│ 1 │ 0 │ -1 │ 0 │ 0.20 │ 0.00 │
|
|
257
|
-
├────┼────┼────┼────┼───────────┼────────┤
|
|
258
|
-
│ TP │ TN │ FP │ FN │ precision │ recall │
|
|
259
|
-
└────┴────┴────┴────┴───────────┴────────┘
|
|
260
360
|
```
|
|
261
361
|
|
|
262
|
-
|
|
362
|
+
For a suite with several results per case, select the keys to compare:
|
|
263
363
|
|
|
364
|
+
```sh
|
|
365
|
+
pnpx tsx bant-suite.ts diff --keys budget --labels FP,FN
|
|
264
366
|
```
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
367
|
+
|
|
368
|
+
`diff` matches results by case hash and key before applying filters. It includes
|
|
369
|
+
new results and changes to a result's value, expected value, or label. A current
|
|
370
|
+
`FP` result keeps its previous value and label even when that previous label
|
|
371
|
+
does not match `--labels`.
|
|
372
|
+
|
|
373
|
+
See [workspace/examples/src/with-cli](./workspace/examples/src/with-cli) for
|
|
374
|
+
more examples. From the repository root, run:
|
|
375
|
+
|
|
376
|
+
```sh
|
|
377
|
+
direnv exec . pnpm exec tsx workspace/examples/src/with-cli/simple-run.ts summarize
|
|
378
|
+
direnv exec . pnpm exec tsx workspace/examples/src/with-cli/simple-effect.ts
|
|
379
|
+
direnv exec . pnpm exec tsx workspace/examples/src/with-cli/multiple-results.ts summarize --keys budget,need
|
|
269
380
|
```
|
|
270
381
|
|
|
271
382
|
### Using the CLI programmatically
|
|
@@ -305,6 +416,30 @@ CLI.effect(
|
|
|
305
416
|
);
|
|
306
417
|
```
|
|
307
418
|
|
|
419
|
+
Each `CLI.effect` call opens and closes its own database connection. To share
|
|
420
|
+
one repository across several commands, use `CLI.effectNoDeps` and provide
|
|
421
|
+
the services once around the whole program. This also lets an in-memory
|
|
422
|
+
database keep its results between commands:
|
|
423
|
+
|
|
424
|
+
```ts
|
|
425
|
+
import * as CLI from '@creative-introvert/tons-of-tests-cli';
|
|
426
|
+
import {NodeRuntime} from '@effect/platform-node';
|
|
427
|
+
import {Effect} from 'effect';
|
|
428
|
+
|
|
429
|
+
const config = {testSuite, dbPath: ':memory:'};
|
|
430
|
+
|
|
431
|
+
Effect.gen(function* () {
|
|
432
|
+
yield* CLI.effectNoDeps(config, ['node', 'script', 'summarize']);
|
|
433
|
+
yield* CLI.effectNoDeps(config, ['node', 'script', 'commit']);
|
|
434
|
+
}).pipe(
|
|
435
|
+
Effect.provide(CLI.buildLayer(config)),
|
|
436
|
+
NodeRuntime.runMain,
|
|
437
|
+
);
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
`effectNoDeps` uses the supplied platform services and `TestRepository`.
|
|
441
|
+
Its `config.dbPath` is only used if you pass the config to `buildLayer`.
|
|
442
|
+
|
|
308
443
|
If you need the last committed test-run hash from inside another script, use
|
|
309
444
|
the dedicated helper:
|
|
310
445
|
|
|
@@ -318,16 +453,10 @@ const hash = await CLI.getLastTestRunHash({
|
|
|
318
453
|
// hash: string | null
|
|
319
454
|
```
|
|
320
455
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
```ts
|
|
326
|
-
import {DiffNonEmpty} from '@creative-introvert/tons-of-tests-cli';
|
|
327
|
-
|
|
328
|
-
// ... compose _diff into your own Effect pipeline, then:
|
|
329
|
-
Effect.catchTag('DiffNonEmpty', () => /* handle */);
|
|
330
|
-
```
|
|
456
|
+
When you use `CLI.effect` or `CLI.effectNoDeps`, `diff --exit-on-diff` fails with a typed
|
|
457
|
+
`DiffNonEmpty` error when the current run has visible diffs. Handle it with
|
|
458
|
+
`Effect.catchTag('DiffNonEmpty', handler)`; `error.count` gives the number of
|
|
459
|
+
visible changed results.
|
|
331
460
|
|
|
332
461
|
At the process entry point (`CLI.run`), `DiffNonEmpty` is translated to
|
|
333
462
|
`process.exitCode = 1` — the user-facing "exit with code 1 on diff"
|
package/dist/cjs/Classify.js
CHANGED
|
@@ -3,22 +3,25 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.values = exports.makeClassify = exports.defaultIsNil = exports.
|
|
6
|
+
exports.values = exports.makeClassify = exports.defaultIsNil = exports.Stats = exports.LabelSchema = void 0;
|
|
7
7
|
var _effect = /*#__PURE__*/require("effect");
|
|
8
8
|
var internal = /*#__PURE__*/_interopRequireWildcard(/*#__PURE__*/require("./internal/Classify.js"));
|
|
9
9
|
var cache;
|
|
10
10
|
function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var r, c, a = Object.defineProperty, n = { __proto__: null, default: e }; if (Object(e) !== e) return n; if (cache || "function" != typeof WeakMap || (cache = new WeakMap()), cache) { if (cache.has(e)) return cache.get(e); cache.set(e, n); } for (c in e) "default" !== c && {}.hasOwnProperty.call(e, c) && ((r = a && Object.getOwnPropertyDescriptor(e, c)) && (r.get || r.set) ? a(n, c, r) : n[c] = e[c]); return n; }
|
|
11
11
|
const LabelSchema = exports.LabelSchema = internal.LabelSchema;
|
|
12
12
|
const values = exports.values = internal.values;
|
|
13
|
-
const defaultIsEqual = exports.defaultIsEqual = internal.defaultIsEqual;
|
|
14
13
|
const defaultIsNil = exports.defaultIsNil = internal.defaultIsNil;
|
|
15
14
|
const makeClassify = exports.makeClassify = internal.makeClassify;
|
|
15
|
+
/** Counts selected results; timing statistics count each selected case once. */
|
|
16
16
|
class Stats extends /*#__PURE__*/_effect.Schema.Class('Stats')({
|
|
17
17
|
TP: _effect.Schema.Finite,
|
|
18
18
|
TN: _effect.Schema.Finite,
|
|
19
19
|
FP: _effect.Schema.Finite,
|
|
20
20
|
FN: _effect.Schema.Finite,
|
|
21
|
+
/** Number of evaluation results. */
|
|
21
22
|
total: _effect.Schema.Finite,
|
|
23
|
+
/** Number of distinct original test cases represented by those results. */
|
|
24
|
+
testCases: _effect.Schema.Int,
|
|
22
25
|
precision: _effect.Schema.Finite,
|
|
23
26
|
recall: _effect.Schema.Finite,
|
|
24
27
|
timeMin: /*#__PURE__*/_effect.Schema.Option(_effect.Schema.Finite),
|
|
@@ -33,6 +36,7 @@ class Stats extends /*#__PURE__*/_effect.Schema.Class('Stats')({
|
|
|
33
36
|
FP: 0,
|
|
34
37
|
FN: 0,
|
|
35
38
|
total: 0,
|
|
39
|
+
testCases: 0,
|
|
36
40
|
precision: 0,
|
|
37
41
|
recall: 0,
|
|
38
42
|
timeMin: _effect.Option.none(),
|
package/dist/cjs/Classify.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Classify.js","names":["_effect","require","internal","_interopRequireWildcard","cache","e","t","__esModule","r","c","a","Object","defineProperty","n","__proto__","default","WeakMap","has","get","set","hasOwnProperty","call","getOwnPropertyDescriptor","LabelSchema","exports","values","
|
|
1
|
+
{"version":3,"file":"Classify.js","names":["_effect","require","internal","_interopRequireWildcard","cache","e","t","__esModule","r","c","a","Object","defineProperty","n","__proto__","default","WeakMap","has","get","set","hasOwnProperty","call","getOwnPropertyDescriptor","LabelSchema","exports","values","defaultIsNil","makeClassify","Stats","Schema","Class","TP","Finite","TN","FP","FN","total","testCases","Int","precision","recall","timeMin","Option","timeMax","timeMedian","timeMean","empty","none"],"sources":["../../src/Classify.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
|
|
@@ -3,42 +3,33 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.
|
|
7
|
-
|
|
6
|
+
exports.TestRunNotFound = exports.TestRunNotCreated = exports.TestRunIncomplete = exports.TestBaselineNotFound = void 0;
|
|
7
|
+
Object.defineProperty(exports, "TestValueError", {
|
|
8
|
+
enumerable: true,
|
|
9
|
+
get: function () {
|
|
10
|
+
return _TestValueError.TestValueError;
|
|
11
|
+
}
|
|
12
|
+
});
|
|
8
13
|
var _effect = /*#__PURE__*/require("effect");
|
|
9
|
-
|
|
10
|
-
class RepositoryQueryError extends /*#__PURE__*/_effect.Schema.TaggedError()('RepositoryQueryError', {
|
|
11
|
-
operation: _effect.Schema.String,
|
|
12
|
-
cause: /*#__PURE__*/_effect.Schema.instanceOf(_SqlError.SqlError)
|
|
13
|
-
}) {
|
|
14
|
-
static fromSql = operation => cause => new RepositoryQueryError({
|
|
15
|
-
operation,
|
|
16
|
-
cause
|
|
17
|
-
});
|
|
18
|
-
}
|
|
19
|
-
exports.RepositoryQueryError = RepositoryQueryError;
|
|
20
|
-
class RepositoryWriteError extends /*#__PURE__*/_effect.Schema.TaggedError()('RepositoryWriteError', {
|
|
21
|
-
operation: _effect.Schema.String,
|
|
22
|
-
cause: SqlCause
|
|
23
|
-
}) {
|
|
24
|
-
static from = operation => cause => new RepositoryWriteError({
|
|
25
|
-
operation,
|
|
26
|
-
cause
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
exports.RepositoryWriteError = RepositoryWriteError;
|
|
30
|
-
class RepositoryDecodeError extends /*#__PURE__*/_effect.Schema.TaggedError()('RepositoryDecodeError', {
|
|
31
|
-
operation: _effect.Schema.String,
|
|
32
|
-
cause: /*#__PURE__*/_effect.Schema.instanceOf(_effect.Schema.SchemaError)
|
|
33
|
-
}) {
|
|
34
|
-
static from = operation => cause => new RepositoryDecodeError({
|
|
35
|
-
operation,
|
|
36
|
-
cause
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
exports.RepositoryDecodeError = RepositoryDecodeError;
|
|
14
|
+
var _TestValueError = /*#__PURE__*/require("./TestValueError.js");
|
|
40
15
|
class TestRunNotCreated extends /*#__PURE__*/_effect.Schema.TaggedError()('TestRunNotCreated', {
|
|
41
16
|
testSuiteName: _effect.Schema.String
|
|
42
17
|
}) {}
|
|
18
|
+
/** A complete saved run is required for this operation. */
|
|
43
19
|
exports.TestRunNotCreated = TestRunNotCreated;
|
|
20
|
+
class TestRunIncomplete extends /*#__PURE__*/_effect.Schema.TaggedError()('TestRunIncomplete', {
|
|
21
|
+
testSuiteName: _effect.Schema.String,
|
|
22
|
+
testRunId: _effect.Schema.Int,
|
|
23
|
+
variant: _effect.Schema.String
|
|
24
|
+
}) {}
|
|
25
|
+
exports.TestRunIncomplete = TestRunIncomplete;
|
|
26
|
+
class TestRunNotFound extends /*#__PURE__*/_effect.Schema.TaggedError()('TestRunNotFound', {
|
|
27
|
+
testRunId: _effect.Schema.Int
|
|
28
|
+
}) {}
|
|
29
|
+
exports.TestRunNotFound = TestRunNotFound;
|
|
30
|
+
class TestBaselineNotFound extends /*#__PURE__*/_effect.Schema.TaggedError()('TestBaselineNotFound', {
|
|
31
|
+
testSuiteName: _effect.Schema.String,
|
|
32
|
+
variant: _effect.Schema.String
|
|
33
|
+
}) {}
|
|
34
|
+
exports.TestBaselineNotFound = TestBaselineNotFound;
|
|
44
35
|
//# sourceMappingURL=RepositoryError.js.map
|