tstyche 7.0.0-rc.1 → 7.1.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
@@ -30,14 +30,14 @@ test("isSameLength", () => {
30
30
  });
31
31
  ```
32
32
 
33
- To group and organize tests, TSTyche has:
33
+ TSTyche lets you organize tests using:
34
34
 
35
- - `test()`, `it()` and `describe()` helpers,
36
- - with `.only`, `.skip` and `.todo` run mode flags.
35
+ - helpers: `test()`, `it()` and `describe()`
36
+ - run mode flags: `.only`, `.skip` and `.todo`
37
37
 
38
38
  ## Assertions
39
39
 
40
- The `expect` style assertions can check either the inferred type of an expression (as in the example above) or a type directly:
40
+ The `expect` style assertions can check either the inferred type of an expression or a type directly:
41
41
 
42
42
  ```ts
43
43
  import { type _, expect } from "tstyche";
@@ -58,32 +58,32 @@ expect<WithLoading<_>>().type.not.toBeInstantiableWith<[string]>();
58
58
 
59
59
  Relation matchers:
60
60
 
61
- - `.toBe()` checks if a type is the same as the given type,
62
- - `.toBeAssignableFrom()` checks if a type is assignable from the given type,
63
- - `.toBeAssignableTo()` checks if a type is assignable to the given type.
61
+ - `.toBe()` checks if a type is the same as the given type
62
+ - `.toBeAssignableFrom()` checks if a type is assignable from the given type
63
+ - `.toBeAssignableTo()` checks if a type is assignable to the given type
64
64
 
65
65
  Ability matchers:
66
66
 
67
- - `.toAcceptProps()` checks if a JSX component accepts the given props,
68
- - `.toBeApplicable` checks if a decorator is applicable to the given class or class member,
69
- - `.toBeCallableWith()` checks if a function is callable with the given arguments,
70
- - `.toBeConstructableWith()` checks if a class is constructable with the given arguments,
71
- - `.toBeInstantiableWith()` checks if a generic is instantiable with the given type arguments,
72
- - `.toHaveProperty()` checks if a type has the given property.
67
+ - `.toAcceptProps()` checks if a JSX component accepts the given props
68
+ - `.toBeApplicable` checks if a decorator is applicable to the given class or class member
69
+ - `.toBeCallableWith()` checks if a function is callable with the given arguments
70
+ - `.toBeConstructableWith()` checks if a class is constructable with the given arguments
71
+ - `.toBeInstantiableWith()` checks if a generic is instantiable with the given type arguments
72
+ - `.toHaveProperty()` checks if a type has the given property
73
73
 
74
74
  ## Runner
75
75
 
76
- 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:
76
+ The `tstyche` command is the heart of TSTyche. It lets you select test files by path, filter tests by name and run them against specific versions of TypeScript:
77
77
 
78
78
  ```shell
79
79
  tstyche query-params --only multiple --target '>=5.6'
80
80
  ```
81
81
 
82
- It is that simple! Actually, TSTyche does even more:
82
+ That is just the beginning. It even lets you:
83
83
 
84
- - checks messages of errors suppressed by `@ts-expect-error` directives,
85
- - generates type tests from a data table,
86
- - runs tests in watch mode.
84
+ - check messages of errors suppressed by `@ts-expect-error` directives
85
+ - generate type tests from a template file
86
+ - run tests in watch mode
87
87
 
88
88
  ## Try It Out
89
89
 
@@ -95,6 +95,10 @@ Try TSTyche online on StackBlitz:
95
95
 
