@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.
Files changed (120) hide show
  1. package/README.md +263 -134
  2. package/dist/cjs/Classify.js +6 -2
  3. package/dist/cjs/Classify.js.map +1 -1
  4. package/dist/cjs/RepositoryError.js +24 -33
  5. package/dist/cjs/RepositoryError.js.map +1 -1
  6. package/dist/cjs/Show.js +18 -0
  7. package/dist/cjs/Show.js.map +1 -1
  8. package/dist/cjs/Test.js +41 -2
  9. package/dist/cjs/Test.js.map +1 -1
  10. package/dist/cjs/Test.repository.js +8 -17
  11. package/dist/cjs/Test.repository.js.map +1 -1
  12. package/dist/cjs/TestRun.js +20 -0
  13. package/dist/cjs/TestRun.js.map +1 -0
  14. package/dist/cjs/TestValueError.js +23 -0
  15. package/dist/cjs/TestValueError.js.map +1 -0
  16. package/dist/cjs/index.js +0 -7
  17. package/dist/cjs/index.js.map +1 -1
  18. package/dist/cjs/internal/Classify.js +1 -9
  19. package/dist/cjs/internal/Classify.js.map +1 -1
  20. package/dist/cjs/internal/Test.js +305 -109
  21. package/dist/cjs/internal/Test.js.map +1 -1
  22. package/dist/cjs/internal/Test.repository.sqlite.js +266 -304
  23. package/dist/cjs/internal/Test.repository.sqlite.js.map +1 -1
  24. package/dist/cjs/internal/Test.serialization.js +128 -0
  25. package/dist/cjs/internal/Test.serialization.js.map +1 -0
  26. package/dist/cjs/internal/common.js.map +1 -1
  27. package/dist/cjs/internal/stats.js +37 -3
  28. package/dist/cjs/internal/stats.js.map +1 -1
  29. package/dist/cjs/internal/summarize.js +155 -36
  30. package/dist/cjs/internal/summarize.js.map +1 -1
  31. package/dist/cjs/internal/test-repository-fixtures.js +31 -0
  32. package/dist/cjs/internal/test-repository-fixtures.js.map +1 -0
  33. package/dist/cjs/internal/test-repository-migrations.js +68 -0
  34. package/dist/cjs/internal/test-repository-migrations.js.map +1 -0
  35. package/dist/cjs/internal/test-result-stats.js +89 -0
  36. package/dist/cjs/internal/test-result-stats.js.map +1 -0
  37. package/dist/dts/Classify.d.ts +4 -1
  38. package/dist/dts/Classify.d.ts.map +1 -1
  39. package/dist/dts/RepositoryError.d.ts +19 -20
  40. package/dist/dts/RepositoryError.d.ts.map +1 -1
  41. package/dist/dts/Show.d.ts +8 -8
  42. package/dist/dts/Show.d.ts.map +1 -1
  43. package/dist/dts/Test.d.ts +155 -11
  44. package/dist/dts/Test.d.ts.map +1 -1
  45. package/dist/dts/Test.repository.d.ts +94 -8
  46. package/dist/dts/Test.repository.d.ts.map +1 -1
  47. package/dist/dts/TestRun.d.ts +18 -0
  48. package/dist/dts/TestRun.d.ts.map +1 -0
  49. package/dist/dts/TestValueError.d.ts +17 -0
  50. package/dist/dts/TestValueError.d.ts.map +1 -0
  51. package/dist/dts/index.d.ts +0 -1
  52. package/dist/dts/index.d.ts.map +1 -1
  53. package/dist/dts/internal/Classify.d.ts +0 -1
  54. package/dist/dts/internal/Classify.d.ts.map +1 -1
  55. package/dist/dts/internal/Test.d.ts +58 -31
  56. package/dist/dts/internal/Test.d.ts.map +1 -1
  57. package/dist/dts/internal/Test.repository.sqlite.d.ts +66 -11
  58. package/dist/dts/internal/Test.repository.sqlite.d.ts.map +1 -1
  59. package/dist/dts/internal/Test.serialization.d.ts +34 -0
  60. package/dist/dts/internal/Test.serialization.d.ts.map +1 -0
  61. package/dist/dts/internal/common.d.ts +1 -1
  62. package/dist/dts/internal/common.d.ts.map +1 -1
  63. package/dist/dts/internal/stats.d.ts +15 -1
  64. package/dist/dts/internal/stats.d.ts.map +1 -1
  65. package/dist/dts/internal/summarize.d.ts +39 -7
  66. package/dist/dts/internal/summarize.d.ts.map +1 -1
  67. package/dist/dts/internal/test-repository-fixtures.d.ts +22 -0
  68. package/dist/dts/internal/test-repository-fixtures.d.ts.map +1 -0
  69. package/dist/dts/internal/test-repository-migrations.d.ts +11 -0
  70. package/dist/dts/internal/test-repository-migrations.d.ts.map +1 -0
  71. package/dist/dts/internal/test-result-stats.d.ts +7 -0
  72. package/dist/dts/internal/test-result-stats.d.ts.map +1 -0
  73. package/dist/esm/Classify.js +5 -1
  74. package/dist/esm/Classify.js.map +1 -1
  75. package/dist/esm/RepositoryError.js +14 -29
  76. package/dist/esm/RepositoryError.js.map +1 -1
  77. package/dist/esm/Show.js +2 -2
  78. package/dist/esm/Show.js.map +1 -1
  79. package/dist/esm/Test.js +38 -1
  80. package/dist/esm/Test.js.map +1 -1
  81. package/dist/esm/Test.repository.js +7 -16
  82. package/dist/esm/Test.repository.js.map +1 -1
  83. package/dist/esm/TestRun.js +13 -0
  84. package/dist/esm/TestRun.js.map +1 -0
  85. package/dist/esm/TestValueError.js +16 -0
  86. package/dist/esm/TestValueError.js.map +1 -0
  87. package/dist/esm/index.js +0 -1
  88. package/dist/esm/index.js.map +1 -1
  89. package/dist/esm/internal/Classify.js +0 -7
  90. package/dist/esm/internal/Classify.js.map +1 -1
  91. package/dist/esm/internal/Test.js +299 -108
  92. package/dist/esm/internal/Test.js.map +1 -1
  93. package/dist/esm/internal/Test.repository.sqlite.js +265 -301
  94. package/dist/esm/internal/Test.repository.sqlite.js.map +1 -1
  95. package/dist/esm/internal/Test.serialization.js +119 -0
  96. package/dist/esm/internal/Test.serialization.js.map +1 -0
  97. package/dist/esm/internal/common.js.map +1 -1
  98. package/dist/esm/internal/stats.js +35 -2
  99. package/dist/esm/internal/stats.js.map +1 -1
  100. package/dist/esm/internal/summarize.js +155 -35
  101. package/dist/esm/internal/summarize.js.map +1 -1
  102. package/dist/esm/internal/test-repository-fixtures.js +25 -0
  103. package/dist/esm/internal/test-repository-fixtures.js.map +1 -0
  104. package/dist/esm/internal/test-repository-migrations.js +62 -0
  105. package/dist/esm/internal/test-repository-migrations.js.map +1 -0
  106. package/dist/esm/internal/test-result-stats.js +83 -0
  107. package/dist/esm/internal/test-result-stats.js.map +1 -0
  108. package/package.json +1 -1
  109. package/dist/cjs/Test.repository.types.js +0 -14
  110. package/dist/cjs/Test.repository.types.js.map +0 -1
  111. package/dist/cjs/internal/lib/Schema.js +0 -14
  112. package/dist/cjs/internal/lib/Schema.js.map +0 -1
  113. package/dist/dts/Test.repository.types.d.ts +0 -56
  114. package/dist/dts/Test.repository.types.d.ts.map +0 -1
  115. package/dist/dts/internal/lib/Schema.d.ts +0 -4
  116. package/dist/dts/internal/lib/Schema.d.ts.map +0 -1
  117. package/dist/esm/Test.repository.types.js +0 -7
  118. package/dist/esm/Test.repository.types.js.map +0 -1
  119. package/dist/esm/internal/lib/Schema.js +0 -7
  120. 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
