ppef 1.0.1 → 1.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 (175) hide show
  1. package/bin/ppef.mjs +20 -0
  2. package/dist/__tests__/framework-pipeline.integration.test.js +13 -11
  3. package/dist/__tests__/framework-pipeline.integration.test.js.map +1 -1
  4. package/dist/__tests__/index-exports.unit.test.d.ts +8 -0
  5. package/dist/__tests__/index-exports.unit.test.d.ts.map +1 -0
  6. package/dist/__tests__/index-exports.unit.test.js +127 -0
  7. package/dist/__tests__/index-exports.unit.test.js.map +1 -0
  8. package/dist/__tests__/registry-executor.integration.test.js +12 -9
  9. package/dist/__tests__/registry-executor.integration.test.js.map +1 -1
  10. package/dist/aggregation/__tests__/aggregators.unit.test.d.ts +7 -0
  11. package/dist/aggregation/__tests__/aggregators.unit.test.d.ts.map +1 -0
  12. package/dist/aggregation/__tests__/aggregators.unit.test.js +350 -0
  13. package/dist/aggregation/__tests__/aggregators.unit.test.js.map +1 -0
  14. package/dist/aggregation/__tests__/pipeline.unit.test.d.ts +7 -0
  15. package/dist/aggregation/__tests__/pipeline.unit.test.d.ts.map +1 -0
  16. package/dist/aggregation/__tests__/pipeline.unit.test.js +213 -0
  17. package/dist/aggregation/__tests__/pipeline.unit.test.js.map +1 -0
  18. package/dist/aggregation/aggregators.d.ts +9 -0
  19. package/dist/aggregation/aggregators.d.ts.map +1 -1
  20. package/dist/aggregation/aggregators.js +1 -1
  21. package/dist/aggregation/aggregators.js.map +1 -1
  22. package/dist/aggregation/index.d.ts +1 -1
  23. package/dist/aggregation/index.d.ts.map +1 -1
  24. package/dist/aggregation/index.js +1 -1
  25. package/dist/aggregation/index.js.map +1 -1
  26. package/dist/claims/__tests__/evaluator.unit.test.d.ts +12 -0
  27. package/dist/claims/__tests__/evaluator.unit.test.d.ts.map +1 -0
  28. package/dist/claims/__tests__/evaluator.unit.test.js +801 -0
  29. package/dist/claims/__tests__/evaluator.unit.test.js.map +1 -0
  30. package/dist/cli/__tests__/aggregate.command.unit.test.d.ts +7 -0
  31. package/dist/cli/__tests__/aggregate.command.unit.test.d.ts.map +1 -0
  32. package/dist/cli/__tests__/aggregate.command.unit.test.js +396 -0
  33. package/dist/cli/__tests__/aggregate.command.unit.test.js.map +1 -0
  34. package/dist/cli/__tests__/commands.unit.test.d.ts +10 -0
  35. package/dist/cli/__tests__/commands.unit.test.d.ts.map +1 -0
  36. package/dist/cli/__tests__/commands.unit.test.js +217 -0
  37. package/dist/cli/__tests__/commands.unit.test.js.map +1 -0
  38. package/dist/cli/__tests__/index.unit.test.d.ts +10 -0
  39. package/dist/cli/__tests__/index.unit.test.d.ts.map +1 -0
  40. package/dist/cli/__tests__/index.unit.test.js +65 -0
  41. package/dist/cli/__tests__/index.unit.test.js.map +1 -0
  42. package/dist/cli/__tests__/logger.unit.test.d.ts +11 -0
  43. package/dist/cli/__tests__/logger.unit.test.d.ts.map +1 -0
  44. package/dist/cli/__tests__/logger.unit.test.js +180 -0
  45. package/dist/cli/__tests__/logger.unit.test.js.map +1 -0
  46. package/dist/cli/__tests__/module-loader.unit.test.d.ts +11 -0
  47. package/dist/cli/__tests__/module-loader.unit.test.d.ts.map +1 -0
  48. package/dist/cli/__tests__/module-loader.unit.test.js +262 -0
  49. package/dist/cli/__tests__/module-loader.unit.test.js.map +1 -0
  50. package/dist/cli/__tests__/output-writer.unit.test.d.ts +10 -0
  51. package/dist/cli/__tests__/output-writer.unit.test.d.ts.map +1 -0
  52. package/dist/cli/__tests__/output-writer.unit.test.js +216 -0
  53. package/dist/cli/__tests__/output-writer.unit.test.js.map +1 -0
  54. package/dist/cli/__tests__/plan.command.unit.test.d.ts +7 -0
  55. package/dist/cli/__tests__/plan.command.unit.test.d.ts.map +1 -0
  56. package/dist/cli/__tests__/plan.command.unit.test.js +289 -0
  57. package/dist/cli/__tests__/plan.command.unit.test.js.map +1 -0
  58. package/dist/cli/__tests__/run.command.unit.test.d.ts +7 -0
  59. package/dist/cli/__tests__/run.command.unit.test.d.ts.map +1 -0
  60. package/dist/cli/__tests__/run.command.unit.test.js +422 -0
  61. package/dist/cli/__tests__/run.command.unit.test.js.map +1 -0
  62. package/dist/cli/__tests__/validate.command.unit.test.d.ts +7 -0
  63. package/dist/cli/__tests__/validate.command.unit.test.d.ts.map +1 -0
  64. package/dist/cli/__tests__/validate.command.unit.test.js +226 -0
  65. package/dist/cli/__tests__/validate.command.unit.test.js.map +1 -0
  66. package/dist/cli/command-deps.d.ts +125 -0
  67. package/dist/cli/command-deps.d.ts.map +1 -0
  68. package/dist/cli/command-deps.js +7 -0
  69. package/dist/cli/command-deps.js.map +1 -0
  70. package/dist/cli/commands/aggregate.d.ts +35 -0
  71. package/dist/cli/commands/aggregate.d.ts.map +1 -0
  72. package/dist/cli/commands/aggregate.js +121 -0
  73. package/dist/cli/commands/aggregate.js.map +1 -0
  74. package/dist/cli/commands/plan.d.ts +36 -0
  75. package/dist/cli/commands/plan.d.ts.map +1 -0
  76. package/dist/cli/commands/plan.js +109 -0
  77. package/dist/cli/commands/plan.js.map +1 -0
  78. package/dist/cli/commands/run.d.ts +33 -0
  79. package/dist/cli/commands/run.d.ts.map +1 -0
  80. package/dist/cli/commands/run.js +185 -0
  81. package/dist/cli/commands/run.js.map +1 -0
  82. package/dist/cli/commands/validate.d.ts +27 -0
  83. package/dist/cli/commands/validate.d.ts.map +1 -0
  84. package/dist/cli/commands/validate.js +88 -0
  85. package/dist/cli/commands/validate.js.map +1 -0
  86. package/dist/cli/config-loader.d.ts +30 -0
  87. package/dist/cli/config-loader.d.ts.map +1 -0
  88. package/dist/cli/config-loader.js +181 -0
  89. package/dist/cli/config-loader.js.map +1 -0
  90. package/dist/cli/index.d.ts +26 -0
  91. package/dist/cli/index.d.ts.map +1 -0
  92. package/dist/cli/index.js +58 -0
  93. package/dist/cli/index.js.map +1 -0
  94. package/dist/cli/logger.d.ts +75 -0
  95. package/dist/cli/logger.d.ts.map +1 -0
  96. package/dist/cli/logger.js +131 -0
  97. package/dist/cli/logger.js.map +1 -0
  98. package/dist/cli/module-loader.d.ts +46 -0
  99. package/dist/cli/module-loader.d.ts.map +1 -0
  100. package/dist/cli/module-loader.js +116 -0
  101. package/dist/cli/module-loader.js.map +1 -0
  102. package/dist/cli/output-writer.d.ts +51 -0
  103. package/dist/cli/output-writer.d.ts.map +1 -0
  104. package/dist/cli/output-writer.js +65 -0
  105. package/dist/cli/output-writer.js.map +1 -0
  106. package/dist/cli/types.d.ts +174 -0
  107. package/dist/cli/types.d.ts.map +1 -0
  108. package/dist/cli/types.js +7 -0
  109. package/dist/cli/types.js.map +1 -0
  110. package/dist/collector/__tests__/result-collector.unit.test.d.ts +7 -0
  111. package/dist/collector/__tests__/result-collector.unit.test.d.ts.map +1 -0
  112. package/dist/collector/__tests__/result-collector.unit.test.js +1021 -0
  113. package/dist/collector/__tests__/result-collector.unit.test.js.map +1 -0
  114. package/dist/collector/__tests__/schema.unit.test.d.ts +7 -0
  115. package/dist/collector/__tests__/schema.unit.test.d.ts.map +1 -0
  116. package/dist/collector/__tests__/schema.unit.test.js +360 -0
  117. package/dist/collector/__tests__/schema.unit.test.js.map +1 -0
  118. package/dist/executor/__tests__/checkpoint-manager.unit.test.js +83 -1
  119. package/dist/executor/__tests__/checkpoint-manager.unit.test.js.map +1 -1
  120. package/dist/executor/__tests__/checkpoint-merge-bug.diagnostic.test.d.ts +3 -6
  121. package/dist/executor/__tests__/checkpoint-merge-bug.diagnostic.test.d.ts.map +1 -1
  122. package/dist/executor/__tests__/checkpoint-merge-bug.diagnostic.test.js +428 -159
  123. package/dist/executor/__tests__/checkpoint-merge-bug.diagnostic.test.js.map +1 -1
  124. package/dist/executor/__tests__/checkpoint-storage.unit.test.js +105 -1
  125. package/dist/executor/__tests__/checkpoint-storage.unit.test.js.map +1 -1
  126. package/dist/executor/__tests__/executor.unit.test.js +69 -1
  127. package/dist/executor/__tests__/executor.unit.test.js.map +1 -1
  128. package/dist/executor/__tests__/memory-monitor.unit.test.d.ts +7 -0
  129. package/dist/executor/__tests__/memory-monitor.unit.test.d.ts.map +1 -0
  130. package/dist/executor/__tests__/memory-monitor.unit.test.js +285 -0
  131. package/dist/executor/__tests__/memory-monitor.unit.test.js.map +1 -0
  132. package/dist/executor/__tests__/parallel-executor.unit.test.d.ts +2 -1
  133. package/dist/executor/__tests__/parallel-executor.unit.test.d.ts.map +1 -1
  134. package/dist/executor/__tests__/parallel-executor.unit.test.js +426 -156
  135. package/dist/executor/__tests__/parallel-executor.unit.test.js.map +1 -1
  136. package/dist/executor/__tests__/run-id.unit.test.d.ts +8 -0
  137. package/dist/executor/__tests__/run-id.unit.test.d.ts.map +1 -0
  138. package/dist/executor/__tests__/run-id.unit.test.js +156 -0
  139. package/dist/executor/__tests__/run-id.unit.test.js.map +1 -0
  140. package/dist/executor/__tests__/worker-entry.integration.test.d.ts +24 -0
  141. package/dist/executor/__tests__/worker-entry.integration.test.d.ts.map +1 -0
  142. package/dist/executor/__tests__/worker-entry.integration.test.js +82 -0
  143. package/dist/executor/__tests__/worker-entry.integration.test.js.map +1 -0
  144. package/dist/executor/__tests__/worker-entry.unit.test.d.ts +7 -0
  145. package/dist/executor/__tests__/worker-entry.unit.test.d.ts.map +1 -0
  146. package/dist/executor/__tests__/worker-entry.unit.test.js +364 -0
  147. package/dist/executor/__tests__/worker-entry.unit.test.js.map +1 -0
  148. package/dist/executor/parallel-executor.d.ts +186 -0
  149. package/dist/executor/parallel-executor.d.ts.map +1 -1
  150. package/dist/executor/parallel-executor.js +218 -83
  151. package/dist/executor/parallel-executor.js.map +1 -1
  152. package/dist/executor/run-id.d.ts.map +1 -1
  153. package/dist/executor/run-id.js +8 -1
  154. package/dist/executor/run-id.js.map +1 -1
  155. package/dist/executor/worker-entry.d.ts +2 -0
  156. package/dist/executor/worker-entry.d.ts.map +1 -1
  157. package/dist/executor/worker-entry.js +29 -54
  158. package/dist/executor/worker-entry.js.map +1 -1
  159. package/dist/executor/worker-executor.d.ts +156 -0
  160. package/dist/executor/worker-executor.d.ts.map +1 -0
  161. package/dist/executor/worker-executor.js +88 -0
  162. package/dist/executor/worker-executor.js.map +1 -0
  163. package/dist/robustness/__tests__/analyzer.unit.test.d.ts +11 -0
  164. package/dist/robustness/__tests__/analyzer.unit.test.d.ts.map +1 -0
  165. package/dist/robustness/__tests__/analyzer.unit.test.js +455 -0
  166. package/dist/robustness/__tests__/analyzer.unit.test.js.map +1 -0
  167. package/dist/robustness/__tests__/perturbations.unit.test.d.ts +11 -0
  168. package/dist/robustness/__tests__/perturbations.unit.test.d.ts.map +1 -0
  169. package/dist/robustness/__tests__/perturbations.unit.test.js +284 -0
  170. package/dist/robustness/__tests__/perturbations.unit.test.js.map +1 -0
  171. package/dist/statistical/__tests__/mann-whitney-u.unit.test.d.ts +7 -0
  172. package/dist/statistical/__tests__/mann-whitney-u.unit.test.d.ts.map +1 -0
  173. package/dist/statistical/__tests__/mann-whitney-u.unit.test.js +185 -0
  174. package/dist/statistical/__tests__/mann-whitney-u.unit.test.js.map +1 -0
  175. package/package.json +8 -1
