feat(cli): Add --startFrom and --stopAt options to filter test files by range
This commit is contained in:
parent
83b324b09f
commit
27c950c1a1
@ -1,5 +1,13 @@
|
||||
# Changelog
|
||||
|
||||
## 2025-05-23 - 1.10.0 - feat(cli)
|
||||
Add --startFrom and --stopAt options to filter test files by range
|
||||
|
||||
- Introduced CLI options --startFrom and --stopAt in ts/index.ts for selective test execution
|
||||
- Added validation to ensure provided range values are positive and startFrom is not greater than stopAt
|
||||
- Propagated file range filtering into test grouping in tstest.classes.tstest.ts, applying the range filter across serial and parallel groups
|
||||
- Updated usage messages to include the new options
|
||||
|
||||
## 2025-05-23 - 1.9.4 - fix(docs)
|
||||
Update documentation and configuration for legal notices and CI permissions. This commit adds a new local settings file for tool permissions, refines the legal and trademark sections in the readme, and improves glob test files with clearer log messages.
|
||||
|
||||
|
@ -3,6 +3,6 @@
|
||||
*/
|
||||
export const commitinfo = {
|
||||
name: '@git.zone/tstest',
|
||||
version: '1.9.4',
|
||||
version: '1.10.0',
|
||||
description: 'a test utility to run tests that match test/**/*.ts'
|
||||
}
|
||||
|
55
ts/index.ts
55
ts/index.ts
@ -13,6 +13,8 @@ export const runCli = async () => {
|
||||
const logOptions: LogOptions = {};
|
||||
let testPath: string | null = null;
|
||||
let tags: string[] = [];
|
||||
let startFromFile: number | null = null;
|
||||
let stopAtFile: number | null = null;
|
||||
|
||||
// Parse options
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
@ -42,6 +44,32 @@ export const runCli = async () => {
|
||||
tags = args[++i].split(',');
|
||||
}
|
||||
break;
|
||||
case '--startFrom':
|
||||
if (i + 1 < args.length) {
|
||||
const value = parseInt(args[++i], 10);
|
||||
if (isNaN(value) || value < 1) {
|
||||
console.error('Error: --startFrom must be a positive integer');
|
||||
process.exit(1);
|
||||
}
|
||||
startFromFile = value;
|
||||
} else {
|
||||
console.error('Error: --startFrom requires a number argument');
|
||||
process.exit(1);
|
||||
}
|
||||
break;
|
||||
case '--stopAt':
|
||||
if (i + 1 < args.length) {
|
||||
const value = parseInt(args[++i], 10);
|
||||
if (isNaN(value) || value < 1) {
|
||||
console.error('Error: --stopAt must be a positive integer');
|
||||
process.exit(1);
|
||||
}
|
||||
stopAtFile = value;
|
||||
} else {
|
||||
console.error('Error: --stopAt requires a number argument');
|
||||
process.exit(1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (!arg.startsWith('-')) {
|
||||
testPath = arg;
|
||||
@ -49,16 +77,24 @@ export const runCli = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
// Validate test file range options
|
||||
if (startFromFile !== null && stopAtFile !== null && startFromFile > stopAtFile) {
|
||||
console.error('Error: --startFrom cannot be greater than --stopAt');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (!testPath) {
|
||||
console.error('You must specify a test directory/file/pattern as argument. Please try again.');
|
||||
console.error('\nUsage: tstest <path> [options]');
|
||||
console.error('\nOptions:');
|
||||
console.error(' --quiet, -q Minimal output');
|
||||
console.error(' --verbose, -v Verbose output');
|
||||
console.error(' --no-color Disable colored output');
|
||||
console.error(' --json Output results as JSON');
|
||||
console.error(' --logfile Write logs to .nogit/testlogs/[testfile].log');
|
||||
console.error(' --tags Run only tests with specified tags (comma-separated)');
|
||||
console.error(' --quiet, -q Minimal output');
|
||||
console.error(' --verbose, -v Verbose output');
|
||||
console.error(' --no-color Disable colored output');
|
||||
console.error(' --json Output results as JSON');
|
||||
console.error(' --logfile Write logs to .nogit/testlogs/[testfile].log');
|
||||
console.error(' --tags <tags> Run only tests with specified tags (comma-separated)');
|
||||
console.error(' --startFrom <n> Start running from test file number n');
|
||||
console.error(' --stopAt <n> Stop running at test file number n');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
@ -73,6 +109,11 @@ export const runCli = async () => {
|
||||
executionMode = TestExecutionMode.DIRECTORY;
|
||||
}
|
||||
|
||||
const tsTestInstance = new TsTest(process.cwd(), testPath, executionMode, logOptions, tags);
|
||||
const tsTestInstance = new TsTest(process.cwd(), testPath, executionMode, logOptions, tags, startFromFile, stopAtFile);
|
||||
await tsTestInstance.run();
|
||||
};
|
||||
|
||||
// Execute CLI when this file is run directly
|
||||
if (import.meta.url === `file://${process.argv[1]}`) {
|
||||
runCli();
|
||||
}
|
||||
|
@ -16,6 +16,8 @@ export class TsTest {
|
||||
public executionMode: TestExecutionMode;
|
||||
public logger: TsTestLogger;
|
||||
public filterTags: string[];
|
||||
public startFromFile: number | null;
|
||||
public stopAtFile: number | null;
|
||||
|
||||
public smartshellInstance = new plugins.smartshell.Smartshell({
|
||||
executor: 'bash',
|
||||
@ -26,16 +28,35 @@ export class TsTest {
|
||||
|
||||
public tsbundleInstance = new plugins.tsbundle.TsBundle();
|
||||
|
||||
constructor(cwdArg: string, testPathArg: string, executionModeArg: TestExecutionMode, logOptions: LogOptions = {}, tags: string[] = []) {
|
||||
constructor(cwdArg: string, testPathArg: string, executionModeArg: TestExecutionMode, logOptions: LogOptions = {}, tags: string[] = [], startFromFile: number | null = null, stopAtFile: number | null = null) {
|
||||
this.executionMode = executionModeArg;
|
||||
this.testDir = new TestDirectory(cwdArg, testPathArg, executionModeArg);
|
||||
this.logger = new TsTestLogger(logOptions);
|
||||
this.filterTags = tags;
|
||||
this.startFromFile = startFromFile;
|
||||
this.stopAtFile = stopAtFile;
|
||||
}
|
||||
|
||||
async run() {
|
||||
const testGroups = await this.testDir.getTestFileGroups();
|
||||
const allFiles = [...testGroups.serial, ...Object.values(testGroups.parallelGroups).flat()];
|
||||
let allFiles = [...testGroups.serial, ...Object.values(testGroups.parallelGroups).flat()];
|
||||
|
||||
// Apply file range filtering if specified
|
||||
if (this.startFromFile !== null || this.stopAtFile !== null) {
|
||||
const startIndex = this.startFromFile ? this.startFromFile - 1 : 0; // Convert to 0-based index
|
||||
const endIndex = this.stopAtFile ? this.stopAtFile : allFiles.length;
|
||||
allFiles = allFiles.slice(startIndex, endIndex);
|
||||
|
||||
// Filter the serial and parallel groups based on remaining files
|
||||
testGroups.serial = testGroups.serial.filter(file => allFiles.includes(file));
|
||||
Object.keys(testGroups.parallelGroups).forEach(groupName => {
|
||||
testGroups.parallelGroups[groupName] = testGroups.parallelGroups[groupName].filter(file => allFiles.includes(file));
|
||||
// Remove empty groups
|
||||
if (testGroups.parallelGroups[groupName].length === 0) {
|
||||
delete testGroups.parallelGroups[groupName];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Log test discovery
|
||||
this.logger.testDiscovery(
|
||||
|
Loading…
x
Reference in New Issue
Block a user