- Existing database files and stored test hashes keep the same format.
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
- // `makeClassify` customises how observed vs. expected results are
64
- // labelled. `isEqual` decides TP/TN vs FP/FN — here we tolerate a
65
- // 0.4 absolute error, so `1.7` passes for `2`, etc.
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
- > Omit `classify` to get default strict equality; then every non-exact result is labelled FP.
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
- #### Summarize
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
- │ SUMMARY │
103
- ├─────┬──────────┬────────┬──────┬───────┬──────────┬────────┬──────────────┤
104
- │ #/∑ │ hash │ ms │ tags │ input │ expected │ label₀ │ diff result₀ │
105
- ├─────┼──────────┼────────┼──────┼───────┼──────────┼────────┼──────────────┤
106
- │ 1/5 │ bd04cb2c │ 0.69ms │ │ 0 │ 0 │ TP │ │
107
- ├─────┼──────────┼────────┼──────┼───────┼──────────┼────────┼──────────────┤
108
- │ 2/5 │ 562e2cca │ 0.36ms │ │ 1 │ 2 │ TP │ 2 => 1.7 │
109
- ├─────┼──────────┼────────┼──────┼───────┼──────────┼────────┼──────────────┤
110
- │ 3/5 │ a5afd52f │ 3.30ms │ │ 2 │ 3 │ TP │ 3 => 3.4 │
111
- ├─────┼──────────┼────────┼──────┼───────┼──────────┼────────┼──────────────┤
112
- │ 4/5 │ 5f7f8725 │ 1.19ms │ │ 3 │ 4 │ FP │ 4 => 5.1 │
113
- ├─────┼──────────┼────────┼──────┼───────┼──────────┼────────┼──────────────┤
114
- │ 5/5 │ 6cc26923 │ 1.22ms │ │ 4 │ 5 │ FP │ 5 => 6.8 │
115
- ├─────┼──────────┼────────┼──────┼───────┼──────────┼────────┼──────────────┤
116
- │ #/∑ │ hash │ ms │ tags │ input │ expected │ label₀ │ diff result₀ │
117
- └─────┴──────────┴────────┴──────┴───────┴──────────┴────────┴──────────────┘
118
-
119
-
120
- ┌────────────────────────────────────────────────────────────────────┐
121
- │ STATS │
122
- ├───┬────┬────┬────┬────┬───────────┬────────┬──────────┬────────────┤
123
- │ ∑ │ TP │ TN │ FP │ FN │ precision │ recall │ timeMean │ timeMedian │
124
- ├───┼────┼────┼────┼────┼───────────┼────────┼──────────┼────────────┤
125
- │ 5 │ 3 │ 0 │ 2 │ 0 │ 0.60 │ 1.00 │ 1.35ms │ 1.19ms │
126
- ├───┼────┼────┼────┼────┼───────────┼────────┼──────────┼────────────┤
127
- │ ∑ │ TP │ TN │ FP │ FN │ precision │ recall │ timeMean │ timeMedian │
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
- #### Summarize With Labels Filter
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
- pnpx tsx my-test-suite.ts summarize --labels TP
189
+ This suite needs a schema for the whole BANT expectation and schemas for the
190
+ individual field values:
135
191
 
