tstest/ts/tstest.classes.testdirectory.ts

142 lines
4.2 KiB
TypeScript

import * as plugins from './tstest.plugins.js';
import * as paths from './tstest.paths.js';
import { SmartFile } from '@push.rocks/smartfile';
import { TestExecutionMode } from './index.js';
// tap related stuff
import { TapCombinator } from './tstest.classes.tap.combinator.js';
import { TapParser } from './tstest.classes.tap.parser.js';
import { TapTestResult } from './tstest.classes.tap.testresult.js';
export class TestDirectory {
/**
* the current working directory
*/
cwd: string;
/**
* the test path or pattern
*/
testPath: string;
/**
* the execution mode
*/
executionMode: TestExecutionMode;
/**
* an array of Smartfiles
*/
testfileArray: SmartFile[] = [];
/**
* the constructor for TestDirectory
* @param cwdArg - the current working directory
* @param testPathArg - the test path/pattern
* @param executionModeArg - the execution mode
*/
constructor(cwdArg: string, testPathArg: string, executionModeArg: TestExecutionMode) {
this.cwd = cwdArg;
this.testPath = testPathArg;
this.executionMode = executionModeArg;
}
private async _init() {
switch (this.executionMode) {
case TestExecutionMode.FILE:
// Single file mode
const filePath = plugins.path.isAbsolute(this.testPath)
? this.testPath
: plugins.path.join(this.cwd, this.testPath);
if (await plugins.smartfile.fs.fileExists(filePath)) {
this.testfileArray = [await plugins.smartfile.SmartFile.fromFilePath(filePath)];
} else {
throw new Error(`Test file not found: ${filePath}`);
}
break;
case TestExecutionMode.GLOB:
// Glob pattern mode - use listFileTree which supports glob patterns
const globPattern = this.testPath;
const matchedFiles = await plugins.smartfile.fs.listFileTree(this.cwd, globPattern);
this.testfileArray = await Promise.all(
matchedFiles.map(async (filePath) => {
const absolutePath = plugins.path.isAbsolute(filePath)
? filePath
: plugins.path.join(this.cwd, filePath);
return await plugins.smartfile.SmartFile.fromFilePath(absolutePath);
})
);
break;
case TestExecutionMode.DIRECTORY:
// Directory mode - now recursive with ** pattern
const dirPath = plugins.path.join(this.cwd, this.testPath);
const testPattern = '**/test*.ts';
const testFiles = await plugins.smartfile.fs.listFileTree(dirPath, testPattern);
this.testfileArray = await Promise.all(
testFiles.map(async (filePath) => {
const absolutePath = plugins.path.isAbsolute(filePath)
? filePath
: plugins.path.join(dirPath, filePath);
return await plugins.smartfile.SmartFile.fromFilePath(absolutePath);
})
);
break;
}
}
async getTestFilePathArray() {
await this._init();
const testFilePaths: string[] = [];
for (const testFile of this.testfileArray) {
// Use the path directly from the SmartFile
testFilePaths.push(testFile.path);
}
return testFilePaths;
}
/**
* Get test files organized by parallel execution groups
* @returns An object with grouped tests
*/
async getTestFileGroups(): Promise<{
serial: string[];
parallelGroups: { [groupName: string]: string[] };
}> {
await this._init();
const result = {
serial: [] as string[],
parallelGroups: {} as { [groupName: string]: string[] }
};
for (const testFile of this.testfileArray) {
const filePath = testFile.path;
const fileName = plugins.path.basename(filePath);
// Check if file has parallel group pattern
const parallelMatch = fileName.match(/\.para__(\d+)\./);
if (parallelMatch) {
const groupNumber = parallelMatch[1];
const groupName = `para__${groupNumber}`;
if (!result.parallelGroups[groupName]) {
result.parallelGroups[groupName] = [];
}
result.parallelGroups[groupName].push(filePath);
} else {
// File runs serially
result.serial.push(filePath);
}
}
return result;
}
}