tstyche 1.0.0-beta.5 → 1.0.0-beta.6
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 +17 -6
- package/README.md +4 -3
- package/build/index.d.cts +4 -0
- package/build/index.d.ts +4 -0
- package/build/tstyche.js +51 -7
- package/package.json +8 -8
package/CHANGELOG.md
CHANGED
|
@@ -1,19 +1,29 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.0.0-beta.6] - 2023-12-03
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- **New!** Add `.toHaveProperty()` matcher ([#36](https://github.com/tstyche/tstyche/pull/36))
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- Accept template literals as arguments of the `.toRaiseError()` matcher ([#38](https://github.com/tstyche/tstyche/pull/38))
|
|
12
|
+
|
|
3
13
|
## [1.0.0-beta.5] - 2023-11-27
|
|
4
14
|
|
|
5
15
|
### Changed
|
|
6
16
|
|
|
7
|
-
- **Breaking
|
|
17
|
+
- **Breaking!** Move retry logic to the `Lock` class ([#31](https://github.com/tstyche/tstyche/pull/31))
|
|
8
18
|
- Bring back support for Node.js 16 ([#28](https://github.com/tstyche/tstyche/pull/28), [#27](https://github.com/tstyche/tstyche/pull/27))
|
|
9
19
|
|
|
10
20
|
### Added
|
|
11
21
|
|
|
12
|
-
- Add support for the `current` target tag ([#33](https://github.com/tstyche/tstyche/pull/33))
|
|
22
|
+
- **New!** Add support for the `current` target tag ([#33](https://github.com/tstyche/tstyche/pull/33))
|
|
13
23
|
|
|
14
24
|
### Fixed
|
|
15
25
|
|
|
16
|
-
- Allow `.raiseError()` to take template literals as arguments
|
|
26
|
+
- Allow `.raiseError()` to take template literals as arguments ([#35](https://github.com/tstyche/tstyche/pull/35))
|
|
17
27
|
|
|
18
28
|
## [1.0.0-beta.4] - 2023-11-24
|
|
19
29
|
|
|
@@ -23,9 +33,9 @@
|
|
|
23
33
|
|
|
24
34
|
### Removed
|
|
25
35
|
|
|
26
|
-
- **Breaking
|
|
27
|
-
- **Breaking
|
|
28
|
-
- **Breaking
|
|
36
|
+
- **Breaking!** Remove the `context()` helper ([#24](https://github.com/tstyche/tstyche/pull/24))
|
|
37
|
+
- **Breaking!** Drop support for Node.js 16 ([#22](https://github.com/tstyche/tstyche/pull/22))
|
|
38
|
+
- **Breaking!** Rename methods of the `StoreService` class ([`5d74201`](https://github.com/tstyche/tstyche/commit/5d74201))
|
|
29
39
|
|
|
30
40
|
### Fixed
|
|
31
41
|
|
|
@@ -55,6 +65,7 @@
|
|
|
55
65
|
|
|
56
66
|
_First pre-release._
|
|
57
67
|
|
|
68
|
+
[1.0.0-beta.6]: https://github.com/tstyche/tstyche/releases/tag/v1.0.0-beta.6
|
|
58
69
|
[1.0.0-beta.5]: https://github.com/tstyche/tstyche/releases/tag/v1.0.0-beta.5
|
|
59
70
|
[1.0.0-beta.4]: https://github.com/tstyche/tstyche/releases/tag/v1.0.0-beta.4
|
|
60
71
|
[1.0.0-beta.3]: https://github.com/tstyche/tstyche/releases/tag/v1.0.0-beta.3
|
package/README.md
CHANGED
|
@@ -56,9 +56,10 @@ test("handles numbers", () => {
|
|
|
56
56
|
|
|
57
57
|
Here is the list of all matchers:
|
|
58
58
|
|
|
59
|
-
- `.toBeAssignable()`, `.toEqual()`, `.toMatch()` compares types or types of expression
|
|
60
|
-
- `.
|
|
61
|
-
- `.
|
|
59
|
+
- `.toBeAssignable()`, `.toEqual()`, `.toMatch()` compares types or types of expression,
|
|
60
|
+
- `.toHaveProperty()` looks up keys on an object type,
|
|
61
|
+
- `.toRaiseError()` captures the type error message or code,
|
|
62
|
+
- `.toBeString()`, `.toBeNumber()`, `.toBeVoid()` and 9 more shorthand checks for primitive types.
|
|
62
63
|
|
|
63
64
|
## Runner
|
|
64
65
|
|
package/build/index.d.cts
CHANGED
|
@@ -133,6 +133,10 @@ interface Matchers {
|
|
|
133
133
|
*/
|
|
134
134
|
(target: unknown): void;
|
|
135
135
|
};
|
|
136
|
+
/**
|
|
137
|
+
* Checks if a property key exists on the source type.
|
|
138
|
+
*/
|
|
139
|
+
toHaveProperty: (key: string | number | symbol) => void;
|
|
136
140
|
/**
|
|
137
141
|
* Checks if the target type is a subtype the source type.
|
|
138
142
|
*/
|
package/build/index.d.ts
CHANGED
|
@@ -133,6 +133,10 @@ interface Matchers {
|
|
|
133
133
|
*/
|
|
134
134
|
(target: unknown): void;
|
|
135
135
|
};
|
|
136
|
+
/**
|
|
137
|
+
* Checks if a property key exists on the source type.
|
|
138
|
+
*/
|
|
139
|
+
toHaveProperty: (key: string | number | symbol) => void;
|
|
136
140
|
/**
|
|
137
141
|
* Checks if the target type is a subtype the source type.
|
|
138
142
|
*/
|
package/build/tstyche.js
CHANGED
|
@@ -1511,6 +1511,7 @@ class CollectService {
|
|
|
1511
1511
|
"toBeUnknown",
|
|
1512
1512
|
"toBeVoid",
|
|
1513
1513
|
"toEqual",
|
|
1514
|
+
"toHaveProperty",
|
|
1514
1515
|
"toMatch",
|
|
1515
1516
|
"toRaiseError",
|
|
1516
1517
|
];
|
|
@@ -1682,10 +1683,12 @@ class Checker {
|
|
|
1682
1683
|
#assertNonNullishTypeChecker(assertion) {
|
|
1683
1684
|
this.#assertNonNullish(assertion.typeChecker, "The 'typeChecker' was not provided.");
|
|
1684
1685
|
}
|
|
1686
|
+
#assertStringsOrNumber(expression) {
|
|
1687
|
+
return (expression != null &&
|
|
1688
|
+
(this.compiler.isStringLiteralLike(expression) || this.compiler.isNumericLiteral(expression)));
|
|
1689
|
+
}
|
|
1685
1690
|
#assertStringsOrNumbers(nodes) {
|
|
1686
|
-
return nodes.every((expression) => this
|
|
1687
|
-
this.compiler.isNumericLiteral(expression) ||
|
|
1688
|
-
this.compiler.isNoSubstitutionTemplateLiteral(expression));
|
|
1691
|
+
return nodes.every((expression) => this.#assertStringsOrNumber(expression));
|
|
1689
1692
|
}
|
|
1690
1693
|
explain(assertion) {
|
|
1691
1694
|
this.#assertNonNullishTypeChecker(assertion);
|
|
@@ -1743,6 +1746,26 @@ class Checker {
|
|
|
1743
1746
|
: `Type '${targetTypeText}' is not identical to type '${sourceTypeText}'.`, origin),
|
|
1744
1747
|
];
|
|
1745
1748
|
}
|
|
1749
|
+
case "toHaveProperty": {
|
|
1750
|
+
this.#assertNonNullishSourceType(assertion);
|
|
1751
|
+
this.#assertNonNullishTargetType(assertion);
|
|
1752
|
+
const sourceText = assertion.typeChecker.typeToString(assertion.sourceType.type);
|
|
1753
|
+
let targetArgumentText;
|
|
1754
|
+
if (assertion.targetType.type.flags & this.compiler.TypeFlags.StringOrNumberLiteral) {
|
|
1755
|
+
targetArgumentText = String(assertion.targetType.type.value);
|
|
1756
|
+
}
|
|
1757
|
+
else if (assertion.targetType.type.flags & this.compiler.TypeFlags.UniqueESSymbol) {
|
|
1758
|
+
targetArgumentText = `[${this.compiler.unescapeLeadingUnderscores(assertion.targetType.type.symbol.escapedName)}]`;
|
|
1759
|
+
}
|
|
1760
|
+
else {
|
|
1761
|
+
throw new Error("An argument for 'key' must be of type 'string | number | symbol'.");
|
|
1762
|
+
}
|
|
1763
|
+
return [
|
|
1764
|
+
Diagnostic.error(assertion.isNot
|
|
1765
|
+
? `Property '${targetArgumentText}' exists on type '${sourceText}'.`
|
|
1766
|
+
: `Property '${targetArgumentText}' does not exist on type '${sourceText}'.`, origin),
|
|
1767
|
+
];
|
|
1768
|
+
}
|
|
1746
1769
|
case "toMatch": {
|
|
1747
1770
|
this.#assertNonNullishSourceType(assertion);
|
|
1748
1771
|
this.#assertNonNullishTargetType(assertion);
|
|
@@ -1796,7 +1819,7 @@ class Checker {
|
|
|
1796
1819
|
}
|
|
1797
1820
|
const isMatch = this.#matchExpectedError(diagnostic, argument);
|
|
1798
1821
|
if (!assertion.isNot && !isMatch) {
|
|
1799
|
-
const expectedText = this.compiler.
|
|
1822
|
+
const expectedText = this.compiler.isStringLiteralLike(argument)
|
|
1800
1823
|
? `matching substring '${argument.text}'`
|
|
1801
1824
|
: `with code ${argument.text}`;
|
|
1802
1825
|
const related = [
|
|
@@ -1806,7 +1829,7 @@ class Checker {
|
|
|
1806
1829
|
diagnostics.push(Diagnostic.error(`${sourceText} did not raise a type error ${expectedText}.`, origin).add({ related }));
|
|
1807
1830
|
}
|
|
1808
1831
|
if (assertion.isNot && isMatch) {
|
|
1809
|
-
const expectedText = this.compiler.
|
|
1832
|
+
const expectedText = this.compiler.isStringLiteralLike(argument)
|
|
1810
1833
|
? `matching substring '${argument.text}'`
|
|
1811
1834
|
: `with code ${argument.text}`;
|
|
1812
1835
|
const related = [
|
|
@@ -1892,6 +1915,27 @@ class Checker {
|
|
|
1892
1915
|
this.#assertNonNullish(assertion.typeChecker?.isTypeIdenticalTo, "The 'isTypeIdenticalTo' method is missing in the provided type checker.");
|
|
1893
1916
|
return assertion.typeChecker.isTypeIdenticalTo(assertion.sourceType.type, assertion.targetType.type);
|
|
1894
1917
|
}
|
|
1918
|
+
case "toHaveProperty": {
|
|
1919
|
+
this.#assertNonNullishSourceType(assertion);
|
|
1920
|
+
this.#assertNonNullishTargetType(assertion);
|
|
1921
|
+
if (!(assertion.sourceType.type.flags & this.compiler.TypeFlags.StructuredType)) {
|
|
1922
|
+
const receivedText = assertion.typeChecker?.typeToString(assertion.sourceType.type);
|
|
1923
|
+
throw new Error(`An argument for 'source' must be of object type, received: '${receivedText}'.`);
|
|
1924
|
+
}
|
|
1925
|
+
let targetArgumentText;
|
|
1926
|
+
if (assertion.targetType.type.flags & this.compiler.TypeFlags.StringOrNumberLiteral) {
|
|
1927
|
+
targetArgumentText = String(assertion.targetType.type.value);
|
|
1928
|
+
}
|
|
1929
|
+
else if (assertion.targetType.type.flags & this.compiler.TypeFlags.UniqueESSymbol) {
|
|
1930
|
+
targetArgumentText = this.compiler.unescapeLeadingUnderscores(assertion.targetType.type.escapedName);
|
|
1931
|
+
}
|
|
1932
|
+
else {
|
|
1933
|
+
throw new Error("An argument for 'key' must be of type 'string | number | symbol'.");
|
|
1934
|
+
}
|
|
1935
|
+
return assertion.sourceType.type.getProperties().some((property) => {
|
|
1936
|
+
return this.compiler.unescapeLeadingUnderscores(property.escapedName) === targetArgumentText;
|
|
1937
|
+
});
|
|
1938
|
+
}
|
|
1895
1939
|
case "toMatch": {
|
|
1896
1940
|
this.#assertNonNullishSourceType(assertion);
|
|
1897
1941
|
this.#assertNonNullishTargetType(assertion);
|
|
@@ -1909,7 +1953,7 @@ class Checker {
|
|
|
1909
1953
|
return false;
|
|
1910
1954
|
}
|
|
1911
1955
|
return assertion.targetArguments.every((expectedArgument, index) => {
|
|
1912
|
-
if (this.compiler.
|
|
1956
|
+
if (this.compiler.isStringLiteralLike(expectedArgument)) {
|
|
1913
1957
|
return this.compiler
|
|
1914
1958
|
.flattenDiagnosticMessageText(assertion.diagnostics[index]?.messageText, " ", 0)
|
|
1915
1959
|
.includes(expectedArgument.text);
|
|
@@ -1925,7 +1969,7 @@ class Checker {
|
|
|
1925
1969
|
}
|
|
1926
1970
|
}
|
|
1927
1971
|
#matchExpectedError(diagnostic, argument) {
|
|
1928
|
-
if (this.compiler.
|
|
1972
|
+
if (this.compiler.isStringLiteralLike(argument)) {
|
|
1929
1973
|
return this.compiler.flattenDiagnosticMessageText(diagnostic.messageText, " ", 0).includes(argument.text);
|
|
1930
1974
|
}
|
|
1931
1975
|
if (this.compiler.isNumericLiteral(argument)) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tstyche",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.6",
|
|
4
4
|
"description": "The Essential Type Testing Tool.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"typescript",
|
|
@@ -57,14 +57,14 @@
|
|
|
57
57
|
"devDependencies": {
|
|
58
58
|
"@jest/globals": "29.7.0",
|
|
59
59
|
"@rollup/plugin-typescript": "11.1.5",
|
|
60
|
-
"@types/node": "20.10.
|
|
61
|
-
"@typescript-eslint/eslint-plugin": "6.
|
|
62
|
-
"@typescript-eslint/parser": "6.
|
|
60
|
+
"@types/node": "20.10.2",
|
|
61
|
+
"@typescript-eslint/eslint-plugin": "6.13.1",
|
|
62
|
+
"@typescript-eslint/parser": "6.13.1",
|
|
63
63
|
"ajv": "8.12.0",
|
|
64
64
|
"c8": "8.0.1",
|
|
65
|
-
"cspell": "8.
|
|
66
|
-
"eslint": "8.
|
|
67
|
-
"eslint-config-prettier": "9.
|
|
65
|
+
"cspell": "8.1.0",
|
|
66
|
+
"eslint": "8.55.0",
|
|
67
|
+
"eslint-config-prettier": "9.1.0",
|
|
68
68
|
"eslint-import-resolver-typescript": "3.6.1",
|
|
69
69
|
"eslint-plugin-import": "2.29.0",
|
|
70
70
|
"eslint-plugin-jest": "27.6.0",
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
"jest-serializer-ansi-escapes": "2.0.1",
|
|
77
77
|
"magic-string": "0.30.5",
|
|
78
78
|
"prettier": "3.1.0",
|
|
79
|
-
"rollup": "4.6.
|
|
79
|
+
"rollup": "4.6.1",
|
|
80
80
|
"rollup-plugin-dts": "6.1.0",
|
|
81
81
|
"rollup-plugin-tsconfig-paths": "1.5.2",
|
|
82
82
|
"ts-node": "10.9.1",
|