136
- ┌───────────────────────────────────────────────────────────────────────────┐
137
- │ SUMMARY │
138
- ├─────┬──────────┬────────┬──────┬───────┬──────────┬────────┬──────────────┤
139
- │ #/∑ │ hash │ ms │ tags │ input │ expected │ label₀ │ diff result₀ │
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
- #### Summarize With Tag Filters
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
- `--tags` includes results matching ANY of the listed tags (OR):
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
- pnpx tsx my-test-suite.ts summarize --tags foo,bar
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
- `--all-tags` includes results matching ALL listed tags (AND):
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
- pnpx tsx my-test-suite.ts summarize --all-tags foo,bar
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
- Both flags compose with `--labels`.
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
- `--cached` reads the most recently inserted test results from the local DB
181
- instead of re-running the program. This is useful when you want to re-format
182
- or re-filter without incurring the cost of a full run:
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
- pnpx tsx my-test-suite.ts summarize --cached
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/tots-cli';
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
- void CLI.run({
352
+ CLI.run({
215
353
  testSuite: {
216
354
  ```
217
355
 
218
- ```
356
+ ```sh
219
357
  pnpx tsx my-test-suite.ts diff
220
- # or, if you want it to process.exit(1) on diff
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
- Checkout `workspace/examples/src/with-cli` for more examples.
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
- pnpx tsx <file-path>
266
- # e.g.
267
- pnpx tsx ./workspace/examples/src/with-cli/simple-run.ts
268
- pnpx tsx ./workspace/examples/src/with-cli/simple-effect.ts
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
- If you compose the CLI's `diff` programmatically (via `_diff` or a custom
322
- harness), `diff --exit-on-diff` fails with a typed `DiffNonEmpty` error
323
- when the current run has visible diffs:
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"
@@ -3,22 +3,25 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.values = exports.makeClassify = exports.defaultIsNil = exports.defaultIsEqual = exports.Stats = exports.LabelSchema = void 0;
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(),
@@ -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","defaultIsEqual","defaultIsNil","makeClassify","Stats","Schema","Class","TP","Finite","TN","FP","FN","total","precision","recall","timeMin","Option","timeMax","timeMedian","timeMean","empty","none"],"sources":["../../src/Classify.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
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.TestRunNotCreated = exports.RepositoryWriteError = exports.RepositoryQueryError = exports.RepositoryDecodeError = void 0;
7
- var _SqlError = /*#__PURE__*/require("effect/sql/SqlError");
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
- const SqlCause = /*#__PURE__*/_effect.Schema.Union([/*#__PURE__*/_effect.Schema.instanceOf(_SqlError.SqlError), /*#__PURE__*/_effect.Schema.instanceOf(_SqlError.ResultLengthMismatch)]);
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