@git.zone/tstest 2.6.1 → 2.7.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.
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/tstest.classes.runtime.docker.d.ts +42 -0
- package/dist_ts/tstest.classes.runtime.docker.js +199 -0
- package/dist_ts/tstest.classes.runtime.parser.d.ts +28 -0
- package/dist_ts/tstest.classes.runtime.parser.js +59 -2
- package/dist_ts/tstest.classes.testdirectory.js +10 -4
- package/dist_ts/tstest.classes.tstest.d.ts +6 -0
- package/dist_ts/tstest.classes.tstest.js +27 -3
- package/package.json +4 -3
- package/readme.md +123 -0
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/tstest.classes.runtime.docker.ts +251 -0
- package/ts/tstest.classes.runtime.parser.ts +79 -1
- package/ts/tstest.classes.testdirectory.ts +13 -5
- package/ts/tstest.classes.tstest.ts +40 -2
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@git.zone/tstest',
|
|
6
|
-
version: '2.
|
|
6
|
+
version: '2.7.0',
|
|
7
7
|
description: 'a test utility to run tests that match test/**/*.ts'
|
|
8
8
|
};
|
|
9
9
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSxrQkFBa0I7SUFDeEIsT0FBTyxFQUFFLE9BQU87SUFDaEIsV0FBVyxFQUFFLHFEQUFxRDtDQUNuRSxDQUFBIn0=
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { RuntimeAdapter, type RuntimeOptions, type RuntimeCommand, type RuntimeAvailability } from './tstest.classes.runtime.adapter.js';
|
|
2
|
+
import { TapParser } from './tstest.classes.tap.parser.js';
|
|
3
|
+
import { TsTestLogger } from './tstest.logging.js';
|
|
4
|
+
import type { Runtime } from './tstest.classes.runtime.parser.js';
|
|
5
|
+
/**
|
|
6
|
+
* Docker runtime adapter
|
|
7
|
+
* Executes shell test files inside Docker containers
|
|
8
|
+
* Pattern: test.{variant}.docker.sh
|
|
9
|
+
* Variants map to Dockerfiles: latest -> Dockerfile, others -> Dockerfile_{variant}
|
|
10
|
+
*/
|
|
11
|
+
export declare class DockerRuntimeAdapter extends RuntimeAdapter {
|
|
12
|
+
private logger;
|
|
13
|
+
private smartshellInstance;
|
|
14
|
+
private timeoutSeconds;
|
|
15
|
+
private cwd;
|
|
16
|
+
readonly id: Runtime;
|
|
17
|
+
readonly displayName: string;
|
|
18
|
+
private builtImages;
|
|
19
|
+
constructor(logger: TsTestLogger, smartshellInstance: any, // SmartShell instance from @push.rocks/smartshell
|
|
20
|
+
timeoutSeconds: number | null, cwd: string);
|
|
21
|
+
/**
|
|
22
|
+
* Check if Docker CLI is available
|
|
23
|
+
*/
|
|
24
|
+
checkAvailable(): Promise<RuntimeAvailability>;
|
|
25
|
+
/**
|
|
26
|
+
* Create command configuration for Docker test execution
|
|
27
|
+
* This is used for informational purposes
|
|
28
|
+
*/
|
|
29
|
+
createCommand(testFile: string, options?: RuntimeOptions): RuntimeCommand;
|
|
30
|
+
/**
|
|
31
|
+
* Build a Docker image from the specified Dockerfile
|
|
32
|
+
*/
|
|
33
|
+
private buildDockerImage;
|
|
34
|
+
/**
|
|
35
|
+
* Execute a Docker test file
|
|
36
|
+
*/
|
|
37
|
+
run(testFile: string, index: number, total: number, options?: RuntimeOptions): Promise<TapParser>;
|
|
38
|
+
/**
|
|
39
|
+
* Clean up built Docker images (optional, can be called at end of test suite)
|
|
40
|
+
*/
|
|
41
|
+
cleanup(): Promise<void>;
|
|
42
|
+
}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import * as plugins from './tstest.plugins.js';
|
|
2
|
+
import { coloredString as cs } from '@push.rocks/consolecolor';
|
|
3
|
+
import { RuntimeAdapter, } from './tstest.classes.runtime.adapter.js';
|
|
4
|
+
import { TapParser } from './tstest.classes.tap.parser.js';
|
|
5
|
+
import { TsTestLogger } from './tstest.logging.js';
|
|
6
|
+
import { parseDockerTestFilename, mapVariantToDockerfile, isDockerTestFile } from './tstest.classes.runtime.parser.js';
|
|
7
|
+
/**
|
|
8
|
+
* Docker runtime adapter
|
|
9
|
+
* Executes shell test files inside Docker containers
|
|
10
|
+
* Pattern: test.{variant}.docker.sh
|
|
11
|
+
* Variants map to Dockerfiles: latest -> Dockerfile, others -> Dockerfile_{variant}
|
|
12
|
+
*/
|
|
13
|
+
export class DockerRuntimeAdapter extends RuntimeAdapter {
|
|
14
|
+
constructor(logger, smartshellInstance, // SmartShell instance from @push.rocks/smartshell
|
|
15
|
+
timeoutSeconds, cwd) {
|
|
16
|
+
super();
|
|
17
|
+
this.logger = logger;
|
|
18
|
+
this.smartshellInstance = smartshellInstance;
|
|
19
|
+
this.timeoutSeconds = timeoutSeconds;
|
|
20
|
+
this.cwd = cwd;
|
|
21
|
+
this.id = 'node'; // Using 'node' temporarily as Runtime type doesn't include 'docker'
|
|
22
|
+
this.displayName = 'Docker';
|
|
23
|
+
this.builtImages = new Set(); // Track built images to avoid rebuilding
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Check if Docker CLI is available
|
|
27
|
+
*/
|
|
28
|
+
async checkAvailable() {
|
|
29
|
+
try {
|
|
30
|
+
const result = await this.smartshellInstance.exec('docker --version');
|
|
31
|
+
if (result.exitCode !== 0) {
|
|
32
|
+
return {
|
|
33
|
+
available: false,
|
|
34
|
+
error: 'Docker command failed',
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
// Extract version from output like "Docker version 24.0.5, build ced0996"
|
|
38
|
+
const versionMatch = result.stdout.match(/Docker version ([^,]+)/);
|
|
39
|
+
const version = versionMatch ? versionMatch[1] : 'unknown';
|
|
40
|
+
return {
|
|
41
|
+
available: true,
|
|
42
|
+
version,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
return {
|
|
47
|
+
available: false,
|
|
48
|
+
error: `Docker not found: ${error.message}`,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Create command configuration for Docker test execution
|
|
54
|
+
* This is used for informational purposes
|
|
55
|
+
*/
|
|
56
|
+
createCommand(testFile, options) {
|
|
57
|
+
const parsed = parseDockerTestFilename(testFile);
|
|
58
|
+
const dockerfilePath = mapVariantToDockerfile(parsed.variant, this.cwd);
|
|
59
|
+
const imageName = `tstest-${parsed.variant}`;
|
|
60
|
+
return {
|
|
61
|
+
command: 'docker',
|
|
62
|
+
args: [
|
|
63
|
+
'run',
|
|
64
|
+
'--rm',
|
|
65
|
+
'-v',
|
|
66
|
+
`${this.cwd}/test:/test`,
|
|
67
|
+
imageName,
|
|
68
|
+
'taprun',
|
|
69
|
+
`/test/${plugins.path.basename(testFile)}`
|
|
70
|
+
],
|
|
71
|
+
env: {},
|
|
72
|
+
cwd: this.cwd,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Build a Docker image from the specified Dockerfile
|
|
77
|
+
*/
|
|
78
|
+
async buildDockerImage(dockerfilePath, imageName) {
|
|
79
|
+
// Check if image is already built
|
|
80
|
+
if (this.builtImages.has(imageName)) {
|
|
81
|
+
this.logger.tapOutput(`Using cached Docker image: ${imageName}`);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
// Check if Dockerfile exists
|
|
85
|
+
if (!await plugins.smartfile.fs.fileExists(dockerfilePath)) {
|
|
86
|
+
throw new Error(`Dockerfile not found: ${dockerfilePath}\n` +
|
|
87
|
+
`Expected Dockerfile for Docker test variant.`);
|
|
88
|
+
}
|
|
89
|
+
this.logger.tapOutput(`Building Docker image: ${imageName} from ${dockerfilePath}`);
|
|
90
|
+
try {
|
|
91
|
+
const buildResult = await this.smartshellInstance.exec(`docker build -f ${dockerfilePath} -t ${imageName} ${this.cwd}`, {
|
|
92
|
+
cwd: this.cwd,
|
|
93
|
+
});
|
|
94
|
+
if (buildResult.exitCode !== 0) {
|
|
95
|
+
throw new Error(`Docker build failed:\n${buildResult.stderr}`);
|
|
96
|
+
}
|
|
97
|
+
this.builtImages.add(imageName);
|
|
98
|
+
this.logger.tapOutput(`✅ Docker image built successfully: ${imageName}`);
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
throw new Error(`Failed to build Docker image: ${error.message}`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Execute a Docker test file
|
|
106
|
+
*/
|
|
107
|
+
async run(testFile, index, total, options) {
|
|
108
|
+
this.logger.testFileStart(testFile, this.displayName, index, total);
|
|
109
|
+
// Parse the Docker test filename
|
|
110
|
+
const parsed = parseDockerTestFilename(testFile);
|
|
111
|
+
const dockerfilePath = mapVariantToDockerfile(parsed.variant, this.cwd);
|
|
112
|
+
const imageName = `tstest-${parsed.variant}`;
|
|
113
|
+
// Build the Docker image
|
|
114
|
+
await this.buildDockerImage(dockerfilePath, imageName);
|
|
115
|
+
// Prepare the test file path relative to the mounted directory
|
|
116
|
+
// We need to get the path relative to cwd
|
|
117
|
+
const absoluteTestPath = plugins.path.isAbsolute(testFile)
|
|
118
|
+
? testFile
|
|
119
|
+
: plugins.path.join(this.cwd, testFile);
|
|
120
|
+
const relativeTestPath = plugins.path.relative(this.cwd, absoluteTestPath);
|
|
121
|
+
// Create TAP parser
|
|
122
|
+
const tapParser = new TapParser(testFile + ':docker', this.logger);
|
|
123
|
+
try {
|
|
124
|
+
// Build docker run command
|
|
125
|
+
const dockerArgs = [
|
|
126
|
+
'run',
|
|
127
|
+
'--rm',
|
|
128
|
+
'-v',
|
|
129
|
+
`${this.cwd}/test:/test`,
|
|
130
|
+
imageName,
|
|
131
|
+
'taprun',
|
|
132
|
+
`/test/${plugins.path.basename(testFile)}`
|
|
133
|
+
];
|
|
134
|
+
this.logger.tapOutput(`Executing: docker ${dockerArgs.join(' ')}`);
|
|
135
|
+
// Execute the Docker container
|
|
136
|
+
const execPromise = this.smartshellInstance.execStreaming(`docker ${dockerArgs.join(' ')}`, {
|
|
137
|
+
cwd: this.cwd,
|
|
138
|
+
});
|
|
139
|
+
// Set up timeout if configured
|
|
140
|
+
let timeoutHandle = null;
|
|
141
|
+
if (this.timeoutSeconds) {
|
|
142
|
+
timeoutHandle = setTimeout(() => {
|
|
143
|
+
this.logger.tapOutput(`⏱️ Test timeout (${this.timeoutSeconds}s) - killing container`);
|
|
144
|
+
// Try to kill any running containers with this image
|
|
145
|
+
this.smartshellInstance.exec(`docker ps -q --filter ancestor=${imageName} | xargs -r docker kill`);
|
|
146
|
+
}, this.timeoutSeconds * 1000);
|
|
147
|
+
}
|
|
148
|
+
// Stream output to TAP parser line by line
|
|
149
|
+
execPromise.childProcess.stdout.on('data', (data) => {
|
|
150
|
+
const output = data.toString();
|
|
151
|
+
const lines = output.split('\n');
|
|
152
|
+
for (const line of lines) {
|
|
153
|
+
if (line.trim()) {
|
|
154
|
+
tapParser.handleTapLog(line);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
execPromise.childProcess.stderr.on('data', (data) => {
|
|
159
|
+
const output = data.toString();
|
|
160
|
+
this.logger.tapOutput(cs(`[stderr] ${output}`, 'orange'));
|
|
161
|
+
});
|
|
162
|
+
// Wait for completion
|
|
163
|
+
const result = await execPromise;
|
|
164
|
+
// Clear timeout
|
|
165
|
+
if (timeoutHandle) {
|
|
166
|
+
clearTimeout(timeoutHandle);
|
|
167
|
+
}
|
|
168
|
+
if (result.exitCode !== 0) {
|
|
169
|
+
this.logger.tapOutput(cs(`❌ Docker test failed with exit code ${result.exitCode}`, 'red'));
|
|
170
|
+
}
|
|
171
|
+
// Evaluate final result
|
|
172
|
+
await tapParser.evaluateFinalResult();
|
|
173
|
+
}
|
|
174
|
+
catch (error) {
|
|
175
|
+
this.logger.tapOutput(cs(`❌ Error running Docker test: ${error.message}`, 'red'));
|
|
176
|
+
// Add a failing test result to the parser
|
|
177
|
+
tapParser.handleTapLog('not ok 1 - Docker test execution failed');
|
|
178
|
+
await tapParser.evaluateFinalResult();
|
|
179
|
+
}
|
|
180
|
+
return tapParser;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Clean up built Docker images (optional, can be called at end of test suite)
|
|
184
|
+
*/
|
|
185
|
+
async cleanup() {
|
|
186
|
+
for (const imageName of this.builtImages) {
|
|
187
|
+
try {
|
|
188
|
+
this.logger.tapOutput(`Removing Docker image: ${imageName}`);
|
|
189
|
+
await this.smartshellInstance.exec(`docker rmi ${imageName}`);
|
|
190
|
+
}
|
|
191
|
+
catch (error) {
|
|
192
|
+
// Ignore cleanup errors
|
|
193
|
+
this.logger.tapOutput(cs(`Warning: Failed to remove image ${imageName}: ${error.message}`, 'orange'));
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
this.builtImages.clear();
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHN0ZXN0LmNsYXNzZXMucnVudGltZS5kb2NrZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy90c3Rlc3QuY2xhc3Nlcy5ydW50aW1lLmRvY2tlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLHFCQUFxQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxhQUFhLElBQUksRUFBRSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDL0QsT0FBTyxFQUNMLGNBQWMsR0FJZixNQUFNLHFDQUFxQyxDQUFDO0FBQzdDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUMzRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFFbkQsT0FBTyxFQUNMLHVCQUF1QixFQUN2QixzQkFBc0IsRUFDdEIsZ0JBQWdCLEVBQ2pCLE1BQU0sb0NBQW9DLENBQUM7QUFFNUM7Ozs7O0dBS0c7QUFDSCxNQUFNLE9BQU8sb0JBQXFCLFNBQVEsY0FBYztJQU10RCxZQUNVLE1BQW9CLEVBQ3BCLGtCQUF1QixFQUFFLGtEQUFrRDtJQUMzRSxjQUE2QixFQUM3QixHQUFXO1FBRW5CLEtBQUssRUFBRSxDQUFDO1FBTEEsV0FBTSxHQUFOLE1BQU0sQ0FBYztRQUNwQix1QkFBa0IsR0FBbEIsa0JBQWtCLENBQUs7UUFDdkIsbUJBQWMsR0FBZCxjQUFjLENBQWU7UUFDN0IsUUFBRyxHQUFILEdBQUcsQ0FBUTtRQVRaLE9BQUUsR0FBWSxNQUFNLENBQUMsQ0FBQyxvRUFBb0U7UUFDMUYsZ0JBQVcsR0FBVyxRQUFRLENBQUM7UUFFaEMsZ0JBQVcsR0FBZ0IsSUFBSSxHQUFHLEVBQUUsQ0FBQyxDQUFDLHlDQUF5QztJQVN2RixDQUFDO0lBRUQ7O09BRUc7SUFDSCxLQUFLLENBQUMsY0FBYztRQUNsQixJQUFJLENBQUM7WUFDSCxNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJ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
|
|
@@ -36,3 +36,31 @@ export declare function isLegacyFilename(fileName: string): boolean;
|
|
|
36
36
|
* Get the suggested new filename for a legacy filename
|
|
37
37
|
*/
|
|
38
38
|
export declare function getLegacyMigrationTarget(fileName: string): string | null;
|
|
39
|
+
/**
|
|
40
|
+
* Docker test file information
|
|
41
|
+
*/
|
|
42
|
+
export interface DockerTestFileInfo {
|
|
43
|
+
baseName: string;
|
|
44
|
+
variant: string;
|
|
45
|
+
isDockerTest: true;
|
|
46
|
+
original: string;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Check if a filename matches the Docker test pattern: *.{variant}.docker.sh
|
|
50
|
+
* Examples: test.latest.docker.sh, test.integration.npmci.docker.sh
|
|
51
|
+
*/
|
|
52
|
+
export declare function isDockerTestFile(fileName: string): boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Parse a Docker test filename to extract variant and base name
|
|
55
|
+
* Pattern: test.{baseName}.{variant}.docker.sh
|
|
56
|
+
* Examples:
|
|
57
|
+
* - test.latest.docker.sh -> { baseName: 'test', variant: 'latest' }
|
|
58
|
+
* - test.integration.npmci.docker.sh -> { baseName: 'test.integration', variant: 'npmci' }
|
|
59
|
+
*/
|
|
60
|
+
export declare function parseDockerTestFilename(filePath: string): DockerTestFileInfo;
|
|
61
|
+
/**
|
|
62
|
+
* Map a Docker variant to its corresponding Dockerfile path
|
|
63
|
+
* "latest" -> "Dockerfile"
|
|
64
|
+
* Other variants -> "Dockerfile_{variant}"
|
|
65
|
+
*/
|
|
66
|
+
export declare function mapVariantToDockerfile(variant: string, baseDir: string): string;
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
const KNOWN_RUNTIMES = new Set(['node', 'chromium', 'deno', 'bun']);
|
|
13
13
|
const KNOWN_MODIFIERS = new Set(['nonci']);
|
|
14
|
-
const VALID_EXTENSIONS = new Set(['ts', 'tsx', 'mts', 'cts']);
|
|
14
|
+
const VALID_EXTENSIONS = new Set(['ts', 'tsx', 'mts', 'cts', 'sh']);
|
|
15
15
|
const ALL_RUNTIMES = ['node', 'chromium', 'deno', 'bun'];
|
|
16
16
|
// Legacy mappings for backwards compatibility
|
|
17
17
|
const LEGACY_RUNTIME_MAP = {
|
|
@@ -174,4 +174,61 @@ export function getLegacyMigrationTarget(fileName) {
|
|
|
174
174
|
parts.push(parsed.extension);
|
|
175
175
|
return parts.join('.');
|
|
176
176
|
}
|
|
177
|
-
|
|
177
|
+
/**
|
|
178
|
+
* Check if a filename matches the Docker test pattern: *.{variant}.docker.sh
|
|
179
|
+
* Examples: test.latest.docker.sh, test.integration.npmci.docker.sh
|
|
180
|
+
*/
|
|
181
|
+
export function isDockerTestFile(fileName) {
|
|
182
|
+
// Must end with .docker.sh
|
|
183
|
+
if (!fileName.endsWith('.docker.sh')) {
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
// Extract filename from path if needed
|
|
187
|
+
const name = fileName.split('/').pop() || fileName;
|
|
188
|
+
// Must have at least 3 parts: [baseName, variant, docker, sh]
|
|
189
|
+
const parts = name.split('.');
|
|
190
|
+
return parts.length >= 4 && parts[parts.length - 2] === 'docker' && parts[parts.length - 1] === 'sh';
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Parse a Docker test filename to extract variant and base name
|
|
194
|
+
* Pattern: test.{baseName}.{variant}.docker.sh
|
|
195
|
+
* Examples:
|
|
196
|
+
* - test.latest.docker.sh -> { baseName: 'test', variant: 'latest' }
|
|
197
|
+
* - test.integration.npmci.docker.sh -> { baseName: 'test.integration', variant: 'npmci' }
|
|
198
|
+
*/
|
|
199
|
+
export function parseDockerTestFilename(filePath) {
|
|
200
|
+
// Extract just the filename from the path
|
|
201
|
+
const fileName = filePath.split('/').pop() || filePath;
|
|
202
|
+
const original = fileName;
|
|
203
|
+
if (!isDockerTestFile(fileName)) {
|
|
204
|
+
throw new Error(`Not a valid Docker test file: "${fileName}". Expected pattern: *.{variant}.docker.sh`);
|
|
205
|
+
}
|
|
206
|
+
// Remove .docker.sh suffix
|
|
207
|
+
const withoutSuffix = fileName.slice(0, -10); // Remove '.docker.sh'
|
|
208
|
+
const tokens = withoutSuffix.split('.');
|
|
209
|
+
if (tokens.length === 0) {
|
|
210
|
+
throw new Error(`Invalid Docker test file: empty basename in "${fileName}"`);
|
|
211
|
+
}
|
|
212
|
+
// Last token before .docker.sh is the variant
|
|
213
|
+
const variant = tokens[tokens.length - 1];
|
|
214
|
+
// Everything else is the base name
|
|
215
|
+
const baseName = tokens.slice(0, -1).join('.');
|
|
216
|
+
return {
|
|
217
|
+
baseName: baseName || 'test',
|
|
218
|
+
variant,
|
|
219
|
+
isDockerTest: true,
|
|
220
|
+
original,
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Map a Docker variant to its corresponding Dockerfile path
|
|
225
|
+
* "latest" -> "Dockerfile"
|
|
226
|
+
* Other variants -> "Dockerfile_{variant}"
|
|
227
|
+
*/
|
|
228
|
+
export function mapVariantToDockerfile(variant, baseDir) {
|
|
229
|
+
if (variant === 'latest') {
|
|
230
|
+
return `${baseDir}/Dockerfile`;
|
|
231
|
+
}
|
|
232
|
+
return `${baseDir}/Dockerfile_${variant}`;
|
|
233
|
+
}
|
|
234
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHN0ZXN0LmNsYXNzZXMucnVudGltZS5wYXJzZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy90c3Rlc3QuY2xhc3Nlcy5ydW50aW1lLnBhcnNlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7OztHQVVHO0FBbUJILE1BQU0sY0FBYyxHQUFnQixJQUFJLEdBQUcsQ0FBQyxDQUFDLE1BQU0sRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7QUFDakYsTUFBTSxlQUFlLEdBQWdCLElBQUksR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztBQUN4RCxNQUFNLGdCQUFnQixHQUFnQixJQUFJLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDO0FBQ2pGLE1BQU0sWUFBWSxHQUFjLENBQUMsTUFBTSxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsS0FBSyxDQUFDLENBQUM7QUFFcEUsOENBQThDO0FBQzlDLE1BQU0sa0JBQWtCLEdBQThCO0lBQ3BELE9BQU8sRUFBRSxDQUFDLFVBQVUsQ0FBQztJQUNyQixJQUFJLEVBQUUsQ0FBQyxNQUFNLEVBQUUsVUFBVSxDQUFDO0NBQzNCLENBQUM7QUFFRjs7O0dBR0c7QUFDSCxNQUFNLFVBQVUsaUJBQWlCLENBQy9CLFFBQWdCLEVBQ2hCLFNBQXVCLEVBQUU7SUFFekIsTUFBTSxvQkFBb0IsR0FBRyxNQUFNLENBQUMsb0JBQW9CLElBQUksSUFBSSxDQUFDO0lBQ2pFLE1BQU0sZUFBZSxHQUFHLE1BQU0sQ0FBQyxlQUFlLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUUzRCwwQ0FBMEM7SUFDMUMsTUFBTSxRQUFRLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsSUFBSSxRQUFRLENBQUM7SUFDdkQsTUFBTSxR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
|
|
@@ -50,9 +50,15 @@ export class TestDirectory {
|
|
|
50
50
|
case TestExecutionMode.DIRECTORY:
|
|
51
51
|
// Directory mode - now recursive with ** pattern
|
|
52
52
|
const dirPath = plugins.path.join(this.cwd, this.testPath);
|
|
53
|
-
|
|
54
|
-
const
|
|
55
|
-
|
|
53
|
+
// Search for both TypeScript test files and Docker shell test files
|
|
54
|
+
const tsPattern = '**/test*.ts';
|
|
55
|
+
const dockerPattern = '**/*.docker.sh';
|
|
56
|
+
const [tsFiles, dockerFiles] = await Promise.all([
|
|
57
|
+
plugins.smartfile.fs.listFileTree(dirPath, tsPattern),
|
|
58
|
+
plugins.smartfile.fs.listFileTree(dirPath, dockerPattern),
|
|
59
|
+
]);
|
|
60
|
+
const allTestFiles = [...tsFiles, ...dockerFiles];
|
|
61
|
+
this.testfileArray = await Promise.all(allTestFiles.map(async (filePath) => {
|
|
56
62
|
const absolutePath = plugins.path.isAbsolute(filePath)
|
|
57
63
|
? filePath
|
|
58
64
|
: plugins.path.join(dirPath, filePath);
|
|
@@ -101,4 +107,4 @@ export class TestDirectory {
|
|
|
101
107
|
return result;
|
|
102
108
|
}
|
|
103
109
|
}
|
|
104
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
110
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHN0ZXN0LmNsYXNzZXMudGVzdGRpcmVjdG9yeS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3RzdGVzdC5jbGFzc2VzLnRlc3RkaXJlY3RvcnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxxQkFBcUIsQ0FBQztBQUMvQyxPQUFPLEtBQUssS0FBSyxNQUFNLG1CQUFtQixDQUFDO0FBQzNDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNsRCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFFL0Msb0JBQW9CO0FBQ3BCLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQztBQUNuRSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDM0QsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBRW5FLE1BQU0sT0FBTyxhQUFhO0lBcUJ4Qjs7Ozs7T0FLRztJQUNILFlBQVksTUFBYyxFQUFFLFdBQW1CLEVBQUUsZ0JBQW1DO1FBWHBGOztXQUVHO1FBQ0gsa0JBQWEsR0FBZ0IsRUFBRSxDQUFDO1FBUzlCLElBQUksQ0FBQyxHQUFHLEdBQUcsTUFBTSxDQUFDO1FBQ2xCLElBQUksQ0FBQyxRQUFRLEdBQUcsV0FBVyxDQUFDO1FBQzVCLElBQUksQ0FBQyxhQUFhLEdBQUcsZ0JBQWdCLENBQUM7SUFDeEMsQ0FBQztJQUVPLEtBQUssQ0FBQyxLQUFLO1FBQ2pCLFFBQVEsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQzNCLEtBQUssaUJBQWlCLENBQUMsSUFBSTtnQkFDekIsbUJBQW1CO2dCQUNuQixNQUFNLFFBQVEsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDO29CQUNyRCxDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVE7b0JBQ2YsQ0FBQyxDQUFD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
|
|
@@ -5,6 +5,7 @@ import { TestExecutionMode } from './index.js';
|
|
|
5
5
|
import { TsTestLogger } from './tstest.logging.js';
|
|
6
6
|
import type { LogOptions } from './tstest.logging.js';
|
|
7
7
|
import { RuntimeAdapterRegistry } from './tstest.classes.runtime.adapter.js';
|
|
8
|
+
import { DockerRuntimeAdapter } from './tstest.classes.runtime.docker.js';
|
|
8
9
|
export declare class TsTest {
|
|
9
10
|
testDir: TestDirectory;
|
|
10
11
|
executionMode: TestExecutionMode;
|
|
@@ -17,6 +18,7 @@ export declare class TsTest {
|
|
|
17
18
|
smartbrowserInstance: plugins.smartbrowser.SmartBrowser;
|
|
18
19
|
tsbundleInstance: plugins.tsbundle.TsBundle;
|
|
19
20
|
runtimeRegistry: RuntimeAdapterRegistry;
|
|
21
|
+
dockerAdapter: DockerRuntimeAdapter | null;
|
|
20
22
|
constructor(cwdArg: string, testPathArg: string, executionModeArg: TestExecutionMode, logOptions?: LogOptions, tags?: string[], startFromFile?: number | null, stopAtFile?: number | null, timeoutSeconds?: number | null);
|
|
21
23
|
/**
|
|
22
24
|
* Check and display available runtimes
|
|
@@ -26,6 +28,10 @@ export declare class TsTest {
|
|
|
26
28
|
runWatch(ignorePatterns?: string[]): Promise<void>;
|
|
27
29
|
private runSingleTestOrSkip;
|
|
28
30
|
private runSingleTest;
|
|
31
|
+
/**
|
|
32
|
+
* Execute a Docker test file
|
|
33
|
+
*/
|
|
34
|
+
private runDockerTest;
|
|
29
35
|
runInNode(fileNameArg: string, index: number, total: number): Promise<TapParser>;
|
|
30
36
|
private findFreePorts;
|
|
31
37
|
runInChrome(fileNameArg: string, index: number, total: number): Promise<TapParser>;
|
|
@@ -7,12 +7,13 @@ import { TapParser } from './tstest.classes.tap.parser.js';
|
|
|
7
7
|
import { TestExecutionMode } from './index.js';
|
|
8
8
|
import { TsTestLogger } from './tstest.logging.js';
|
|
9
9
|
// Runtime adapters
|
|
10
|
-
import { parseTestFilename } from './tstest.classes.runtime.parser.js';
|
|
10
|
+
import { parseTestFilename, isDockerTestFile, parseDockerTestFilename } from './tstest.classes.runtime.parser.js';
|
|
11
11
|
import { RuntimeAdapterRegistry } from './tstest.classes.runtime.adapter.js';
|
|
12
12
|
import { NodeRuntimeAdapter } from './tstest.classes.runtime.node.js';
|
|
13
13
|
import { ChromiumRuntimeAdapter } from './tstest.classes.runtime.chromium.js';
|
|
14
14
|
import { DenoRuntimeAdapter } from './tstest.classes.runtime.deno.js';
|
|
15
15
|
import { BunRuntimeAdapter } from './tstest.classes.runtime.bun.js';
|
|
16
|
+
import { DockerRuntimeAdapter } from './tstest.classes.runtime.docker.js';
|
|
16
17
|
export class TsTest {
|
|
17
18
|
constructor(cwdArg, testPathArg, executionModeArg, logOptions = {}, tags = [], startFromFile = null, stopAtFile = null, timeoutSeconds = null) {
|
|
18
19
|
this.smartshellInstance = new plugins.smartshell.Smartshell({
|
|
@@ -23,6 +24,7 @@ export class TsTest {
|
|
|
23
24
|
this.smartbrowserInstance = new plugins.smartbrowser.SmartBrowser();
|
|
24
25
|
this.tsbundleInstance = new plugins.tsbundle.TsBundle();
|
|
25
26
|
this.runtimeRegistry = new RuntimeAdapterRegistry();
|
|
27
|
+
this.dockerAdapter = null;
|
|
26
28
|
this.executionMode = executionModeArg;
|
|
27
29
|
this.testDir = new TestDirectory(cwdArg, testPathArg, executionModeArg);
|
|
28
30
|
this.logger = new TsTestLogger(logOptions);
|
|
@@ -35,6 +37,8 @@ export class TsTest {
|
|
|
35
37
|
this.runtimeRegistry.register(new ChromiumRuntimeAdapter(this.logger, this.tsbundleInstance, this.smartbrowserInstance, this.timeoutSeconds));
|
|
36
38
|
this.runtimeRegistry.register(new DenoRuntimeAdapter(this.logger, this.smartshellInstance, this.timeoutSeconds, this.filterTags));
|
|
37
39
|
this.runtimeRegistry.register(new BunRuntimeAdapter(this.logger, this.smartshellInstance, this.timeoutSeconds, this.filterTags));
|
|
40
|
+
// Initialize Docker adapter
|
|
41
|
+
this.dockerAdapter = new DockerRuntimeAdapter(this.logger, this.smartshellInstance, this.timeoutSeconds, cwdArg);
|
|
38
42
|
}
|
|
39
43
|
/**
|
|
40
44
|
* Check and display available runtimes
|
|
@@ -150,8 +154,12 @@ export class TsTest {
|
|
|
150
154
|
await this.runSingleTest(fileNameArg, fileIndex, totalFiles, tapCombinator);
|
|
151
155
|
}
|
|
152
156
|
async runSingleTest(fileNameArg, fileIndex, totalFiles, tapCombinator) {
|
|
153
|
-
// Parse the filename to determine runtimes and modifiers
|
|
154
157
|
const fileName = plugins.path.basename(fileNameArg);
|
|
158
|
+
// Check if this is a Docker test file
|
|
159
|
+
if (isDockerTestFile(fileName)) {
|
|
160
|
+
return await this.runDockerTest(fileNameArg, fileIndex, totalFiles, tapCombinator);
|
|
161
|
+
}
|
|
162
|
+
// Parse the filename to determine runtimes and modifiers (for TypeScript tests)
|
|
155
163
|
const parsed = parseTestFilename(fileName, { strictUnknownRuntime: false });
|
|
156
164
|
// Check for nonci modifier in CI environment
|
|
157
165
|
if (process.env.CI && parsed.modifiers.includes('nonci')) {
|
|
@@ -192,6 +200,22 @@ export class TsTest {
|
|
|
192
200
|
}
|
|
193
201
|
}
|
|
194
202
|
}
|
|
203
|
+
/**
|
|
204
|
+
* Execute a Docker test file
|
|
205
|
+
*/
|
|
206
|
+
async runDockerTest(fileNameArg, fileIndex, totalFiles, tapCombinator) {
|
|
207
|
+
if (!this.dockerAdapter) {
|
|
208
|
+
this.logger.tapOutput(cs('❌ Docker adapter not initialized', 'red'));
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
try {
|
|
212
|
+
const tapParser = await this.dockerAdapter.run(fileNameArg, fileIndex, totalFiles);
|
|
213
|
+
tapCombinator.addTapParser(tapParser);
|
|
214
|
+
}
|
|
215
|
+
catch (error) {
|
|
216
|
+
this.logger.tapOutput(cs(`❌ Docker test failed: ${error.message}`, 'red'));
|
|
217
|
+
}
|
|
218
|
+
}
|
|
195
219
|
async runInNode(fileNameArg, index, total) {
|
|
196
220
|
this.logger.testFileStart(fileNameArg, 'node.js', index, total);
|
|
197
221
|
const tapParser = new TapParser(fileNameArg + ':node', this.logger);
|
|
@@ -533,4 +557,4 @@ import '${absoluteTestFile.replace(/\\/g, '/')}';
|
|
|
533
557
|
}
|
|
534
558
|
}
|
|
535
559
|
}
|
|
536
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHN0ZXN0LmNsYXNzZXMudHN0ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvdHN0ZXN0LmNsYXNzZXMudHN0ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0scUJBQXFCLENBQUM7QUFDL0MsT0FBTyxLQUFLLEtBQUssTUFBTSxtQkFBbUIsQ0FBQztBQUUzQyxPQUFPLEVBQUUsYUFBYSxJQUFJLEVBQUUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBRS9ELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQztBQUNsRSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sb0NBQW9DLENBQUM7QUFDbkUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQzNELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUMvQyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFHbkQsbUJBQW1CO0FBQ25CLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBQ3ZFLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLHFDQUFxQyxDQUFDO0FBQzdFLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBQ3RFLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLHNDQUFzQyxDQUFDO0FBQzlFLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBQ3RFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBRXBFLE1BQU0sT0FBTyxNQUFNO0lBb0JqQixZQUFZLE1BQWMsRUFBRSxXQUFtQixFQUFFLGdCQUFtQyxFQUFFLGFBQXlCLEVBQUUsRUFBRSxPQUFpQixFQUFFLEVBQUUsZ0JBQStCLElBQUksRUFBRSxhQUE0QixJQUFJLEVBQUUsaUJBQWdDLElBQUk7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
|
|
560
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHN0ZXN0LmNsYXNzZXMudHN0ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvdHN0ZXN0LmNsYXNzZXMudHN0ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0scUJBQXFCLENBQUM7QUFDL0MsT0FBTyxLQUFLLEtBQUssTUFBTSxtQkFBbUIsQ0FBQztBQUUzQyxPQUFPLEVBQUUsYUFBYSxJQUFJLEVBQUUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBRS9ELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQztBQUNsRSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sb0NBQW9DLENBQUM7QUFDbkUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQzNELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUMvQyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFHbkQsbUJBQW1CO0FBQ25CLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxnQkFBZ0IsRUFBRSx1QkFBdUIsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBQ2xILE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLHFDQUFxQyxDQUFDO0FBQzdFLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBQ3RFLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLHNDQUFzQyxDQUFDO0FBQzlFLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBQ3RFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ3BFLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBRTFFLE1BQU0sT0FBTyxNQUFNO0lBcUJqQixZQUFZLE1BQWMsRUFBRSxXQUFtQixFQUFFLGdCQUFtQyxFQUFFLGFBQXlCLEVB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
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@git.zone/tstest",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.7.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "a test utility to run tests that match test/**/*.ts",
|
|
6
6
|
"exports": {
|
|
7
7
|
".": "./dist_ts/index.js",
|
|
8
8
|
"./tapbundle": "./dist_ts_tapbundle/index.js",
|
|
9
|
-
"./tapbundle_node": "./dist_ts_tapbundle_node/index.js"
|
|
9
|
+
"./tapbundle_node": "./dist_ts_tapbundle_node/index.js",
|
|
10
|
+
"./tapbundle_protocol": "./dist_ts_tapbundle_protocol/index.js"
|
|
10
11
|
},
|
|
11
12
|
"type": "module",
|
|
12
13
|
"author": "Lossless GmbH",
|
|
@@ -37,7 +38,7 @@
|
|
|
37
38
|
"@push.rocks/smartnetwork": "^4.4.0",
|
|
38
39
|
"@push.rocks/smartpath": "^6.0.0",
|
|
39
40
|
"@push.rocks/smartpromise": "^4.2.3",
|
|
40
|
-
"@push.rocks/smartrequest": "^4.3.
|
|
41
|
+
"@push.rocks/smartrequest": "^4.3.2",
|
|
41
42
|
"@push.rocks/smarts3": "^2.2.6",
|
|
42
43
|
"@push.rocks/smartshell": "^3.3.0",
|
|
43
44
|
"@push.rocks/smarttime": "^4.1.1",
|
package/readme.md
CHANGED
|
@@ -319,6 +319,129 @@ tstest provides multiple exports for different use cases:
|
|
|
319
319
|
- `@git.zone/tstest` - Main CLI and test runner functionality
|
|
320
320
|
- `@git.zone/tstest/tapbundle` - Browser-compatible test framework
|
|
321
321
|
- `@git.zone/tstest/tapbundle_node` - Node.js-specific test utilities
|
|
322
|
+
- `@git.zone/tstest/tapbundle_protocol` - Protocol V2 emitter and parser for TAP extensions
|
|
323
|
+
|
|
324
|
+
## tapbundle Protocol V2
|
|
325
|
+
|
|
326
|
+
tstest includes an enhanced TAP protocol (Protocol V2) that extends standard TAP 13 with additional metadata while maintaining backwards compatibility.
|
|
327
|
+
|
|
328
|
+
### Overview
|
|
329
|
+
|
|
330
|
+
Protocol V2 adds structured metadata to TAP output using Unicode markers (`⟦TSTEST:...⟧`) that standard TAP parsers safely ignore. This allows for:
|
|
331
|
+
|
|
332
|
+
- **Timing information** - Test execution duration in milliseconds
|
|
333
|
+
- **Structured errors** - Stack traces, diffs, and detailed error data
|
|
334
|
+
- **Test events** - Real-time progress and lifecycle events
|
|
335
|
+
- **Snapshots** - Snapshot testing data exchange
|
|
336
|
+
- **Custom metadata** - Tags, retry counts, file locations
|
|
337
|
+
|
|
338
|
+
### Using the Protocol
|
|
339
|
+
|
|
340
|
+
```typescript
|
|
341
|
+
import {
|
|
342
|
+
ProtocolEmitter,
|
|
343
|
+
ProtocolParser,
|
|
344
|
+
PROTOCOL_MARKERS,
|
|
345
|
+
PROTOCOL_VERSION
|
|
346
|
+
} from '@git.zone/tstest/tapbundle_protocol';
|
|
347
|
+
|
|
348
|
+
// Create an emitter
|
|
349
|
+
const emitter = new ProtocolEmitter();
|
|
350
|
+
|
|
351
|
+
// Emit protocol header
|
|
352
|
+
console.log(emitter.emitProtocolHeader());
|
|
353
|
+
// Output: ⟦TSTEST:PROTOCOL:2.0.0⟧
|
|
354
|
+
|
|
355
|
+
// Emit TAP version
|
|
356
|
+
console.log(emitter.emitTapVersion(13));
|
|
357
|
+
// Output: TAP version 13
|
|
358
|
+
|
|
359
|
+
// Emit a test result with metadata
|
|
360
|
+
const testResult = {
|
|
361
|
+
ok: true,
|
|
362
|
+
testNumber: 1,
|
|
363
|
+
description: 'user authentication works',
|
|
364
|
+
metadata: {
|
|
365
|
+
time: 123,
|
|
366
|
+
tags: ['auth', 'unit']
|
|
367
|
+
}
|
|
368
|
+
};
|
|
369
|
+
console.log(emitter.emitTest(testResult).join('\n'));
|
|
370
|
+
// Output: ok 1 - user authentication works ⟦TSTEST:time:123⟧
|
|
371
|
+
// ⟦TSTEST:META:{"tags":["auth","unit"]}⟧
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
### Protocol Markers
|
|
375
|
+
|
|
376
|
+
```typescript
|
|
377
|
+
PROTOCOL_MARKERS = {
|
|
378
|
+
START: '⟦TSTEST:',
|
|
379
|
+
END: '⟧',
|
|
380
|
+
META_PREFIX: 'META:',
|
|
381
|
+
ERROR_PREFIX: 'ERROR',
|
|
382
|
+
SNAPSHOT_PREFIX: 'SNAPSHOT:',
|
|
383
|
+
SKIP_PREFIX: 'SKIP:',
|
|
384
|
+
TODO_PREFIX: 'TODO:',
|
|
385
|
+
EVENT_PREFIX: 'EVENT:'
|
|
386
|
+
}
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
### Use Cases
|
|
390
|
+
|
|
391
|
+
#### Creating Custom Test Runners
|
|
392
|
+
|
|
393
|
+
```typescript
|
|
394
|
+
import { ProtocolEmitter } from '@git.zone/tstest/tapbundle_protocol';
|
|
395
|
+
|
|
396
|
+
const emitter = new ProtocolEmitter();
|
|
397
|
+
|
|
398
|
+
// Emit header and version
|
|
399
|
+
console.log(emitter.emitProtocolHeader());
|
|
400
|
+
console.log(emitter.emitTapVersion(13));
|
|
401
|
+
console.log(emitter.emitPlan({ start: 1, end: 2 }));
|
|
402
|
+
|
|
403
|
+
// Run your tests and emit results
|
|
404
|
+
const startTime = Date.now();
|
|
405
|
+
// ... run test ...
|
|
406
|
+
const duration = Date.now() - startTime;
|
|
407
|
+
|
|
408
|
+
console.log(emitter.emitTest({
|
|
409
|
+
ok: true,
|
|
410
|
+
testNumber: 1,
|
|
411
|
+
description: 'my custom test',
|
|
412
|
+
metadata: { time: duration }
|
|
413
|
+
}).join('\n'));
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
#### Parsing tapbundle Output
|
|
417
|
+
|
|
418
|
+
```typescript
|
|
419
|
+
import { ProtocolParser } from '@git.zone/tstest/tapbundle_protocol';
|
|
420
|
+
|
|
421
|
+
const parser = new ProtocolParser();
|
|
422
|
+
|
|
423
|
+
// Parse TAP output line by line
|
|
424
|
+
parser.parseLine('⟦TSTEST:PROTOCOL:2.0.0⟧');
|
|
425
|
+
parser.parseLine('TAP version 13');
|
|
426
|
+
parser.parseLine('1..1');
|
|
427
|
+
parser.parseLine('ok 1 - test name ⟦TSTEST:time:123⟧');
|
|
428
|
+
|
|
429
|
+
// Get parsed results
|
|
430
|
+
const results = parser.getResults();
|
|
431
|
+
console.log(results);
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
### Backwards Compatibility
|
|
435
|
+
|
|
436
|
+
Protocol V2 is fully backwards compatible with standard TAP 13. The Unicode markers are treated as comments by standard TAP parsers, so Protocol V2 output can be consumed by any TAP-compliant tool:
|
|
437
|
+
|
|
438
|
+
```
|
|
439
|
+
⟦TSTEST:PROTOCOL:2.0.0⟧ ← Ignored by standard TAP parsers
|
|
440
|
+
TAP version 13 ← Standard TAP
|
|
441
|
+
1..2 ← Standard TAP
|
|
442
|
+
ok 1 - test ⟦TSTEST:time:45⟧ ← TAP parsers see: "ok 1 - test"
|
|
443
|
+
ok 2 - another test ← Standard TAP
|
|
444
|
+
```
|
|
322
445
|
|
|
323
446
|
## tapbundle Test Framework
|
|
324
447
|
|
package/ts/00_commitinfo_data.ts
CHANGED
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
import * as plugins from './tstest.plugins.js';
|
|
2
|
+
import { coloredString as cs } from '@push.rocks/consolecolor';
|
|
3
|
+
import {
|
|
4
|
+
RuntimeAdapter,
|
|
5
|
+
type RuntimeOptions,
|
|
6
|
+
type RuntimeCommand,
|
|
7
|
+
type RuntimeAvailability,
|
|
8
|
+
} from './tstest.classes.runtime.adapter.js';
|
|
9
|
+
import { TapParser } from './tstest.classes.tap.parser.js';
|
|
10
|
+
import { TsTestLogger } from './tstest.logging.js';
|
|
11
|
+
import type { Runtime } from './tstest.classes.runtime.parser.js';
|
|
12
|
+
import {
|
|
13
|
+
parseDockerTestFilename,
|
|
14
|
+
mapVariantToDockerfile,
|
|
15
|
+
isDockerTestFile
|
|
16
|
+
} from './tstest.classes.runtime.parser.js';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Docker runtime adapter
|
|
20
|
+
* Executes shell test files inside Docker containers
|
|
21
|
+
* Pattern: test.{variant}.docker.sh
|
|
22
|
+
* Variants map to Dockerfiles: latest -> Dockerfile, others -> Dockerfile_{variant}
|
|
23
|
+
*/
|
|
24
|
+
export class DockerRuntimeAdapter extends RuntimeAdapter {
|
|
25
|
+
readonly id: Runtime = 'node'; // Using 'node' temporarily as Runtime type doesn't include 'docker'
|
|
26
|
+
readonly displayName: string = 'Docker';
|
|
27
|
+
|
|
28
|
+
private builtImages: Set<string> = new Set(); // Track built images to avoid rebuilding
|
|
29
|
+
|
|
30
|
+
constructor(
|
|
31
|
+
private logger: TsTestLogger,
|
|
32
|
+
private smartshellInstance: any, // SmartShell instance from @push.rocks/smartshell
|
|
33
|
+
private timeoutSeconds: number | null,
|
|
34
|
+
private cwd: string
|
|
35
|
+
) {
|
|
36
|
+
super();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Check if Docker CLI is available
|
|
41
|
+
*/
|
|
42
|
+
async checkAvailable(): Promise<RuntimeAvailability> {
|
|
43
|
+
try {
|
|
44
|
+
const result = await this.smartshellInstance.exec('docker --version');
|
|
45
|
+
|
|
46
|
+
if (result.exitCode !== 0) {
|
|
47
|
+
return {
|
|
48
|
+
available: false,
|
|
49
|
+
error: 'Docker command failed',
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Extract version from output like "Docker version 24.0.5, build ced0996"
|
|
54
|
+
const versionMatch = result.stdout.match(/Docker version ([^,]+)/);
|
|
55
|
+
const version = versionMatch ? versionMatch[1] : 'unknown';
|
|
56
|
+
|
|
57
|
+
return {
|
|
58
|
+
available: true,
|
|
59
|
+
version,
|
|
60
|
+
};
|
|
61
|
+
} catch (error) {
|
|
62
|
+
return {
|
|
63
|
+
available: false,
|
|
64
|
+
error: `Docker not found: ${error.message}`,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Create command configuration for Docker test execution
|
|
71
|
+
* This is used for informational purposes
|
|
72
|
+
*/
|
|
73
|
+
createCommand(testFile: string, options?: RuntimeOptions): RuntimeCommand {
|
|
74
|
+
const parsed = parseDockerTestFilename(testFile);
|
|
75
|
+
const dockerfilePath = mapVariantToDockerfile(parsed.variant, this.cwd);
|
|
76
|
+
const imageName = `tstest-${parsed.variant}`;
|
|
77
|
+
|
|
78
|
+
return {
|
|
79
|
+
command: 'docker',
|
|
80
|
+
args: [
|
|
81
|
+
'run',
|
|
82
|
+
'--rm',
|
|
83
|
+
'-v',
|
|
84
|
+
`${this.cwd}/test:/test`,
|
|
85
|
+
imageName,
|
|
86
|
+
'taprun',
|
|
87
|
+
`/test/${plugins.path.basename(testFile)}`
|
|
88
|
+
],
|
|
89
|
+
env: {},
|
|
90
|
+
cwd: this.cwd,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Build a Docker image from the specified Dockerfile
|
|
96
|
+
*/
|
|
97
|
+
private async buildDockerImage(dockerfilePath: string, imageName: string): Promise<void> {
|
|
98
|
+
// Check if image is already built
|
|
99
|
+
if (this.builtImages.has(imageName)) {
|
|
100
|
+
this.logger.tapOutput(`Using cached Docker image: ${imageName}`);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Check if Dockerfile exists
|
|
105
|
+
if (!await plugins.smartfile.fs.fileExists(dockerfilePath)) {
|
|
106
|
+
throw new Error(
|
|
107
|
+
`Dockerfile not found: ${dockerfilePath}\n` +
|
|
108
|
+
`Expected Dockerfile for Docker test variant.`
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
this.logger.tapOutput(`Building Docker image: ${imageName} from ${dockerfilePath}`);
|
|
113
|
+
|
|
114
|
+
try {
|
|
115
|
+
const buildResult = await this.smartshellInstance.exec(
|
|
116
|
+
`docker build -f ${dockerfilePath} -t ${imageName} ${this.cwd}`,
|
|
117
|
+
{
|
|
118
|
+
cwd: this.cwd,
|
|
119
|
+
}
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
if (buildResult.exitCode !== 0) {
|
|
123
|
+
throw new Error(`Docker build failed:\n${buildResult.stderr}`);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
this.builtImages.add(imageName);
|
|
127
|
+
this.logger.tapOutput(`✅ Docker image built successfully: ${imageName}`);
|
|
128
|
+
} catch (error) {
|
|
129
|
+
throw new Error(`Failed to build Docker image: ${error.message}`);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Execute a Docker test file
|
|
135
|
+
*/
|
|
136
|
+
async run(
|
|
137
|
+
testFile: string,
|
|
138
|
+
index: number,
|
|
139
|
+
total: number,
|
|
140
|
+
options?: RuntimeOptions
|
|
141
|
+
): Promise<TapParser> {
|
|
142
|
+
this.logger.testFileStart(testFile, this.displayName, index, total);
|
|
143
|
+
|
|
144
|
+
// Parse the Docker test filename
|
|
145
|
+
const parsed = parseDockerTestFilename(testFile);
|
|
146
|
+
const dockerfilePath = mapVariantToDockerfile(parsed.variant, this.cwd);
|
|
147
|
+
const imageName = `tstest-${parsed.variant}`;
|
|
148
|
+
|
|
149
|
+
// Build the Docker image
|
|
150
|
+
await this.buildDockerImage(dockerfilePath, imageName);
|
|
151
|
+
|
|
152
|
+
// Prepare the test file path relative to the mounted directory
|
|
153
|
+
// We need to get the path relative to cwd
|
|
154
|
+
const absoluteTestPath = plugins.path.isAbsolute(testFile)
|
|
155
|
+
? testFile
|
|
156
|
+
: plugins.path.join(this.cwd, testFile);
|
|
157
|
+
|
|
158
|
+
const relativeTestPath = plugins.path.relative(this.cwd, absoluteTestPath);
|
|
159
|
+
|
|
160
|
+
// Create TAP parser
|
|
161
|
+
const tapParser = new TapParser(testFile + ':docker', this.logger);
|
|
162
|
+
|
|
163
|
+
try {
|
|
164
|
+
// Build docker run command
|
|
165
|
+
const dockerArgs = [
|
|
166
|
+
'run',
|
|
167
|
+
'--rm',
|
|
168
|
+
'-v',
|
|
169
|
+
`${this.cwd}/test:/test`,
|
|
170
|
+
imageName,
|
|
171
|
+
'taprun',
|
|
172
|
+
`/test/${plugins.path.basename(testFile)}`
|
|
173
|
+
];
|
|
174
|
+
|
|
175
|
+
this.logger.tapOutput(`Executing: docker ${dockerArgs.join(' ')}`);
|
|
176
|
+
|
|
177
|
+
// Execute the Docker container
|
|
178
|
+
const execPromise = this.smartshellInstance.execStreaming(
|
|
179
|
+
`docker ${dockerArgs.join(' ')}`,
|
|
180
|
+
{
|
|
181
|
+
cwd: this.cwd,
|
|
182
|
+
}
|
|
183
|
+
);
|
|
184
|
+
|
|
185
|
+
// Set up timeout if configured
|
|
186
|
+
let timeoutHandle: NodeJS.Timeout | null = null;
|
|
187
|
+
if (this.timeoutSeconds) {
|
|
188
|
+
timeoutHandle = setTimeout(() => {
|
|
189
|
+
this.logger.tapOutput(`⏱️ Test timeout (${this.timeoutSeconds}s) - killing container`);
|
|
190
|
+
// Try to kill any running containers with this image
|
|
191
|
+
this.smartshellInstance.exec(`docker ps -q --filter ancestor=${imageName} | xargs -r docker kill`);
|
|
192
|
+
}, this.timeoutSeconds * 1000);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Stream output to TAP parser line by line
|
|
196
|
+
execPromise.childProcess.stdout.on('data', (data: Buffer) => {
|
|
197
|
+
const output = data.toString();
|
|
198
|
+
const lines = output.split('\n');
|
|
199
|
+
for (const line of lines) {
|
|
200
|
+
if (line.trim()) {
|
|
201
|
+
tapParser.handleTapLog(line);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
execPromise.childProcess.stderr.on('data', (data: Buffer) => {
|
|
207
|
+
const output = data.toString();
|
|
208
|
+
this.logger.tapOutput(cs(`[stderr] ${output}`, 'orange'));
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
// Wait for completion
|
|
212
|
+
const result = await execPromise;
|
|
213
|
+
|
|
214
|
+
// Clear timeout
|
|
215
|
+
if (timeoutHandle) {
|
|
216
|
+
clearTimeout(timeoutHandle);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
if (result.exitCode !== 0) {
|
|
220
|
+
this.logger.tapOutput(cs(`❌ Docker test failed with exit code ${result.exitCode}`, 'red'));
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Evaluate final result
|
|
224
|
+
await tapParser.evaluateFinalResult();
|
|
225
|
+
|
|
226
|
+
} catch (error) {
|
|
227
|
+
this.logger.tapOutput(cs(`❌ Error running Docker test: ${error.message}`, 'red'));
|
|
228
|
+
// Add a failing test result to the parser
|
|
229
|
+
tapParser.handleTapLog('not ok 1 - Docker test execution failed');
|
|
230
|
+
await tapParser.evaluateFinalResult();
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
return tapParser;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Clean up built Docker images (optional, can be called at end of test suite)
|
|
238
|
+
*/
|
|
239
|
+
async cleanup(): Promise<void> {
|
|
240
|
+
for (const imageName of this.builtImages) {
|
|
241
|
+
try {
|
|
242
|
+
this.logger.tapOutput(`Removing Docker image: ${imageName}`);
|
|
243
|
+
await this.smartshellInstance.exec(`docker rmi ${imageName}`);
|
|
244
|
+
} catch (error) {
|
|
245
|
+
// Ignore cleanup errors
|
|
246
|
+
this.logger.tapOutput(cs(`Warning: Failed to remove image ${imageName}: ${error.message}`, 'orange'));
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
this.builtImages.clear();
|
|
250
|
+
}
|
|
251
|
+
}
|
|
@@ -29,7 +29,7 @@ export interface ParserConfig {
|
|
|
29
29
|
|
|
30
30
|
const KNOWN_RUNTIMES: Set<string> = new Set(['node', 'chromium', 'deno', 'bun']);
|
|
31
31
|
const KNOWN_MODIFIERS: Set<string> = new Set(['nonci']);
|
|
32
|
-
const VALID_EXTENSIONS: Set<string> = new Set(['ts', 'tsx', 'mts', 'cts']);
|
|
32
|
+
const VALID_EXTENSIONS: Set<string> = new Set(['ts', 'tsx', 'mts', 'cts', 'sh']);
|
|
33
33
|
const ALL_RUNTIMES: Runtime[] = ['node', 'chromium', 'deno', 'bun'];
|
|
34
34
|
|
|
35
35
|
// Legacy mappings for backwards compatibility
|
|
@@ -228,3 +228,81 @@ export function getLegacyMigrationTarget(fileName: string): string | null {
|
|
|
228
228
|
|
|
229
229
|
return parts.join('.');
|
|
230
230
|
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Docker test file information
|
|
234
|
+
*/
|
|
235
|
+
export interface DockerTestFileInfo {
|
|
236
|
+
baseName: string;
|
|
237
|
+
variant: string;
|
|
238
|
+
isDockerTest: true;
|
|
239
|
+
original: string;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Check if a filename matches the Docker test pattern: *.{variant}.docker.sh
|
|
244
|
+
* Examples: test.latest.docker.sh, test.integration.npmci.docker.sh
|
|
245
|
+
*/
|
|
246
|
+
export function isDockerTestFile(fileName: string): boolean {
|
|
247
|
+
// Must end with .docker.sh
|
|
248
|
+
if (!fileName.endsWith('.docker.sh')) {
|
|
249
|
+
return false;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// Extract filename from path if needed
|
|
253
|
+
const name = fileName.split('/').pop() || fileName;
|
|
254
|
+
|
|
255
|
+
// Must have at least 3 parts: [baseName, variant, docker, sh]
|
|
256
|
+
const parts = name.split('.');
|
|
257
|
+
return parts.length >= 4 && parts[parts.length - 2] === 'docker' && parts[parts.length - 1] === 'sh';
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Parse a Docker test filename to extract variant and base name
|
|
262
|
+
* Pattern: test.{baseName}.{variant}.docker.sh
|
|
263
|
+
* Examples:
|
|
264
|
+
* - test.latest.docker.sh -> { baseName: 'test', variant: 'latest' }
|
|
265
|
+
* - test.integration.npmci.docker.sh -> { baseName: 'test.integration', variant: 'npmci' }
|
|
266
|
+
*/
|
|
267
|
+
export function parseDockerTestFilename(filePath: string): DockerTestFileInfo {
|
|
268
|
+
// Extract just the filename from the path
|
|
269
|
+
const fileName = filePath.split('/').pop() || filePath;
|
|
270
|
+
const original = fileName;
|
|
271
|
+
|
|
272
|
+
if (!isDockerTestFile(fileName)) {
|
|
273
|
+
throw new Error(`Not a valid Docker test file: "${fileName}". Expected pattern: *.{variant}.docker.sh`);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// Remove .docker.sh suffix
|
|
277
|
+
const withoutSuffix = fileName.slice(0, -10); // Remove '.docker.sh'
|
|
278
|
+
const tokens = withoutSuffix.split('.');
|
|
279
|
+
|
|
280
|
+
if (tokens.length === 0) {
|
|
281
|
+
throw new Error(`Invalid Docker test file: empty basename in "${fileName}"`);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// Last token before .docker.sh is the variant
|
|
285
|
+
const variant = tokens[tokens.length - 1];
|
|
286
|
+
|
|
287
|
+
// Everything else is the base name
|
|
288
|
+
const baseName = tokens.slice(0, -1).join('.');
|
|
289
|
+
|
|
290
|
+
return {
|
|
291
|
+
baseName: baseName || 'test',
|
|
292
|
+
variant,
|
|
293
|
+
isDockerTest: true,
|
|
294
|
+
original,
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Map a Docker variant to its corresponding Dockerfile path
|
|
300
|
+
* "latest" -> "Dockerfile"
|
|
301
|
+
* Other variants -> "Dockerfile_{variant}"
|
|
302
|
+
*/
|
|
303
|
+
export function mapVariantToDockerfile(variant: string, baseDir: string): string {
|
|
304
|
+
if (variant === 'latest') {
|
|
305
|
+
return `${baseDir}/Dockerfile`;
|
|
306
|
+
}
|
|
307
|
+
return `${baseDir}/Dockerfile_${variant}`;
|
|
308
|
+
}
|
|
@@ -74,12 +74,20 @@ export class TestDirectory {
|
|
|
74
74
|
case TestExecutionMode.DIRECTORY:
|
|
75
75
|
// Directory mode - now recursive with ** pattern
|
|
76
76
|
const dirPath = plugins.path.join(this.cwd, this.testPath);
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
const
|
|
80
|
-
|
|
77
|
+
|
|
78
|
+
// Search for both TypeScript test files and Docker shell test files
|
|
79
|
+
const tsPattern = '**/test*.ts';
|
|
80
|
+
const dockerPattern = '**/*.docker.sh';
|
|
81
|
+
|
|
82
|
+
const [tsFiles, dockerFiles] = await Promise.all([
|
|
83
|
+
plugins.smartfile.fs.listFileTree(dirPath, tsPattern),
|
|
84
|
+
plugins.smartfile.fs.listFileTree(dirPath, dockerPattern),
|
|
85
|
+
]);
|
|
86
|
+
|
|
87
|
+
const allTestFiles = [...tsFiles, ...dockerFiles];
|
|
88
|
+
|
|
81
89
|
this.testfileArray = await Promise.all(
|
|
82
|
-
|
|
90
|
+
allTestFiles.map(async (filePath) => {
|
|
83
91
|
const absolutePath = plugins.path.isAbsolute(filePath)
|
|
84
92
|
? filePath
|
|
85
93
|
: plugins.path.join(dirPath, filePath);
|
|
@@ -11,12 +11,13 @@ import { TsTestLogger } from './tstest.logging.js';
|
|
|
11
11
|
import type { LogOptions } from './tstest.logging.js';
|
|
12
12
|
|
|
13
13
|
// Runtime adapters
|
|
14
|
-
import { parseTestFilename } from './tstest.classes.runtime.parser.js';
|
|
14
|
+
import { parseTestFilename, isDockerTestFile, parseDockerTestFilename } from './tstest.classes.runtime.parser.js';
|
|
15
15
|
import { RuntimeAdapterRegistry } from './tstest.classes.runtime.adapter.js';
|
|
16
16
|
import { NodeRuntimeAdapter } from './tstest.classes.runtime.node.js';
|
|
17
17
|
import { ChromiumRuntimeAdapter } from './tstest.classes.runtime.chromium.js';
|
|
18
18
|
import { DenoRuntimeAdapter } from './tstest.classes.runtime.deno.js';
|
|
19
19
|
import { BunRuntimeAdapter } from './tstest.classes.runtime.bun.js';
|
|
20
|
+
import { DockerRuntimeAdapter } from './tstest.classes.runtime.docker.js';
|
|
20
21
|
|
|
21
22
|
export class TsTest {
|
|
22
23
|
public testDir: TestDirectory;
|
|
@@ -37,6 +38,7 @@ export class TsTest {
|
|
|
37
38
|
public tsbundleInstance = new plugins.tsbundle.TsBundle();
|
|
38
39
|
|
|
39
40
|
public runtimeRegistry = new RuntimeAdapterRegistry();
|
|
41
|
+
public dockerAdapter: DockerRuntimeAdapter | null = null;
|
|
40
42
|
|
|
41
43
|
constructor(cwdArg: string, testPathArg: string, executionModeArg: TestExecutionMode, logOptions: LogOptions = {}, tags: string[] = [], startFromFile: number | null = null, stopAtFile: number | null = null, timeoutSeconds: number | null = null) {
|
|
42
44
|
this.executionMode = executionModeArg;
|
|
@@ -60,6 +62,14 @@ export class TsTest {
|
|
|
60
62
|
this.runtimeRegistry.register(
|
|
61
63
|
new BunRuntimeAdapter(this.logger, this.smartshellInstance, this.timeoutSeconds, this.filterTags)
|
|
62
64
|
);
|
|
65
|
+
|
|
66
|
+
// Initialize Docker adapter
|
|
67
|
+
this.dockerAdapter = new DockerRuntimeAdapter(
|
|
68
|
+
this.logger,
|
|
69
|
+
this.smartshellInstance,
|
|
70
|
+
this.timeoutSeconds,
|
|
71
|
+
cwdArg
|
|
72
|
+
);
|
|
63
73
|
}
|
|
64
74
|
|
|
65
75
|
/**
|
|
@@ -211,8 +221,14 @@ export class TsTest {
|
|
|
211
221
|
}
|
|
212
222
|
|
|
213
223
|
private async runSingleTest(fileNameArg: string, fileIndex: number, totalFiles: number, tapCombinator: TapCombinator) {
|
|
214
|
-
// Parse the filename to determine runtimes and modifiers
|
|
215
224
|
const fileName = plugins.path.basename(fileNameArg);
|
|
225
|
+
|
|
226
|
+
// Check if this is a Docker test file
|
|
227
|
+
if (isDockerTestFile(fileName)) {
|
|
228
|
+
return await this.runDockerTest(fileNameArg, fileIndex, totalFiles, tapCombinator);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// Parse the filename to determine runtimes and modifiers (for TypeScript tests)
|
|
216
232
|
const parsed = parseTestFilename(fileName, { strictUnknownRuntime: false });
|
|
217
233
|
|
|
218
234
|
// Check for nonci modifier in CI environment
|
|
@@ -258,6 +274,28 @@ export class TsTest {
|
|
|
258
274
|
}
|
|
259
275
|
}
|
|
260
276
|
|
|
277
|
+
/**
|
|
278
|
+
* Execute a Docker test file
|
|
279
|
+
*/
|
|
280
|
+
private async runDockerTest(
|
|
281
|
+
fileNameArg: string,
|
|
282
|
+
fileIndex: number,
|
|
283
|
+
totalFiles: number,
|
|
284
|
+
tapCombinator: TapCombinator
|
|
285
|
+
): Promise<void> {
|
|
286
|
+
if (!this.dockerAdapter) {
|
|
287
|
+
this.logger.tapOutput(cs('❌ Docker adapter not initialized', 'red'));
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
try {
|
|
292
|
+
const tapParser = await this.dockerAdapter.run(fileNameArg, fileIndex, totalFiles);
|
|
293
|
+
tapCombinator.addTapParser(tapParser);
|
|
294
|
+
} catch (error) {
|
|
295
|
+
this.logger.tapOutput(cs(`❌ Docker test failed: ${error.message}`, 'red'));
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
261
299
|
public async runInNode(fileNameArg: string, index: number, total: number): Promise<TapParser> {
|
|
262
300
|
this.logger.testFileStart(fileNameArg, 'node.js', index, total);
|
|
263
301
|
const tapParser = new TapParser(fileNameArg + ':node', this.logger);
|