@@ -0,0 +1,226 @@
1
+ /**
2
+ * Unit tests for validate command
3
+ *
4
+ * Tests validate command functionality with injected dependencies.
5
+ */
6
+ import { beforeEach, describe, it, mock } from "node:test";
7
+ import { strict as assert } from "node:assert";
8
+ import { executeValidate } from "../commands/validate.js";
9
+ describe("validate command", () => {
10
+ let mockLogger;
11
+ let mockConfigLoader;
12
+ let mockProcessExit;
13
+ let exitCode;
14
+ const loggedMessages = [];
15
+ beforeEach(() => {
16
+ loggedMessages.length = 0;
17
+ exitCode = null;
18
+ // Mock logger
19
+ mockLogger = {
20
+ header: mock.fn((msg) => {
21
+ loggedMessages.push(`[header] ${msg}`);
22
+ }),
23
+ subheader: mock.fn((msg) => {
24
+ loggedMessages.push(`[subheader] ${msg}`);
25
+ }),
26
+ info: mock.fn((msg) => {
27
+ loggedMessages.push(`[info] ${msg}`);
28
+ }),
29
+ debug: mock.fn((msg) => {
30
+ loggedMessages.push(`[debug] ${msg}`);
31
+ }),
32
+ error: mock.fn((msg) => {
33
+ loggedMessages.push(`[error] ${msg}`);
34
+ }),
35
+ warn: mock.fn((msg) => {
36
+ loggedMessages.push(`[warn] ${msg}`);
37
+ }),
38
+ setProgress: mock.fn(() => {
39
+ // Do nothing
40
+ }),
41
+ };
42
+ // Mock process exit
43
+ mockProcessExit = mock.fn((code) => {
44
+ exitCode = code;
45
+ throw new Error(`process.exit(${code})`);
46
+ });
47
+ // Mock config loader
48
+ mockConfigLoader = {
49
+ loadAndValidateConfig: async (configPath) => {
50
+ return {
51
+ config: {
52
+ experiment: {
53
+ name: "Test Experiment",
54
+ description: "Test Description",
55
+ version: "1.0.0",
56
+ },
57
+ suts: [
58
+ {
59
+ id: "test-sut",
60
+ module: "./test.js",
61
+ exportName: "createSUT",
62
+ registration: {
63
+ name: "Test SUT",
64
+ version: "1.0.0",
65
+ role: "primary",
66
+ tags: [],
67
+ },
68
+ },
69
+ ],
70
+ cases: [
71
+ {
72
+ id: "test-case",
73
+ module: "./case.js",
74
+ exportName: "createCase",
75
+ },
76
+ ],
77
+ metricsExtractor: {
78
+ module: "./metrics.js",
79
+ exportName: "extractMetrics",
80
+ },
81
+ executor: {
82
+ repetitions: 10,
83
+ seedBase: 42,
84
+ timeoutMs: 5000,
85
+ concurrency: 4,
86
+ continueOnError: true,
87
+ collectProvenance: false,
88
+ },
89
+ output: {
90
+ path: "./results",
91
+ format: "json-pretty",
92
+ aggregate: true,
93
+ },
94
+ },
95
+ baseDir: "/test/base",
96
+ configPath: "/test/config.json",
97
+ };
98
+ },
99
+ };
100
+ });
101
+ describe("executeValidate", () => {
102
+ it("should log configuration details", async () => {
103
+ await executeValidate("/test/config.json", {
104
+ logger: mockLogger,
105
+ configLoader: mockConfigLoader,
106
+ processExit: mockProcessExit,
107
+ });
108
+ assert.ok(loggedMessages.includes("[header] Configuration Validation"));
109
+ assert.ok(loggedMessages.some((msg) => msg.includes("Configuration file: /test/config.json")));
110
+ assert.ok(loggedMessages.some((msg) => msg.includes("Experiment: Test Experiment")));
111
+ });
112
+ it("should log SUT details", async () => {
113
+ await executeValidate("/test/config.json", {
114
+ logger: mockLogger,
115
+ configLoader: mockConfigLoader,
116
+ processExit: mockProcessExit,
117
+ });
118
+ assert.ok(loggedMessages.includes("[subheader] SUTs"));
119
+ assert.ok(loggedMessages.some((msg) => msg.includes("test-sut")));
120
+ assert.ok(loggedMessages.some((msg) => msg.includes("(Test SUT v1.0.0)")));
121
+ });
122
+ it("should log case details", async () => {
123
+ await executeValidate("/test/config.json", {
124
+ logger: mockLogger,
125
+ configLoader: mockConfigLoader,
126
+ processExit: mockProcessExit,
127
+ });
128
+ assert.ok(loggedMessages.includes("[subheader] Cases"));
129
+ assert.ok(loggedMessages.some((msg) => msg.includes("test-case")));
130
+ });
131
+ it("should log executor config", async () => {
132
+ await executeValidate("/test/config.json", {
133
+ logger: mockLogger,
134
+ configLoader: mockConfigLoader,
135
+ processExit: mockProcessExit,
136
+ });
137
+ assert.ok(loggedMessages.includes("[subheader] Executor"));
138
+ assert.ok(loggedMessages.some((msg) => msg.includes("Repetitions: 10")));
139
+ assert.ok(loggedMessages.some((msg) => msg.includes("Seed base: 42")));
140
+ });
141
+ it("should log output config", async () => {
142
+ await executeValidate("/test/config.json", {
143
+ logger: mockLogger,
144
+ configLoader: mockConfigLoader,
145
+ processExit: mockProcessExit,
146
+ });
147
+ assert.ok(loggedMessages.includes("[subheader] Output"));
148
+ assert.ok(loggedMessages.some((msg) => msg.includes("Path: ./results")));
149
+ });
150
+ it("should log success message", async () => {
151
+ await executeValidate("/test/config.json", {
152
+ logger: mockLogger,
153
+ configLoader: mockConfigLoader,
154
+ processExit: mockProcessExit,
155
+ });
156
+ assert.ok(loggedMessages.some((msg) => msg.includes("Configuration is valid!")));
157
+ assert.strictEqual(exitCode, null); // No exit on success
158
+ });
159
+ it("should call process.exit on error", async () => {
160
+ mockConfigLoader.loadAndValidateConfig = async () => {
161
+ throw new Error("Config validation failed");
162
+ };
163
+ try {
164
+ await executeValidate("/test/config.json", {
165
+ logger: mockLogger,
166
+ configLoader: mockConfigLoader,
167
+ processExit: mockProcessExit,
168
+ });
169
+ }
170
+ catch {
171
+ // Expected to throw due to mock process.exit
172
+ }
173
+ assert.ok(loggedMessages.some((msg) => msg.includes("[error] Config validation failed")));
174
+ assert.strictEqual(exitCode, 1);
175
+ });
176
+ it("should handle non-Error errors", async () => {
177
+ mockConfigLoader.loadAndValidateConfig = async () => {
178
+ throw new Error("String error");
179
+ };
180
+ try {
181
+ await executeValidate("/test/config.json", {
182
+ logger: mockLogger,
183
+ configLoader: mockConfigLoader,
184
+ processExit: mockProcessExit,
185
+ });
186
+ }
187
+ catch {
188
+ // Expected to throw
189
+ }
190
+ assert.ok(loggedMessages.some((msg) => msg.includes("[error] String error")));
191
+ assert.strictEqual(exitCode, 1);
192
+ });
193
+ it("should handle null/undefined optional fields", async () => {
194
+ mockConfigLoader.loadAndValidateConfig = async () => {
195
+ return {
196
+ config: {
197
+ experiment: {
198
+ name: "Minimal Test",
199
+ // No description, version
200
+ },
201
+ suts: [],
202
+ cases: [],
203
+ metricsExtractor: {
204
+ module: "./metrics.js",
205
+ exportName: "extractMetrics",
206
+ },
207
+ executor: {},
208
+ output: {},
209
+ },
210
+ baseDir: "/test",
211
+ configPath: "/test/config.json",
212
+ };
213
+ };
214
+ await executeValidate("/test/config.json", {
215
+ logger: mockLogger,
216
+ configLoader: mockConfigLoader,
217
+ processExit: mockProcessExit,
218
+ });
219
+ // Check that default values are logged for optional fields
220
+ assert.ok(loggedMessages.some((msg) => msg.includes("Repetitions: default")));
221
+ assert.ok(loggedMessages.some((msg) => msg.includes("Seed base: default")));
222
+ assert.ok(loggedMessages.some((msg) => msg.includes("Path: ./results")));
223
+ });
224
+ });
225
+ });
226
+ //# sourceMappingURL=validate.command.unit.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.command.unit.test.js","sourceRoot":"","sources":["../../../src/cli/__tests__/validate.command.unit.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,125 @@
1
+ /**
2
+ * Command dependencies interface for dependency injection.
3
+ *
4
+ * This allows commands to be tested with mocked dependencies.
5
+ */
6
+ import type { EvaluationResult } from "../types/result.js";
7
+ import type { AggregationOutput } from "../types/aggregate.js";
8
+ import type { EvaluationCase } from "../types/case.js";
9
+ import type { LoadedConfig } from "./types.js";
10
+ /**
11
+ * Logger interface for output handling.
12
+ */
13
+ export interface ICommandLogger {
14
+ header(message: string): void;
15
+ subheader(message: string): void;
16
+ info(message: string): void;
17
+ debug(message: string): void;
18
+ error(message: string): void;
19
+ warn(message: string): void;
20
+ setProgress(enabled: boolean): void;
21
+ }
22
+ /**
23
+ * Configuration loader interface.
24
+ */
25
+ export interface IConfigLoader {
26
+ loadAndValidateConfig(configPath: string): Promise<LoadedConfig>;
27
+ }
28
+ /**
29
+ * SUT factory interface.
30
+ */
31
+ export interface ISutFactory {
32
+ id: string;
33
+ config: unknown;
34
+ run: (input: unknown) => Promise<unknown>;
35
+ }
36
+ /**
37
+ * Case definition interface.
38
+ * Matches the structure of CaseDefinition from types/case.ts
39
+ */
40
+ export interface ICaseDefinition {
41
+ case: EvaluationCase;
42
+ getInput: () => Promise<unknown>;
43
+ getInputs?: () => unknown[];
44
+ }
45
+ /**
46
+ * Metrics extractor interface.
47
+ */
48
+ export interface IMetricsExtractor {
49
+ extract: (result: unknown, input: unknown) => Record<string, number>;
50
+ }
51
+ /**
52
+ * Module loader interface for dynamic imports.
53
+ */
54
+ export interface IModuleLoader {
55
+ loadSutFactory(module: string, exportName: string, baseDir: string, registration: {
56
+ id: string;
57
+ name: string;
58
+ version: string;
59
+ role: string;
60
+ config: unknown;
61
+ tags: string[];
62
+ description?: string;
63
+ }, sutConfig: unknown): Promise<ISutFactory>;
64
+ loadCaseDefinition(module: string, exportName: string, baseDir: string): Promise<ICaseDefinition>;
65
+ loadMetricsExtractor(module: string, exportName: string, baseDir: string): Promise<IMetricsExtractor>;
66
+ }
67
+ /**
68
+ * Output writer interface.
69
+ */
70
+ export interface IOutputWriter {
71
+ generateOutputFilename(experimentName: string, type: "results" | "aggregates"): string;
72
+ writeResults(results: EvaluationResult[], outputPath: string, format: "json" | "json-pretty"): Promise<void>;
73
+ writeAggregates(aggregates: AggregationOutput, outputPath: string, format: "json" | "json-pretty"): Promise<void>;
74
+ }
75
+ /**
76
+ * Executor interface.
77
+ */
78
+ export interface IExecutor {
79
+ execute(sutDefinitions: ISutFactory[], caseDefinitions: ICaseDefinition[], metricsExtractor: IMetricsExtractor, onResult?: (result: EvaluationResult) => void): Promise<{
80
+ totalRuns: number;
81
+ successfulRuns: number;
82
+ failedRuns: number;
83
+ elapsedMs: number;
84
+ results: EvaluationResult[];
85
+ errors: {
86
+ runId: string;
87
+ error: string;
88
+ }[];
89
+ }>;
90
+ plan(sutDefinitions: ISutFactory[], caseDefinitions: ICaseDefinition[]): {
91
+ sutId: string;
92
+ caseId: string;
93
+ repetition: number;
94
+ seed: number;
95
+ }[];
96
+ }
97
+ /**
98
+ * File system interface for file operations.
99
+ */
100
+ export interface IFileSystem {
101
+ readFile(path: string, encoding: string): Promise<string>;
102
+ }
103
+ /**
104
+ * Aggregator interface.
105
+ */
106
+ export interface IAggregator {
107
+ aggregateResults(results: EvaluationResult[], options: {
108
+ groupByCaseClass: boolean;
109
+ computeComparisons: boolean;
110
+ }): Awaited<ReturnType<typeof import("../aggregation/index.js").aggregateResults>>;
111
+ createAggregationOutput(aggregates: Awaited<ReturnType<typeof import("../aggregation/index.js").aggregateResults>>, results: EvaluationResult[]): AggregationOutput;
112
+ }
113
+ /**
114
+ * Command dependencies container.
115
+ */
116
+ export interface ICommandDependencies {
117
+ logger: ICommandLogger;
118
+ configLoader: IConfigLoader;
119
+ moduleLoader: IModuleLoader;
120
+ outputWriter: IOutputWriter;
121
+ executor: new (config: unknown) => IExecutor;
122
+ aggregator: IAggregator;
123
+ processExit: (code: number) => never;
124
+ }
125
+ //# sourceMappingURL=command-deps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command-deps.d.ts","sourceRoot":"","sources":["../../src/cli/command-deps.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C;;GAEG;AACH,MAAM,WAAW,cAAc;IAC9B,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC7B,qBAAqB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;CACjE;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,OAAO,CAAC;IAChB,GAAG,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAC1C;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC/B,IAAI,EAAE,cAAc,CAAC;IACrB,QAAQ,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,OAAO,EAAE,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IACjC,OAAO,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,KAAK,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrE;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC7B,cAAc,CACb,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,YAAY,EAAE;QACb,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,OAAO,CAAC;QAChB,IAAI,EAAE,MAAM,EAAE,CAAC;QACf,WAAW,CAAC,EAAE,MAAM,CAAC;KACrB,EACD,SAAS,EAAE,OAAO,GAChB,OAAO,CAAC,WAAW,CAAC,CAAC;IAExB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IAElG,oBAAoB,CACnB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,GACb,OAAO,CAAC,iBAAiB,CAAC,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC7B,sBAAsB,CAAC,cAAc,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,YAAY,GAAG,MAAM,CAAC;IACvF,YAAY,CACX,OAAO,EAAE,gBAAgB,EAAE,EAC3B,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,GAAG,aAAa,GAC5B,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,eAAe,CACd,UAAU,EAAE,iBAAiB,EAC7B,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,GAAG,aAAa,GAC5B,OAAO,CAAC,IAAI,CAAC,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACzB,OAAO,CACN,cAAc,EAAE,WAAW,EAAE,EAC7B,eAAe,EAAE,eAAe,EAAE,EAClC,gBAAgB,EAAE,iBAAiB,EACnC,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,GAC3C,OAAO,CAAC;QACV,SAAS,EAAE,MAAM,CAAC;QAClB,cAAc,EAAE,MAAM,CAAC;QACvB,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,gBAAgB,EAAE,CAAC;QAC5B,MAAM,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;KAC3C,CAAC,CAAC;IAEH,IAAI,CACH,cAAc,EAAE,WAAW,EAAE,EAC7B,eAAe,EAAE,eAAe,EAAE,GAChC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACzE;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC1D;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC3B,gBAAgB,CACf,OAAO,EAAE,gBAAgB,EAAE,EAC3B,OAAO,EAAE;QAAE,gBAAgB,EAAE,OAAO,CAAC;QAAC,kBAAkB,EAAE,OAAO,CAAA;KAAE,GACjE,OAAO,CAAC,UAAU,CAAC,cAAc,yBAAyB,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAElF,uBAAuB,CACtB,UAAU,EAAE,OAAO,CAAC,UAAU,CAAC,cAAc,yBAAyB,EAAE,gBAAgB,CAAC,CAAC,EAC1F,OAAO,EAAE,gBAAgB,EAAE,GACzB,iBAAiB,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACpC,MAAM,EAAE,cAAc,CAAC;IACvB,YAAY,EAAE,aAAa,CAAC;IAC5B,YAAY,EAAE,aAAa,CAAC;IAC5B,YAAY,EAAE,aAAa,CAAC;IAC5B,QAAQ,EAAE,KAAK,MAAM,EAAE,OAAO,KAAK,SAAS,CAAC;IAC7C,UAAU,EAAE,WAAW,CAAC;IACxB,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,KAAK,CAAC;CACrC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Command dependencies interface for dependency injection.
3
+ *
4
+ * This allows commands to be tested with mocked dependencies.
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=command-deps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command-deps.js","sourceRoot":"","sources":["../../src/cli/command-deps.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Aggregate Command
3
+ *
4
+ * Aggregates existing results from a JSON file.
5
+ */
6
+ import type { Command } from "commander";
7
+ import type { IAggregator, ICommandLogger, IFileSystem, IOutputWriter } from "../command-deps.js";
8
+ /**
9
+ * Execute aggregate command with injected dependencies.
10
+ *
11
+ * This function is exported for testing.
12
+ *
13
+ * @param resultsFile - Path to results JSON file
14
+ * @param options - Command options
15
+ * @param dependencies - Injected dependencies
16
+ */
17
+ export declare function executeAggregate(resultsFile: string, options: {
18
+ output?: string;
19
+ format?: "json" | "json-pretty";
20
+ groupByCaseClass?: boolean;
21
+ computeComparisons?: boolean;
22
+ }, dependencies: {
23
+ logger: ICommandLogger;
24
+ fileSystem: IFileSystem;
25
+ aggregator: IAggregator;
26
+ outputWriter: IOutputWriter;
27
+ processExit: (code: number) => never;
28
+ }): Promise<void>;
29
+ /**
30
+ * Register the aggregate command.
31
+ *
32
+ * @param program - Commander program instance
33
+ */
34
+ export declare function registerAggregateCommand(program: Command): void;
35
+ //# sourceMappingURL=aggregate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aggregate.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/aggregate.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGzC,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAIlG;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CACrC,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE;IACR,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,GAAG,aAAa,CAAC;IAChC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC7B,EACD,YAAY,EAAE;IACb,MAAM,EAAE,cAAc,CAAC;IACvB,UAAU,EAAE,WAAW,CAAC;IACxB,UAAU,EAAE,WAAW,CAAC;IACxB,YAAY,EAAE,aAAa,CAAC;IAC5B,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,KAAK,CAAC;CACrC,GACC,OAAO,CAAC,IAAI,CAAC,CAgFf;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAwC/D"}
@@ -0,0 +1,121 @@
1
+ /**
2
+ * Aggregate Command
3
+ *
4
+ * Aggregates existing results from a JSON file.
5
+ */
6
+ import { readFile } from "node:fs/promises";
7
+ import { aggregateResults, createAggregationOutput } from "../../aggregation/index.js";
8
+ import { writeAggregates } from "../output-writer.js";
9
+ /**
10
+ * Execute aggregate command with injected dependencies.
11
+ *
12
+ * This function is exported for testing.
13
+ *
14
+ * @param resultsFile - Path to results JSON file
15
+ * @param options - Command options
16
+ * @param dependencies - Injected dependencies
17
+ */
18
+ export async function executeAggregate(resultsFile, options, dependencies) {
19
+ const { logger, fileSystem, aggregator, outputWriter, processExit } = dependencies;
20
+ try {
21
+ logger.header("Aggregating Results");
22
+ // Read results file
23
+ logger.info(`Reading results from: ${resultsFile}`);
24
+ const content = await fileSystem.readFile(resultsFile, "utf-8");
25
+ const data = JSON.parse(content);
26
+ if (!data.results || !Array.isArray(data.results)) {
27
+ throw new Error("Invalid results file: missing or invalid 'results' array");
28
+ }
29
+ logger.info(`Found ${data.results.length} results`);
30
+ // Aggregate
31
+ logger.subheader("Computing aggregations...");
32
+ const results = data.results;
33
+ const aggregates = aggregator.aggregateResults(results, {
34
+ groupByCaseClass: options.groupByCaseClass ?? true,
35
+ computeComparisons: options.computeComparisons ?? true,
36
+ });
37
+ const aggregationOutput = aggregator.createAggregationOutput(aggregates, results);
38
+ // Determine output path
39
+ const outputPath = options.output ?? resultsFile.replace("-results-", "-aggregates-");
40
+ const format = options.format ?? "json-pretty";
41
+ // Write aggregates
42
+ logger.subheader("Writing aggregates...");
43
+ await outputWriter.writeAggregates(aggregationOutput, outputPath, format);
44
+ logger.info(`Aggregates written to: ${outputPath}`);
45
+ // Display summary
46
+ logger.info("");
47
+ logger.subheader("Aggregation Summary");
48
+ for (const agg of aggregates) {
49
+ const caseClassSuffix = agg.caseClass ? ` (${agg.caseClass})` : "";
50
+ logger.info(`${agg.sut}${caseClassSuffix}:`);
51
+ logger.info(` Runs: ${agg.group.runCount}`);
52
+ logger.info(` Cases: ${agg.group.caseCount}`);
53
+ if (Object.keys(agg.metrics).length > 0) {
54
+ logger.info(` Metrics:`);
55
+ for (const [metric, stats] of Object.entries(agg.metrics)) {
56
+ const std = stats.std ?? 0;
57
+ logger.info(` ${metric}: mean=${stats.mean.toFixed(2)}, ` +
58
+ `median=${stats.median.toFixed(2)}, ` +
59
+ `std=${std.toFixed(2)}`);
60
+ }
61
+ }
62
+ if (agg.comparisons && Object.keys(agg.comparisons).length > 0) {
63
+ logger.info(` Comparisons:`);
64
+ for (const [baseline, comparison] of Object.entries(agg.comparisons)) {
65
+ logger.info(` vs ${baseline}:`);
66
+ if (comparison.pValue !== undefined) {
67
+ logger.info(` p-value: ${comparison.pValue.toFixed(4)}`);
68
+ }
69
+ if (comparison.effectSize !== undefined) {
70
+ logger.info(` effect size: ${comparison.effectSize.toFixed(4)}`);
71
+ }
72
+ }
73
+ }
74
+ }
75
+ logger.info("");
76
+ logger.info("Aggregation completed successfully!");
77
+ }
78
+ catch (error) {
79
+ if (error instanceof Error) {
80
+ logger.error(error.message);
81
+ }
82
+ else {
83
+ logger.error(String(error));
84
+ }
85
+ processExit(1);
86
+ }
87
+ }
88
+ /**
89
+ * Register the aggregate command.
90
+ *
91
+ * @param program - Commander program instance
92
+ */
93
+ export function registerAggregateCommand(program) {
94
+ program
95
+ .command("aggregate")
96
+ .description("Aggregate existing results from a JSON file")
97
+ .argument("<results-file>", "Path to results JSON file")
98
+ .option("-o, --output <path>", "Output file path")
99
+ .option("-f, --format <format>", "Output format (json or json-pretty)", "json-pretty")
100
+ .option("--group-by-case-class", "Group results by case class", true)
101
+ .option("--compute-comparisons", "Compute comparisons with baselines", true)
102
+ .action(async (resultsFile, options) => {
103
+ const { createLogger } = await import("../logger.js");
104
+ const logger = createLogger();
105
+ await executeAggregate(resultsFile, {
106
+ output: options.output,
107
+ format: options.format,
108
+ groupByCaseClass: options.groupByCaseClass,
109
+ computeComparisons: options.computeComparisons,
110
+ }, {
111
+ logger,
112
+ fileSystem: {
113
+ readFile: (path, encoding) => readFile(path, encoding),
114
+ },
115
+ aggregator: { aggregateResults, createAggregationOutput },
116
+ outputWriter: { writeAggregates },
117
+ processExit: (code) => process.exit(code),
118
+ });
119
+ });
120
+ }
121
+ //# sourceMappingURL=aggregate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aggregate.js","sourceRoot":"","sources":["../../../src/cli/commands/aggregate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Plan Command
3
+ *
4
+ * Shows execution plan without running experiments.
5
+ */
6
+ import type { Command } from "commander";
7
+ import type { ICaseDefinition, ICommandLogger, IConfigLoader, IModuleLoader, ISutFactory } from "../command-deps.js";
8
+ /**
9
+ * Execute plan command with injected dependencies.
10
+ *
11
+ * This function is exported for testing.
12
+ *
13
+ * @param configFile - Path to config file
14
+ * @param dependencies - Injected dependencies
15
+ */
16
+ export declare function executePlan(configFile: string, dependencies: {
17
+ logger: ICommandLogger;
18
+ configLoader: IConfigLoader;
19
+ moduleLoader: IModuleLoader;
20
+ executor: {
21
+ plan: (suts: ISutFactory[], cases: ICaseDefinition[]) => {
22
+ sutId: string;
23
+ caseId: string;
24
+ repetition: number;
25
+ seed: number;
26
+ }[];
27
+ };
28
+ processExit: (code: number) => never;
29
+ }): Promise<void>;
30
+ /**
31
+ * Register the plan command.
32
+ *
33
+ * @param program - Commander program instance
34
+ */
35
+ export declare function registerPlanCommand(program: Command): void;
36
+ //# sourceMappingURL=plan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/plan.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGzC,OAAO,KAAK,EACX,eAAe,EACf,cAAc,EACd,aAAa,EACb,aAAa,EACb,WAAW,EACX,MAAM,oBAAoB,CAAC;AAM5B;;;;;;;GAOG;AACH,wBAAsB,WAAW,CAChC,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE;IACb,MAAM,EAAE,cAAc,CAAC;IACvB,YAAY,EAAE,aAAa,CAAC;IAC5B,YAAY,EAAE,aAAa,CAAC;IAC5B,QAAQ,EAAE;QACT,IAAI,EAAE,CACL,IAAI,EAAE,WAAW,EAAE,EACnB,KAAK,EAAE,eAAe,EAAE,KACpB;YACJ,KAAK,EAAE,MAAM,CAAC;YACd,MAAM,EAAE,MAAM,CAAC;YACf,UAAU,EAAE,MAAM,CAAC;YACnB,IAAI,EAAE,MAAM,CAAC;SACb,EAAE,CAAC;KACJ,CAAC;IACF,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,KAAK,CAAC;CACrC,GACC,OAAO,CAAC,IAAI,CAAC,CAqFf;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAwB1D"}