Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4d1896bdf9 | |||
| fdc84a2d83 | |||
| d92850e1d2 | |||
| 6c498b3686 | |||
| 913c3cafe8 | |||
| 9ec2c8b6eb |
21
changelog.md
21
changelog.md
@@ -1,5 +1,26 @@
|
||||
# Changelog
|
||||
|
||||
## 2026-01-25 - 3.1.8 - fix(tapbundle)
|
||||
treat tests that call tools.allowFailure() as passing and update tests to use tools parameter
|
||||
|
||||
- Set testResult.ok to this.failureAllowed so allowed failures are considered passing in the tap test runner implementation (ts_tapbundle/tapbundle.classes.taptest.ts).
|
||||
- Updated multiple tests to accept the tools parameter and call tools.allowFailure() where failures are intended (test/tapbundle/test.performance-metrics.ts, test/tstest/test.fail.ts, test/tstest/test.failing-with-logs.ts).
|
||||
- Prevents intentionally-failing tests from skewing timing/metric calculations and preserves console logs for allowed failures.
|
||||
|
||||
## 2026-01-25 - 3.1.7 - fix(tap-parser)
|
||||
append newline to WebSocket tap log messages to ensure proper line-by-line processing
|
||||
|
||||
- Fixes handling of WebSocket console.log messages by appending a trailing newline before processing to avoid merged lines.
|
||||
- Modified ts/tstest.classes.tap.parser.ts: handleTapLog now calls _processLog(tapLog + '\n').
|
||||
|
||||
## 2026-01-19 - 3.1.6 - fix(logging)
|
||||
handle mid-line streaming output in test logger and add streaming tests
|
||||
|
||||
- Introduce isOutputMidLine flag to track when streaming output does not end with a newline
|
||||
- Only prepend the visual prefix at the start of a line and append segments to the last buffered entry when mid-line
|
||||
- Write consistent output to log files for both complete lines and raw streaming segments
|
||||
- Add tests to exercise streaming behavior: test/tstest/test.gap-debug.ts and test/tstest/test.gap-debug2.ts
|
||||
|
||||
## 2026-01-19 - 3.1.5 - fix(tstest)
|
||||
preserve streaming console output and correctly buffer incomplete TAP lines
|
||||
|
||||
|
||||
@@ -9,5 +9,5 @@
|
||||
"target": "ES2022"
|
||||
},
|
||||
"nodeModulesDir": true,
|
||||
"version": "3.1.5"
|
||||
"version": "3.1.8"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@git.zone/tstest",
|
||||
"version": "3.1.5",
|
||||
"version": "3.1.8",
|
||||
"private": false,
|
||||
"description": "a test utility to run tests that match test/**/*.ts",
|
||||
"exports": {
|
||||
|
||||
@@ -47,6 +47,7 @@ tap.test('metric test fast 3 - minimal work', async () => {
|
||||
|
||||
// Test to verify that failed tests still contribute to timing metrics
|
||||
tap.test('metric test that fails - 60ms before failure', async (tools) => {
|
||||
tools.allowFailure();
|
||||
await tools.delayFor(60);
|
||||
expect(true).toBeFalse(); // This will fail
|
||||
});
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { expect, tap } from '../../ts_tapbundle/index.js';
|
||||
|
||||
tap.test('This test should fail', async () => {
|
||||
tap.test('This test should fail', async (tools) => {
|
||||
tools.allowFailure();
|
||||
console.log('This test will fail on purpose');
|
||||
expect(true).toBeFalse();
|
||||
});
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { expect, tap } from '../../ts_tapbundle/index.js';
|
||||
|
||||
tap.test('Test that will fail with console logs', async () => {
|
||||
tap.test('Test that will fail with console logs', async (tools) => {
|
||||
tools.allowFailure();
|
||||
console.log('Starting the test...');
|
||||
console.log('Doing some setup work');
|
||||
console.log('About to check assertion');
|
||||
|
||||
12
test/tstest/test.gap-debug.ts
Normal file
12
test/tstest/test.gap-debug.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { tap, expect } from '../../ts_tapbundle/index.js';
|
||||
|
||||
tap.test('check for gaps in streaming', async () => {
|
||||
// This should print "ABCD" with no gaps
|
||||
process.stdout.write("A");
|
||||
process.stdout.write("B");
|
||||
process.stdout.write("C");
|
||||
process.stdout.write("D\n");
|
||||
expect(true).toEqual(true);
|
||||
});
|
||||
|
||||
export default tap.start();
|
||||
14
test/tstest/test.gap-debug2.ts
Normal file
14
test/tstest/test.gap-debug2.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { tap, expect } from '../../ts_tapbundle/index.js';
|
||||
|
||||
tap.test('streaming with delays', async (tools) => {
|
||||
// Simulate real streaming with delays
|
||||
process.stdout.write("Progress: [");
|
||||
for (let i = 0; i < 10; i++) {
|
||||
await tools.delayFor(50);
|
||||
process.stdout.write("=");
|
||||
}
|
||||
process.stdout.write("]\n");
|
||||
expect(true).toEqual(true);
|
||||
});
|
||||
|
||||
export default tap.start();
|
||||
@@ -3,6 +3,6 @@
|
||||
*/
|
||||
export const commitinfo = {
|
||||
name: '@git.zone/tstest',
|
||||
version: '3.1.5',
|
||||
version: '3.1.8',
|
||||
description: 'a test utility to run tests that match test/**/*.ts'
|
||||
}
|
||||
|
||||
@@ -487,7 +487,9 @@ export class TapParser {
|
||||
}
|
||||
|
||||
public async handleTapLog(tapLog: string) {
|
||||
this._processLog(tapLog);
|
||||
// Each WebSocket message represents a complete console.log() call,
|
||||
// so append newline to ensure proper line-by-line processing
|
||||
this._processLog(tapLog + '\n');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -44,6 +44,7 @@ export class TsTestLogger {
|
||||
private currentTestLogFile: string | null = null;
|
||||
private currentTestLogs: string[] = []; // Buffer for current test logs
|
||||
private currentTestFailed: boolean = false;
|
||||
private isOutputMidLine: boolean = false; // Track whether we're mid-line for streaming output
|
||||
|
||||
constructor(options: LogOptions = {}) {
|
||||
this.options = options;
|
||||
@@ -189,6 +190,7 @@ export class TsTestLogger {
|
||||
// Reset test-specific state
|
||||
this.currentTestLogs = [];
|
||||
this.currentTestFailed = false;
|
||||
this.isOutputMidLine = false;
|
||||
|
||||
// Only set up test log file if --logfile option is specified
|
||||
if (this.options.logFile) {
|
||||
@@ -352,17 +354,28 @@ export class TsTestLogger {
|
||||
testConsoleOutput(message: string) {
|
||||
if (this.options.json) return;
|
||||
|
||||
const prefix = ' ';
|
||||
// In verbose mode, show console output immediately
|
||||
if (this.options.verbose) {
|
||||
this.log(this.format(` ${message}`, 'dim'));
|
||||
// Only add prefix if we're starting a new line
|
||||
const output = this.isOutputMidLine ? message : prefix + message;
|
||||
this.log(this.format(output, 'dim'));
|
||||
} else {
|
||||
// In non-verbose mode, buffer the logs
|
||||
this.currentTestLogs.push(message);
|
||||
if (this.isOutputMidLine && this.currentTestLogs.length > 0) {
|
||||
// Append to the last buffered entry since we're mid-line
|
||||
this.currentTestLogs[this.currentTestLogs.length - 1] += message;
|
||||
} else {
|
||||
this.currentTestLogs.push(message);
|
||||
}
|
||||
}
|
||||
|
||||
// Reset mid-line state since we just output a complete line
|
||||
this.isOutputMidLine = false;
|
||||
|
||||
// Always log to test file if --logfile is specified
|
||||
if (this.currentTestLogFile) {
|
||||
this.logToTestFile(` ${message}`);
|
||||
this.logToTestFile(`${prefix}${message}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -371,13 +384,15 @@ export class TsTestLogger {
|
||||
if (this.options.json) return;
|
||||
|
||||
const prefix = ' ';
|
||||
// Only add prefix if we're starting a new line (not mid-line)
|
||||
const output = this.isOutputMidLine ? message : prefix + message;
|
||||
|
||||
if (this.options.verbose) {
|
||||
// Use process.stdout.write to preserve streaming without adding newlines
|
||||
process.stdout.write(this.format(prefix + message, 'dim'));
|
||||
process.stdout.write(this.format(output, 'dim'));
|
||||
} else {
|
||||
// Buffer without trailing newline - append to last entry if exists and incomplete
|
||||
if (this.currentTestLogs.length > 0) {
|
||||
// Append to the last buffered entry (for streaming segments)
|
||||
// Buffer mode: append to last entry if mid-line
|
||||
if (this.isOutputMidLine && this.currentTestLogs.length > 0) {
|
||||
this.currentTestLogs[this.currentTestLogs.length - 1] += message;
|
||||
} else {
|
||||
this.currentTestLogs.push(message);
|
||||
@@ -386,8 +401,11 @@ export class TsTestLogger {
|
||||
|
||||
// Log to test file without adding newline
|
||||
if (this.currentTestLogFile) {
|
||||
this.logToTestFileRaw(prefix + message);
|
||||
this.logToTestFileRaw(output);
|
||||
}
|
||||
|
||||
// We're now mid-line (no newline was written)
|
||||
this.isOutputMidLine = true;
|
||||
}
|
||||
|
||||
private logToTestFileRaw(message: string) {
|
||||
|
||||
@@ -261,7 +261,7 @@ export class TapTest<T = unknown> {
|
||||
|
||||
// Final failure
|
||||
const testResult = {
|
||||
ok: false,
|
||||
ok: this.failureAllowed, // Pass if failure is allowed
|
||||
testNumber,
|
||||
description: this.description,
|
||||
metadata: {
|
||||
|
||||
Reference in New Issue
Block a user