@creative-introvert/tons-of-tests 1.2.0 → 2.1.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 (202) hide show
  1. package/README.md +200 -134
  2. package/dist/cjs/Classify.js +18 -31
  3. package/dist/cjs/Classify.js.map +1 -1
  4. package/dist/cjs/DisplayConfig.js +2 -20
  5. package/dist/cjs/DisplayConfig.js.map +1 -1
  6. package/dist/cjs/RepositoryError.js +4 -5
  7. package/dist/cjs/RepositoryError.js.map +1 -1
  8. package/dist/cjs/Test.js +7 -21
  9. package/dist/cjs/Test.js.map +1 -1
  10. package/dist/cjs/Test.repository.js +3 -21
  11. package/dist/cjs/Test.repository.js.map +1 -1
  12. package/dist/cjs/Test.repository.types.js.map +1 -1
  13. package/dist/cjs/index.js +2 -20
  14. package/dist/cjs/index.js.map +1 -1
  15. package/dist/cjs/internal/Classify.js +2 -2
  16. package/dist/cjs/internal/Classify.js.map +1 -1
  17. package/dist/cjs/internal/Test.js +123 -80
  18. package/dist/cjs/internal/Test.js.map +1 -1
  19. package/dist/cjs/internal/Test.repository.sqlite.js +118 -79
  20. package/dist/cjs/internal/Test.repository.sqlite.js.map +1 -1
  21. package/dist/cjs/internal/common.js +1 -5
  22. package/dist/cjs/internal/common.js.map +1 -1
  23. package/dist/cjs/internal/diff.js +1 -5
  24. package/dist/cjs/internal/diff.js.map +1 -1
  25. package/dist/cjs/internal/format-diff.js +2 -6
  26. package/dist/cjs/internal/format-diff.js.map +1 -1
  27. package/dist/cjs/internal/lib/Schema.js +3 -3
  28. package/dist/cjs/internal/lib/Schema.js.map +1 -1
  29. package/dist/cjs/internal/lib/jsondiffpatch/contexts/diff.js +1 -5
  30. package/dist/cjs/internal/lib/jsondiffpatch/contexts/diff.js.map +1 -1
  31. package/dist/cjs/internal/lib/jsondiffpatch/contexts/patch.js +1 -5
  32. package/dist/cjs/internal/lib/jsondiffpatch/contexts/patch.js.map +1 -1
  33. package/dist/cjs/internal/lib/jsondiffpatch/contexts/reverse.js +1 -5
  34. package/dist/cjs/internal/lib/jsondiffpatch/contexts/reverse.js.map +1 -1
  35. package/dist/cjs/internal/lib/jsondiffpatch/diffpatcher.js +3 -25
  36. package/dist/cjs/internal/lib/jsondiffpatch/diffpatcher.js.map +1 -1
  37. package/dist/cjs/internal/lib/jsondiffpatch/filters/arrays.js +1 -5
  38. package/dist/cjs/internal/lib/jsondiffpatch/filters/arrays.js.map +1 -1
  39. package/dist/cjs/internal/lib/jsondiffpatch/filters/nested.js +1 -5
  40. package/dist/cjs/internal/lib/jsondiffpatch/filters/nested.js.map +1 -1
  41. package/dist/cjs/internal/lib/jsondiffpatch/formatters/annotated.js +1 -5
  42. package/dist/cjs/internal/lib/jsondiffpatch/formatters/annotated.js.map +1 -1
  43. package/dist/cjs/internal/lib/jsondiffpatch/formatters/html.js +1 -5
  44. package/dist/cjs/internal/lib/jsondiffpatch/formatters/html.js.map +1 -1
  45. package/dist/cjs/internal/lib/jsondiffpatch/formatters/jsonpatch.js +1 -5
  46. package/dist/cjs/internal/lib/jsondiffpatch/formatters/jsonpatch.js.map +1 -1
  47. package/dist/cjs/internal/lib/jsondiffpatch/index.js +1 -5
  48. package/dist/cjs/internal/lib/jsondiffpatch/index.js.map +1 -1
  49. package/dist/cjs/internal/lib/jsondiffpatch/with-text-diffs.js +1 -5
  50. package/dist/cjs/internal/lib/jsondiffpatch/with-text-diffs.js.map +1 -1
  51. package/dist/cjs/internal/pack.js +28 -50
  52. package/dist/cjs/internal/pack.js.map +1 -1
  53. package/dist/cjs/internal/stats.js +9 -7
  54. package/dist/cjs/internal/stats.js.map +1 -1
  55. package/dist/cjs/internal/summarize.js +19 -18
  56. package/dist/cjs/internal/summarize.js.map +1 -1
  57. package/dist/cjs/package.json +1 -0
  58. package/dist/dts/Classify.d.ts +24 -57
  59. package/dist/dts/Classify.d.ts.map +1 -1
  60. package/dist/dts/DisplayConfig.d.ts +2 -1
  61. package/dist/dts/DisplayConfig.d.ts.map +1 -1
  62. package/dist/dts/RepositoryError.d.ts +21 -22
  63. package/dist/dts/RepositoryError.d.ts.map +1 -1
  64. package/dist/dts/Show.d.ts +3 -3
  65. package/dist/dts/Show.d.ts.map +1 -1
  66. package/dist/dts/Test.d.ts +53 -23
  67. package/dist/dts/Test.d.ts.map +1 -1
  68. package/dist/dts/Test.repository.d.ts +4 -4
  69. package/dist/dts/Test.repository.d.ts.map +1 -1
  70. package/dist/dts/Test.repository.types.d.ts +16 -20
  71. package/dist/dts/Test.repository.types.d.ts.map +1 -1
  72. package/dist/dts/internal/Classify.d.ts +1 -1
  73. package/dist/dts/internal/Classify.d.ts.map +1 -1
  74. package/dist/dts/internal/Test.d.ts +24 -12
  75. package/dist/dts/internal/Test.d.ts.map +1 -1
  76. package/dist/dts/internal/Test.repository.sqlite.d.ts +3 -2
  77. package/dist/dts/internal/Test.repository.sqlite.d.ts.map +1 -1
  78. package/dist/dts/internal/lib/Schema.d.ts +2 -2
  79. package/dist/dts/internal/lib/Schema.d.ts.map +1 -1
  80. package/dist/dts/internal/lib/jsondiffpatch/filters/lcs.d.ts +2 -1
  81. package/dist/dts/internal/lib/jsondiffpatch/filters/lcs.d.ts.map +1 -1
  82. package/dist/dts/internal/pack.d.ts.map +1 -1
  83. package/dist/dts/internal/stats.d.ts.map +1 -1
  84. package/dist/dts/internal/summarize.d.ts.map +1 -1
  85. package/dist/esm/Classify.js +28 -50
  86. package/dist/esm/Classify.js.map +1 -1
  87. package/dist/esm/DisplayConfig.js +2 -28
  88. package/dist/esm/DisplayConfig.js.map +1 -1
  89. package/dist/esm/RepositoryError.js +13 -24
  90. package/dist/esm/RepositoryError.js.map +1 -1
  91. package/dist/esm/Show.js +3 -26
  92. package/dist/esm/Show.js.map +1 -1
  93. package/dist/esm/Test.js +9 -12
  94. package/dist/esm/Test.js.map +1 -1
  95. package/dist/esm/Test.repository.js +8 -41
  96. package/dist/esm/Test.repository.js.map +1 -1
  97. package/dist/esm/Test.repository.types.js +5 -12
  98. package/dist/esm/Test.repository.types.js.map +1 -1
  99. package/dist/esm/index.js +7 -45
  100. package/dist/esm/index.js.map +1 -1
  101. package/dist/esm/internal/Classify.js +16 -31
  102. package/dist/esm/internal/Classify.js.map +1 -1
  103. package/dist/esm/internal/DisplayConfig.js +1 -8
  104. package/dist/esm/internal/DisplayConfig.js.map +1 -1
  105. package/dist/esm/internal/Test.js +144 -113
  106. package/dist/esm/internal/Test.js.map +1 -1
  107. package/dist/esm/internal/Test.repository.sqlite.js +186 -160
  108. package/dist/esm/internal/Test.repository.sqlite.js.map +1 -1
  109. package/dist/esm/internal/common.js +15 -32
  110. package/dist/esm/internal/common.js.map +1 -1
  111. package/dist/esm/internal/diff.js +18 -30
  112. package/dist/esm/internal/diff.js.map +1 -1
  113. package/dist/esm/internal/format-diff.js +9 -22
  114. package/dist/esm/internal/format-diff.js.map +1 -1
  115. package/dist/esm/internal/lib/Schema.js +4 -11
  116. package/dist/esm/internal/lib/Schema.js.map +1 -1
  117. package/dist/esm/internal/lib/jsondiffpatch/clone.js +1 -7
  118. package/dist/esm/internal/lib/jsondiffpatch/clone.js.map +1 -1
  119. package/dist/esm/internal/lib/jsondiffpatch/contexts/context.js +1 -8
  120. package/dist/esm/internal/lib/jsondiffpatch/contexts/context.js.map +1 -1
  121. package/dist/esm/internal/lib/jsondiffpatch/contexts/diff.js +5 -16
  122. package/dist/esm/internal/lib/jsondiffpatch/contexts/diff.js.map +1 -1
  123. package/dist/esm/internal/lib/jsondiffpatch/contexts/patch.js +3 -14
  124. package/dist/esm/internal/lib/jsondiffpatch/contexts/patch.js.map +1 -1
  125. package/dist/esm/internal/lib/jsondiffpatch/contexts/reverse.js +3 -14
  126. package/dist/esm/internal/lib/jsondiffpatch/contexts/reverse.js.map +1 -1
  127. package/dist/esm/internal/lib/jsondiffpatch/date-reviver.js +1 -7
  128. package/dist/esm/internal/lib/jsondiffpatch/date-reviver.js.map +1 -1
  129. package/dist/esm/internal/lib/jsondiffpatch/diffpatcher.js +20 -51
  130. package/dist/esm/internal/lib/jsondiffpatch/diffpatcher.js.map +1 -1
  131. package/dist/esm/internal/lib/jsondiffpatch/filters/arrays.js +16 -28
  132. package/dist/esm/internal/lib/jsondiffpatch/filters/arrays.js.map +1 -1
  133. package/dist/esm/internal/lib/jsondiffpatch/filters/dates.js +1 -7
  134. package/dist/esm/internal/lib/jsondiffpatch/filters/dates.js.map +1 -1
  135. package/dist/esm/internal/lib/jsondiffpatch/filters/lcs.js +1 -7
  136. package/dist/esm/internal/lib/jsondiffpatch/filters/lcs.js.map +1 -1
  137. package/dist/esm/internal/lib/jsondiffpatch/filters/nested.js +13 -27
  138. package/dist/esm/internal/lib/jsondiffpatch/filters/nested.js.map +1 -1
  139. package/dist/esm/internal/lib/jsondiffpatch/filters/texts.js +3 -9
  140. package/dist/esm/internal/lib/jsondiffpatch/filters/texts.js.map +1 -1
  141. package/dist/esm/internal/lib/jsondiffpatch/filters/trivial.js +3 -9
  142. package/dist/esm/internal/lib/jsondiffpatch/filters/trivial.js.map +1 -1
  143. package/dist/esm/internal/lib/jsondiffpatch/formatters/annotated.js +4 -16
  144. package/dist/esm/internal/lib/jsondiffpatch/formatters/annotated.js.map +1 -1
  145. package/dist/esm/internal/lib/jsondiffpatch/formatters/base.js +1 -7
  146. package/dist/esm/internal/lib/jsondiffpatch/formatters/base.js.map +1 -1
  147. package/dist/esm/internal/lib/jsondiffpatch/formatters/html.js +6 -21
  148. package/dist/esm/internal/lib/jsondiffpatch/formatters/html.js.map +1 -1
  149. package/dist/esm/internal/lib/jsondiffpatch/formatters/jsonpatch.js +6 -20
  150. package/dist/esm/internal/lib/jsondiffpatch/formatters/jsonpatch.js.map +1 -1
  151. package/dist/esm/internal/lib/jsondiffpatch/index.js +15 -42
  152. package/dist/esm/internal/lib/jsondiffpatch/index.js.map +1 -1
  153. package/dist/esm/internal/lib/jsondiffpatch/pipe.js +1 -7
  154. package/dist/esm/internal/lib/jsondiffpatch/pipe.js.map +1 -1
  155. package/dist/esm/internal/lib/jsondiffpatch/processor.js +1 -7
  156. package/dist/esm/internal/lib/jsondiffpatch/processor.js.map +1 -1
  157. package/dist/esm/internal/lib/jsondiffpatch/types.js +1 -6
  158. package/dist/esm/internal/lib/jsondiffpatch/with-text-diffs.js +22 -49
  159. package/dist/esm/internal/lib/jsondiffpatch/with-text-diffs.js.map +1 -1
  160. package/dist/esm/internal/pack.js +26 -55
  161. package/dist/esm/internal/pack.js.map +1 -1
  162. package/dist/esm/internal/stats.js +29 -35
  163. package/dist/esm/internal/stats.js.map +1 -1
  164. package/dist/esm/internal/summarize.js +45 -52
  165. package/dist/esm/internal/summarize.js.map +1 -1
  166. package/package.json +11 -9
  167. package/dist/cjs/Error.js +0 -10
  168. package/dist/cjs/Error.js.map +0 -1
  169. package/dist/cjs/internal/Classify.spec.js +0 -223
  170. package/dist/cjs/internal/Classify.spec.js.map +0 -1
  171. package/dist/cjs/internal/Test.repository.sqlite.spec.js +0 -294
  172. package/dist/cjs/internal/Test.repository.sqlite.spec.js.map +0 -1
  173. package/dist/cjs/internal/Test.spec.js +0 -260
  174. package/dist/cjs/internal/Test.spec.js.map +0 -1
  175. package/dist/cjs/internal/format-diff.spec.js +0 -103
  176. package/dist/cjs/internal/format-diff.spec.js.map +0 -1
  177. package/dist/cjs/pack.js +0 -28
  178. package/dist/cjs/pack.js.map +0 -1
  179. package/dist/dts/Error.d.ts +0 -10
  180. package/dist/dts/Error.d.ts.map +0 -1
  181. package/dist/dts/internal/Classify.spec.d.ts +0 -2
  182. package/dist/dts/internal/Classify.spec.d.ts.map +0 -1
  183. package/dist/dts/internal/Test.repository.sqlite.spec.d.ts +0 -2
  184. package/dist/dts/internal/Test.repository.sqlite.spec.d.ts.map +0 -1
  185. package/dist/dts/internal/Test.spec.d.ts +0 -2
  186. package/dist/dts/internal/Test.spec.d.ts.map +0 -1
  187. package/dist/dts/internal/format-diff.spec.d.ts +0 -2
  188. package/dist/dts/internal/format-diff.spec.d.ts.map +0 -1
  189. package/dist/dts/pack.d.ts +0 -2
  190. package/dist/dts/pack.d.ts.map +0 -1
  191. package/dist/esm/Error.js +0 -10
  192. package/dist/esm/Error.js.map +0 -1
  193. package/dist/esm/internal/Classify.spec.js +0 -223
  194. package/dist/esm/internal/Classify.spec.js.map +0 -1
  195. package/dist/esm/internal/Test.repository.sqlite.spec.js +0 -294
  196. package/dist/esm/internal/Test.repository.sqlite.spec.js.map +0 -1
  197. package/dist/esm/internal/Test.spec.js +0 -241
  198. package/dist/esm/internal/Test.spec.js.map +0 -1
  199. package/dist/esm/internal/format-diff.spec.js +0 -103
  200. package/dist/esm/internal/format-diff.spec.js.map +0 -1
  201. package/dist/esm/pack.js +0 -28
  202. package/dist/esm/pack.js.map +0 -1
