tstyche 7.0.0-beta.2 → 7.0.0-beta.4

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
 
package/dist/api.d.ts CHANGED
@@ -15,13 +15,9 @@ declare class CancellationToken {
15
15
  reset(): void;
16
16
  }
17
17
 
18
- interface CliOptions {
19
- noErrorExitCode?: boolean;
20
- }
21
18
  declare class Cli {
22
19
  #private;
23
- constructor(options?: CliOptions);
24
- run(commandLine: ReadonlyArray<string>, cancellationToken?: CancellationToken): Promise<void>;
20
+ run(commandLine: ReadonlyArray<string>, cancellationToken?: CancellationToken): Promise<number>;
25
21
  }
26
22
 
27
23
  declare enum DiagnosticCategory {
@@ -755,4 +751,4 @@ declare class Version {
755
751
  }
756
752
 
757
753
  export { BaseReporter, CancellationReason, CancellationToken, Cli, Color, Config, ConfigDiagnosticText, DescribeResult, Diagnostic, DiagnosticCategory, DiagnosticOrigin, Directive, DotReporter, EventEmitter, ExpectResult, FileLocation, FileResult, Line, ListReporter, OptionBrand, OptionGroup, Options, OutputService, Path, ProjectConfigKind, ProjectResult, Result, ResultStatus, Runner, Scribbler, ScribblerJsx, Select, SelectDiagnosticText, SetupReporter, Store, StreamController, SummaryReporter, SuppressedResult, TargetResult, TestResult, Text, Version, WatchReporter, addsText, defaultOptions, describeNameText, diagnosticBelongsToNode, diagnosticText, dotText, environmentOptions, fileStatusText, formattedText, getDiagnosticMessageText, getTextSpanEnd, helpText, isDiagnosticWithLocation, prologueText, summaryText, testNameText, usesText, waitingForFileChangesText, watchUsageText };
758
- export type { AssertionCounts, AssertionResultStatus, CliOptions, CodeFrameOptions, CommandLineOptions, ConfigFileOptions, DiagnosticsHandler, DirectiveRange, EnvironmentOptions, Event, EventHandler, FileCounts, FileResultStatus, InlineConfig, ItemDefinition, OptionDefinition, ProjectConfig, Reporter, ReporterEvent, ResolvedConfig, ResultCounts, ResultTiming, ScribblerOptions, SuppressedCounts, SuppressedResultStatus, TargetCounts, TargetResultStatus, TestCounts, TestResultStatus, TextRange, WriteStream };
754
+ export type { AssertionCounts, AssertionResultStatus, CodeFrameOptions, CommandLineOptions, ConfigFileOptions, DiagnosticsHandler, DirectiveRange, EnvironmentOptions, Event, EventHandler, FileCounts, FileResultStatus, InlineConfig, ItemDefinition, OptionDefinition, ProjectConfig, Reporter, ReporterEvent, ResolvedConfig, ResultCounts, ResultTiming, ScribblerOptions, SuppressedCounts, SuppressedResultStatus, TargetCounts, TargetResultStatus, TestCounts, TestResultStatus, TextRange, WriteStream };
package/dist/api.js CHANGED
@@ -56,25 +56,24 @@ class JsonNode {
56
56
  this.text = text;
57
57
  }
58
58
  getValue(options) {
59
- if (this.text == null) {
60
- return undefined;
61
- }
62
- if (/^['"]/.test(this.text)) {
63
- return this.text.slice(1, -1).replaceAll("\\", "");
64
- }
65
- if (options?.expectsIdentifier) {
66
- return this.text;
67
- }
68
- if (this.text === "true") {
69
- return true;
70
- }
71
- if (this.text === "false") {
72
- return false;
73
- }
74
- if (/^\d/.test(this.text)) {
75
- return Number.parseFloat(this.text);
59
+ if (this.text != null) {
60
+ if (/^['"]/.test(this.text)) {
61
+ return this.text.slice(1, -1).replaceAll("\\", "");
62
+ }
63
+ if (options?.expectsIdentifier) {
64
+ return this.text;
65
+ }
66
+ if (this.text === "true") {
67
+ return true;
68
+ }
69
+ if (this.text === "false") {
70
+ return false;
71
+ }
72
+ if (/^\d/.test(this.text)) {
73
+ return Number.parseFloat(this.text);
74
+ }
76
75
  }
77
- return undefined;
76
+ return;
78
77
  }
79
78
  }
80
79
 
@@ -730,7 +729,9 @@ class ManifestService {
730
729
  const versions = [];
731
730
  const packageMetadata = (await response.json());
732
731
  for (const [tag, meta] of Object.entries(packageMetadata.versions)) {
733
- if (!tag.includes("-") && Version.isSatisfiedWith(tag, "5.4.2")) {
732
+ if (!tag.includes("-") &&
733
+ Version.isSatisfiedWith(tag, "5.4") &&
734
+ !Version.isSatisfiedWith(tag, "7.0")) {
734
735
  versions.push(tag);
735
736
  packages[tag] = { integrity: meta.dist.integrity, tarball: meta.dist.tarball };
736
737
  }
@@ -752,6 +753,7 @@ class ManifestService {
752
753
  }
753
754
  }
754
755
  }
756
+ resolutions["latest"] = versions.findLast((version) => version.startsWith("6"));
755
757
  return new Manifest({ minorVersions, npmRegistry: this.#npmRegistry, packages, resolutions, versions });
756
758
  }
757
759
  async open(options) {
@@ -1795,22 +1797,23 @@ class CancellationHandler {
1795
1797
  }
1796
1798
 
1797
1799
  class ExitCodeHandler {
1800
+ #exitCode = 0;
1801
+ getExitCode() {
1802
+ return this.#exitCode;
1803
+ }
1798
1804
  on([event, payload]) {
1799
1805
  if (event === "run:start") {
1800
- this.resetCode();
1806
+ this.#exitCode = 0;
1801
1807
  return;
1802
1808
  }
1803
1809
  if ("diagnostics" in payload) {
1804
1810
  if (payload.diagnostics.some((diagnostic) => diagnostic.category === "error")) {
1805
- this.#setCode(1);
1811
+ this.#exitCode = 1;
1806
1812
  }
1807
1813
  }
1808
1814
  }
1809
- resetCode() {
1810
- this.#setCode(0);
1811
- }
1812
- #setCode(exitCode) {
1813
- process.exitCode = exitCode;
1815
+ reset() {
1816
+ this.#exitCode = 0;
1814
1817
  }
1815
1818
  }
1816
1819
 
@@ -3450,6 +3453,51 @@ class AbilityLayer {
3450
3453
  }
3451
3454
  break;
3452
3455
  }
3456
+ case "toBeInstantiableWith": {
3457
+ this.#nodes.push(expect);
3458
+ const sourceNode = expect.source[0];
3459
+ const targetNode = expect.target?.[0];
3460
+ if (!sourceNode) {
3461
+ return;
3462
+ }
3463
+ if (nodeBelongsToArgumentList(this.#compiler, sourceNode)) {
3464
+ this.#editor.eraseTrailingComma(expect.source);
3465
+ this.#editor.replaceRanges([
3466
+ [
3467
+ expectStart,
3468
+ expectExpressionEnd,
3469
+ nodeIsChildOfExpressionStatement(this.#compiler, expect.matcherNode) ? ";" : "",
3470
+ ],
3471
+ [expectEnd, matcherNodeEnd],
3472
+ ]);
3473
+ if (this.#compiler.isExpressionWithTypeArguments(sourceNode)) {
3474
+ this.#editor.replaceRanges([[sourceNode.expression.getEnd(), sourceNode.getEnd()]]);
3475
+ }
3476
+ }
3477
+ else {
3478
+ const sourceText = this.#compiler.isTypeReferenceNode(sourceNode)
3479
+ ? sourceNode.typeName.getText()
3480
+ : sourceNode.getText();
3481
+ this.#editor.replaceRanges([
3482
+ [
3483
+ expectStart,
3484
+ matcherNodeEnd,
3485
+ nodeIsChildOfExpressionStatement(this.#compiler, expect.matcherNode)
3486
+ ? `;undefined as any as ${sourceText}`
3487
+ : `undefined as any as ${sourceText}`,
3488
+ ],
3489
+ ]);
3490
+ }
3491
+ if (targetNode != null) {
3492
+ const targetText = targetNode.getText().slice(1, -1);
3493
+ if (targetText.trim().length > 1) {
3494
+ this.#editor.replaceRanges([
3495
+ [targetNode.getFullStart(), targetNode.getEnd(), `<${targetText}>`.padStart(targetNode.getFullWidth())],
3496
+ ]);
3497
+ }
3498
+ }
3499
+ break;
3500
+ }
3453
3501
  case "toHaveProperty": {
3454
3502
  this.#nodes.push(expect);
3455
3503
  const sourceNode = expect.source[0];
@@ -4327,10 +4375,13 @@ class EnsureDiagnosticText {
4327
4375
  static argumentOrTypeArgumentMustBeProvided(argumentNameText, typeArgumentNameText) {
4328
4376
  return `An argument for '${argumentNameText}' or type argument for '${typeArgumentNameText}' must be provided.`;
4329
4377
  }
4378
+ static typeArgumentMustBeProvided(typeArgumentNameText) {
4379
+ return `Type argument for '${typeArgumentNameText}' must be provided.`;
4380
+ }
4330
4381
  }
4331
4382
 
4332
- function argumentIsProvided(argumentNameText, node, enclosingNode, onDiagnostics) {
4333
- if (!node) {
4383
+ function argumentIsProvided(compiler, argumentNameText, node, enclosingNode, onDiagnostics) {
4384
+ if (!node || !nodeBelongsToArgumentList(compiler, node)) {
4334
4385
  const text = EnsureDiagnosticText.argumentMustBeProvided(argumentNameText);
4335
4386
  const origin = DiagnosticOrigin.fromNode(enclosingNode);
4336
4387
  onDiagnostics([Diagnostic.error(text, origin)]);
@@ -4349,6 +4400,16 @@ function argumentOrTypeArgumentIsProvided(argumentNameText, typeArgumentNameText
4349
4400
  return true;
4350
4401
  }
4351
4402
 
4403
+ function typeArgumentIsProvided(compiler, typeArgumentNameText, node, enclosingNode, onDiagnostics) {
4404
+ if (!node || nodeBelongsToArgumentList(compiler, node)) {
4405
+ const text = EnsureDiagnosticText.typeArgumentMustBeProvided(typeArgumentNameText);
4406
+ const origin = DiagnosticOrigin.fromNode(enclosingNode);
4407
+ onDiagnostics([Diagnostic.error(text, origin)]);
4408
+ return false;
4409
+ }
4410
+ return true;
4411
+ }
4412
+
4352
4413
  class ExpectDiagnosticText {
4353
4414
  static argumentMustBe(argumentNameText, expectedText) {
4354
4415
  return `An argument for '${argumentNameText}' must be ${expectedText}.`;
@@ -4368,6 +4429,12 @@ class ExpectDiagnosticText {
4368
4429
  static isNotConstructable(isExpression, targetText) {
4369
4430
  return `${isExpression ? "Expression" : "Type"} is not constructable ${targetText}.`;
4370
4431
  }
4432
+ static isInstantiable(isExpression, targetText) {
4433
+ return `${isExpression ? "Expression" : "Type"} is instantiable ${targetText}.`;
4434
+ }
4435
+ static isNotInstantiable(isExpression, targetText) {
4436
+ return `${isExpression ? "Expression" : "Type"} is not instantiable ${targetText}.`;
4437
+ }
4371
4438
  static acceptsProps(isExpression) {
4372
4439
  return `${isExpression ? "Component" : "Component type"} accepts props of the given type.`;
4373
4440
  }
@@ -4453,12 +4520,12 @@ class MatchWorker {
4453
4520
  this.typeChecker = program.getTypeChecker();
4454
4521
  this.assertionNode = assertionNode;
4455
4522
  }
4523
+ checkIsAssignableFrom(sourceNode, targetNode) {
4524
+ return this.#checkIsRelatedTo(targetNode, sourceNode);
4525
+ }
4456
4526
  checkIsAssignableTo(sourceNode, targetNode) {
4457
4527
  return this.#checkIsRelatedTo(sourceNode, targetNode);
4458
4528
  }
4459
- checkIsAssignableWith(sourceNode, targetNode) {
4460
- return this.#checkIsRelatedTo(targetNode, sourceNode);
4461
- }
4462
4529
  #checkIsRelatedTo(sourceNode, targetNode) {
4463
4530
  const sourceType = this.getType(sourceNode);
4464
4531
  const targetType = this.getType(targetNode);
@@ -5314,7 +5381,7 @@ class ToBeAssignableFrom extends RelationMatcherBase {
5314
5381
  match(matchWorker, sourceNode, targetNode) {
5315
5382
  return {
5316
5383
  explain: () => this.explain(matchWorker, sourceNode, targetNode),
5317
- isMatch: matchWorker.checkIsAssignableWith(sourceNode, targetNode),
5384
+ isMatch: matchWorker.checkIsAssignableFrom(sourceNode, targetNode),
5318
5385
  };
5319
5386
  }
5320
5387
  }
@@ -5335,7 +5402,7 @@ class AbilityMatcherBase {
5335
5402
  constructor(compiler) {
5336
5403
  this.compiler = compiler;
5337
5404
  }
5338
- #resolveTargetText(nodes) {
5405
+ getArgumentCountText(nodes) {
5339
5406
  if (nodes.length === 0) {
5340
5407
  return "without arguments";
5341
5408
  }
@@ -5344,15 +5411,21 @@ class AbilityMatcherBase {
5344
5411
  }
5345
5412
  return `with the given argument${nodes.length === 1 ? "" : "s"}`;
5346
5413
  }
5347
- explain(matchWorker, sourceNode, targetNodes) {
5414
+ getTypeArgumentCountText(targetNode) {
5415
+ if (targetNode.elements.length === 0) {
5416
+ return "without type arguments";
5417
+ }
5418
+ return `with the given type argument${targetNode.elements.length === 1 ? "" : "s"}`;
5419
+ }
5420
+ explain(matchWorker, sourceNode, targetNode, getArgumentCountText) {
5348
5421
  const isExpression = nodeBelongsToArgumentList(this.compiler, sourceNode);
5349
- const targetText = this.#resolveTargetText(targetNodes);
5422
+ const argumentCountText = getArgumentCountText();
5350
5423
  const diagnostics = [];
5351
5424
  if (matchWorker.assertionNode.abilityDiagnostics.size > 0) {
5352
5425
  for (const diagnostic of matchWorker.assertionNode.abilityDiagnostics) {
5353
- const text = [this.explainNotText(isExpression, targetText), getDiagnosticMessageText(diagnostic)];
5426
+ const text = [this.explainNotText(isExpression, argumentCountText), getDiagnosticMessageText(diagnostic)];
5354
5427
  let origin;
5355
- if (isDiagnosticWithLocation(diagnostic) && diagnosticBelongsToNode(diagnostic, targetNodes)) {
5428
+ if (isDiagnosticWithLocation(diagnostic) && diagnosticBelongsToNode(diagnostic, targetNode)) {
5356
5429
  origin = new DiagnosticOrigin(diagnostic.start, getTextSpanEnd(diagnostic), sourceNode.getSourceFile(), matchWorker.assertionNode);
5357
5430
  }
5358
5431
  else {
@@ -5367,7 +5440,7 @@ class AbilityMatcherBase {
5367
5440
  }
5368
5441
  else {
5369
5442
  const origin = DiagnosticOrigin.fromAssertion(matchWorker.assertionNode);
5370
- diagnostics.push(Diagnostic.error(this.explainText(isExpression, targetText), origin));
5443
+ diagnostics.push(Diagnostic.error(this.explainText(isExpression, argumentCountText), origin));
5371
5444
  }
5372
5445
  return diagnostics;
5373
5446
  }
@@ -5394,7 +5467,7 @@ class ToBeCallableWith extends AbilityMatcherBase {
5394
5467
  return;
5395
5468
  }
5396
5469
  return {
5397
- explain: () => this.explain(matchWorker, sourceNode, targetNodes),
5470
+ explain: () => this.explain(matchWorker, sourceNode, targetNodes, () => this.getArgumentCountText(targetNodes)),
5398
5471
  isMatch: matchWorker.assertionNode.abilityDiagnostics.size === 0,
5399
5472
  };
5400
5473
  }
@@ -5421,7 +5494,38 @@ class ToBeConstructableWith extends AbilityMatcherBase {
5421
5494
  return;
5422
5495
  }
5423
5496
  return {
5424
- explain: () => this.explain(matchWorker, sourceNode, targetNodes),
5497
+ explain: () => this.explain(matchWorker, sourceNode, targetNodes, () => this.getArgumentCountText(targetNodes)),
5498
+ isMatch: matchWorker.assertionNode.abilityDiagnostics.size === 0,
5499
+ };
5500
+ }
5501
+ }
5502
+
5503
+ class ToBeInstantiableWith extends AbilityMatcherBase {
5504
+ explainText = ExpectDiagnosticText.isInstantiable;
5505
+ explainNotText = ExpectDiagnosticText.isNotInstantiable;
5506
+ match(matchWorker, sourceNode, targetNode, onDiagnostics) {
5507
+ if (!(this.compiler.isIdentifier(sourceNode) ||
5508
+ this.compiler.isTypeReferenceNode(sourceNode) ||
5509
+ this.compiler.isExpressionWithTypeArguments(sourceNode))) {
5510
+ let text;
5511
+ if (nodeBelongsToArgumentList(this.compiler, sourceNode)) {
5512
+ text = ExpectDiagnosticText.argumentMustBe("source", "an instantiable expression");
5513
+ }
5514
+ else {
5515
+ text = ExpectDiagnosticText.typeArgumentMustBe("Source", "an instantiable type");
5516
+ }
5517
+ const origin = DiagnosticOrigin.fromNode(sourceNode);
5518
+ onDiagnostics([Diagnostic.error(text, origin)]);
5519
+ return;
5520
+ }
5521
+ if (!this.compiler.isTupleTypeNode(targetNode)) {
5522
+ const text = ExpectDiagnosticText.typeArgumentMustBe("Target", "a tuple type");
5523
+ const origin = DiagnosticOrigin.fromNode(targetNode);
5524
+ onDiagnostics([Diagnostic.error(text, origin)]);
5525
+ return;
5526
+ }
5527
+ return {
5528
+ explain: () => this.explain(matchWorker, sourceNode, targetNode, () => this.getTypeArgumentCountText(targetNode)),
5425
5529
  isMatch: matchWorker.assertionNode.abilityDiagnostics.size === 0,
5426
5530
  };
5427
5531
  }
@@ -5572,6 +5676,7 @@ class ExpectService {
5572
5676
  toBeAssignableTo;
5573
5677
  toBeCallableWith;
5574
5678
  toBeConstructableWith;
5679
+ toBeInstantiableWith;
5575
5680
  toHaveProperty;
5576
5681
  toRaiseError;
5577
5682
  constructor(compiler, program, reject) {
@@ -5585,6 +5690,7 @@ class ExpectService {
5585
5690
  this.toBeAssignableTo = new ToBeAssignableTo();
5586
5691
  this.toBeCallableWith = new ToBeCallableWith(compiler);
5587
5692
  this.toBeConstructableWith = new ToBeConstructableWith(compiler);
5693
+ this.toBeInstantiableWith = new ToBeInstantiableWith(compiler);
5588
5694
  this.toHaveProperty = new ToHaveProperty(compiler);
5589
5695
  this.toRaiseError = new ToRaiseError(compiler);
5590
5696
  }
@@ -5594,7 +5700,7 @@ class ExpectService {
5594
5700
  return;
5595
5701
  }
5596
5702
  const matchWorker = new MatchWorker(this.#compiler, this.#program, assertionNode);
5597
- if (!(matcherNameText === "toRaiseError" && !assertionNode.isNot) &&
5703
+ if (!(matcherNameText === "toBeInstantiableWith" || (matcherNameText === "toRaiseError" && !assertionNode.isNot)) &&
5598
5704
  this.#reject.argumentType([
5599
5705
  ["source", assertionNode.source[0]],
5600
5706
  ["target", assertionNode.target?.[0]],
@@ -5616,8 +5722,14 @@ class ExpectService {
5616
5722
  case "toBeConstructableWith":
5617
5723
  case "toRaiseError":
5618
5724
  return this[matcherNameText].match(matchWorker, assertionNode.source[0], assertionNode.target, onDiagnostics);
5725
+ case "toBeInstantiableWith": {
5726
+ if (!typeArgumentIsProvided(this.#compiler, "Target", assertionNode.target?.[0], assertionNode.matcherNameNode.name, onDiagnostics)) {
5727
+ return;
5728
+ }
5729
+ return this.toBeInstantiableWith.match(matchWorker, assertionNode.source[0], assertionNode.target[0], onDiagnostics);
5730
+ }
5619
5731
  case "toHaveProperty":
5620
- if (!argumentIsProvided("key", assertionNode.target?.[0], assertionNode.matcherNameNode.name, onDiagnostics)) {
5732
+ if (!argumentIsProvided(this.#compiler, "key", assertionNode.target?.[0], assertionNode.matcherNameNode.name, onDiagnostics)) {
5621
5733
  return;
5622
5734
  }
5623
5735
  return this.toHaveProperty.match(matchWorker, assertionNode.source[0], assertionNode.target[0], onDiagnostics);
@@ -5701,14 +5813,16 @@ class WhenDiagnosticText {
5701
5813
  }
5702
5814
 
5703
5815
  class WhenService {
5816
+ #compiler;
5704
5817
  #onDiagnostics;
5705
5818
  #reject;
5706
- constructor(reject, onDiagnostics) {
5819
+ constructor(compiler, reject, onDiagnostics) {
5820
+ this.#compiler = compiler;
5707
5821
  this.#reject = reject;
5708
5822
  this.#onDiagnostics = onDiagnostics;
5709
5823
  }
5710
5824
  action(when) {
5711
- if (!argumentIsProvided("target", when.target[0], when.node.expression, this.#onDiagnostics) ||
5825
+ if (!argumentIsProvided(this.#compiler, "target", when.target[0], when.node.expression, this.#onDiagnostics) ||
5712
5826
  this.#reject.argumentType([["target", when.target[0]]], this.#onDiagnostics)) {
5713
5827
  return;
5714
5828
  }
@@ -5825,7 +5939,7 @@ class TestTreeWalker {
5825
5939
  this.#position = options.position;
5826
5940
  const reject = new Reject(compiler, program, resolvedConfig);
5827
5941
  this.#expectService = new ExpectService(compiler, program, reject);
5828
- this.#whenService = new WhenService(reject, onFileDiagnostics);
5942
+ this.#whenService = new WhenService(compiler, reject, onFileDiagnostics);
5829
5943
  }
5830
5944
  async #resolveRunMode(flags, node) {
5831
5945
  const ifDirective = Directive.getDirectiveRange(this.#compiler, node, "if");
@@ -6065,7 +6179,7 @@ class FileRunner {
6065
6179
  class Runner {
6066
6180
  #eventEmitter = new EventEmitter();
6067
6181
  #resolvedConfig;
6068
- static version = "7.0.0-beta.2";
6182
+ static version = "7.0.0-beta.4";
6069
6183
  constructor(resolvedConfig) {
6070
6184
  this.#resolvedConfig = resolvedConfig;
6071
6185
  }
@@ -6164,15 +6278,20 @@ class CliDiagnosticText {
6164
6278
  class Cli {
6165
6279
  #deferredDiagnostics;
6166
6280
  #eventEmitter = new EventEmitter();
6167
- #noErrorExitCode;
6168
- constructor(options) {
6169
- this.#noErrorExitCode = options?.noErrorExitCode ?? false;
6170
- }
6171
6281
  async run(commandLine, cancellationToken = new CancellationToken()) {
6282
+ const exitCodeHandler = new ExitCodeHandler();
6283
+ this.#eventEmitter.addHandler(exitCodeHandler);
6284
+ await this.#run(commandLine, exitCodeHandler, cancellationToken);
6285
+ if (this.#deferredDiagnostics != null) {
6286
+ OutputService.writeBlankLine();
6287
+ OutputService.writeWarning(diagnosticText(this.#deferredDiagnostics));
6288
+ }
6289
+ this.#eventEmitter.removeHandlers();
6290
+ return exitCodeHandler.getExitCode();
6291
+ }
6292
+ async #run(commandLine, exitCodeHandler, cancellationToken) {
6172
6293
  const cancellationHandler = new CancellationHandler(cancellationToken, "configError");
6173
6294
  this.#eventEmitter.addHandler(cancellationHandler);
6174
- const exitCodeHandler = new ExitCodeHandler();
6175
- !this.#noErrorExitCode && this.#eventEmitter.addHandler(exitCodeHandler);
6176
6295
  const setupReporter = new SetupReporter();
6177
6296
  this.#eventEmitter.addReporter(setupReporter);
6178
6297
  if (commandLine.includes("--help")) {
@@ -6205,7 +6324,7 @@ class Cli {
6205
6324
  }
6206
6325
  if (!commandLineOptions.config) {
6207
6326
  const oldConfigFilePath = Path.resolve(Config.resolveRootPath(commandLineOptions.root), "./tstyche.config.json");
6208
- if (existsSync(oldConfigFilePath) && !environmentOptions.isCi) {
6327
+ if (existsSync(oldConfigFilePath)) {
6209
6328
  const newConfigFilePath = Path.resolve(Config.resolveConfigFilePath(undefined, commandLineOptions.root));
6210
6329
  await fs.rename(oldConfigFilePath, newConfigFilePath);
6211
6330
  this.#deferredDiagnostics = Diagnostic.warning(CliDiagnosticText.configLocationChanged(oldConfigFilePath, newConfigFilePath));
@@ -6214,7 +6333,7 @@ class Cli {
6214
6333
  do {
6215
6334
  if (cancellationToken.getReason() === "configChange") {
6216
6335
  cancellationToken.reset();
6217
- exitCodeHandler.resetCode();
6336
+ exitCodeHandler.reset();
6218
6337
  OutputService.clearTerminal();
6219
6338
  this.#eventEmitter.addHandler(cancellationHandler);
6220
6339
  this.#eventEmitter.addReporter(setupReporter);
@@ -6256,11 +6375,6 @@ class Cli {
6256
6375
  const runner = new Runner(resolvedConfig);
6257
6376
  await runner.run(testFiles, cancellationToken);
6258
6377
  } while (cancellationToken.getReason() === "configChange");
6259
- if (this.#deferredDiagnostics != null) {
6260
- OutputService.writeBlankLine();
6261
- OutputService.writeWarning(diagnosticText(this.#deferredDiagnostics));
6262
- }
6263
- this.#eventEmitter.removeHandlers();
6264
6378
  }
6265
6379
  #waitForChangedFiles(resolvedConfig, cancellationToken) {
6266
6380
  return new Promise((resolve) => {
package/dist/bin.js CHANGED
@@ -3,4 +3,5 @@ import process from 'node:process';
3
3
  import { Cli } from './api.js';
4
4
 
5
5
  const cli = new Cli();
6
- await cli.run(process.argv.slice(2));
6
+ const commandLine = process.argv.slice(2);
7
+ process.exitCode = await cli.run(commandLine);
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,31 +1,10 @@
1
- import { Cli, EventEmitter, CancellationToken } from './api.js';
1
+ import { Cli } from './api.js';
2
2
 
3
- class StatusHandler {
4
- #hasError = false;
5
- hasError() {
6
- return this.#hasError;
7
- }
8
- on([event, payload]) {
9
- if (event === "run:start") {
10
- this.#hasError = false;
11
- return;
12
- }
13
- if ("diagnostics" in payload) {
14
- if (payload.diagnostics.some((diagnostic) => diagnostic.category === "error")) {
15
- this.#hasError = true;
16
- }
17
- }
18
- }
19
- }
20
3
  async function tstyche(template, ...substitutions) {
21
- const cli = new Cli({ noErrorExitCode: true });
4
+ const cli = new Cli();
22
5
  const commandLine = String.raw(template, ...substitutions).split(/\s+/);
23
- const eventEmitter = new EventEmitter();
24
- const statusHandler = new StatusHandler();
25
- eventEmitter.addHandler(statusHandler);
26
- await cli.run(commandLine, new CancellationToken());
27
- eventEmitter.removeHandler(statusHandler);
28
- if (statusHandler.hasError()) {
6
+ const exitCode = await cli.run(commandLine);
7
+ if (exitCode > 0) {
29
8
  throw new Error("TSTyche test run failed. Check the output above for details.");
30
9
  }
31
10
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tstyche",
3
- "version": "7.0.0-beta.2",
3
+ "version": "7.0.0-beta.4",
4
4
  "description": "Everything You Need for Type Testing.",
5
5
  "keywords": [
6
6
  "typescript",
@@ -0,0 +1,88 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "type": "object",
4
+ "properties": {
5
+ "checkDeclarationFiles": {
6
+ "description": "Check declaration files for type errors.",
7
+ "default": true,
8
+ "type": "boolean"
9
+ },
10
+ "checkSuppressedErrors": {
11
+ "description": "Check errors silenced by '@ts-expect-error' directives.",
12
+ "default": true,
13
+ "type": "boolean"
14
+ },
15
+ "failFast": {
16
+ "description": "Stop running tests after the first failed assertion.",
17
+ "default": false,
18
+ "type": "boolean"
19
+ },
20
+ "fixtureFileMatch": {
21
+ "description": "The list of glob patterns matching the fixture files.",
22
+ "default": [
23
+ "**/__fixtures__/*.{ts,tsx}",
24
+ "**/fixtures/*.{ts,tsx}"
25
+ ],
26
+ "type": "array",
27
+ "uniqueItems": true,
28
+ "items": {
29
+ "type": "string"
30
+ }
31
+ },
32
+ "quiet": {
33
+ "description": "Silence all test runner output except errors and warnings.",
34
+ "default": false,
35
+ "type": "boolean"
36
+ },
37
+ "rejectAnyType": {
38
+ "description": "Reject the 'any' type passed as an argument to the 'expect()' function or a matcher.",
39
+ "default": true,
40
+ "type": "boolean"
41
+ },
42
+ "rejectNeverType": {
43
+ "description": "Reject the 'never' type passed as an argument to the 'expect()' function or a matcher.",
44
+ "default": true,
45
+ "type": "boolean"
46
+ },
47
+ "reporters": {
48
+ "description": "The list of reporters to use.",
49
+ "default": [
50
+ "list",
51
+ "summary"
52
+ ],
53
+ "type": "array",
54
+ "uniqueItems": true,
55
+ "items": {
56
+ "type": "string"
57
+ }
58
+ },
59
+ "target": {
60
+ "description": "The range of TypeScript versions to test against.",
61
+ "default": "*",
62
+ "type": "string"
63
+ },
64
+ "testFileMatch": {
65
+ "description": "The list of glob patterns matching the test files.",
66
+ "default": [
67
+ "**/*.tst.*",
68
+ "**/__typetests__/*.test.*",
69
+ "**/typetests/*.test.*"
70
+ ],
71
+ "type": "array",
72
+ "uniqueItems": true,
73
+ "items": {
74
+ "type": "string"
75
+ }
76
+ },
77
+ "tsconfig": {
78
+ "description": "The TSConfig to load.",
79
+ "default": "findup",
80
+ "type": "string"
81
+ },
82
+ "verbose": {
83
+ "description": "Enable detailed logging.",
84
+ "default": false,
85
+ "type": "boolean"
86
+ }
87
+ }
88
+ }