tstyche 5.0.0-beta.1 → 5.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/build/4.x/index.d.cts +2 -2
- package/build/4.x/index.d.ts +2 -2
- package/build/index.d.cts +2 -2
- package/build/index.d.ts +2 -2
- package/build/tstyche.d.ts +6 -3
- package/build/tstyche.js +171 -109
- package/package.json +1 -1
package/build/4.x/index.d.cts
CHANGED
|
@@ -218,11 +218,11 @@ declare const describe: Describe;
|
|
|
218
218
|
/**
|
|
219
219
|
* Defines a single test.
|
|
220
220
|
*/
|
|
221
|
-
declare const
|
|
221
|
+
declare const it: Test;
|
|
222
222
|
/**
|
|
223
223
|
* Defines a single test.
|
|
224
224
|
*/
|
|
225
|
-
declare const
|
|
225
|
+
declare const test: Test;
|
|
226
226
|
interface Actions {
|
|
227
227
|
/**
|
|
228
228
|
* Calls the given function with the provided arguments.
|
package/build/4.x/index.d.ts
CHANGED
|
@@ -218,11 +218,11 @@ declare const describe: Describe;
|
|
|
218
218
|
/**
|
|
219
219
|
* Defines a single test.
|
|
220
220
|
*/
|
|
221
|
-
declare const
|
|
221
|
+
declare const it: Test;
|
|
222
222
|
/**
|
|
223
223
|
* Defines a single test.
|
|
224
224
|
*/
|
|
225
|
-
declare const
|
|
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
|
|
225
|
+
declare const it: Test;
|
|
226
226
|
/**
|
|
227
227
|
* Defines a single test.
|
|
228
228
|
*/
|
|
229
|
-
declare const
|
|
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
|
|
225
|
+
declare const it: Test;
|
|
226
226
|
/**
|
|
227
227
|
* Defines a single test.
|
|
228
228
|
*/
|
|
229
|
-
declare const
|
|
229
|
+
declare const test: Test;
|
|
230
230
|
interface Actions {
|
|
231
231
|
/**
|
|
232
232
|
* Calls the given function with the provided arguments.
|
package/build/tstyche.d.ts
CHANGED
|
@@ -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
|
}
|
|
@@ -614,6 +615,8 @@ declare class OutputService {
|
|
|
614
615
|
static writeWarning(element: ScribblerJsx.Element | Array<ScribblerJsx.Element>): void;
|
|
615
616
|
}
|
|
616
617
|
|
|
618
|
+
declare function prologueText(runnerVersion: string, rootPath: string): ScribblerJsx.Element;
|
|
619
|
+
|
|
617
620
|
interface SummaryTextOptions {
|
|
618
621
|
targetCounts: ResultCounts;
|
|
619
622
|
fileCounts: ResultCounts;
|
|
@@ -730,5 +733,5 @@ declare class Version {
|
|
|
730
733
|
static isSatisfiedWith(source: string, target: string): boolean;
|
|
731
734
|
}
|
|
732
735
|
|
|
733
|
-
export { BaseReporter, CancellationReason, CancellationToken, Cli, Color, Config, ConfigDiagnosticText, DescribeResult, Diagnostic, DiagnosticCategory, DiagnosticOrigin, Directive, EventEmitter, ExpectResult, FileLocation, FileResult, Line, ListReporter, OptionBrand, OptionGroup, Options, OutputService, Path, PluginService, ProjectResult, Result, ResultStatus, Runner, Scribbler, ScribblerJsx, Select, SelectDiagnosticText, SetupReporter, Store, SummaryReporter, SuppressedResult, TargetResult, TestResult, Text, Version, WatchReporter, addsPackageText, defaultOptions, describeNameText, diagnosticBelongsToNode, diagnosticText, environmentOptions, fileStatusText, fileViewText, formattedText, getDiagnosticMessageText, getTextSpanEnd, helpText, isDiagnosticWithLocation, summaryText, testNameText, usesCompilerText, waitingForFileChangesText, watchUsageText };
|
|
736
|
+
export { BaseReporter, CancellationReason, CancellationToken, Cli, Color, Config, ConfigDiagnosticText, DescribeResult, Diagnostic, DiagnosticCategory, DiagnosticOrigin, Directive, EventEmitter, ExpectResult, FileLocation, FileResult, Line, ListReporter, OptionBrand, OptionGroup, Options, OutputService, Path, PluginService, ProjectResult, Result, ResultStatus, Runner, Scribbler, ScribblerJsx, Select, SelectDiagnosticText, SetupReporter, Store, SummaryReporter, SuppressedResult, TargetResult, TestResult, Text, Version, WatchReporter, addsPackageText, defaultOptions, describeNameText, diagnosticBelongsToNode, diagnosticText, environmentOptions, fileStatusText, fileViewText, formattedText, getDiagnosticMessageText, getTextSpanEnd, helpText, isDiagnosticWithLocation, prologueText, summaryText, testNameText, usesCompilerText, waitingForFileChangesText, watchUsageText };
|
|
734
737
|
export type { AssertionCounts, AssertionResultStatus, CodeFrameOptions, CommandLineOptions, ConfigFileOptions, DiagnosticsHandler, DirectiveRange, EnvironmentOptions, Event, EventHandler, FileCounts, FileResultStatus, InlineConfig, ItemDefinition, OptionDefinition, Plugin, Reporter, ReporterEvent, ResolvedConfig, ResultCounts, ResultTiming, ScribblerOptions, SelectHookContext, SuppressedCounts, SuppressedResultStatus, TargetCounts, TargetResultStatus, TestCounts, TestResultStatus, TextRange };
|
package/build/tstyche.js
CHANGED
|
@@ -968,7 +968,7 @@ class Store {
|
|
|
968
968
|
modulePath = Path.resolve(modulePath, "../tsserverlibrary.js");
|
|
969
969
|
}
|
|
970
970
|
const sourceText = await fs.readFile(modulePath, { encoding: "utf8" });
|
|
971
|
-
const toExpose = ["
|
|
971
|
+
const toExpose = ["isTypeIdenticalTo"];
|
|
972
972
|
const modifiedSourceText = sourceText.replace("return checker;", `return { ...checker, ${toExpose.join(", ")} };`);
|
|
973
973
|
const compiledWrapper = vm.compileFunction(modifiedSourceText, ["exports", "require", "module", "__filename", "__dirname"], { filename: modulePath });
|
|
974
974
|
compiledWrapper(exports, createRequire(modulePath), module, modulePath, Path.dirname(modulePath));
|
|
@@ -2491,6 +2491,10 @@ class OutputService {
|
|
|
2491
2491
|
}
|
|
2492
2492
|
}
|
|
2493
2493
|
|
|
2494
|
+
function prologueText(runnerVersion, rootPath) {
|
|
2495
|
+
return (jsx(Text, { children: [jsx(Line, { children: [jsx(Text, { color: "90", children: "····" }), " TSTyche ", runnerVersion, jsx(Text, { color: "90", children: [" at ", rootPath] })] }), jsx(Line, {})] }));
|
|
2496
|
+
}
|
|
2497
|
+
|
|
2494
2498
|
function RowText({ label, text }) {
|
|
2495
2499
|
return (jsx(Line, { children: [`${label}:`.padEnd(12), text] }));
|
|
2496
2500
|
}
|
|
@@ -2595,9 +2599,6 @@ class FileView {
|
|
|
2595
2599
|
#indent = 0;
|
|
2596
2600
|
#lines = [];
|
|
2597
2601
|
#messages = [];
|
|
2598
|
-
get hasErrors() {
|
|
2599
|
-
return this.#messages.length > 0;
|
|
2600
|
-
}
|
|
2601
2602
|
addMessage(message) {
|
|
2602
2603
|
this.#messages.push(message);
|
|
2603
2604
|
}
|
|
@@ -2620,7 +2621,10 @@ class FileView {
|
|
|
2620
2621
|
return this.#messages;
|
|
2621
2622
|
}
|
|
2622
2623
|
getViewText(options) {
|
|
2623
|
-
return fileViewText(this.#lines, options?.appendEmptyLine || this.hasErrors);
|
|
2624
|
+
return fileViewText(this.#lines, options?.appendEmptyLine || this.hasErrors());
|
|
2625
|
+
}
|
|
2626
|
+
hasErrors() {
|
|
2627
|
+
return this.#messages.length > 0;
|
|
2624
2628
|
}
|
|
2625
2629
|
}
|
|
2626
2630
|
|
|
@@ -2631,7 +2635,7 @@ class ListReporter extends BaseReporter {
|
|
|
2631
2635
|
#hasReportedError = false;
|
|
2632
2636
|
#hasReportedUses = false;
|
|
2633
2637
|
#isFileViewExpanded = false;
|
|
2634
|
-
|
|
2638
|
+
#isLastFile() {
|
|
2635
2639
|
return this.#fileCount === 0;
|
|
2636
2640
|
}
|
|
2637
2641
|
on([event, payload]) {
|
|
@@ -2684,8 +2688,8 @@ class ListReporter extends BaseReporter {
|
|
|
2684
2688
|
OutputService.eraseLastLine();
|
|
2685
2689
|
}
|
|
2686
2690
|
OutputService.writeMessage(fileStatusText(payload.result.status, payload.result.file));
|
|
2687
|
-
OutputService.writeMessage(this.#fileView.getViewText({ appendEmptyLine: this.#isLastFile }));
|
|
2688
|
-
if (this.#fileView.hasErrors) {
|
|
2691
|
+
OutputService.writeMessage(this.#fileView.getViewText({ appendEmptyLine: this.#isLastFile() }));
|
|
2692
|
+
if (this.#fileView.hasErrors()) {
|
|
2689
2693
|
OutputService.writeError(this.#fileView.getMessages());
|
|
2690
2694
|
this.#hasReportedError = true;
|
|
2691
2695
|
}
|
|
@@ -2829,18 +2833,18 @@ var CancellationReason;
|
|
|
2829
2833
|
class CancellationToken {
|
|
2830
2834
|
#isCancelled = false;
|
|
2831
2835
|
#reason;
|
|
2832
|
-
get isCancellationRequested() {
|
|
2833
|
-
return this.#isCancelled;
|
|
2834
|
-
}
|
|
2835
|
-
get reason() {
|
|
2836
|
-
return this.#reason;
|
|
2837
|
-
}
|
|
2838
2836
|
cancel(reason) {
|
|
2839
2837
|
if (!this.#isCancelled) {
|
|
2840
2838
|
this.#isCancelled = true;
|
|
2841
2839
|
this.#reason = reason;
|
|
2842
2840
|
}
|
|
2843
2841
|
}
|
|
2842
|
+
isCancellationRequested() {
|
|
2843
|
+
return this.#isCancelled;
|
|
2844
|
+
}
|
|
2845
|
+
getReason() {
|
|
2846
|
+
return this.#reason;
|
|
2847
|
+
}
|
|
2844
2848
|
reset() {
|
|
2845
2849
|
if (this.#isCancelled) {
|
|
2846
2850
|
this.#isCancelled = false;
|
|
@@ -3225,7 +3229,7 @@ class WatchService {
|
|
|
3225
3229
|
for (const watcher of this.#watchers) {
|
|
3226
3230
|
watcher.watch();
|
|
3227
3231
|
}
|
|
3228
|
-
while (!cancellationToken.isCancellationRequested) {
|
|
3232
|
+
while (!cancellationToken.isCancellationRequested()) {
|
|
3229
3233
|
const testFiles = await debounce.schedule();
|
|
3230
3234
|
if (testFiles.length > 0) {
|
|
3231
3235
|
yield testFiles;
|
|
@@ -3257,6 +3261,9 @@ function deepCompareKeys(a, b, keys) {
|
|
|
3257
3261
|
}
|
|
3258
3262
|
return true;
|
|
3259
3263
|
}
|
|
3264
|
+
function nodeBelongsToArgumentList(compiler, node) {
|
|
3265
|
+
return compiler.isCallExpression(node.parent) && node.parent.arguments.some((argument) => argument === node);
|
|
3266
|
+
}
|
|
3260
3267
|
function nodeIsChildOfExpressionStatement(compiler, node) {
|
|
3261
3268
|
return compiler.isExpressionStatement(node.parent);
|
|
3262
3269
|
}
|
|
@@ -3302,6 +3309,7 @@ class AbilityLayer {
|
|
|
3302
3309
|
const expectExpressionEnd = expect.node.expression.getEnd();
|
|
3303
3310
|
const expectEnd = expect.node.getEnd();
|
|
3304
3311
|
const matcherNameEnd = expect.matcherNameNode.getEnd();
|
|
3312
|
+
const matcherNodeEnd = expect.matcherNode.getEnd();
|
|
3305
3313
|
switch (expect.matcherNameNode.name.text) {
|
|
3306
3314
|
case "toBeApplicable":
|
|
3307
3315
|
this.#nodes.push(expect);
|
|
@@ -3310,30 +3318,102 @@ class AbilityLayer {
|
|
|
3310
3318
|
[expectEnd, matcherNameEnd],
|
|
3311
3319
|
]);
|
|
3312
3320
|
break;
|
|
3313
|
-
case "toBeCallableWith":
|
|
3321
|
+
case "toBeCallableWith": {
|
|
3314
3322
|
this.#nodes.push(expect);
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
|
|
3319
|
-
|
|
3320
|
-
|
|
3321
|
-
|
|
3322
|
-
|
|
3323
|
-
|
|
3323
|
+
const sourceNode = expect.source[0];
|
|
3324
|
+
if (!sourceNode) {
|
|
3325
|
+
return;
|
|
3326
|
+
}
|
|
3327
|
+
if (nodeBelongsToArgumentList(this.#compiler, sourceNode)) {
|
|
3328
|
+
this.#editor.eraseTrailingComma(expect.source);
|
|
3329
|
+
this.#editor.replaceRanges([
|
|
3330
|
+
[
|
|
3331
|
+
expectStart,
|
|
3332
|
+
expectExpressionEnd,
|
|
3333
|
+
nodeIsChildOfExpressionStatement(this.#compiler, expect.matcherNode) ? ";" : "",
|
|
3334
|
+
],
|
|
3335
|
+
[expectEnd, matcherNameEnd],
|
|
3336
|
+
]);
|
|
3337
|
+
}
|
|
3338
|
+
else {
|
|
3339
|
+
const sourceText = sourceNode.getFullText();
|
|
3340
|
+
this.#editor.replaceRanges([
|
|
3341
|
+
[
|
|
3342
|
+
expectStart,
|
|
3343
|
+
matcherNameEnd,
|
|
3344
|
+
nodeIsChildOfExpressionStatement(this.#compiler, expect.matcherNode)
|
|
3345
|
+
? `;(undefined as any as ${sourceText})`
|
|
3346
|
+
: `(undefined as any as ${sourceText})`,
|
|
3347
|
+
],
|
|
3348
|
+
]);
|
|
3349
|
+
}
|
|
3324
3350
|
break;
|
|
3325
|
-
|
|
3351
|
+
}
|
|
3352
|
+
case "toBeConstructableWith": {
|
|
3326
3353
|
this.#nodes.push(expect);
|
|
3327
|
-
|
|
3328
|
-
|
|
3329
|
-
|
|
3330
|
-
|
|
3331
|
-
|
|
3332
|
-
|
|
3333
|
-
|
|
3334
|
-
|
|
3335
|
-
|
|
3354
|
+
const sourceNode = expect.source[0];
|
|
3355
|
+
if (!sourceNode) {
|
|
3356
|
+
return;
|
|
3357
|
+
}
|
|
3358
|
+
if (nodeBelongsToArgumentList(this.#compiler, sourceNode)) {
|
|
3359
|
+
this.#editor.eraseTrailingComma(expect.source);
|
|
3360
|
+
this.#editor.replaceRanges([
|
|
3361
|
+
[
|
|
3362
|
+
expectStart,
|
|
3363
|
+
expectExpressionEnd,
|
|
3364
|
+
nodeIsChildOfExpressionStatement(this.#compiler, expect.matcherNode) ? "; new" : "new",
|
|
3365
|
+
],
|
|
3366
|
+
[expectEnd, matcherNameEnd],
|
|
3367
|
+
]);
|
|
3368
|
+
}
|
|
3369
|
+
else {
|
|
3370
|
+
const sourceText = sourceNode.getFullText();
|
|
3371
|
+
this.#editor.replaceRanges([
|
|
3372
|
+
[
|
|
3373
|
+
expectStart,
|
|
3374
|
+
matcherNameEnd,
|
|
3375
|
+
nodeIsChildOfExpressionStatement(this.#compiler, expect.matcherNode)
|
|
3376
|
+
? `;new (undefined as any as ${sourceText})`
|
|
3377
|
+
: `new (undefined as any as ${sourceText})`,
|
|
3378
|
+
],
|
|
3379
|
+
]);
|
|
3380
|
+
}
|
|
3381
|
+
break;
|
|
3382
|
+
}
|
|
3383
|
+
case "toHaveProperty": {
|
|
3384
|
+
this.#nodes.push(expect);
|
|
3385
|
+
const sourceNode = expect.source[0];
|
|
3386
|
+
const targetNode = expect.target?.[0];
|
|
3387
|
+
if (!sourceNode || !targetNode) {
|
|
3388
|
+
return;
|
|
3389
|
+
}
|
|
3390
|
+
const sourceText = sourceNode.getFullText();
|
|
3391
|
+
const targetText = targetNode.getFullText();
|
|
3392
|
+
if (nodeBelongsToArgumentList(this.#compiler, sourceNode)) {
|
|
3393
|
+
this.#editor.eraseTrailingComma(expect.source);
|
|
3394
|
+
this.#editor.replaceRanges([
|
|
3395
|
+
[
|
|
3396
|
+
expectStart,
|
|
3397
|
+
matcherNodeEnd,
|
|
3398
|
+
nodeIsChildOfExpressionStatement(this.#compiler, expect.matcherNode)
|
|
3399
|
+
? `;(${sourceText})[${targetText}]`
|
|
3400
|
+
: `(${sourceText})[${targetText}]`,
|
|
3401
|
+
],
|
|
3402
|
+
]);
|
|
3403
|
+
}
|
|
3404
|
+
else {
|
|
3405
|
+
this.#editor.replaceRanges([
|
|
3406
|
+
[
|
|
3407
|
+
expectStart,
|
|
3408
|
+
matcherNodeEnd,
|
|
3409
|
+
nodeIsChildOfExpressionStatement(this.#compiler, expect.matcherNode)
|
|
3410
|
+
? `;(undefined as any as ${sourceText})[${targetText}]`
|
|
3411
|
+
: `(undefined as any as ${sourceText})[${targetText}]`,
|
|
3412
|
+
],
|
|
3413
|
+
]);
|
|
3414
|
+
}
|
|
3336
3415
|
break;
|
|
3416
|
+
}
|
|
3337
3417
|
}
|
|
3338
3418
|
}
|
|
3339
3419
|
visitWhen(when) {
|
|
@@ -3675,14 +3755,15 @@ class IdentifierLookup {
|
|
|
3675
3755
|
}
|
|
3676
3756
|
switch (identifier) {
|
|
3677
3757
|
case "describe":
|
|
3678
|
-
return { brand: "describe", flags
|
|
3758
|
+
return { brand: "describe", flags };
|
|
3679
3759
|
case "it":
|
|
3760
|
+
return { brand: "it", flags };
|
|
3680
3761
|
case "test":
|
|
3681
|
-
return { brand: "test", flags
|
|
3762
|
+
return { brand: "test", flags };
|
|
3682
3763
|
case "expect":
|
|
3683
|
-
return { brand: "expect", flags
|
|
3764
|
+
return { brand: "expect", flags };
|
|
3684
3765
|
case "when":
|
|
3685
|
-
return { brand: "when", flags
|
|
3766
|
+
return { brand: "when", flags };
|
|
3686
3767
|
}
|
|
3687
3768
|
return;
|
|
3688
3769
|
}
|
|
@@ -3735,7 +3816,9 @@ class CollectService {
|
|
|
3735
3816
|
if (!this.#checkNode(node, meta, parent)) {
|
|
3736
3817
|
return;
|
|
3737
3818
|
}
|
|
3738
|
-
if (meta.brand === "describe" ||
|
|
3819
|
+
if (meta.brand === "describe" ||
|
|
3820
|
+
meta.brand === "it" ||
|
|
3821
|
+
meta.brand === "test") {
|
|
3739
3822
|
const testTreeNode = new TestTreeNode(this.#compiler, meta.brand, node, parent, meta.flags);
|
|
3740
3823
|
this.#compiler.forEachChild(node, (node) => {
|
|
3741
3824
|
this.#collectTestTreeNodes(node, testTreeNode, testTree);
|
|
@@ -3746,15 +3829,24 @@ class CollectService {
|
|
|
3746
3829
|
if (meta.brand === "expect") {
|
|
3747
3830
|
const modifierNode = this.#getChainedNode(node, "type");
|
|
3748
3831
|
if (!modifierNode) {
|
|
3832
|
+
const text = "'expect()' must be followed by the '.type' modifier.";
|
|
3833
|
+
const origin = DiagnosticOrigin.fromNode(node);
|
|
3834
|
+
this.#onDiagnostics(Diagnostic.error(text, origin));
|
|
3749
3835
|
return;
|
|
3750
3836
|
}
|
|
3751
3837
|
const notNode = this.#getChainedNode(modifierNode, "not");
|
|
3752
3838
|
const matcherNameNode = this.#getChainedNode(notNode ?? modifierNode);
|
|
3753
3839
|
if (!matcherNameNode) {
|
|
3840
|
+
const text = "The final element in the chain must be a matcher.";
|
|
3841
|
+
const origin = DiagnosticOrigin.fromNode(notNode ?? modifierNode);
|
|
3842
|
+
this.#onDiagnostics(Diagnostic.error(text, origin));
|
|
3754
3843
|
return;
|
|
3755
3844
|
}
|
|
3756
3845
|
const matcherNode = this.#getMatcherNode(matcherNameNode);
|
|
3757
3846
|
if (!matcherNode) {
|
|
3847
|
+
const text = "The matcher must be called with an argument.";
|
|
3848
|
+
const origin = DiagnosticOrigin.fromNode(matcherNameNode);
|
|
3849
|
+
this.#onDiagnostics(Diagnostic.error(text, origin));
|
|
3758
3850
|
return;
|
|
3759
3851
|
}
|
|
3760
3852
|
const expectNode = new ExpectNode(this.#compiler, meta.brand, node, parent, meta.flags, matcherNode, matcherNameNode, modifierNode, notNode);
|
|
@@ -3768,17 +3860,25 @@ class CollectService {
|
|
|
3768
3860
|
if (meta.brand === "when") {
|
|
3769
3861
|
const actionNameNode = this.#getChainedNode(node);
|
|
3770
3862
|
if (!actionNameNode) {
|
|
3863
|
+
const text = "The final element in the chain must be an action.";
|
|
3864
|
+
const origin = DiagnosticOrigin.fromNode(node);
|
|
3865
|
+
this.#onDiagnostics(Diagnostic.error(text, origin));
|
|
3771
3866
|
return;
|
|
3772
3867
|
}
|
|
3773
3868
|
const actionNode = this.#getActionNode(actionNameNode);
|
|
3774
3869
|
if (!actionNode) {
|
|
3870
|
+
const text = "The action must be called with an argument.";
|
|
3871
|
+
const origin = DiagnosticOrigin.fromNode(actionNameNode);
|
|
3872
|
+
this.#onDiagnostics(Diagnostic.error(text, origin));
|
|
3775
3873
|
return;
|
|
3776
3874
|
}
|
|
3777
3875
|
this.#compiler.forEachChild(actionNode, (node) => {
|
|
3778
3876
|
if (this.#compiler.isCallExpression(node)) {
|
|
3779
3877
|
const meta = this.#identifierLookup.resolveTestTreeNodeMeta(node);
|
|
3780
|
-
if (meta?.brand === "describe" ||
|
|
3781
|
-
|
|
3878
|
+
if (meta?.brand === "describe" ||
|
|
3879
|
+
meta?.brand === "it" ||
|
|
3880
|
+
meta?.brand === "test") {
|
|
3881
|
+
const text = CollectDiagnosticText.cannotBeNestedWithin(meta.brand, "when");
|
|
3782
3882
|
const origin = DiagnosticOrigin.fromNode(node);
|
|
3783
3883
|
this.#onDiagnostics(Diagnostic.error(text, origin));
|
|
3784
3884
|
}
|
|
@@ -3811,7 +3911,7 @@ class CollectService {
|
|
|
3811
3911
|
}
|
|
3812
3912
|
#checkNode(node, meta, parent) {
|
|
3813
3913
|
if ("brand" in parent && !this.#isNodeAllowed(meta, parent)) {
|
|
3814
|
-
const text = CollectDiagnosticText.cannotBeNestedWithin(meta.
|
|
3914
|
+
const text = CollectDiagnosticText.cannotBeNestedWithin(meta.brand, parent.brand);
|
|
3815
3915
|
const origin = DiagnosticOrigin.fromNode(node);
|
|
3816
3916
|
this.#onDiagnostics(Diagnostic.error(text, origin));
|
|
3817
3917
|
return false;
|
|
@@ -3821,8 +3921,11 @@ class CollectService {
|
|
|
3821
3921
|
#isNodeAllowed(meta, parent) {
|
|
3822
3922
|
switch (meta.brand) {
|
|
3823
3923
|
case "describe":
|
|
3924
|
+
case "it":
|
|
3824
3925
|
case "test":
|
|
3825
|
-
if (parent.brand === "
|
|
3926
|
+
if (parent.brand === "it" ||
|
|
3927
|
+
parent.brand === "test" ||
|
|
3928
|
+
parent.brand === "expect") {
|
|
3826
3929
|
return false;
|
|
3827
3930
|
}
|
|
3828
3931
|
break;
|
|
@@ -3874,14 +3977,11 @@ class CollectService {
|
|
|
3874
3977
|
}
|
|
3875
3978
|
}
|
|
3876
3979
|
|
|
3877
|
-
function nodeBelongsToArgumentList(compiler, node) {
|
|
3878
|
-
return compiler.isCallExpression(node.parent) && node.parent.arguments.some((argument) => argument === node);
|
|
3879
|
-
}
|
|
3880
|
-
|
|
3881
3980
|
var TestTreeNodeBrand;
|
|
3882
3981
|
(function (TestTreeNodeBrand) {
|
|
3883
3982
|
TestTreeNodeBrand["Describe"] = "describe";
|
|
3884
3983
|
TestTreeNodeBrand["Test"] = "test";
|
|
3984
|
+
TestTreeNodeBrand["It"] = "it";
|
|
3885
3985
|
TestTreeNodeBrand["Expect"] = "expect";
|
|
3886
3986
|
TestTreeNodeBrand["When"] = "when";
|
|
3887
3987
|
})(TestTreeNodeBrand || (TestTreeNodeBrand = {}));
|
|
@@ -4261,19 +4361,6 @@ class MatchWorker {
|
|
|
4261
4361
|
this.typeChecker = typeChecker;
|
|
4262
4362
|
this.assertionNode = assertionNode;
|
|
4263
4363
|
}
|
|
4264
|
-
checkHasApplicableIndexType(sourceNode, targetNode) {
|
|
4265
|
-
const sourceType = this.getType(sourceNode);
|
|
4266
|
-
const targetType = this.getType(targetNode);
|
|
4267
|
-
return this.typeChecker
|
|
4268
|
-
.getIndexInfosOfType(sourceType)
|
|
4269
|
-
.some(({ keyType }) => this.typeChecker.isApplicableIndexType(targetType, keyType));
|
|
4270
|
-
}
|
|
4271
|
-
checkHasProperty(sourceNode, propertyNameText) {
|
|
4272
|
-
const sourceType = this.getType(sourceNode);
|
|
4273
|
-
return sourceType
|
|
4274
|
-
.getProperties()
|
|
4275
|
-
.some((property) => this.#compiler.unescapeLeadingUnderscores(property.escapedName) === propertyNameText);
|
|
4276
|
-
}
|
|
4277
4364
|
checkIsAssignableTo(sourceNode, targetNode) {
|
|
4278
4365
|
return this.#checkIsRelatedTo(sourceNode, targetNode, "assignable");
|
|
4279
4366
|
}
|
|
@@ -4702,19 +4789,8 @@ class ToBeCallableWith extends AbilityMatcherBase {
|
|
|
4702
4789
|
explainText = ExpectDiagnosticText.isCallable;
|
|
4703
4790
|
explainNotText = ExpectDiagnosticText.isNotCallable;
|
|
4704
4791
|
match(matchWorker, sourceNode, targetNodes, onDiagnostics) {
|
|
4705
|
-
|
|
4706
|
-
if (
|
|
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) {
|
|
4792
|
+
const sourceType = matchWorker.getType(sourceNode);
|
|
4793
|
+
if (sourceType.getCallSignatures().length === 0) {
|
|
4718
4794
|
const text = [];
|
|
4719
4795
|
if (nodeBelongsToArgumentList(this.compiler, sourceNode)) {
|
|
4720
4796
|
text.push(ExpectDiagnosticText.argumentMustBe("source", "a callable expression"));
|
|
@@ -4722,7 +4798,7 @@ class ToBeCallableWith extends AbilityMatcherBase {
|
|
|
4722
4798
|
else {
|
|
4723
4799
|
text.push(ExpectDiagnosticText.typeArgumentMustBe("Source", "a callable type"));
|
|
4724
4800
|
}
|
|
4725
|
-
if (
|
|
4801
|
+
if (sourceType.getConstructSignatures().length > 0) {
|
|
4726
4802
|
text.push(ExpectDiagnosticText.didYouMeanToUse("the '.toBeConstructableWith()' matcher"));
|
|
4727
4803
|
}
|
|
4728
4804
|
const origin = DiagnosticOrigin.fromNode(sourceNode);
|
|
@@ -4740,16 +4816,8 @@ class ToBeConstructableWith extends AbilityMatcherBase {
|
|
|
4740
4816
|
explainText = ExpectDiagnosticText.isConstructable;
|
|
4741
4817
|
explainNotText = ExpectDiagnosticText.isNotConstructable;
|
|
4742
4818
|
match(matchWorker, sourceNode, targetNodes, onDiagnostics) {
|
|
4743
|
-
|
|
4744
|
-
if (
|
|
4745
|
-
type = matchWorker.typeChecker.getResolvedSignature(sourceNode)?.getReturnType();
|
|
4746
|
-
}
|
|
4747
|
-
if (this.compiler.isExpressionWithTypeArguments(sourceNode) ||
|
|
4748
|
-
this.compiler.isIdentifier(sourceNode) ||
|
|
4749
|
-
this.compiler.isPropertyAccessExpression(sourceNode)) {
|
|
4750
|
-
type = matchWorker.getType(sourceNode);
|
|
4751
|
-
}
|
|
4752
|
-
if (!type || type.getConstructSignatures().length === 0) {
|
|
4819
|
+
const sourceType = matchWorker.getType(sourceNode);
|
|
4820
|
+
if (sourceType.getConstructSignatures().length === 0) {
|
|
4753
4821
|
const text = [];
|
|
4754
4822
|
if (nodeBelongsToArgumentList(this.compiler, sourceNode)) {
|
|
4755
4823
|
text.push(ExpectDiagnosticText.argumentMustBe("source", "a constructable expression"));
|
|
@@ -4757,7 +4825,7 @@ class ToBeConstructableWith extends AbilityMatcherBase {
|
|
|
4757
4825
|
else {
|
|
4758
4826
|
text.push(ExpectDiagnosticText.typeArgumentMustBe("Source", "a constructable type"));
|
|
4759
4827
|
}
|
|
4760
|
-
if (
|
|
4828
|
+
if (sourceType.getCallSignatures().length > 0) {
|
|
4761
4829
|
text.push(ExpectDiagnosticText.didYouMeanToUse("the '.toBeCallableWith()' matcher"));
|
|
4762
4830
|
}
|
|
4763
4831
|
const origin = DiagnosticOrigin.fromNode(sourceNode);
|
|
@@ -4804,14 +4872,7 @@ class ToHaveProperty {
|
|
|
4804
4872
|
diagnostics.push(Diagnostic.error(text, origin));
|
|
4805
4873
|
}
|
|
4806
4874
|
const targetType = matchWorker.getType(targetNode);
|
|
4807
|
-
|
|
4808
|
-
if (isStringOrNumberLiteralType(this.#compiler, targetType)) {
|
|
4809
|
-
propertyNameText = targetType.value.toString();
|
|
4810
|
-
}
|
|
4811
|
-
else if (isUniqueSymbolType(this.#compiler, targetType)) {
|
|
4812
|
-
propertyNameText = this.#compiler.unescapeLeadingUnderscores(targetType.escapedName);
|
|
4813
|
-
}
|
|
4814
|
-
else {
|
|
4875
|
+
if (!(isStringOrNumberLiteralType(this.#compiler, targetType) || isUniqueSymbolType(this.#compiler, targetType))) {
|
|
4815
4876
|
const expectedText = "of type 'string | number | symbol'";
|
|
4816
4877
|
const text = ExpectDiagnosticText.argumentMustBe("key", expectedText);
|
|
4817
4878
|
const origin = DiagnosticOrigin.fromNode(targetNode);
|
|
@@ -4821,11 +4882,9 @@ class ToHaveProperty {
|
|
|
4821
4882
|
onDiagnostics(diagnostics);
|
|
4822
4883
|
return;
|
|
4823
4884
|
}
|
|
4824
|
-
const isMatch = matchWorker.checkHasProperty(sourceNode, propertyNameText) ||
|
|
4825
|
-
matchWorker.checkHasApplicableIndexType(sourceNode, targetNode);
|
|
4826
4885
|
return {
|
|
4827
4886
|
explain: () => this.#explain(matchWorker, sourceNode, targetNode),
|
|
4828
|
-
isMatch,
|
|
4887
|
+
isMatch: matchWorker.assertionNode.abilityDiagnostics.size === 0,
|
|
4829
4888
|
};
|
|
4830
4889
|
}
|
|
4831
4890
|
}
|
|
@@ -5153,8 +5212,7 @@ class FixmeService {
|
|
|
5153
5212
|
FixmeService.#range = FixmeService.#range?.previous;
|
|
5154
5213
|
}
|
|
5155
5214
|
if (isFail === false) {
|
|
5156
|
-
const
|
|
5157
|
-
const text = [FixmeDiagnosticText.wasSupposedToFail(targetText), FixmeDiagnosticText.considerRemoving()];
|
|
5215
|
+
const text = [FixmeDiagnosticText.wasSupposedToFail(owner.brand), FixmeDiagnosticText.considerRemoving()];
|
|
5158
5216
|
const origin = new DiagnosticOrigin(directive.namespace.start, directive.directive.end, directive.sourceFile);
|
|
5159
5217
|
onFileDiagnostics([Diagnostic.error(text, origin)]);
|
|
5160
5218
|
}
|
|
@@ -5206,17 +5264,18 @@ class TestTreeWalker {
|
|
|
5206
5264
|
}
|
|
5207
5265
|
async visit(nodes, runModeFlags, parentResult) {
|
|
5208
5266
|
for (const node of nodes) {
|
|
5209
|
-
if (this.#cancellationToken?.isCancellationRequested) {
|
|
5267
|
+
if (this.#cancellationToken?.isCancellationRequested()) {
|
|
5210
5268
|
break;
|
|
5211
5269
|
}
|
|
5212
5270
|
const fixmeDirective = Directive.getDirectiveRange(this.#compiler, node, "fixme");
|
|
5213
5271
|
if (fixmeDirective) {
|
|
5214
|
-
FixmeService.start(fixmeDirective, node);
|
|
5272
|
+
await FixmeService.start(fixmeDirective, node);
|
|
5215
5273
|
}
|
|
5216
5274
|
switch (node.brand) {
|
|
5217
5275
|
case "describe":
|
|
5218
5276
|
await this.#visitDescribe(node, runModeFlags, parentResult);
|
|
5219
5277
|
break;
|
|
5278
|
+
case "it":
|
|
5220
5279
|
case "test":
|
|
5221
5280
|
await this.#visitTest(node, runModeFlags, parentResult);
|
|
5222
5281
|
break;
|
|
@@ -5348,7 +5407,7 @@ class FileRunner {
|
|
|
5348
5407
|
EventEmitter.dispatch(["file:error", { diagnostics, result }]);
|
|
5349
5408
|
}
|
|
5350
5409
|
async run(file, cancellationToken) {
|
|
5351
|
-
if (cancellationToken.isCancellationRequested) {
|
|
5410
|
+
if (cancellationToken.isCancellationRequested()) {
|
|
5352
5411
|
return;
|
|
5353
5412
|
}
|
|
5354
5413
|
this.#projectService.openFile(file.path);
|
|
@@ -5423,7 +5482,7 @@ class FileRunner {
|
|
|
5423
5482
|
class Runner {
|
|
5424
5483
|
#eventEmitter = new EventEmitter();
|
|
5425
5484
|
#resolvedConfig;
|
|
5426
|
-
static version = "5.0.0-beta.
|
|
5485
|
+
static version = "5.0.0-beta.3";
|
|
5427
5486
|
constructor(resolvedConfig) {
|
|
5428
5487
|
this.#resolvedConfig = resolvedConfig;
|
|
5429
5488
|
}
|
|
@@ -5461,6 +5520,9 @@ class Runner {
|
|
|
5461
5520
|
}
|
|
5462
5521
|
}
|
|
5463
5522
|
async run(files, cancellationToken = new CancellationToken()) {
|
|
5523
|
+
if (!this.#resolvedConfig.watch) {
|
|
5524
|
+
OutputService.writeMessage(prologueText(Runner.version, this.#resolvedConfig.rootPath));
|
|
5525
|
+
}
|
|
5464
5526
|
const fileLocations = files.map((file) => (file instanceof FileLocation ? file : new FileLocation(file)));
|
|
5465
5527
|
this.#addHandlers(cancellationToken);
|
|
5466
5528
|
await this.#addReporters();
|
|
@@ -5487,7 +5549,7 @@ class Runner {
|
|
|
5487
5549
|
EventEmitter.dispatch(["target:end", { result: targetResult }]);
|
|
5488
5550
|
}
|
|
5489
5551
|
EventEmitter.dispatch(["run:end", { result }]);
|
|
5490
|
-
if (cancellationToken.
|
|
5552
|
+
if (cancellationToken.getReason() === "failFast") {
|
|
5491
5553
|
cancellationToken.reset();
|
|
5492
5554
|
}
|
|
5493
5555
|
}
|
|
@@ -5533,11 +5595,11 @@ class Cli {
|
|
|
5533
5595
|
return;
|
|
5534
5596
|
}
|
|
5535
5597
|
const { commandLineOptions, pathMatch } = await Config.parseCommandLine(commandLine);
|
|
5536
|
-
if (cancellationToken.isCancellationRequested) {
|
|
5598
|
+
if (cancellationToken.isCancellationRequested()) {
|
|
5537
5599
|
return;
|
|
5538
5600
|
}
|
|
5539
5601
|
do {
|
|
5540
|
-
if (cancellationToken.
|
|
5602
|
+
if (cancellationToken.getReason() === "configChange") {
|
|
5541
5603
|
cancellationToken.reset();
|
|
5542
5604
|
exitCodeHandler.resetCode();
|
|
5543
5605
|
OutputService.clearTerminal();
|
|
@@ -5551,7 +5613,7 @@ class Cli {
|
|
|
5551
5613
|
commandLineOptions,
|
|
5552
5614
|
pathMatch,
|
|
5553
5615
|
});
|
|
5554
|
-
if (cancellationToken.isCancellationRequested) {
|
|
5616
|
+
if (cancellationToken.isCancellationRequested()) {
|
|
5555
5617
|
if (commandLine.includes("--watch")) {
|
|
5556
5618
|
await this.#waitForChangedFiles(resolvedConfig, cancellationToken);
|
|
5557
5619
|
}
|
|
@@ -5592,7 +5654,7 @@ class Cli {
|
|
|
5592
5654
|
const runner = new Runner(resolvedConfig);
|
|
5593
5655
|
await runner.run(testFiles, cancellationToken);
|
|
5594
5656
|
PluginService.removeHandlers();
|
|
5595
|
-
} while (cancellationToken.
|
|
5657
|
+
} while (cancellationToken.getReason() === "configChange");
|
|
5596
5658
|
this.#eventEmitter.removeHandlers();
|
|
5597
5659
|
}
|
|
5598
5660
|
#waitForChangedFiles(resolvedConfig, cancellationToken) {
|
|
@@ -5623,4 +5685,4 @@ class Cli {
|
|
|
5623
5685
|
}
|
|
5624
5686
|
}
|
|
5625
5687
|
|
|
5626
|
-
export { BaseReporter, CancellationReason, CancellationToken, Cli, Color, Config, ConfigDiagnosticText, DescribeResult, Diagnostic, DiagnosticCategory, DiagnosticOrigin, Directive, EventEmitter, ExpectResult, FileLocation, FileResult, Line, ListReporter, OptionBrand, OptionGroup, Options, OutputService, Path, PluginService, ProjectResult, Result, ResultStatus, Runner, Scribbler, Select, SelectDiagnosticText, SetupReporter, Store, SummaryReporter, SuppressedResult, TargetResult, TestResult, Text, Version, WatchReporter, addsPackageText, defaultOptions, describeNameText, diagnosticBelongsToNode, diagnosticText, environmentOptions, fileStatusText, fileViewText, formattedText, getDiagnosticMessageText, getTextSpanEnd, helpText, isDiagnosticWithLocation, summaryText, testNameText, usesCompilerText, waitingForFileChangesText, watchUsageText };
|
|
5688
|
+
export { BaseReporter, CancellationReason, CancellationToken, Cli, Color, Config, ConfigDiagnosticText, DescribeResult, Diagnostic, DiagnosticCategory, DiagnosticOrigin, Directive, EventEmitter, ExpectResult, FileLocation, FileResult, Line, ListReporter, OptionBrand, OptionGroup, Options, OutputService, Path, PluginService, ProjectResult, Result, ResultStatus, Runner, Scribbler, Select, SelectDiagnosticText, SetupReporter, Store, SummaryReporter, SuppressedResult, TargetResult, TestResult, Text, Version, WatchReporter, addsPackageText, defaultOptions, describeNameText, diagnosticBelongsToNode, diagnosticText, environmentOptions, fileStatusText, fileViewText, formattedText, getDiagnosticMessageText, getTextSpanEnd, helpText, isDiagnosticWithLocation, prologueText, summaryText, testNameText, usesCompilerText, waitingForFileChangesText, watchUsageText };
|