@creative-introvert/tons-of-tests 2.1.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 +143 -37
  2. package/dist/cjs/Classify.js +1 -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 +37 -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 +236 -93
  21. package/dist/cjs/internal/Test.js.map +1 -1
  22. package/dist/cjs/internal/Test.repository.sqlite.js +262 -357
  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 +29 -1
  28. package/dist/cjs/internal/stats.js.map +1 -1
  29. package/dist/cjs/internal/summarize.js +143 -29
  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 +0 -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 +5 -5
  42. package/dist/dts/Show.d.ts.map +1 -1
  43. package/dist/dts/Test.d.ts +120 -14
  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 +52 -30
  56. package/dist/dts/internal/Test.d.ts.map +1 -1
  57. package/dist/dts/internal/Test.repository.sqlite.d.ts +66 -12
  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 +0 -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 +34 -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 +232 -92
  92. package/dist/esm/internal/Test.js.map +1 -1
  93. package/dist/esm/internal/Test.repository.sqlite.js +261 -354
  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 +27 -0
  99. package/dist/esm/internal/stats.js.map +1 -1
  100. package/dist/esm/internal/summarize.js +143 -28
  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 -62
  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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-repository-fixtures.js","names":["_effect","require","_sql","_TestRun","_TestRepositorySqlite","getAllTestRuns","exports","Effect","gen","sql","SqlClient","Schema","decodeUnknownEffect","Array","TestRun","tables","testRuns","getAllTestResults","TestResultStorage","testResults","getAllTestRunResults","Struct","testRun","Int","testResult","String","ordering","resultOrdering","timeMillis","Finite","tags","fromJsonString","testRunResults"],"sources":["../../../src/internal/test-repository-fixtures.ts"],"sourcesContent":[null],"mappings":";;;;;;AAAA,IAAAA,OAAA,gBAAAC,OAAA;AACA,IAAAC,IAAA,gBAAAD,OAAA;AAEA,IAAAE,QAAA,gBAAAF,OAAA;AACA,IAAAG,qBAAA,gBAAAH,OAAA;AAEA;AACO,MAAMI,cAAc,GAAAC,OAAA,CAAAD,cAAA,gBAAGE,cAAM,CAACC,GAAG,CAAC,aAAS;EAC9C,MAAMC,GAAG,GAAG,OAAOC,cAAS,CAACA,SAAS;EACtC,OAAO,OAAOC,cAAM,CAACC,mBAAmB,CAACD,cAAM,CAACE,KAAK,CAACC,gBAAO,CAAC,CAAC,CAC3D,OAAOL,GAAG,iBAAiBA,GAAG,CAACM,4BAAM,CAACC,QAAQ,CAAC,GAAG,CACrD;AACL,CAAC,CAAC;AAEK,MAAMC,iBAAiB,GAAAX,OAAA,CAAAW,iBAAA,gBAAGV,cAAM,CAACC,GAAG,CAAC,aAAS;EACjD,MAAMC,GAAG,GAAG,OAAOC,cAAS,CAACA,SAAS;EACtC,OAAO,OAAOC,cAAM,CAACC,mBAAmB,CAACD,cAAM,CAACE,KAAK,CAACK,uCAAiB,CAAC,CAAC,CACrE,OAAOT,GAAG,iBAAiBA,GAAG,CAACM,4BAAM,CAACI,WAAW,CAAC,GAAG,CACxD;AACL,CAAC,CAAC;AAEK,MAAMC,oBAAoB,GAAAd,OAAA,CAAAc,oBAAA,gBAAGb,cAAM,CAACC,GAAG,CAAC,aAAS;EACpD,MAAMC,GAAG,GAAG,OAAOC,cAAS,CAACA,SAAS;EACtC,OAAO,OAAOC,cAAM,CAACC,mBAAmB,CACpCD,cAAM,CAACE,KAAK,CACRF,cAAM,CAACU,MAAM,CAAC;IACVC,OAAO,EAAEX,cAAM,CAACY,GAAG;IACnBC,UAAU,EAAEb,cAAM,CAACc,MAAM;IACzBC,QAAQ,EAAEf,cAAM,CAACY,GAAG;IACpBI,cAAc,EAAEhB,cAAM,CAACY,GAAG;IAC1BK,UAAU,EAAEjB,cAAM,CAACkB,MAAM;IACzBC,IAAI,EAAEnB,cAAM,CAACoB,cAAc,CAACpB,cAAM,CAACE,KAAK,CAACF,cAAM,CAACc,MAAM,CAAC;GAC1D,CAAC,CACL,CACJ,CAAC,OAAOhB,GAAG,iBAAiBA,GAAG,CAACM,4BAAM,CAACiB,cAAc,CAAC,GAAG,CAAC;AAC/D,CAAC,CAAC","ignoreList":[]}
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.tables = exports.migrate = void 0;
7
+ var _sqlSqliteNode = /*#__PURE__*/require("@effect/sql-sqlite-node");
8
+ var _effect = /*#__PURE__*/require("effect");
9
+ var _sql = /*#__PURE__*/require("effect/sql");
10
+ const tables = exports.tables = {
11
+ testResults: 'test-results',
12
+ testRuns: 'test-runs',
13
+ testBaselines: 'test-baselines',
14
+ testRunResults: 'test-run-results'
15
+ };
16
+ const migrate = exports.migrate = /*#__PURE__*/_sqlSqliteNode.SqliteMigrator.run({
17
+ table: 'tons_of_tests_migrations',
18
+ loader: /*#__PURE__*/_sqlSqliteNode.SqliteMigrator.fromRecord({
19
+ '001_create_tables': /*#__PURE__*/_effect.Effect.gen(function* () {
20
+ const sql = yield* _sql.SqlClient.SqlClient;
21
+ yield* sql`
22
+ CREATE TABLE ${sql(tables.testRuns)}(
23
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
24
+ name TEXT NOT NULL,
25
+ variant TEXT NOT NULL,
26
+ state TEXT NOT NULL CHECK (state IN ('Running', 'Complete', 'Failed'))
27
+ );
28
+ `;
29
+ yield* sql`CREATE INDEX idx_run_name_variant_id ON ${sql(tables.testRuns)}(name, variant, id);`;
30
+ yield* sql`
31
+ CREATE TABLE ${sql(tables.testBaselines)}(
32
+ name TEXT NOT NULL,
33
+ variant TEXT NOT NULL,
34
+ testRun INTEGER NOT NULL REFERENCES ${sql(tables.testRuns)}(id),
35
+ PRIMARY KEY (name, variant)
36
+ );
37
+ `;
38
+ yield* sql`
39
+ CREATE TABLE ${sql(tables.testResults)}(
40
+ id TEXT PRIMARY KEY,
41
+ hashTestCase TEXT NOT NULL,
42
+ key TEXT NOT NULL,
43
+ input TEXT,
44
+ result TEXT,
45
+ expected TEXT,
46
+ label TEXT NOT NULL
47
+ );
48
+ `;
49
+ yield* sql`CREATE INDEX idx_tr_case_key ON ${sql(tables.testResults)}(hashTestCase, key);`;
50
+ yield* sql`
51
+ CREATE TABLE ${sql(tables.testRunResults)}(
52
+ testRun INTEGER NOT NULL,
53
+ testResult TEXT NOT NULL,
54
+ ordering INTEGER NOT NULL,
55
+ resultOrdering INTEGER NOT NULL,
56
+ timeMillis REAL NOT NULL,
57
+ tags TEXT NOT NULL,
58
+ FOREIGN KEY (testRun) REFERENCES ${sql(tables.testRuns)}(id),
59
+ FOREIGN KEY (testResult) REFERENCES ${sql(tables.testResults)}(id),
60
+ UNIQUE (testRun, testResult)
61
+ );
62
+ `;
63
+ yield* sql`CREATE INDEX idx_trr_testresult ON ${sql(tables.testRunResults)}(testResult);`;
64
+ yield* sql`CREATE INDEX idx_trr_run_order ON ${sql(tables.testRunResults)}(testRun, ordering, resultOrdering, testResult);`;
65
+ })
66
+ })
67
+ });
68
+ //# sourceMappingURL=test-repository-migrations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-repository-migrations.js","names":["_sqlSqliteNode","require","_effect","_sql","tables","exports","testResults","testRuns","testBaselines","testRunResults","migrate","SqliteMigrator","run","table","loader","fromRecord","Effect","gen","sql","SqlClient"],"sources":["../../../src/internal/test-repository-migrations.ts"],"sourcesContent":[null],"mappings":";;;;;;AAAA,IAAAA,cAAA,gBAAAC,OAAA;AACA,IAAAC,OAAA,gBAAAD,OAAA;AACA,IAAAE,IAAA,gBAAAF,OAAA;AAEO,MAAMG,MAAM,GAAAC,OAAA,CAAAD,MAAA,GAAG;EAClBE,WAAW,EAAE,cAAc;EAC3BC,QAAQ,EAAE,WAAW;EACrBC,aAAa,EAAE,gBAAgB;EAC/BC,cAAc,EAAE;CACV;AAEH,MAAMC,OAAO,GAAAL,OAAA,CAAAK,OAAA,gBAAGC,6BAAc,CAACC,GAAG,CAAC;EACtCC,KAAK,EAAE,0BAA0B;EACjCC,MAAM,eAAEH,6BAAc,CAACI,UAAU,CAAC;IAC9B,mBAAmB,eAAEC,cAAM,CAACC,GAAG,CAAC,aAAS;MACrC,MAAMC,GAAG,GAAG,OAAOC,cAAS,CAACA,SAAS;MACtC,OAAOD,GAAG;+BACSA,GAAG,CAACd,MAAM,CAACG,QAAQ,CAAC;;;;;;aAMtC;MACD,OAAOW,GAAG,2CAA2CA,GAAG,CAACd,MAAM,CAACG,QAAQ,CAAC,sBAAsB;MAC/F,OAAOW,GAAG;+BACSA,GAAG,CAACd,MAAM,CAACI,aAAa,CAAC;;;0DAGEU,GAAG,CAACd,MAAM,CAACG,QAAQ,CAAC;;;aAGjE;MAED,OAAOW,GAAG;+BACSA,GAAG,CAACd,MAAM,CAACE,WAAW,CAAC;;;;;;;;;aASzC;MACD,OAAOY,GAAG,mCAAmCA,GAAG,CAACd,MAAM,CAACE,WAAW,CAAC,sBAAsB;MAE1F,OAAOY,GAAG;+BACSA,GAAG,CAACd,MAAM,CAACK,cAAc,CAAC;;;;;;;uDAOFS,GAAG,CAACd,MAAM,CAACG,QAAQ,CAAC;0DACjBW,GAAG,CAACd,MAAM,CAACE,WAAW,CAAC;;;aAGpE;MACD,OAAOY,GAAG,sCAAsCA,GAAG,CAACd,MAAM,CAACK,cAAc,CAAC,eAAe;MACzF,OAAOS,GAAG,qCAAqCA,GAAG,CAACd,MAAM,CAACK,cAAc,CAAC,kDAAkD;IAC/H,CAAC;GACJ;CACJ,CAAC","ignoreList":[]}
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.withStats = void 0;
7
+ var _effect = /*#__PURE__*/require("effect");
8
+ var _sql = /*#__PURE__*/require("effect/sql");
9
+ var _Classify = /*#__PURE__*/require("../Classify.js");
10
+ var _Classify2 = /*#__PURE__*/require("./Classify.js");
11
+ const decodeName = /*#__PURE__*/_effect.Schema.decodeUnknownEffect(/*#__PURE__*/_effect.Schema.Tuple([/*#__PURE__*/_effect.Schema.Struct({
12
+ name: _effect.Schema.String
13
+ })]));
14
+ const decodeTimes = /*#__PURE__*/_effect.Schema.decodeUnknownEffect(/*#__PURE__*/_effect.Schema.Tuple([/*#__PURE__*/_effect.Schema.Struct({
15
+ count: _effect.Schema.Int,
16
+ mean: /*#__PURE__*/_effect.Schema.NullOr(_effect.Schema.Finite),
17
+ min: /*#__PURE__*/_effect.Schema.NullOr(_effect.Schema.Finite),
18
+ max: /*#__PURE__*/_effect.Schema.NullOr(_effect.Schema.Finite)
19
+ })]));
20
+ const decodeMedian = /*#__PURE__*/_effect.Schema.decodeUnknownEffect(/*#__PURE__*/_effect.Schema.Array(/*#__PURE__*/_effect.Schema.Struct({
21
+ timeMillis: _effect.Schema.Finite
22
+ })));
23
+ const withStats = exports.withStats = /*#__PURE__*/_effect.Effect.fnUntraced(function* (use) {
24
+ const sql = yield* _sql.SqlClient.SqlClient;
25
+ const [{
26
+ name
27
+ }] = yield* decodeName(yield* sql`SELECT 'tots_stats_' || lower(hex(randomblob(16))) AS name;`);
28
+ return yield* _effect.Effect.acquireUseRelease(sql`CREATE TEMP TABLE ${sql(name)} (hashTestCase TEXT PRIMARY KEY, timeMillis REAL NOT NULL);`, () => _effect.Effect.gen(function* () {
29
+ yield* sql`CREATE INDEX ${sql(`${name}_time`)} ON ${sql(name)} (timeMillis);`;
30
+ const counts = yield* _effect.Ref.make({
31
+ TP: 0,
32
+ TN: 0,
33
+ FP: 0,
34
+ FN: 0,
35
+ total: 0
36
+ });
37
+ const add = _effect.Effect.fnUntraced(function* (results) {
38
+ for (let offset = 0; offset < results.length; offset += 50) {
39
+ const batch = results.slice(offset, offset + 50);
40
+ yield* sql`
41
+ INSERT INTO ${sql(name)} ${sql.insert(batch.map(({
42
+ hashTestCase,
43
+ timeMillis
44
+ }) => ({
45
+ hashTestCase,
46
+ timeMillis
47
+ })))}
48
+ ON CONFLICT(hashTestCase) DO NOTHING;
49
+ `;
50
+ yield* _effect.Ref.update(counts, previous => {
51
+ const next = {
52
+ ...previous
53
+ };
54
+ for (const result of batch) {
55
+ next[result.label]++;
56
+ next.total++;
57
+ }
58
+ return next;
59
+ });
60
+ }
61
+ });
62
+ const stats = _effect.Effect.gen(function* () {
63
+ const totals = yield* _effect.Ref.get(counts);
64
+ const [times] = yield* decodeTimes(yield* sql`
65
+ SELECT COUNT(*) AS count, AVG(timeMillis) AS mean,
66
+ MIN(timeMillis) AS min, MAX(timeMillis) AS max FROM ${sql(name)};
67
+ `);
68
+ const middle = times.count === 0 ? [] : yield* decodeMedian(yield* sql`
69
+ SELECT timeMillis FROM ${sql(name)} ORDER BY timeMillis
70
+ LIMIT ${2 - times.count % 2} OFFSET ${Math.floor((times.count - 1) / 2)};
71
+ `);
72
+ return new _Classify.Stats({
73
+ ...totals,
74
+ testCases: times.count,
75
+ precision: (0, _Classify2.precision)(totals),
76
+ recall: (0, _Classify2.recall)(totals),
77
+ timeMin: _effect.Option.fromNullishOr(times.min),
78
+ timeMax: _effect.Option.fromNullishOr(times.max),
79
+ timeMean: _effect.Option.fromNullishOr(times.mean),
80
+ timeMedian: middle.length === 0 ? _effect.Option.none() : _effect.Option.some(middle.reduce((sum, row) => sum + row.timeMillis, 0) / middle.length)
81
+ });
82
+ });
83
+ return yield* use({
84
+ add,
85
+ stats
86
+ });
87
+ }), () => sql`DROP TABLE ${sql(name)};`.pipe(_effect.Effect.asVoid));
88
+ });
89
+ //# sourceMappingURL=test-result-stats.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-result-stats.js","names":["_effect","require","_sql","_Classify","_Classify2","decodeName","Schema","decodeUnknownEffect","Tuple","Struct","name","String","decodeTimes","count","Int","mean","NullOr","Finite","min","max","decodeMedian","Array","timeMillis","withStats","exports","Effect","fnUntraced","use","sql","SqlClient","acquireUseRelease","gen","counts","Ref","make","TP","TN","FP","FN","total","add","results","offset","length","batch","slice","insert","map","hashTestCase","update","previous","next","result","label","stats","totals","get","times","middle","Math","floor","Stats","testCases","precision","recall","timeMin","Option","fromNullishOr","timeMax","timeMean","timeMedian","none","some","reduce","sum","row","pipe","asVoid"],"sources":["../../../src/internal/test-result-stats.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
@@ -8,7 +8,6 @@ export declare const values: {
8
8
  readonly FP: 'FP';
9
9
  readonly FN: 'FN';
10
10
  };