package/README.md CHANGED
@@ -24,6 +24,11 @@ A specialized test runner for predictive functions, focusing on scenarios where
24
24
 
25
25
  ## Getting Started
26
26
 
27
+ Use Node.js 24 or newer and Effect 4. The Effect packages in this repository
28
+ use the same exact version. The SQLite driver uses Node's built-in SQLite.
29
+ Existing database files are migrated when opened. Previously stored results
30
+ receive the key `result`; their test case hashes stay the same.
31
+
27
32
  ### Installation
28
33
 
29
34
  Install the required packages with your preferred package manager:
@@ -45,6 +50,10 @@ import * as CLI from '@creative-introvert/tons-of-tests-cli';
45
50
  import {Effect} from 'effect';
46
51
 
47
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
+ });
48
57
 
49
58
  CLI.run({
50
59
  testSuite: {
@@ -56,12 +65,9 @@ CLI.run({
56
65
  {input: 3, expected: 4},
57
66
  {input: 4, expected: 5},
58
67
  ],
59
- // `makeClassify` customises how observed vs. expected results are
60
- // labelled. `isEqual` decides TP/TN vs FP/FN — here we tolerate a
61
- // 0.4 absolute error, so `1.7` passes for `2`, etc.
62
- classify: Classify.makeClassify({
63
- isEqual: (a, b) => Math.abs(b - a) <= 0.4,
64
- }),
68
+ evaluate: (result, expected) => [
69
+ {key: 'result', result, expected, label: classify(result, expected)},
70
+ ],
65
71
  program: (input: number) => Effect.promise(() => myFunction(input)),
66
72
  },
67
73
  dbPath: 'with-cli-simple.db',
@@ -69,7 +75,10 @@ CLI.run({
69
75
  });
70
76
  ```
71
77
 
72
- > Omit `classify` to get default strict equality; then every non-exact result is labelled FP.
78
+ Omit `evaluate` to compare the whole output with the expected value using
79
+ `Classify.defaultIsEqual`. The default evaluator returns one result with key
80
+ `result`. `Classify.makeClassify` returns a label for one comparison; use it
81
+ inside `evaluate` when you want to choose how values match.
73
82
 
74
83
  `testCases` can also be an Effect `Stream`, which is useful for large or generated suites that are consumed lazily by the runner:
75
84
 
@@ -89,96 +98,146 @@ CLI.run({
89
98
  });
90
99
  ```
91
100
 
92
- #### Summarize
101
+ ### Multiple Results From One Test Case
102
+
103
+ Use `evaluate` to track parts of one program output separately. The runner calls
104
+ `program` once per test case, then passes its output and the case's expected
105
+ value to `evaluate`.
106
+
107
+ For a BANT inference, the evaluator can return a result for each of budget,
108
+ authority, need, and timeline:
93
109
 
110
+ ```ts
111
+ import {Classify, type Test} from '@creative-introvert/tons-of-tests';
112
+ import {Array} from 'effect';
113
+
114
+ type Bant = {
115
+ readonly budget: string | null;
116
+ readonly authority: string | null;
117
+ readonly need: string | null;
118
+ readonly timeline: string | null;
119
+ };
120
+
121
+ const fields = ['budget', 'authority', 'need', 'timeline'] as const;
122
+ const classify = Classify.makeClassify({isEqual: Classify.defaultIsEqual});
123
+
124
+ const evaluate: Test.Evaluate<Bant, Bant, string | null, string | null> = (
125
+ output,
126
+ expected,
127
+ ) =>
128
+ Array.map(fields, key => ({
129
+ key,
130
+ result: output[key],
131
+ expected: expected[key],
132
+ label: classify(output[key], expected[key]),
133
+ }));
94
134
  ```
95
- pnpx tsx my-test-suite.ts summarize
96
135
 
97
- ┌───────────────────────────────────────────────────────────────────────────┐
98
- │ SUMMARY │
99
- ├─────┬──────────┬────────┬──────┬───────┬──────────┬────────┬──────────────┤
100
- │ #/∑ │ hash │ ms │ tags │ input │ expected │ label₀ │ diff result₀ │
101
- ├─────┼──────────┼────────┼──────┼───────┼──────────┼────────┼──────────────┤
102
- │ 1/5 │ bd04cb2c │ 0.69ms │ │ 0 │ 0 │ TP │ │
103
- ├─────┼──────────┼────────┼──────┼───────┼──────────┼────────┼──────────────┤
104
- │ 2/5 │ 562e2cca │ 0.36ms │ │ 1 │ 2 │ TP │ 2 => 1.7 │
105
- ├─────┼──────────┼────────┼──────┼───────┼──────────┼────────┼──────────────┤
106
- │ 3/5 │ a5afd52f │ 3.30ms │ │ 2 │ 3 │ TP │ 3 => 3.4 │
107
- ├─────┼──────────┼────────┼──────┼───────┼──────────┼────────┼──────────────┤
108
- │ 4/5 │ 5f7f8725 │ 1.19ms │ │ 3 │ 4 │ FP │ 4 => 5.1 │
109
- ├─────┼──────────┼────────┼──────┼───────┼──────────┼────────┼──────────────┤
110
- │ 5/5 │ 6cc26923 │ 1.22ms │ │ 4 │ 5 │ FP │ 5 => 6.8 │
111
- ├─────┼──────────┼────────┼──────┼───────┼──────────┼────────┼──────────────┤
112
- │ #/∑ │ hash │ ms │ tags │ input │ expected │ label₀ │ diff result₀ │
113
- └─────┴──────────┴────────┴──────┴───────┴──────────┴────────┴──────────────┘
114
-
115
-
116
- ┌────────────────────────────────────────────────────────────────────┐
117
- │ STATS │
118
- ├───┬────┬────┬────┬────┬───────────┬────────┬──────────┬────────────┤
119
- │ ∑ │ TP │ TN │ FP │ FN │ precision │ recall │ timeMean │ timeMedian │
120
- ├───┼────┼────┼────┼────┼───────────┼────────┼──────────┼────────────┤
121
- │ 5 │ 3 │ 0 │ 2 │ 0 │ 0.60 │ 1.00 │ 1.35ms │ 1.19ms │
122
- ├───┼────┼────┼────┼────┼───────────┼────────┼──────────┼────────────┤
123
- │ ∑ │ TP │ TN │ FP │ FN │ precision │ recall │ timeMean │ timeMedian │
124
- └───┴────┴────┴────┴────┴───────────┴────────┴──────────┴────────────┘
136
+ Pass `evaluate` alongside `program` in the test suite. See the runnable
137
+ [multiple-results.ts example](./workspace/examples/src/with-cli/multiple-results.ts)
138
+ for a complete suite using a fixed response in place of an LLM call.
139
+
140
+ `evaluate` is a pure function. It must return a non-empty readonly array of
141
+ `Test.EvaluationResult` values. Each value has a `key`, `result`, `expected`, and
142
+ `label`. Keys must be non-empty and unique within the case. Keep keys stable
143
+ across runs so the CLI can match each result to its previous value.
144
+
145
+ The CLI shows one row per result in the existing table. Rows from the same case
146
+ stay next to each other and share the same `hash`. The `key` column identifies
147
+ each result. The hash comes from the original input and expected value; each
148
+ result is matched across runs by that hash and its key.
149
+
150
+ For the BANT example, these columns show the shared case hash (other columns
151
+ are omitted here):
152
+
153
+ ```text
154
+ ┌──────────┬───────────┬───────┐
155
+ │ hash │ key │ label │
156
+ ├──────────┼───────────┼───────┤
157
+ │ 688c8d1f │ budget │ FP │
158
+ ├──────────┼───────────┼───────┤
159
+ │ 688c8d1f │ authority │ TP │
160
+ ├──────────┼───────────┼───────┤
161
+ │ 688c8d1f │ need │ TP │
162
+ ├──────────┼───────────┼───────┤
163
+ │ 688c8d1f │ timeline │ FN │
164
+ └──────────┴───────────┴───────┘
125
165
  ```
126
166
 
127
- #### Summarize With Labels Filter
167
+ The statistics count cases and results separately. Labels, precision, and recall
168
+ count visible results. Timing statistics count each visible case once, even when
169
+ it has several result rows.
128
170
 
129
- ```
130
- pnpx tsx my-test-suite.ts summarize --labels TP
171
+ If you supply `testSuite.schemas`, `input` describes the original input.
172
+ `result` and `expected` describe the values returned by `evaluate`. For this
173
+ BANT example, both use `Schema.NullOr(Schema.String)` because each result is one
174
+ field, even though the program returns a full BANT object.
175
+
176
+ #### Updating Suites That Use `classify`
131
177
 
132
- ┌───────────────────────────────────────────────────────────────────────────┐
133
- │ SUMMARY │
134
- ├─────┬──────────┬────────┬──────┬───────┬──────────┬────────┬──────────────┤
135
- │ #/∑ │ hash │ ms │ tags │ input │ expected │ label₀ │ diff result₀ │
136
- ├─────┼──────────┼────────┼──────┼───────┼──────────┼────────┼──────────────┤
137
- │ 1/3 │ bd04cb2c │ 0.52ms │ │ 0 │ 0 │ TP │ │
138
- ├─────┼──────────┼────────┼──────┼───────┼──────────┼────────┼──────────────┤
139
- │ 2/3 │ 562e2cca │ 0.41ms │ │ 1 │ 2 │ TP │ 2 => 1.7 │
140
- ├─────┼──────────┼────────┼──────┼───────┼──────────┼────────┼──────────────┤
141
- │ 3/3 │ a5afd52f │ 0.74ms │ │ 2 │ 3 │ TP │ 3 => 3.4 │
142
- ├─────┼──────────┼────────┼──────┼───────┼──────────┼────────┼──────────────┤
143
- │ #/∑ │ hash │ ms │ tags │ input │ expected │ label₀ │ diff result₀ │
144
- └─────┴──────────┴────────┴──────┴───────┴──────────┴────────┴──────────────┘
145
-
146
-
147
- ┌────────────────────────────────────────────────────────────────────┐
148
- │ STATS │
149
- ├───┬────┬────┬────┬────┬───────────┬────────┬──────────┬────────────┤
150
- │ ∑ │ TP │ TN │ FP │ FN │ precision │ recall │ timeMean │ timeMedian │
151
- ├───┼────┼────┼────┼────┼───────────┼────────┼──────────┼────────────┤
152
- │ 5 │ 3 │ 0 │ 2 │ 0 │ 0.60 │ 1.00 │ 1.23ms │ 1.28ms │
153
- ├───┼────┼────┼────┼────┼───────────┼────────┼──────────┼────────────┤
154
- │ ∑ │ TP │ TN │ FP │ FN │ precision │ recall │ timeMean │ timeMedian │
155
- └───┴────┴────┴────┴────┴───────────┴────────┴──────────┴────────────┘
178
+ Replace the suite's `classify` property with an `evaluate` callback. Keep the
179
+ classifier and wrap its label in a result, as shown in the basic example:
180
+
181
+ ```ts
182
+ evaluate: (result, expected) => [
183
+ {key: 'result', result, expected, label: classify(result, expected)},
184
+ ],
156
185
  ```
157
186
 
158
- #### Summarize With Tag Filters
187
+ Suites that use the default comparison and omit `classify` need no changes.
188
+ Cached results keep their saved values and labels. Run the suite again after
189
+ changing `evaluate` to produce new results.
159
190
 
160
- `--tags` includes results matching ANY of the listed tags (OR):
191
+ The same `schemas` decode current and previous runs. If you change the stored
192
+ result or expected-value shape and your schemas cannot read older values, use
193
+ a new suite name for the new shape.
161
194
 
195
+ ### CLI Commands
196
+
197
+ #### Summarize
198
+
199
+ ```sh
200
+ pnpx tsx my-test-suite.ts summarize
162
201
  ```
163
- pnpx tsx my-test-suite.ts summarize --tags foo,bar
164
- ```
165
202
 
166
- `--all-tags` includes results matching ALL listed tags (AND):
203
+ #### Filter Results
204
+
205
+ Both `summarize` and `diff` accept these filters:
206
+
207
+ | Flag | Includes a result when… |
208
+ | --- | --- |
209
+ | `--keys budget,need` | Its key is `budget` or `need`. |
210
+ | `--labels FP,FN` | Its current label is `FP` or `FN`. |
211
+ | `--tags enterprise,german` | Its case has either tag. |
212
+ | `--all-tags enterprise,german` | Its case has both tags. |
213
+
214
+ Different flags combine with AND. For example, show budget errors from
215
+ enterprise cases:
167
216
 
217
+ ```sh
218
+ pnpx tsx bant-suite.ts summarize --keys budget --labels FP,FN --tags enterprise
168
219
  ```
169
- pnpx tsx my-test-suite.ts summarize --all-tags foo,bar
220
+
221
+ For the basic example, show matching results:
222
+
223
+ ```sh
224
+ pnpx tsx my-test-suite.ts summarize --labels TP
170
225
  ```
171
226
 
172
- Both flags compose with `--labels`.
227
+ Filters change the displayed rows and statistics. The CLI runs and saves all
228
+ evaluations before applying them, so filtering does not discard saved results
229
+ or reduce the number of program calls. No matches produces an empty view;
230
+ `summarize` also reports zero counts.
173
231
 
174
232
  #### Summarize From Cache
175
233
 
176
- `--cached` reads the most recently inserted test results from the local DB
177
- instead of re-running the program. This is useful when you want to re-format
178
- or re-filter without incurring the cost of a full run:
234
+ When results for the current run are already saved, `--cached` reads them
235
+ without re-running the program or evaluator. If no cached results exist, it
236
+ runs and saves the suite. After the first run, use it to inspect other keys
237
+ without making another inference call:
179
238
 
180
- ```
181
- pnpx tsx my-test-suite.ts summarize --cached
239
+ ```sh
240
+ pnpx tsx bant-suite.ts summarize --cached --keys budget,need
182
241
  ```
183
242
 
184
243
  `diff --cached` behaves the same way for the current-run side of the diff.
@@ -192,6 +251,7 @@ pnpx tsx my-test-suite.ts commit
192
251
  #### Diff
193
252
 
194
253
  The diff command compares your current test results with previously committed results. This is useful when you've made changes to either:
254
+
195
255
  - Your test suite's inputs or expected values
196
256
  - The implementation of the function being tested
197
257
 
@@ -201,67 +261,40 @@ index 21cd713..ab1b6dc 100644
201
261
  --- a/my-test-suite.ts
202
262
  +++ b/my-test-suite.ts
203
263
  @@ -1,7 +1,7 @@
204
- import * as CLI from '@creative-introvert/tots-cli';
264
+ import * as CLI from '@creative-introvert/tons-of-tests-cli';
205
265
  import {Effect} from 'effect';
206
266
 
207
267
  -const myFunction = (input: number) => Promise.resolve(input * 1.7);
208
268
  +const myFunction = (input: number) => Promise.resolve(input * 2);
209
269
 
210
- void CLI.run({
270
+ CLI.run({
211
271
  testSuite: {
212
272
  ```
213
273
 
214
- ```
274
+ ```sh
215
275
  pnpx tsx my-test-suite.ts diff
216
- # or, if you want it to process.exit(1) on diff
276
+ # Exit with code 1 when the filtered view contains differences.
217
277
  pnpx tsx my-test-suite.ts diff --exit-on-diff
218
-
219
- ┌─────────────────────────────────────────────────────────────────────────────────────────────────────┐
220
- │ SUMMARY │
221
- ├─────┬──────────┬────────┬──────┬───────┬──────────┬────────┬──────────────┬─────────┬───────────────┤
222
- │ #/∑ │ hash │ ms │ tags │ input │ expected │ label₀ │ diff result₀ │ label₋₁ │ diff result₋₁ │
223
- ├─────┼──────────┼────────┼──────┼───────┼──────────┼────────┼──────────────┼─────────┼───────────────┤
224
- │ 1/4 │ 562e2cca │ 0.23ms │ │ 1 │ 2 │ TP │ │ FP │ 2 => 1.7 │
225
- ├─────┼──────────┼────────┼──────┼───────┼──────────┼────────┼──────────────┼─────────┼───────────────┤
226
- │ 2/4 │ a5afd52f │ 3.66ms │ │ 2 │ 3 │ FP │ 3 => 4 │ FP │ 3 => 3.4 │
227
- ├─────┼──────────┼────────┼──────┼───────┼──────────┼────────┼──────────────┼─────────┼───────────────┤
228
- │ 3/4 │ 5f7f8725 │ 1.19ms │ │ 3 │ 4 │ FP │ 4 => 6 │ FP │ 4 => 5.1 │
229
- ├─────┼──────────┼────────┼──────┼───────┼──────────┼────────┼──────────────┼─────────┼───────────────┤
230
- │ 4/4 │ 6cc26923 │ 0.98ms │ │ 4 │ 5 │ FP │ 5 => 8 │ FP │ 5 => 6.8 │
231
- ├─────┼──────────┼────────┼──────┼───────┼──────────┼────────┼──────────────┼─────────┼───────────────┤
232
- │ #/∑ │ hash │ ms │ tags │ input │ expected │ label₀ │ diff result₀ │ label₋₁ │ diff result₋₁ │
233
- └─────┴──────────┴────────┴──────┴───────┴──────────┴────────┴──────────────┴─────────┴───────────────┘
234
-
235
-
236
- ┌────────────────────────────────────────────────────────────────────┐
237
- │ STATS │
238
- ├───┬────┬────┬────┬────┬───────────┬────────┬──────────┬────────────┤
239
- │ ∑ │ TP │ TN │ FP │ FN │ precision │ recall │ timeMean │ timeMedian │
240
- ├───┼────┼────┼────┼────┼───────────┼────────┼──────────┼────────────┤
241
- │ 5 │ 2 │ 0 │ 3 │ 0 │ 0.40 │ 1.00 │ 1.30ms │ 0.98ms │
242
- ├───┼────┼────┼────┼────┼───────────┼────────┼──────────┼────────────┤
243
- │ ∑ │ TP │ TN │ FP │ FN │ precision │ recall │ timeMean │ timeMedian │
244
- └───┴────┴────┴────┴────┴───────────┴────────┴──────────┴────────────┘
245
-
246
-
247
- ┌────────────────────────────────────────┐
248
- │ DIFF │
249
- ├────┬────┬────┬────┬───────────┬────────┤
250
- │ TP │ TN │ FP │ FN │ precision │ recall │
251
- ├────┼────┼────┼────┼───────────┼────────┤
252
- │ 1 │ 0 │ -1 │ 0 │ 0.20 │ 0.00 │
253
- ├────┼────┼────┼────┼───────────┼────────┤
254
- │ TP │ TN │ FP │ FN │ precision │ recall │
255
- └────┴────┴────┴────┴───────────┴────────┘
256
278
  ```
257
279
 
258
- Checkout `workspace/examples/src/with-cli` for more examples.
280
+ For a suite with several results per case, select the keys to compare:
259
281
 
282
+ ```sh
283
+ pnpx tsx bant-suite.ts diff --keys budget --labels FP,FN
260
284
  ```
261
- pnpx tsx <file-path>
262
- # e.g.
263
- pnpx tsx ./workspace/examples/src/with-cli/simple-run.ts
264
- pnpx tsx ./workspace/examples/src/with-cli/simple-effect.ts
285
+
286
+ `diff` matches results by case hash and key before applying filters. It includes
287
+ new results and changes to a result's value, expected value, or label. A current
288
+ `FP` result keeps its previous value and label even when that previous label
289
+ does not match `--labels`.
290
+
291
+ See [workspace/examples/src/with-cli](./workspace/examples/src/with-cli) for
292
+ more examples. From the repository root, run:
293
+
294
+ ```sh
295
+ direnv exec . pnpm exec tsx workspace/examples/src/with-cli/simple-run.ts summarize
296
+ direnv exec . pnpm exec tsx workspace/examples/src/with-cli/simple-effect.ts
297
+ direnv exec . pnpm exec tsx workspace/examples/src/with-cli/multiple-results.ts summarize --keys budget,need
265
298
  ```
266
299
 
267
300
  ### Using the CLI programmatically
@@ -272,7 +305,7 @@ process.argv`, runs the CLI under `NodeRuntime.runMain`, and returns `void`:
272
305
  ```ts
273
306
  import * as CLI from '@creative-introvert/tons-of-tests-cli';
274
307
 
275
- void CLI.run(
308
+ CLI.run(
276
309
  {
277
310
  testSuite,
278
311
  dbPath: 'with-cli-simple.db',
@@ -314,21 +347,54 @@ const hash = await CLI.getLastTestRunHash({
314
347
  // hash: string | null
315
348
  ```
316
349
 
317
- If you compose the CLI's `diff` programmatically (via `_diff` or a custom
318
- harness), `diff --exit-on-diff` fails with a typed `DiffNonEmpty` error
319
- when the current run has visible diffs:
320
-
321
- ```ts
322
- import {DiffNonEmpty} from '@creative-introvert/tons-of-tests-cli';
323
-
324
- // ... compose _diff into your own Effect pipeline, then:
325
- Effect.catchTag('DiffNonEmpty', () => /* handle */);
326
- ```
350
+ When you use `CLI.effect`, `diff --exit-on-diff` fails with a typed
351
+ `DiffNonEmpty` error when the current run has visible diffs. Handle it with
352
+ `Effect.catchTag('DiffNonEmpty', handler)`; `error.count` gives the number of
353
+ visible changed results.
327
354
 
328
355
  At the process entry point (`CLI.run`), `DiffNonEmpty` is translated to
329
356
  `process.exitCode = 1` — the user-facing "exit with code 1 on diff"
330
357
  behavior is unchanged.
331
358
 
359
+ ## Development
360
+
361
+ The repository uses pnpm 12, TypeScript 7, Vitest 5, and the Effect compiler
362
+ and linter tools. Install the pnpm version pinned in `package.json`.
363
+ `pnpm install` also patches TypeScript and Oxlint through the `prepare` hook.
364
+
365
+ Run project commands from the repository root through direnv:
366
+
367
+ ```sh
368
+ direnv exec . pnpm install --frozen-lockfile
369
+ direnv exec . just
370
+ direnv exec . just check
371
+ direnv exec . just check-fix
372
+ direnv exec . just typecheck
373
+ direnv exec . just test
374
+ direnv exec . just build
375
+ direnv exec . just verify
376
+ ```
377
+
378
+ `check` runs lint and format checks. `check-fix` applies fixes. `verify` also
379
+ checks types, runs tests, and builds both publishable packages. `test` accepts
380
+ Vitest arguments, such as `just test workspace/tons-of-tests-cli`.
381
+ Use `test-watch` or `typecheck-watch` while editing.
382
+
383
+ The root `tsconfig.json` builds the workspace projects. Each workspace keeps
384
+ tests and build scripts out of its production output. `tsconfig.tools.json`
385
+ checks tests and tooling, while `tsconfig.typecheck.json` checks all source
386
+ without writing JavaScript. The build writes ESM, CommonJS, and declarations
387
+ to each published package's `dist` directory.
388
+
389
+ Package scripts are kept for the existing GitHub Actions jobs, which do not
390
+ install Just. Just calls those same scripts where both need the same command.
391
+ Use `changeset`, `changeset-version`, and `changeset-publish` for releases.
392
+
393
+ Oxlint permits the Effect platform, SQL, CLI, and test APIs marked unstable;
394
+ their versions are pinned. `Stats` and `TestRun` keep their existing structural
395
+ types so callers can still pass matching objects. Other Effect lint checks
396
+ remain enabled. VS Code uses the patched workspace TypeScript compiler.
397
+
332
398
  ## Why No Runtime?
333
399
 
334
400
  Most test runners like Jest and Vitest come with their own command-line interface (CLI). When you run `jest` or `vitest`, these tools automatically find your test files, execute them, and report results.
@@ -6,43 +6,29 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.values = exports.makeClassify = exports.defaultIsNil = exports.defaultIsEqual = 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
- function _interopRequireWildcard(e, t) {
10
- if ("function" == typeof WeakMap) var r = new WeakMap(),
11
- n = new WeakMap();
12
- return (_interopRequireWildcard = function (e, t) {
13
- if (!t && e && e.__esModule) return e;
14
- var o,
15
- i,
16
- f = {
17
- __proto__: null,
18
- default: e
19
- };
20
- if (null === e || "object" != typeof e && "function" != typeof e) return f;
21
- if (o = t ? n : r) {
22
- if (o.has(e)) return o.get(e);
23
- o.set(e, f);
24
- }
25
- for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]);
26
- return f;
27
- })(e, t);
28
- }
9
+ var cache;
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; }
29
11
  const LabelSchema = exports.LabelSchema = internal.LabelSchema;
