tstyche 1.0.0-rc → 1.0.0-rc.2
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/CHANGELOG.md +22 -0
- package/README.md +9 -2
- package/build/tstyche.d.ts +8 -8
- package/build/tstyche.js +26 -29
- package/package.json +15 -14
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.0.0-rc.2] - 2024-02-14
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- Use the `isTypeRelatedTo()` method directly, to make strict subtype checks possible ([#127](https://github.com/tstyche/tstyche/pull/127), [#126](https://github.com/tstyche/tstyche/pull/126))
|
|
8
|
+
|
|
9
|
+
## [1.0.0-rc.1] - 2024-02-10
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- **Breaking!** Remove the `disableTestFileLookup` option in favor of `testFileMatch: []` ([#121](https://github.com/tstyche/tstyche/pull/121))
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- **New!** Set `module: "preserve"` in the default compiler options for inferred project that are using TypeScript 5.4 and up ([#111](https://github.com/tstyche/tstyche/pull/111))
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
|
|
21
|
+
- Do not select test files, if `testFileMatch` is an empty list ([#120](https://github.com/tstyche/tstyche/pull/120))
|
|
22
|
+
|
|
3
23
|
## [1.0.0-rc] - 2024-01-28
|
|
4
24
|
|
|
5
25
|
### Changed
|
|
@@ -116,6 +136,8 @@
|
|
|
116
136
|
|
|
117
137
|
_First pre-release._
|
|
118
138
|
|
|
139
|
+
[1.0.0-rc.2]: https://github.com/tstyche/tstyche/releases/tag/v1.0.0-rc.2
|
|
140
|
+
[1.0.0-rc.1]: https://github.com/tstyche/tstyche/releases/tag/v1.0.0-rc.1
|
|
119
141
|
[1.0.0-rc]: https://github.com/tstyche/tstyche/releases/tag/v1.0.0-rc
|
|
120
142
|
[1.0.0-beta.9]: https://github.com/tstyche/tstyche/releases/tag/v1.0.0-beta.9
|
|
121
143
|
[1.0.0-beta.8]: https://github.com/tstyche/tstyche/releases/tag/v1.0.0-beta.8
|
package/README.md
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
[![license][license-badge]][license-url]
|
|
5
5
|
[![packagephobia][packagephobia-badge]][packagephobia-url]
|
|
6
6
|
[![coverage][coverage-badge]][coverage-url]
|
|
7
|
+
[![discord][discord-badge]][discord-url]
|
|
7
8
|
|
|
8
9
|
The Essential Type Testing Tool.
|
|
9
10
|
|
|
@@ -75,6 +76,10 @@ This simple!
|
|
|
75
76
|
|
|
76
77
|
Visit [https://tstyche.org](https://tstyche.org) to view the full documentation.
|
|
77
78
|
|
|
79
|
+
## Feedback
|
|
80
|
+
|
|
81
|
+
If you have any questions or suggestions, [start a discussion](https://github.com/tstyche/tstyche/discussions/new/choose) or [open an issue](https://github.com/tstyche/tstyche/issues/new/choose) on GitHub. Preferring a chat? Join our [Discord server][discord-url].
|
|
82
|
+
|
|
78
83
|
## License
|
|
79
84
|
|
|
80
85
|
[MIT][license-url] © TSTyche
|
|
@@ -85,5 +90,7 @@ Visit [https://tstyche.org](https://tstyche.org) to view the full documentation.
|
|
|
85
90
|
[license-url]: https://github.com/tstyche/tstyche/blob/main/LICENSE.md
|
|
86
91
|
[packagephobia-badge]: https://badgen.net/packagephobia/install/tstyche
|
|
87
92
|
[packagephobia-url]: https://packagephobia.com/result?p=tstyche
|
|
88
|
-
[coverage-badge]: https://badgen.net/
|
|
89
|
-
[coverage-url]: https://app.
|
|
93
|
+
[coverage-badge]: https://badgen.net/codacy/coverage/a581ca5c323a455886b7bdd9623c4ec8
|
|
94
|
+
[coverage-url]: https://app.codacy.com/gh/tstyche/tstyche/coverage/dashboard
|
|
95
|
+
[discord-badge]: https://badgen.net/static/chat/on%20Discord
|
|
96
|
+
[discord-url]: https://discord.gg/gCSasd3QJq
|
package/build/tstyche.d.ts
CHANGED
|
@@ -139,10 +139,6 @@ interface CommandLineOptions {
|
|
|
139
139
|
* Options loaded from the configuration file.
|
|
140
140
|
*/
|
|
141
141
|
interface ConfigFileOptions {
|
|
142
|
-
/**
|
|
143
|
-
* Do not search for the test files.
|
|
144
|
-
*/
|
|
145
|
-
disableTestFileLookup?: boolean;
|
|
146
142
|
/**
|
|
147
143
|
* Stop running tests after the first failed assertion.
|
|
148
144
|
*/
|
|
@@ -183,7 +179,7 @@ declare class ConfigService {
|
|
|
183
179
|
declare class TSTyche {
|
|
184
180
|
#private;
|
|
185
181
|
readonly resolvedConfig: ResolvedConfig;
|
|
186
|
-
static readonly version = "
|
|
182
|
+
static readonly version = "1.0.0-rc.2";
|
|
187
183
|
constructor(resolvedConfig: ResolvedConfig, storeService: StoreService);
|
|
188
184
|
run(testFiles: Array<string | URL>): Promise<void>;
|
|
189
185
|
}
|
|
@@ -445,10 +441,14 @@ interface MatchResult {
|
|
|
445
441
|
explain: () => Array<Diagnostic>;
|
|
446
442
|
isMatch: boolean;
|
|
447
443
|
}
|
|
444
|
+
type Relation = Map<string, unknown>;
|
|
448
445
|
interface TypeChecker extends ts.TypeChecker {
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
446
|
+
isTypeRelatedTo: (source: ts.Type, target: ts.Type, relation: Relation) => boolean;
|
|
447
|
+
relation: {
|
|
448
|
+
assignable: Relation;
|
|
449
|
+
identity: Relation;
|
|
450
|
+
subtype: Relation;
|
|
451
|
+
};
|
|
452
452
|
}
|
|
453
453
|
|
|
454
454
|
declare class PrimitiveTypeMatcher {
|
package/build/tstyche.js
CHANGED
|
@@ -1742,7 +1742,7 @@ class ToBeAssignable {
|
|
|
1742
1742
|
: [Diagnostic.error(`Type '${targetTypeText}' is not assignable to type '${sourceTypeText}'.`)];
|
|
1743
1743
|
}
|
|
1744
1744
|
match(sourceType, targetType, isNot) {
|
|
1745
|
-
const isMatch = this.typeChecker.
|
|
1745
|
+
const isMatch = this.typeChecker.isTypeRelatedTo(targetType, sourceType, this.typeChecker.relation.assignable);
|
|
1746
1746
|
return {
|
|
1747
1747
|
explain: () => this.#explain(sourceType, targetType, isNot),
|
|
1748
1748
|
isMatch,
|
|
@@ -1763,7 +1763,7 @@ class ToEqual {
|
|
|
1763
1763
|
: [Diagnostic.error(`Type '${targetTypeText}' is not identical to type '${sourceTypeText}'.`)];
|
|
1764
1764
|
}
|
|
1765
1765
|
match(sourceType, targetType, isNot) {
|
|
1766
|
-
const isMatch = this.typeChecker.
|
|
1766
|
+
const isMatch = this.typeChecker.isTypeRelatedTo(sourceType, targetType, this.typeChecker.relation.identity);
|
|
1767
1767
|
return {
|
|
1768
1768
|
explain: () => this.#explain(sourceType, targetType, isNot),
|
|
1769
1769
|
isMatch,
|
|
@@ -1825,7 +1825,7 @@ class ToMatch {
|
|
|
1825
1825
|
: [Diagnostic.error(`Type '${targetTypeText}' is not a subtype of type '${sourceTypeText}'.`)];
|
|
1826
1826
|
}
|
|
1827
1827
|
match(sourceType, targetType, isNot) {
|
|
1828
|
-
const isMatch = this.typeChecker.
|
|
1828
|
+
const isMatch = this.typeChecker.isTypeRelatedTo(sourceType, targetType, this.typeChecker.relation.subtype);
|
|
1829
1829
|
return {
|
|
1830
1830
|
explain: () => this.#explain(sourceType, targetType, isNot),
|
|
1831
1831
|
isMatch,
|
|
@@ -1971,7 +1971,7 @@ class Expect {
|
|
|
1971
1971
|
this.toRaiseError = new ToRaiseError(this.compiler, this.typeChecker);
|
|
1972
1972
|
}
|
|
1973
1973
|
static assertTypeChecker(typeChecker) {
|
|
1974
|
-
return ("
|
|
1974
|
+
return ("isTypeRelatedTo" in typeChecker && "relation" in typeChecker);
|
|
1975
1975
|
}
|
|
1976
1976
|
#getType(node) {
|
|
1977
1977
|
return this.compiler.isExpression(node)
|
|
@@ -2030,7 +2030,7 @@ class Expect {
|
|
|
2030
2030
|
const sourceType = this.#getType(assertion.source[0]);
|
|
2031
2031
|
const nonPrimitiveType = { flags: this.compiler.TypeFlags.NonPrimitive };
|
|
2032
2032
|
if (sourceType.flags & (this.compiler.TypeFlags.Any | this.compiler.TypeFlags.Never)
|
|
2033
|
-
|| !this.typeChecker.
|
|
2033
|
+
|| !this.typeChecker.isTypeRelatedTo(sourceType, nonPrimitiveType, this.typeChecker.relation.assignable)) {
|
|
2034
2034
|
this.#onSourceArgumentMustBeObjectType(assertion.source[0], expectResult);
|
|
2035
2035
|
return;
|
|
2036
2036
|
}
|
|
@@ -2254,7 +2254,10 @@ class ProjectService {
|
|
|
2254
2254
|
strictNullChecks: true,
|
|
2255
2255
|
target: "esnext",
|
|
2256
2256
|
};
|
|
2257
|
-
if (Version.isSatisfiedWith(this.compiler.version, "5")) {
|
|
2257
|
+
if (Version.isSatisfiedWith(this.compiler.version, "5.4")) {
|
|
2258
|
+
defaultCompilerOptions.module = "preserve";
|
|
2259
|
+
}
|
|
2260
|
+
if (Version.isSatisfiedWith(this.compiler.version, "5.0")) {
|
|
2258
2261
|
defaultCompilerOptions["allowImportingTsExtensions"] = true;
|
|
2259
2262
|
defaultCompilerOptions.moduleResolution = "bundler";
|
|
2260
2263
|
}
|
|
@@ -2525,7 +2528,7 @@ class TestFileRunner {
|
|
|
2525
2528
|
}
|
|
2526
2529
|
const typeChecker = program.getTypeChecker();
|
|
2527
2530
|
if (!Expect.assertTypeChecker(typeChecker)) {
|
|
2528
|
-
const text = "The required '
|
|
2531
|
+
const text = "The required 'isTypeRelatedTo()' method is missing in the provided type checker.";
|
|
2529
2532
|
EventEmitter.dispatch(["file:error", { diagnostics: [Diagnostic.error(text)], result: fileResult }]);
|
|
2530
2533
|
return;
|
|
2531
2534
|
}
|
|
@@ -2577,7 +2580,7 @@ class TSTyche {
|
|
|
2577
2580
|
#abortController = new AbortController();
|
|
2578
2581
|
#storeService;
|
|
2579
2582
|
#taskRunner;
|
|
2580
|
-
static version = "1.0.0-rc";
|
|
2583
|
+
static version = "1.0.0-rc.2";
|
|
2581
2584
|
constructor(resolvedConfig, storeService) {
|
|
2582
2585
|
this.resolvedConfig = resolvedConfig;
|
|
2583
2586
|
this.#storeService = storeService;
|
|
@@ -2588,12 +2591,11 @@ class TSTyche {
|
|
|
2588
2591
|
EventEmitter.addHandler(([eventName, payload]) => {
|
|
2589
2592
|
if (eventName.includes("error") || eventName.includes("fail")) {
|
|
2590
2593
|
if ("diagnostics" in payload
|
|
2591
|
-
&&
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
this.#abortController.abort();
|
|
2594
|
+
&& payload.diagnostics.some((diagnostic) => diagnostic.category === "error")) {
|
|
2595
|
+
process.exitCode = 1;
|
|
2596
|
+
if (this.resolvedConfig.failFast) {
|
|
2597
|
+
this.#abortController.abort();
|
|
2598
|
+
}
|
|
2597
2599
|
}
|
|
2598
2600
|
}
|
|
2599
2601
|
});
|
|
@@ -2628,12 +2630,6 @@ class OptionDefinitionsMap {
|
|
|
2628
2630
|
group: 2,
|
|
2629
2631
|
name: "config",
|
|
2630
2632
|
},
|
|
2631
|
-
{
|
|
2632
|
-
brand: "boolean",
|
|
2633
|
-
description: "Do not search for the test files.",
|
|
2634
|
-
group: 4,
|
|
2635
|
-
name: "disableTestFileLookup",
|
|
2636
|
-
},
|
|
2637
2633
|
{
|
|
2638
2634
|
brand: "boolean",
|
|
2639
2635
|
description: "Stop running tests after the first failed assertion.",
|
|
@@ -3114,7 +3110,6 @@ class ConfigService {
|
|
|
3114
3110
|
#commandLineOptions = {};
|
|
3115
3111
|
#configFileOptions = {};
|
|
3116
3112
|
static #defaultOptions = {
|
|
3117
|
-
disableTestFileLookup: false,
|
|
3118
3113
|
failFast: false,
|
|
3119
3114
|
rootPath: Path.resolve("./"),
|
|
3120
3115
|
target: [Environment.typescriptPath == null ? "latest" : "current"],
|
|
@@ -3535,10 +3530,14 @@ class StoreService {
|
|
|
3535
3530
|
const candidatePaths = [Path.join(Path.dirname(modulePath), "tsserverlibrary.js"), modulePath];
|
|
3536
3531
|
for (const candidatePath of candidatePaths) {
|
|
3537
3532
|
const sourceText = await fs.readFile(candidatePath, { encoding: "utf8" });
|
|
3538
|
-
|
|
3539
|
-
if (modifiedSourceText.length === sourceText.length) {
|
|
3533
|
+
if (!sourceText.includes("isTypeRelatedTo")) {
|
|
3540
3534
|
continue;
|
|
3541
3535
|
}
|
|
3536
|
+
const toExpose = [
|
|
3537
|
+
"isTypeRelatedTo",
|
|
3538
|
+
"relation: { assignable: assignableRelation, identity: identityRelation, subtype: strictSubtypeRelation }",
|
|
3539
|
+
];
|
|
3540
|
+
const modifiedSourceText = sourceText.replace("return checker;", `return { ...checker, ${toExpose.join(", ")} };`);
|
|
3542
3541
|
const compiledWrapper = vm.compileFunction(modifiedSourceText, ["exports", "require", "module", "__filename", "__dirname"], { filename: candidatePath });
|
|
3543
3542
|
compiledWrapper(exports, createRequire(candidatePath), module, candidatePath, Path.dirname(candidatePath));
|
|
3544
3543
|
break;
|
|
@@ -3595,7 +3594,6 @@ class StoreService {
|
|
|
3595
3594
|
}
|
|
3596
3595
|
|
|
3597
3596
|
class Cli {
|
|
3598
|
-
#abortController = new AbortController();
|
|
3599
3597
|
#logger;
|
|
3600
3598
|
#storeService;
|
|
3601
3599
|
constructor() {
|
|
@@ -3612,7 +3610,6 @@ class Cli {
|
|
|
3612
3610
|
for (const diagnostic of payload.diagnostics) {
|
|
3613
3611
|
switch (diagnostic.category) {
|
|
3614
3612
|
case "error":
|
|
3615
|
-
this.#abortController.abort();
|
|
3616
3613
|
process.exitCode = 1;
|
|
3617
3614
|
this.#logger.writeError(diagnosticText(diagnostic));
|
|
3618
3615
|
break;
|
|
@@ -3640,10 +3637,10 @@ class Cli {
|
|
|
3640
3637
|
return;
|
|
3641
3638
|
}
|
|
3642
3639
|
if (commandLineArguments.includes("--update")) {
|
|
3643
|
-
await this.#storeService.update(
|
|
3640
|
+
await this.#storeService.update();
|
|
3644
3641
|
return;
|
|
3645
3642
|
}
|
|
3646
|
-
const compiler = await this.#storeService.load(Environment.typescriptPath == null ? "latest" : "current"
|
|
3643
|
+
const compiler = await this.#storeService.load(Environment.typescriptPath == null ? "latest" : "current");
|
|
3647
3644
|
if (!compiler) {
|
|
3648
3645
|
return;
|
|
3649
3646
|
}
|
|
@@ -3670,12 +3667,12 @@ class Cli {
|
|
|
3670
3667
|
}
|
|
3671
3668
|
if (configService.commandLineOptions.install === true) {
|
|
3672
3669
|
for (const tag of resolvedConfig.target) {
|
|
3673
|
-
await this.#storeService.install(tag
|
|
3670
|
+
await this.#storeService.install(tag);
|
|
3674
3671
|
}
|
|
3675
3672
|
return;
|
|
3676
3673
|
}
|
|
3677
3674
|
let testFiles = [];
|
|
3678
|
-
if (
|
|
3675
|
+
if (resolvedConfig.testFileMatch.length !== 0) {
|
|
3679
3676
|
testFiles = configService.selectTestFiles();
|
|
3680
3677
|
if (testFiles.length === 0) {
|
|
3681
3678
|
return;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tstyche",
|
|
3
|
-
"version": "1.0.0-rc",
|
|
3
|
+
"version": "1.0.0-rc.2",
|
|
4
4
|
"description": "The Essential Type Testing Tool.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"typescript",
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
"type": "git",
|
|
18
18
|
"url": "git+https://github.com/tstyche/tstyche.git"
|
|
19
19
|
},
|
|
20
|
+
"funding": "https://github.com/tstyche/tstyche?sponsor=1",
|
|
20
21
|
"license": "MIT",
|
|
21
22
|
"type": "module",
|
|
22
23
|
"exports": {
|
|
@@ -37,15 +38,15 @@
|
|
|
37
38
|
"bench": "./benchmarks/tstyche.bench.sh",
|
|
38
39
|
"build": "rollup --config rollup.config.js",
|
|
39
40
|
"build:watch": "yarn build --sourcemap --watch",
|
|
40
|
-
"clean": "rm -rf build",
|
|
41
|
-
"generate": "yarn generate:schema && yarn generate:types",
|
|
42
|
-
"generate:schema": "node ./models/__scripts__/generate-schema.js",
|
|
43
|
-
"generate:types": "node ./models/__scripts__/generate-types.js",
|
|
44
41
|
"check": "yarn check:spelling && yarn check:formatting",
|
|
45
|
-
"check:spelling": "cspell --config cspell.config.json --quiet",
|
|
46
42
|
"check:formatting": "dprint check",
|
|
43
|
+
"check:spelling": "cspell --config cspell.config.json --quiet",
|
|
47
44
|
"check:types": "tsc --noEmit --project tsconfig.json",
|
|
45
|
+
"clean": "rm -rf build",
|
|
48
46
|
"format": "dprint fmt",
|
|
47
|
+
"generate": "yarn generate:schema && yarn generate:types",
|
|
48
|
+
"generate:schema": "node ./models/__scripts__/generate-schema.js",
|
|
49
|
+
"generate:types": "node ./models/__scripts__/generate-types.js",
|
|
49
50
|
"lint": "eslint ./ --config eslint.config.json --ext .js,.cts,.ts,.tsx",
|
|
50
51
|
"prepack": "yarn clean && yarn build",
|
|
51
52
|
"prepublish": "yarn test",
|
|
@@ -59,9 +60,9 @@
|
|
|
59
60
|
"devDependencies": {
|
|
60
61
|
"@jest/globals": "29.7.0",
|
|
61
62
|
"@rollup/plugin-typescript": "11.1.6",
|
|
62
|
-
"@types/node": "20.11.
|
|
63
|
-
"@typescript-eslint/eslint-plugin": "
|
|
64
|
-
"@typescript-eslint/parser": "
|
|
63
|
+
"@types/node": "20.11.17",
|
|
64
|
+
"@typescript-eslint/eslint-plugin": "7.0.1",
|
|
65
|
+
"@typescript-eslint/parser": "7.0.1",
|
|
65
66
|
"ajv": "8.12.0",
|
|
66
67
|
"c8": "9.1.0",
|
|
67
68
|
"cspell": "8.3.2",
|
|
@@ -69,13 +70,13 @@
|
|
|
69
70
|
"eslint": "8.56.0",
|
|
70
71
|
"eslint-import-resolver-typescript": "3.6.1",
|
|
71
72
|
"eslint-plugin-import": "2.29.1",
|
|
72
|
-
"eslint-plugin-jest": "27.
|
|
73
|
+
"eslint-plugin-jest": "27.8.0",
|
|
73
74
|
"eslint-plugin-jest-formatting": "3.1.0",
|
|
74
|
-
"eslint-plugin-simple-import-sort": "
|
|
75
|
+
"eslint-plugin-simple-import-sort": "12.0.0",
|
|
75
76
|
"jest": "29.7.0",
|
|
76
77
|
"jest-serializer-ansi-escapes": "2.0.1",
|
|
77
|
-
"magic-string": "0.30.
|
|
78
|
-
"rollup": "4.
|
|
78
|
+
"magic-string": "0.30.7",
|
|
79
|
+
"rollup": "4.10.0",
|
|
79
80
|
"rollup-plugin-dts": "6.1.0",
|
|
80
81
|
"ts-node": "10.9.2",
|
|
81
82
|
"tslib": "2.6.2",
|
|
@@ -89,7 +90,7 @@
|
|
|
89
90
|
"optional": true
|
|
90
91
|
}
|
|
91
92
|
},
|
|
92
|
-
"packageManager": "yarn@3.
|
|
93
|
+
"packageManager": "yarn@3.8.0",
|
|
93
94
|
"engines": {
|
|
94
95
|
"node": "^16.14 || 18.x || >=20.x"
|
|
95
96
|
}
|