tstyche 3.1.0 → 3.2.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/README.md +3 -3
- package/build/tstyche.d.ts +5 -1
- package/build/tstyche.js +77 -43
- package/package.json +8 -8
package/README.md
CHANGED
|
@@ -64,10 +64,10 @@ Here is the list of all matchers:
|
|
|
64
64
|
|
|
65
65
|
## Runner
|
|
66
66
|
|
|
67
|
-
The `tstyche` command is the heart of TSTyche. For example, it can select test files by path, filter tests by name and pass them through
|
|
67
|
+
The `tstyche` command is the heart of TSTyche. For example, it can select test files by path, filter tests by name and pass them through a range of TypeScript versions:
|
|
68
68
|
|
|
69
|
-
```
|
|
70
|
-
tstyche
|
|
69
|
+
```shell
|
|
70
|
+
tstyche query-params --only multiple --target '>=5.0 <5.3'
|
|
71
71
|
```
|
|
72
72
|
|
|
73
73
|
This simple! (And it has watch mode too.)
|
package/build/tstyche.d.ts
CHANGED
|
@@ -152,6 +152,10 @@ declare class ConfigDiagnosticText {
|
|
|
152
152
|
* Options loaded from the configuration file.
|
|
153
153
|
*/
|
|
154
154
|
interface ConfigFileOptions {
|
|
155
|
+
/**
|
|
156
|
+
* Enable type error reporting for source files.
|
|
157
|
+
*/
|
|
158
|
+
checkSourceFiles?: boolean;
|
|
155
159
|
/**
|
|
156
160
|
* Stop running tests after the first failed assertion.
|
|
157
161
|
*/
|
|
@@ -867,4 +871,4 @@ declare class WatchService {
|
|
|
867
871
|
watch(cancellationToken: CancellationToken): AsyncIterable<Array<Task>>;
|
|
868
872
|
}
|
|
869
873
|
|
|
870
|
-
export { Assertion, BaseReporter, CancellationHandler, CancellationReason, CancellationToken, Cli, CollectService, Color, type CommandLineOptions, Config, ConfigDiagnosticText, type ConfigFileOptions, DescribeResult, Diagnostic, DiagnosticCategory, DiagnosticOrigin, type DiagnosticsHandler, type EnvironmentOptions, type Event, EventEmitter, type EventHandler, ExitCodeHandler, ExpectResult, ExpectService, type FileWatchHandler, FileWatcher, type InputHandler, InputService, type ItemDefinition, Line, ListReporter, type MatchResult, OptionBrand, type OptionDefinition, OptionGroup, Options, OutputService, Path, type Plugin, PluginService, ProjectResult, ProjectService, type Reporter, type ReporterEvent, type ResolvedConfig, Result, ResultCount, ResultHandler, ResultStatus, ResultTiming, Runner, Scribbler, ScribblerJsx, type ScribblerOptions, Select, SelectDiagnosticText, SetupReporter, SourceFile, Store, SummaryReporter, TargetResult, type TargetResultStatus, Task, TaskResult, type TaskResultStatus, TestMember, TestMemberBrand, TestMemberFlags, TestResult, TestTree, Text, type TypeChecker, Version, type WatchHandler, WatchReporter, WatchService, Watcher, type WatcherOptions, addsPackageText, defaultOptions, describeNameText, diagnosticText, environmentOptions, fileViewText, formattedText, helpText, summaryText, taskStatusText, testNameText, usesCompilerText, waitingForFileChangesText, watchUsageText };
|
|
874
|
+
export { Assertion, BaseReporter, CancellationHandler, CancellationReason, CancellationToken, Cli, CollectService, Color, type CommandLineOptions, Config, ConfigDiagnosticText, type ConfigFileOptions, DescribeResult, Diagnostic, DiagnosticCategory, DiagnosticOrigin, type DiagnosticsHandler, type EnvironmentOptions, type Event, EventEmitter, type EventHandler, ExitCodeHandler, ExpectResult, ExpectService, type FileWatchHandler, FileWatcher, type InputHandler, InputService, type ItemDefinition, Line, ListReporter, type MatchResult, OptionBrand, type OptionDefinition, OptionGroup, Options, OutputService, Path, type Plugin, PluginService, ProjectResult, ProjectService, type Reporter, type ReporterEvent, type ResolvedConfig, Result, ResultCount, ResultHandler, ResultStatus, ResultTiming, Runner, Scribbler, ScribblerJsx, type ScribblerOptions, Select, SelectDiagnosticText, type SelectHookContext, SetupReporter, SourceFile, Store, SummaryReporter, TargetResult, type TargetResultStatus, Task, TaskResult, type TaskResultStatus, TestMember, TestMemberBrand, TestMemberFlags, TestResult, TestTree, Text, type TypeChecker, Version, type WatchHandler, WatchReporter, WatchService, Watcher, type WatcherOptions, addsPackageText, defaultOptions, describeNameText, diagnosticText, environmentOptions, fileViewText, formattedText, helpText, summaryText, taskStatusText, testNameText, usesCompilerText, waitingForFileChangesText, watchUsageText };
|
package/build/tstyche.js
CHANGED
|
@@ -824,13 +824,14 @@ class Store {
|
|
|
824
824
|
|
|
825
825
|
class Target {
|
|
826
826
|
static #rangeRegex = /^[<>]=?\d\.\d( [<>]=?\d\.\d)?$/;
|
|
827
|
-
static expand(queries) {
|
|
827
|
+
static async expand(queries) {
|
|
828
828
|
const include = [];
|
|
829
829
|
for (const query of queries) {
|
|
830
830
|
if (!Target.isRange(query)) {
|
|
831
831
|
include.push(query);
|
|
832
832
|
continue;
|
|
833
833
|
}
|
|
834
|
+
await Store.open();
|
|
834
835
|
if (Store.manifest != null) {
|
|
835
836
|
let versions = Object.keys(Store.manifest.resolutions).slice(0, -4);
|
|
836
837
|
for (const comparator of query.split(" ")) {
|
|
@@ -842,14 +843,16 @@ class Target {
|
|
|
842
843
|
return include;
|
|
843
844
|
}
|
|
844
845
|
static #filter(comparator, versions) {
|
|
845
|
-
const
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
846
|
+
const targetVersion = comparator.replace(/^[<>]=?/, "");
|
|
847
|
+
switch (comparator.charAt(0)) {
|
|
848
|
+
case ">":
|
|
849
|
+
return versions.filter((sourceVersion) => comparator.charAt(1) === "="
|
|
850
|
+
? Version.isSatisfiedWith(sourceVersion, targetVersion)
|
|
851
|
+
: Version.isGreaterThan(sourceVersion, targetVersion));
|
|
852
|
+
case "<":
|
|
853
|
+
return versions.filter((sourceVersion) => comparator.charAt(1) === "="
|
|
854
|
+
? Version.isSatisfiedWith(targetVersion, sourceVersion)
|
|
855
|
+
: Version.isGreaterThan(targetVersion, sourceVersion));
|
|
853
856
|
}
|
|
854
857
|
return [];
|
|
855
858
|
}
|
|
@@ -866,6 +869,12 @@ class Options {
|
|
|
866
869
|
group: 4,
|
|
867
870
|
name: "$schema",
|
|
868
871
|
},
|
|
872
|
+
{
|
|
873
|
+
brand: "boolean",
|
|
874
|
+
description: "Enable type error reporting for source files.",
|
|
875
|
+
group: 4,
|
|
876
|
+
name: "checkSourceFiles",
|
|
877
|
+
},
|
|
869
878
|
{
|
|
870
879
|
brand: "string",
|
|
871
880
|
description: "The path to a TSTyche configuration file.",
|
|
@@ -1083,18 +1092,7 @@ class Options {
|
|
|
1083
1092
|
break;
|
|
1084
1093
|
case "target": {
|
|
1085
1094
|
if (/[<>=]/.test(optionValue)) {
|
|
1086
|
-
if (Target.isRange(optionValue)) {
|
|
1087
|
-
for (const value of optionValue.split(" ").map((value) => value.replace(/^[<>]=?/, ""))) {
|
|
1088
|
-
if ((await Store.validateTag(value)) === false) {
|
|
1089
|
-
onDiagnostics(Diagnostic.error([
|
|
1090
|
-
ConfigDiagnosticText.versionIsNotSupported(value),
|
|
1091
|
-
...ConfigDiagnosticText.usage(optionName, optionBrand),
|
|
1092
|
-
ConfigDiagnosticText.inspectSupportedVersions(),
|
|
1093
|
-
], origin));
|
|
1094
|
-
}
|
|
1095
|
-
}
|
|
1096
|
-
}
|
|
1097
|
-
else {
|
|
1095
|
+
if (!Target.isRange(optionValue)) {
|
|
1098
1096
|
onDiagnostics(Diagnostic.error([ConfigDiagnosticText.rangeIsNotValid(optionValue), ...ConfigDiagnosticText.rangeUsage()], origin));
|
|
1099
1097
|
}
|
|
1100
1098
|
break;
|
|
@@ -1482,6 +1480,7 @@ class ConfigFileParser {
|
|
|
1482
1480
|
}
|
|
1483
1481
|
|
|
1484
1482
|
const defaultOptions = {
|
|
1483
|
+
checkSourceFiles: false,
|
|
1485
1484
|
failFast: false,
|
|
1486
1485
|
plugins: [],
|
|
1487
1486
|
rejectAnyType: false,
|
|
@@ -1502,6 +1501,9 @@ class Config {
|
|
|
1502
1501
|
const pathMatch = [];
|
|
1503
1502
|
const commandLineParser = new CommandLineParser(commandLineOptions, pathMatch, Config.#onDiagnostics);
|
|
1504
1503
|
await commandLineParser.parse(commandLine);
|
|
1504
|
+
if (commandLineOptions.target != null) {
|
|
1505
|
+
commandLineOptions.target = await Target.expand(commandLineOptions.target);
|
|
1506
|
+
}
|
|
1505
1507
|
return { commandLineOptions, pathMatch };
|
|
1506
1508
|
}
|
|
1507
1509
|
static async parseConfigFile(filePath) {
|
|
@@ -1516,6 +1518,9 @@ class Config {
|
|
|
1516
1518
|
const sourceFile = new SourceFile(configFilePath, configFileText);
|
|
1517
1519
|
const configFileParser = new ConfigFileParser(configFileOptions, sourceFile, Config.#onDiagnostics);
|
|
1518
1520
|
await configFileParser.parse();
|
|
1521
|
+
if (configFileOptions.target != null) {
|
|
1522
|
+
configFileOptions.target = await Target.expand(configFileOptions.target);
|
|
1523
|
+
}
|
|
1519
1524
|
}
|
|
1520
1525
|
return { configFileOptions, configFilePath };
|
|
1521
1526
|
}
|
|
@@ -1530,7 +1535,6 @@ class Config {
|
|
|
1530
1535
|
if ("config" in resolvedConfig) {
|
|
1531
1536
|
delete resolvedConfig.config;
|
|
1532
1537
|
}
|
|
1533
|
-
resolvedConfig.target = Target.expand(resolvedConfig.target);
|
|
1534
1538
|
return resolvedConfig;
|
|
1535
1539
|
}
|
|
1536
1540
|
static resolveConfigFilePath(filePath) {
|
|
@@ -2338,12 +2342,11 @@ class FileView {
|
|
|
2338
2342
|
}
|
|
2339
2343
|
|
|
2340
2344
|
class ListReporter extends BaseReporter {
|
|
2341
|
-
#currentCompilerVersion;
|
|
2342
|
-
#currentProjectConfigFilePath;
|
|
2343
2345
|
#fileCount = 0;
|
|
2344
2346
|
#fileView = new FileView();
|
|
2345
2347
|
#hasReportedAdds = false;
|
|
2346
2348
|
#hasReportedError = false;
|
|
2349
|
+
#hasReportedUses = false;
|
|
2347
2350
|
#isFileViewExpanded = false;
|
|
2348
2351
|
#seenDeprecations = new Set();
|
|
2349
2352
|
get #isLastFile() {
|
|
@@ -2374,21 +2377,14 @@ class ListReporter extends BaseReporter {
|
|
|
2374
2377
|
break;
|
|
2375
2378
|
case "target:start":
|
|
2376
2379
|
this.#fileCount = payload.result.tasks.length;
|
|
2377
|
-
|
|
2378
|
-
case "target:end":
|
|
2379
|
-
this.#currentCompilerVersion = undefined;
|
|
2380
|
-
this.#currentProjectConfigFilePath = undefined;
|
|
2380
|
+
this.#hasReportedUses = false;
|
|
2381
2381
|
break;
|
|
2382
2382
|
case "project:uses":
|
|
2383
|
-
|
|
2384
|
-
this.#
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
this.#hasReportedAdds = false;
|
|
2389
|
-
this.#currentCompilerVersion = payload.compilerVersion;
|
|
2390
|
-
this.#currentProjectConfigFilePath = payload.projectConfigFilePath;
|
|
2391
|
-
}
|
|
2383
|
+
OutputService.writeMessage(usesCompilerText(payload.compilerVersion, payload.projectConfigFilePath, {
|
|
2384
|
+
prependEmptyLine: this.#hasReportedUses && !this.#hasReportedAdds && !this.#hasReportedError,
|
|
2385
|
+
}));
|
|
2386
|
+
this.#hasReportedAdds = false;
|
|
2387
|
+
this.#hasReportedUses = true;
|
|
2392
2388
|
break;
|
|
2393
2389
|
case "project:error":
|
|
2394
2390
|
for (const diagnostic of payload.diagnostics) {
|
|
@@ -3165,7 +3161,9 @@ var TestMemberFlags;
|
|
|
3165
3161
|
|
|
3166
3162
|
class ProjectService {
|
|
3167
3163
|
#compiler;
|
|
3164
|
+
#lastSeenProject = "";
|
|
3168
3165
|
#resolvedConfig;
|
|
3166
|
+
#seenPrograms = new WeakSet();
|
|
3169
3167
|
#service;
|
|
3170
3168
|
constructor(resolvedConfig, compiler) {
|
|
3171
3169
|
this.#resolvedConfig = resolvedConfig;
|
|
@@ -3240,7 +3238,12 @@ class ProjectService {
|
|
|
3240
3238
|
return defaultCompilerOptions;
|
|
3241
3239
|
}
|
|
3242
3240
|
getDefaultProject(filePath) {
|
|
3243
|
-
|
|
3241
|
+
const project = this.#service.getDefaultProjectForFile(this.#compiler.server.toNormalizedPath(filePath), true);
|
|
3242
|
+
const compilerOptions = project?.getCompilerOptions();
|
|
3243
|
+
if (this.#resolvedConfig.checkSourceFiles && compilerOptions?.skipLibCheck) {
|
|
3244
|
+
project?.setCompilerOptions({ ...compilerOptions, skipLibCheck: false });
|
|
3245
|
+
}
|
|
3246
|
+
return project;
|
|
3244
3247
|
}
|
|
3245
3248
|
getLanguageService(filePath) {
|
|
3246
3249
|
const project = this.getDefaultProject(filePath);
|
|
@@ -3248,16 +3251,47 @@ class ProjectService {
|
|
|
3248
3251
|
}
|
|
3249
3252
|
openFile(filePath, sourceText, projectRootPath) {
|
|
3250
3253
|
const { configFileErrors, configFileName } = this.#service.openClientFile(filePath, sourceText, undefined, projectRootPath);
|
|
3251
|
-
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
|
|
3254
|
+
if (configFileName !== this.#lastSeenProject) {
|
|
3255
|
+
this.#lastSeenProject = configFileName;
|
|
3256
|
+
EventEmitter.dispatch([
|
|
3257
|
+
"project:uses",
|
|
3258
|
+
{ compilerVersion: this.#compiler.version, projectConfigFilePath: configFileName },
|
|
3259
|
+
]);
|
|
3260
|
+
}
|
|
3255
3261
|
if (configFileErrors && configFileErrors.length > 0) {
|
|
3256
3262
|
EventEmitter.dispatch([
|
|
3257
3263
|
"project:error",
|
|
3258
3264
|
{ diagnostics: Diagnostic.fromDiagnostics(configFileErrors, this.#compiler) },
|
|
3259
3265
|
]);
|
|
3260
3266
|
}
|
|
3267
|
+
if (this.#resolvedConfig.checkSourceFiles) {
|
|
3268
|
+
const languageService = this.getLanguageService(filePath);
|
|
3269
|
+
const program = languageService?.getProgram();
|
|
3270
|
+
if (!program || this.#seenPrograms.has(program)) {
|
|
3271
|
+
return;
|
|
3272
|
+
}
|
|
3273
|
+
this.#seenPrograms.add(program);
|
|
3274
|
+
const filesToCheck = [];
|
|
3275
|
+
for (const sourceFile of program.getSourceFiles()) {
|
|
3276
|
+
if (program.isSourceFileFromExternalLibrary(sourceFile) || program.isSourceFileDefaultLibrary(sourceFile)) {
|
|
3277
|
+
continue;
|
|
3278
|
+
}
|
|
3279
|
+
if (!Select.isTestFile(sourceFile.fileName, { ...this.#resolvedConfig, pathMatch: [] })) {
|
|
3280
|
+
filesToCheck.push(sourceFile);
|
|
3281
|
+
}
|
|
3282
|
+
}
|
|
3283
|
+
const diagnostics = [];
|
|
3284
|
+
for (const sourceFile of filesToCheck) {
|
|
3285
|
+
diagnostics.push(...program.getSyntacticDiagnostics(sourceFile), ...program.getSemanticDiagnostics(sourceFile));
|
|
3286
|
+
}
|
|
3287
|
+
if (diagnostics.length > 0) {
|
|
3288
|
+
EventEmitter.dispatch([
|
|
3289
|
+
"project:error",
|
|
3290
|
+
{ diagnostics: Diagnostic.fromDiagnostics(diagnostics, this.#compiler) },
|
|
3291
|
+
]);
|
|
3292
|
+
return;
|
|
3293
|
+
}
|
|
3294
|
+
}
|
|
3261
3295
|
}
|
|
3262
3296
|
}
|
|
3263
3297
|
|
|
@@ -4273,7 +4307,7 @@ class TaskRunner {
|
|
|
4273
4307
|
class Runner {
|
|
4274
4308
|
#eventEmitter = new EventEmitter();
|
|
4275
4309
|
#resolvedConfig;
|
|
4276
|
-
static version = "3.
|
|
4310
|
+
static version = "3.2.0";
|
|
4277
4311
|
constructor(resolvedConfig) {
|
|
4278
4312
|
this.#resolvedConfig = resolvedConfig;
|
|
4279
4313
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tstyche",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.2.0",
|
|
4
4
|
"description": "The Essential Type Testing Tool.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"typescript",
|
|
@@ -62,15 +62,15 @@
|
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
|
64
64
|
"@biomejs/biome": "1.9.4",
|
|
65
|
-
"@rollup/plugin-typescript": "12.1.
|
|
66
|
-
"@types/node": "22.10.
|
|
67
|
-
"@types/react": "
|
|
65
|
+
"@rollup/plugin-typescript": "12.1.2",
|
|
66
|
+
"@types/node": "22.10.2",
|
|
67
|
+
"@types/react": "19.0.2",
|
|
68
68
|
"ajv": "8.17.1",
|
|
69
|
-
"cspell": "8.
|
|
70
|
-
"magic-string": "0.30.
|
|
71
|
-
"monocart-coverage-reports": "2.11.
|
|
69
|
+
"cspell": "8.17.1",
|
|
70
|
+
"magic-string": "0.30.17",
|
|
71
|
+
"monocart-coverage-reports": "2.11.5",
|
|
72
72
|
"pretty-ansi": "3.0.0",
|
|
73
|
-
"rollup": "4.
|
|
73
|
+
"rollup": "4.29.1",
|
|
74
74
|
"rollup-plugin-dts": "6.1.1",
|
|
75
75
|
"tslib": "2.8.1",
|
|
76
76
|
"typescript": "5.7.2"
|