11
- export declare const defaultIsEqual: typeof internal.defaultIsEqual;
12
11
  export declare const defaultIsNil: typeof internal.defaultIsNil;
13
12
  export declare const makeClassify: typeof internal.makeClassify;
14
13
  export type Classify<O, T> = (output: O, expected: T) => Label;
@@ -1 +1 @@
1
- {"version":3,"file":"Classify.d.ts","sourceRoot":"","sources":["../../src/Classify.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,MAAM,EAAC,MAAM,QAAQ,CAAC;AAEtC,OAAO,KAAK,QAAQ,MAAM,wBAAwB,CAAC;AAEnD,eAAO,MAAM,WAAW,oDAAuB,CAAC;AAChD,MAAM,MAAM,KAAK,GAAG,OAAO,WAAW,CAAC,IAAI,CAAC;AAE5C,eAAO,MAAM,MAAM;;;;;CAAkB,CAAC;AACtC,eAAO,MAAM,cAAc,gCAA0B,CAAC;AACtD,eAAO,MAAM,YAAY,8BAAwB,CAAC;AAClD,eAAO,MAAM,YAAY,8BAAwB,CAAC;AAElD,MAAM,MAAM,QAAQ,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,KAAK,KAAK,CAAC;;;;;;IAQ3D,oCAAoC;;IAEpC,2EAA2E;;;;;;;;;AAR/E,gFAAgF;AAChF,qBAAa,KAAM,SAAQ,UAezB;IACE,MAAM,CAAC,KAAK,IAAI,KAAK,CAepB;CACJ"}
1
+ {"version":3,"file":"Classify.d.ts","sourceRoot":"","sources":["../../src/Classify.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,MAAM,EAAC,MAAM,QAAQ,CAAC;AAEtC,OAAO,KAAK,QAAQ,MAAM,wBAAwB,CAAC;AAEnD,eAAO,MAAM,WAAW,oDAAuB,CAAC;AAChD,MAAM,MAAM,KAAK,GAAG,OAAO,WAAW,CAAC,IAAI,CAAC;AAE5C,eAAO,MAAM,MAAM;;;;;CAAkB,CAAC;AACtC,eAAO,MAAM,YAAY,8BAAwB,CAAC;AAClD,eAAO,MAAM,YAAY,8BAAwB,CAAC;AAElD,MAAM,MAAM,QAAQ,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,KAAK,KAAK,CAAC;;;;;;IAQ3D,oCAAoC;;IAEpC,2EAA2E;;;;;;;;;AAR/E,gFAAgF;AAChF,qBAAa,KAAM,SAAQ,UAezB;IACE,MAAM,CAAC,KAAK,IAAI,KAAK,CAepB;CACJ"}
@@ -1,39 +1,38 @@
1
- import { ResultLengthMismatch, SqlError } from 'effect/sql/SqlError';
1
+ import type { SqlError } from 'effect/sql/SqlError';
2
2
  import { Schema } from 'effect';
3
- declare const RepositoryQueryError_base: Schema.Class<RepositoryQueryError, Schema.TaggedStruct<"RepositoryQueryError", {
4
- readonly operation: Schema.String;
5
- readonly cause: Schema.instanceOf<SqlError, unknown>;
3
+ import type { TestValueError } from './TestValueError.js';
4
+ export { TestValueError } from './TestValueError.js';
5
+ declare const TestRunNotCreated_base: Schema.Class<TestRunNotCreated, Schema.TaggedStruct<"TestRunNotCreated", {
6
+ readonly testSuiteName: Schema.String;
6
7
  }>, import("effect/Cause").YieldableError & {
7
8
  readonly brand: unique symbol;
8
9
  }>;
9
- export declare class RepositoryQueryError extends RepositoryQueryError_base {
10
- static fromSql: (operation: string) => (cause: SqlError) => RepositoryQueryError;
10
+ export declare class TestRunNotCreated extends TestRunNotCreated_base {
11
11
  }
12
- declare const RepositoryWriteError_base: Schema.Class<RepositoryWriteError, Schema.TaggedStruct<"RepositoryWriteError", {
13
- readonly operation: Schema.String;
14
- readonly cause: Schema.Union<readonly [Schema.instanceOf<SqlError, unknown>, Schema.instanceOf<ResultLengthMismatch, unknown>]>;
12
+ declare const TestRunIncomplete_base: Schema.Class<TestRunIncomplete, Schema.TaggedStruct<"TestRunIncomplete", {
13
+ readonly testSuiteName: Schema.String;
14
+ readonly testRunId: Schema.Int;
15
+ readonly variant: Schema.String;
15
16
  }>, import("effect/Cause").YieldableError & {
16
17
  readonly brand: unique symbol;
17
18
  }>;
18
- export declare class RepositoryWriteError extends RepositoryWriteError_base {
19
- static from: (operation: string) => (cause: SqlError | ResultLengthMismatch) => RepositoryWriteError;
19
+ /** A complete saved run is required for this operation. */
20
+ export declare class TestRunIncomplete extends TestRunIncomplete_base {
20
21
  }
21
- declare const RepositoryDecodeError_base: Schema.Class<RepositoryDecodeError, Schema.TaggedStruct<"RepositoryDecodeError", {
22
- readonly operation: Schema.String;
23
- readonly cause: Schema.instanceOf<Schema.SchemaError, unknown>;
22
+ declare const TestRunNotFound_base: Schema.Class<TestRunNotFound, Schema.TaggedStruct<"TestRunNotFound", {
23
+ readonly testRunId: Schema.Int;
24
24
  }>, import("effect/Cause").YieldableError & {
25
25
  readonly brand: unique symbol;
26
26
  }>;
27
- export declare class RepositoryDecodeError extends RepositoryDecodeError_base {
28
- static from: (operation: string) => (cause: Schema.SchemaError) => RepositoryDecodeError;
27
+ export declare class TestRunNotFound extends TestRunNotFound_base {
29
28
  }
30
- declare const TestRunNotCreated_base: Schema.Class<TestRunNotCreated, Schema.TaggedStruct<"TestRunNotCreated", {
29
+ declare const TestBaselineNotFound_base: Schema.Class<TestBaselineNotFound, Schema.TaggedStruct<"TestBaselineNotFound", {
31
30
  readonly testSuiteName: Schema.String;
31
+ readonly variant: Schema.String;
32
32
  }>, import("effect/Cause").YieldableError & {
33
33
  readonly brand: unique symbol;
34
34
  }>;
35
- export declare class TestRunNotCreated extends TestRunNotCreated_base {
35
+ export declare class TestBaselineNotFound extends TestBaselineNotFound_base {
36
36
  }
37
- export type RepositoryError = RepositoryQueryError | RepositoryWriteError | RepositoryDecodeError | TestRunNotCreated;
38
- export {};
37
+ export type RepositoryError = SqlError | Schema.SchemaError | TestValueError | TestRunNotCreated | TestRunIncomplete | TestRunNotFound | TestBaselineNotFound;
39
38
  //# sourceMappingURL=RepositoryError.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"RepositoryError.d.ts","sourceRoot":"","sources":["../../src/RepositoryError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,oBAAoB,EAAE,QAAQ,EAAC,MAAM,qBAAqB,CAAC;AACnE,OAAO,EAAC,MAAM,EAAC,MAAM,QAAQ,CAAC;;;;;oBAST,OAAO,MAAM;;AAFlC,qBAAa,oBAAqB,SAAQ,yBAMxC;IACE,MAAM,CAAC,OAAO,cAAe,MAAM,aAAa,QAAQ,0BACP;CACpD;;;;;oBAIoB,OAAO,MAAM;;AAFlC,qBAAa,oBAAqB,SAAQ,yBAG8B;IACpE,MAAM,CAAC,IAAI,cACK,MAAM,aAAa,QAAQ,GAAG,oBAAoB,0BACb;CACxD;;;;;oBAIoB,OAAO,MAAM;;AAFlC,qBAAa,qBAAsB,SAAQ,0BAMzC;IACE,MAAM,CAAC,IAAI,cAAe,MAAM,aAAa,MAAM,CAAC,WAAW,2BACb;CACrD;;;;oBAIoB,OAAO,MAAM;;AAFlC,qBAAa,iBAAkB,SAAQ,sBAGiB;CAAG;AAE3D,MAAM,MAAM,eAAe,GACrB,oBAAoB,GACpB,oBAAoB,GACpB,qBAAqB,GACrB,iBAAiB,CAAC"}
1
+ {"version":3,"file":"RepositoryError.d.ts","sourceRoot":"","sources":["../../src/RepositoryError.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAC,MAAM,EAAC,MAAM,QAAQ,CAAC;AAC9B,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,qBAAqB,CAAC;AAExD,OAAO,EAAC,cAAc,EAAC,MAAM,qBAAqB,CAAC;;;;oBAI9B,OAAO,MAAM;;AAFlC,qBAAa,iBAAkB,SAAQ,sBAGiB;CAAG;;;;;;oBAKtC,OAAO,MAAM;;AAHlC,2DAA2D;AAC3D,qBAAa,iBAAkB,SAAQ,sBAOrC;CAAG;;;;oBAIgB,OAAO,MAAM;;AAFlC,qBAAa,eAAgB,SAAQ,oBAGU;CAAG;;;;;oBAI7B,OAAO,MAAM;;AAFlC,qBAAa,oBAAqB,SAAQ,yBAMxC;CAAG;AAEL,MAAM,MAAM,eAAe,GACrB,QAAQ,GACR,MAAM,CAAC,WAAW,GAClB,cAAc,GACd,iBAAiB,GACjB,iBAAiB,GACjB,eAAe,GACf,oBAAoB,CAAC"}
@@ -2,8 +2,8 @@ import type { Option } from 'effect';
2
2
  import type { Stats } from './Classify.js';
3
3
  import type { Diff, TestResult } from './Test.js';
4
4
  export { showDiff as diff } from './internal/diff.js';
5
- export { showStats as stats } from './internal/stats.js';
6
- export { showSummary as summarize } from './internal/summarize.js';
5
+ export { showStats as stats, showRunSummaries as runSummaries, } from './internal/stats.js';
6
+ export { showSummary as summarize, prepareSummary, prepareComparison, } from './internal/summarize.js';
7
7
  export type DiffContext = {
8
8
  diff: Diff;
9
9
  };
@@ -22,11 +22,11 @@ export type StatsColumn = {
22
22
  label: string;
23
23
  make: (ctx: StatsContext) => string[];
24
24
  };
25
- export type SummarizeContext = {
25
+ export type SummarizeContext<I = unknown, O = unknown, T = unknown> = {
26
26
  i: number;
27
27
  resultKeys: string[];
28
- testResult: TestResult;
29
- previousTestResult: Option.Option<TestResult>;
28
+ testResult: TestResult<I, O, T>;
29
+ previousTestResult: Option.Option<TestResult<I, O, T>>;
30
30
  };
31
31
  export type SummarizeColumnNames = 'index' | 'hash' | 'key' | 'timeMillis' | 'input' | 'tags' | 'label' | 'expected' | 'result' | 'result_diff' | 'prev_label' | 'prev_result' | 'prev_result_diff';
32
32
  export type SummarizeColumn = {
@@ -1 +1 @@
1
- {"version":3,"file":"Show.d.ts","sourceRoot":"","sources":["../../src/Show.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,QAAQ,CAAC;AAEnC,OAAO,KAAK,EAAC,KAAK,EAAC,MAAM,eAAe,CAAC;AACzC,OAAO,KAAK,EAAC,IAAI,EAAE,UAAU,EAAC,MAAM,WAAW,CAAC;AAEhD,OAAO,EAAC,QAAQ,IAAI,IAAI,EAAC,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAC,SAAS,IAAI,KAAK,EAAC,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAC,WAAW,IAAI,SAAS,EAAC,MAAM,yBAAyB,CAAC;AAEjE,MAAM,MAAM,WAAW,GAAG;IACtB,IAAI,EAAE,IAAI,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,eAAe,GACrB,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,WAAW,GACX,QAAQ,CAAC;AAEf,MAAM,MAAM,UAAU,GAAG;IACrB,IAAI,EAAE,eAAe,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,MAAM,EAAE,CAAC;CACxC,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACvB,KAAK,EAAE,KAAK,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GACtB,OAAO,GACP,WAAW,GACX,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,WAAW,GACX,QAAQ,GACR,SAAS,GACT,SAAS,GACT,UAAU,GACV,YAAY,CAAC;AAEnB,MAAM,MAAM,WAAW,GAAG;IACtB,IAAI,EAAE,gBAAgB,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,CAAC,GAAG,EAAE,YAAY,KAAK,MAAM,EAAE,CAAC;CACzC,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC3B,CAAC,EAAE,MAAM,CAAC;IACV,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,UAAU,EAAE,UAAU,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;CACjD,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAC1B,OAAO,GACP,MAAM,GACN,KAAK,GACL,YAAY,GACZ,OAAO,GACP,MAAM,GACN,OAAO,GACP,UAAU,GACV,QAAQ,GACR,aAAa,GACb,YAAY,GACZ,aAAa,GACb,kBAAkB,CAAC;AAEzB,MAAM,MAAM,eAAe,GAAG;IAC1B,IAAI,EAAE,oBAAoB,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,MAAM,EAAE,CAAC;CAC7C,CAAC"}
1
+ {"version":3,"file":"Show.d.ts","sourceRoot":"","sources":["../../src/Show.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,QAAQ,CAAC;AAEnC,OAAO,KAAK,EAAC,KAAK,EAAC,MAAM,eAAe,CAAC;AACzC,OAAO,KAAK,EAAC,IAAI,EAAE,UAAU,EAAC,MAAM,WAAW,CAAC;AAEhD,OAAO,EAAC,QAAQ,IAAI,IAAI,EAAC,MAAM,oBAAoB,CAAC;AACpD,OAAO,EACH,SAAS,IAAI,KAAK,EAClB,gBAAgB,IAAI,YAAY,GACnC,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACH,WAAW,IAAI,SAAS,EACxB,cAAc,EACd,iBAAiB,GACpB,MAAM,yBAAyB,CAAC;AAEjC,MAAM,MAAM,WAAW,GAAG;IACtB,IAAI,EAAE,IAAI,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,eAAe,GACrB,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,WAAW,GACX,QAAQ,CAAC;AAEf,MAAM,MAAM,UAAU,GAAG;IACrB,IAAI,EAAE,eAAe,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,MAAM,EAAE,CAAC;CACxC,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACvB,KAAK,EAAE,KAAK,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GACtB,OAAO,GACP,WAAW,GACX,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,WAAW,GACX,QAAQ,GACR,SAAS,GACT,SAAS,GACT,UAAU,GACV,YAAY,CAAC;AAEnB,MAAM,MAAM,WAAW,GAAG;IACtB,IAAI,EAAE,gBAAgB,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,CAAC,GAAG,EAAE,YAAY,KAAK,MAAM,EAAE,CAAC;CACzC,CAAC;AAEF,MAAM,MAAM,gBAAgB,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,IAAI;IAClE,CAAC,EAAE,MAAM,CAAC;IACV,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,UAAU,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAChC,kBAAkB,EAAE,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;CAC1D,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAC1B,OAAO,GACP,MAAM,GACN,KAAK,GACL,YAAY,GACZ,OAAO,GACP,MAAM,GACN,OAAO,GACP,UAAU,GACV,QAAQ,GACR,aAAa,GACb,YAAY,GACZ,aAAa,GACb,kBAAkB,CAAC;AAEzB,MAAM,MAAM,eAAe,GAAG;IAC1B,IAAI,EAAE,oBAAoB,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,MAAM,EAAE,CAAC;CAC7C,CAAC"}
@@ -1,8 +1,13 @@
1
- import { type Array, Effect, Option, type Stream } from 'effect';
1
+ import { type Array, type Effect, type Option, Schema, type Stream } from 'effect';
2
2
  import type { Label, Stats } from './Classify.js';
3
3
  import * as internal from './internal/Test.js';
4
4
  import type { TestRun, TestResultSchemas } from './Test.repository.js';
5
- export type TestSuiteSchemas<I, O, T> = TestResultSchemas<I, O, T>;
5
+ /** Codecs must encode deterministically and preserve values through JSON. */
6
+ export type TestSuiteSchemas<I, T, A, B> = TestResultSchemas<I, A, B> & {
7
+ testCase: {
8
+ expected: Schema.Codec<T, unknown>;
9
+ };
10
+ };
6
11
  export type TestCases<I, T, E = never, R = never> = ReadonlyArray<TestCase<I, T>> | Stream.Stream<TestCase<I, T>, E, R>;
7
12
  export type EvaluationResult<A, B> = {
8
13
  /** Non-empty and unique within the case. Keep it stable across runs. */
@@ -17,24 +22,80 @@ export type EvaluationResult<A, B> = {
17
22
  * unique within the case.
18
23
  */
19
24
  export type Evaluate<O, T, A = O, B = T> = (output: O, expected: T) => Array.NonEmptyReadonlyArray<EvaluationResult<A, B>>;
25
+ export type TestSuitePrograms<I, O, E, R> = {
26
+ program: Program<I, O, E, R>;
27
+ variants?: never;
28
+ } | {
29
+ program?: never;
30
+ variants: Readonly<Record<string, {
31
+ program: Program<I, O, E, R>;
32
+ }>>;
33
+ };
34
+ type SuiteProgram<S> = S extends {
35
+ program: infer P;
36
+ } ? P : S extends {
37
+ variants: infer V;
38
+ } ? V[keyof V] extends {
39
+ program: infer P;
40
+ } ? P : never : never;
41
+ type ProgramEffect<S> = SuiteProgram<S> extends (...args: never[]) => infer F ? F : never;
42
+ /** Errors from every configured program and from the case stream. */
43
+ export type TestSuiteError<S> = Effect.Error<ProgramEffect<S>> | Stream.Error<S extends {
44
+ testCases: infer C;
45
+ } ? C : never>;
46
+ /** Callers provide all services used by any program or the case stream. */
47
+ export type TestSuiteServices<S> = Effect.Services<ProgramEffect<S>> | Stream.Services<S extends {
48
+ testCases: infer C;
49
+ } ? C : never>;
50
+ /**
51
+ * Keep source effect types. Skip `evaluate` during inference so the suite supplies
52
+ * its callback parameter types.
53
+ */
54
+ export type InferTestSuite<S> = {
55
+ [K in keyof S]: K extends 'evaluate' ? unknown : S[K];
56
+ };
57
+ export type SelectedProgram<S> = Program<SuiteProgram<S> extends (input: infer I) => unknown ? I : never, Effect.Success<ProgramEffect<S>>, Effect.Error<ProgramEffect<S>>, Effect.Services<ProgramEffect<S>>>;
58
+ declare const TestVariantRequired_base: Schema.Class<TestVariantRequired, Schema.TaggedStruct<"TestVariantRequired", {
59
+ readonly testSuiteName: Schema.String;
60
+ }>, import("effect/Cause").YieldableError & {
61
+ readonly brand: unique symbol;
62
+ }>;
63
+ export declare class TestVariantRequired extends TestVariantRequired_base {
64
+ }
65
+ declare const TestVariantNotFound_base: Schema.Class<TestVariantNotFound, Schema.TaggedStruct<"TestVariantNotFound", {
66
+ readonly testSuiteName: Schema.String;
67
+ readonly variant: Schema.String;
68
+ }>, import("effect/Cause").YieldableError & {
69
+ readonly brand: unique symbol;
70
+ }>;
71
+ export declare class TestVariantNotFound extends TestVariantNotFound_base {
72
+ }
20
73
  /**
21
- * Runs `program` once per case, then evaluates its output. `O` and `T` describe
22
- * the whole output and expected value; `A` and `B` describe the evaluated values.
23
- * Without `evaluate`, the default comparison returns one result with key `result`.
74
+ * Defines either one `program` or named `variants` that share cases, schemas,
75
+ * and evaluation. A single program has the permanent variant ID `default`.
76
+ * Named variants need an explicit selection, even when there is only one.
77
+ * Variant IDs must be non-empty, contain no commas, and not start with `run:`.
78
+ * Editing a program keeps its history; changing its ID starts another history.
79
+ * An empty `variants` map keeps saved runs readable after all programs are removed.
80
+ *
81
+ * Runs the selected program once per distinct input/expected-value hash, then
82
+ * evaluates its output. Later duplicates are warned about and skipped; the first
83
+ * case's tags are kept. `O` and `T` describe the whole output and expected value;
84
+ * `A` and `B` describe the evaluated values.
85
+ * Without `evaluate`, reuse the same schema for evaluation.result and
86
+ * evaluation.expected. Schema equality produces one result with key `result`.
24
87
  */
25
88
  export type TestSuite<I = unknown, O = unknown, T = unknown, E = never, R = never, A = O, B = T> = {
26
89
  name: string;
27
- /** Decode cached input and the result/expected values returned by `evaluate`. */
28
- schemas?: TestSuiteSchemas<I, A, B>;
29
- } & ({
90
+ } & (({
91
+ schemas: TestSuiteSchemas<I, T, A, B>;
30
92
  testCases: TestCases<I, T, E, R>;
31
- program: Program<I, O, E, R>;
32
93
  evaluate: Evaluate<O, T, A, B>;
33
- } | {
94
+ } & TestSuitePrograms<I, O, E, R>) | ({
95
+ schemas: TestSuiteSchemas<I, T & NoInfer<B>, A, B>;
34
96
  testCases: TestCases<I, T & NoInfer<B>, E, R>;
35
- program: Program<I, O & NoInfer<A>, E, R>;
36
97
  evaluate?: undefined;
37
- });
98
+ } & TestSuitePrograms<I, O & NoInfer<A>, E, R>));
38
99
  export type TestCase<I, T> = {
39
100
  input: I;
40
101
  expected: T;
@@ -58,7 +119,7 @@ export type TestResult<I = unknown, O = unknown, T = unknown> = {
58
119
  /** Program duration for the case, shared by all its results. */
59
120
  timeMillis: number;
60
121
  };
61
- export type TestRunResults<I = unknown, O = unknown, T = unknown> = TestRun & {
122
+ export type TestRunResults<I = unknown, O = unknown, T = unknown> = Pick<TestRun, 'id' | 'name' | 'variant' | 'state'> & {
62
123
  /** Indexed by `resultKey`, which combines the case hash and evaluation key. */
63
124
  testResultsByKey: Record<string, TestResult<I, O, T>>;
64
125
  /** Keys into `testResultsByKey`, in display order. */
@@ -75,12 +136,57 @@ export type TestResultPredicate<I, O, T> = (args: {
75
136
  testResult: TestResult<I, O, T>;
76
137
  previousTestResult: Option.Option<TestResult<I, O, T>>;
77
138
  }) => boolean;
139
+ export type TestResultComparison<I, A, B> = {
140
+ _tag: 'Matched';
141
+ from: TestResult<I, A, B>;
142
+ to: TestResult<I, A, B>;
143
+ changed: boolean;
144
+ } | {
145
+ _tag: 'OnlyFrom';
146
+ from: TestResult<I, A, B>;
147
+ } | {
148
+ _tag: 'OnlyTo';
149
+ to: TestResult<I, A, B>;
150
+ };
151
+ /** Selects a program without running it or requiring its services. */
152
+ export declare const selectVariant: typeof internal.selectVariant;
153
+ /**
154
+ * Runs only the selected program. Its error and service types include every
155
+ * configured program and the case stream, even when the variant ID is a literal.
156
+ */
78
157
  export declare const all: typeof internal.all;
158
+ /**
159
+ * Compares complete saved runs without evaluating again. The shared codecs must
160
+ * decode both runs and require no Effect services. Callers decide whether comparing
161
+ * different suites or program versions is meaningful.
162
+ *
163
+ * Results match by case hash and evaluation key. A match changes when its label
164
+ * or evaluated values change. Rows follow `to` order, followed by rows found only
165
+ * in `from`, in `from` order. Empty complete runs are valid comparison endpoints.
166
+ * Resolve missing baselines before calling; both endpoints must be saved runs.
167
+ * Incompatible codecs fail with `TestValueError`, which names the saved suite.
168
+ */
169
+ export declare const compareRuns: typeof internal.compareRuns;
170
+ /**
171
+ * Summarizes all matching results in a complete saved run. Each case contributes
172
+ * its timing once. Empty complete runs have zero counts and no timing values.
173
+ * The shared codecs must still read that run. The caller decides whether the
174
+ * stored values still have the same meaning. Resolve a missing baseline before
175
+ * calling; it differs from an empty run.
176
+ */
177
+ export declare const summarizeRun: <I, A, B>(args_0: {
178
+ run: TestRun;
179
+ schemas: TestResultSchemas<I, A, B>;
180
+ predicate?: (result: TestResult<I, A, B>) => boolean;
181
+ }) => Effect.Effect<{
182
+ run: TestRun;
183
+ stats: Stats;
184
+ }, import("./RepositoryError.ts").RepositoryError, import("./Test.repository.js").TestRepository>;
79
185
  export declare const diff: typeof internal.diff;
80
- export declare const makeSha256: typeof internal.makeSha256;
81
186
  /** Builds the lookup key for one evaluation within its original test case. */
82
187
  export declare const resultKey: typeof internal.resultKey;
83
188
  export declare const runCollectRecord: typeof internal.runCollectRecord;
84
189
  /** Keeps matching results and recalculates counts and case timing statistics. */
85
190
  export declare const filterResults: typeof internal.filterResults;
191
+ export {};
86
192
  //# sourceMappingURL=Test.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Test.d.ts","sourceRoot":"","sources":["../../src/Test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Test.d.ts","sourceRoot":"","sources":["../../src/Test.ts"],"names":[],"mappings":"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"}
@@ -1,12 +1,98 @@
1
1
  import * as Sqlite from '@effect/sql-sqlite-node';
2
- import { Context, Layer } from 'effect';
3
- import type { TestRepositoryShape } from './Test.repository.types.js';
4
- export { TestRun } from './Test.repository.types.js';
5
- export type { TestRepositoryShape, TestResultRead, TestResultSchemas, TestRunResults, } from './Test.repository.types.js';
6
- declare const TestRepository_base: Context.ServiceClass<TestRepository, "TestRepository", TestRepositoryShape>;
2
+ import { Context, type Effect, Layer, type Option, type Schema, type Stream } from 'effect';
3
+ import type { Stats } from './Classify.js';
4
+ import type { RepositoryError } from './RepositoryError.js';
5
+ import type { TestResult } from './Test.js';
6
+ import type { TestRun } from './TestRun.js';
7
+ export { TestRun } from './TestRun.js';
8
+ type StatsCollector = {
9
+ add: (results: ReadonlyArray<Pick<TestResult, 'hashTestCase' | 'label' | 'timeMillis'>>) => Effect.Effect<void, RepositoryError>;
10
+ stats: Effect.Effect<Stats, RepositoryError>;
11
+ };
12
+ /**
13
+ * Encode and decode saved input and evaluated values. Pass a suite's schemas
14
+ * directly; its whole-case expectation is only needed by the runner.
15
+ * Codecs must be deterministic, preserve equivalent values through JSON, and
16
+ * require no Effect services.
17
+ */
18
+ export type TestResultSchemas<I = unknown, O = unknown, T = unknown> = {
19
+ testCase: {
20
+ input: Schema.Codec<I, unknown>;
21
+ };
22
+ evaluation: {
23
+ result: Schema.Codec<O, unknown>;
24
+ expected: Schema.Codec<T, unknown>;
25
+ };
26
+ };
27
+ /**
28
+ * Saves attempts and a baseline for each variant in one database. This storage
29
+ * format requires a fresh database; older formats are not migrated. Reads never
30
+ * create runs. Saved history is not pruned automatically.
31
+ */
32
+ export type TestRepositoryShape = {
33
+ getTestResultsStream: <I = unknown, O = unknown, T = unknown>(testRun: TestRun, schemas: TestResultSchemas<I, O, T>,
34
+ /** Match at most 50 case/key pairs per call. Results retain their saved order. */
35
+ matching?: ReadonlyArray<Pick<TestResult, 'hashTestCase' | 'key'>>) => Stream.Stream<TestResult<I, O, T>, RepositoryError>;
36
+ /** Calculate exact statistics using temporary SQLite storage, released after use. */
37
+ withStats: <A, E, R>(use: (collector: StatsCollector) => Effect.Effect<A, E, R>) => Effect.Effect<A, E | RepositoryError, R>;
38
+ /**
39
+ * Create a new `Running` attempt and call `execute` once. The callback can be
40
+ * interrupted. Save `Complete` after callback success, including empty runs.
41
+ * Save `Failed` after a callback failure, synchronous throw, defect, or
42
+ * interruption. Return success only after saving `Complete`.
43
+ *
44
+ * Database errors propagate. If execution and finalization both fail, preserve
45
+ * both causes. A failed final write or abrupt process exit can leave the attempt
46
+ * `Running`; it cannot be committed.
47
+ */
48
+ withTestRun: <A, E = never, R = never>(input: {
49
+ name: string;
50
+ variant: string;
51
+ }, execute: (testRun: TestRun) => Effect.Effect<A, E, R>) => Effect.Effect<{
52
+ run: TestRun;
53
+ value: A;
54
+ }, E | RepositoryError, R>;
55
+ /** Find one saved attempt, including `Running` and `Failed` attempts. */
56
+ getTestRun: (id: number) => Effect.Effect<Option.Option<TestRun>, RepositoryError>;
57
+ /** Find the run with the greatest saved ID for this suite and variant, in any state. */
58
+ getLatestTestRun: (input: {
59
+ name: string;
60
+ variant: string;
61
+ }) => Effect.Effect<Option.Option<TestRun>, RepositoryError>;
62
+ /** A missing baseline is `None`; it differs from a completed empty run. */
63
+ getBaselineTestRun: (input: {
64
+ name: string;
65
+ variant: string;
66
+ }) => Effect.Effect<Option.Option<TestRun>, RepositoryError>;
67
+ /**
68
+ * Set the baseline for this run's suite and variant to its exact run ID.
69
+ * The run must be `Complete`; empty runs are allowed. Repeating a commit or
70
+ * choosing an older run is allowed. Past runs and their results stay unchanged.
71
+ */
72
+ commitTestRun: (id: number) => Effect.Effect<void, RepositoryError>;
73
+ /** List runs by descending ID. `limit` must be 1–100; the next page has `id < before`. */
74
+ listTestRuns: (input: {
75
+ name: string;
76
+ variant?: string;
77
+ before?: number;
78
+ limit: number;
79
+ }) => Effect.Effect<ReadonlyArray<TestRun & {
80
+ readonly isBaseline: boolean;
81
+ }>, RepositoryError>;
82
+ /** List every stored variant by name, with its saved baseline when one exists. */
83
+ listVariantBaselines: (name: string) => Effect.Effect<ReadonlyArray<{
84
+ variant: string;
85
+ baseline: Option.Option<TestRun>;
86
+ }>, RepositoryError>;
87
+ /** Only `Running` attempts accept writes; completed and failed runs cannot change. */
88
+ insertTestResult: <I, O, T>(input: TestResult<I, O, T>, testRun: TestRun, schemas: TestResultSchemas<I, O, T>) => Effect.Effect<void, RepositoryError>;
89
+ /** Check the saved state inside each batch transaction before writing. */
90
+ insertTestResults: <I, O, T>(inputs: ReadonlyArray<TestResult<I, O, T>>, testRun: TestRun, schemas: TestResultSchemas<I, O, T>) => Effect.Effect<void, RepositoryError>;
91
+ };
92
+ declare const TestRepository_base: Context.ServiceClass<TestRepository, "@creative-introvert/tons-of-tests/TestRepository", TestRepositoryShape>;
7
93
  export declare class TestRepository extends TestRepository_base {
8
- static get Live(): Layer.Layer<TestRepository, import("./RepositoryError.ts").RepositoryDecodeError | import("effect/sql/SqlError").SqlError, import("effect/sql/SqlClient").SqlClient>;
9
- static layer(dbPath: string): Layer.Layer<TestRepository, import("./RepositoryError.ts").RepositoryDecodeError | import("effect/sql/SqlError").SqlError, never>;
10
- static get TestLayer(): Layer.Layer<import("effect/sql/SqlClient").SqlClient | Sqlite.SqliteClient.SqliteClient | TestRepository, import("./RepositoryError.ts").RepositoryDecodeError | import("effect/sql/SqlError").SqlError, never>;
94
+ static readonly layerNoDeps: Layer.Layer<TestRepository, Sqlite.SqliteMigrator.MigrationError | import("effect/sql/SqlError").SqlError, import("effect/sql/SqlClient").SqlClient>;
95
+ static layer(dbPath: string): Layer.Layer<TestRepository, Sqlite.SqliteMigrator.MigrationError | import("effect/sql/SqlError").SqlError, never>;
96
+ static readonly TestLayer: Layer.Layer<import("effect/sql/SqlClient").SqlClient | Sqlite.SqliteClient.SqliteClient | TestRepository, Sqlite.SqliteMigrator.MigrationError | import("effect/sql/SqlError").SqlError, never>;
11
97
  }
12
98
  //# sourceMappingURL=Test.repository.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Test.repository.d.ts","sourceRoot":"","sources":["../../src/Test.repository.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,yBAAyB,CAAC;AAClD,OAAO,EAAC,OAAO,EAAE,KAAK,EAAC,MAAM,QAAQ,CAAC;AAGtC,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,4BAA4B,CAAC;AAEpE,OAAO,EAAC,OAAO,EAAC,MAAM,4BAA4B,CAAC;AACnD,YAAY,EACR,mBAAmB,EACnB,cAAc,EACd,iBAAiB,EACjB,cAAc,GACjB,MAAM,4BAA4B,CAAC;;AAUpC,qBAAa,cAAe,SAAQ,mBAGf;IAIjB,MAAM,KAAK,IAAI,yKAEd;IACD,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,qIAK1B;IAED,MAAM,KAAK,SAAS,oNAEnB;CACJ"}
1
+ {"version":3,"file":"Test.repository.d.ts","sourceRoot":"","sources":["../../src/Test.repository.ts"],"names":[],"mappings":"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"}