tstyche 7.0.0-beta.1 → 7.0.0-beta.3

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
@@ -40,28 +40,36 @@ To group and organize tests, TSTyche has:
40
40
  The `expect` style assertions can check either the inferred type of an expression (as in the example above) or a type directly:
41
41
 
42
42
  ```ts
43
- import { expect } from "tstyche";
43
+ import { type _, expect } from "tstyche";
44
44
 
45
45
  type AsyncProps<T> = {
46
46
  [K in keyof T]+?: T[K] | Promise<T[K]>;
47
47
  };
48
48
 
49
- type WithLoading<T> = T & { loading: boolean };
49
+ type WithLoading<T extends object> = T & { loading: boolean };
50
50
 
51
51
  expect<WithLoading<AsyncProps<{ query: string }>>>().type.toBe<{
52
52
  query?: string | Promise<string>;
53
53
  loading: boolean;
54
54
  }>();
55
+
56
+ expect<WithLoading<_>>().type.not.toBeInstantiableWith<[string]>();
55
57
  ```
56
58
 
57
- Here is the list of all matchers:
59
+ Relation matchers:
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.
64
+
65
+ Ability matchers:
58
66
 
59
- - `.toBe()`, `.toBeAssignableFrom()`, `.toBeAssignableTo()` compare types or type of expressions,
60
- - `.toAcceptProps()` checks the type of JSX component props,
61
- - `.toBeApplicable` ensures that the decorator function can be applied,
62
- - `.toBeCallableWith()` checks whether a function is callable with the given arguments,
63
- - `.toBeConstructableWith()` checks whether a class is constructable with the given arguments,
64
- - `.toHaveProperty()` looks up keys on an object type.
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.
65
73
 
66
74
  ## Runner
67
75
 
@@ -73,7 +81,7 @@ tstyche query-params --only multiple --target '>=5.6'
73
81
 
74
82
  It is that simple! Actually, TSTyche does even more:
75
83
 
76
- - checks messages of errors suppressed by `// @ts-expect-error`,
84
+ - checks messages of errors suppressed by `@ts-expect-error` directives,
77
85
  - generates type tests from a data table,
78
86
  - runs tests in watch mode.
79
87
 
@@ -1038,7 +1038,7 @@ class Options {
1038
1038
  },
1039
1039
  {
1040
1040
  brand: "boolean",
1041
- description: "Check errors silenced by '// @ts-expect-error' directives.",
1041
+ description: "Check errors silenced by '@ts-expect-error' directives.",
1042
1042
  group: 4,
1043
1043
  name: "checkSuppressedErrors",
1044
1044
  },
@@ -3450,6 +3450,51 @@ class AbilityLayer {
3450
3450
  }
3451
3451
  break;
3452
3452
  }
