taist 0.1.2 → 0.1.4
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/instrument.js +10 -3
- package/lib/service-tracer.js +2 -0
- package/lib/toon-formatter.js +23 -0
- package/lib/vitest-reporter.js +17 -2
- package/package.json +1 -1
package/instrument.js
CHANGED
|
@@ -94,22 +94,29 @@ if (tracer.options.enabled) {
|
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
// Output stats periodically if not writing to file
|
|
97
|
+
// Use unref() so this doesn't keep the process alive
|
|
97
98
|
if (!tracer.options.outputFile) {
|
|
98
|
-
setInterval(() => {
|
|
99
|
+
const outputTimer = setInterval(() => {
|
|
99
100
|
const output = tracer.writeOutput();
|
|
100
101
|
console.log('\n' + output);
|
|
101
102
|
}, tracer.options.outputInterval);
|
|
103
|
+
outputTimer.unref();
|
|
102
104
|
}
|
|
103
105
|
|
|
104
|
-
// Handle shutdown gracefully
|
|
106
|
+
// Handle shutdown gracefully - but don't force exit (let process exit naturally)
|
|
107
|
+
// This allows test runners like Vitest to handle cleanup properly
|
|
108
|
+
let shutdownCalled = false;
|
|
105
109
|
const shutdown = () => {
|
|
110
|
+
if (shutdownCalled) return;
|
|
111
|
+
shutdownCalled = true;
|
|
106
112
|
logger.log('Shutting down...');
|
|
107
113
|
const insights = tracer.getInsights();
|
|
108
114
|
const output = tracer.formatOutput(insights);
|
|
109
115
|
console.log('\n=== Final Trace Summary ===');
|
|
110
116
|
console.log(output);
|
|
111
117
|
console.log('===========================\n');
|
|
112
|
-
process.exit(
|
|
118
|
+
// Don't call process.exit() - let the process exit naturally
|
|
119
|
+
// This prevents interference with test runners like Vitest
|
|
113
120
|
};
|
|
114
121
|
|
|
115
122
|
process.on('SIGINT', shutdown);
|
package/lib/service-tracer.js
CHANGED
package/lib/toon-formatter.js
CHANGED
|
@@ -45,10 +45,22 @@ export class ToonFormatter {
|
|
|
45
45
|
*/
|
|
46
46
|
format(results) {
|
|
47
47
|
const lines = [];
|
|
48
|
+
const total = results.stats?.total || 0;
|
|
49
|
+
const tests = results.tests || [];
|
|
48
50
|
|
|
49
51
|
// Header
|
|
50
52
|
lines.push(this.formatHeader(results));
|
|
51
53
|
|
|
54
|
+
// Show passing tests when running small batches (≤10 tests)
|
|
55
|
+
if (total > 0 && total <= 10) {
|
|
56
|
+
const passingTests = tests.filter(t => t.state === 'pass');
|
|
57
|
+
for (const test of passingTests) {
|
|
58
|
+
const duration = Math.round(test.duration);
|
|
59
|
+
const shortName = this.shortenTestName(test.name);
|
|
60
|
+
lines.push(`✓ ${shortName} (${duration}ms)`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
52
64
|
// Failures
|
|
53
65
|
if (results.failures && results.failures.length > 0) {
|
|
54
66
|
lines.push('');
|
|
@@ -76,8 +88,19 @@ export class ToonFormatter {
|
|
|
76
88
|
return lines.join('\n');
|
|
77
89
|
}
|
|
78
90
|
|
|
91
|
+
/**
|
|
92
|
+
* Shorten a test name for display
|
|
93
|
+
* "Suite > Nested > actual test name" -> "actual test name"
|
|
94
|
+
*/
|
|
95
|
+
shortenTestName(name) {
|
|
96
|
+
if (!name) return '';
|
|
97
|
+
const parts = name.split(' > ');
|
|
98
|
+
return parts[parts.length - 1] || name;
|
|
99
|
+
}
|
|
100
|
+
|
|
79
101
|
/**
|
|
80
102
|
* Format test result header
|
|
103
|
+
* Note: total represents tests that actually ran, not discovered
|
|
81
104
|
*/
|
|
82
105
|
formatHeader(results) {
|
|
83
106
|
const passed = results.stats?.passed || 0;
|
package/lib/vitest-reporter.js
CHANGED
|
@@ -59,6 +59,7 @@ export class TaistReporter {
|
|
|
59
59
|
this.taskResults = new Map(); // Map task id to result
|
|
60
60
|
this.results = {
|
|
61
61
|
stats: { total: 0, passed: 0, failed: 0, skipped: 0 },
|
|
62
|
+
tests: [], // Individual test results for enhanced output
|
|
62
63
|
failures: [],
|
|
63
64
|
duration: 0,
|
|
64
65
|
trace: []
|
|
@@ -117,6 +118,7 @@ export class TaistReporter {
|
|
|
117
118
|
|
|
118
119
|
// Reset stats
|
|
119
120
|
this.results.stats = { total: 0, passed: 0, failed: 0, skipped: 0 };
|
|
121
|
+
this.results.tests = [];
|
|
120
122
|
this.results.failures = [];
|
|
121
123
|
|
|
122
124
|
// Process all test files
|
|
@@ -181,17 +183,30 @@ export class TaistReporter {
|
|
|
181
183
|
*/
|
|
182
184
|
_processTask(task, file) {
|
|
183
185
|
if (task.type === 'test') {
|
|
184
|
-
this.results.stats.total++;
|
|
185
|
-
|
|
186
186
|
const state = task.result?.state;
|
|
187
|
+
|
|
188
|
+
// Only count tests that actually ran (have a pass/fail result)
|
|
187
189
|
if (state === 'pass') {
|
|
190
|
+
this.results.stats.total++;
|
|
188
191
|
this.results.stats.passed++;
|
|
192
|
+
this.results.tests.push({
|
|
193
|
+
name: this._getTestName(task),
|
|
194
|
+
duration: task.result?.duration || 0,
|
|
195
|
+
state: 'pass'
|
|
196
|
+
});
|
|
189
197
|
} else if (state === 'fail') {
|
|
198
|
+
this.results.stats.total++;
|
|
190
199
|
this.results.stats.failed++;
|
|
191
200
|
this.results.failures.push(this._formatFailure(task, file));
|
|
201
|
+
this.results.tests.push({
|
|
202
|
+
name: this._getTestName(task),
|
|
203
|
+
duration: task.result?.duration || 0,
|
|
204
|
+
state: 'fail'
|
|
205
|
+
});
|
|
192
206
|
} else if (state === 'skip') {
|
|
193
207
|
this.results.stats.skipped++;
|
|
194
208
|
}
|
|
209
|
+
// Tests without state (filtered out) are not counted
|
|
195
210
|
} else if (task.type === 'suite' && task.tasks) {
|
|
196
211
|
// Process nested tasks
|
|
197
212
|
for (const subtask of task.tasks) {
|