fragment-ts 1.0.19 ā 1.0.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/commands/init.command.js +1 -1
- package/dist/cli/commands/test.command.d.ts +1 -0
- package/dist/cli/commands/test.command.d.ts.map +1 -1
- package/dist/cli/commands/test.command.js +149 -173
- package/dist/cli/commands/test.command.js.map +1 -1
- package/dist/testing/runner.d.ts +5 -2
- package/dist/testing/runner.d.ts.map +1 -1
- package/dist/testing/runner.js +110 -23
- package/dist/testing/runner.js.map +1 -1
- package/dist/web/application.d.ts.map +1 -1
- package/dist/web/application.js +1 -0
- package/dist/web/application.js.map +1 -1
- package/package.json +1 -1
- package/src/cli/commands/init.command.ts +1 -1
- package/src/cli/commands/test.command.ts +188 -173
- package/src/testing/runner.ts +138 -23
- package/src/web/application.ts +1 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test.command.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/test.command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,qBAAa,WAAW;IACtB,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;
|
|
1
|
+
{"version":3,"file":"test.command.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/test.command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,qBAAa,WAAW;IACtB,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;mBAkBlB,QAAQ;IA8I7B,OAAO,CAAC,MAAM,CAAC,oBAAoB;CAwIpC"}
|
|
@@ -50,6 +50,7 @@ class TestCommand {
|
|
|
50
50
|
.option("--env <environment>", "Environment mode: dev (use src/) or prod (use dist/)", "auto")
|
|
51
51
|
.option("--pattern <pattern>", "Test file pattern", "**/*.spec.ts")
|
|
52
52
|
.option("--coverage", "Generate coverage report")
|
|
53
|
+
.option("--no-color", "Disable colored output")
|
|
53
54
|
.action(async (options) => {
|
|
54
55
|
await this.runTests(options);
|
|
55
56
|
});
|
|
@@ -81,7 +82,7 @@ class TestCommand {
|
|
|
81
82
|
useTypeScript = false;
|
|
82
83
|
mode = "production (dist/)";
|
|
83
84
|
basePath = "dist";
|
|
84
|
-
pattern = options.pattern.replace(
|
|
85
|
+
pattern = options.pattern.replace(/\.ts$/, ".js") || "**/*.spec.js";
|
|
85
86
|
}
|
|
86
87
|
else {
|
|
87
88
|
// Auto-detect
|
|
@@ -95,191 +96,54 @@ class TestCommand {
|
|
|
95
96
|
useTypeScript = false;
|
|
96
97
|
mode = "auto-detected production (dist/)";
|
|
97
98
|
basePath = "dist";
|
|
98
|
-
pattern = options.pattern.replace(
|
|
99
|
+
pattern = options.pattern.replace(/\.ts$/, ".js") || "**/*.spec.js";
|
|
99
100
|
}
|
|
100
101
|
else {
|
|
101
102
|
console.log(chalk_1.default.red("No src/ or dist/ directory found. Run: fragment init"));
|
|
102
103
|
return;
|
|
103
104
|
}
|
|
104
105
|
}
|
|
105
|
-
console.log(chalk_1.default.gray(` Mode: ${mode}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
const
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
};
|
|
121
|
-
|
|
122
|
-
// Global test functions
|
|
123
|
-
global.describe = function(name, fn) {
|
|
124
|
-
const suite = { name, tests: [] };
|
|
125
|
-
testState.suites.push(suite);
|
|
126
|
-
testState.currentSuite = suite;
|
|
127
|
-
fn();
|
|
128
|
-
testState.currentSuite = null;
|
|
129
|
-
};
|
|
130
|
-
|
|
131
|
-
global.it = function(name, fn) {
|
|
132
|
-
if (!testState.currentSuite) {
|
|
133
|
-
throw new Error('it() must be called inside describe()');
|
|
134
|
-
}
|
|
135
|
-
testState.currentSuite.tests.push({ name, fn });
|
|
136
|
-
};
|
|
137
|
-
|
|
138
|
-
global.expect = function(actual) {
|
|
139
|
-
return {
|
|
140
|
-
toBe(expected) {
|
|
141
|
-
if (actual !== expected) {
|
|
142
|
-
throw new Error(\`Expected \${actual} to be \${expected}\`);
|
|
143
|
-
}
|
|
144
|
-
},
|
|
145
|
-
toEqual(expected) {
|
|
146
|
-
if (JSON.stringify(actual) !== JSON.stringify(expected)) {
|
|
147
|
-
throw new Error(\`Expected \${JSON.stringify(actual)} to equal \${JSON.stringify(expected)}\`);
|
|
148
|
-
}
|
|
149
|
-
},
|
|
150
|
-
toBeTruthy() {
|
|
151
|
-
if (!actual) {
|
|
152
|
-
throw new Error(\`Expected \${actual} to be truthy\`);
|
|
153
|
-
}
|
|
154
|
-
},
|
|
155
|
-
toBeFalsy() {
|
|
156
|
-
if (actual) {
|
|
157
|
-
throw new Error(\`Expected \${actual} to be falsy\`);
|
|
158
|
-
}
|
|
159
|
-
},
|
|
160
|
-
toThrow(expectedError) {
|
|
161
|
-
let threw = false;
|
|
162
|
-
let error = null;
|
|
163
|
-
try {
|
|
164
|
-
actual();
|
|
165
|
-
} catch (e) {
|
|
166
|
-
threw = true;
|
|
167
|
-
error = e;
|
|
168
|
-
}
|
|
169
|
-
if (!threw) {
|
|
170
|
-
throw new Error('Expected function to throw');
|
|
171
|
-
}
|
|
172
|
-
if (expectedError && error.message !== expectedError) {
|
|
173
|
-
throw new Error(\`Expected error message "\${expectedError}" but got "\${error.message}"\`);
|
|
174
|
-
}
|
|
175
|
-
},
|
|
176
|
-
toBeInstanceOf(expected) {
|
|
177
|
-
if (!(actual instanceof expected)) {
|
|
178
|
-
throw new Error(\`Expected \${actual} to be instance of \${expected.name}\`);
|
|
179
|
-
}
|
|
180
|
-
},
|
|
181
|
-
toContain(expected) {
|
|
182
|
-
if (!actual.includes(expected)) {
|
|
183
|
-
throw new Error(\`Expected \${actual} to contain \${expected}\`);
|
|
184
|
-
}
|
|
185
|
-
},
|
|
186
|
-
toHaveProperty(property, value) {
|
|
187
|
-
if (!(property in actual)) {
|
|
188
|
-
throw new Error(\`Expected object to have property \${property}\`);
|
|
189
|
-
}
|
|
190
|
-
if (value !== undefined && actual[property] !== value) {
|
|
191
|
-
throw new Error(\`Expected property \${property} to be \${value} but got \${actual[property]}\`);
|
|
192
|
-
}
|
|
193
|
-
},
|
|
194
|
-
toBeNull() {
|
|
195
|
-
if (actual !== null) {
|
|
196
|
-
throw new Error(\`Expected \${actual} to be null\`);
|
|
197
|
-
}
|
|
198
|
-
},
|
|
199
|
-
toBeUndefined() {
|
|
200
|
-
if (actual !== undefined) {
|
|
201
|
-
throw new Error(\`Expected \${actual} to be undefined\`);
|
|
202
|
-
}
|
|
203
|
-
},
|
|
204
|
-
toHaveLength(expected) {
|
|
205
|
-
if (actual.length !== expected) {
|
|
206
|
-
throw new Error(\`Expected length \${expected} but got \${actual.length}\`);
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
};
|
|
210
|
-
};
|
|
211
|
-
|
|
212
|
-
async function runTests() {
|
|
213
|
-
try {
|
|
214
|
-
// Find and load test files
|
|
215
|
-
const files = await glob('${basePath}/${pattern}', { cwd: process.cwd() });
|
|
216
|
-
|
|
217
|
-
if (files.length === 0) {
|
|
218
|
-
console.log('No test files found matching pattern: ${basePath}/${pattern}');
|
|
219
|
-
process.exit(0);
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
console.log(\`Found \${files.length} test file(s)\\n\`);
|
|
223
|
-
|
|
224
|
-
// Load all test files
|
|
225
|
-
for (const file of files) {
|
|
226
|
-
require(path.resolve(file));
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
// Run all tests
|
|
230
|
-
for (const suite of testState.suites) {
|
|
231
|
-
console.log(\`\\nš¦ \${suite.name}\`);
|
|
232
|
-
|
|
233
|
-
for (const test of suite.tests) {
|
|
234
|
-
try {
|
|
235
|
-
await test.fn();
|
|
236
|
-
console.log(\` ā \${test.name}\`);
|
|
237
|
-
testState.passed++;
|
|
238
|
-
} catch (error) {
|
|
239
|
-
console.log(\` ā \${test.name}\`);
|
|
240
|
-
console.error(\` \${error.message}\`);
|
|
241
|
-
testState.failed++;
|
|
242
|
-
testState.errors.push({
|
|
243
|
-
suite: suite.name,
|
|
244
|
-
test: test.name,
|
|
245
|
-
error: error.message,
|
|
246
|
-
stack: error.stack
|
|
247
|
-
});
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
// Print summary
|
|
253
|
-
console.log(\`\\n\\nš Results: \${testState.passed} passed, \${testState.failed} failed\\n\`);
|
|
254
|
-
|
|
255
|
-
if (testState.failed > 0) {
|
|
256
|
-
console.log('\\nā Failed Tests:\\n');
|
|
257
|
-
testState.errors.forEach(err => {
|
|
258
|
-
console.log(\` \${err.suite} > \${err.test}\`);
|
|
259
|
-
console.log(\` \${err.error}\\n\`);
|
|
260
|
-
});
|
|
261
|
-
process.exit(1);
|
|
262
|
-
} else {
|
|
263
|
-
console.log('ā
All tests passed!\\n');
|
|
264
|
-
process.exit(0);
|
|
265
|
-
}
|
|
266
|
-
} catch (error) {
|
|
267
|
-
console.error('Error running tests:', error);
|
|
268
|
-
process.exit(1);
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
runTests();
|
|
273
|
-
`;
|
|
106
|
+
console.log(chalk_1.default.gray(` Mode: ${mode}`));
|
|
107
|
+
console.log(chalk_1.default.gray(` Pattern: ${basePath}/${pattern}`));
|
|
108
|
+
// Check if we need to use ts-node for TypeScript files
|
|
109
|
+
const tsConfigPath = path.join(cwd, "tsconfig.json");
|
|
110
|
+
const hasTsConfig = fs.existsSync(tsConfigPath);
|
|
111
|
+
// Create a simple runner script that uses our test runner module
|
|
112
|
+
const scriptContent = this.generateRunnerScript({
|
|
113
|
+
useTypeScript,
|
|
114
|
+
basePath,
|
|
115
|
+
pattern,
|
|
116
|
+
hasTsConfig,
|
|
117
|
+
tsConfigPath,
|
|
118
|
+
watchMode: options.watch,
|
|
119
|
+
coverage: options.coverage,
|
|
120
|
+
noColor: options.color === false,
|
|
121
|
+
});
|
|
274
122
|
const scriptPath = path.join(cwd, ".fragment-test-runner.js");
|
|
275
123
|
try {
|
|
276
124
|
fs.writeFileSync(scriptPath, scriptContent);
|
|
125
|
+
// Make the script executable
|
|
126
|
+
fs.chmodSync(scriptPath, "755");
|
|
277
127
|
const nodeArgs = [scriptPath];
|
|
278
128
|
const env = {
|
|
279
129
|
...process.env,
|
|
280
130
|
TS_NODE_TRANSPILE_ONLY: "true",
|
|
281
131
|
NODE_ENV: "test",
|
|
132
|
+
// Only set TS_NODE_PROJECT if tsconfig exists
|
|
133
|
+
...(hasTsConfig && useTypeScript
|
|
134
|
+
? { TS_NODE_PROJECT: tsConfigPath }
|
|
135
|
+
: {}),
|
|
136
|
+
// Handle color output
|
|
137
|
+
FORCE_COLOR: options.color === false ? "0" : "1",
|
|
282
138
|
};
|
|
139
|
+
// Add --watch support
|
|
140
|
+
if (options.watch) {
|
|
141
|
+
console.log(chalk_1.default.yellow("\nā ļø Watch mode is not yet implemented. Running once.\n"));
|
|
142
|
+
}
|
|
143
|
+
// Add --coverage support
|
|
144
|
+
if (options.coverage) {
|
|
145
|
+
console.log(chalk_1.default.yellow("\nā ļø Coverage reporting is not yet implemented.\n"));
|
|
146
|
+
}
|
|
283
147
|
const proc = (0, child_process_1.spawn)("node", nodeArgs, {
|
|
284
148
|
cwd,
|
|
285
149
|
stdio: "inherit",
|
|
@@ -289,7 +153,9 @@ runTests();
|
|
|
289
153
|
try {
|
|
290
154
|
fs.unlinkSync(scriptPath);
|
|
291
155
|
}
|
|
292
|
-
catch {
|
|
156
|
+
catch (e) {
|
|
157
|
+
// Ignore cleanup errors
|
|
158
|
+
}
|
|
293
159
|
process.exit(code || 0);
|
|
294
160
|
});
|
|
295
161
|
proc.on("error", (error) => {
|
|
@@ -297,7 +163,9 @@ runTests();
|
|
|
297
163
|
try {
|
|
298
164
|
fs.unlinkSync(scriptPath);
|
|
299
165
|
}
|
|
300
|
-
catch {
|
|
166
|
+
catch (e) {
|
|
167
|
+
// Ignore cleanup errors
|
|
168
|
+
}
|
|
301
169
|
process.exit(1);
|
|
302
170
|
});
|
|
303
171
|
}
|
|
@@ -306,6 +174,114 @@ runTests();
|
|
|
306
174
|
process.exit(1);
|
|
307
175
|
}
|
|
308
176
|
}
|
|
177
|
+
static generateRunnerScript(options) {
|
|
178
|
+
const { useTypeScript, basePath, pattern, hasTsConfig, tsConfigPath, noColor, } = options;
|
|
179
|
+
// Determine the runner path - try to find the actual test runner
|
|
180
|
+
// This assumes the test runner is installed as a dependency
|
|
181
|
+
let runnerImportPath = "fragment-ts/testing";
|
|
182
|
+
// Try to find the local test runner first for development
|
|
183
|
+
const possiblePaths = [
|
|
184
|
+
path.join(process.cwd(), "node_modules", "fragment-ts", "testing"),
|
|
185
|
+
path.join(process.cwd(), "node_modules", "fragment-ts", "dist", "testing"),
|
|
186
|
+
path.join(__dirname, "..", "..", "testing"), // If we're in the fragment-ts package itself
|
|
187
|
+
];
|
|
188
|
+
let resolvedRunnerPath = runnerImportPath;
|
|
189
|
+
for (const testPath of possiblePaths) {
|
|
190
|
+
if (fs.existsSync(testPath + ".ts") || fs.existsSync(testPath + ".js")) {
|
|
191
|
+
resolvedRunnerPath = testPath;
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return `
|
|
196
|
+
"use strict";
|
|
197
|
+
|
|
198
|
+
${useTypeScript ? "require('ts-node/register/transpile-only');" : ""}
|
|
199
|
+
require('reflect-metadata');
|
|
200
|
+
|
|
201
|
+
// Set environment
|
|
202
|
+
process.env.NODE_ENV = 'test';
|
|
203
|
+
${noColor ? "process.env.FORCE_COLOR = '0';" : "process.env.FORCE_COLOR = '1';"}
|
|
204
|
+
|
|
205
|
+
// Set up TypeScript config if available
|
|
206
|
+
${hasTsConfig && useTypeScript
|
|
207
|
+
? `
|
|
208
|
+
try {
|
|
209
|
+
const tsNode = require('ts-node');
|
|
210
|
+
tsNode.register({
|
|
211
|
+
project: '${tsConfigPath}',
|
|
212
|
+
transpileOnly: true,
|
|
213
|
+
compilerOptions: {
|
|
214
|
+
module: 'commonjs',
|
|
215
|
+
target: 'ES2020',
|
|
216
|
+
esModuleInterop: true,
|
|
217
|
+
skipLibCheck: true
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
} catch (error) {
|
|
221
|
+
// Ignore, ts-node might not be available
|
|
222
|
+
}`
|
|
223
|
+
: ""}
|
|
224
|
+
|
|
225
|
+
let testRunner;
|
|
226
|
+
try {
|
|
227
|
+
// Try to import the test runner
|
|
228
|
+
const testModule = require('${resolvedRunnerPath}');
|
|
229
|
+
|
|
230
|
+
// Handle different export patterns
|
|
231
|
+
if (testModule.getTestRunner) {
|
|
232
|
+
testRunner = testModule.getTestRunner();
|
|
233
|
+
} else if (testModule.TestRunner) {
|
|
234
|
+
testRunner = new testModule.TestRunner();
|
|
235
|
+
} else if (testModule.default && testModule.default.getTestRunner) {
|
|
236
|
+
testRunner = testModule.default.getTestRunner();
|
|
237
|
+
} else {
|
|
238
|
+
// Fallback to creating a new instance
|
|
239
|
+
testRunner = testModule;
|
|
240
|
+
}
|
|
241
|
+
} catch (error) {
|
|
242
|
+
console.error('Failed to load test runner:', error.message);
|
|
243
|
+
console.error('Make sure fragment-ts is installed as a dependency');
|
|
244
|
+
process.exit(1);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
async function runTests() {
|
|
248
|
+
try {
|
|
249
|
+
console.log('Looking for test files...');
|
|
250
|
+
|
|
251
|
+
// Load test files with the runner
|
|
252
|
+
await testRunner.loadTestFiles('${basePath}/${pattern}');
|
|
253
|
+
|
|
254
|
+
// Run tests
|
|
255
|
+
await testRunner.run();
|
|
256
|
+
} catch (error) {
|
|
257
|
+
console.error('\\nā Error running tests:', error.message);
|
|
258
|
+
|
|
259
|
+
if (error.stack && process.env.DEBUG) {
|
|
260
|
+
console.error(error.stack);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
process.exit(1);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// Handle process termination
|
|
268
|
+
process.on('SIGINT', () => {
|
|
269
|
+
console.log('\\n\\nTest run interrupted');
|
|
270
|
+
process.exit(130);
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
process.on('SIGTERM', () => {
|
|
274
|
+
console.log('\\n\\nTest run terminated');
|
|
275
|
+
process.exit(143);
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
// Run the tests
|
|
279
|
+
runTests().catch(error => {
|
|
280
|
+
console.error('Unhandled error:', error);
|
|
281
|
+
process.exit(1);
|
|
282
|
+
});
|
|
283
|
+
`;
|
|
284
|
+
}
|
|
309
285
|
}
|
|
310
286
|
exports.TestCommand = TestCommand;
|
|
311
287
|
//# sourceMappingURL=test.command.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test.command.js","sourceRoot":"","sources":["../../../src/cli/commands/test.command.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,kDAA0B;AAC1B,2CAA6B;AAC7B,iDAAsC;AACtC,uCAAyB;AAEzB,MAAa,WAAW;IACtB,MAAM,CAAC,QAAQ,CAAC,OAAgB;QAC9B,OAAO;aACJ,OAAO,CAAC,MAAM,CAAC;aACf,WAAW,CAAC,WAAW,CAAC;aACxB,MAAM,CAAC,SAAS,EAAE,yBAAyB,CAAC;aAC5C,MAAM,CACL,qBAAqB,EACrB,sDAAsD,EACtD,MAAM,CACP;aACA,MAAM,CAAC,qBAAqB,EAAE,mBAAmB,EAAE,cAAc,CAAC;aAClE,MAAM,CAAC,YAAY,EAAE,0BAA0B,CAAC;aAChD,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;YACxB,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QAC/B,CAAC,CAAC,CAAC;IACP,CAAC;IAEO,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAY;QACxC,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC,CAAC;QAE5D,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;QAC1B,MAAM,SAAS,GAAG,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;QACvD,MAAM,OAAO,GAAG,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC;QAEtD,IAAI,aAAsB,CAAC;QAC3B,IAAI,IAAY,CAAC;QACjB,IAAI,QAAgB,CAAC;QACrB,IAAI,OAAe,CAAC;QAEpB,IAAI,OAAO,CAAC,GAAG,KAAK,KAAK,EAAE,CAAC;YAC1B,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,OAAO,CAAC,GAAG,CACT,eAAK,CAAC,GAAG,CAAC,yDAAyD,CAAC,CACrE,CAAC;gBACF,OAAO;YACT,CAAC;YACD,aAAa,GAAG,IAAI,CAAC;YACrB,IAAI,GAAG,oBAAoB,CAAC;YAC5B,QAAQ,GAAG,KAAK,CAAC;YACjB,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,cAAc,CAAC;QAC9C,CAAC;aAAM,IAAI,OAAO,CAAC,GAAG,KAAK,MAAM,EAAE,CAAC;YAClC,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,OAAO,CAAC,GAAG,CACT,eAAK,CAAC,GAAG,CACP,8EAA8E,CAC/E,CACF,CAAC;gBACF,OAAO;YACT,CAAC;YACD,aAAa,GAAG,KAAK,CAAC;YACtB,IAAI,GAAG,oBAAoB,CAAC;YAC5B,QAAQ,GAAG,MAAM,CAAC;YAClB,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"test.command.js","sourceRoot":"","sources":["../../../src/cli/commands/test.command.ts"],"names":[],"mappings":"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"}
|
package/dist/testing/runner.d.ts
CHANGED
|
@@ -12,10 +12,13 @@ export declare class TestRunner {
|
|
|
12
12
|
private suites;
|
|
13
13
|
private passed;
|
|
14
14
|
private failed;
|
|
15
|
+
private errors;
|
|
15
16
|
describe(name: string, fn: () => void): void;
|
|
16
17
|
run(): Promise<void>;
|
|
17
18
|
loadTestFiles(pattern: string): Promise<void>;
|
|
18
19
|
}
|
|
20
|
+
export declare function getTestRunner(): TestRunner;
|
|
21
|
+
export declare function initTestRunner(): TestRunner;
|
|
19
22
|
export declare function describe(name: string, fn: () => void): void;
|
|
20
23
|
export declare function it(name: string, fn: () => void | Promise<void>): void;
|
|
21
24
|
export declare function beforeEach(fn: () => void | Promise<void>): void;
|
|
@@ -25,10 +28,10 @@ export declare function expect(actual: any): {
|
|
|
25
28
|
toEqual(expected: any): void;
|
|
26
29
|
toBeTruthy(): void;
|
|
27
30
|
toBeFalsy(): void;
|
|
28
|
-
toThrow(): void;
|
|
31
|
+
toThrow(expectedError?: string): void;
|
|
29
32
|
toBeInstanceOf(expected: any): void;
|
|
30
33
|
toContain(expected: any): void;
|
|
31
|
-
toHaveProperty(
|
|
34
|
+
toHaveProperty(property: string, value?: any): void;
|
|
32
35
|
toBeNull(): void;
|
|
33
36
|
toBeUndefined(): void;
|
|
34
37
|
toHaveLength(expected: number): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/testing/runner.ts"],"names":[],"mappings":"AAmBA,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,eAAe,EAAE,KAAK,CAAC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACnD,cAAc,EAAE,KAAK,CAAC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;CACnD;AAED,MAAM,WAAW,IAAI;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAChC;AAKD,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,MAAM,CAAK;
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/testing/runner.ts"],"names":[],"mappings":"AAmBA,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,eAAe,EAAE,KAAK,CAAC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACnD,cAAc,EAAE,KAAK,CAAC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;CACnD;AAED,MAAM,WAAW,IAAI;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAChC;AAKD,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,MAAM,CAKN;IAER,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,IAAI,GAAG,IAAI;IAiCtC,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;IAiEpB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CA2BpD;AAOD,wBAAgB,aAAa,IAAI,UAAU,CAM1C;AAED,wBAAgB,cAAc,IAAI,UAAU,CAE3C;AAkBD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,IAAI,GAAG,IAAI,CAa3D;AAED,wBAAgB,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAKrE;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAK/D;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAK9D;AAKD,wBAAgB,MAAM,CAAC,MAAM,EAAE,GAAG;mBAEf,GAAG;sBAMA,GAAG;;;4BAoBG,MAAM;6BAyBL,GAAG;wBAMR,GAAG;6BAUE,MAAM,UAAU,GAAG;;;2BAwBrB,MAAM;EAUhC"}
|
package/dist/testing/runner.js
CHANGED
|
@@ -34,6 +34,8 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.TestRunner = void 0;
|
|
37
|
+
exports.getTestRunner = getTestRunner;
|
|
38
|
+
exports.initTestRunner = initTestRunner;
|
|
37
39
|
exports.describe = describe;
|
|
38
40
|
exports.it = it;
|
|
39
41
|
exports.beforeEach = beforeEach;
|
|
@@ -50,6 +52,7 @@ class TestRunner {
|
|
|
50
52
|
this.suites = [];
|
|
51
53
|
this.passed = 0;
|
|
52
54
|
this.failed = 0;
|
|
55
|
+
this.errors = [];
|
|
53
56
|
}
|
|
54
57
|
describe(name, fn) {
|
|
55
58
|
const suite = {
|
|
@@ -77,47 +80,118 @@ class TestRunner {
|
|
|
77
80
|
G.afterEach = originalAfterEach;
|
|
78
81
|
}
|
|
79
82
|
async run() {
|
|
80
|
-
console.log("\
|
|
83
|
+
console.log("\nš§Ŗ Running Fragment Tests\n");
|
|
84
|
+
if (this.suites.length === 0) {
|
|
85
|
+
console.log("No test suites found");
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
81
88
|
for (const suite of this.suites) {
|
|
82
|
-
console.log(`\
|
|
89
|
+
console.log(`\nš¦ ${suite.name}`);
|
|
90
|
+
if (suite.tests.length === 0) {
|
|
91
|
+
console.log(" (no tests)");
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
83
94
|
for (const test of suite.tests) {
|
|
84
95
|
try {
|
|
96
|
+
// Run beforeEach hooks
|
|
85
97
|
for (const hook of suite.beforeEachHooks) {
|
|
86
98
|
await hook();
|
|
87
99
|
}
|
|
100
|
+
// Run the test
|
|
88
101
|
await test.fn();
|
|
102
|
+
// Run afterEach hooks
|
|
89
103
|
for (const hook of suite.afterEachHooks) {
|
|
90
104
|
await hook();
|
|
91
105
|
}
|
|
92
|
-
console.log(`
|
|
106
|
+
console.log(` ā ${test.name}`);
|
|
93
107
|
this.passed++;
|
|
94
108
|
}
|
|
95
109
|
catch (error) {
|
|
96
|
-
console.log(`
|
|
110
|
+
console.log(` ā ${test.name}`);
|
|
97
111
|
console.error(` ${error?.message ?? error}`);
|
|
98
112
|
this.failed++;
|
|
113
|
+
this.errors.push({
|
|
114
|
+
suite: suite.name,
|
|
115
|
+
test: test.name,
|
|
116
|
+
error: error?.message ?? String(error),
|
|
117
|
+
stack: error?.stack,
|
|
118
|
+
});
|
|
99
119
|
}
|
|
100
120
|
}
|
|
101
121
|
}
|
|
102
|
-
|
|
122
|
+
// Print summary
|
|
123
|
+
console.log(`\n\nš Results: ${this.passed} passed, ${this.failed} failed\n`);
|
|
103
124
|
if (this.failed > 0) {
|
|
125
|
+
console.log("ā Failed Tests:\n");
|
|
126
|
+
this.errors.forEach((err) => {
|
|
127
|
+
console.log(` ${err.suite} > ${err.test}`);
|
|
128
|
+
console.log(` ${err.error}\n`);
|
|
129
|
+
});
|
|
104
130
|
process.exit(1);
|
|
105
131
|
}
|
|
132
|
+
else {
|
|
133
|
+
console.log("ā
All tests passed!\n");
|
|
134
|
+
process.exit(0);
|
|
135
|
+
}
|
|
106
136
|
}
|
|
107
137
|
async loadTestFiles(pattern) {
|
|
108
|
-
const files = await (0, glob_1.glob)(pattern);
|
|
138
|
+
const files = await (0, glob_1.glob)(pattern, { cwd: process.cwd() });
|
|
139
|
+
if (files.length === 0) {
|
|
140
|
+
console.log(`No test files found matching pattern: ${pattern}`);
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
console.log(`Found ${files.length} test file(s)\n`);
|
|
144
|
+
// Set the global runner before loading any files
|
|
145
|
+
G.__testRunner = this;
|
|
109
146
|
for (const file of files) {
|
|
110
|
-
|
|
147
|
+
const fullPath = path.resolve(file);
|
|
148
|
+
// Clear require cache for this file to allow hot reloading
|
|
149
|
+
delete require.cache[fullPath];
|
|
150
|
+
try {
|
|
151
|
+
require(fullPath);
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
console.error(`Error loading test file ${file}:`, error.message);
|
|
155
|
+
throw error;
|
|
156
|
+
}
|
|
111
157
|
}
|
|
112
158
|
}
|
|
113
159
|
}
|
|
114
160
|
exports.TestRunner = TestRunner;
|
|
161
|
+
/* ======================================================
|
|
162
|
+
* Singleton instance
|
|
163
|
+
* ====================================================== */
|
|
164
|
+
let runnerInstance = null;
|
|
165
|
+
function getTestRunner() {
|
|
166
|
+
if (!runnerInstance) {
|
|
167
|
+
runnerInstance = new TestRunner();
|
|
168
|
+
G.__testRunner = runnerInstance;
|
|
169
|
+
}
|
|
170
|
+
return runnerInstance;
|
|
171
|
+
}
|
|
172
|
+
function initTestRunner() {
|
|
173
|
+
return getTestRunner();
|
|
174
|
+
}
|
|
175
|
+
/* ======================================================
|
|
176
|
+
* Auto-initialization for test environment
|
|
177
|
+
* ====================================================== */
|
|
178
|
+
// Auto-initialize when in test environment
|
|
179
|
+
if (process.env.NODE_ENV === "test" ||
|
|
180
|
+
process.argv.some((arg) => arg.includes("test"))) {
|
|
181
|
+
if (!G.__testRunner) {
|
|
182
|
+
getTestRunner();
|
|
183
|
+
}
|
|
184
|
+
}
|
|
115
185
|
/* ======================================================
|
|
116
186
|
* Global test helpers
|
|
117
187
|
* ====================================================== */
|
|
118
188
|
function describe(name, fn) {
|
|
119
189
|
if (!G.__testRunner) {
|
|
120
|
-
|
|
190
|
+
// Try to auto-initialize
|
|
191
|
+
getTestRunner();
|
|
192
|
+
}
|
|
193
|
+
if (!G.__testRunner) {
|
|
194
|
+
throw new Error("TestRunner not initialized. Make sure to call initTestRunner() or run tests via 'fragment test' command");
|
|
121
195
|
}
|
|
122
196
|
G.__testRunner.describe(name, fn);
|
|
123
197
|
}
|
|
@@ -166,20 +240,25 @@ function expect(actual) {
|
|
|
166
240
|
throw new Error(`Expected ${actual} to be falsy`);
|
|
167
241
|
}
|
|
168
242
|
},
|
|
169
|
-
toThrow() {
|
|
243
|
+
toThrow(expectedError) {
|
|
170
244
|
if (typeof actual !== "function") {
|
|
171
245
|
throw new Error("toThrow expects a function");
|
|
172
246
|
}
|
|
173
247
|
let threw = false;
|
|
248
|
+
let error = null;
|
|
174
249
|
try {
|
|
175
250
|
actual();
|
|
176
251
|
}
|
|
177
|
-
catch {
|
|
252
|
+
catch (e) {
|
|
178
253
|
threw = true;
|
|
254
|
+
error = e;
|
|
179
255
|
}
|
|
180
256
|
if (!threw) {
|
|
181
257
|
throw new Error("Expected function to throw an error");
|
|
182
258
|
}
|
|
259
|
+
if (expectedError && error?.message !== expectedError) {
|
|
260
|
+
throw new Error(`Expected error message "${expectedError}" but got "${error?.message}"`);
|
|
261
|
+
}
|
|
183
262
|
},
|
|
184
263
|
toBeInstanceOf(expected) {
|
|
185
264
|
if (!(actual instanceof expected)) {
|
|
@@ -194,9 +273,12 @@ function expect(actual) {
|
|
|
194
273
|
throw new Error(`Expected ${actual} to contain ${expected}`);
|
|
195
274
|
}
|
|
196
275
|
},
|
|
197
|
-
toHaveProperty(
|
|
198
|
-
if (actual == null || !(
|
|
199
|
-
throw new Error(`Expected object to have property "${
|
|
276
|
+
toHaveProperty(property, value) {
|
|
277
|
+
if (actual == null || !(property in actual)) {
|
|
278
|
+
throw new Error(`Expected object to have property "${property}"`);
|
|
279
|
+
}
|
|
280
|
+
if (value !== undefined && actual[property] !== value) {
|
|
281
|
+
throw new Error(`Expected property "${property}" to be ${value} but got ${actual[property]}`);
|
|
200
282
|
}
|
|
201
283
|
},
|
|
202
284
|
toBeNull() {
|
|
@@ -220,17 +302,22 @@ function expect(actual) {
|
|
|
220
302
|
};
|
|
221
303
|
}
|
|
222
304
|
/* ======================================================
|
|
223
|
-
* CLI entry
|
|
305
|
+
* CLI entry (when this file is run directly)
|
|
224
306
|
* ====================================================== */
|
|
225
307
|
if (require.main === module) {
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
308
|
+
(async () => {
|
|
309
|
+
try {
|
|
310
|
+
const runner = getTestRunner();
|
|
311
|
+
// Auto-detect TypeScript based on arguments
|
|
312
|
+
const isTsNode = process.argv.some((arg) => arg.includes("ts-node") || arg.includes("ts-node/register"));
|
|
313
|
+
const pattern = isTsNode ? "src/**/*.spec.ts" : "dist/**/*.spec.js";
|
|
314
|
+
await runner.loadTestFiles(pattern);
|
|
315
|
+
await runner.run();
|
|
316
|
+
}
|
|
317
|
+
catch (err) {
|
|
318
|
+
console.error("Failed to run tests:", err.message);
|
|
319
|
+
process.exit(1);
|
|
320
|
+
}
|
|
321
|
+
})();
|
|
235
322
|
}
|
|
236
323
|
//# sourceMappingURL=runner.js.map
|