3453
+ case "toBeInstantiableWith": {
3454
+ this.#nodes.push(expect);
3455
+ const sourceNode = expect.source[0];
3456
+ const targetNode = expect.target?.[0];
3457
+ if (!sourceNode) {
3458
+ return;
3459
+ }
3460
+ if (nodeBelongsToArgumentList(this.#compiler, sourceNode)) {
3461
+ this.#editor.eraseTrailingComma(expect.source);
3462
+ this.#editor.replaceRanges([
3463
+ [
3464
+ expectStart,
3465
+ expectExpressionEnd,
3466
+ nodeIsChildOfExpressionStatement(this.#compiler, expect.matcherNode) ? ";" : "",
3467
+ ],
3468
+ [expectEnd, matcherNodeEnd],
3469
+ ]);
3470
+ if (this.#compiler.isExpressionWithTypeArguments(sourceNode)) {
3471
+ this.#editor.replaceRanges([[sourceNode.expression.getEnd(), sourceNode.getEnd()]]);
3472
+ }
3473
+ }
3474
+ else {
3475
+ const sourceText = this.#compiler.isTypeReferenceNode(sourceNode)
3476
+ ? sourceNode.typeName.getText()
3477
+ : sourceNode.getText();
3478
+ this.#editor.replaceRanges([
3479
+ [
3480
+ expectStart,
3481
+ matcherNodeEnd,
3482
+ nodeIsChildOfExpressionStatement(this.#compiler, expect.matcherNode)
3483
+ ? `;undefined as any as ${sourceText}`
3484
+ : `undefined as any as ${sourceText}`,
3485
+ ],
3486
+ ]);
3487
+ }
3488
+ if (targetNode != null) {
3489
+ const targetText = targetNode.getText().slice(1, -1);
3490
+ if (targetText.trim().length > 1) {
3491
+ this.#editor.replaceRanges([
3492
+ [targetNode.getFullStart(), targetNode.getEnd(), `<${targetText}>`.padStart(targetNode.getFullWidth())],
3493
+ ]);
3494
+ }
3495
+ }
3496
+ break;
3497
+ }
3453
3498
  case "toHaveProperty": {
3454
3499
  this.#nodes.push(expect);
3455
3500
  const sourceNode = expect.source[0];
@@ -3566,7 +3611,7 @@ class SourceTextEditor {
3566
3611
  class SuppressedLayer {
3567
3612
  #compiler;
3568
3613
  #editor;
3569
- #expectErrorRegex = /^(\s*)(\/\/ *@ts-expect-error)(!?)(:? *)(.*)?$/gim;
3614
+ #expectErrorRegex = /^([ \t/*{]*)(@ts-expect-error)(!?)(:? *)(.*?)(?:\*\/.*)?$/gim;
3570
3615
  #resolvedConfig;
3571
3616
  #suppressedErrorsMap;
3572
3617
  constructor(compiler, editor, resolvedConfig) {
@@ -4327,10 +4372,13 @@ class EnsureDiagnosticText {
4327
4372
  static argumentOrTypeArgumentMustBeProvided(argumentNameText, typeArgumentNameText) {
4328
4373
  return `An argument for '${argumentNameText}' or type argument for '${typeArgumentNameText}' must be provided.`;
4329
4374
  }
4375
+ static typeArgumentMustBeProvided(typeArgumentNameText) {
4376
+ return `Type argument for '${typeArgumentNameText}' must be provided.`;
4377
+ }
4330
4378
  }
4331
4379
 
4332
- function argumentIsProvided(argumentNameText, node, enclosingNode, onDiagnostics) {
4333
- if (!node) {
4380
+ function argumentIsProvided(compiler, argumentNameText, node, enclosingNode, onDiagnostics) {
4381
+ if (!node || !nodeBelongsToArgumentList(compiler, node)) {
4334
4382
  const text = EnsureDiagnosticText.argumentMustBeProvided(argumentNameText);
4335
4383
  const origin = DiagnosticOrigin.fromNode(enclosingNode);
4336
4384
  onDiagnostics([Diagnostic.error(text, origin)]);
@@ -4349,6 +4397,16 @@ function argumentOrTypeArgumentIsProvided(argumentNameText, typeArgumentNameText
4349
4397
  return true;
4350
4398
  }
4351
4399
 
4400
+ function typeArgumentIsProvided(compiler, typeArgumentNameText, node, enclosingNode, onDiagnostics) {
4401
+ if (!node || nodeBelongsToArgumentList(compiler, node)) {
4402
+ const text = EnsureDiagnosticText.typeArgumentMustBeProvided(typeArgumentNameText);
4403
+ const origin = DiagnosticOrigin.fromNode(enclosingNode);
4404
+ onDiagnostics([Diagnostic.error(text, origin)]);
4405
+ return false;
4406
+ }
4407
+ return true;
4408
+ }
4409
+
4352
4410
  class ExpectDiagnosticText {
4353
4411
  static argumentMustBe(argumentNameText, expectedText) {
4354
4412
  return `An argument for '${argumentNameText}' must be ${expectedText}.`;
@@ -4368,6 +4426,12 @@ class ExpectDiagnosticText {
4368
4426
  static isNotConstructable(isExpression, targetText) {
4369
4427
  return `${isExpression ? "Expression" : "Type"} is not constructable ${targetText}.`;
4370
4428
  }
4429
+ static isInstantiable(isExpression, targetText) {
4430
+ return `${isExpression ? "Expression" : "Type"} is instantiable ${targetText}.`;
4431
+ }
4432
+ static isNotInstantiable(isExpression, targetText) {
4433
+ return `${isExpression ? "Expression" : "Type"} is not instantiable ${targetText}.`;
4434
+ }
4371
4435
  static acceptsProps(isExpression) {
4372
4436
  return `${isExpression ? "Component" : "Component type"} accepts props of the given type.`;
4373
4437
  }
@@ -5335,7 +5399,7 @@ class AbilityMatcherBase {
5335
5399
  constructor(compiler) {
5336
5400
  this.compiler = compiler;
5337
5401
  }
5338
- #resolveTargetText(nodes) {
5402
+ getArgumentCountText(nodes) {
5339
5403
  if (nodes.length === 0) {
5340
5404
  return "without arguments";
5341
5405
  }
@@ -5344,15 +5408,21 @@ class AbilityMatcherBase {
5344
5408
  }
5345
5409
  return `with the given argument${nodes.length === 1 ? "" : "s"}`;
5346
5410
  }
5347
- explain(matchWorker, sourceNode, targetNodes) {
5411
+ getTypeArgumentCountText(targetNode) {
5412
+ if (targetNode.elements.length === 0) {
5413
+ return "without type arguments";
5414
+ }
5415
+ return `with the given type argument${targetNode.elements.length === 1 ? "" : "s"}`;
5416
+ }
5417
+ explain(matchWorker, sourceNode, targetNode, getArgumentCountText) {
5348
5418
  const isExpression = nodeBelongsToArgumentList(this.compiler, sourceNode);
5349
- const targetText = this.#resolveTargetText(targetNodes);
5419
+ const argumentCountText = getArgumentCountText();
5350
5420
  const diagnostics = [];
5351
5421
  if (matchWorker.assertionNode.abilityDiagnostics.size > 0) {
5352
5422
  for (const diagnostic of matchWorker.assertionNode.abilityDiagnostics) {
5353
- const text = [this.explainNotText(isExpression, targetText), getDiagnosticMessageText(diagnostic)];
5423
+ const text = [this.explainNotText(isExpression, argumentCountText), getDiagnosticMessageText(diagnostic)];
5354
5424
  let origin;
5355
- if (isDiagnosticWithLocation(diagnostic) && diagnosticBelongsToNode(diagnostic, targetNodes)) {
5425
+ if (isDiagnosticWithLocation(diagnostic) && diagnosticBelongsToNode(diagnostic, targetNode)) {
5356
5426
  origin = new DiagnosticOrigin(diagnostic.start, getTextSpanEnd(diagnostic), sourceNode.getSourceFile(), matchWorker.assertionNode);
5357
5427
  }
5358
5428
  else {
@@ -5367,7 +5437,7 @@ class AbilityMatcherBase {
5367
5437
  }
5368
5438
  else {
5369
5439
  const origin = DiagnosticOrigin.fromAssertion(matchWorker.assertionNode);
5370
- diagnostics.push(Diagnostic.error(this.explainText(isExpression, targetText), origin));
5440
+ diagnostics.push(Diagnostic.error(this.explainText(isExpression, argumentCountText), origin));
5371
5441
  }
5372
5442
  return diagnostics;
5373
5443
  }
@@ -5394,7 +5464,7 @@ class ToBeCallableWith extends AbilityMatcherBase {
5394
5464
  return;
5395
5465
  }
5396
5466
  return {
5397
- explain: () => this.explain(matchWorker, sourceNode, targetNodes),
5467
+ explain: () => this.explain(matchWorker, sourceNode, targetNodes, () => this.getArgumentCountText(targetNodes)),
5398
5468
  isMatch: matchWorker.assertionNode.abilityDiagnostics.size === 0,
5399
5469
  };
5400
5470
  }
@@ -5421,7 +5491,38 @@ class ToBeConstructableWith extends AbilityMatcherBase {
5421
5491
  return;
5422
5492
  }
5423
5493
  return {
5424
- explain: () => this.explain(matchWorker, sourceNode, targetNodes),
5494
+ explain: () => this.explain(matchWorker, sourceNode, targetNodes, () => this.getArgumentCountText(targetNodes)),
5495
+ isMatch: matchWorker.assertionNode.abilityDiagnostics.size === 0,
5496
+ };
5497
+ }
5498
+ }
5499
+
5500
+ class ToBeInstantiableWith extends AbilityMatcherBase {
5501
+ explainText = ExpectDiagnosticText.isInstantiable;
5502
+ explainNotText = ExpectDiagnosticText.isNotInstantiable;
5503
+ match(matchWorker, sourceNode, targetNode, onDiagnostics) {
5504
+ if (!(this.compiler.isIdentifier(sourceNode) ||
5505
+ this.compiler.isTypeReferenceNode(sourceNode) ||
5506
+ this.compiler.isExpressionWithTypeArguments(sourceNode))) {
5507
+ let text;
5508
+ if (nodeBelongsToArgumentList(this.compiler, sourceNode)) {
5509
+ text = ExpectDiagnosticText.argumentMustBe("source", "an instantiable expression");
5510
+ }
5511
+ else {
5512
+ text = ExpectDiagnosticText.typeArgumentMustBe("Source", "an instantiable type");
5513
+ }
5514
+ const origin = DiagnosticOrigin.fromNode(sourceNode);
5515
+ onDiagnostics([Diagnostic.error(text, origin)]);
5516
+ return;
5517
+ }
5518
+ if (!this.compiler.isTupleTypeNode(targetNode)) {
5519
+ const text = ExpectDiagnosticText.typeArgumentMustBe("Target", "a tuple type");
5520
+ const origin = DiagnosticOrigin.fromNode(targetNode);
5521
+ onDiagnostics([Diagnostic.error(text, origin)]);
5522
+ return;
5523
+ }
5524
+ return {
5525
+ explain: () => this.explain(matchWorker, sourceNode, targetNode, () => this.getTypeArgumentCountText(targetNode)),
5425
5526
  isMatch: matchWorker.assertionNode.abilityDiagnostics.size === 0,
5426
5527
  };
5427
5528
  }
@@ -5572,6 +5673,7 @@ class ExpectService {
5572
5673
  toBeAssignableTo;
5573
5674
  toBeCallableWith;
5574
5675
  toBeConstructableWith;
5676
+ toBeInstantiableWith;
5575
5677
  toHaveProperty;
5576
5678
  toRaiseError;
5577
5679
  constructor(compiler, program, reject) {
@@ -5585,6 +5687,7 @@ class ExpectService {
5585
5687
  this.toBeAssignableTo = new ToBeAssignableTo();
5586
5688
  this.toBeCallableWith = new ToBeCallableWith(compiler);
5587
5689
  this.toBeConstructableWith = new ToBeConstructableWith(compiler);
5690
+ this.toBeInstantiableWith = new ToBeInstantiableWith(compiler);
5588
5691
  this.toHaveProperty = new ToHaveProperty(compiler);
5589
5692
  this.toRaiseError = new ToRaiseError(compiler);
5590
5693
  }
@@ -5594,7 +5697,7 @@ class ExpectService {
5594
5697
  return;
5595
5698
  }
5596
5699
  const matchWorker = new MatchWorker(this.#compiler, this.#program, assertionNode);
5597
- if (!(matcherNameText === "toRaiseError" && !assertionNode.isNot) &&
5700
+ if (!(matcherNameText === "toBeInstantiableWith" || (matcherNameText === "toRaiseError" && !assertionNode.isNot)) &&
5598
5701
  this.#reject.argumentType([
5599
5702
  ["source", assertionNode.source[0]],
5600
5703
  ["target", assertionNode.target?.[0]],
@@ -5616,8 +5719,14 @@ class ExpectService {
5616
5719
  case "toBeConstructableWith":
5617
5720
  case "toRaiseError":
5618
5721
  return this[matcherNameText].match(matchWorker, assertionNode.source[0], assertionNode.target, onDiagnostics);
5722
+ case "toBeInstantiableWith": {
5723
+ if (!typeArgumentIsProvided(this.#compiler, "Target", assertionNode.target?.[0], assertionNode.matcherNameNode.name, onDiagnostics)) {
5724
+ return;
5725
+ }
5726
+ return this.toBeInstantiableWith.match(matchWorker, assertionNode.source[0], assertionNode.target[0], onDiagnostics);
5727
+ }
5619
5728
  case "toHaveProperty":
5620
- if (!argumentIsProvided("key", assertionNode.target?.[0], assertionNode.matcherNameNode.name, onDiagnostics)) {
5729
+ if (!argumentIsProvided(this.#compiler, "key", assertionNode.target?.[0], assertionNode.matcherNameNode.name, onDiagnostics)) {
5621
5730
  return;
5622
5731
  }
5623
5732
  return this.toHaveProperty.match(matchWorker, assertionNode.source[0], assertionNode.target[0], onDiagnostics);
@@ -5701,14 +5810,16 @@ class WhenDiagnosticText {
5701
5810
  }
5702
5811
 
5703
5812
  class WhenService {
5813
+ #compiler;
5704
5814
  #onDiagnostics;
5705
5815
  #reject;
5706
- constructor(reject, onDiagnostics) {
5816
+ constructor(compiler, reject, onDiagnostics) {
5817
+ this.#compiler = compiler;
5707
5818
  this.#reject = reject;
5708
5819
  this.#onDiagnostics = onDiagnostics;
5709
5820
  }
5710
5821
  action(when) {
5711
- if (!argumentIsProvided("target", when.target[0], when.node.expression, this.#onDiagnostics) ||
5822
+ if (!argumentIsProvided(this.#compiler, "target", when.target[0], when.node.expression, this.#onDiagnostics) ||
5712
5823
  this.#reject.argumentType([["target", when.target[0]]], this.#onDiagnostics)) {
5713
5824
  return;
5714
5825
  }
@@ -5825,7 +5936,7 @@ class TestTreeWalker {
5825
5936
  this.#position = options.position;
5826
5937
  const reject = new Reject(compiler, program, resolvedConfig);
5827
5938
  this.#expectService = new ExpectService(compiler, program, reject);
5828
- this.#whenService = new WhenService(reject, onFileDiagnostics);
5939
+ this.#whenService = new WhenService(compiler, reject, onFileDiagnostics);
5829
5940
  }
5830
5941
  async #resolveRunMode(flags, node) {
5831
5942
  const ifDirective = Directive.getDirectiveRange(this.#compiler, node, "if");
@@ -6065,7 +6176,7 @@ class FileRunner {
6065
6176
  class Runner {
6066
6177
  #eventEmitter = new EventEmitter();
6067
6178
  #resolvedConfig;
6068
- static version = "7.0.0-beta.1";
6179
+ static version = "7.0.0-beta.3";
6069
6180
  constructor(resolvedConfig) {
6070
6181
  this.#resolvedConfig = resolvedConfig;
6071
6182
  }
@@ -6205,7 +6316,7 @@ class Cli {
6205
6316
  }
6206
6317
  if (!commandLineOptions.config) {
6207
6318
  const oldConfigFilePath = Path.resolve(Config.resolveRootPath(commandLineOptions.root), "./tstyche.config.json");
6208
- if (existsSync(oldConfigFilePath) && !environmentOptions.isCi) {
6319
+ if (existsSync(oldConfigFilePath)) {
6209
6320
  const newConfigFilePath = Path.resolve(Config.resolveConfigFilePath(undefined, commandLineOptions.root));
6210
6321
  await fs.rename(oldConfigFilePath, newConfigFilePath);
6211
6322
  this.#deferredDiagnostics = Diagnostic.warning(CliDiagnosticText.configLocationChanged(oldConfigFilePath, newConfigFilePath));
package/dist/bin.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import process from 'node:process';
3
- import { Cli } from './tstyche.js';
3
+ import { Cli } from './api.js';
4
4
 
5
5
  const cli = new Cli();
6
6
  await cli.run(process.argv.slice(2));
package/dist/index.d.cts CHANGED
@@ -28,119 +28,84 @@ interface Describe {
28
28
  */
29
29
  todo: (name: string, callback?: () => void | Promise<void>) => void;
30
30
  }
31
- interface Test {
32
- /**
33
- * Defines a single test.
34
- *
35
- * @param name - The name of the test.
36
- * @param callback - The function with a code snippet and assertions.
37
- */
38
- (name: string, callback: () => void | Promise<void>): void;
39
- /**
40
- * Marks a test as focused.
41
- *
42
- * @param name - The name of the test.
43
- * @param callback - The function with a code snippet and assertions.
44
- */
45
- only: (name: string, callback: () => void | Promise<void>) => void;
46
- /**
47
- * Marks a test as skipped.
48
- *
49
- * @param name - The name of the test.
50
- * @param callback - The function with a code snippet and assertions.
51
- */
52
- skip: (name: string, callback: () => void | Promise<void>) => void;
53
- /**
54
- * Marks a test as yet to be implemented.
55
- *
56
- * @param name - The name of the test.
57
- * @param callback - The function with a code snippet and assertions.
58
- */
59
- todo: (name: string, callback?: () => void | Promise<void>) => void;
60
- }
31
+
61
32
  interface Matchers {
62
33
  /**
63
- * Checks if the JSX component accepts props of the given type.
64
- *
65
- * @remarks
66
- *
67
- * This is a work in progress feature. Generic components are not yet supported.
34
+ * Checks if the type is the same as the given type.
68
35
  */
69
- toAcceptProps: {
36
+ toBe: {
70
37
  /**
71
- * Checks if the JSX component accepts props of the given type.
72
- *
73
- * @remarks
74
- *
75
- * This is a work in progress feature. Generic components are not yet supported.
38
+ * Checks if the type is the same as the given type.
76
39
  */
77
40
  <Target>(): void;
78
41
  /**
79
- * Checks if the JSX component accepts the given props.
80
- *
81
- * @remarks
82
- *
83
- * This is a work in progress feature. Generic components are not yet supported.
42
+ * Checks if the type is the same as type of the given expression.
84
43
  */
85
44
  (target: unknown): void;
86
45
  };
87
46
  /**
88
- * Checks if the source type is the same as the target type.
47
+ * Checks if the type is assignable from the given type.
89
48
  */
90
- toBe: {
49
+ toBeAssignableFrom: {
91
50
  /**
92
- * Checks if the source type is the same as the target type.
51
+ * Checks if the type is assignable from the given type.
93
52
  */
94
53
  <Target>(): void;
95
54
  /**
96
- * Checks if the source type is the same as type of the target expression.
55
+ * Checks if the type is assignable from type of the given expression.
97
56
  */
98
57
  (target: unknown): void;
99
58
  };
100
59
  /**
101
- * Checks if the decorator function can be applied.
60
+ * Checks if the type is assignable to the given type.
102
61
  */
103
- toBeApplicable: (target: unknown, context: DecoratorContext) => void;
104
- /**
105
- * Checks if the source type is assignable from the target type.
106
- */
107
- toBeAssignableFrom: {
62
+ toBeAssignableTo: {
108
63
  /**
109
- * Checks if the source type is assignable from the target type.
64
+ * Checks if the type is assignable to the given type.
110
65
  */
111
66
  <Target>(): void;
112
67
  /**
113
- * Checks if the source type is assignable from type of the target expression.
68
+ * Checks if the type is assignable to type of the given expression.
114
69
  */
115
70
  (target: unknown): void;
116
71
  };
72
+ }
73
+ interface Matchers {
117
74
  /**
118
- * Checks if the source type is assignable to the target type.
75
+ * Checks if the JSX component accepts the given props.
119
76
  */
120
- toBeAssignableTo: {
77
+ toAcceptProps: {
121
78
  /**
122
- * Checks if the source type is assignable to the target type.
79
+ * Checks if the JSX component accepts props of the given type.
123
80
  */
124
81
  <Target>(): void;
125
82
  /**
126
- * Checks if the source type is assignable to type of the target expression.
83
+ * Checks if the JSX component accepts the given props.
127
84
  */
128
85
  (target: unknown): void;
129
86
  };
130
87
  /**
131
- * Checks if the source type is callable with the given arguments.
88
+ * Checks if the decorator is applicable to the given class or class member.
89
+ */
90
+ toBeApplicable: (target: unknown, context: DecoratorContext) => void;
91
+ /**
92
+ * Checks if the function is callable with the given arguments.
132
93
  */
133
94
  toBeCallableWith: (...args: Array<unknown>) => void;
134
95
  /**
135
- * Checks if the source type is constructable with the given arguments.
96
+ * Checks if the class is constructable with the given arguments.
136
97
  */
137
98
  toBeConstructableWith: (...args: Array<unknown>) => void;
138
99
  /**
139
- * Checks if a property key exists on the source type.
100
+ * Checks if the generic is instantiable with the given type arguments.
101
+ */
102
+ toBeInstantiableWith: <Target extends [...args: Array<unknown>]>() => void;
103
+ /**
104
+ * Checks if the type has the given property.
140
105
  */
141
106
  toHaveProperty: (key: string | number | symbol) => void;
142
107
  /**
143
- * Checks if the source type raises an error.
108
+ * Checks if the type raises an error.
144
109
  */
145
110
  toRaiseError: (...target: Array<string | number | RegExp>) => void;
146
111
  }
@@ -203,6 +168,63 @@ interface Expect {
203
168
  (source: unknown): Modifier;
204
169
  };
205
170
  }
171
+
172
+ interface Test {
173
+ /**
174
+ * Defines a single test.
175
+ *
176
+ * @param name - The name of the test.
177
+ * @param callback - The function with a code snippet and assertions.
178
+ */
179
+ (name: string, callback: () => void | Promise<void>): void;
180
+ /**
181
+ * Marks a test as focused.
182
+ *
183
+ * @param name - The name of the test.
184
+ * @param callback - The function with a code snippet and assertions.
185
+ */
186
+ only: (name: string, callback: () => void | Promise<void>) => void;
187
+ /**
188
+ * Marks a test as skipped.
189
+ *
190
+ * @param name - The name of the test.
191
+ * @param callback - The function with a code snippet and assertions.
192
+ */
193
+ skip: (name: string, callback: () => void | Promise<void>) => void;
194
+ /**
195
+ * Marks a test as yet to be implemented.
196
+ *
197
+ * @param name - The name of the test.
198
+ * @param callback - The function with a code snippet and assertions.
199
+ */
200
+ todo: (name: string, callback?: () => void | Promise<void>) => void;
201
+ }
202
+
203
+ interface Actions {
204
+ /**
205
+ * Calls the given function with the provided arguments.
206
+ */
207
+ isCalledWith: (...args: Array<unknown>) => void;
208
+ }
209
+ interface When {
210
+ /**
211
+ * Creates a test plan.
212
+ *
213
+ * @template Target - The type upon which an action is performed.
214
+ */
215
+ <Target>(): Actions;
216
+ /**
217
+ * Creates a test plan.
218
+ *
219
+ * @param target - The expression upon which an action is performed.
220
+ */
221
+ (target: unknown): Actions;
222
+ }
223
+
224
+ /**
225
+ * The fill-in type. Useful to fill in the required type arguments of generic types.
226
+ */
227
+ type _ = never;
206
228
  /**
207
229
  * Builds an assertion.
208
230
  */
@@ -227,29 +249,10 @@ declare const it: Test;
227
249
  * Defines a single test.
228
250
  */
229
251
  declare const test: Test;
230
- interface Actions {
231
- /**
232
- * Calls the given function with the provided arguments.
233
- */
234
- isCalledWith: (...args: Array<unknown>) => void;
235
- }
236
- interface When {
237
- /**
238
- * Creates a test plan.
239
- *
240
- * @template Target - The type upon which an action is performed.
241
- */
242
- <Target>(): Actions;
243
- /**
244
- * Creates a test plan.
245
- *
246
- * @param target - The expression upon which an action is performed.
247
- */
248
- (target: unknown): Actions;
249
- }
250
252
  /**
251
253
  * Creates a test plan.
252
254
  */
253
255
  declare const when: When;
254
256
 
255
257
  export { describe, expect, it, omit, pick, test, when };
258
+ export type { _ };
package/dist/index.d.ts CHANGED
@@ -28,119 +28,84 @@ interface Describe {
28
28
  */
29
29
  todo: (name: string, callback?: () => void | Promise<void>) => void;
30
30
  }
31
- interface Test {
32
- /**
33
- * Defines a single test.
34
- *
35
- * @param name - The name of the test.
36
- * @param callback - The function with a code snippet and assertions.
37
- */
38
- (name: string, callback: () => void | Promise<void>): void;
39
- /**
40
- * Marks a test as focused.
41
- *
42
- * @param name - The name of the test.
43
- * @param callback - The function with a code snippet and assertions.
44
- */
45
- only: (name: string, callback: () => void | Promise<void>) => void;
46
- /**
47
- * Marks a test as skipped.
48
- *
49
- * @param name - The name of the test.
50
- * @param callback - The function with a code snippet and assertions.
51
- */
52
- skip: (name: string, callback: () => void | Promise<void>) => void;
53
- /**
54
- * Marks a test as yet to be implemented.
55
- *
56
- * @param name - The name of the test.
57
- * @param callback - The function with a code snippet and assertions.
58
- */
59
- todo: (name: string, callback?: () => void | Promise<void>) => void;
60
- }
31
+
61
32
  interface Matchers {
62
33
  /**
63
- * Checks if the JSX component accepts props of the given type.
64
- *
65
- * @remarks
66
- *
67
- * This is a work in progress feature. Generic components are not yet supported.
34
+ * Checks if the type is the same as the given type.
68
35
  */
69
- toAcceptProps: {
36
+ toBe: {
70
37
  /**
71
- * Checks if the JSX component accepts props of the given type.
72
- *
73
- * @remarks
74
- *
75
- * This is a work in progress feature. Generic components are not yet supported.
38
+ * Checks if the type is the same as the given type.
76
39
  */
77
40
  <Target>(): void;
78
41
  /**
79
- * Checks if the JSX component accepts the given props.
80
- *
81
- * @remarks
82
- *
83
- * This is a work in progress feature. Generic components are not yet supported.
42
+ * Checks if the type is the same as type of the given expression.
84
43
  */
85
44
  (target: unknown): void;
86
45
  };
87
46
  /**
88
- * Checks if the source type is the same as the target type.
47
+ * Checks if the type is assignable from the given type.
89
48
  */
90
- toBe: {
49
+ toBeAssignableFrom: {
91
50
  /**
92
- * Checks if the source type is the same as the target type.
51
+ * Checks if the type is assignable from the given type.
93
52
  */
94
53
  <Target>(): void;
95
54
  /**
96
- * Checks if the source type is the same as type of the target expression.
55
+ * Checks if the type is assignable from type of the given expression.
97
56
  */
98
57
  (target: unknown): void;
99
58
  };
100
59
  /**
101
- * Checks if the decorator function can be applied.
60
+ * Checks if the type is assignable to the given type.
102
61
  */
103
- toBeApplicable: (target: unknown, context: DecoratorContext) => void;
104
- /**
105
- * Checks if the source type is assignable from the target type.
106
- */
107
- toBeAssignableFrom: {
62
+ toBeAssignableTo: {
108
63
  /**
109
- * Checks if the source type is assignable from the target type.
64
+ * Checks if the type is assignable to the given type.
110
65
  */
111
66
  <Target>(): void;
112
67
  /**
113
- * Checks if the source type is assignable from type of the target expression.
68
+ * Checks if the type is assignable to type of the given expression.
114
69
  */
115
70
  (target: unknown): void;
116
71
  };
72
+ }
73
+ interface Matchers {
117
74
  /**
118
- * Checks if the source type is assignable to the target type.
75
+ * Checks if the JSX component accepts the given props.
119
76
  */
120
- toBeAssignableTo: {
77
+ toAcceptProps: {
121
78
  /**
122
- * Checks if the source type is assignable to the target type.
79
+ * Checks if the JSX component accepts props of the given type.
123
80
  */
124
81
  <Target>(): void;
125
82
  /**
126
- * Checks if the source type is assignable to type of the target expression.
83
+ * Checks if the JSX component accepts the given props.
127
84
  */
128
85
  (target: unknown): void;
129
86
  };
130
87
  /**
131
- * Checks if the source type is callable with the given arguments.
88
+ * Checks if the decorator is applicable to the given class or class member.
89
+ */
90
+ toBeApplicable: (target: unknown, context: DecoratorContext) => void;
91
+ /**
92
+ * Checks if the function is callable with the given arguments.
132
93
  */
133
94
  toBeCallableWith: (...args: Array<unknown>) => void;
134
95
  /**
135
- * Checks if the source type is constructable with the given arguments.
96
+ * Checks if the class is constructable with the given arguments.
136
97
  */
137
98
  toBeConstructableWith: (...args: Array<unknown>) => void;
138
99
  /**
139
- * Checks if a property key exists on the source type.
100
+ * Checks if the generic is instantiable with the given type arguments.
101
+ */
102
+ toBeInstantiableWith: <Target extends [...args: Array<unknown>]>() => void;
103
+ /**
104
+ * Checks if the type has the given property.
140
105
  */
141
106
  toHaveProperty: (key: string | number | symbol) => void;
142
107
  /**
143
- * Checks if the source type raises an error.
108
+ * Checks if the type raises an error.
144
109
  */
145
110
  toRaiseError: (...target: Array<string | number | RegExp>) => void;
146
111
  }
@@ -203,6 +168,63 @@ interface Expect {
203
168
  (source: unknown): Modifier;
204
169
  };
205
170
  }
171
+
172
+ interface Test {
173
+ /**
174
+ * Defines a single test.
175
+ *
176
+ * @param name - The name of the test.
177
+ * @param callback - The function with a code snippet and assertions.
178
+ */
179
+ (name: string, callback: () => void | Promise<void>): void;
180
+ /**
181
+ * Marks a test as focused.
182
+ *
183
+ * @param name - The name of the test.
184
+ * @param callback - The function with a code snippet and assertions.
185
+ */
186
+ only: (name: string, callback: () => void | Promise<void>) => void;
187
+ /**
188
+ * Marks a test as skipped.
189
+ *
190
+ * @param name - The name of the test.
191
+ * @param callback - The function with a code snippet and assertions.
192
+ */
193
+ skip: (name: string, callback: () => void | Promise<void>) => void;
194
+ /**
195
+ * Marks a test as yet to be implemented.
196
+ *
197
+ * @param name - The name of the test.
198
+ * @param callback - The function with a code snippet and assertions.
199
+ */
200
+ todo: (name: string, callback?: () => void | Promise<void>) => void;
201
+ }
202
+
203
+ interface Actions {
204
+ /**
205
+ * Calls the given function with the provided arguments.
206
+ */
207
+ isCalledWith: (...args: Array<unknown>) => void;
208
+ }
209
+ interface When {
210
+ /**
211
+ * Creates a test plan.
212
+ *
213
+ * @template Target - The type upon which an action is performed.
214
+ */
215
+ <Target>(): Actions;
216
+ /**
217
+ * Creates a test plan.
218
+ *
219
+ * @param target - The expression upon which an action is performed.
220
+ */
221
+ (target: unknown): Actions;
222
+ }
223
+
224
+ /**
225
+ * The fill-in type. Useful to fill in the required type arguments of generic types.
226
+ */
227
+ type _ = never;
206
228
  /**
207
229
  * Builds an assertion.
208
230
  */
@@ -227,29 +249,10 @@ declare const it: Test;
227
249
  * Defines a single test.
228
250
  */
229
251
  declare const test: Test;
230
- interface Actions {
231
- /**
232
- * Calls the given function with the provided arguments.
233
- */
234
- isCalledWith: (...args: Array<unknown>) => void;
235
- }
236
- interface When {
237
- /**
238
- * Creates a test plan.
239
- *
240
- * @template Target - The type upon which an action is performed.
241
- */
242
- <Target>(): Actions;
243
- /**
244
- * Creates a test plan.
245
- *
246
- * @param target - The expression upon which an action is performed.
247
- */
248
- (target: unknown): Actions;
249
- }
250
252
  /**
251
253
  * Creates a test plan.
252
254
  */
253
255
  declare const when: When;
254
256
 
255
257
  export { describe, expect, it, omit, pick, test, when };
258
+ export type { _ };
package/dist/tag.js CHANGED
@@ -1,4 +1,4 @@
1
- import { Cli, EventEmitter, CancellationToken } from './tstyche.js';
1
+ import { Cli, EventEmitter, CancellationToken } from './api.js';
2
2
 
3
3
  class StatusHandler {
4
4
  #hasError = false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tstyche",
3
- "version": "7.0.0-beta.1",
3
+ "version": "7.0.0-beta.3",
4
4
  "description": "Everything You Need for Type Testing.",
5
5
  "keywords": [
6
6
  "typescript",
@@ -25,8 +25,8 @@
25
25
  "import": "./dist/index.js",
26
26
  "require": "./dist/index.cjs"
27
27
  },
28
+ "./api": "./dist/api.js",
28
29
  "./tag": "./dist/tag.js",
29
- "./tstyche": "./dist/tstyche.js",
30
30
  "./package.json": "./package.json"
31
31
  },
32
32
  "main": "./dist/index.js",
File without changes