tstyche 5.0.0-beta.1 → 5.0.0-beta.2

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.
@@ -218,11 +218,11 @@ declare const describe: Describe;
218
218
  /**
219
219
  * Defines a single test.
220
220
  */
221
- declare const test: Test;
221
+ declare const it: Test;
222
222
  /**
223
223
  * Defines a single test.
224
224
  */
225
- declare const it: Test;
225
+ declare const test: Test;
226
226
  interface Actions {
227
227
  /**
228
228
  * Calls the given function with the provided arguments.
@@ -218,11 +218,11 @@ declare const describe: Describe;
218
218
  /**
219
219
  * Defines a single test.
220
220
  */
221
- declare const test: Test;
221
+ declare const it: Test;
222
222
  /**
223
223
  * Defines a single test.
224
224
  */
225
- declare const it: Test;
225
+ declare const test: Test;
226
226
  interface Actions {
227
227
  /**
228
228
  * Calls the given function with the provided arguments.
package/build/index.d.cts CHANGED
@@ -222,11 +222,11 @@ declare const describe: Describe;
222
222
  /**
223
223
  * Defines a single test.
224
224
  */
225
- declare const test: Test;
225
+ declare const it: Test;
226
226
  /**
227
227
  * Defines a single test.
228
228
  */
229
- declare const it: Test;
229
+ declare const test: Test;
230
230
  interface Actions {
231
231
  /**
232
232
  * Calls the given function with the provided arguments.
package/build/index.d.ts CHANGED
@@ -222,11 +222,11 @@ declare const describe: Describe;
222
222
  /**
223
223
  * Defines a single test.
224
224
  */
225
- declare const test: Test;
225
+ declare const it: Test;
226
226
  /**
227
227
  * Defines a single test.
228
228
  */
229
- declare const it: Test;
229
+ declare const test: Test;
230
230
  interface Actions {
231
231
  /**
232
232
  * Calls the given function with the provided arguments.
@@ -9,9 +9,9 @@ declare enum CancellationReason {
9
9
 
10
10
  declare class CancellationToken {
11
11
  #private;
12
- get isCancellationRequested(): boolean;
13
- get reason(): CancellationReason | undefined;
14
12
  cancel(reason: CancellationReason): void;
13
+ isCancellationRequested(): boolean;
14
+ getReason(): CancellationReason | undefined;
15
15
  reset(): void;
16
16
  }
17
17
 
@@ -35,6 +35,7 @@ interface SuppressedError {
35
35
  declare enum TestTreeNodeBrand {
36
36
  Describe = "describe",
37
37
  Test = "test",
38
+ It = "it",
38
39
  Expect = "expect",
39
40
  When = "when"
40
41
  }
package/build/tstyche.js CHANGED
@@ -2595,9 +2595,6 @@ class FileView {
2595
2595
  #indent = 0;
2596
2596
  #lines = [];
2597
2597
  #messages = [];
2598
- get hasErrors() {
2599
- return this.#messages.length > 0;
2600
- }
2601
2598
  addMessage(message) {
2602
2599
  this.#messages.push(message);
2603
2600
  }
@@ -2620,7 +2617,10 @@ class FileView {
2620
2617
  return this.#messages;
2621
2618
  }
2622
2619
  getViewText(options) {
2623
- return fileViewText(this.#lines, options?.appendEmptyLine || this.hasErrors);
2620
+ return fileViewText(this.#lines, options?.appendEmptyLine || this.hasErrors());
2621
+ }
2622
+ hasErrors() {
2623
+ return this.#messages.length > 0;
2624
2624
  }
2625
2625
  }
2626
2626
 
@@ -2631,7 +2631,7 @@ class ListReporter extends BaseReporter {
2631
2631
  #hasReportedError = false;
2632
2632
  #hasReportedUses = false;
2633
2633
  #isFileViewExpanded = false;
2634
- get #isLastFile() {
2634
+ #isLastFile() {
2635
2635
  return this.#fileCount === 0;
2636
2636
  }
2637
2637
  on([event, payload]) {
@@ -2684,8 +2684,8 @@ class ListReporter extends BaseReporter {
2684
2684
  OutputService.eraseLastLine();
2685
2685
  }
2686
2686
  OutputService.writeMessage(fileStatusText(payload.result.status, payload.result.file));
2687
- OutputService.writeMessage(this.#fileView.getViewText({ appendEmptyLine: this.#isLastFile }));
2688
- if (this.#fileView.hasErrors) {
2687
+ OutputService.writeMessage(this.#fileView.getViewText({ appendEmptyLine: this.#isLastFile() }));
2688
+ if (this.#fileView.hasErrors()) {
2689
2689
  OutputService.writeError(this.#fileView.getMessages());
2690
2690
  this.#hasReportedError = true;
2691
2691
  }
@@ -2829,18 +2829,18 @@ var CancellationReason;
2829
2829
  class CancellationToken {
2830
2830
  #isCancelled = false;
2831
2831
  #reason;
2832
- get isCancellationRequested() {
2833
- return this.#isCancelled;
2834
- }
2835
- get reason() {
2836
- return this.#reason;
2837
- }
2838
2832
  cancel(reason) {
2839
2833
  if (!this.#isCancelled) {
2840
2834
  this.#isCancelled = true;
2841
2835
  this.#reason = reason;
2842
2836
  }
2843
2837
  }
2838
+ isCancellationRequested() {
2839
+ return this.#isCancelled;
2840
+ }
2841
+ getReason() {
2842
+ return this.#reason;
2843
+ }
2844
2844
  reset() {
2845
2845
  if (this.#isCancelled) {
2846
2846
  this.#isCancelled = false;
@@ -3225,7 +3225,7 @@ class WatchService {
3225
3225
  for (const watcher of this.#watchers) {
3226
3226
  watcher.watch();
3227
3227
  }
3228
- while (!cancellationToken.isCancellationRequested) {
3228
+ while (!cancellationToken.isCancellationRequested()) {
3229
3229
  const testFiles = await debounce.schedule();
3230
3230
  if (testFiles.length > 0) {
3231
3231
  yield testFiles;
@@ -3257,6 +3257,9 @@ function deepCompareKeys(a, b, keys) {
3257
3257
  }
3258
3258
  return true;
3259
3259
  }
3260
+ function nodeBelongsToArgumentList(compiler, node) {
3261
+ return compiler.isCallExpression(node.parent) && node.parent.arguments.some((argument) => argument === node);
3262
+ }
3260
3263
  function nodeIsChildOfExpressionStatement(compiler, node) {
3261
3264
  return compiler.isExpressionStatement(node.parent);
3262
3265
  }
@@ -3310,18 +3313,37 @@ class AbilityLayer {
3310
3313
  [expectEnd, matcherNameEnd],
3311
3314
  ]);
3312
3315
  break;
3313
- case "toBeCallableWith":
3316
+ case "toBeCallableWith": {
3314
3317
  this.#nodes.push(expect);
3315
- this.#editor.eraseTrailingComma(expect.source);
3316
- this.#editor.replaceRanges([
3317
- [
3318
- expectStart,
3319
- expectExpressionEnd,
3320
- nodeIsChildOfExpressionStatement(this.#compiler, expect.matcherNode) ? ";" : "",
3321
- ],
3322
- [expectEnd, matcherNameEnd],
3323
- ]);
3318
+ const sourceNode = expect.source[0];
3319
+ if (!sourceNode) {
3320
+ return;
3321
+ }
3322
+ if (nodeBelongsToArgumentList(this.#compiler, sourceNode)) {
3323
+ this.#editor.eraseTrailingComma(expect.source);
3324
+ this.#editor.replaceRanges([
3325
+ [
3326
+ expectStart,
3327
+ expectExpressionEnd,
3328
+ nodeIsChildOfExpressionStatement(this.#compiler, expect.matcherNode) ? ";" : "",
3329
+ ],
3330
+ [expectEnd, matcherNameEnd],
3331
+ ]);
3332
+ }
3333
+ else {
3334
+ const sourceText = sourceNode.getFullText();
3335
+ this.#editor.replaceRanges([
3336
+ [
3337
+ expectStart,
3338
+ matcherNameEnd,
3339
+ nodeIsChildOfExpressionStatement(this.#compiler, expect.matcherNode)
3340
+ ? `;(undefined as any as ${sourceText})`
3341
+ : `(undefined as any as ${sourceText})`,
3342
+ ],
3343
+ ]);
3344
+ }
3324
3345
  break;
3346
+ }
3325
3347
  case "toBeConstructableWith":
3326
3348
  this.#nodes.push(expect);
3327
3349
  this.#editor.eraseTrailingComma(expect.source);
@@ -3675,14 +3697,15 @@ class IdentifierLookup {
3675
3697
  }
3676
3698
  switch (identifier) {
3677
3699
  case "describe":
3678
- return { brand: "describe", flags, identifier };
3700
+ return { brand: "describe", flags };
3679
3701
  case "it":
3702
+ return { brand: "it", flags };
3680
3703
  case "test":
3681
- return { brand: "test", flags, identifier };
3704
+ return { brand: "test", flags };
3682
3705
  case "expect":
3683
- return { brand: "expect", flags, identifier };
3706
+ return { brand: "expect", flags };
3684
3707
  case "when":
3685
- return { brand: "when", flags, identifier };
3708
+ return { brand: "when", flags };
3686
3709
  }
3687
3710
  return;
3688
3711
  }
@@ -3735,7 +3758,9 @@ class CollectService {
3735
3758
  if (!this.#checkNode(node, meta, parent)) {
3736
3759
  return;
3737
3760
  }
3738
- if (meta.brand === "describe" || meta.brand === "test") {
3761
+ if (meta.brand === "describe" ||
3762
+ meta.brand === "it" ||
3763
+ meta.brand === "test") {
3739
3764
  const testTreeNode = new TestTreeNode(this.#compiler, meta.brand, node, parent, meta.flags);
3740
3765
  this.#compiler.forEachChild(node, (node) => {
3741
3766
  this.#collectTestTreeNodes(node, testTreeNode, testTree);
@@ -3746,15 +3771,24 @@ class CollectService {
3746
3771
  if (meta.brand === "expect") {
3747
3772
  const modifierNode = this.#getChainedNode(node, "type");
3748
3773
  if (!modifierNode) {
3774
+ const text = "'expect()' must be followed by the '.type' modifier.";
3775
+ const origin = DiagnosticOrigin.fromNode(node);
3776
+ this.#onDiagnostics(Diagnostic.error(text, origin));
3749
3777
  return;
3750
3778
  }
3751
3779
  const notNode = this.#getChainedNode(modifierNode, "not");
3752
3780
  const matcherNameNode = this.#getChainedNode(notNode ?? modifierNode);
3753
3781
  if (!matcherNameNode) {
3782
+ const text = "The final element in the chain must be a matcher.";
3783
+ const origin = DiagnosticOrigin.fromNode(notNode ?? modifierNode);
3784
+ this.#onDiagnostics(Diagnostic.error(text, origin));
3754
3785
  return;
3755
3786
  }
3756
3787
  const matcherNode = this.#getMatcherNode(matcherNameNode);
3757
3788
  if (!matcherNode) {
3789
+ const text = "The matcher must be called with an argument.";
3790
+ const origin = DiagnosticOrigin.fromNode(matcherNameNode);
3791
+ this.#onDiagnostics(Diagnostic.error(text, origin));
3758
3792
  return;
3759
3793
  }
3760
3794
  const expectNode = new ExpectNode(this.#compiler, meta.brand, node, parent, meta.flags, matcherNode, matcherNameNode, modifierNode, notNode);
@@ -3768,17 +3802,25 @@ class CollectService {
3768
3802
  if (meta.brand === "when") {
3769
3803
  const actionNameNode = this.#getChainedNode(node);
3770
3804
  if (!actionNameNode) {
3805
+ const text = "The final element in the chain must be an action.";
3806
+ const origin = DiagnosticOrigin.fromNode(node);
3807
+ this.#onDiagnostics(Diagnostic.error(text, origin));
3771
3808
  return;
3772
3809
  }
3773
3810
  const actionNode = this.#getActionNode(actionNameNode);
3774
3811
  if (!actionNode) {
3812
+ const text = "The action must be called with an argument.";
3813
+ const origin = DiagnosticOrigin.fromNode(actionNameNode);
3814
+ this.#onDiagnostics(Diagnostic.error(text, origin));
3775
3815
  return;
3776
3816
  }
3777
3817
  this.#compiler.forEachChild(actionNode, (node) => {
3778
3818
  if (this.#compiler.isCallExpression(node)) {
3779
3819
  const meta = this.#identifierLookup.resolveTestTreeNodeMeta(node);
3780
- if (meta?.brand === "describe" || meta?.brand === "test") {
3781
- const text = CollectDiagnosticText.cannotBeNestedWithin(meta.identifier, "when");
3820
+ if (meta?.brand === "describe" ||
3821
+ meta?.brand === "it" ||
3822
+ meta?.brand === "test") {
3823
+ const text = CollectDiagnosticText.cannotBeNestedWithin(meta.brand, "when");
3782
3824
  const origin = DiagnosticOrigin.fromNode(node);
3783
3825
  this.#onDiagnostics(Diagnostic.error(text, origin));
3784
3826
  }
@@ -3811,7 +3853,7 @@ class CollectService {
3811
3853
  }
3812
3854
  #checkNode(node, meta, parent) {
3813
3855
  if ("brand" in parent && !this.#isNodeAllowed(meta, parent)) {
3814
- const text = CollectDiagnosticText.cannotBeNestedWithin(meta.identifier, parent.node.expression.getText());
3856
+ const text = CollectDiagnosticText.cannotBeNestedWithin(meta.brand, parent.brand);
3815
3857
  const origin = DiagnosticOrigin.fromNode(node);
3816
3858
  this.#onDiagnostics(Diagnostic.error(text, origin));
3817
3859
  return false;
@@ -3821,8 +3863,11 @@ class CollectService {
3821
3863
  #isNodeAllowed(meta, parent) {
3822
3864
  switch (meta.brand) {
3823
3865
  case "describe":
3866
+ case "it":
3824
3867
  case "test":
3825
- if (parent.brand === "test" || parent.brand === "expect") {
3868
+ if (parent.brand === "it" ||
3869
+ parent.brand === "test" ||
3870
+ parent.brand === "expect") {
3826
3871
  return false;
3827
3872
  }
3828
3873
  break;
@@ -3874,14 +3919,11 @@ class CollectService {
3874
3919
  }
3875
3920
  }
3876
3921
 
3877
- function nodeBelongsToArgumentList(compiler, node) {
3878
- return compiler.isCallExpression(node.parent) && node.parent.arguments.some((argument) => argument === node);
3879
- }
3880
-
3881
3922
  var TestTreeNodeBrand;
3882
3923
  (function (TestTreeNodeBrand) {
3883
3924
  TestTreeNodeBrand["Describe"] = "describe";
3884
3925
  TestTreeNodeBrand["Test"] = "test";
3926
+ TestTreeNodeBrand["It"] = "it";
3885
3927
  TestTreeNodeBrand["Expect"] = "expect";
3886
3928
  TestTreeNodeBrand["When"] = "when";
3887
3929
  })(TestTreeNodeBrand || (TestTreeNodeBrand = {}));
@@ -4702,19 +4744,8 @@ class ToBeCallableWith extends AbilityMatcherBase {
4702
4744
  explainText = ExpectDiagnosticText.isCallable;
4703
4745
  explainNotText = ExpectDiagnosticText.isNotCallable;
4704
4746
  match(matchWorker, sourceNode, targetNodes, onDiagnostics) {
4705
- let type;
4706
- if (this.compiler.isCallExpression(sourceNode)) {
4707
- type = matchWorker.typeChecker.getResolvedSignature(sourceNode)?.getReturnType();
4708
- }
4709
- if (this.compiler.isArrowFunction(sourceNode) ||
4710
- this.compiler.isFunctionDeclaration(sourceNode) ||
4711
- this.compiler.isFunctionExpression(sourceNode) ||
4712
- this.compiler.isExpressionWithTypeArguments(sourceNode) ||
4713
- this.compiler.isIdentifier(sourceNode) ||
4714
- this.compiler.isPropertyAccessExpression(sourceNode)) {
4715
- type = matchWorker.getType(sourceNode);
4716
- }
4717
- if (!type || type.getCallSignatures().length === 0) {
4747
+ const sourceType = matchWorker.getType(sourceNode);
4748
+ if (sourceType.getCallSignatures().length === 0) {
4718
4749
  const text = [];
4719
4750
  if (nodeBelongsToArgumentList(this.compiler, sourceNode)) {
4720
4751
  text.push(ExpectDiagnosticText.argumentMustBe("source", "a callable expression"));
@@ -4722,7 +4753,7 @@ class ToBeCallableWith extends AbilityMatcherBase {
4722
4753
  else {
4723
4754
  text.push(ExpectDiagnosticText.typeArgumentMustBe("Source", "a callable type"));
4724
4755
  }
4725
- if (type != null && type.getConstructSignatures().length > 0) {
4756
+ if (sourceType.getConstructSignatures().length > 0) {
4726
4757
  text.push(ExpectDiagnosticText.didYouMeanToUse("the '.toBeConstructableWith()' matcher"));
4727
4758
  }
4728
4759
  const origin = DiagnosticOrigin.fromNode(sourceNode);
@@ -5153,8 +5184,7 @@ class FixmeService {
5153
5184
  FixmeService.#range = FixmeService.#range?.previous;
5154
5185
  }
5155
5186
  if (isFail === false) {
5156
- const targetText = owner.node.expression.getText();
5157
- const text = [FixmeDiagnosticText.wasSupposedToFail(targetText), FixmeDiagnosticText.considerRemoving()];
5187
+ const text = [FixmeDiagnosticText.wasSupposedToFail(owner.brand), FixmeDiagnosticText.considerRemoving()];
5158
5188
  const origin = new DiagnosticOrigin(directive.namespace.start, directive.directive.end, directive.sourceFile);
5159
5189
  onFileDiagnostics([Diagnostic.error(text, origin)]);
5160
5190
  }
@@ -5206,7 +5236,7 @@ class TestTreeWalker {
5206
5236
  }
5207
5237
  async visit(nodes, runModeFlags, parentResult) {
5208
5238
  for (const node of nodes) {
5209
- if (this.#cancellationToken?.isCancellationRequested) {
5239
+ if (this.#cancellationToken?.isCancellationRequested()) {
5210
5240
  break;
5211
5241
  }
5212
5242
  const fixmeDirective = Directive.getDirectiveRange(this.#compiler, node, "fixme");
@@ -5217,6 +5247,7 @@ class TestTreeWalker {
5217
5247
  case "describe":
5218
5248
  await this.#visitDescribe(node, runModeFlags, parentResult);
5219
5249
  break;
5250
+ case "it":
5220
5251
  case "test":
5221
5252
  await this.#visitTest(node, runModeFlags, parentResult);
5222
5253
  break;
@@ -5348,7 +5379,7 @@ class FileRunner {
5348
5379
  EventEmitter.dispatch(["file:error", { diagnostics, result }]);
5349
5380
  }
5350
5381
  async run(file, cancellationToken) {
5351
- if (cancellationToken.isCancellationRequested) {
5382
+ if (cancellationToken.isCancellationRequested()) {
5352
5383
  return;
5353
5384
  }
5354
5385
  this.#projectService.openFile(file.path);
@@ -5423,7 +5454,7 @@ class FileRunner {
5423
5454
  class Runner {
5424
5455
  #eventEmitter = new EventEmitter();
5425
5456
  #resolvedConfig;
5426
- static version = "5.0.0-beta.1";
5457
+ static version = "5.0.0-beta.2";
5427
5458
  constructor(resolvedConfig) {
5428
5459
  this.#resolvedConfig = resolvedConfig;
5429
5460
  }
@@ -5487,7 +5518,7 @@ class Runner {
5487
5518
  EventEmitter.dispatch(["target:end", { result: targetResult }]);
5488
5519
  }
5489
5520
  EventEmitter.dispatch(["run:end", { result }]);
5490
- if (cancellationToken.reason === "failFast") {
5521
+ if (cancellationToken.getReason() === "failFast") {
5491
5522
  cancellationToken.reset();
5492
5523
  }
5493
5524
  }
@@ -5533,11 +5564,11 @@ class Cli {
5533
5564
  return;
5534
5565
  }
5535
5566
  const { commandLineOptions, pathMatch } = await Config.parseCommandLine(commandLine);
5536
- if (cancellationToken.isCancellationRequested) {
5567
+ if (cancellationToken.isCancellationRequested()) {
5537
5568
  return;
5538
5569
  }
5539
5570
  do {
5540
- if (cancellationToken.reason === "configChange") {
5571
+ if (cancellationToken.getReason() === "configChange") {
5541
5572
  cancellationToken.reset();
5542
5573
  exitCodeHandler.resetCode();
5543
5574
  OutputService.clearTerminal();
@@ -5551,7 +5582,7 @@ class Cli {
5551
5582
  commandLineOptions,
5552
5583
  pathMatch,
5553
5584
  });
5554
- if (cancellationToken.isCancellationRequested) {
5585
+ if (cancellationToken.isCancellationRequested()) {
5555
5586
  if (commandLine.includes("--watch")) {
5556
5587
  await this.#waitForChangedFiles(resolvedConfig, cancellationToken);
5557
5588
  }
@@ -5592,7 +5623,7 @@ class Cli {
5592
5623
  const runner = new Runner(resolvedConfig);
5593
5624
  await runner.run(testFiles, cancellationToken);
5594
5625
  PluginService.removeHandlers();
5595
- } while (cancellationToken.reason === "configChange");
5626
+ } while (cancellationToken.getReason() === "configChange");
5596
5627
  this.#eventEmitter.removeHandlers();
5597
5628
  }
5598
5629
  #waitForChangedFiles(resolvedConfig, cancellationToken) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tstyche",
3
- "version": "5.0.0-beta.1",
3
+ "version": "5.0.0-beta.2",
4
4
  "description": "Everything You Need for Type Testing.",
5
5
  "keywords": [
6
6
  "typescript",