96
96
  Visit [tstyche.org](https://tstyche.org) to view the full documentation.
97
97
 
98
+ ## Roadmap
99
+
100
+ See [ROADMAP.md](https://github.com/tstyche/tstyche/blob/main/ROADMAP.md) for planned features.
101
+
98
102
  ## License
99
103
 
100
104
  [MIT][license-url] © TSTyche
package/dist/api.d.ts CHANGED
@@ -36,8 +36,7 @@ declare enum TestTreeNodeBrand {
36
36
  Describe = "describe",
37
37
  Test = "test",
38
38
  It = "it",
39
- Expect = "expect",
40
- When = "when"
39
+ Expect = "expect"
41
40
  }
42
41
 
43
42
  declare enum TestTreeNodeFlags {
@@ -47,17 +46,9 @@ declare enum TestTreeNodeFlags {
47
46
  Todo = 4
48
47
  }
49
48
 
50
- declare class WhenNode extends TestTreeNode {
51
- actionNode: ts.CallExpression;
52
- actionNameNode: ts.PropertyAccessExpression;
53
- abilityDiagnostics: Set<ts.Diagnostic>;
54
- target: ts.NodeArray<ts.Expression> | ts.NodeArray<ts.TypeNode>;
55
- constructor(compiler: typeof ts, brand: TestTreeNodeBrand, node: ts.CallExpression, parent: TestTree | TestTreeNode, flags: TestTreeNodeFlags, actionNode: ts.CallExpression, actionNameNode: ts.PropertyAccessExpression);
56
- }
57
-
58
49
  declare class TestTreeNode {
59
50
  brand: TestTreeNodeBrand;
60
- children: Array<TestTreeNode | ExpectNode | WhenNode>;
51
+ children: Array<TestTreeNode | ExpectNode>;
61
52
  diagnostics: Set<ts.Diagnostic>;
62
53
  flags: TestTreeNodeFlags;
63
54
  name: string;
@@ -79,7 +70,7 @@ declare class ExpectNode extends TestTreeNode {
79
70
  }
80
71
 
81
72
  declare class TestTree {
82
- children: Array<TestTreeNode | ExpectNode | WhenNode>;
73
+ children: Array<TestTreeNode | ExpectNode>;
83
74
  diagnostics: Set<ts.Diagnostic>;
84
75
  hasOnly: boolean;
85
76
  sourceFile: ts.SourceFile;
@@ -95,7 +86,6 @@ declare class DiagnosticOrigin {
95
86
  constructor(start: number, end: number, sourceFile: ts.SourceFile | JsonSourceFile, assertionNode?: ExpectNode);
96
87
  static fromAssertion(assertionNode: ExpectNode): DiagnosticOrigin;
97
88
  static fromNode(node: ts.Node, assertionNode?: ExpectNode): DiagnosticOrigin;
98
- static fromNodes(nodes: ts.NodeArray<ts.Node>, assertionNode?: ExpectNode): DiagnosticOrigin;
99
89
  }
100
90
 
101
91
  declare class Diagnostic {
@@ -451,9 +441,6 @@ declare class SuppressedResult {
451
441
  constructor(suppressed: SuppressedError);
452
442
  }
453
443
 
454
- interface EventHandler {
455
- on: (event: Event) => void;
456
- }
457
444
  type Event = ["config:error", {
458
445
  diagnostics: Array<Diagnostic>;
459
446
  }] | ["select:error", {
@@ -490,7 +477,7 @@ type Event = ["config:error", {
490
477
  }] | ["collect:error", {
491
478
  diagnostics: Array<Diagnostic>;
492
479
  }] | ["collect:node", {
493
- node: TestTreeNode | ExpectNode | WhenNode;
480
+ node: TestTreeNode | ExpectNode;
494
481
  }] | ["collect:end", {
495
482
  tree: TestTree;
496
483
  }] | ["describe:start", {
@@ -536,6 +523,9 @@ type Event = ["config:error", {
536
523
  }] | ["watch:error", {
537
524
  diagnostics: Array<Diagnostic>;
538
525
  }];
526
+ interface EventHandler {
527
+ on: (event: Event) => void;
528
+ }
539
529
 
540
530
  declare class EventEmitter {
541
531
  #private;
package/dist/api.js CHANGED
@@ -112,9 +112,6 @@ class DiagnosticOrigin {
112
112
  static fromNode(node, assertionNode) {
113
113
  return new DiagnosticOrigin(node.getStart(), node.getEnd(), node.getSourceFile(), assertionNode);
114
114
  }
115
- static fromNodes(nodes, assertionNode) {
116
- return new DiagnosticOrigin(nodes.pos, nodes.end, nodes[0].getSourceFile(), assertionNode);
117
- }
118
115
  }
119
116
 
120
117
  function diagnosticBelongsToNode(diagnostic, node) {
@@ -776,9 +773,7 @@ class ManifestService {
776
773
  return manifest;
777
774
  }
778
775
  async #persist(manifest) {
779
- if (!existsSync(this.#storePath)) {
780
- await fs.mkdir(this.#storePath, { recursive: true });
781
- }
776
+ await fs.mkdir(this.#storePath, { recursive: true });
782
777
  await fs.writeFile(this.#manifestFilePath, manifest.stringify());
783
778
  }
784
779
  async prune() {
@@ -851,28 +846,8 @@ class PackageService {
851
846
  this.#fetcher = fetcher;
852
847
  this.#lockService = lockService;
853
848
  }
854
- async #add(packagePath, resource, diagnostic) {
855
- const request = new Request(resource.tarball, { integrity: resource.integrity });
856
- const response = await this.#fetcher.get(request, diagnostic);
857
- if (response?.body != null) {
858
- const targetPath = `${packagePath}-${Math.random().toString(32).slice(2)}`;
859
- const stream = response.body.pipeThrough(new DecompressionStream("gzip"));
860
- const tarReader = new TarReader(stream);
861
- for await (const file of tarReader.extract()) {
862
- const filePath = Path.join(targetPath, file.name.replace(/^package\//, ""));
863
- const directoryPath = Path.dirname(filePath);
864
- if (!existsSync(directoryPath)) {
865
- await fs.mkdir(directoryPath, { recursive: true });
866
- }
867
- await fs.writeFile(filePath, file.content);
868
- }
869
- await fs.rename(targetPath, packagePath);
870
- return packagePath;
871
- }
872
- return;
873
- }
874
849
  async ensure(packageVersion, manifest) {
875
- let packagePath = Path.join(this.#storePath, `typescript@${packageVersion}`);
850
+ const packagePath = Path.join(this.#storePath, `typescript@${packageVersion}`);
876
851
  const diagnostic = Diagnostic.error(StoreDiagnosticText.failedToFetchPackage(packageVersion));
877
852
  if (await this.#lockService.isLocked(packagePath, diagnostic)) {
878
853
  return;
@@ -881,18 +856,29 @@ class PackageService {
881
856
  return packagePath;
882
857
  }
883
858
  EventEmitter.dispatch(["store:adds", { packagePath, packageVersion }]);
884
- const resource = manifest?.packages[packageVersion];
885
- if (resource != null) {
886
- const lock = this.#lockService.getLock(packagePath);
887
- try {
888
- packagePath = await this.#add(packagePath, resource, diagnostic);
859
+ const resource = manifest.packages[packageVersion];
860
+ const lock = this.#lockService.getLock(packagePath);
861
+ try {
862
+ const request = new Request(resource.tarball, { integrity: resource.integrity });
863
+ const response = await this.#fetcher.get(request, diagnostic);
864
+ if (!response?.body) {
865
+ return;
889
866
  }
890
- finally {
891
- lock.release();
867
+ const targetPath = await fs.mkdtemp(`${packagePath}-`);
868
+ const stream = response.body.pipeThrough(new DecompressionStream("gzip"));
869
+ const tarReader = new TarReader(stream);
870
+ for await (const file of tarReader.extract()) {
871
+ const filePath = Path.join(targetPath, file.name.replace(/^package\//, ""));
872
+ const directoryPath = Path.dirname(filePath);
873
+ await fs.mkdir(directoryPath, { recursive: true });
874
+ await fs.writeFile(filePath, file.content);
892
875
  }
876
+ await fs.rename(targetPath, packagePath);
893
877
  return packagePath;
894
878
  }
895
- return;
879
+ finally {
880
+ lock.release();
881
+ }
896
882
  }
897
883
  }
898
884
 
@@ -912,17 +898,20 @@ class Store {
912
898
  Store.#packageService = new PackageService(Store.#storePath, Store.#fetcher, Store.#lockService);
913
899
  Store.#manifestService = new ManifestService(Store.#storePath, Store.#npmRegistry, Store.#fetcher);
914
900
  }
915
- static async fetch(tag) {
916
- if (tag === "*" && environmentOptions.typescriptModule != null) {
917
- return;
918
- }
901
+ static async #ensure(tag) {
919
902
  await Store.open();
920
903
  const version = Store.manifest?.resolve(tag);
921
904
  if (!version) {
922
905
  Store.#onDiagnostics(Diagnostic.error(StoreDiagnosticText.cannotAddTypeScriptPackage(tag)));
923
906
  return;
924
907
  }
925
- await Store.#packageService.ensure(version, Store.manifest);
908
+ return await Store.#packageService.ensure(version, Store.manifest);
909
+ }
910
+ static async fetch(tag) {
911
+ if (tag === "*" && environmentOptions.typescriptModule != null) {
912
+ return;
913
+ }
914
+ await Store.#ensure(tag);
926
915
  }
927
916
  static async load(tag) {
928
917
  let resolvedModule;
@@ -930,13 +919,7 @@ class Store {
930
919
  resolvedModule = environmentOptions.typescriptModule;
931
920
  }
932
921
  else {
933
- await Store.open();
934
- const version = Store.manifest?.resolve(tag);
935
- if (!version) {
936
- Store.#onDiagnostics(Diagnostic.error(StoreDiagnosticText.cannotAddTypeScriptPackage(tag)));
937
- return;
938
- }
939
- const packagePath = await Store.#packageService.ensure(version, Store.manifest);
922
+ const packagePath = await Store.#ensure(tag);
940
923
  if (packagePath != null) {
941
924
  resolvedModule = pathToFileURL(`${packagePath}/lib/typescript.js`).toString();
942
925
  }
@@ -950,7 +933,9 @@ class Store {
950
933
  EventEmitter.dispatch(["store:error", { diagnostics: [diagnostic] }]);
951
934
  }
952
935
  static async open() {
953
- Store.open = () => Promise.resolve();
936
+ if (Store.manifest != null) {
937
+ return;
938
+ }
954
939
  Store.manifest = await Store.#manifestService.open();
955
940
  if (Store.manifest != null) {
956
941
  Store.#supportedTags = [...Object.keys(Store.manifest.resolutions), ...Store.manifest.versions];
@@ -1040,7 +1025,7 @@ class Options {
1040
1025
  },
1041
1026
  {
1042
1027
  brand: "boolean",
1043
- description: "Check errors silenced by '@ts-expect-error' directives.",
1028
+ description: "Check errors suppressed by '@ts-expect-error' directives.",
1044
1029
  group: 4,
1045
1030
  name: "checkSuppressedErrors",
1046
1031
  },
@@ -1092,13 +1077,13 @@ class Options {
1092
1077
  },
1093
1078
  {
1094
1079
  brand: "string",
1095
- description: "Only run tests with matching name.",
1080
+ description: "Only run tests with a matching name.",
1096
1081
  group: 2,
1097
1082
  name: "only",
1098
1083
  },
1099
1084
  {
1100
1085
  brand: "true",
1101
- description: "Remove all installed versions of the 'typescript' package and exit.",
1086
+ description: "Remove all fetched versions of the 'typescript' package and exit.",
1102
1087
  group: 2,
1103
1088
  name: "prune",
1104
1089
  },
@@ -1132,7 +1117,7 @@ class Options {
1132
1117
  },
1133
1118
  {
1134
1119
  brand: "string",
1135
- description: "The path to a directory containing files of a test project.",
1120
+ description: "The path to the root directory of a test project.",
1136
1121
  group: 2,
1137
1122
  name: "root",
1138
1123
  },
@@ -1144,13 +1129,13 @@ class Options {
1144
1129
  },
1145
1130
  {
1146
1131
  brand: "string",
1147
- description: "Skip tests with matching name.",
1132
+ description: "Skip tests with a matching name.",
1148
1133
  group: 2,
1149
1134
  name: "skip",
1150
1135
  },
1151
1136
  {
1152
1137
  brand: "range",
1153
- description: "The range of TypeScript versions to test against.",
1138
+ description: "The TypeScript version or range of versions to test against.",
1154
1139
  group: 2 | 4 | 8,
1155
1140
  name: "target",
1156
1141
  },
@@ -3350,15 +3335,8 @@ class AbilityLayer {
3350
3335
  this.#editor = editor;
3351
3336
  }
3352
3337
  #belongsToNode(node, diagnostic) {
3353
- switch (node.brand) {
3354
- case "expect":
3355
- return (diagnosticBelongsToNode(diagnostic, node.matcherNode) ||
3356
- diagnosticBelongsToNode(diagnostic, node.source));
3357
- case "when":
3358
- return (diagnosticBelongsToNode(diagnostic, node.actionNode) &&
3359
- !diagnosticBelongsToNode(diagnostic, node.target));
3360
- }
3361
- return false;
3338
+ return (diagnosticBelongsToNode(diagnostic, node.matcherNode) ||
3339
+ diagnosticBelongsToNode(diagnostic, node.source));
3362
3340
  }
3363
3341
  close(diagnostics) {
3364
3342
  if (diagnostics != null && this.#nodes.length > 0) {
@@ -3534,22 +3512,6 @@ class AbilityLayer {
3534
3512
  }
3535
3513
  }
3536
3514
  }
3537
- visitWhen(when) {
3538
- const whenStart = when.node.getStart();
3539
- const whenExpressionEnd = when.node.expression.getEnd();
3540
- const whenEnd = when.node.getEnd();
3541
- const actionNameEnd = when.actionNameNode.getEnd();
3542
- switch (when.actionNameNode.name.text) {
3543
- case "isCalledWith":
3544
- this.#nodes.push(when);
3545
- this.#editor.eraseTrailingComma(when.target);
3546
- this.#editor.replaceRanges([
3547
- [whenStart, whenExpressionEnd, nodeIsChildOfExpressionStatement(this.#compiler, when.actionNode) ? ";" : ""],
3548
- [whenEnd, actionNameEnd],
3549
- ]);
3550
- break;
3551
- }
3552
- }
3553
3515
  }
3554
3516
 
3555
3517
  class SourceTextEditor {
@@ -3721,14 +3683,7 @@ class Layers {
3721
3683
  this.#suppressedLayer.close(this.#suppressedDiagnostics);
3722
3684
  }
3723
3685
  visit(node) {
3724
- switch (node.brand) {
3725
- case "expect":
3726
- this.#abilityLayer.visitExpect(node);
3727
- break;
3728
- case "when":
3729
- this.#abilityLayer.visitWhen(node);
3730
- break;
3731
- }
3686
+ this.#abilityLayer.visitExpect(node);
3732
3687
  }
3733
3688
  }
3734
3689
 
@@ -3880,8 +3835,6 @@ class IdentifierLookup {
3880
3835
  return { brand: "test", flags };
3881
3836
  case "expect":
3882
3837
  return { brand: "expect", flags };
3883
- case "when":
3884
- return { brand: "when", flags };
3885
3838
  }
3886
3839
  return;
3887
3840
  }
@@ -3899,25 +3852,6 @@ class TestTree {
3899
3852
  }
3900
3853
  }
3901
3854
 
3902
- class WhenNode extends TestTreeNode {
3903
- actionNode;
3904
- actionNameNode;
3905
- abilityDiagnostics = new Set();
3906
- target;
3907
- constructor(compiler, brand, node, parent, flags, actionNode, actionNameNode) {
3908
- super(compiler, brand, node, parent, flags);
3909
- this.actionNode = actionNode;
3910
- this.actionNameNode = actionNameNode;
3911
- this.target = this.node.typeArguments ?? this.node.arguments;
3912
- for (const diagnostic of parent.diagnostics) {
3913
- if (diagnosticBelongsToNode(diagnostic, node)) {
3914
- this.diagnostics.add(diagnostic);
3915
- parent.diagnostics.delete(diagnostic);
3916
- }
3917
- }
3918
- }
3919
- }
3920
-
3921
3855
  class CollectService {
3922
3856
  #layers;
3923
3857
  #compiler;
@@ -3977,38 +3911,6 @@ class CollectService {
3977
3911
  this.#onNode(expectNode, parent, testTree);
3978
3912
  return;
3979
3913
  }
3980
- if (meta.brand === "when") {
3981
- const actionNameNode = this.#getChainedNode(node);
3982
- if (!actionNameNode) {
3983
- const text = "The final element in the chain must be an action.";
3984
- const origin = DiagnosticOrigin.fromNode(node);
3985
- this.#onDiagnostics(Diagnostic.error(text, origin));
3986
- return;
3987
- }
3988
- const actionNode = this.#getActionNode(actionNameNode);
3989
- if (!actionNode) {
3990
- const text = "The action must be called with an argument.";
3991
- const origin = DiagnosticOrigin.fromNode(actionNameNode);
3992
- this.#onDiagnostics(Diagnostic.error(text, origin));
3993
- return;
3994
- }
3995
- this.#compiler.forEachChild(actionNode, (node) => {
3996
- if (this.#compiler.isCallExpression(node)) {
3997
- const meta = this.#identifierLookup.resolveTestTreeNodeMeta(node);
3998
- if (meta?.brand === "describe" ||
3999
- meta?.brand === "it" ||
4000
- meta?.brand === "test") {
4001
- const text = CollectDiagnosticText.cannotBeNestedWithin(meta.brand, "when");
4002
- const origin = DiagnosticOrigin.fromNode(node);
4003
- this.#onDiagnostics(Diagnostic.error(text, origin));
4004
- }
4005
- }
4006
- });
4007
- const whenNode = new WhenNode(this.#compiler, meta.brand, node, parent, meta.flags, actionNode, actionNameNode);
4008
- this.#layers.visit(whenNode);
4009
- this.#onNode(whenNode, parent, testTree);
4010
- return;
4011
- }
4012
3914
  }
4013
3915
  }
4014
3916
  if (this.#compiler.isImportDeclaration(node)) {
@@ -4050,7 +3952,6 @@ class CollectService {
4050
3952
  }
4051
3953
  break;
4052
3954
  case "expect":
4053
- case "when":
4054
3955
  if (parent.brand === "describe") {
4055
3956
  return false;
4056
3957
  }
@@ -4079,12 +3980,6 @@ class CollectService {
4079
3980
  }
4080
3981
  return;
4081
3982
  }
4082
- #getActionNode(node) {
4083
- if (this.#compiler.isCallExpression(node.parent)) {
4084
- return node.parent;
4085
- }
4086
- return;
4087
- }
4088
3983
  #onDiagnostics(diagnostic) {
4089
3984
  EventEmitter.dispatch(["collect:error", { diagnostics: [diagnostic] }]);
4090
3985
  }
@@ -4103,7 +3998,6 @@ var TestTreeNodeBrand;
4103
3998
  TestTreeNodeBrand["Test"] = "test";
4104
3999
  TestTreeNodeBrand["It"] = "it";
4105
4000
  TestTreeNodeBrand["Expect"] = "expect";
4106
- TestTreeNodeBrand["When"] = "when";
4107
4001
  })(TestTreeNodeBrand || (TestTreeNodeBrand = {}));
4108
4002
 
4109
4003
  var TestTreeNodeFlags;
@@ -4117,7 +4011,7 @@ var TestTreeNodeFlags;
4117
4011
  class ProjectService {
4118
4012
  #compiler;
4119
4013
  #host;
4120
- #lastSeenProject = "";
4014
+ #lastSeenProject = "none";
4121
4015
  #projectConfig;
4122
4016
  #resolvedConfig;
4123
4017
  #seenProjects = new Set();
@@ -4182,7 +4076,6 @@ class ProjectService {
4182
4076
  noUncheckedIndexedAccess: true,
4183
4077
  resolveJsonModule: true,
4184
4078
  strict: true,
4185
- verbatimModuleSyntax: true,
4186
4079
  target: this.#compiler.ScriptTarget.ESNext,
4187
4080
  };
4188
4081
  if (Version.isSatisfiedWith(this.#compiler.version, "5.6")) {
@@ -4226,7 +4119,7 @@ class ProjectService {
4226
4119
  if (Options.isJsonString(specifier)) {
4227
4120
  return {
4228
4121
  kind: 3,
4229
- specifier: Path.resolve(this.#resolvedConfig.rootPath, `${Math.random().toString(32).slice(2)}.tsconfig.json`),
4122
+ specifier: Path.resolve(this.#resolvedConfig.rootPath, `${Date.now().toString(36)}.tsconfig.json`),
4230
4123
  };
4231
4124
  }
4232
4125
  return { kind: 2, specifier };
@@ -5797,63 +5690,6 @@ class Reject {
5797
5690
  }
5798
5691
  }
5799
5692
 
5800
- class WhenDiagnosticText {
5801
- static actionIsNotSupported(actionNameText) {
5802
- return `The '.${actionNameText}()' action is not supported.`;
5803
- }
5804
- }
5805
-
5806
- class WhenService {
5807
- #compiler;
5808
- #onDiagnostics;
5809
- #reject;
5810
- constructor(compiler, reject, onDiagnostics) {
5811
- this.#compiler = compiler;
5812
- this.#reject = reject;
5813
- this.#onDiagnostics = onDiagnostics;
5814
- }
5815
- action(when) {
5816
- if (!argumentIsProvided(this.#compiler, "target", when.target[0], when.node.expression, this.#onDiagnostics) ||
5817
- this.#reject.argumentType([["target", when.target[0]]], this.#onDiagnostics)) {
5818
- return;
5819
- }
5820
- const actionNameText = when.actionNameNode.name.getText();
5821
- switch (actionNameText) {
5822
- case "isCalledWith":
5823
- break;
5824
- default:
5825
- this.#onActionIsNotSupported(actionNameText, when, this.#onDiagnostics);
5826
- return;
5827
- }
5828
- if (when.abilityDiagnostics.size > 0) {
5829
- const diagnostics = [];
5830
- for (const diagnostic of when.abilityDiagnostics) {
5831
- if (isDiagnosticWithLocation(diagnostic)) {
5832
- const text = getDiagnosticMessageText(diagnostic);
5833
- let origin;
5834
- if (isDiagnosticWithLocation(diagnostic) && diagnosticBelongsToNode(diagnostic, when.node)) {
5835
- origin = DiagnosticOrigin.fromNodes(when.target);
5836
- }
5837
- else {
5838
- origin = new DiagnosticOrigin(diagnostic.start, getTextSpanEnd(diagnostic), when.node.getSourceFile());
5839
- }
5840
- let related;
5841
- if (diagnostic.relatedInformation != null) {
5842
- related = Diagnostic.fromDiagnostics(diagnostic.relatedInformation);
5843
- }
5844
- diagnostics.push(Diagnostic.error(text, origin).add({ related }));
5845
- }
5846
- }
5847
- this.#onDiagnostics(diagnostics);
5848
- }
5849
- }
5850
- #onActionIsNotSupported(actionNameText, when, onDiagnostics) {
5851
- const text = WhenDiagnosticText.actionIsNotSupported(actionNameText);
5852
- const origin = DiagnosticOrigin.fromNode(when.actionNameNode.name);
5853
- onDiagnostics([Diagnostic.error(text, origin)]);
5854
- }
5855
- }
5856
-
5857
5693
  class FixmeDiagnosticText {
5858
5694
  static considerRemoving() {
5859
5695
  return "Consider removing the '// @tstyche fixme' directive.";
@@ -5920,7 +5756,6 @@ class TestTreeWalker {
5920
5756
  #onFileDiagnostics;
5921
5757
  #position;
5922
5758
  #resolvedConfig;
5923
- #whenService;
5924
5759
  constructor(compiler, program, resolvedConfig, onFileDiagnostics, options) {
5925
5760
  this.#compiler = compiler;
5926
5761
  this.#resolvedConfig = resolvedConfig;
@@ -5930,7 +5765,6 @@ class TestTreeWalker {
5930
5765
  this.#position = options.position;
5931
5766
  const reject = new Reject(compiler, program, resolvedConfig);
5932
5767
  this.#expectService = new ExpectService(compiler, program, reject);
5933
- this.#whenService = new WhenService(compiler, reject, onFileDiagnostics);
5934
5768
  }
5935
5769
  async #resolveRunMode(flags, node) {
5936
5770
  const ifDirective = Directive.getDirectiveRange(this.#compiler, node, "if");
@@ -5975,9 +5809,6 @@ class TestTreeWalker {
5975
5809
  case "expect":
5976
5810
  await this.#visitExpect(node, runModeFlags, parentResult);
5977
5811
  break;
5978
- case "when":
5979
- this.#visitWhen(node);
5980
- break;
5981
5812
  }
5982
5813
  if (fixmeDirective) {
5983
5814
  FixmeService.end(fixmeDirective, node, this.#onFileDiagnostics);
@@ -6079,9 +5910,6 @@ class TestTreeWalker {
6079
5910
  EventEmitter.dispatch(["test:fail", { result: testResult }]);
6080
5911
  }
6081
5912
  }
6082
- #visitWhen(when) {
6083
- this.#whenService.action(when);
6084
- }
6085
5913
  }
6086
5914
 
6087
5915
  class FileRunner {
@@ -6170,7 +5998,7 @@ class FileRunner {
6170
5998
  class Runner {
6171
5999
  #eventEmitter = new EventEmitter();
6172
6000
  #resolvedConfig;
6173
- static version = "7.0.0-rc.1";
6001
+ static version = "7.1.0";
6174
6002
  constructor(resolvedConfig) {
6175
6003
  this.#resolvedConfig = resolvedConfig;
6176
6004
  }
package/dist/index.cjs CHANGED
@@ -17,4 +17,3 @@ exports.it = noopChain;
17
17
  exports.omit = noop;
18
18
  exports.pick = noop;
19
19
  exports.test = noopChain;
20
- exports.when = noopChain;
package/dist/index.d.cts CHANGED
@@ -100,7 +100,7 @@ interface Matchers {
100
100
  /**
101
101
  * Checks if the type raises an error.
102
102
  *
103
- * @deprecated This matcher is planned to be removed. For a replacement, see https://tstyche.org/guides/expect-errors.
103
+ * @deprecated This API is planned to be removed. For a replacement, see https://tstyche.org/guides/expect-errors.
104
104
  */
105
105
  toRaiseError: (...target: Array<string | number | RegExp>) => void;
106
106
  }
@@ -183,23 +183,6 @@ interface Test {
183
183
  todo: (name: string, callback?: () => void | Promise<void>) => void;
184
184
  }
185
185
 
186
- interface Actions {
187
- /**
188
- * Calls the given function with the provided arguments.
189
- */
190
- isCalledWith: (...args: Array<unknown>) => void;
191
- }
192
- interface When {
193
- /**
194
- * Creates a test plan.
195
- */
196
- <T>(): Actions;
197
- /**
198
- * Creates a test plan.
199
- */
200
- (target: unknown): Actions;
201
- }
202
-
203
186
  /**
204
187
  * The fill-in type. Useful to fill in the required type arguments of generic types.
205
188
  */
@@ -228,10 +211,6 @@ declare const it: Test;
228
211
  * Defines a single test.
229
212
  */
230
213
  declare const test: Test;
231
- /**
232
- * Creates a test plan.
233
- */
234
- declare const when: When;
235
214
 
236
- export { describe, expect, it, omit, pick, test, when };
215
+ export { describe, expect, it, omit, pick, test };
237
216
  export type { _ };
package/dist/index.d.ts CHANGED
@@ -100,7 +100,7 @@ interface Matchers {
100
100
  /**
101
101
  * Checks if the type raises an error.
102
102
  *
103
- * @deprecated This matcher is planned to be removed. For a replacement, see https://tstyche.org/guides/expect-errors.
103
+ * @deprecated This API is planned to be removed. For a replacement, see https://tstyche.org/guides/expect-errors.
104
104
  */
105
105
  toRaiseError: (...target: Array<string | number | RegExp>) => void;
106
106
  }
@@ -183,23 +183,6 @@ interface Test {
183
183
  todo: (name: string, callback?: () => void | Promise<void>) => void;
184
184
  }
185
185
 
186
- interface Actions {
187
- /**
188
- * Calls the given function with the provided arguments.
189
- */
190
- isCalledWith: (...args: Array<unknown>) => void;
191
- }
192
- interface When {
193
- /**
194
- * Creates a test plan.
195
- */
196
- <T>(): Actions;
197
- /**
198
- * Creates a test plan.
199
- */
200
- (target: unknown): Actions;
201
- }
202
-
203
186
  /**
204
187
  * The fill-in type. Useful to fill in the required type arguments of generic types.
205
188
  */
@@ -228,10 +211,6 @@ declare const it: Test;
228
211
  * Defines a single test.
229
212
  */
230
213
  declare const test: Test;
231
- /**
232
- * Creates a test plan.
233
- */
234
- declare const when: When;
235
214
 
236
- export { describe, expect, it, omit, pick, test, when };
215
+ export { describe, expect, it, omit, pick, test };
237
216
  export type { _ };
package/dist/index.js CHANGED
@@ -9,4 +9,4 @@ const noopChain = new Proxy(noop, {
9
9
  },
10
10
  });
11
11
 
12
- export { noopChain as describe, noopChain as expect, noopChain as it, noop as omit, noop as pick, noopChain as test, noopChain as when };
12
+ export { noopChain as describe, noopChain as expect, noopChain as it, noop as omit, noop as pick, noopChain as test };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tstyche",
3
- "version": "7.0.0-rc.1",
3
+ "version": "7.1.0",
4
4
  "description": "Everything You Need for Type Testing.",
5
5
  "keywords": [
6
6
  "typescript",
@@ -8,7 +8,7 @@
8
8
  "type": "boolean"
9
9
  },
10
10
  "checkSuppressedErrors": {
11
- "description": "Check errors silenced by '@ts-expect-error' directives.",
11
+ "description": "Check errors suppressed by '@ts-expect-error' directives.",
12
12
  "default": true,
13
13
  "type": "boolean"
14
14
  },
@@ -57,7 +57,7 @@
57
57
  }
58
58
  },
59
59
  "target": {
60
- "description": "The range of TypeScript versions to test against.",
60
+ "description": "The TypeScript version or range of versions to test against.",
61
61
  "default": "*",
62
62
  "type": "string"
63
63
  },