tstyche 1.0.0-rc.1 → 1.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/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.0.0] - 2024-02-20
4
+
5
+ _Stable release based on [1.0.0-rc.2]._
6
+
7
+ ## [1.0.0-rc.2] - 2024-02-14
8
+
9
+ ### Fixed
10
+
11
+ - 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))
12
+
3
13
  ## [1.0.0-rc.1] - 2024-02-10
4
14
 
5
15
  ### Changed
@@ -130,6 +140,8 @@
130
140
 
131
141
  _First pre-release._
132
142
 
143
+ [1.0.0]: https://github.com/tstyche/tstyche/releases/tag/v1.0.0
144
+ [1.0.0-rc.2]: https://github.com/tstyche/tstyche/releases/tag/v1.0.0-rc.2
133
145
  [1.0.0-rc.1]: https://github.com/tstyche/tstyche/releases/tag/v1.0.0-rc.1
134
146
  [1.0.0-rc]: https://github.com/tstyche/tstyche/releases/tag/v1.0.0-rc
135
147
  [1.0.0-beta.9]: https://github.com/tstyche/tstyche/releases/tag/v1.0.0-beta.9
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
@@ -87,3 +92,5 @@ Visit [https://tstyche.org](https://tstyche.org) to view the full documentation.
87
92
  [packagephobia-url]: https://packagephobia.com/result?p=tstyche
88
93
  [coverage-badge]: https://badgen.net/codacy/coverage/a581ca5c323a455886b7bdd9623c4ec8
89
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
@@ -51,7 +51,6 @@ declare enum OptionBrand {
51
51
  True = "true",// an option which does not take a value
52
52
  List = "list"
53
53
  }
54
-
55
54
  declare enum OptionGroup {
56
55
  CommandLine = 2,
57
56
  ConfigFile = 4
@@ -179,7 +178,7 @@ declare class ConfigService {
179
178
  declare class TSTyche {
180
179
  #private;
181
180
  readonly resolvedConfig: ResolvedConfig;
182
- static readonly version = "__version__";
181
+ static readonly version = "1.0.0";
183
182
  constructor(resolvedConfig: ResolvedConfig, storeService: StoreService);
184
183
  run(testFiles: Array<string | URL>): Promise<void>;
185
184
  }
@@ -195,7 +194,6 @@ declare enum TestMemberBrand {
195
194
  Test = "test",
196
195
  Expect = "expect"
197
196
  }
198
-
199
197
  declare enum TestMemberFlags {
200
198
  None = 0,
201
199
  Fail = 1,
@@ -282,7 +280,6 @@ declare class ResultTiming {
282
280
  get duration(): number;
283
281
  }
284
282
 
285
- type FileResultStatus = ResultStatus.Runs | ResultStatus.Passed | ResultStatus.Failed;
286
283
  declare enum ResultStatus {
287
284
  Runs = "runs",
288
285
  Passed = "passed",
@@ -327,6 +324,7 @@ declare class DescribeResult {
327
324
  constructor(describe: TestMember, parent: DescribeResult | undefined);
328
325
  }
329
326
 
327
+ type FileResultStatus = ResultStatus.Runs | ResultStatus.Passed | ResultStatus.Failed;
330
328
  declare class FileResult {
331
329
  testFile: URL;
332
330
  diagnostics: Array<Diagnostic>;
@@ -346,11 +344,12 @@ declare class ProjectResult {
346
344
  constructor(compilerVersion: string, projectConfigFilePath: string | undefined);
347
345
  }
348
346
 
347
+ type TargetResultStatus = ResultStatus.Runs | ResultStatus.Passed | ResultStatus.Failed;
349
348
  declare class TargetResult {
350
349
  versionTag: string;
351
350
  testFiles: Array<URL>;
352
351
  results: Map<string | undefined, ProjectResult>;
353
- status: ResultStatus.Runs | ResultStatus.Passed | ResultStatus.Failed;
352
+ status: TargetResultStatus;
354
353
  timing: ResultTiming;
355
354
  constructor(versionTag: string, testFiles: Array<URL>);
356
355
  }
@@ -441,33 +440,43 @@ interface MatchResult {
441
440
  explain: () => Array<Diagnostic>;
442
441
  isMatch: boolean;
443
442
  }
443
+ type Relation = Map<string, unknown>;
444
444
  interface TypeChecker extends ts.TypeChecker {
445
- isTypeAssignableTo: (source: ts.Type, target: ts.Type) => boolean;
446
- isTypeIdenticalTo: (source: ts.Type, target: ts.Type) => boolean;
447
- isTypeSubtypeOf: (source: ts.Type, target: ts.Type) => boolean;
445
+ isTypeRelatedTo: (source: ts.Type, target: ts.Type, relation: Relation) => boolean;
446
+ relation: {
447
+ assignable: Relation;
448
+ identity: Relation;
449
+ subtype: Relation;
450
+ };
448
451
  }
449
452
 
450
453
  declare class PrimitiveTypeMatcher {
451
454
  #private;
452
455
  typeChecker: TypeChecker;
453
- constructor(typeChecker: TypeChecker, targetTypeFlag: ts.TypeFlags, targetTypeText: string);
454
- match(sourceType: ts.Type, isNot: boolean): MatchResult;
456
+ constructor(typeChecker: TypeChecker, targetTypeFlag: ts.TypeFlags);
457
+ match(sourceType: ts.Type): MatchResult;
455
458
  }
456
459
 
457
- declare class ToBeAssignable {
458
- #private;
460
+ declare abstract class RelationMatcherBase {
459
461
  typeChecker: TypeChecker;
462
+ abstract relation: Relation;
463
+ abstract relationExplanationText: string;
460
464
  constructor(typeChecker: TypeChecker);
465
+ protected explain(sourceType: ts.Type, targetType: ts.Type, isNot: boolean): Array<Diagnostic>;
461
466
  match(sourceType: ts.Type, targetType: ts.Type, isNot: boolean): MatchResult;
462
467
  }
463
468
 
464
- declare class ToEqual {
465
- #private;
466
- typeChecker: TypeChecker;
467
- constructor(typeChecker: TypeChecker);
469
+ declare class ToBeAssignable extends RelationMatcherBase {
470
+ relation: Relation;
471
+ relationExplanationText: string;
468
472
  match(sourceType: ts.Type, targetType: ts.Type, isNot: boolean): MatchResult;
469
473
  }
470
474
 
475
+ declare class ToEqual extends RelationMatcherBase {
476
+ relation: Relation;
477
+ relationExplanationText: string;
478
+ }
479
+
471
480
  declare class ToHaveProperty {
472
481
  #private;
473
482
  compiler: typeof ts;
@@ -476,11 +485,9 @@ declare class ToHaveProperty {
476
485
  match(sourceType: ts.Type, targetType: ts.StringLiteralType | ts.NumberLiteralType | ts.UniqueESSymbolType, isNot: boolean): MatchResult;
477
486
  }
478
487
 
479
- declare class ToMatch {
480
- #private;
481
- typeChecker: TypeChecker;
482
- constructor(typeChecker: TypeChecker);
483
- match(sourceType: ts.Type, targetType: ts.Type, isNot: boolean): MatchResult;
488
+ declare class ToMatch extends RelationMatcherBase {
489
+ relation: Relation;
490
+ relationExplanationText: string;
484
491
  }
485
492
 
486
493
  declare class ToRaiseError {
@@ -742,4 +749,4 @@ declare class Version {
742
749
  static isVersionTag(target: string): boolean;
743
750
  }
744
751
 
745
- export { Assertion, Cli, CollectService, Color, type CommandLineOptions, type ConfigFileOptions, ConfigService, DescribeResult, Diagnostic, DiagnosticCategory, type DiagnosticOrigin, Environment, type Event, EventEmitter, type EventHandler, Expect, ExpectResult, FileResult, type FileResultStatus, type ItemDefinition, Line, Logger, type LoggerOptions, type MatchResult, OptionBrand, type OptionDefinition, OptionDefinitionsMap, OptionGroup, Path, ProjectResult, ProjectService, Reporter, type ResolvedConfig, Result, ResultCount, ResultManager, ResultStatus, ResultTiming, Scribbler, type ScribblerOptions, StoreService, SummaryReporter, TSTyche, TargetResult, TaskRunner, TestMember, TestMemberBrand, TestMemberFlags, TestResult, TestTree, Text, ThoroughReporter, type TypeChecker, Version, type WriteStream, addsPackageStepText, describeNameText, diagnosticText, fileStatusText, fileViewText, formattedText, helpText, summaryText, testNameText, usesCompilerStepText };
752
+ export { Assertion, Cli, CollectService, Color, type CommandLineOptions, type ConfigFileOptions, ConfigService, DescribeResult, Diagnostic, DiagnosticCategory, type DiagnosticOrigin, Environment, type Event, EventEmitter, type EventHandler, Expect, ExpectResult, FileResult, type FileResultStatus, type ItemDefinition, Line, Logger, type LoggerOptions, type MatchResult, OptionBrand, type OptionDefinition, OptionDefinitionsMap, OptionGroup, Path, ProjectResult, ProjectService, Reporter, type ResolvedConfig, Result, ResultCount, ResultManager, ResultStatus, ResultTiming, Scribbler, type ScribblerOptions, StoreService, SummaryReporter, TSTyche, TargetResult, type TargetResultStatus, TaskRunner, TestMember, TestMemberBrand, TestMemberFlags, TestResult, TestTree, Text, ThoroughReporter, type TypeChecker, Version, type WriteStream, addsPackageStepText, describeNameText, diagnosticText, fileStatusText, fileViewText, formattedText, helpText, summaryText, testNameText, usesCompilerStepText };
package/build/tstyche.js CHANGED
@@ -999,6 +999,15 @@ class DescribeResult {
999
999
  }
1000
1000
  }
1001
1001
 
1002
+ var ResultStatus;
1003
+ (function (ResultStatus) {
1004
+ ResultStatus["Runs"] = "runs";
1005
+ ResultStatus["Passed"] = "passed";
1006
+ ResultStatus["Failed"] = "failed";
1007
+ ResultStatus["Skipped"] = "skipped";
1008
+ ResultStatus["Todo"] = "todo";
1009
+ })(ResultStatus || (ResultStatus = {}));
1010
+
1002
1011
  class ExpectResult {
1003
1012
  assertion;
1004
1013
  parent;
@@ -1254,15 +1263,6 @@ class ResultManager {
1254
1263
  }
1255
1264
  }
1256
1265
 
1257
- var ResultStatus;
1258
- (function (ResultStatus) {
1259
- ResultStatus["Runs"] = "runs";
1260
- ResultStatus["Passed"] = "passed";
1261
- ResultStatus["Failed"] = "failed";
1262
- ResultStatus["Skipped"] = "skipped";
1263
- ResultStatus["Todo"] = "todo";
1264
- })(ResultStatus || (ResultStatus = {}));
1265
-
1266
1266
  class TargetResult {
1267
1267
  versionTag;
1268
1268
  testFiles;
@@ -1695,7 +1695,6 @@ var TestMemberBrand;
1695
1695
  TestMemberBrand["Test"] = "test";
1696
1696
  TestMemberBrand["Expect"] = "expect";
1697
1697
  })(TestMemberBrand || (TestMemberBrand = {}));
1698
-
1699
1698
  var TestMemberFlags;
1700
1699
  (function (TestMemberFlags) {
1701
1700
  TestMemberFlags[TestMemberFlags["None"] = 0] = "None";
@@ -1708,69 +1707,61 @@ var TestMemberFlags;
1708
1707
  class PrimitiveTypeMatcher {
1709
1708
  typeChecker;
1710
1709
  #targetTypeFlag;
1711
- #targetTypeText;
1712
- constructor(typeChecker, targetTypeFlag, targetTypeText) {
1710
+ constructor(typeChecker, targetTypeFlag) {
1713
1711
  this.typeChecker = typeChecker;
1714
1712
  this.#targetTypeFlag = targetTypeFlag;
1715
- this.#targetTypeText = targetTypeText;
1716
1713
  }
1717
- #explain(sourceType, isNot) {
1714
+ #explain(sourceType) {
1718
1715
  const sourceTypeText = this.typeChecker.typeToString(sourceType);
1719
- return isNot
1720
- ? [Diagnostic.error(`Type '${this.#targetTypeText}' is identical to type '${sourceTypeText}'.`)]
1721
- : [Diagnostic.error(`Type '${this.#targetTypeText}' is not identical to type '${sourceTypeText}'.`)];
1716
+ return [Diagnostic.error(`The source type is '${sourceTypeText}'.`)];
1722
1717
  }
1723
- match(sourceType, isNot) {
1718
+ match(sourceType) {
1724
1719
  const isMatch = Boolean(sourceType.flags & this.#targetTypeFlag);
1725
1720
  return {
1726
- explain: () => this.#explain(sourceType, isNot),
1721
+ explain: () => this.#explain(sourceType),
1727
1722
  isMatch,
1728
1723
  };
1729
1724
  }
1730
1725
  }
1731
1726
 
1732
- class ToBeAssignable {
1727
+ class RelationMatcherBase {
1733
1728
  typeChecker;
1734
1729
  constructor(typeChecker) {
1735
1730
  this.typeChecker = typeChecker;
1736
1731
  }
1737
- #explain(sourceType, targetType, isNot) {
1732
+ explain(sourceType, targetType, isNot) {
1738
1733
  const sourceTypeText = this.typeChecker.typeToString(sourceType);
1739
1734
  const targetTypeText = this.typeChecker.typeToString(targetType);
1740
1735
  return isNot
1741
- ? [Diagnostic.error(`Type '${targetTypeText}' is assignable to type '${sourceTypeText}'.`)]
1742
- : [Diagnostic.error(`Type '${targetTypeText}' is not assignable to type '${sourceTypeText}'.`)];
1736
+ ? [Diagnostic.error(`Type '${targetTypeText}' is ${this.relationExplanationText} type '${sourceTypeText}'.`)]
1737
+ : [Diagnostic.error(`Type '${targetTypeText}' is not ${this.relationExplanationText} type '${sourceTypeText}'.`)];
1743
1738
  }
1744
1739
  match(sourceType, targetType, isNot) {
1745
- const isMatch = this.typeChecker.isTypeAssignableTo(targetType, sourceType);
1740
+ const isMatch = this.typeChecker.isTypeRelatedTo(sourceType, targetType, this.relation);
1746
1741
  return {
1747
- explain: () => this.#explain(sourceType, targetType, isNot),
1742
+ explain: () => this.explain(sourceType, targetType, isNot),
1748
1743
  isMatch,
1749
1744
  };
1750
1745
  }
1751
1746
  }
1752
1747
 
1753
- class ToEqual {
1754
- typeChecker;
1755
- constructor(typeChecker) {
1756
- this.typeChecker = typeChecker;
1757
- }
1758
- #explain(sourceType, targetType, isNot) {
1759
- const sourceTypeText = this.typeChecker.typeToString(sourceType);
1760
- const targetTypeText = this.typeChecker.typeToString(targetType);
1761
- return isNot
1762
- ? [Diagnostic.error(`Type '${targetTypeText}' is identical to type '${sourceTypeText}'.`)]
1763
- : [Diagnostic.error(`Type '${targetTypeText}' is not identical to type '${sourceTypeText}'.`)];
1764
- }
1748
+ class ToBeAssignable extends RelationMatcherBase {
1749
+ relation = this.typeChecker.relation.assignable;
1750
+ relationExplanationText = "assignable to";
1765
1751
  match(sourceType, targetType, isNot) {
1766
- const isMatch = this.typeChecker.isTypeIdenticalTo(sourceType, targetType);
1752
+ const isMatch = this.typeChecker.isTypeRelatedTo(targetType, sourceType, this.relation);
1767
1753
  return {
1768
- explain: () => this.#explain(sourceType, targetType, isNot),
1754
+ explain: () => this.explain(sourceType, targetType, isNot),
1769
1755
  isMatch,
1770
1756
  };
1771
1757
  }
1772
1758
  }
1773
1759
 
1760
+ class ToEqual extends RelationMatcherBase {
1761
+ relation = this.typeChecker.relation.identity;
1762
+ relationExplanationText = "identical to";
1763
+ }
1764
+
1774
1765
  class ToHaveProperty {
1775
1766
  compiler;
1776
1767
  typeChecker;
@@ -1812,25 +1803,9 @@ class ToHaveProperty {
1812
1803
  }
1813
1804
  }
1814
1805
 
1815
- class ToMatch {
1816
- typeChecker;
1817
- constructor(typeChecker) {
1818
- this.typeChecker = typeChecker;
1819
- }
1820
- #explain(sourceType, targetType, isNot) {
1821
- const sourceTypeText = this.typeChecker.typeToString(sourceType);
1822
- const targetTypeText = this.typeChecker.typeToString(targetType);
1823
- return isNot
1824
- ? [Diagnostic.error(`Type '${targetTypeText}' is a subtype of type '${sourceTypeText}'.`)]
1825
- : [Diagnostic.error(`Type '${targetTypeText}' is not a subtype of type '${sourceTypeText}'.`)];
1826
- }
1827
- match(sourceType, targetType, isNot) {
1828
- const isMatch = this.typeChecker.isTypeSubtypeOf(sourceType, targetType);
1829
- return {
1830
- explain: () => this.#explain(sourceType, targetType, isNot),
1831
- isMatch,
1832
- };
1833
- }
1806
+ class ToMatch extends RelationMatcherBase {
1807
+ relation = this.typeChecker.relation.subtype;
1808
+ relationExplanationText = "a subtype of";
1834
1809
  }
1835
1810
 
1836
1811
  class ToRaiseError {
@@ -1952,26 +1927,26 @@ class Expect {
1952
1927
  constructor(compiler, typeChecker) {
1953
1928
  this.compiler = compiler;
1954
1929
  this.typeChecker = typeChecker;
1955
- this.toBeAny = new PrimitiveTypeMatcher(this.typeChecker, this.compiler.TypeFlags.Any, "any");
1930
+ this.toBeAny = new PrimitiveTypeMatcher(this.typeChecker, this.compiler.TypeFlags.Any);
1956
1931
  this.toBeAssignable = new ToBeAssignable(this.typeChecker);
1957
- this.toBeBigInt = new PrimitiveTypeMatcher(this.typeChecker, this.compiler.TypeFlags.BigInt, "bigint");
1958
- this.toBeBoolean = new PrimitiveTypeMatcher(this.typeChecker, this.compiler.TypeFlags.Boolean, "boolean");
1959
- this.toBeNever = new PrimitiveTypeMatcher(this.typeChecker, this.compiler.TypeFlags.Never, "never");
1960
- this.toBeNull = new PrimitiveTypeMatcher(this.typeChecker, this.compiler.TypeFlags.Null, "null");
1961
- this.toBeNumber = new PrimitiveTypeMatcher(this.typeChecker, this.compiler.TypeFlags.Number, "number");
1962
- this.toBeString = new PrimitiveTypeMatcher(this.typeChecker, this.compiler.TypeFlags.String, "string");
1963
- this.toBeSymbol = new PrimitiveTypeMatcher(this.typeChecker, this.compiler.TypeFlags.ESSymbol, "symbol");
1964
- this.toBeUndefined = new PrimitiveTypeMatcher(this.typeChecker, this.compiler.TypeFlags.Undefined, "undefined");
1965
- this.toBeUniqueSymbol = new PrimitiveTypeMatcher(this.typeChecker, this.compiler.TypeFlags.UniqueESSymbol, "unique symbol");
1966
- this.toBeUnknown = new PrimitiveTypeMatcher(this.typeChecker, this.compiler.TypeFlags.Unknown, "unknown");
1967
- this.toBeVoid = new PrimitiveTypeMatcher(this.typeChecker, this.compiler.TypeFlags.Void, "void");
1932
+ this.toBeBigInt = new PrimitiveTypeMatcher(this.typeChecker, this.compiler.TypeFlags.BigInt);
1933
+ this.toBeBoolean = new PrimitiveTypeMatcher(this.typeChecker, this.compiler.TypeFlags.Boolean);
1934
+ this.toBeNever = new PrimitiveTypeMatcher(this.typeChecker, this.compiler.TypeFlags.Never);
1935
+ this.toBeNull = new PrimitiveTypeMatcher(this.typeChecker, this.compiler.TypeFlags.Null);
1936
+ this.toBeNumber = new PrimitiveTypeMatcher(this.typeChecker, this.compiler.TypeFlags.Number);
1937
+ this.toBeString = new PrimitiveTypeMatcher(this.typeChecker, this.compiler.TypeFlags.String);
1938
+ this.toBeSymbol = new PrimitiveTypeMatcher(this.typeChecker, this.compiler.TypeFlags.ESSymbol);
1939
+ this.toBeUndefined = new PrimitiveTypeMatcher(this.typeChecker, this.compiler.TypeFlags.Undefined);
1940
+ this.toBeUniqueSymbol = new PrimitiveTypeMatcher(this.typeChecker, this.compiler.TypeFlags.UniqueESSymbol);
1941
+ this.toBeUnknown = new PrimitiveTypeMatcher(this.typeChecker, this.compiler.TypeFlags.Unknown);
1942
+ this.toBeVoid = new PrimitiveTypeMatcher(this.typeChecker, this.compiler.TypeFlags.Void);
1968
1943
  this.toEqual = new ToEqual(this.typeChecker);
1969
1944
  this.toHaveProperty = new ToHaveProperty(this.compiler, this.typeChecker);
1970
1945
  this.toMatch = new ToMatch(this.typeChecker);
1971
1946
  this.toRaiseError = new ToRaiseError(this.compiler, this.typeChecker);
1972
1947
  }
1973
1948
  static assertTypeChecker(typeChecker) {
1974
- return ("isTypeAssignableTo" in typeChecker && "isTypeIdenticalTo" in typeChecker && "isTypeSubtypeOf" in typeChecker);
1949
+ return ("isTypeRelatedTo" in typeChecker && "relation" in typeChecker);
1975
1950
  }
1976
1951
  #getType(node) {
1977
1952
  return this.compiler.isExpression(node)
@@ -2021,7 +1996,7 @@ class Expect {
2021
1996
  this.#onSourceArgumentMustBeProvided(assertion, expectResult);
2022
1997
  return;
2023
1998
  }
2024
- return this[matcherNameText].match(this.#getType(assertion.source[0]), assertion.isNot);
1999
+ return this[matcherNameText].match(this.#getType(assertion.source[0]));
2025
2000
  case "toHaveProperty": {
2026
2001
  if (assertion.source[0] == null) {
2027
2002
  this.#onSourceArgumentMustBeProvided(assertion, expectResult);
@@ -2030,7 +2005,7 @@ class Expect {
2030
2005
  const sourceType = this.#getType(assertion.source[0]);
2031
2006
  const nonPrimitiveType = { flags: this.compiler.TypeFlags.NonPrimitive };
2032
2007
  if (sourceType.flags & (this.compiler.TypeFlags.Any | this.compiler.TypeFlags.Never)
2033
- || !this.typeChecker.isTypeAssignableTo(sourceType, nonPrimitiveType)) {
2008
+ || !this.typeChecker.isTypeRelatedTo(sourceType, nonPrimitiveType, this.typeChecker.relation.assignable)) {
2034
2009
  this.#onSourceArgumentMustBeObjectType(assertion.source[0], expectResult);
2035
2010
  return;
2036
2011
  }
@@ -2528,7 +2503,7 @@ class TestFileRunner {
2528
2503
  }
2529
2504
  const typeChecker = program.getTypeChecker();
2530
2505
  if (!Expect.assertTypeChecker(typeChecker)) {
2531
- const text = "The required 'isTypeAssignableTo()', 'isTypeIdenticalTo()' and 'isTypeSubtypeOf()' methods are missing in the provided type checker.";
2506
+ const text = "The required 'isTypeRelatedTo()' method is missing in the provided type checker.";
2532
2507
  EventEmitter.dispatch(["file:error", { diagnostics: [Diagnostic.error(text)], result: fileResult }]);
2533
2508
  return;
2534
2509
  }
@@ -2580,7 +2555,7 @@ class TSTyche {
2580
2555
  #abortController = new AbortController();
2581
2556
  #storeService;
2582
2557
  #taskRunner;
2583
- static version = "1.0.0-rc.1";
2558
+ static version = "1.0.0";
2584
2559
  constructor(resolvedConfig, storeService) {
2585
2560
  this.resolvedConfig = resolvedConfig;
2586
2561
  this.#storeService = storeService;
@@ -2591,12 +2566,11 @@ class TSTyche {
2591
2566
  EventEmitter.addHandler(([eventName, payload]) => {
2592
2567
  if (eventName.includes("error") || eventName.includes("fail")) {
2593
2568
  if ("diagnostics" in payload
2594
- && !payload.diagnostics.some(({ category }) => category === "error")) {
2595
- return;
2596
- }
2597
- process.exitCode = 1;
2598
- if (this.resolvedConfig.failFast) {
2599
- this.#abortController.abort();
2569
+ && payload.diagnostics.some((diagnostic) => diagnostic.category === "error")) {
2570
+ process.exitCode = 1;
2571
+ if (this.resolvedConfig.failFast) {
2572
+ this.#abortController.abort();
2573
+ }
2600
2574
  }
2601
2575
  }
2602
2576
  });
@@ -3195,7 +3169,6 @@ var OptionBrand;
3195
3169
  OptionBrand["True"] = "true";
3196
3170
  OptionBrand["List"] = "list";
3197
3171
  })(OptionBrand || (OptionBrand = {}));
3198
-
3199
3172
  var OptionGroup;
3200
3173
  (function (OptionGroup) {
3201
3174
  OptionGroup[OptionGroup["CommandLine"] = 2] = "CommandLine";
@@ -3531,10 +3504,14 @@ class StoreService {
3531
3504
  const candidatePaths = [Path.join(Path.dirname(modulePath), "tsserverlibrary.js"), modulePath];
3532
3505
  for (const candidatePath of candidatePaths) {
3533
3506
  const sourceText = await fs.readFile(candidatePath, { encoding: "utf8" });
3534
- const modifiedSourceText = sourceText.replace("return checker;", "return { ...checker, isTypeIdenticalTo, isTypeSubtypeOf };");
3535
- if (modifiedSourceText.length === sourceText.length) {
3507
+ if (!sourceText.includes("isTypeRelatedTo")) {
3536
3508
  continue;
3537
3509
  }
3510
+ const toExpose = [
3511
+ "isTypeRelatedTo",
3512
+ "relation: { assignable: assignableRelation, identity: identityRelation, subtype: strictSubtypeRelation }",
3513
+ ];
3514
+ const modifiedSourceText = sourceText.replace("return checker;", `return { ...checker, ${toExpose.join(", ")} };`);
3538
3515
  const compiledWrapper = vm.compileFunction(modifiedSourceText, ["exports", "require", "module", "__filename", "__dirname"], { filename: candidatePath });
3539
3516
  compiledWrapper(exports, createRequire(candidatePath), module, candidatePath, Path.dirname(candidatePath));
3540
3517
  break;
@@ -3586,7 +3563,7 @@ class StoreService {
3586
3563
  `The resolution of the '${tag}' tag may be outdated.`,
3587
3564
  ]));
3588
3565
  }
3589
- return this.#manifest.versions.includes(tag) || tag in this.#manifest.resolutions || tag === "current";
3566
+ return tag in this.#manifest.resolutions || this.#manifest.versions.includes(tag);
3590
3567
  }
3591
3568
  }
3592
3569
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tstyche",
3
- "version": "1.0.0-rc.1",
3
+ "version": "1.0.0",
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,47 +38,50 @@
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",
52
- "test": "NODE_OPTIONS='--experimental-vm-modules --no-warnings' jest --config jest.config.js",
53
+ "test": "yarn test:unit && yarn test:e2e",
53
54
  "test:coverage": "yarn build --sourcemap && c8 --config c8.config.json yarn test:e2e",
54
- "test:e2e": "yarn test --testMatch '**/tests/*.test.js'",
55
+ "test:e2e": "NODE_OPTIONS='--experimental-vm-modules --no-warnings' jest --config jest.config.js",
55
56
  "test:examples": "tstyche examples",
56
57
  "test:types": "tstyche tests",
57
- "test:unit": "yarn test --testMatch '**/source/**/__tests__/*.test.ts?(x)'"
58
+ "test:unit": "mocha --config mocha.config.json"
58
59
  },
59
60
  "devDependencies": {
60
61
  "@jest/globals": "29.7.0",
61
62
  "@rollup/plugin-typescript": "11.1.6",
62
- "@types/node": "20.11.17",
63
- "@typescript-eslint/eslint-plugin": "6.21.0",
64
- "@typescript-eslint/parser": "6.21.0",
63
+ "@types/chai": "4.3.11",
64
+ "@types/mocha": "10.0.6",
65
+ "@types/node": "20.11.19",
66
+ "@typescript-eslint/eslint-plugin": "7.0.2",
67
+ "@typescript-eslint/parser": "7.0.2",
65
68
  "ajv": "8.12.0",
66
69
  "c8": "9.1.0",
67
- "cspell": "8.3.2",
70
+ "chai": "5.1.0",
71
+ "cspell": "8.4.0",
68
72
  "dprint": "0.45.0",
69
73
  "eslint": "8.56.0",
70
74
  "eslint-import-resolver-typescript": "3.6.1",
71
75
  "eslint-plugin-import": "2.29.1",
72
- "eslint-plugin-jest": "27.6.3",
76
+ "eslint-plugin-jest": "27.9.0",
73
77
  "eslint-plugin-jest-formatting": "3.1.0",
74
- "eslint-plugin-simple-import-sort": "11.0.0",
78
+ "eslint-plugin-simple-import-sort": "12.0.0",
75
79
  "jest": "29.7.0",
76
- "jest-serializer-ansi-escapes": "2.0.1",
77
80
  "magic-string": "0.30.7",
78
- "rollup": "4.9.6",
81
+ "mocha": "10.3.0",
82
+ "pretty-ansi": "1.0.0",
83
+ "rollup": "4.12.0",
79
84
  "rollup-plugin-dts": "6.1.0",
80
- "ts-node": "10.9.2",
81
85
  "tslib": "2.6.2",
82
86
  "typescript": "5.3.3"
83
87
  },