tstyche 3.1.1 → 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/tstyche.d.ts +6 -2
- package/build/tstyche.js +317 -260
- package/package.json +9 -9
package/build/tstyche.js
CHANGED
|
@@ -75,6 +75,12 @@ class ConfigDiagnosticText {
|
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
+
var DiagnosticCategory;
|
|
79
|
+
(function (DiagnosticCategory) {
|
|
80
|
+
DiagnosticCategory["Error"] = "error";
|
|
81
|
+
DiagnosticCategory["Warning"] = "warning";
|
|
82
|
+
})(DiagnosticCategory || (DiagnosticCategory = {}));
|
|
83
|
+
|
|
78
84
|
class DiagnosticOrigin {
|
|
79
85
|
assertion;
|
|
80
86
|
end;
|
|
@@ -116,40 +122,42 @@ class Diagnostic {
|
|
|
116
122
|
return this;
|
|
117
123
|
}
|
|
118
124
|
static error(text, origin) {
|
|
119
|
-
return new Diagnostic(text,
|
|
125
|
+
return new Diagnostic(text, DiagnosticCategory.Error, origin);
|
|
120
126
|
}
|
|
121
127
|
extendWith(text, origin) {
|
|
122
128
|
return new Diagnostic([this.text, text].flat(), this.category, origin ?? this.origin);
|
|
123
129
|
}
|
|
124
|
-
static fromDiagnostics(diagnostics
|
|
130
|
+
static fromDiagnostics(diagnostics) {
|
|
125
131
|
return diagnostics.map((diagnostic) => {
|
|
126
132
|
const code = `ts(${diagnostic.code})`;
|
|
127
133
|
let origin;
|
|
128
|
-
if (
|
|
134
|
+
if (diagnostic.file != null && diagnostic.start != null && diagnostic.length != null) {
|
|
129
135
|
origin = new DiagnosticOrigin(diagnostic.start, diagnostic.start + diagnostic.length, diagnostic.file);
|
|
130
136
|
}
|
|
131
137
|
let related;
|
|
132
138
|
if (diagnostic.relatedInformation != null) {
|
|
133
|
-
related = Diagnostic.fromDiagnostics(diagnostic.relatedInformation
|
|
139
|
+
related = Diagnostic.fromDiagnostics(diagnostic.relatedInformation);
|
|
134
140
|
}
|
|
135
|
-
const text =
|
|
136
|
-
|
|
141
|
+
const text = typeof diagnostic.messageText === "string"
|
|
142
|
+
? diagnostic.messageText
|
|
143
|
+
: Diagnostic.#toMessageText(diagnostic.messageText);
|
|
144
|
+
return new Diagnostic(text, DiagnosticCategory.Error, origin).add({ code, related });
|
|
137
145
|
});
|
|
138
146
|
}
|
|
139
|
-
static #
|
|
140
|
-
|
|
147
|
+
static #toMessageText(chain) {
|
|
148
|
+
const result = [chain.messageText];
|
|
149
|
+
if (chain.next != null) {
|
|
150
|
+
for (const nextChain of chain.next) {
|
|
151
|
+
result.push(...Diagnostic.#toMessageText(nextChain));
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return result;
|
|
141
155
|
}
|
|
142
156
|
static warning(text, origin) {
|
|
143
|
-
return new Diagnostic(text,
|
|
157
|
+
return new Diagnostic(text, DiagnosticCategory.Warning, origin);
|
|
144
158
|
}
|
|
145
159
|
}
|
|
146
160
|
|
|
147
|
-
var DiagnosticCategory;
|
|
148
|
-
(function (DiagnosticCategory) {
|
|
149
|
-
DiagnosticCategory["Error"] = "error";
|
|
150
|
-
DiagnosticCategory["Warning"] = "warning";
|
|
151
|
-
})(DiagnosticCategory || (DiagnosticCategory = {}));
|
|
152
|
-
|
|
153
161
|
class SourceFile {
|
|
154
162
|
fileName;
|
|
155
163
|
#lineMap;
|
|
@@ -255,6 +263,22 @@ class Path {
|
|
|
255
263
|
}
|
|
256
264
|
}
|
|
257
265
|
|
|
266
|
+
var OptionBrand;
|
|
267
|
+
(function (OptionBrand) {
|
|
268
|
+
OptionBrand["String"] = "string";
|
|
269
|
+
OptionBrand["Number"] = "number";
|
|
270
|
+
OptionBrand["Boolean"] = "boolean";
|
|
271
|
+
OptionBrand["BareTrue"] = "bareTrue";
|
|
272
|
+
OptionBrand["List"] = "list";
|
|
273
|
+
})(OptionBrand || (OptionBrand = {}));
|
|
274
|
+
|
|
275
|
+
var OptionGroup;
|
|
276
|
+
(function (OptionGroup) {
|
|
277
|
+
OptionGroup[OptionGroup["CommandLine"] = 2] = "CommandLine";
|
|
278
|
+
OptionGroup[OptionGroup["ConfigFile"] = 4] = "ConfigFile";
|
|
279
|
+
OptionGroup[OptionGroup["ResolvedConfig"] = 6] = "ResolvedConfig";
|
|
280
|
+
})(OptionGroup || (OptionGroup = {}));
|
|
281
|
+
|
|
258
282
|
class Environment {
|
|
259
283
|
static resolve() {
|
|
260
284
|
return {
|
|
@@ -864,151 +888,157 @@ class Target {
|
|
|
864
888
|
class Options {
|
|
865
889
|
static #definitions = [
|
|
866
890
|
{
|
|
867
|
-
brand:
|
|
891
|
+
brand: OptionBrand.String,
|
|
868
892
|
description: "The Url to the config file validation schema.",
|
|
869
|
-
group:
|
|
893
|
+
group: OptionGroup.ConfigFile,
|
|
870
894
|
name: "$schema",
|
|
871
895
|
},
|
|
872
896
|
{
|
|
873
|
-
brand:
|
|
897
|
+
brand: OptionBrand.Boolean,
|
|
898
|
+
description: "Enable type error reporting for source files.",
|
|
899
|
+
group: OptionGroup.ConfigFile,
|
|
900
|
+
name: "checkSourceFiles",
|
|
901
|
+
},
|
|
902
|
+
{
|
|
903
|
+
brand: OptionBrand.String,
|
|
874
904
|
description: "The path to a TSTyche configuration file.",
|
|
875
|
-
group:
|
|
905
|
+
group: OptionGroup.CommandLine,
|
|
876
906
|
name: "config",
|
|
877
907
|
},
|
|
878
908
|
{
|
|
879
|
-
brand:
|
|
909
|
+
brand: OptionBrand.Boolean,
|
|
880
910
|
description: "Stop running tests after the first failed assertion.",
|
|
881
|
-
group:
|
|
911
|
+
group: OptionGroup.ConfigFile | OptionGroup.CommandLine,
|
|
882
912
|
name: "failFast",
|
|
883
913
|
},
|
|
884
914
|
{
|
|
885
|
-
brand:
|
|
915
|
+
brand: OptionBrand.BareTrue,
|
|
886
916
|
description: "Print the list of command line options with brief descriptions and exit.",
|
|
887
|
-
group:
|
|
917
|
+
group: OptionGroup.CommandLine,
|
|
888
918
|
name: "help",
|
|
889
919
|
},
|
|
890
920
|
{
|
|
891
|
-
brand:
|
|
921
|
+
brand: OptionBrand.BareTrue,
|
|
892
922
|
description: "Install specified versions of the 'typescript' package and exit.",
|
|
893
|
-
group:
|
|
923
|
+
group: OptionGroup.CommandLine,
|
|
894
924
|
name: "install",
|
|
895
925
|
},
|
|
896
926
|
{
|
|
897
|
-
brand:
|
|
927
|
+
brand: OptionBrand.BareTrue,
|
|
898
928
|
description: "Print the list of supported versions of the 'typescript' package and exit.",
|
|
899
|
-
group:
|
|
929
|
+
group: OptionGroup.CommandLine,
|
|
900
930
|
name: "list",
|
|
901
931
|
},
|
|
902
932
|
{
|
|
903
|
-
brand:
|
|
933
|
+
brand: OptionBrand.BareTrue,
|
|
904
934
|
description: "Print the list of the selected test files and exit.",
|
|
905
|
-
group:
|
|
935
|
+
group: OptionGroup.CommandLine,
|
|
906
936
|
name: "listFiles",
|
|
907
937
|
},
|
|
908
938
|
{
|
|
909
|
-
brand:
|
|
939
|
+
brand: OptionBrand.String,
|
|
910
940
|
description: "Only run tests with matching name.",
|
|
911
|
-
group:
|
|
941
|
+
group: OptionGroup.CommandLine,
|
|
912
942
|
name: "only",
|
|
913
943
|
},
|
|
914
944
|
{
|
|
915
|
-
brand:
|
|
945
|
+
brand: OptionBrand.List,
|
|
916
946
|
description: "The list of plugins to use.",
|
|
917
|
-
group:
|
|
947
|
+
group: OptionGroup.CommandLine | OptionGroup.ConfigFile,
|
|
918
948
|
items: {
|
|
919
|
-
brand:
|
|
949
|
+
brand: OptionBrand.String,
|
|
920
950
|
name: "plugins",
|
|
921
951
|
},
|
|
922
952
|
name: "plugins",
|
|
923
953
|
},
|
|
924
954
|
{
|
|
925
|
-
brand:
|
|
955
|
+
brand: OptionBrand.BareTrue,
|
|
926
956
|
description: "Remove all installed versions of the 'typescript' package and exit.",
|
|
927
|
-
group:
|
|
957
|
+
group: OptionGroup.CommandLine,
|
|
928
958
|
name: "prune",
|
|
929
959
|
},
|
|
930
960
|
{
|
|
931
|
-
brand:
|
|
961
|
+
brand: OptionBrand.Boolean,
|
|
932
962
|
description: "Reject the 'any' type passed as an argument to the 'expect()' function or a matcher.",
|
|
933
|
-
group:
|
|
963
|
+
group: OptionGroup.ConfigFile,
|
|
934
964
|
name: "rejectAnyType",
|
|
935
965
|
},
|
|
936
966
|
{
|
|
937
|
-
brand:
|
|
967
|
+
brand: OptionBrand.Boolean,
|
|
938
968
|
description: "Reject the 'never' type passed as an argument to the 'expect()' function or a matcher.",
|
|
939
|
-
group:
|
|
969
|
+
group: OptionGroup.ConfigFile,
|
|
940
970
|
name: "rejectNeverType",
|
|
941
971
|
},
|
|
942
972
|
{
|
|
943
|
-
brand:
|
|
973
|
+
brand: OptionBrand.List,
|
|
944
974
|
description: "The list of reporters to use.",
|
|
945
|
-
group:
|
|
975
|
+
group: OptionGroup.CommandLine | OptionGroup.ConfigFile,
|
|
946
976
|
items: {
|
|
947
|
-
brand:
|
|
977
|
+
brand: OptionBrand.String,
|
|
948
978
|
name: "reporters",
|
|
949
979
|
},
|
|
950
980
|
name: "reporters",
|
|
951
981
|
},
|
|
952
982
|
{
|
|
953
|
-
brand:
|
|
983
|
+
brand: OptionBrand.String,
|
|
954
984
|
description: "The path to a directory containing files of a test project.",
|
|
955
|
-
group:
|
|
985
|
+
group: OptionGroup.ConfigFile,
|
|
956
986
|
name: "rootPath",
|
|
957
987
|
},
|
|
958
988
|
{
|
|
959
|
-
brand:
|
|
989
|
+
brand: OptionBrand.BareTrue,
|
|
960
990
|
description: "Print the resolved configuration and exit.",
|
|
961
|
-
group:
|
|
991
|
+
group: OptionGroup.CommandLine,
|
|
962
992
|
name: "showConfig",
|
|
963
993
|
},
|
|
964
994
|
{
|
|
965
|
-
brand:
|
|
995
|
+
brand: OptionBrand.String,
|
|
966
996
|
description: "Skip tests with matching name.",
|
|
967
|
-
group:
|
|
997
|
+
group: OptionGroup.CommandLine,
|
|
968
998
|
name: "skip",
|
|
969
999
|
},
|
|
970
1000
|
{
|
|
971
|
-
brand:
|
|
1001
|
+
brand: OptionBrand.List,
|
|
972
1002
|
description: "The list of TypeScript versions to be tested on.",
|
|
973
|
-
group:
|
|
1003
|
+
group: OptionGroup.CommandLine | OptionGroup.ConfigFile,
|
|
974
1004
|
items: {
|
|
975
|
-
brand:
|
|
1005
|
+
brand: OptionBrand.String,
|
|
976
1006
|
name: "target",
|
|
977
1007
|
},
|
|
978
1008
|
name: "target",
|
|
979
1009
|
},
|
|
980
1010
|
{
|
|
981
|
-
brand:
|
|
1011
|
+
brand: OptionBrand.List,
|
|
982
1012
|
description: "The list of glob patterns matching the test files.",
|
|
983
|
-
group:
|
|
1013
|
+
group: OptionGroup.ConfigFile,
|
|
984
1014
|
items: {
|
|
985
|
-
brand:
|
|
1015
|
+
brand: OptionBrand.String,
|
|
986
1016
|
name: "testFileMatch",
|
|
987
1017
|
},
|
|
988
1018
|
name: "testFileMatch",
|
|
989
1019
|
},
|
|
990
1020
|
{
|
|
991
|
-
brand:
|
|
1021
|
+
brand: OptionBrand.String,
|
|
992
1022
|
description: "The look up strategy to be used to find the TSConfig file.",
|
|
993
|
-
group:
|
|
1023
|
+
group: OptionGroup.CommandLine | OptionGroup.ConfigFile,
|
|
994
1024
|
name: "tsconfig",
|
|
995
1025
|
},
|
|
996
1026
|
{
|
|
997
|
-
brand:
|
|
1027
|
+
brand: OptionBrand.BareTrue,
|
|
998
1028
|
description: "Fetch the 'typescript' package metadata from the registry and exit.",
|
|
999
|
-
group:
|
|
1029
|
+
group: OptionGroup.CommandLine,
|
|
1000
1030
|
name: "update",
|
|
1001
1031
|
},
|
|
1002
1032
|
{
|
|
1003
|
-
brand:
|
|
1033
|
+
brand: OptionBrand.BareTrue,
|
|
1004
1034
|
description: "Print the version number and exit.",
|
|
1005
|
-
group:
|
|
1035
|
+
group: OptionGroup.CommandLine,
|
|
1006
1036
|
name: "version",
|
|
1007
1037
|
},
|
|
1008
1038
|
{
|
|
1009
|
-
brand:
|
|
1039
|
+
brand: OptionBrand.BareTrue,
|
|
1010
1040
|
description: "Watch for changes and rerun related test files.",
|
|
1011
|
-
group:
|
|
1041
|
+
group: OptionGroup.CommandLine,
|
|
1012
1042
|
name: "watch",
|
|
1013
1043
|
},
|
|
1014
1044
|
];
|
|
@@ -1125,7 +1155,7 @@ class CommandLineParser {
|
|
|
1125
1155
|
this.#commandLineOptions = commandLine;
|
|
1126
1156
|
this.#pathMatch = pathMatch;
|
|
1127
1157
|
this.#onDiagnostics = onDiagnostics;
|
|
1128
|
-
this.#options = Options.for(
|
|
1158
|
+
this.#options = Options.for(OptionGroup.CommandLine);
|
|
1129
1159
|
}
|
|
1130
1160
|
async #onExpectsValue(optionName, optionBrand) {
|
|
1131
1161
|
const text = [
|
|
@@ -1160,18 +1190,18 @@ class CommandLineParser {
|
|
|
1160
1190
|
async #parseOptionValue(commandLineArgs, index, optionName, optionDefinition) {
|
|
1161
1191
|
let optionValue = this.#resolveOptionValue(commandLineArgs[index]);
|
|
1162
1192
|
switch (optionDefinition.brand) {
|
|
1163
|
-
case
|
|
1193
|
+
case OptionBrand.BareTrue:
|
|
1164
1194
|
await Options.validate(optionName, optionValue, optionDefinition.brand, this.#onDiagnostics);
|
|
1165
1195
|
this.#commandLineOptions[optionDefinition.name] = true;
|
|
1166
1196
|
break;
|
|
1167
|
-
case
|
|
1197
|
+
case OptionBrand.Boolean:
|
|
1168
1198
|
await Options.validate(optionName, optionValue, optionDefinition.brand, this.#onDiagnostics);
|
|
1169
1199
|
this.#commandLineOptions[optionDefinition.name] = optionValue !== "false";
|
|
1170
1200
|
if (optionValue === "false" || optionValue === "true") {
|
|
1171
1201
|
index++;
|
|
1172
1202
|
}
|
|
1173
1203
|
break;
|
|
1174
|
-
case
|
|
1204
|
+
case OptionBrand.List:
|
|
1175
1205
|
if (optionValue !== "") {
|
|
1176
1206
|
const optionValues = optionValue
|
|
1177
1207
|
.split(",")
|
|
@@ -1187,7 +1217,7 @@ class CommandLineParser {
|
|
|
1187
1217
|
}
|
|
1188
1218
|
await this.#onExpectsValue(optionName, optionDefinition.brand);
|
|
1189
1219
|
break;
|
|
1190
|
-
case
|
|
1220
|
+
case OptionBrand.String:
|
|
1191
1221
|
if (optionValue !== "") {
|
|
1192
1222
|
optionValue = Options.resolve(optionName, optionValue);
|
|
1193
1223
|
await Options.validate(optionName, optionValue, optionDefinition.brand, this.#onDiagnostics);
|
|
@@ -1343,7 +1373,7 @@ class ConfigFileParser {
|
|
|
1343
1373
|
this.#configFileOptions = configFileOptions;
|
|
1344
1374
|
this.#sourceFile = sourceFile;
|
|
1345
1375
|
this.#onDiagnostics = onDiagnostics;
|
|
1346
|
-
this.#options = Options.for(
|
|
1376
|
+
this.#options = Options.for(OptionGroup.ConfigFile);
|
|
1347
1377
|
this.#jsonScanner = new JsonScanner(this.#sourceFile);
|
|
1348
1378
|
}
|
|
1349
1379
|
#onRequiresValue(optionDefinition, jsonNode, isListItem) {
|
|
@@ -1356,7 +1386,7 @@ class ConfigFileParser {
|
|
|
1356
1386
|
let jsonNode;
|
|
1357
1387
|
let optionValue;
|
|
1358
1388
|
switch (optionDefinition.brand) {
|
|
1359
|
-
case
|
|
1389
|
+
case OptionBrand.Boolean: {
|
|
1360
1390
|
jsonNode = this.#jsonScanner.read();
|
|
1361
1391
|
optionValue = jsonNode.getValue();
|
|
1362
1392
|
if (typeof optionValue !== "boolean") {
|
|
@@ -1365,7 +1395,7 @@ class ConfigFileParser {
|
|
|
1365
1395
|
}
|
|
1366
1396
|
break;
|
|
1367
1397
|
}
|
|
1368
|
-
case
|
|
1398
|
+
case OptionBrand.String: {
|
|
1369
1399
|
jsonNode = this.#jsonScanner.read();
|
|
1370
1400
|
optionValue = jsonNode.getValue();
|
|
1371
1401
|
if (typeof optionValue !== "string") {
|
|
@@ -1377,7 +1407,7 @@ class ConfigFileParser {
|
|
|
1377
1407
|
await Options.validate(optionDefinition.name, optionValue, optionDefinition.brand, this.#onDiagnostics, jsonNode.origin);
|
|
1378
1408
|
break;
|
|
1379
1409
|
}
|
|
1380
|
-
case
|
|
1410
|
+
case OptionBrand.List: {
|
|
1381
1411
|
optionValue = [];
|
|
1382
1412
|
const leftBracketToken = this.#jsonScanner.readToken("[");
|
|
1383
1413
|
if (!leftBracketToken.text) {
|
|
@@ -1474,6 +1504,7 @@ class ConfigFileParser {
|
|
|
1474
1504
|
}
|
|
1475
1505
|
|
|
1476
1506
|
const defaultOptions = {
|
|
1507
|
+
checkSourceFiles: false,
|
|
1477
1508
|
failFast: false,
|
|
1478
1509
|
plugins: [],
|
|
1479
1510
|
rejectAnyType: false,
|
|
@@ -1535,22 +1566,6 @@ class Config {
|
|
|
1535
1566
|
}
|
|
1536
1567
|
}
|
|
1537
1568
|
|
|
1538
|
-
var OptionBrand;
|
|
1539
|
-
(function (OptionBrand) {
|
|
1540
|
-
OptionBrand["String"] = "string";
|
|
1541
|
-
OptionBrand["Number"] = "number";
|
|
1542
|
-
OptionBrand["Boolean"] = "boolean";
|
|
1543
|
-
OptionBrand["BareTrue"] = "bareTrue";
|
|
1544
|
-
OptionBrand["List"] = "list";
|
|
1545
|
-
})(OptionBrand || (OptionBrand = {}));
|
|
1546
|
-
|
|
1547
|
-
var OptionGroup;
|
|
1548
|
-
(function (OptionGroup) {
|
|
1549
|
-
OptionGroup[OptionGroup["CommandLine"] = 2] = "CommandLine";
|
|
1550
|
-
OptionGroup[OptionGroup["ConfigFile"] = 4] = "ConfigFile";
|
|
1551
|
-
OptionGroup[OptionGroup["ResolvedConfig"] = 6] = "ResolvedConfig";
|
|
1552
|
-
})(OptionGroup || (OptionGroup = {}));
|
|
1553
|
-
|
|
1554
1569
|
class CancellationHandler {
|
|
1555
1570
|
#cancellationToken;
|
|
1556
1571
|
#cancellationReason;
|
|
@@ -1560,7 +1575,7 @@ class CancellationHandler {
|
|
|
1560
1575
|
}
|
|
1561
1576
|
on([, payload]) {
|
|
1562
1577
|
if ("diagnostics" in payload) {
|
|
1563
|
-
if (payload.diagnostics.some((diagnostic) => diagnostic.category ===
|
|
1578
|
+
if (payload.diagnostics.some((diagnostic) => diagnostic.category === DiagnosticCategory.Error)) {
|
|
1564
1579
|
this.#cancellationToken.cancel(this.#cancellationReason);
|
|
1565
1580
|
}
|
|
1566
1581
|
}
|
|
@@ -1574,7 +1589,7 @@ class ExitCodeHandler {
|
|
|
1574
1589
|
return;
|
|
1575
1590
|
}
|
|
1576
1591
|
if ("diagnostics" in payload) {
|
|
1577
|
-
if (payload.diagnostics.some((diagnostic) => diagnostic.category ===
|
|
1592
|
+
if (payload.diagnostics.some((diagnostic) => diagnostic.category === DiagnosticCategory.Error)) {
|
|
1578
1593
|
this.#setCode(1);
|
|
1579
1594
|
}
|
|
1580
1595
|
}
|
|
@@ -1606,11 +1621,20 @@ class DescribeResult {
|
|
|
1606
1621
|
}
|
|
1607
1622
|
}
|
|
1608
1623
|
|
|
1624
|
+
var ResultStatus;
|
|
1625
|
+
(function (ResultStatus) {
|
|
1626
|
+
ResultStatus["Runs"] = "runs";
|
|
1627
|
+
ResultStatus["Passed"] = "passed";
|
|
1628
|
+
ResultStatus["Failed"] = "failed";
|
|
1629
|
+
ResultStatus["Skipped"] = "skipped";
|
|
1630
|
+
ResultStatus["Todo"] = "todo";
|
|
1631
|
+
})(ResultStatus || (ResultStatus = {}));
|
|
1632
|
+
|
|
1609
1633
|
class ExpectResult {
|
|
1610
1634
|
assertion;
|
|
1611
1635
|
diagnostics = [];
|
|
1612
1636
|
parent;
|
|
1613
|
-
status =
|
|
1637
|
+
status = ResultStatus.Runs;
|
|
1614
1638
|
timing = new ResultTiming();
|
|
1615
1639
|
constructor(assertion, parent) {
|
|
1616
1640
|
this.assertion = assertion;
|
|
@@ -1654,18 +1678,9 @@ class Result {
|
|
|
1654
1678
|
}
|
|
1655
1679
|
}
|
|
1656
1680
|
|
|
1657
|
-
var ResultStatus;
|
|
1658
|
-
(function (ResultStatus) {
|
|
1659
|
-
ResultStatus["Runs"] = "runs";
|
|
1660
|
-
ResultStatus["Passed"] = "passed";
|
|
1661
|
-
ResultStatus["Failed"] = "failed";
|
|
1662
|
-
ResultStatus["Skipped"] = "skipped";
|
|
1663
|
-
ResultStatus["Todo"] = "todo";
|
|
1664
|
-
})(ResultStatus || (ResultStatus = {}));
|
|
1665
|
-
|
|
1666
1681
|
class TargetResult {
|
|
1667
1682
|
results = new Map();
|
|
1668
|
-
status =
|
|
1683
|
+
status = ResultStatus.Runs;
|
|
1669
1684
|
target;
|
|
1670
1685
|
tasks;
|
|
1671
1686
|
timing = new ResultTiming();
|
|
@@ -1679,7 +1694,7 @@ class TaskResult {
|
|
|
1679
1694
|
diagnostics = [];
|
|
1680
1695
|
expectCount = new ResultCount();
|
|
1681
1696
|
results = [];
|
|
1682
|
-
status =
|
|
1697
|
+
status = ResultStatus.Runs;
|
|
1683
1698
|
task;
|
|
1684
1699
|
testCount = new ResultCount();
|
|
1685
1700
|
timing = new ResultTiming();
|
|
@@ -1693,7 +1708,7 @@ class TestResult {
|
|
|
1693
1708
|
expectCount = new ResultCount();
|
|
1694
1709
|
parent;
|
|
1695
1710
|
results = [];
|
|
1696
|
-
status =
|
|
1711
|
+
status = ResultStatus.Runs;
|
|
1697
1712
|
test;
|
|
1698
1713
|
timing = new ResultTiming();
|
|
1699
1714
|
constructor(test, parent) {
|
|
@@ -1726,19 +1741,19 @@ class ResultHandler {
|
|
|
1726
1741
|
this.#targetResult.timing.start = Date.now();
|
|
1727
1742
|
break;
|
|
1728
1743
|
case "target:end":
|
|
1729
|
-
if (this.#targetResult.status ===
|
|
1744
|
+
if (this.#targetResult.status === ResultStatus.Failed) {
|
|
1730
1745
|
this.#result.targetCount.failed++;
|
|
1731
1746
|
}
|
|
1732
1747
|
else {
|
|
1733
1748
|
this.#result.targetCount.passed++;
|
|
1734
|
-
this.#targetResult.status =
|
|
1749
|
+
this.#targetResult.status = ResultStatus.Passed;
|
|
1735
1750
|
}
|
|
1736
1751
|
this.#targetResult.timing.end = Date.now();
|
|
1737
1752
|
this.#targetResult = undefined;
|
|
1738
1753
|
break;
|
|
1739
1754
|
case "store:error":
|
|
1740
|
-
if (payload.diagnostics.some(({ category }) => category ===
|
|
1741
|
-
this.#targetResult.status =
|
|
1755
|
+
if (payload.diagnostics.some(({ category }) => category === DiagnosticCategory.Error)) {
|
|
1756
|
+
this.#targetResult.status = ResultStatus.Failed;
|
|
1742
1757
|
}
|
|
1743
1758
|
break;
|
|
1744
1759
|
case "project:uses": {
|
|
@@ -1751,7 +1766,7 @@ class ResultHandler {
|
|
|
1751
1766
|
break;
|
|
1752
1767
|
}
|
|
1753
1768
|
case "project:error":
|
|
1754
|
-
this.#targetResult.status =
|
|
1769
|
+
this.#targetResult.status = ResultStatus.Failed;
|
|
1755
1770
|
this.#projectResult.diagnostics.push(...payload.diagnostics);
|
|
1756
1771
|
break;
|
|
1757
1772
|
case "task:start":
|
|
@@ -1760,21 +1775,21 @@ class ResultHandler {
|
|
|
1760
1775
|
this.#taskResult.timing.start = Date.now();
|
|
1761
1776
|
break;
|
|
1762
1777
|
case "task:error":
|
|
1763
|
-
this.#targetResult.status =
|
|
1764
|
-
this.#taskResult.status =
|
|
1778
|
+
this.#targetResult.status = ResultStatus.Failed;
|
|
1779
|
+
this.#taskResult.status = ResultStatus.Failed;
|
|
1765
1780
|
this.#taskResult.diagnostics.push(...payload.diagnostics);
|
|
1766
1781
|
break;
|
|
1767
1782
|
case "task:end":
|
|
1768
|
-
if (this.#taskResult.status ===
|
|
1783
|
+
if (this.#taskResult.status === ResultStatus.Failed ||
|
|
1769
1784
|
this.#taskResult.expectCount.failed > 0 ||
|
|
1770
1785
|
this.#taskResult.testCount.failed > 0) {
|
|
1771
1786
|
this.#result.fileCount.failed++;
|
|
1772
|
-
this.#targetResult.status =
|
|
1773
|
-
this.#taskResult.status =
|
|
1787
|
+
this.#targetResult.status = ResultStatus.Failed;
|
|
1788
|
+
this.#taskResult.status = ResultStatus.Failed;
|
|
1774
1789
|
}
|
|
1775
1790
|
else {
|
|
1776
1791
|
this.#result.fileCount.passed++;
|
|
1777
|
-
this.#taskResult.status =
|
|
1792
|
+
this.#taskResult.status = ResultStatus.Passed;
|
|
1778
1793
|
}
|
|
1779
1794
|
this.#taskResult.timing.end = Date.now();
|
|
1780
1795
|
this.#taskResult = undefined;
|
|
@@ -1806,7 +1821,7 @@ class ResultHandler {
|
|
|
1806
1821
|
case "test:error":
|
|
1807
1822
|
this.#result.testCount.failed++;
|
|
1808
1823
|
this.#taskResult.testCount.failed++;
|
|
1809
|
-
this.#testResult.status =
|
|
1824
|
+
this.#testResult.status = ResultStatus.Failed;
|
|
1810
1825
|
this.#testResult.diagnostics.push(...payload.diagnostics);
|
|
1811
1826
|
this.#testResult.timing.end = Date.now();
|
|
1812
1827
|
this.#testResult = undefined;
|
|
@@ -1814,28 +1829,28 @@ class ResultHandler {
|
|
|
1814
1829
|
case "test:fail":
|
|
1815
1830
|
this.#result.testCount.failed++;
|
|
1816
1831
|
this.#taskResult.testCount.failed++;
|
|
1817
|
-
this.#testResult.status =
|
|
1832
|
+
this.#testResult.status = ResultStatus.Failed;
|
|
1818
1833
|
this.#testResult.timing.end = Date.now();
|
|
1819
1834
|
this.#testResult = undefined;
|
|
1820
1835
|
break;
|
|
1821
1836
|
case "test:pass":
|
|
1822
1837
|
this.#result.testCount.passed++;
|
|
1823
1838
|
this.#taskResult.testCount.passed++;
|
|
1824
|
-
this.#testResult.status =
|
|
1839
|
+
this.#testResult.status = ResultStatus.Passed;
|
|
1825
1840
|
this.#testResult.timing.end = Date.now();
|
|
1826
1841
|
this.#testResult = undefined;
|
|
1827
1842
|
break;
|
|
1828
1843
|
case "test:skip":
|
|
1829
1844
|
this.#result.testCount.skipped++;
|
|
1830
1845
|
this.#taskResult.testCount.skipped++;
|
|
1831
|
-
this.#testResult.status =
|
|
1846
|
+
this.#testResult.status = ResultStatus.Skipped;
|
|
1832
1847
|
this.#testResult.timing.end = Date.now();
|
|
1833
1848
|
this.#testResult = undefined;
|
|
1834
1849
|
break;
|
|
1835
1850
|
case "test:todo":
|
|
1836
1851
|
this.#result.testCount.todo++;
|
|
1837
1852
|
this.#taskResult.testCount.todo++;
|
|
1838
|
-
this.#testResult.status =
|
|
1853
|
+
this.#testResult.status = ResultStatus.Todo;
|
|
1839
1854
|
this.#testResult.timing.end = Date.now();
|
|
1840
1855
|
this.#testResult = undefined;
|
|
1841
1856
|
break;
|
|
@@ -1855,7 +1870,7 @@ class ResultHandler {
|
|
|
1855
1870
|
if (this.#testResult) {
|
|
1856
1871
|
this.#testResult.expectCount.failed++;
|
|
1857
1872
|
}
|
|
1858
|
-
this.#expectResult.status =
|
|
1873
|
+
this.#expectResult.status = ResultStatus.Failed;
|
|
1859
1874
|
this.#expectResult.diagnostics.push(...payload.diagnostics);
|
|
1860
1875
|
this.#expectResult.timing.end = Date.now();
|
|
1861
1876
|
this.#expectResult = undefined;
|
|
@@ -1866,7 +1881,7 @@ class ResultHandler {
|
|
|
1866
1881
|
if (this.#testResult) {
|
|
1867
1882
|
this.#testResult.expectCount.failed++;
|
|
1868
1883
|
}
|
|
1869
|
-
this.#expectResult.status =
|
|
1884
|
+
this.#expectResult.status = ResultStatus.Failed;
|
|
1870
1885
|
this.#expectResult.timing.end = Date.now();
|
|
1871
1886
|
this.#expectResult = undefined;
|
|
1872
1887
|
break;
|
|
@@ -1876,7 +1891,7 @@ class ResultHandler {
|
|
|
1876
1891
|
if (this.#testResult) {
|
|
1877
1892
|
this.#testResult.expectCount.passed++;
|
|
1878
1893
|
}
|
|
1879
|
-
this.#expectResult.status =
|
|
1894
|
+
this.#expectResult.status = ResultStatus.Passed;
|
|
1880
1895
|
this.#expectResult.timing.end = Date.now();
|
|
1881
1896
|
this.#expectResult = undefined;
|
|
1882
1897
|
break;
|
|
@@ -1886,7 +1901,7 @@ class ResultHandler {
|
|
|
1886
1901
|
if (this.#testResult) {
|
|
1887
1902
|
this.#testResult.expectCount.skipped++;
|
|
1888
1903
|
}
|
|
1889
|
-
this.#expectResult.status =
|
|
1904
|
+
this.#expectResult.status = ResultStatus.Skipped;
|
|
1890
1905
|
this.#expectResult.timing.end = Date.now();
|
|
1891
1906
|
this.#expectResult = undefined;
|
|
1892
1907
|
break;
|
|
@@ -1915,7 +1930,7 @@ function Text({ children, color, indent }) {
|
|
|
1915
1930
|
if (color != null) {
|
|
1916
1931
|
ansiEscapes.push(color);
|
|
1917
1932
|
}
|
|
1918
|
-
return (jsx("text", { indent: indent ?? 0, children: [ansiEscapes.length > 0 ? jsx("ansi", { escapes: ansiEscapes }) : undefined, children, ansiEscapes.length > 0 ? jsx("ansi", { escapes:
|
|
1933
|
+
return (jsx("text", { indent: indent ?? 0, children: [ansiEscapes.length > 0 ? jsx("ansi", { escapes: ansiEscapes }) : undefined, children, ansiEscapes.length > 0 ? jsx("ansi", { escapes: Color.Reset }) : undefined] }));
|
|
1919
1934
|
}
|
|
1920
1935
|
|
|
1921
1936
|
function Line({ children, color, indent }) {
|
|
@@ -1976,7 +1991,7 @@ class Scribbler {
|
|
|
1976
1991
|
}
|
|
1977
1992
|
|
|
1978
1993
|
function addsPackageText(packageVersion, packagePath) {
|
|
1979
|
-
return (jsx(Line, { children: [jsx(Text, { color:
|
|
1994
|
+
return (jsx(Line, { children: [jsx(Text, { color: Color.Gray, children: "adds" }), " TypeScript ", packageVersion, jsx(Text, { color: Color.Gray, children: [" to ", packagePath] })] }));
|
|
1980
1995
|
}
|
|
1981
1996
|
|
|
1982
1997
|
function describeNameText(name, indent = 0) {
|
|
@@ -1990,13 +2005,13 @@ function BreadcrumbsText({ ancestor }) {
|
|
|
1990
2005
|
ancestor = ancestor.parent;
|
|
1991
2006
|
}
|
|
1992
2007
|
text.push("");
|
|
1993
|
-
return jsx(Text, { color:
|
|
2008
|
+
return jsx(Text, { color: Color.Gray, children: text.reverse().join(" ❭ ") });
|
|
1994
2009
|
}
|
|
1995
|
-
function CodeLineText({ gutterWidth, lineNumber, lineNumberColor =
|
|
1996
|
-
return (jsx(Line, { children: [jsx(Text, { color: lineNumberColor, children: lineNumber.toString().padStart(gutterWidth) }), jsx(Text, { color:
|
|
2010
|
+
function CodeLineText({ gutterWidth, lineNumber, lineNumberColor = Color.Gray, lineText }) {
|
|
2011
|
+
return (jsx(Line, { children: [jsx(Text, { color: lineNumberColor, children: lineNumber.toString().padStart(gutterWidth) }), jsx(Text, { color: Color.Gray, children: " | " }), lineText] }));
|
|
1997
2012
|
}
|
|
1998
2013
|
function SquiggleLineText({ gutterWidth, indentWidth = 0, squiggleColor, squiggleWidth }) {
|
|
1999
|
-
return (jsx(Line, { children: [" ".repeat(gutterWidth), jsx(Text, { color:
|
|
2014
|
+
return (jsx(Line, { children: [" ".repeat(gutterWidth), jsx(Text, { color: Color.Gray, children: " | " }), " ".repeat(indentWidth), jsx(Text, { color: squiggleColor, children: "~".repeat(squiggleWidth === 0 ? 1 : squiggleWidth) })] }));
|
|
2000
2015
|
}
|
|
2001
2016
|
function CodeSpanText({ diagnosticCategory, diagnosticOrigin }) {
|
|
2002
2017
|
const lineMap = diagnosticOrigin.sourceFile.getLineStarts();
|
|
@@ -2007,11 +2022,11 @@ function CodeSpanText({ diagnosticCategory, diagnosticOrigin }) {
|
|
|
2007
2022
|
const gutterWidth = (lastLine + 1).toString().length + 2;
|
|
2008
2023
|
let highlightColor;
|
|
2009
2024
|
switch (diagnosticCategory) {
|
|
2010
|
-
case
|
|
2011
|
-
highlightColor =
|
|
2025
|
+
case DiagnosticCategory.Error:
|
|
2026
|
+
highlightColor = Color.Red;
|
|
2012
2027
|
break;
|
|
2013
|
-
case
|
|
2014
|
-
highlightColor =
|
|
2028
|
+
case DiagnosticCategory.Warning:
|
|
2029
|
+
highlightColor = Color.Yellow;
|
|
2015
2030
|
break;
|
|
2016
2031
|
}
|
|
2017
2032
|
const codeSpan = [];
|
|
@@ -2038,14 +2053,14 @@ function CodeSpanText({ diagnosticCategory, diagnosticOrigin }) {
|
|
|
2038
2053
|
codeSpan.push(jsx(CodeLineText, { gutterWidth: gutterWidth, lineNumber: index + 1, lineText: lineText }));
|
|
2039
2054
|
}
|
|
2040
2055
|
}
|
|
2041
|
-
const location = (jsx(Line, { children: [" ".repeat(gutterWidth + 2), jsx(Text, { color:
|
|
2056
|
+
const location = (jsx(Line, { children: [" ".repeat(gutterWidth + 2), jsx(Text, { color: Color.Gray, children: " at " }), jsx(Text, { color: Color.Cyan, children: Path.relative("", diagnosticOrigin.sourceFile.fileName) }), jsx(Text, { color: Color.Gray, children: `:${firstMarkedLine + 1}:${firstMarkedLineCharacter + 1}` }), diagnosticOrigin.assertion && jsx(BreadcrumbsText, { ancestor: diagnosticOrigin.assertion.parent })] }));
|
|
2042
2057
|
return (jsx(Text, { children: [codeSpan, jsx(Line, {}), location] }));
|
|
2043
2058
|
}
|
|
2044
2059
|
|
|
2045
2060
|
function DiagnosticText({ diagnostic }) {
|
|
2046
|
-
const code = diagnostic.code ? jsx(Text, { color:
|
|
2061
|
+
const code = diagnostic.code ? jsx(Text, { color: Color.Gray, children: [" ", diagnostic.code] }) : undefined;
|
|
2047
2062
|
const text = Array.isArray(diagnostic.text) ? diagnostic.text : [diagnostic.text];
|
|
2048
|
-
const message = text.map((text, index) => (jsx(Text, { children: [index === 1 ? jsx(Line, {}) : undefined, jsx(Line, { children: [text, code] })] })));
|
|
2063
|
+
const message = text.map((text, index) => (jsx(Text, { children: [index === 1 ? jsx(Line, {}) : undefined, jsx(Line, { children: [text, index === 0 ? code : undefined] })] })));
|
|
2049
2064
|
const related = diagnostic.related?.map((relatedDiagnostic) => jsx(DiagnosticText, { diagnostic: relatedDiagnostic }));
|
|
2050
2065
|
const codeSpan = diagnostic.origin ? (jsx(Text, { children: [jsx(Line, {}), jsx(CodeSpanText, { diagnosticCategory: diagnostic.category, diagnosticOrigin: diagnostic.origin })] })) : undefined;
|
|
2051
2066
|
return (jsx(Text, { children: [message, codeSpan, jsx(Line, {}), jsx(Text, { indent: 2, children: related })] }));
|
|
@@ -2053,11 +2068,11 @@ function DiagnosticText({ diagnostic }) {
|
|
|
2053
2068
|
function diagnosticText(diagnostic) {
|
|
2054
2069
|
let prefix;
|
|
2055
2070
|
switch (diagnostic.category) {
|
|
2056
|
-
case
|
|
2057
|
-
prefix = jsx(Text, { color:
|
|
2071
|
+
case DiagnosticCategory.Error:
|
|
2072
|
+
prefix = jsx(Text, { color: Color.Red, children: "Error: " });
|
|
2058
2073
|
break;
|
|
2059
|
-
case
|
|
2060
|
-
prefix = jsx(Text, { color:
|
|
2074
|
+
case DiagnosticCategory.Warning:
|
|
2075
|
+
prefix = jsx(Text, { color: Color.Yellow, children: "Warning: " });
|
|
2061
2076
|
break;
|
|
2062
2077
|
}
|
|
2063
2078
|
return (jsx(Text, { children: [prefix, jsx(DiagnosticText, { diagnostic: diagnostic })] }));
|
|
@@ -2068,22 +2083,22 @@ function FileNameText({ filePath }) {
|
|
|
2068
2083
|
const lastPathSeparator = relativePath.lastIndexOf("/");
|
|
2069
2084
|
const directoryNameText = relativePath.slice(0, lastPathSeparator + 1);
|
|
2070
2085
|
const fileNameText = relativePath.slice(lastPathSeparator + 1);
|
|
2071
|
-
return (jsx(Text, { children: [jsx(Text, { color:
|
|
2086
|
+
return (jsx(Text, { children: [jsx(Text, { color: Color.Gray, children: directoryNameText }), fileNameText] }));
|
|
2072
2087
|
}
|
|
2073
2088
|
function taskStatusText(status, task) {
|
|
2074
2089
|
let statusColor;
|
|
2075
2090
|
let statusText;
|
|
2076
2091
|
switch (status) {
|
|
2077
|
-
case
|
|
2078
|
-
statusColor =
|
|
2092
|
+
case ResultStatus.Runs:
|
|
2093
|
+
statusColor = Color.Yellow;
|
|
2079
2094
|
statusText = "runs";
|
|
2080
2095
|
break;
|
|
2081
|
-
case
|
|
2082
|
-
statusColor =
|
|
2096
|
+
case ResultStatus.Passed:
|
|
2097
|
+
statusColor = Color.Green;
|
|
2083
2098
|
statusText = "pass";
|
|
2084
2099
|
break;
|
|
2085
|
-
case
|
|
2086
|
-
statusColor =
|
|
2100
|
+
case ResultStatus.Failed:
|
|
2101
|
+
statusColor = Color.Red;
|
|
2087
2102
|
statusText = "fail";
|
|
2088
2103
|
break;
|
|
2089
2104
|
}
|
|
@@ -2113,13 +2128,13 @@ function formattedText(input) {
|
|
|
2113
2128
|
}
|
|
2114
2129
|
|
|
2115
2130
|
function HintText({ children }) {
|
|
2116
|
-
return (jsx(Text, { indent: 1, color:
|
|
2131
|
+
return (jsx(Text, { indent: 1, color: Color.Gray, children: children }));
|
|
2117
2132
|
}
|
|
2118
2133
|
function HelpHeaderText({ tstycheVersion }) {
|
|
2119
2134
|
return (jsx(Line, { children: ["The TSTyche Type Test Runner", jsx(HintText, { children: tstycheVersion })] }));
|
|
2120
2135
|
}
|
|
2121
2136
|
function CommandText({ hint, text }) {
|
|
2122
|
-
return (jsx(Line, { indent: 1, children: [jsx(Text, { color:
|
|
2137
|
+
return (jsx(Line, { indent: 1, children: [jsx(Text, { color: Color.Blue, children: text }), hint && jsx(HintText, { children: hint })] }));
|
|
2123
2138
|
}
|
|
2124
2139
|
function OptionDescriptionText({ text }) {
|
|
2125
2140
|
return jsx(Line, { indent: 1, children: text });
|
|
@@ -2137,7 +2152,7 @@ function CommandLineOptionNameText({ text }) {
|
|
|
2137
2152
|
return jsx(Text, { children: `--${text}` });
|
|
2138
2153
|
}
|
|
2139
2154
|
function CommandLineOptionHintText({ definition }) {
|
|
2140
|
-
if (definition.brand ===
|
|
2155
|
+
if (definition.brand === OptionBrand.List) {
|
|
2141
2156
|
return jsx(Text, { children: `${definition.brand} of ${definition.items.brand}s` });
|
|
2142
2157
|
}
|
|
2143
2158
|
return jsx(Text, { children: definition.brand });
|
|
@@ -2146,7 +2161,7 @@ function CommandLineOptionsText({ optionDefinitions }) {
|
|
|
2146
2161
|
const definitions = [...optionDefinitions.values()];
|
|
2147
2162
|
const optionsText = definitions.map((definition) => {
|
|
2148
2163
|
let hint;
|
|
2149
|
-
if (definition.brand !==
|
|
2164
|
+
if (definition.brand !== OptionBrand.BareTrue) {
|
|
2150
2165
|
hint = jsx(CommandLineOptionHintText, { definition: definition });
|
|
2151
2166
|
}
|
|
2152
2167
|
return (jsx(Text, { children: [jsx(CommandText, { text: jsx(CommandLineOptionNameText, { text: definition.name }), hint: hint }), jsx(OptionDescriptionText, { text: definition.description }), jsx(Line, {})] }));
|
|
@@ -2196,7 +2211,7 @@ function RowText({ label, text }) {
|
|
|
2196
2211
|
return (jsx(Line, { children: [`${label}:`.padEnd(12), text] }));
|
|
2197
2212
|
}
|
|
2198
2213
|
function CountText({ failed, passed, skipped, todo, total }) {
|
|
2199
|
-
return (jsx(Text, { children: [failed > 0 ? (jsx(Text, { children: [jsx(Text, { color:
|
|
2214
|
+
return (jsx(Text, { children: [failed > 0 ? (jsx(Text, { children: [jsx(Text, { color: Color.Red, children: [failed, " failed"] }), jsx(Text, { children: ", " })] })) : undefined, skipped > 0 ? (jsx(Text, { children: [jsx(Text, { color: Color.Yellow, children: [skipped, " skipped"] }), jsx(Text, { children: ", " })] })) : undefined, todo > 0 ? (jsx(Text, { children: [jsx(Text, { color: Color.Magenta, children: [todo, " todo"] }), jsx(Text, { children: ", " })] })) : undefined, passed > 0 ? (jsx(Text, { children: [jsx(Text, { color: Color.Green, children: [passed, " passed"] }), jsx(Text, { children: ", " })] })) : undefined, jsx(Text, { children: [total, " total"] })] }));
|
|
2200
2215
|
}
|
|
2201
2216
|
function DurationText({ seconds }) {
|
|
2202
2217
|
return jsx(Text, { children: `${Math.round(seconds * 10) / 10}s` });
|
|
@@ -2209,24 +2224,24 @@ function MatchText({ text }) {
|
|
|
2209
2224
|
return jsx(Text, { children: ["'", ...text, "'"] });
|
|
2210
2225
|
}
|
|
2211
2226
|
const lastItem = text.pop();
|
|
2212
|
-
return (jsx(Text, { children: [text.map((match, index, list) => (jsx(Text, { children: ["'", match, "'", index === list.length - 1 ? jsx(Text, { children: " " }) : jsx(Text, { color:
|
|
2227
|
+
return (jsx(Text, { children: [text.map((match, index, list) => (jsx(Text, { children: ["'", match, "'", index === list.length - 1 ? jsx(Text, { children: " " }) : jsx(Text, { color: Color.Gray, children: ", " })] }))), jsx(Text, { color: Color.Gray, children: "or" }), " '", lastItem, "'"] }));
|
|
2213
2228
|
}
|
|
2214
2229
|
function RanFilesText({ onlyMatch, pathMatch, skipMatch }) {
|
|
2215
2230
|
const testNameMatchText = [];
|
|
2216
2231
|
if (onlyMatch != null) {
|
|
2217
|
-
testNameMatchText.push(jsx(Text, { children: [jsx(Text, { color:
|
|
2232
|
+
testNameMatchText.push(jsx(Text, { children: [jsx(Text, { color: Color.Gray, children: "matching " }), jsx(MatchText, { text: onlyMatch })] }));
|
|
2218
2233
|
}
|
|
2219
2234
|
if (skipMatch != null) {
|
|
2220
|
-
testNameMatchText.push(jsx(Text, { children: [onlyMatch && jsx(Text, { color:
|
|
2235
|
+
testNameMatchText.push(jsx(Text, { children: [onlyMatch && jsx(Text, { color: Color.Gray, children: " and " }), jsx(Text, { color: Color.Gray, children: "not matching " }), jsx(MatchText, { text: skipMatch })] }));
|
|
2221
2236
|
}
|
|
2222
2237
|
let pathMatchText;
|
|
2223
2238
|
if (pathMatch.length > 0) {
|
|
2224
|
-
pathMatchText = (jsx(Text, { children: [jsx(Text, { color:
|
|
2239
|
+
pathMatchText = (jsx(Text, { children: [jsx(Text, { color: Color.Gray, children: "test files matching " }), jsx(MatchText, { text: pathMatch }), jsx(Text, { color: Color.Gray, children: "." })] }));
|
|
2225
2240
|
}
|
|
2226
2241
|
else {
|
|
2227
|
-
pathMatchText = jsx(Text, { color:
|
|
2242
|
+
pathMatchText = jsx(Text, { color: Color.Gray, children: "all test files." });
|
|
2228
2243
|
}
|
|
2229
|
-
return (jsx(Line, { children: [jsx(Text, { color:
|
|
2244
|
+
return (jsx(Line, { children: [jsx(Text, { color: Color.Gray, children: "Ran " }), testNameMatchText.length > 0 ? jsx(Text, { color: Color.Gray, children: "tests " }) : undefined, testNameMatchText, testNameMatchText.length > 0 ? jsx(Text, { color: Color.Gray, children: " in " }) : undefined, pathMatchText] }));
|
|
2230
2245
|
}
|
|
2231
2246
|
function summaryText({ duration, expectCount, fileCount, onlyMatch, pathMatch, skipMatch, targetCount, testCount, }) {
|
|
2232
2247
|
const targetCountText = (jsx(RowText, { label: "Targets", text: jsx(CountText, { failed: targetCount.failed, passed: targetCount.passed, skipped: targetCount.skipped, todo: targetCount.todo, total: targetCount.total }) }));
|
|
@@ -2239,25 +2254,25 @@ function summaryText({ duration, expectCount, fileCount, onlyMatch, pathMatch, s
|
|
|
2239
2254
|
function StatusText({ status }) {
|
|
2240
2255
|
switch (status) {
|
|
2241
2256
|
case "fail":
|
|
2242
|
-
return jsx(Text, { color:
|
|
2257
|
+
return jsx(Text, { color: Color.Red, children: "\u00D7" });
|
|
2243
2258
|
case "pass":
|
|
2244
|
-
return jsx(Text, { color:
|
|
2259
|
+
return jsx(Text, { color: Color.Green, children: "+" });
|
|
2245
2260
|
case "skip":
|
|
2246
|
-
return jsx(Text, { color:
|
|
2261
|
+
return jsx(Text, { color: Color.Yellow, children: "- skip" });
|
|
2247
2262
|
case "todo":
|
|
2248
|
-
return jsx(Text, { color:
|
|
2263
|
+
return jsx(Text, { color: Color.Magenta, children: "- todo" });
|
|
2249
2264
|
}
|
|
2250
2265
|
}
|
|
2251
2266
|
function testNameText(status, name, indent = 0) {
|
|
2252
|
-
return (jsx(Line, { indent: indent + 1, children: [jsx(StatusText, { status: status }), " ", jsx(Text, { color:
|
|
2267
|
+
return (jsx(Line, { indent: indent + 1, children: [jsx(StatusText, { status: status }), " ", jsx(Text, { color: Color.Gray, children: name })] }));
|
|
2253
2268
|
}
|
|
2254
2269
|
|
|
2255
2270
|
function usesCompilerText(compilerVersion, projectConfigFilePath, options) {
|
|
2256
2271
|
let projectConfigPathText;
|
|
2257
2272
|
if (projectConfigFilePath != null) {
|
|
2258
|
-
projectConfigPathText = (jsx(Text, { color:
|
|
2273
|
+
projectConfigPathText = (jsx(Text, { color: Color.Gray, children: [" with ", Path.relative("", projectConfigFilePath)] }));
|
|
2259
2274
|
}
|
|
2260
|
-
return (jsx(Text, { children: [options?.prependEmptyLine ? jsx(Line, {}) : undefined, jsx(Line, { children: [jsx(Text, { color:
|
|
2275
|
+
return (jsx(Text, { children: [options?.prependEmptyLine ? jsx(Line, {}) : undefined, jsx(Line, { children: [jsx(Text, { color: Color.Blue, children: "uses" }), " TypeScript ", compilerVersion, projectConfigPathText] }), jsx(Line, {})] }));
|
|
2261
2276
|
}
|
|
2262
2277
|
|
|
2263
2278
|
function waitingForFileChangesText() {
|
|
@@ -2270,7 +2285,7 @@ function watchUsageText() {
|
|
|
2270
2285
|
["x", "to exit."],
|
|
2271
2286
|
];
|
|
2272
2287
|
const usageText = usage.map(([keyText, actionText]) => {
|
|
2273
|
-
return (jsx(Line, { children: [jsx(Text, { color:
|
|
2288
|
+
return (jsx(Line, { children: [jsx(Text, { color: Color.Gray, children: "Press" }), jsx(Text, { children: ` ${keyText} ` }), jsx(Text, { color: Color.Gray, children: actionText })] }));
|
|
2274
2289
|
});
|
|
2275
2290
|
return jsx(Text, { children: usageText });
|
|
2276
2291
|
}
|
|
@@ -2335,12 +2350,11 @@ class FileView {
|
|
|
2335
2350
|
}
|
|
2336
2351
|
|
|
2337
2352
|
class ListReporter extends BaseReporter {
|
|
2338
|
-
#currentCompilerVersion;
|
|
2339
|
-
#currentProjectConfigFilePath;
|
|
2340
2353
|
#fileCount = 0;
|
|
2341
2354
|
#fileView = new FileView();
|
|
2342
2355
|
#hasReportedAdds = false;
|
|
2343
2356
|
#hasReportedError = false;
|
|
2357
|
+
#hasReportedUses = false;
|
|
2344
2358
|
#isFileViewExpanded = false;
|
|
2345
2359
|
#seenDeprecations = new Set();
|
|
2346
2360
|
get #isLastFile() {
|
|
@@ -2371,21 +2385,14 @@ class ListReporter extends BaseReporter {
|
|
|
2371
2385
|
break;
|
|
2372
2386
|
case "target:start":
|
|
2373
2387
|
this.#fileCount = payload.result.tasks.length;
|
|
2374
|
-
|
|
2375
|
-
case "target:end":
|
|
2376
|
-
this.#currentCompilerVersion = undefined;
|
|
2377
|
-
this.#currentProjectConfigFilePath = undefined;
|
|
2388
|
+
this.#hasReportedUses = false;
|
|
2378
2389
|
break;
|
|
2379
2390
|
case "project:uses":
|
|
2380
|
-
|
|
2381
|
-
this.#
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
this.#hasReportedAdds = false;
|
|
2386
|
-
this.#currentCompilerVersion = payload.compilerVersion;
|
|
2387
|
-
this.#currentProjectConfigFilePath = payload.projectConfigFilePath;
|
|
2388
|
-
}
|
|
2391
|
+
OutputService.writeMessage(usesCompilerText(payload.compilerVersion, payload.projectConfigFilePath, {
|
|
2392
|
+
prependEmptyLine: this.#hasReportedUses && !this.#hasReportedAdds && !this.#hasReportedError,
|
|
2393
|
+
}));
|
|
2394
|
+
this.#hasReportedAdds = false;
|
|
2395
|
+
this.#hasReportedUses = true;
|
|
2389
2396
|
break;
|
|
2390
2397
|
case "project:error":
|
|
2391
2398
|
for (const diagnostic of payload.diagnostics) {
|
|
@@ -2474,10 +2481,10 @@ class SetupReporter {
|
|
|
2474
2481
|
if ("diagnostics" in payload) {
|
|
2475
2482
|
for (const diagnostic of payload.diagnostics) {
|
|
2476
2483
|
switch (diagnostic.category) {
|
|
2477
|
-
case
|
|
2484
|
+
case DiagnosticCategory.Error:
|
|
2478
2485
|
OutputService.writeError(diagnosticText(diagnostic));
|
|
2479
2486
|
break;
|
|
2480
|
-
case
|
|
2487
|
+
case DiagnosticCategory.Warning:
|
|
2481
2488
|
OutputService.writeWarning(diagnosticText(diagnostic));
|
|
2482
2489
|
break;
|
|
2483
2490
|
}
|
|
@@ -2841,7 +2848,7 @@ class WatchService {
|
|
|
2841
2848
|
case "\u001B":
|
|
2842
2849
|
case "q":
|
|
2843
2850
|
case "x":
|
|
2844
|
-
onClose(
|
|
2851
|
+
onClose(CancellationReason.WatchClose);
|
|
2845
2852
|
break;
|
|
2846
2853
|
case "\u000D":
|
|
2847
2854
|
case "\u0020":
|
|
@@ -2876,7 +2883,7 @@ class WatchService {
|
|
|
2876
2883
|
};
|
|
2877
2884
|
this.#watchers.push(new Watcher(this.#resolvedConfig.rootPath, onChangedFile, onRemovedFile, { recursive: true }));
|
|
2878
2885
|
const onChangedConfigFile = () => {
|
|
2879
|
-
onClose(
|
|
2886
|
+
onClose(CancellationReason.ConfigChange);
|
|
2880
2887
|
};
|
|
2881
2888
|
this.#watchers.push(new FileWatcher(this.#resolvedConfig.configFilePath, onChangedConfigFile));
|
|
2882
2889
|
for (const watcher of this.#watchers) {
|
|
@@ -2891,6 +2898,13 @@ class WatchService {
|
|
|
2891
2898
|
}
|
|
2892
2899
|
}
|
|
2893
2900
|
|
|
2901
|
+
var TestMemberBrand;
|
|
2902
|
+
(function (TestMemberBrand) {
|
|
2903
|
+
TestMemberBrand["Describe"] = "describe";
|
|
2904
|
+
TestMemberBrand["Test"] = "test";
|
|
2905
|
+
TestMemberBrand["Expect"] = "expect";
|
|
2906
|
+
})(TestMemberBrand || (TestMemberBrand = {}));
|
|
2907
|
+
|
|
2894
2908
|
class TestMember {
|
|
2895
2909
|
brand;
|
|
2896
2910
|
#compiler;
|
|
@@ -2932,17 +2946,17 @@ class TestMember {
|
|
|
2932
2946
|
return node.parent;
|
|
2933
2947
|
};
|
|
2934
2948
|
switch (this.brand) {
|
|
2935
|
-
case
|
|
2949
|
+
case TestMemberBrand.Describe:
|
|
2936
2950
|
for (const member of this.members) {
|
|
2937
|
-
if (member.brand ===
|
|
2951
|
+
if (member.brand === TestMemberBrand.Expect) {
|
|
2938
2952
|
diagnostics.push(Diagnostic.error(getText(member.node), DiagnosticOrigin.fromNode(getParentCallExpression(member.node))));
|
|
2939
2953
|
}
|
|
2940
2954
|
}
|
|
2941
2955
|
break;
|
|
2942
|
-
case
|
|
2943
|
-
case
|
|
2956
|
+
case TestMemberBrand.Test:
|
|
2957
|
+
case TestMemberBrand.Expect:
|
|
2944
2958
|
for (const member of this.members) {
|
|
2945
|
-
if (member.brand !==
|
|
2959
|
+
if (member.brand !== TestMemberBrand.Expect) {
|
|
2946
2960
|
diagnostics.push(Diagnostic.error(getText(member.node), DiagnosticOrigin.fromNode(member.node)));
|
|
2947
2961
|
}
|
|
2948
2962
|
}
|
|
@@ -2977,6 +2991,15 @@ class Assertion extends TestMember {
|
|
|
2977
2991
|
}
|
|
2978
2992
|
}
|
|
2979
2993
|
|
|
2994
|
+
var TestMemberFlags;
|
|
2995
|
+
(function (TestMemberFlags) {
|
|
2996
|
+
TestMemberFlags[TestMemberFlags["None"] = 0] = "None";
|
|
2997
|
+
TestMemberFlags[TestMemberFlags["Fail"] = 1] = "Fail";
|
|
2998
|
+
TestMemberFlags[TestMemberFlags["Only"] = 2] = "Only";
|
|
2999
|
+
TestMemberFlags[TestMemberFlags["Skip"] = 4] = "Skip";
|
|
3000
|
+
TestMemberFlags[TestMemberFlags["Todo"] = 8] = "Todo";
|
|
3001
|
+
})(TestMemberFlags || (TestMemberFlags = {}));
|
|
3002
|
+
|
|
2980
3003
|
class IdentifierLookup {
|
|
2981
3004
|
#compiler;
|
|
2982
3005
|
#identifiers;
|
|
@@ -3021,7 +3044,7 @@ class IdentifierLookup {
|
|
|
3021
3044
|
}
|
|
3022
3045
|
}
|
|
3023
3046
|
resolveTestMemberMeta(node) {
|
|
3024
|
-
let flags =
|
|
3047
|
+
let flags = TestMemberFlags.None;
|
|
3025
3048
|
let expression = node.expression;
|
|
3026
3049
|
while (this.#compiler.isPropertyAccessExpression(expression)) {
|
|
3027
3050
|
if (expression.expression.getText() === this.#identifiers.namespace) {
|
|
@@ -3029,16 +3052,16 @@ class IdentifierLookup {
|
|
|
3029
3052
|
}
|
|
3030
3053
|
switch (expression.name.getText()) {
|
|
3031
3054
|
case "fail":
|
|
3032
|
-
flags |=
|
|
3055
|
+
flags |= TestMemberFlags.Fail;
|
|
3033
3056
|
break;
|
|
3034
3057
|
case "only":
|
|
3035
|
-
flags |=
|
|
3058
|
+
flags |= TestMemberFlags.Only;
|
|
3036
3059
|
break;
|
|
3037
3060
|
case "skip":
|
|
3038
|
-
flags |=
|
|
3061
|
+
flags |= TestMemberFlags.Skip;
|
|
3039
3062
|
break;
|
|
3040
3063
|
case "todo":
|
|
3041
|
-
flags |=
|
|
3064
|
+
flags |= TestMemberFlags.Todo;
|
|
3042
3065
|
break;
|
|
3043
3066
|
}
|
|
3044
3067
|
expression = expression.expression;
|
|
@@ -3056,12 +3079,12 @@ class IdentifierLookup {
|
|
|
3056
3079
|
}
|
|
3057
3080
|
switch (identifierName) {
|
|
3058
3081
|
case "describe":
|
|
3059
|
-
return { brand:
|
|
3082
|
+
return { brand: TestMemberBrand.Describe, flags };
|
|
3060
3083
|
case "it":
|
|
3061
3084
|
case "test":
|
|
3062
|
-
return { brand:
|
|
3085
|
+
return { brand: TestMemberBrand.Test, flags };
|
|
3063
3086
|
case "expect":
|
|
3064
|
-
return { brand:
|
|
3087
|
+
return { brand: TestMemberBrand.Expect, flags };
|
|
3065
3088
|
}
|
|
3066
3089
|
return;
|
|
3067
3090
|
}
|
|
@@ -3077,7 +3100,7 @@ class TestTree {
|
|
|
3077
3100
|
}
|
|
3078
3101
|
get hasOnly() {
|
|
3079
3102
|
function hasOnly(root) {
|
|
3080
|
-
return root.members.some((branch) => branch.flags &
|
|
3103
|
+
return root.members.some((branch) => branch.flags & TestMemberFlags.Only || ("members" in branch && hasOnly(branch)));
|
|
3081
3104
|
}
|
|
3082
3105
|
return hasOnly(this);
|
|
3083
3106
|
}
|
|
@@ -3091,7 +3114,7 @@ class CollectService {
|
|
|
3091
3114
|
#collectTestMembers(node, identifiers, parent) {
|
|
3092
3115
|
if (this.#compiler.isCallExpression(node)) {
|
|
3093
3116
|
const meta = identifiers.resolveTestMemberMeta(node);
|
|
3094
|
-
if (meta != null && (meta.brand ===
|
|
3117
|
+
if (meta != null && (meta.brand === TestMemberBrand.Describe || meta.brand === TestMemberBrand.Test)) {
|
|
3095
3118
|
const testMember = new TestMember(this.#compiler, meta.brand, node, parent, meta.flags);
|
|
3096
3119
|
parent.members.push(testMember);
|
|
3097
3120
|
this.#compiler.forEachChild(node, (node) => {
|
|
@@ -3099,7 +3122,7 @@ class CollectService {
|
|
|
3099
3122
|
});
|
|
3100
3123
|
return;
|
|
3101
3124
|
}
|
|
3102
|
-
if (meta != null && meta.brand ===
|
|
3125
|
+
if (meta != null && meta.brand === TestMemberBrand.Expect) {
|
|
3103
3126
|
const modifierNode = this.#getChainedNode(node, "type");
|
|
3104
3127
|
if (!modifierNode) {
|
|
3105
3128
|
return;
|
|
@@ -3144,25 +3167,11 @@ class CollectService {
|
|
|
3144
3167
|
}
|
|
3145
3168
|
}
|
|
3146
3169
|
|
|
3147
|
-
var TestMemberBrand;
|
|
3148
|
-
(function (TestMemberBrand) {
|
|
3149
|
-
TestMemberBrand["Describe"] = "describe";
|
|
3150
|
-
TestMemberBrand["Test"] = "test";
|
|
3151
|
-
TestMemberBrand["Expect"] = "expect";
|
|
3152
|
-
})(TestMemberBrand || (TestMemberBrand = {}));
|
|
3153
|
-
|
|
3154
|
-
var TestMemberFlags;
|
|
3155
|
-
(function (TestMemberFlags) {
|
|
3156
|
-
TestMemberFlags[TestMemberFlags["None"] = 0] = "None";
|
|
3157
|
-
TestMemberFlags[TestMemberFlags["Fail"] = 1] = "Fail";
|
|
3158
|
-
TestMemberFlags[TestMemberFlags["Only"] = 2] = "Only";
|
|
3159
|
-
TestMemberFlags[TestMemberFlags["Skip"] = 4] = "Skip";
|
|
3160
|
-
TestMemberFlags[TestMemberFlags["Todo"] = 8] = "Todo";
|
|
3161
|
-
})(TestMemberFlags || (TestMemberFlags = {}));
|
|
3162
|
-
|
|
3163
3170
|
class ProjectService {
|
|
3164
3171
|
#compiler;
|
|
3172
|
+
#lastSeenProject = "";
|
|
3165
3173
|
#resolvedConfig;
|
|
3174
|
+
#seenPrograms = new WeakSet();
|
|
3166
3175
|
#service;
|
|
3167
3176
|
constructor(resolvedConfig, compiler) {
|
|
3168
3177
|
this.#resolvedConfig = resolvedConfig;
|
|
@@ -3237,7 +3246,12 @@ class ProjectService {
|
|
|
3237
3246
|
return defaultCompilerOptions;
|
|
3238
3247
|
}
|
|
3239
3248
|
getDefaultProject(filePath) {
|
|
3240
|
-
|
|
3249
|
+
const project = this.#service.getDefaultProjectForFile(this.#compiler.server.toNormalizedPath(filePath), true);
|
|
3250
|
+
const compilerOptions = project?.getCompilerOptions();
|
|
3251
|
+
if (this.#resolvedConfig.checkSourceFiles && compilerOptions?.skipLibCheck) {
|
|
3252
|
+
project?.setCompilerOptions({ ...compilerOptions, skipLibCheck: false });
|
|
3253
|
+
}
|
|
3254
|
+
return project;
|
|
3241
3255
|
}
|
|
3242
3256
|
getLanguageService(filePath) {
|
|
3243
3257
|
const project = this.getDefaultProject(filePath);
|
|
@@ -3245,19 +3259,56 @@ class ProjectService {
|
|
|
3245
3259
|
}
|
|
3246
3260
|
openFile(filePath, sourceText, projectRootPath) {
|
|
3247
3261
|
const { configFileErrors, configFileName } = this.#service.openClientFile(filePath, sourceText, undefined, projectRootPath);
|
|
3248
|
-
|
|
3249
|
-
|
|
3250
|
-
|
|
3251
|
-
|
|
3262
|
+
if (configFileName !== this.#lastSeenProject) {
|
|
3263
|
+
this.#lastSeenProject = configFileName;
|
|
3264
|
+
EventEmitter.dispatch([
|
|
3265
|
+
"project:uses",
|
|
3266
|
+
{ compilerVersion: this.#compiler.version, projectConfigFilePath: configFileName },
|
|
3267
|
+
]);
|
|
3268
|
+
}
|
|
3252
3269
|
if (configFileErrors && configFileErrors.length > 0) {
|
|
3253
3270
|
EventEmitter.dispatch([
|
|
3254
3271
|
"project:error",
|
|
3255
|
-
{ diagnostics: Diagnostic.fromDiagnostics(configFileErrors
|
|
3272
|
+
{ diagnostics: Diagnostic.fromDiagnostics(configFileErrors) },
|
|
3256
3273
|
]);
|
|
3257
3274
|
}
|
|
3275
|
+
if (this.#resolvedConfig.checkSourceFiles) {
|
|
3276
|
+
const languageService = this.getLanguageService(filePath);
|
|
3277
|
+
const program = languageService?.getProgram();
|
|
3278
|
+
if (!program || this.#seenPrograms.has(program)) {
|
|
3279
|
+
return;
|
|
3280
|
+
}
|
|
3281
|
+
this.#seenPrograms.add(program);
|
|
3282
|
+
const filesToCheck = [];
|
|
3283
|
+
for (const sourceFile of program.getSourceFiles()) {
|
|
3284
|
+
if (program.isSourceFileFromExternalLibrary(sourceFile) || program.isSourceFileDefaultLibrary(sourceFile)) {
|
|
3285
|
+
continue;
|
|
3286
|
+
}
|
|
3287
|
+
if (!Select.isTestFile(sourceFile.fileName, { ...this.#resolvedConfig, pathMatch: [] })) {
|
|
3288
|
+
filesToCheck.push(sourceFile);
|
|
3289
|
+
}
|
|
3290
|
+
}
|
|
3291
|
+
const diagnostics = [];
|
|
3292
|
+
for (const sourceFile of filesToCheck) {
|
|
3293
|
+
diagnostics.push(...program.getSyntacticDiagnostics(sourceFile), ...program.getSemanticDiagnostics(sourceFile));
|
|
3294
|
+
}
|
|
3295
|
+
if (diagnostics.length > 0) {
|
|
3296
|
+
EventEmitter.dispatch(["project:error", { diagnostics: Diagnostic.fromDiagnostics(diagnostics) }]);
|
|
3297
|
+
return;
|
|
3298
|
+
}
|
|
3299
|
+
}
|
|
3258
3300
|
}
|
|
3259
3301
|
}
|
|
3260
3302
|
|
|
3303
|
+
var RunMode;
|
|
3304
|
+
(function (RunMode) {
|
|
3305
|
+
RunMode[RunMode["Normal"] = 0] = "Normal";
|
|
3306
|
+
RunMode[RunMode["Fail"] = 1] = "Fail";
|
|
3307
|
+
RunMode[RunMode["Only"] = 2] = "Only";
|
|
3308
|
+
RunMode[RunMode["Skip"] = 4] = "Skip";
|
|
3309
|
+
RunMode[RunMode["Todo"] = 8] = "Todo";
|
|
3310
|
+
})(RunMode || (RunMode = {}));
|
|
3311
|
+
|
|
3261
3312
|
class Format {
|
|
3262
3313
|
static capitalize(text) {
|
|
3263
3314
|
return text.replace(/^./, text.charAt(0).toUpperCase());
|
|
@@ -3425,7 +3476,13 @@ class MatchWorker {
|
|
|
3425
3476
|
#checkIsRelatedTo(sourceNode, targetNode, relation) {
|
|
3426
3477
|
const sourceType = this.getType(sourceNode);
|
|
3427
3478
|
const targetType = this.getType(targetNode);
|
|
3428
|
-
|
|
3479
|
+
let result = this.#typeChecker.isTypeRelatedTo(sourceType, targetType, relation);
|
|
3480
|
+
if (!result &&
|
|
3481
|
+
relation === this.#typeChecker.relation.identity &&
|
|
3482
|
+
(sourceType.isIntersection() || sourceType.isUnion())) {
|
|
3483
|
+
result = sourceType.types.every((type) => this.#typeChecker.isTypeRelatedTo(type, targetType, relation));
|
|
3484
|
+
}
|
|
3485
|
+
return result;
|
|
3429
3486
|
}
|
|
3430
3487
|
extendsObjectType(type) {
|
|
3431
3488
|
const nonPrimitiveType = { flags: this.#compiler.TypeFlags.NonPrimitive };
|
|
@@ -3830,7 +3887,7 @@ class ToRaiseError {
|
|
|
3830
3887
|
const text = ExpectDiagnosticText.typeRaisedError(isTypeNode, count, targetNodes.length);
|
|
3831
3888
|
const related = [
|
|
3832
3889
|
Diagnostic.error(ExpectDiagnosticText.raisedTypeError(count)),
|
|
3833
|
-
...Diagnostic.fromDiagnostics([...matchWorker.assertion.diagnostics]
|
|
3890
|
+
...Diagnostic.fromDiagnostics([...matchWorker.assertion.diagnostics]),
|
|
3834
3891
|
];
|
|
3835
3892
|
return [Diagnostic.error(text, origin).add({ related })];
|
|
3836
3893
|
}
|
|
@@ -3844,7 +3901,7 @@ class ToRaiseError {
|
|
|
3844
3901
|
const origin = DiagnosticOrigin.fromNode(targetNode, matchWorker.assertion);
|
|
3845
3902
|
const related = [
|
|
3846
3903
|
Diagnostic.error(ExpectDiagnosticText.raisedTypeError()),
|
|
3847
|
-
...Diagnostic.fromDiagnostics([diagnostic]
|
|
3904
|
+
...Diagnostic.fromDiagnostics([diagnostic]),
|
|
3848
3905
|
];
|
|
3849
3906
|
accumulator.push(Diagnostic.error(text, origin).add({ related }));
|
|
3850
3907
|
}
|
|
@@ -4063,23 +4120,23 @@ class TestTreeWalker {
|
|
|
4063
4120
|
this.#expectService = new ExpectService(compiler, typeChecker, this.#resolvedConfig);
|
|
4064
4121
|
}
|
|
4065
4122
|
#resolveRunMode(mode, member) {
|
|
4066
|
-
if (member.flags &
|
|
4067
|
-
mode |=
|
|
4123
|
+
if (member.flags & TestMemberFlags.Fail) {
|
|
4124
|
+
mode |= RunMode.Fail;
|
|
4068
4125
|
}
|
|
4069
|
-
if (member.flags &
|
|
4126
|
+
if (member.flags & TestMemberFlags.Only ||
|
|
4070
4127
|
(this.#resolvedConfig.only != null && member.name.toLowerCase().includes(this.#resolvedConfig.only.toLowerCase()))) {
|
|
4071
|
-
mode |=
|
|
4128
|
+
mode |= RunMode.Only;
|
|
4072
4129
|
}
|
|
4073
|
-
if (member.flags &
|
|
4130
|
+
if (member.flags & TestMemberFlags.Skip ||
|
|
4074
4131
|
(this.#resolvedConfig.skip != null && member.name.toLowerCase().includes(this.#resolvedConfig.skip.toLowerCase()))) {
|
|
4075
|
-
mode |=
|
|
4132
|
+
mode |= RunMode.Skip;
|
|
4076
4133
|
}
|
|
4077
|
-
if (member.flags &
|
|
4078
|
-
mode |=
|
|
4134
|
+
if (member.flags & TestMemberFlags.Todo) {
|
|
4135
|
+
mode |= RunMode.Todo;
|
|
4079
4136
|
}
|
|
4080
4137
|
if (this.#position != null && member.node.getStart() === this.#position) {
|
|
4081
|
-
mode |=
|
|
4082
|
-
mode &= ~
|
|
4138
|
+
mode |= RunMode.Only;
|
|
4139
|
+
mode &= ~RunMode.Skip;
|
|
4083
4140
|
}
|
|
4084
4141
|
return mode;
|
|
4085
4142
|
}
|
|
@@ -4094,13 +4151,13 @@ class TestTreeWalker {
|
|
|
4094
4151
|
break;
|
|
4095
4152
|
}
|
|
4096
4153
|
switch (member.brand) {
|
|
4097
|
-
case
|
|
4154
|
+
case TestMemberBrand.Describe:
|
|
4098
4155
|
this.#visitDescribe(member, runMode, parentResult);
|
|
4099
4156
|
break;
|
|
4100
|
-
case
|
|
4157
|
+
case TestMemberBrand.Test:
|
|
4101
4158
|
this.#visitTest(member, runMode, parentResult);
|
|
4102
4159
|
break;
|
|
4103
|
-
case
|
|
4160
|
+
case TestMemberBrand.Expect:
|
|
4104
4161
|
this.#visitAssertion(member, runMode, parentResult);
|
|
4105
4162
|
break;
|
|
4106
4163
|
}
|
|
@@ -4111,7 +4168,7 @@ class TestTreeWalker {
|
|
|
4111
4168
|
const expectResult = new ExpectResult(assertion, parentResult);
|
|
4112
4169
|
EventEmitter.dispatch(["expect:start", { result: expectResult }]);
|
|
4113
4170
|
runMode = this.#resolveRunMode(runMode, assertion);
|
|
4114
|
-
if (runMode &
|
|
4171
|
+
if (runMode & RunMode.Skip || (this.#hasOnly && !(runMode & RunMode.Only))) {
|
|
4115
4172
|
EventEmitter.dispatch(["expect:skip", { result: expectResult }]);
|
|
4116
4173
|
return;
|
|
4117
4174
|
}
|
|
@@ -4122,7 +4179,7 @@ class TestTreeWalker {
|
|
|
4122
4179
|
]);
|
|
4123
4180
|
};
|
|
4124
4181
|
if (assertion.diagnostics.size > 0 && assertion.matcherName.getText() !== "toRaiseError") {
|
|
4125
|
-
onExpectDiagnostics(Diagnostic.fromDiagnostics([...assertion.diagnostics]
|
|
4182
|
+
onExpectDiagnostics(Diagnostic.fromDiagnostics([...assertion.diagnostics]));
|
|
4126
4183
|
return;
|
|
4127
4184
|
}
|
|
4128
4185
|
const matchResult = this.#expectService.match(assertion, onExpectDiagnostics);
|
|
@@ -4130,7 +4187,7 @@ class TestTreeWalker {
|
|
|
4130
4187
|
return;
|
|
4131
4188
|
}
|
|
4132
4189
|
if (assertion.isNot ? !matchResult.isMatch : matchResult.isMatch) {
|
|
4133
|
-
if (runMode &
|
|
4190
|
+
if (runMode & RunMode.Fail) {
|
|
4134
4191
|
const text = ["The assertion was supposed to fail, but it passed.", "Consider removing the '.fail' flag."];
|
|
4135
4192
|
const origin = DiagnosticOrigin.fromNode(assertion.node.expression.name);
|
|
4136
4193
|
onExpectDiagnostics(Diagnostic.error(text, origin));
|
|
@@ -4139,7 +4196,7 @@ class TestTreeWalker {
|
|
|
4139
4196
|
EventEmitter.dispatch(["expect:pass", { result: expectResult }]);
|
|
4140
4197
|
}
|
|
4141
4198
|
}
|
|
4142
|
-
else if (runMode &
|
|
4199
|
+
else if (runMode & RunMode.Fail) {
|
|
4143
4200
|
EventEmitter.dispatch(["expect:pass", { result: expectResult }]);
|
|
4144
4201
|
}
|
|
4145
4202
|
else {
|
|
@@ -4150,12 +4207,12 @@ class TestTreeWalker {
|
|
|
4150
4207
|
const describeResult = new DescribeResult(describe, parentResult);
|
|
4151
4208
|
EventEmitter.dispatch(["describe:start", { result: describeResult }]);
|
|
4152
4209
|
runMode = this.#resolveRunMode(runMode, describe);
|
|
4153
|
-
if (!(runMode &
|
|
4210
|
+
if (!(runMode & RunMode.Skip || (this.#hasOnly && !(runMode & RunMode.Only)) || runMode & RunMode.Todo) &&
|
|
4154
4211
|
describe.diagnostics.size > 0) {
|
|
4155
4212
|
EventEmitter.dispatch([
|
|
4156
4213
|
"task:error",
|
|
4157
4214
|
{
|
|
4158
|
-
diagnostics: Diagnostic.fromDiagnostics([...describe.diagnostics]
|
|
4215
|
+
diagnostics: Diagnostic.fromDiagnostics([...describe.diagnostics]),
|
|
4159
4216
|
result: this.#taskResult,
|
|
4160
4217
|
},
|
|
4161
4218
|
]);
|
|
@@ -4169,22 +4226,22 @@ class TestTreeWalker {
|
|
|
4169
4226
|
const testResult = new TestResult(test, parentResult);
|
|
4170
4227
|
EventEmitter.dispatch(["test:start", { result: testResult }]);
|
|
4171
4228
|
runMode = this.#resolveRunMode(runMode, test);
|
|
4172
|
-
if (runMode &
|
|
4229
|
+
if (runMode & RunMode.Todo) {
|
|
4173
4230
|
EventEmitter.dispatch(["test:todo", { result: testResult }]);
|
|
4174
4231
|
return;
|
|
4175
4232
|
}
|
|
4176
|
-
if (!(runMode &
|
|
4233
|
+
if (!(runMode & RunMode.Skip || (this.#hasOnly && !(runMode & RunMode.Only))) && test.diagnostics.size > 0) {
|
|
4177
4234
|
EventEmitter.dispatch([
|
|
4178
4235
|
"test:error",
|
|
4179
4236
|
{
|
|
4180
|
-
diagnostics: Diagnostic.fromDiagnostics([...test.diagnostics]
|
|
4237
|
+
diagnostics: Diagnostic.fromDiagnostics([...test.diagnostics]),
|
|
4181
4238
|
result: testResult,
|
|
4182
4239
|
},
|
|
4183
4240
|
]);
|
|
4184
4241
|
return;
|
|
4185
4242
|
}
|
|
4186
4243
|
this.visit(test.members, runMode, testResult);
|
|
4187
|
-
if (runMode &
|
|
4244
|
+
if (runMode & RunMode.Skip || (this.#hasOnly && !(runMode & RunMode.Only))) {
|
|
4188
4245
|
EventEmitter.dispatch(["test:skip", { result: testResult }]);
|
|
4189
4246
|
return;
|
|
4190
4247
|
}
|
|
@@ -4235,7 +4292,7 @@ class TaskRunner {
|
|
|
4235
4292
|
if (syntacticDiagnostics.length > 0) {
|
|
4236
4293
|
EventEmitter.dispatch([
|
|
4237
4294
|
"task:error",
|
|
4238
|
-
{ diagnostics: Diagnostic.fromDiagnostics(syntacticDiagnostics
|
|
4295
|
+
{ diagnostics: Diagnostic.fromDiagnostics(syntacticDiagnostics), result: taskResult },
|
|
4239
4296
|
]);
|
|
4240
4297
|
return;
|
|
4241
4298
|
}
|
|
@@ -4252,7 +4309,7 @@ class TaskRunner {
|
|
|
4252
4309
|
if (testTree.diagnostics.size > 0) {
|
|
4253
4310
|
EventEmitter.dispatch([
|
|
4254
4311
|
"task:error",
|
|
4255
|
-
{ diagnostics: Diagnostic.fromDiagnostics([...testTree.diagnostics]
|
|
4312
|
+
{ diagnostics: Diagnostic.fromDiagnostics([...testTree.diagnostics]), result: taskResult },
|
|
4256
4313
|
]);
|
|
4257
4314
|
return;
|
|
4258
4315
|
}
|
|
@@ -4263,14 +4320,14 @@ class TaskRunner {
|
|
|
4263
4320
|
hasOnly: testTree.hasOnly,
|
|
4264
4321
|
position: task.position,
|
|
4265
4322
|
});
|
|
4266
|
-
testTreeWalker.visit(testTree.members,
|
|
4323
|
+
testTreeWalker.visit(testTree.members, RunMode.Normal, undefined);
|
|
4267
4324
|
}
|
|
4268
4325
|
}
|
|
4269
4326
|
|
|
4270
4327
|
class Runner {
|
|
4271
4328
|
#eventEmitter = new EventEmitter();
|
|
4272
4329
|
#resolvedConfig;
|
|
4273
|
-
static version = "3.
|
|
4330
|
+
static version = "3.3.0";
|
|
4274
4331
|
constructor(resolvedConfig) {
|
|
4275
4332
|
this.#resolvedConfig = resolvedConfig;
|
|
4276
4333
|
}
|
|
@@ -4305,7 +4362,7 @@ class Runner {
|
|
|
4305
4362
|
this.#eventEmitter.addHandler(resultHandler);
|
|
4306
4363
|
await this.#addReporters();
|
|
4307
4364
|
if (this.#resolvedConfig.failFast) {
|
|
4308
|
-
const cancellationHandler = new CancellationHandler(cancellationToken,
|
|
4365
|
+
const cancellationHandler = new CancellationHandler(cancellationToken, CancellationReason.FailFast);
|
|
4309
4366
|
this.#eventEmitter.addHandler(cancellationHandler);
|
|
4310
4367
|
}
|
|
4311
4368
|
await this.#run(tasks, cancellationToken);
|
|
@@ -4331,7 +4388,7 @@ class Runner {
|
|
|
4331
4388
|
EventEmitter.dispatch(["target:end", { result: targetResult }]);
|
|
4332
4389
|
}
|
|
4333
4390
|
EventEmitter.dispatch(["run:end", { result }]);
|
|
4334
|
-
if (cancellationToken.reason ===
|
|
4391
|
+
if (cancellationToken.reason === CancellationReason.FailFast) {
|
|
4335
4392
|
cancellationToken.reset();
|
|
4336
4393
|
}
|
|
4337
4394
|
}
|
|
@@ -4346,14 +4403,14 @@ class Runner {
|
|
|
4346
4403
|
class Cli {
|
|
4347
4404
|
#eventEmitter = new EventEmitter();
|
|
4348
4405
|
async run(commandLine, cancellationToken = new CancellationToken()) {
|
|
4349
|
-
const cancellationHandler = new CancellationHandler(cancellationToken,
|
|
4406
|
+
const cancellationHandler = new CancellationHandler(cancellationToken, CancellationReason.ConfigError);
|
|
4350
4407
|
this.#eventEmitter.addHandler(cancellationHandler);
|
|
4351
4408
|
const exitCodeHandler = new ExitCodeHandler();
|
|
4352
4409
|
this.#eventEmitter.addHandler(exitCodeHandler);
|
|
4353
4410
|
const setupReporter = new SetupReporter();
|
|
4354
4411
|
this.#eventEmitter.addReporter(setupReporter);
|
|
4355
4412
|
if (commandLine.includes("--help")) {
|
|
4356
|
-
const options = Options.for(
|
|
4413
|
+
const options = Options.for(OptionGroup.CommandLine);
|
|
4357
4414
|
OutputService.writeMessage(helpText(options, Runner.version));
|
|
4358
4415
|
return;
|
|
4359
4416
|
}
|
|
@@ -4381,7 +4438,7 @@ class Cli {
|
|
|
4381
4438
|
return;
|
|
4382
4439
|
}
|
|
4383
4440
|
do {
|
|
4384
|
-
if (cancellationToken.reason ===
|
|
4441
|
+
if (cancellationToken.reason === CancellationReason.ConfigChange) {
|
|
4385
4442
|
cancellationToken.reset();
|
|
4386
4443
|
exitCodeHandler.resetCode();
|
|
4387
4444
|
OutputService.clearTerminal();
|
|
@@ -4436,7 +4493,7 @@ class Cli {
|
|
|
4436
4493
|
const runner = new Runner(resolvedConfig);
|
|
4437
4494
|
await runner.run(testFiles, cancellationToken);
|
|
4438
4495
|
PluginService.removeHandlers();
|
|
4439
|
-
} while (cancellationToken.reason ===
|
|
4496
|
+
} while (cancellationToken.reason === CancellationReason.ConfigChange);
|
|
4440
4497
|
this.#eventEmitter.removeHandlers();
|
|
4441
4498
|
}
|
|
4442
4499
|
#waitForChangedFiles(resolvedConfig, cancellationToken) {
|
|
@@ -4445,7 +4502,7 @@ class Cli {
|
|
|
4445
4502
|
cancellationToken.reset();
|
|
4446
4503
|
OutputService.writeMessage(waitingForFileChangesText());
|
|
4447
4504
|
const onChanged = () => {
|
|
4448
|
-
cancellationToken.cancel(
|
|
4505
|
+
cancellationToken.cancel(CancellationReason.ConfigChange);
|
|
4449
4506
|
for (const watcher of watchers) {
|
|
4450
4507
|
watcher.close();
|
|
4451
4508
|
}
|