tstyche 6.0.0-rc.0 → 6.0.1
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 +27 -24
- package/dist/tstyche.js +15 -22
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@ TSTyche is a type testing tool for TypeScript. It ships with `describe()` and `t
|
|
|
13
13
|
|
|
14
14
|
## Helpers
|
|
15
15
|
|
|
16
|
-
If you are used to
|
|
16
|
+
If you are used to testing, a type test should look familiar:
|
|
17
17
|
|
|
18
18
|
```ts
|
|
19
19
|
import { expect, test } from "tstyche";
|
|
@@ -30,42 +30,33 @@ test("isSameLength", () => {
|
|
|
30
30
|
});
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
-
To
|
|
33
|
+
To group and organize tests, TSTyche has:
|
|
34
34
|
|
|
35
35
|
- `test()`, `it()` and `describe()` helpers,
|
|
36
36
|
- with `.only`, `.skip` and `.todo` run mode flags.
|
|
37
37
|
|
|
38
38
|
## Assertions
|
|
39
39
|
|
|
40
|
-
The assertions can
|
|
40
|
+
The `expect` style assertions can check either the inferred type of an expression (as in the example above) or a type directly:
|
|
41
41
|
|
|
42
42
|
```ts
|
|
43
|
-
import
|
|
44
|
-
import test from "node:test";
|
|
45
|
-
import * as tstyche from "tstyche";
|
|
43
|
+
import { expect } from "tstyche";
|
|
46
44
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
45
|
+
type AsyncProps<T> = {
|
|
46
|
+
[K in keyof T]+?: T[K] | Promise<T[K]>;
|
|
47
|
+
};
|
|
51
48
|
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
test("toMilliseconds", () => {
|
|
56
|
-
const sample = toMilliseconds(10);
|
|
49
|
+
type WithLoading<T> = T & { loading: boolean };
|
|
57
50
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
tstyche.expect(toMilliseconds).type.not.toBeCallableWith("20");
|
|
63
|
-
});
|
|
51
|
+
expect<WithLoading<AsyncProps<{ query: string }>>>().type.toBe<{
|
|
52
|
+
query?: string | Promise<string>;
|
|
53
|
+
loading: boolean;
|
|
54
|
+
}>();
|
|
64
55
|
```
|
|
65
56
|
|
|
66
57
|
Here is the list of all matchers:
|
|
67
58
|
|
|
68
|
-
- `.toBe()`, `.toBeAssignableFrom()`, `.toBeAssignableTo()` compare types or
|
|
59
|
+
- `.toBe()`, `.toBeAssignableFrom()`, `.toBeAssignableTo()` compare types or type of expressions,
|
|
69
60
|
- `.toAcceptProps()` checks the type of JSX component props,
|
|
70
61
|
- `.toBeApplicable` ensures that the decorator function can be applied,
|
|
71
62
|
- `.toBeCallableWith()` checks whether a function is callable with the given arguments,
|
|
@@ -74,13 +65,23 @@ Here is the list of all matchers:
|
|
|
74
65
|
|
|
75
66
|
## Runner
|
|
76
67
|
|
|
77
|
-
The `tstyche` command is the heart of TSTyche.
|
|
68
|
+
The `tstyche` command is the heart of TSTyche. It allows you to select test files by path, filter tests by name and run them against specific versions of TypeScript:
|
|
78
69
|
|
|
79
70
|
```shell
|
|
80
71
|
tstyche query-params --only multiple --target '>=5.6'
|
|
81
72
|
```
|
|
82
73
|
|
|
83
|
-
|
|
74
|
+
It is that simple! Actually, TSTyche does even more:
|
|
75
|
+
|
|
76
|
+
- checks messages of errors suppressed by `// @ts-expect-error`,
|
|
77
|
+
- generates type tests from a data table,
|
|
78
|
+
- runs tests in watch mode.
|
|
79
|
+
|
|
80
|
+
## Try It Out
|
|
81
|
+
|
|
82
|
+
Try TSTyche online on StackBlitz:
|
|
83
|
+
|
|
84
|
+
[![Open in StackBlitz][starter-badge]][starter-url]
|
|
84
85
|
|
|
85
86
|
## Documentation
|
|
86
87
|
|
|
@@ -98,3 +99,5 @@ Visit [tstyche.org](https://tstyche.org) to view the full documentation.
|
|
|
98
99
|
[install-size-url]: https://packagephobia.com/result?p=tstyche
|
|
99
100
|
[coverage-badge]: https://badgen.net/codacy/coverage/a581ca5c323a455886b7bdd9623c4ec8
|
|
100
101
|
[coverage-url]: https://app.codacy.com/gh/tstyche/tstyche/coverage/dashboard
|
|
102
|
+
[starter-badge]: https://developer.stackblitz.com/img/open_in_stackblitz.svg
|
|
103
|
+
[starter-url]: https://tstyche.org/new
|
package/dist/tstyche.js
CHANGED
|
@@ -4550,9 +4550,9 @@ class ToAcceptProps {
|
|
|
4550
4550
|
}
|
|
4551
4551
|
}
|
|
4552
4552
|
|
|
4553
|
-
function
|
|
4553
|
+
function containsInstantiable(target, compiler) {
|
|
4554
4554
|
return ("types" in target &&
|
|
4555
|
-
target.types.some((type) => type.flags & compiler.TypeFlags.
|
|
4555
|
+
target.types.some((type) => type.flags & compiler.TypeFlags.Instantiable));
|
|
4556
4556
|
}
|
|
4557
4557
|
function getIndexSignatures(type, compiler, typeChecker) {
|
|
4558
4558
|
if (type.flags & compiler.TypeFlags.Intersection) {
|
|
@@ -4587,9 +4587,6 @@ function getTargetSymbol(symbol, compiler) {
|
|
|
4587
4587
|
function isCheckFlagSet(symbol, flag, compiler) {
|
|
4588
4588
|
return !!(symbol.flags & compiler.SymbolFlags.Transient && symbol.links.checkFlags & flag);
|
|
4589
4589
|
}
|
|
4590
|
-
function isSymbolFromDefaultLibrary(symbol, program) {
|
|
4591
|
-
return !!symbol.declarations?.every((declaration) => program.isSourceFileDefaultLibrary(declaration.getSourceFile()));
|
|
4592
|
-
}
|
|
4593
4590
|
|
|
4594
4591
|
function getParameterFactsFromTuple(type, position, compiler) {
|
|
4595
4592
|
return {
|
|
@@ -4677,13 +4674,11 @@ class SeenService {
|
|
|
4677
4674
|
class Structure {
|
|
4678
4675
|
#compiler;
|
|
4679
4676
|
#compilerOptions;
|
|
4680
|
-
#program;
|
|
4681
4677
|
#seen = new SeenService();
|
|
4682
4678
|
#typeChecker;
|
|
4683
4679
|
constructor(compiler, program) {
|
|
4684
4680
|
this.#compiler = compiler;
|
|
4685
4681
|
this.#compilerOptions = program.getCompilerOptions();
|
|
4686
|
-
this.#program = program;
|
|
4687
4682
|
this.#typeChecker = program.getTypeChecker();
|
|
4688
4683
|
}
|
|
4689
4684
|
#compareMaybeNullish(a, b) {
|
|
@@ -4713,7 +4708,7 @@ class Structure {
|
|
|
4713
4708
|
return true;
|
|
4714
4709
|
}
|
|
4715
4710
|
}
|
|
4716
|
-
if (
|
|
4711
|
+
if (containsInstantiable(a, this.#compiler) || containsInstantiable(b, this.#compiler)) {
|
|
4717
4712
|
return false;
|
|
4718
4713
|
}
|
|
4719
4714
|
if ((a.flags & b.flags) | this.#compiler.TypeFlags.StructuredType) {
|
|
@@ -4791,9 +4786,8 @@ class Structure {
|
|
|
4791
4786
|
}
|
|
4792
4787
|
compareObjects(a, b) {
|
|
4793
4788
|
if (a.objectFlags & b.objectFlags & this.#compiler.ObjectFlags.Reference) {
|
|
4794
|
-
|
|
4795
|
-
|
|
4796
|
-
return isSame;
|
|
4789
|
+
if (!((a.objectFlags | b.objectFlags) & this.#compiler.ObjectFlags.ClassOrInterface)) {
|
|
4790
|
+
return this.compareTypeReferences(a, b);
|
|
4797
4791
|
}
|
|
4798
4792
|
}
|
|
4799
4793
|
return this.compareStructuredTypes(a, b);
|
|
@@ -4805,21 +4799,20 @@ class Structure {
|
|
|
4805
4799
|
}
|
|
4806
4800
|
return false;
|
|
4807
4801
|
}
|
|
4808
|
-
if ((a.
|
|
4802
|
+
if (!this.compare(a.target, b.target)) {
|
|
4809
4803
|
return this.compareStructuredTypes(a, b);
|
|
4810
4804
|
}
|
|
4811
|
-
if (a.symbol !== b.symbol) {
|
|
4812
|
-
if (isSymbolFromDefaultLibrary(a.symbol, this.#program) || isSymbolFromDefaultLibrary(b.symbol, this.#program)) {
|
|
4813
|
-
return false;
|
|
4814
|
-
}
|
|
4815
|
-
return;
|
|
4816
|
-
}
|
|
4817
4805
|
const aTypeArguments = this.#typeChecker.getTypeArguments(a);
|
|
4818
4806
|
const bTypeArguments = this.#typeChecker.getTypeArguments(b);
|
|
4819
4807
|
if (aTypeArguments.length !== bTypeArguments.length) {
|
|
4820
4808
|
return false;
|
|
4821
4809
|
}
|
|
4822
|
-
|
|
4810
|
+
for (let i = 0; i < aTypeArguments.length; i++) {
|
|
4811
|
+
if (!this.compare(aTypeArguments[i], bTypeArguments[i])) {
|
|
4812
|
+
return false;
|
|
4813
|
+
}
|
|
4814
|
+
}
|
|
4815
|
+
return true;
|
|
4823
4816
|
}
|
|
4824
4817
|
compareTuples(a, b) {
|
|
4825
4818
|
if (a.target.readonly !== b.target.readonly) {
|
|
@@ -5049,8 +5042,8 @@ class Structure {
|
|
|
5049
5042
|
return type.regularType;
|
|
5050
5043
|
}
|
|
5051
5044
|
if (type.flags & this.#compiler.TypeFlags.UnionOrIntersection) {
|
|
5052
|
-
const candidateType =
|
|
5053
|
-
if (type.types.every((t) => this.compare(
|
|
5045
|
+
const candidateType = type.types[0];
|
|
5046
|
+
if (type.types.every((t) => this.compare(t, candidateType))) {
|
|
5054
5047
|
return candidateType;
|
|
5055
5048
|
}
|
|
5056
5049
|
}
|
|
@@ -5912,7 +5905,7 @@ class FileRunner {
|
|
|
5912
5905
|
class Runner {
|
|
5913
5906
|
#eventEmitter = new EventEmitter();
|
|
5914
5907
|
#resolvedConfig;
|
|
5915
|
-
static version = "6.0.
|
|
5908
|
+
static version = "6.0.1";
|
|
5916
5909
|
constructor(resolvedConfig) {
|
|
5917
5910
|
this.#resolvedConfig = resolvedConfig;
|
|
5918
5911
|
}
|