30
12
  const values = exports.values = internal.values;
31
13
  const defaultIsEqual = exports.defaultIsEqual = internal.defaultIsEqual;
32
14
  const defaultIsNil = exports.defaultIsNil = internal.defaultIsNil;
33
15
  const makeClassify = exports.makeClassify = internal.makeClassify;
16
+ /** Counts selected results; timing statistics count each selected case once. */
34
17
  class Stats extends /*#__PURE__*/_effect.Schema.Class('Stats')({
35
- TP: _effect.Schema.Number,
36
- TN: _effect.Schema.Number,
37
- FP: _effect.Schema.Number,
38
- FN: _effect.Schema.Number,
39
- total: _effect.Schema.Number,
40
- precision: _effect.Schema.Number,
41
- recall: _effect.Schema.Number,
42
- timeMin: /*#__PURE__*/_effect.Schema.OptionFromSelf(_effect.Schema.Number),
43
- timeMax: /*#__PURE__*/_effect.Schema.OptionFromSelf(_effect.Schema.Number),
44
- timeMedian: /*#__PURE__*/_effect.Schema.OptionFromSelf(_effect.Schema.Number),
45
- timeMean: /*#__PURE__*/_effect.Schema.OptionFromSelf(_effect.Schema.Number)
18
+ TP: _effect.Schema.Finite,
19
+ TN: _effect.Schema.Finite,
20
+ FP: _effect.Schema.Finite,
21
+ FN: _effect.Schema.Finite,
22
+ /** Number of evaluation results. */
23
+ total: _effect.Schema.Finite,
24
+ /** Number of distinct original test cases represented by those results. */
25
+ testCases: _effect.Schema.Int,
26
+ precision: _effect.Schema.Finite,
27
+ recall: _effect.Schema.Finite,
28
+ timeMin: /*#__PURE__*/_effect.Schema.Option(_effect.Schema.Finite),
29
+ timeMax: /*#__PURE__*/_effect.Schema.Option(_effect.Schema.Finite),
30
+ timeMedian: /*#__PURE__*/_effect.Schema.Option(_effect.Schema.Finite),
31
+ timeMean: /*#__PURE__*/_effect.Schema.Option(_effect.Schema.Finite)
46
32
  }) {
47
33
  static empty() {
48
34
  return new Stats({
@@ -51,6 +37,7 @@ class Stats extends /*#__PURE__*/_effect.Schema.Class('Stats')({
51
37
  FP: 0,
52
38
  FN: 0,
53
39
  total: 0,
40
+ testCases: 0,
54
41
  precision: 0,
55
42
  recall: 0,
56
43
  timeMin: _effect.Option.none(),
@@ -1 +1 @@
1
- {"version":3,"file":"Classify.js","names":["_effect","require","internal","_interopRequireWildcard","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","LabelSchema","exports","values","defaultIsEqual","defaultIsNil","makeClassify","Stats","Schema","Class","TP","Number","TN","FP","FN","total","precision","recall","timeMin","OptionFromSelf","timeMax","timeMedian","timeMean","empty","Option","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","defaultIsEqual","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":[]}
@@ -5,25 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.makeDefault = void 0;
7
7
  var internal = /*#__PURE__*/_interopRequireWildcard(/*#__PURE__*/require("./internal/DisplayConfig.js"));
8
- function _interopRequireWildcard(e, t) {
9
- if ("function" == typeof WeakMap) var r = new WeakMap(),
10
- n = new WeakMap();
11
- return (_interopRequireWildcard = function (e, t) {
12
- if (!t && e && e.__esModule) return e;
13
- var o,
14
- i,
15
- f = {
16
- __proto__: null,
17
- default: e
18
- };
19
- if (null === e || "object" != typeof e && "function" != typeof e) return f;
20
- if (o = t ? n : r) {
21
- if (o.has(e)) return o.get(e);
22
- o.set(e, f);
23
- }
24
- for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]);
25
- return f;
26
- })(e, t);
27
- }
8
+ var cache;
9
+ 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; }
28
10
  const makeDefault = exports.makeDefault = internal.makeDefault;
29
11
  //# sourceMappingURL=DisplayConfig.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DisplayConfig.js","names":["internal","_interopRequireWildcard","require","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","makeDefault","exports"],"sources":["../../src/DisplayConfig.ts"],"sourcesContent":[null],"mappings":";;;;;;AAAA,IAAAA,QAAA,gBAAAC,uBAAA,cAAAC,OAAA;AAAwD,SAAAD,wBAAAE,CAAA,EAAAC,CAAA;EAAA,yBAAAC,OAAA,MAAAC,CAAA,OAAAD,OAAA;IAAAE,CAAA,OAAAF,OAAA;EAAA,QAAAJ,uBAAA,YAAAA,CAAAE,CAAA,EAAAC,CAAA;IAAA,KAAAA,CAAA,IAAAD,CAAA,IAAAA,CAAA,CAAAK,UAAA,SAAAL,CAAA;IAAA,IAAAM,CAAA;MAAAC,CAAA;MAAAC,CAAA;QAAAC,SAAA;QAAAC,OAAA,EAAAV;MAAA;IAAA,aAAAA,CAAA,uBAAAA,CAAA,yBAAAA,CAAA,SAAAQ,CAAA;IAAA,IAAAF,CAAA,GAAAL,CAAA,GAAAG,CAAA,GAAAD,CAAA;MAAA,IAAAG,CAAA,CAAAK,GAAA,CAAAX,CAAA,UAAAM,CAAA,CAAAM,GAAA,CAAAZ,CAAA;MAAAM,CAAA,CAAAO,GAAA,CAAAb,CAAA,EAAAQ,CAAA;IAAA;IAAA,WAAAP,CAAA,IAAAD,CAAA,gBAAAC,CAAA,OAAAa,cAAA,CAAAC,IAAA,CAAAf,CAAA,EAAAC,CAAA,OAAAM,CAAA,IAAAD,CAAA,GAAAU,MAAA,CAAAC,cAAA,KAAAD,MAAA,CAAAE,wBAAA,CAAAlB,CAAA,EAAAC,CAAA,OAAAM,CAAA,CAAAK,GAAA,IAAAL,CAAA,CAAAM,GAAA,IAAAP,CAAA,CAAAE,CAAA,EAAAP,CAAA,EAAAM,CAAA,IAAAC,CAAA,CAAAP,CAAA,IAAAD,CAAA,CAAAC,CAAA;IAAA,OAAAO,CAAA;EAAA,GAAAR,CAAA,EAAAC,CAAA;AAAA;AAoBjD,MAAMkB,WAAW,GAAAC,OAAA,CAAAD,WAAA,GAAGtB,QAAQ,CAACsB,WAAW","ignoreList":[]}
1
+ {"version":3,"file":"DisplayConfig.js","names":["internal","_interopRequireWildcard","require","cache","e","t","__esModule","r","c","a","Object","defineProperty","n","__proto__","default","WeakMap","has","get","set","hasOwnProperty","call","getOwnPropertyDescriptor","makeDefault","exports"],"sources":["../../src/DisplayConfig.ts"],"sourcesContent":[null],"mappings":";;;;;;AAAA,IAAAA,QAAA,gBAAAC,uBAAA,cAAAC,OAAA;AAAwD,IAAAC,KAAA;AAAA,SAAAF,wBAAAG,CAAA,EAAAC,CAAA,SAAAA,CAAA,IAAAD,CAAA,IAAAA,CAAA,CAAAE,UAAA,SAAAF,CAAA,MAAAG,CAAA,EAAAC,CAAA,EAAAC,CAAA,GAAAC,MAAA,CAAAC,cAAA,EAAAC,CAAA,KAAAC,SAAA,QAAAC,OAAA,EAAAV,CAAA,QAAAM,MAAA,CAAAN,CAAA,MAAAA,CAAA,SAAAQ,CAAA,MAAAT,KAAA,yBAAAY,OAAA,KAAAZ,KAAA,OAAAY,OAAA,KAAAZ,KAAA,QAAAA,KAAA,CAAAa,GAAA,CAAAZ,CAAA,UAAAD,KAAA,CAAAc,GAAA,CAAAb,CAAA,GAAAD,KAAA,CAAAe,GAAA,CAAAd,CAAA,EAAAQ,CAAA,UAAAJ,CAAA,IAAAJ,CAAA,gBAAAI,CAAA,OAAAW,cAAA,CAAAC,IAAA,CAAAhB,CAAA,EAAAI,CAAA,OAAAD,CAAA,GAAAE,CAAA,IAAAC,MAAA,CAAAW,wBAAA,CAAAjB,CAAA,EAAAI,CAAA,OAAAD,CAAA,CAAAU,GAAA,IAAAV,CAAA,CAAAW,GAAA,IAAAT,CAAA,CAAAG,CAAA,EAAAJ,CAAA,EAAAD,CAAA,IAAAK,CAAA,CAAAJ,CAAA,IAAAJ,CAAA,CAAAI,CAAA,WAAAI,CAAA;AAoBjD,MAAMU,WAAW,GAAAC,OAAA,CAAAD,WAAA,GAAGtB,QAAQ,CAACsB,WAAW","ignoreList":[]}
@@ -4,10 +4,9 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.TestRunNotCreated = exports.RepositoryWriteError = exports.RepositoryQueryError = exports.RepositoryDecodeError = void 0;
7
- var _SqlError = /*#__PURE__*/require("@effect/sql/SqlError");
7
+ var _SqlError = /*#__PURE__*/require("effect/sql/SqlError");
8
8
  var _effect = /*#__PURE__*/require("effect");
9
- var _ParseResult = /*#__PURE__*/require("effect/ParseResult");
10
- const SqlCause = /*#__PURE__*/_effect.Schema.Union(/*#__PURE__*/_effect.Schema.instanceOf(_SqlError.SqlError), /*#__PURE__*/_effect.Schema.instanceOf(_SqlError.ResultLengthMismatch));
9
+ const SqlCause = /*#__PURE__*/_effect.Schema.Union([/*#__PURE__*/_effect.Schema.instanceOf(_SqlError.SqlError), /*#__PURE__*/_effect.Schema.instanceOf(_SqlError.ResultLengthMismatch)]);
11
10
  class RepositoryQueryError extends /*#__PURE__*/_effect.Schema.TaggedError()('RepositoryQueryError', {
12
11
  operation: _effect.Schema.String,
13
12
  cause: /*#__PURE__*/_effect.Schema.instanceOf(_SqlError.SqlError)
@@ -30,7 +29,7 @@ class RepositoryWriteError extends /*#__PURE__*/_effect.Schema.TaggedError()('Re
30
29
  exports.RepositoryWriteError = RepositoryWriteError;
31
30
  class RepositoryDecodeError extends /*#__PURE__*/_effect.Schema.TaggedError()('RepositoryDecodeError', {
32
31
  operation: _effect.Schema.String,
33
- cause: /*#__PURE__*/_effect.Schema.instanceOf(_ParseResult.ParseError)
32
+ cause: /*#__PURE__*/_effect.Schema.instanceOf(_effect.Schema.SchemaError)
34
33
  }) {
35
34
  static from = operation => cause => new RepositoryDecodeError({
36
35
  operation,
@@ -39,7 +38,7 @@ class RepositoryDecodeError extends /*#__PURE__*/_effect.Schema.TaggedError()('R
39
38
  }
40
39
  exports.RepositoryDecodeError = RepositoryDecodeError;
41
40
  class TestRunNotCreated extends /*#__PURE__*/_effect.Schema.TaggedError()('TestRunNotCreated', {
42
- name: _effect.Schema.String
41
+ testSuiteName: _effect.Schema.String
43
42
  }) {}
44
43
  exports.TestRunNotCreated = TestRunNotCreated;
45
44
  //# sourceMappingURL=RepositoryError.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"RepositoryError.js","names":["_SqlError","require","_effect","_ParseResult","SqlCause","Schema","Union","instanceOf","SqlError","ResultLengthMismatch","RepositoryQueryError","TaggedError","operation","String","cause","fromSql","exports","RepositoryWriteError","from","RepositoryDecodeError","ParseError","TestRunNotCreated","name"],"sources":["../../src/RepositoryError.ts"],"sourcesContent":[null],"mappings":";;;;;;AAAA,IAAAA,SAAA,gBAAAC,OAAA;AACA,IAAAC,OAAA,gBAAAD,OAAA;AACA,IAAAE,YAAA,gBAAAF,OAAA;AAEA,MAAMG,QAAQ,gBAAGF,OAAA,CAAAG,MAAM,CAACC,KAAK,cACzBJ,OAAA,CAAAG,MAAM,CAACE,UAAU,CAACP,SAAA,CAAAQ,QAAQ,CAAC,eAC3BN,OAAA,CAAAG,MAAM,CAACE,UAAU,CAACP,SAAA,CAAAS,oBAAoB,CAAC,CAC1C;AAEK,MAAOC,oBAAqB,sBAAQR,OAAA,CAAAG,MAAM,CAACM,WAAW,EAAwB,CAChF,sBAAsB,EACtB;EAACC,SAAS,EAAEV,OAAA,CAAAG,MAAM,CAACQ,MAAM;EAAEC,KAAK,eAAEZ,OAAA,CAAAG,MAAM,CAACE,UAAU,CAACP,SAAA,CAAAQ,QAAQ;AAAC,CAAC,CACjE;EACG,OAAOO,OAAO,GAAIH,SAAiB,IAAME,KAAe,IACpD,IAAIJ,oBAAoB,CAAC;IAACE,SAAS;IAAEE;EAAK,CAAC,CAAC;;AACnDE,OAAA,CAAAN,oBAAA,GAAAA,oBAAA;AAEK,MAAOO,oBAAqB,sBAAQf,OAAA,CAAAG,MAAM,CAACM,WAAW,EAAwB,CAChF,sBAAsB,EACtB;EAACC,SAAS,EAAEV,OAAA,CAAAG,MAAM,CAACQ,MAAM;EAAEC,KAAK,EAAEV;AAAQ,CAAC,CAC9C;EACG,OAAOc,IAAI,GACNN,SAAiB,IAAME,KAAsC,IAC1D,IAAIG,oBAAoB,CAAC;IAACL,SAAS;IAAEE;EAAK,CAAC,CAAC;;AACvDE,OAAA,CAAAC,oBAAA,GAAAA,oBAAA;AAEK,MAAOE,qBAAsB,sBAAQjB,OAAA,CAAAG,MAAM,CAACM,WAAW,EAAyB,CAClF,uBAAuB,EACvB;EAACC,SAAS,EAAEV,OAAA,CAAAG,MAAM,CAACQ,MAAM;EAAEC,KAAK,eAAEZ,OAAA,CAAAG,MAAM,CAACE,UAAU,CAACJ,YAAA,CAAAiB,UAAU;AAAC,CAAC,CACnE;EACG,OAAOF,IAAI,GAAIN,SAAiB,IAAME,KAAiB,IACnD,IAAIK,qBAAqB,CAAC;IAACP,SAAS;IAAEE;EAAK,CAAC,CAAC;;AACpDE,OAAA,CAAAG,qBAAA,GAAAA,qBAAA;AAEK,MAAOE,iBAAkB,sBAAQnB,OAAA,CAAAG,MAAM,CAACM,WAAW,EAAqB,CAC1E,mBAAmB,EACnB;EAACW,IAAI,EAAEpB,OAAA,CAAAG,MAAM,CAACQ;AAAM,CAAC,CACxB;AAAGG,OAAA,CAAAK,iBAAA,GAAAA,iBAAA","ignoreList":[]}
1
+ {"version":3,"file":"RepositoryError.js","names":["_SqlError","require","_effect","SqlCause","Schema","Union","instanceOf","SqlError","ResultLengthMismatch","RepositoryQueryError","TaggedError","operation","String","cause","fromSql","exports","RepositoryWriteError","from","RepositoryDecodeError","SchemaError","TestRunNotCreated","testSuiteName"],"sources":["../../src/RepositoryError.ts"],"sourcesContent":[null],"mappings":";;;;;;AAAA,IAAAA,SAAA,gBAAAC,OAAA;AACA,IAAAC,OAAA,gBAAAD,OAAA;AAEA,MAAME,QAAQ,gBAAGC,cAAM,CAACC,KAAK,CAAC,cAC1BD,cAAM,CAACE,UAAU,CAACC,kBAAQ,CAAC,eAC3BH,cAAM,CAACE,UAAU,CAACE,8BAAoB,CAAC,CAC1C,CAAC;AAEI,MAAOC,oBAAqB,sBAAQL,cAAM,CAACM,WAAW,EAGzD,CAAC,sBAAsB,EAAE;EACxBC,SAAS,EAAEP,cAAM,CAACQ,MAAM;EACxBC,KAAK,eAAET,cAAM,CAACE,UAAU,CAACC,kBAAQ;CACpC,CAAC;EACE,OAAOO,OAAO,GAAIH,SAAiB,IAAME,KAAe,IACpD,IAAIJ,oBAAoB,CAAC;IAACE,SAAS;IAAEE;EAAK,CAAC,CAAC;;AACnDE,OAAA,CAAAN,oBAAA,GAAAA,oBAAA;AAEK,MAAOO,oBAAqB,sBAAQZ,cAAM,CAACM,WAAW,EAGzD,CAAC,sBAAsB,EAAE;EAACC,SAAS,EAAEP,cAAM,CAACQ,MAAM;EAAEC,KAAK,EAAEV;AAAQ,CAAC,CAAC;EACpE,OAAOc,IAAI,GACNN,SAAiB,IAAME,KAAsC,IAC1D,IAAIG,oBAAoB,CAAC;IAACL,SAAS;IAAEE;EAAK,CAAC,CAAC;;AACvDE,OAAA,CAAAC,oBAAA,GAAAA,oBAAA;AAEK,MAAOE,qBAAsB,sBAAQd,cAAM,CAACM,WAAW,EAG1D,CAAC,uBAAuB,EAAE;EACzBC,SAAS,EAAEP,cAAM,CAACQ,MAAM;EACxBC,KAAK,eAAET,cAAM,CAACE,UAAU,CAACF,cAAM,CAACe,WAAW;CAC9C,CAAC;EACE,OAAOF,IAAI,GAAIN,SAAiB,IAAME,KAAyB,IAC3D,IAAIK,qBAAqB,CAAC;IAACP,SAAS;IAAEE;EAAK,CAAC,CAAC;;AACpDE,OAAA,CAAAG,qBAAA,GAAAA,qBAAA;AAEK,MAAOE,iBAAkB,sBAAQhB,cAAM,CAACM,WAAW,EAGtD,CAAC,mBAAmB,EAAE;EAACW,aAAa,EAAEjB,cAAM,CAACQ;AAAM,CAAC,CAAC;AAAGG,OAAA,CAAAK,iBAAA,GAAAA,iBAAA","ignoreList":[]}