tstyche 4.0.0-rc.1 → 4.0.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 CHANGED
@@ -5,7 +5,7 @@
5
5
  [![install-size][install-size-badge]][install-size-url]
6
6
  [![coverage][coverage-badge]][coverage-url]
7
7
 
8
- The Essential Type Testing Tool.
8
+ Everything You Need for Type Testing.
9
9
 
10
10
  ---
11
11
 
@@ -37,21 +37,29 @@ To organize, debug and plan tests TSTyche has:
37
37
 
38
38
  ## Assertions
39
39
 
40
- The assertions can be used to write type tests (like in the above example) or mixed in your functional tests:
40
+ The assertions can be used to write type tests (like in the above example) or mixed in your unit tests:
41
41
 
42
42
  ```ts
43
43
  import assert from "node:assert";
44
44
  import test from "node:test";
45
45
  import * as tstyche from "tstyche";
46
46
 
47
- function secondItem<T>(target: Array<T>): T | undefined {
48
- return target[1];
47
+ function toMilliseconds(value: number) {
48
+ if (typeof value === "number" && !Number.isNaN(value)) {
49
+ return value * 1000;
50
+ }
51
+
52
+ throw new Error("Not a number");
49
53
  }
50
54
 
51
- test("handles numbers", () => {
52
- assert.strictEqual(secondItem([1, 2, 3]), 2);
55
+ test("toMilliseconds", () => {
56
+ const sample = toMilliseconds(10);
57
+
58
+ assert.equal(sample, 10_000);
59
+ tstyche.expect(sample).type.toBe<number>();
53
60
 
54
- tstyche.expect(secondItem([1, 2, 3])).type.toBe<number | undefined>();
61
+ // Will pass as a type test and not throw at runtime
62
+ tstyche.expect(toMilliseconds).type.not.toBeCallableWith("20");
55
63
  });
56
64
  ```
57
65
 
@@ -40,6 +40,7 @@ declare class ConfigDiagnosticText {
40
40
  static requiresValueType(optionName: string, optionBrand: OptionBrand): string;
41
41
  static seen(element: string): string;
42
42
  static testFileMatchCannotStartWith(segment: string): Array<string>;
43
+ static unexpected(element: string): string;
43
44
  static unknownOption(optionName: string): string;
44
45
  static usage(optionName: string, optionBrand: OptionBrand): Array<string>;
45
46
  static versionIsNotSupported(value: string): string;
package/build/tstyche.js CHANGED
@@ -49,6 +49,9 @@ class ConfigDiagnosticText {
49
49
  "The test files are only collected within the 'rootPath' directory.",
50
50
  ];
51
51
  }
52
+ static unexpected(element) {
53
+ return `Unexpected ${element}.`;
54
+ }
52
55
  static unknownOption(optionName) {
53
56
  return `Unknown option '${optionName}'.`;
54
57
  }
@@ -1375,6 +1378,13 @@ class ConfigParser {
1375
1378
  related: [Diagnostic.error(relatedText, leftBraceToken.origin)],
1376
1379
  });
1377
1380
  this.#onDiagnostics(diagnostic);
1381
+ return;
1382
+ }
1383
+ const unexpectedToken = this.#jsonScanner.readToken(/\S/);
1384
+ if (unexpectedToken.text != null) {
1385
+ const text = ConfigDiagnosticText.unexpected("token");
1386
+ const diagnostic = Diagnostic.error(text, unexpectedToken.origin);
1387
+ this.#onDiagnostics(diagnostic);
1378
1388
  }
1379
1389
  }
1380
1390
  async parse() {
@@ -1474,9 +1484,10 @@ class JsonScanner {
1474
1484
  readToken(token) {
1475
1485
  this.#skipTrivia();
1476
1486
  this.#previousPosition = this.#position;
1477
- if (this.#peekCharacter() === token) {
1487
+ const character = this.#peekCharacter();
1488
+ if (typeof token === "string" ? token === character : token.test(character)) {
1478
1489
  this.#position++;
1479
- return new JsonNode(token, this.#getOrigin());
1490
+ return new JsonNode(character, this.#getOrigin());
1480
1491
  }
1481
1492
  return new JsonNode(undefined, this.#getOrigin());
1482
1493
  }
@@ -3037,7 +3048,8 @@ class AssertionNode extends TestTreeNode {
3037
3048
  this.target = this.matcherNode.typeArguments ?? this.matcherNode.arguments;
3038
3049
  }
3039
3050
  for (const diagnostic of parent.diagnostics) {
3040
- if (diagnosticBelongsToNode(diagnostic, this.source)) {
3051
+ if (diagnosticBelongsToNode(diagnostic, this.source) ||
3052
+ (this.target != null && diagnosticBelongsToNode(diagnostic, this.target))) {
3041
3053
  this.diagnostics.add(diagnostic);
3042
3054
  parent.diagnostics.delete(diagnostic);
3043
3055
  }
@@ -4894,7 +4906,7 @@ class TaskRunner {
4894
4906
  class Runner {
4895
4907
  #eventEmitter = new EventEmitter();
4896
4908
  #resolvedConfig;
4897
- static version = "4.0.0-rc.1";
4909
+ static version = "4.0.0";
4898
4910
  constructor(resolvedConfig) {
4899
4911
  this.#resolvedConfig = resolvedConfig;
4900
4912
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "tstyche",
3
- "version": "4.0.0-rc.1",
4
- "description": "The Essential Type Testing Tool.",
3
+ "version": "4.0.0",
4
+ "description": "Everything You Need for Type Testing.",
5
5
  "keywords": [
6
6
  "typescript",
7
7
  "types",