tstyche 6.0.3 → 6.2.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/dist/tag.d.ts +8 -0
- package/dist/tag.js +36 -0
- package/dist/tstyche.d.ts +38 -9
- package/dist/tstyche.js +172 -46
- package/package.json +2 -1
package/dist/tag.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runs TSTyche in the same process, streaming error messages and test results to the `stderr` and `stdout` in real-time.
|
|
3
|
+
*
|
|
4
|
+
* @returns A promise that resolves if the test run is successful and rejects if it fails.
|
|
5
|
+
*/
|
|
6
|
+
declare function tstyche(template: TemplateStringsArray, ...substitutions: Array<string>): Promise<void>;
|
|
7
|
+
|
|
8
|
+
export { tstyche as default };
|
package/dist/tag.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Cli, EventEmitter, CancellationToken } from './tstyche.js';
|
|
2
|
+
|
|
3
|
+
class StatusHandler {
|
|
4
|
+
#hasError = false;
|
|
5
|
+
hasError() {
|
|
6
|
+
return this.#hasError;
|
|
7
|
+
}
|
|
8
|
+
on([event, payload]) {
|
|
9
|
+
if (event === "run:start") {
|
|
10
|
+
this.#hasError = false;
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
if ("diagnostics" in payload) {
|
|
14
|
+
if (payload.diagnostics.some((diagnostic) => diagnostic.category === "error")) {
|
|
15
|
+
this.#hasError = true;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
async function tstyche(template, ...substitutions) {
|
|
21
|
+
const cli = new Cli({ noErrorExitCode: true });
|
|
22
|
+
const commandLine = String.raw(template, ...substitutions).split(/\s+/);
|
|
23
|
+
const eventEmitter = new EventEmitter();
|
|
24
|
+
const statusHandler = new StatusHandler();
|
|
25
|
+
eventEmitter.addHandler(statusHandler);
|
|
26
|
+
await cli.run(commandLine, new CancellationToken());
|
|
27
|
+
eventEmitter.removeHandler(statusHandler);
|
|
28
|
+
return new Promise((resolve, reject) => {
|
|
29
|
+
if (statusHandler.hasError()) {
|
|
30
|
+
reject(new Error("TSTyche test run failed. Check the output above for details."));
|
|
31
|
+
}
|
|
32
|
+
resolve();
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export { tstyche as default };
|
package/dist/tstyche.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type ts from 'typescript';
|
|
2
|
+
import type { WriteStream } from 'node:tty';
|
|
2
3
|
|
|
3
4
|
declare enum CancellationReason {
|
|
4
5
|
ConfigChange = "configChange",
|
|
@@ -15,9 +16,13 @@ declare class CancellationToken {
|
|
|
15
16
|
reset(): void;
|
|
16
17
|
}
|
|
17
18
|
|
|
19
|
+
interface CliOptions {
|
|
20
|
+
noErrorExitCode?: boolean;
|
|
21
|
+
}
|
|
18
22
|
declare class Cli {
|
|
19
23
|
#private;
|
|
20
|
-
|
|
24
|
+
constructor(options?: CliOptions);
|
|
25
|
+
run(commandLine: ReadonlyArray<string>, cancellationToken?: CancellationToken): Promise<void>;
|
|
21
26
|
}
|
|
22
27
|
|
|
23
28
|
declare enum DiagnosticCategory {
|
|
@@ -143,12 +148,15 @@ interface CommandLineOptions {
|
|
|
143
148
|
listFiles?: boolean;
|
|
144
149
|
only?: string;
|
|
145
150
|
prune?: boolean;
|
|
151
|
+
quiet?: boolean;
|
|
146
152
|
reporters?: Array<string>;
|
|
153
|
+
root?: string;
|
|
147
154
|
showConfig?: boolean;
|
|
148
155
|
skip?: string;
|
|
149
156
|
target?: Array<string>;
|
|
150
157
|
tsconfig?: string;
|
|
151
158
|
update?: boolean;
|
|
159
|
+
verbose?: boolean;
|
|
152
160
|
version?: boolean;
|
|
153
161
|
watch?: boolean;
|
|
154
162
|
}
|
|
@@ -157,6 +165,7 @@ interface ConfigFileOptions {
|
|
|
157
165
|
checkSuppressedErrors?: boolean;
|
|
158
166
|
failFast?: boolean;
|
|
159
167
|
fixtureFileMatch?: Array<string>;
|
|
168
|
+
quiet?: boolean;
|
|
160
169
|
rejectAnyType?: boolean;
|
|
161
170
|
rejectNeverType?: boolean;
|
|
162
171
|
reporters?: Array<string>;
|
|
@@ -164,6 +173,7 @@ interface ConfigFileOptions {
|
|
|
164
173
|
target?: Array<string>;
|
|
165
174
|
testFileMatch?: Array<string>;
|
|
166
175
|
tsconfig?: string;
|
|
176
|
+
verbose?: boolean;
|
|
167
177
|
}
|
|
168
178
|
|
|
169
179
|
interface InlineConfig {
|
|
@@ -191,11 +201,11 @@ interface DirectiveRange {
|
|
|
191
201
|
|
|
192
202
|
declare class Config {
|
|
193
203
|
#private;
|
|
194
|
-
static parseCommandLine(commandLine:
|
|
204
|
+
static parseCommandLine(commandLine: ReadonlyArray<string>): Promise<{
|
|
195
205
|
commandLineOptions: CommandLineOptions;
|
|
196
206
|
pathMatch: Array<string>;
|
|
197
207
|
}>;
|
|
198
|
-
static parseConfigFile(
|
|
208
|
+
static parseConfigFile(configPath?: string, rootPath?: string): Promise<{
|
|
199
209
|
configFileOptions: ConfigFileOptions;
|
|
200
210
|
configFilePath: string;
|
|
201
211
|
}>;
|
|
@@ -205,7 +215,7 @@ declare class Config {
|
|
|
205
215
|
commandLineOptions?: Omit<CommandLineOptions, "config">;
|
|
206
216
|
pathMatch?: Array<string>;
|
|
207
217
|
}): ResolvedConfig;
|
|
208
|
-
static resolveConfigFilePath(
|
|
218
|
+
static resolveConfigFilePath(configPath?: string, rootPath?: string): string;
|
|
209
219
|
}
|
|
210
220
|
|
|
211
221
|
declare enum OptionBrand {
|
|
@@ -300,6 +310,11 @@ declare abstract class BaseReporter implements Reporter {
|
|
|
300
310
|
abstract on([event, payload]: ReporterEvent): void;
|
|
301
311
|
}
|
|
302
312
|
|
|
313
|
+
declare class DotReporter extends BaseReporter {
|
|
314
|
+
#private;
|
|
315
|
+
on([event, payload]: ReporterEvent): void;
|
|
316
|
+
}
|
|
317
|
+
|
|
303
318
|
declare class ListReporter extends BaseReporter {
|
|
304
319
|
#private;
|
|
305
320
|
on([event, payload]: ReporterEvent): void;
|
|
@@ -584,7 +599,9 @@ interface TextProps {
|
|
|
584
599
|
}
|
|
585
600
|
declare function Text({ children, color, indent }: TextProps): ScribblerJsx.Element;
|
|
586
601
|
|
|
587
|
-
declare function addsPackageText(packageVersion: string, packagePath: string
|
|
602
|
+
declare function addsPackageText(packageVersion: string, packagePath: string, options?: {
|
|
603
|
+
short?: boolean;
|
|
604
|
+
}): ScribblerJsx.Element;
|
|
588
605
|
|
|
589
606
|
declare function describeNameText(name: string, indent?: number): ScribblerJsx.Element;
|
|
590
607
|
|
|
@@ -596,18 +613,29 @@ interface CodeFrameOptions {
|
|
|
596
613
|
|
|
597
614
|
declare function diagnosticText(diagnostic: Diagnostic, codeFrameOptions?: CodeFrameOptions): ScribblerJsx.Element;
|
|
598
615
|
|
|
599
|
-
declare function
|
|
616
|
+
declare function dotText(status: ResultStatus): ScribblerJsx.Element;
|
|
600
617
|
|
|
601
|
-
declare function
|
|
618
|
+
declare function fileStatusText(status: FileResultStatus, file: FileLocation): ScribblerJsx.Element;
|
|
602
619
|
|
|
603
620
|
declare function formattedText(input: string | Array<string> | Record<string, unknown>): ScribblerJsx.Element;
|
|
604
621
|
|
|
605
622
|
declare function helpText(options: Map<string, OptionDefinition>, version: string): ScribblerJsx.Element;
|
|
606
623
|
|
|
624
|
+
declare class StreamController {
|
|
625
|
+
#private;
|
|
626
|
+
constructor(stream: WriteStream);
|
|
627
|
+
disable(): void;
|
|
628
|
+
enable(): void;
|
|
629
|
+
write(text: string): void;
|
|
630
|
+
}
|
|
631
|
+
|
|
607
632
|
declare class OutputService {
|
|
608
633
|
#private;
|
|
634
|
+
static errorStream: StreamController;
|
|
635
|
+
static outputStream: StreamController;
|
|
609
636
|
static clearTerminal(): void;
|
|
610
637
|
static eraseLastLine(): void;
|
|
638
|
+
static writeBlankLine(count?: number): void;
|
|
611
639
|
static writeError(element: ScribblerJsx.Element | Array<ScribblerJsx.Element>): void;
|
|
612
640
|
static writeMessage(element: ScribblerJsx.Element | Array<ScribblerJsx.Element>): void;
|
|
613
641
|
static writeWarning(element: ScribblerJsx.Element | Array<ScribblerJsx.Element>): void;
|
|
@@ -628,7 +656,8 @@ declare function summaryText({ targetCounts, fileCounts, testCounts, assertionCo
|
|
|
628
656
|
declare function testNameText(status: Exclude<TestResultStatus, ResultStatus.Runs>, name: string, indent?: number): ScribblerJsx.Element;
|
|
629
657
|
|
|
630
658
|
declare function usesCompilerText(compilerVersion: string, projectConfigFilePath: string | undefined, options?: {
|
|
631
|
-
prependEmptyLine
|
|
659
|
+
prependEmptyLine?: boolean;
|
|
660
|
+
short?: boolean;
|
|
632
661
|
}): ScribblerJsx.Element;
|
|
633
662
|
|
|
634
663
|
declare function waitingForFileChangesText(): ScribblerJsx.Element;
|
|
@@ -714,5 +743,5 @@ declare class Version {
|
|
|
714
743
|
static isSatisfiedWith(source: string, target: string): boolean;
|
|
715
744
|
}
|
|
716
745
|
|
|
717
|
-
export { BaseReporter, CancellationReason, CancellationToken, Cli, Color, Config, ConfigDiagnosticText, DescribeResult, Diagnostic, DiagnosticCategory, DiagnosticOrigin, Directive, EventEmitter, ExpectResult, FileLocation, FileResult, Line, ListReporter, OptionBrand, OptionGroup, Options, OutputService, Path, ProjectResult, Result, ResultStatus, Runner, Scribbler, ScribblerJsx, Select, SelectDiagnosticText, SetupReporter, Store, SummaryReporter, SuppressedResult, TargetResult, TestResult, Text, Version, WatchReporter, addsPackageText, defaultOptions, describeNameText, diagnosticBelongsToNode, diagnosticText, environmentOptions, fileStatusText,
|
|
746
|
+
export { BaseReporter, CancellationReason, CancellationToken, Cli, Color, Config, ConfigDiagnosticText, DescribeResult, Diagnostic, DiagnosticCategory, DiagnosticOrigin, Directive, DotReporter, EventEmitter, ExpectResult, FileLocation, FileResult, Line, ListReporter, OptionBrand, OptionGroup, Options, OutputService, Path, ProjectResult, Result, ResultStatus, Runner, Scribbler, ScribblerJsx, Select, SelectDiagnosticText, SetupReporter, Store, StreamController, SummaryReporter, SuppressedResult, TargetResult, TestResult, Text, Version, WatchReporter, addsPackageText, defaultOptions, describeNameText, diagnosticBelongsToNode, diagnosticText, dotText, environmentOptions, fileStatusText, formattedText, getDiagnosticMessageText, getTextSpanEnd, helpText, isDiagnosticWithLocation, prologueText, summaryText, testNameText, usesCompilerText, waitingForFileChangesText, watchUsageText };
|
|
718
747
|
export type { AssertionCounts, AssertionResultStatus, CodeFrameOptions, CommandLineOptions, ConfigFileOptions, DiagnosticsHandler, DirectiveRange, EnvironmentOptions, Event, EventHandler, FileCounts, FileResultStatus, InlineConfig, ItemDefinition, OptionDefinition, Reporter, ReporterEvent, ResolvedConfig, ResultCounts, ResultTiming, ScribblerOptions, SuppressedCounts, SuppressedResultStatus, TargetCounts, TargetResultStatus, TestCounts, TestResultStatus, TextRange };
|
package/dist/tstyche.js
CHANGED
|
@@ -375,7 +375,7 @@ class ConfigDiagnosticText {
|
|
|
375
375
|
static fileMatchPatternCannotStartWith(optionName, segment) {
|
|
376
376
|
return [
|
|
377
377
|
`A '${optionName}' pattern cannot start with '${segment}'.`,
|
|
378
|
-
"The files are only collected within the
|
|
378
|
+
"The files are only collected within the root directory.",
|
|
379
379
|
];
|
|
380
380
|
}
|
|
381
381
|
static inspectSupportedVersions() {
|
|
@@ -1099,6 +1099,12 @@ class Options {
|
|
|
1099
1099
|
group: 2,
|
|
1100
1100
|
name: "prune",
|
|
1101
1101
|
},
|
|
1102
|
+
{
|
|
1103
|
+
brand: "boolean",
|
|
1104
|
+
description: "Silence all test runner output except errors and warnings.",
|
|
1105
|
+
group: 2 | 4,
|
|
1106
|
+
name: "quiet",
|
|
1107
|
+
},
|
|
1102
1108
|
{
|
|
1103
1109
|
brand: "boolean",
|
|
1104
1110
|
description: "Reject the 'any' type passed as an argument to the 'expect()' function or a matcher.",
|
|
@@ -1121,6 +1127,12 @@ class Options {
|
|
|
1121
1127
|
},
|
|
1122
1128
|
name: "reporters",
|
|
1123
1129
|
},
|
|
1130
|
+
{
|
|
1131
|
+
brand: "string",
|
|
1132
|
+
description: "The path to a directory containing files of a test project.",
|
|
1133
|
+
group: 2,
|
|
1134
|
+
name: "root",
|
|
1135
|
+
},
|
|
1124
1136
|
{
|
|
1125
1137
|
brand: "string",
|
|
1126
1138
|
description: "The path to a directory containing files of a test project.",
|
|
@@ -1167,6 +1179,12 @@ class Options {
|
|
|
1167
1179
|
group: 2,
|
|
1168
1180
|
name: "update",
|
|
1169
1181
|
},
|
|
1182
|
+
{
|
|
1183
|
+
brand: "boolean",
|
|
1184
|
+
description: "Enable detailed logging.",
|
|
1185
|
+
group: 2 | 4,
|
|
1186
|
+
name: "verbose",
|
|
1187
|
+
},
|
|
1170
1188
|
{
|
|
1171
1189
|
brand: "true",
|
|
1172
1190
|
description: "Print the version number and exit.",
|
|
@@ -1193,7 +1211,7 @@ class Options {
|
|
|
1193
1211
|
return optionName.startsWith("--") ? optionName.slice(2) : optionName;
|
|
1194
1212
|
}
|
|
1195
1213
|
static #isBuiltinReporter(optionValue) {
|
|
1196
|
-
return ["list", "summary"].includes(optionValue);
|
|
1214
|
+
return ["dot", "list", "summary"].includes(optionValue);
|
|
1197
1215
|
}
|
|
1198
1216
|
static #isLookupStrategy(optionValue) {
|
|
1199
1217
|
return ["findup", "ignore"].includes(optionValue);
|
|
@@ -1202,11 +1220,15 @@ class Options {
|
|
|
1202
1220
|
const canonicalOptionName = Options.#getCanonicalOptionName(optionName);
|
|
1203
1221
|
switch (canonicalOptionName) {
|
|
1204
1222
|
case "config":
|
|
1223
|
+
case "root":
|
|
1205
1224
|
case "rootPath":
|
|
1206
1225
|
case "tsconfig":
|
|
1207
1226
|
if (canonicalOptionName === "tsconfig" && Options.#isLookupStrategy(optionValue)) {
|
|
1208
1227
|
break;
|
|
1209
1228
|
}
|
|
1229
|
+
if (optionValue.startsWith("file:")) {
|
|
1230
|
+
optionValue = fileURLToPath(optionValue);
|
|
1231
|
+
}
|
|
1210
1232
|
optionValue = Path.resolve(rootPath, optionValue);
|
|
1211
1233
|
break;
|
|
1212
1234
|
case "reporters":
|
|
@@ -1231,6 +1253,7 @@ class Options {
|
|
|
1231
1253
|
const canonicalOptionName = Options.#getCanonicalOptionName(optionName);
|
|
1232
1254
|
switch (canonicalOptionName) {
|
|
1233
1255
|
case "config":
|
|
1256
|
+
case "root":
|
|
1234
1257
|
case "rootPath":
|
|
1235
1258
|
case "tsconfig":
|
|
1236
1259
|
if (canonicalOptionName === "tsconfig" && Options.#isLookupStrategy(optionValue)) {
|
|
@@ -1553,6 +1576,7 @@ const defaultOptions = {
|
|
|
1553
1576
|
checkSuppressedErrors: true,
|
|
1554
1577
|
failFast: false,
|
|
1555
1578
|
fixtureFileMatch: ["**/__fixtures__/*.{ts,tsx}", "**/fixtures/*.{ts,tsx}"],
|
|
1579
|
+
quiet: false,
|
|
1556
1580
|
rejectAnyType: true,
|
|
1557
1581
|
rejectNeverType: true,
|
|
1558
1582
|
reporters: ["list", "summary"],
|
|
@@ -1560,6 +1584,7 @@ const defaultOptions = {
|
|
|
1560
1584
|
target: ["*"],
|
|
1561
1585
|
testFileMatch: ["**/*.tst.*", "**/__typetests__/*.test.*", "**/typetests/*.test.*"],
|
|
1562
1586
|
tsconfig: "findup",
|
|
1587
|
+
verbose: false,
|
|
1563
1588
|
};
|
|
1564
1589
|
|
|
1565
1590
|
class Config {
|
|
@@ -1573,10 +1598,10 @@ class Config {
|
|
|
1573
1598
|
await commandLineParser.parse(commandLine);
|
|
1574
1599
|
return { commandLineOptions, pathMatch };
|
|
1575
1600
|
}
|
|
1576
|
-
static async parseConfigFile(
|
|
1577
|
-
const configFilePath = Config.resolveConfigFilePath(
|
|
1601
|
+
static async parseConfigFile(configPath, rootPath) {
|
|
1602
|
+
const configFilePath = Config.resolveConfigFilePath(configPath, rootPath);
|
|
1578
1603
|
const configFileOptions = {
|
|
1579
|
-
rootPath: Path.dirname(configFilePath),
|
|
1604
|
+
rootPath: rootPath ?? Path.dirname(configFilePath),
|
|
1580
1605
|
};
|
|
1581
1606
|
if (existsSync(configFilePath)) {
|
|
1582
1607
|
const configFileText = await fs.readFile(configFilePath, {
|
|
@@ -1599,10 +1624,16 @@ class Config {
|
|
|
1599
1624
|
if ("config" in resolvedConfig) {
|
|
1600
1625
|
delete resolvedConfig.config;
|
|
1601
1626
|
}
|
|
1627
|
+
if ("root" in resolvedConfig) {
|
|
1628
|
+
delete resolvedConfig.root;
|
|
1629
|
+
}
|
|
1602
1630
|
return resolvedConfig;
|
|
1603
1631
|
}
|
|
1604
|
-
static resolveConfigFilePath(
|
|
1605
|
-
|
|
1632
|
+
static resolveConfigFilePath(configPath, rootPath = ".") {
|
|
1633
|
+
if (configPath != null) {
|
|
1634
|
+
return Path.resolve(configPath);
|
|
1635
|
+
}
|
|
1636
|
+
return Path.resolve(rootPath, "./tstyche.config.json");
|
|
1606
1637
|
}
|
|
1607
1638
|
}
|
|
1608
1639
|
|
|
@@ -2198,7 +2229,10 @@ class Scribbler {
|
|
|
2198
2229
|
}
|
|
2199
2230
|
}
|
|
2200
2231
|
|
|
2201
|
-
function addsPackageText(packageVersion, packagePath) {
|
|
2232
|
+
function addsPackageText(packageVersion, packagePath, options) {
|
|
2233
|
+
if (options?.short) {
|
|
2234
|
+
return (jsx(Line, { children: jsx(Text, { color: "90", children: packageVersion }) }));
|
|
2235
|
+
}
|
|
2202
2236
|
return (jsx(Line, { children: [jsx(Text, { color: "90", children: "adds" }), " TypeScript ", packageVersion, jsx(Text, { color: "90", children: [" to ", packagePath] })] }));
|
|
2203
2237
|
}
|
|
2204
2238
|
|
|
@@ -2295,6 +2329,16 @@ function diagnosticText(diagnostic, codeFrameOptions = {}) {
|
|
|
2295
2329
|
return (jsx(Text, { children: [prefix, jsx(DiagnosticText, { codeFrameOptions: codeFrameOptions, diagnostic: diagnostic })] }));
|
|
2296
2330
|
}
|
|
2297
2331
|
|
|
2332
|
+
function dotText(status) {
|
|
2333
|
+
let statusColor;
|
|
2334
|
+
let statusText = "·";
|
|
2335
|
+
if (status === "failed") {
|
|
2336
|
+
statusColor = "31";
|
|
2337
|
+
statusText = "×";
|
|
2338
|
+
}
|
|
2339
|
+
return jsx(Text, { color: statusColor, children: statusText });
|
|
2340
|
+
}
|
|
2341
|
+
|
|
2298
2342
|
function getStatusColor(status) {
|
|
2299
2343
|
switch (status) {
|
|
2300
2344
|
case "runs":
|
|
@@ -2342,10 +2386,6 @@ function fileStatusText(status, file) {
|
|
|
2342
2386
|
return (jsx(Line, { children: [jsx(Text, { color: getStatusColor(status), children: statusText }), " ", jsx(FileNameText, { filePath: file.path })] }));
|
|
2343
2387
|
}
|
|
2344
2388
|
|
|
2345
|
-
function fileViewText(lines, addEmptyFinalLine) {
|
|
2346
|
-
return (jsx(Text, { children: [[...lines], addEmptyFinalLine ? jsx(Line, {}) : undefined] }));
|
|
2347
|
-
}
|
|
2348
|
-
|
|
2349
2389
|
function formattedText(input) {
|
|
2350
2390
|
if (typeof input === "string") {
|
|
2351
2391
|
return jsx(Line, { children: input });
|
|
@@ -2415,35 +2455,56 @@ function helpText(options, version) {
|
|
|
2415
2455
|
return (jsx(Text, { children: [jsx(HelpHeaderText, { tstycheVersion: version }), jsx(Line, {}), jsx(CommandLineUsageText, {}), jsx(Line, {}), jsx(CommandLineOptionsText, { optionDefinitions: options }), jsx(Line, {}), jsx(HelpFooterText, {}), jsx(Line, {})] }));
|
|
2416
2456
|
}
|
|
2417
2457
|
|
|
2458
|
+
class StreamController {
|
|
2459
|
+
#isEnabled = true;
|
|
2460
|
+
#stream;
|
|
2461
|
+
constructor(stream) {
|
|
2462
|
+
this.#stream = stream;
|
|
2463
|
+
}
|
|
2464
|
+
disable() {
|
|
2465
|
+
this.#isEnabled = false;
|
|
2466
|
+
}
|
|
2467
|
+
enable() {
|
|
2468
|
+
this.#isEnabled = true;
|
|
2469
|
+
}
|
|
2470
|
+
write(text) {
|
|
2471
|
+
this.#isEnabled && this.#stream.write(text);
|
|
2472
|
+
}
|
|
2473
|
+
}
|
|
2474
|
+
|
|
2418
2475
|
class OutputService {
|
|
2476
|
+
static errorStream = new StreamController(process.stderr);
|
|
2477
|
+
static outputStream = new StreamController(process.stdout);
|
|
2419
2478
|
static #isClear = false;
|
|
2420
|
-
static #
|
|
2421
|
-
static #
|
|
2422
|
-
static #stdout = process.stdout;
|
|
2479
|
+
static #newLine = "\n";
|
|
2480
|
+
static #scribbler = new Scribbler({ newLine: OutputService.#newLine });
|
|
2423
2481
|
static clearTerminal() {
|
|
2424
2482
|
if (!OutputService.#isClear) {
|
|
2425
|
-
OutputService
|
|
2483
|
+
OutputService.outputStream.write("\u001B[2J\u001B[3J\u001B[H");
|
|
2426
2484
|
OutputService.#isClear = true;
|
|
2427
2485
|
}
|
|
2428
2486
|
}
|
|
2429
2487
|
static eraseLastLine() {
|
|
2430
|
-
OutputService
|
|
2488
|
+
OutputService.outputStream.write("\u001B[1A\u001B[0K");
|
|
2431
2489
|
}
|
|
2432
|
-
static #
|
|
2490
|
+
static #write(stream, element) {
|
|
2433
2491
|
const elements = Array.isArray(element) ? element : [element];
|
|
2434
2492
|
for (const element of elements) {
|
|
2435
2493
|
stream.write(OutputService.#scribbler.render(element));
|
|
2436
2494
|
}
|
|
2437
2495
|
OutputService.#isClear = false;
|
|
2438
2496
|
}
|
|
2497
|
+
static writeBlankLine(count = 1) {
|
|
2498
|
+
OutputService.outputStream.write(OutputService.#newLine.repeat(count));
|
|
2499
|
+
}
|
|
2439
2500
|
static writeError(element) {
|
|
2440
|
-
OutputService.#
|
|
2501
|
+
OutputService.#write(OutputService.errorStream, element);
|
|
2441
2502
|
}
|
|
2442
2503
|
static writeMessage(element) {
|
|
2443
|
-
OutputService.#
|
|
2504
|
+
OutputService.#write(OutputService.outputStream, element);
|
|
2444
2505
|
}
|
|
2445
2506
|
static writeWarning(element) {
|
|
2446
|
-
OutputService.#
|
|
2507
|
+
OutputService.#write(OutputService.errorStream, element);
|
|
2447
2508
|
}
|
|
2448
2509
|
}
|
|
2449
2510
|
|
|
@@ -2503,6 +2564,9 @@ function testNameText(status, name, indent = 0) {
|
|
|
2503
2564
|
}
|
|
2504
2565
|
|
|
2505
2566
|
function usesCompilerText(compilerVersion, projectConfigFilePath, options) {
|
|
2567
|
+
if (options?.short) {
|
|
2568
|
+
return jsx(Text, { color: "34", children: compilerVersion });
|
|
2569
|
+
}
|
|
2506
2570
|
let projectConfigPathText;
|
|
2507
2571
|
if (projectConfigFilePath != null) {
|
|
2508
2572
|
projectConfigPathText = (jsx(Text, { color: "90", children: [" with ", Path.relative("", projectConfigFilePath)] }));
|
|
@@ -2532,6 +2596,55 @@ class BaseReporter {
|
|
|
2532
2596
|
}
|
|
2533
2597
|
}
|
|
2534
2598
|
|
|
2599
|
+
class DotReporter extends BaseReporter {
|
|
2600
|
+
#diagnostics = [];
|
|
2601
|
+
#hasReportedAdds = false;
|
|
2602
|
+
on([event, payload]) {
|
|
2603
|
+
switch (event) {
|
|
2604
|
+
case "store:adds":
|
|
2605
|
+
OutputService.writeMessage(addsPackageText(payload.packageVersion, payload.packagePath, { short: true }));
|
|
2606
|
+
this.#hasReportedAdds = true;
|
|
2607
|
+
break;
|
|
2608
|
+
case "store:error":
|
|
2609
|
+
for (const diagnostic of payload.diagnostics) {
|
|
2610
|
+
OutputService.writeError(diagnosticText(diagnostic));
|
|
2611
|
+
}
|
|
2612
|
+
break;
|
|
2613
|
+
case "project:uses":
|
|
2614
|
+
if (this.#hasReportedAdds) {
|
|
2615
|
+
if (!environmentOptions.noInteractive) {
|
|
2616
|
+
OutputService.eraseLastLine();
|
|
2617
|
+
}
|
|
2618
|
+
this.#hasReportedAdds = false;
|
|
2619
|
+
}
|
|
2620
|
+
if (this.resolvedConfig.target.length > 1) {
|
|
2621
|
+
OutputService.writeMessage(usesCompilerText(payload.compilerVersion, payload.projectConfigFilePath, { short: true }));
|
|
2622
|
+
}
|
|
2623
|
+
break;
|
|
2624
|
+
case "target:end":
|
|
2625
|
+
OutputService.writeBlankLine(2);
|
|
2626
|
+
for (const diagnostic of this.#diagnostics) {
|
|
2627
|
+
OutputService.writeError(diagnosticText(diagnostic));
|
|
2628
|
+
}
|
|
2629
|
+
this.#diagnostics = [];
|
|
2630
|
+
break;
|
|
2631
|
+
case "file:end":
|
|
2632
|
+
OutputService.writeMessage(dotText(payload.result.status));
|
|
2633
|
+
break;
|
|
2634
|
+
case "project:error":
|
|
2635
|
+
case "file:error":
|
|
2636
|
+
case "directive:error":
|
|
2637
|
+
case "collect:error":
|
|
2638
|
+
case "test:error":
|
|
2639
|
+
case "suppressed:error":
|
|
2640
|
+
case "expect:error":
|
|
2641
|
+
case "expect:fail":
|
|
2642
|
+
this.#diagnostics.push(...payload.diagnostics);
|
|
2643
|
+
break;
|
|
2644
|
+
}
|
|
2645
|
+
}
|
|
2646
|
+
}
|
|
2647
|
+
|
|
2535
2648
|
class FileView {
|
|
2536
2649
|
#indent = 0;
|
|
2537
2650
|
#lines = [];
|
|
@@ -2557,8 +2670,8 @@ class FileView {
|
|
|
2557
2670
|
getMessages() {
|
|
2558
2671
|
return this.#messages;
|
|
2559
2672
|
}
|
|
2560
|
-
|
|
2561
|
-
return
|
|
2673
|
+
getView() {
|
|
2674
|
+
return this.#lines;
|
|
2562
2675
|
}
|
|
2563
2676
|
hasErrors() {
|
|
2564
2677
|
return this.#messages.length > 0;
|
|
@@ -2571,14 +2684,12 @@ class ListReporter extends BaseReporter {
|
|
|
2571
2684
|
#hasReportedAdds = false;
|
|
2572
2685
|
#hasReportedError = false;
|
|
2573
2686
|
#hasReportedUses = false;
|
|
2574
|
-
#
|
|
2575
|
-
#isLastFile() {
|
|
2576
|
-
return this.#fileCount === 0;
|
|
2577
|
-
}
|
|
2687
|
+
#isVerbose = false;
|
|
2578
2688
|
on([event, payload]) {
|
|
2579
2689
|
switch (event) {
|
|
2580
2690
|
case "run:start":
|
|
2581
|
-
this.#
|
|
2691
|
+
this.#isVerbose =
|
|
2692
|
+
this.resolvedConfig.verbose || (payload.result.files.length === 1 && this.resolvedConfig.watch !== true);
|
|
2582
2693
|
break;
|
|
2583
2694
|
case "store:adds":
|
|
2584
2695
|
OutputService.writeMessage(addsPackageText(payload.packageVersion, payload.packagePath));
|
|
@@ -2625,7 +2736,10 @@ class ListReporter extends BaseReporter {
|
|
|
2625
2736
|
OutputService.eraseLastLine();
|
|
2626
2737
|
}
|
|
2627
2738
|
OutputService.writeMessage(fileStatusText(payload.result.status, payload.result.file));
|
|
2628
|
-
OutputService.writeMessage(this.#fileView.
|
|
2739
|
+
OutputService.writeMessage(this.#fileView.getView());
|
|
2740
|
+
if (this.#isVerbose || this.#fileCount === 0 || this.#fileView.hasErrors()) {
|
|
2741
|
+
OutputService.writeBlankLine();
|
|
2742
|
+
}
|
|
2629
2743
|
if (this.#fileView.hasErrors()) {
|
|
2630
2744
|
OutputService.writeError(this.#fileView.getMessages());
|
|
2631
2745
|
this.#hasReportedError = true;
|
|
@@ -2633,32 +2747,32 @@ class ListReporter extends BaseReporter {
|
|
|
2633
2747
|
this.#fileView.clear();
|
|
2634
2748
|
break;
|
|
2635
2749
|
case "describe:start":
|
|
2636
|
-
if (this.#
|
|
2750
|
+
if (this.#isVerbose) {
|
|
2637
2751
|
this.#fileView.beginDescribe(payload.result.describe.name);
|
|
2638
2752
|
}
|
|
2639
2753
|
break;
|
|
2640
2754
|
case "describe:end":
|
|
2641
|
-
if (this.#
|
|
2755
|
+
if (this.#isVerbose) {
|
|
2642
2756
|
this.#fileView.endDescribe();
|
|
2643
2757
|
}
|
|
2644
2758
|
break;
|
|
2645
2759
|
case "test:skip":
|
|
2646
|
-
if (this.#
|
|
2760
|
+
if (this.#isVerbose) {
|
|
2647
2761
|
this.#fileView.addTest("skipped", payload.result.test.name);
|
|
2648
2762
|
}
|
|
2649
2763
|
break;
|
|
2650
2764
|
case "test:fixme":
|
|
2651
|
-
if (this.#
|
|
2765
|
+
if (this.#isVerbose) {
|
|
2652
2766
|
this.#fileView.addTest("fixme", payload.result.test.name);
|
|
2653
2767
|
}
|
|
2654
2768
|
break;
|
|
2655
2769
|
case "test:todo":
|
|
2656
|
-
if (this.#
|
|
2770
|
+
if (this.#isVerbose) {
|
|
2657
2771
|
this.#fileView.addTest("todo", payload.result.test.name);
|
|
2658
2772
|
}
|
|
2659
2773
|
break;
|
|
2660
2774
|
case "test:error":
|
|
2661
|
-
if (this.#
|
|
2775
|
+
if (this.#isVerbose) {
|
|
2662
2776
|
this.#fileView.addTest("failed", payload.result.test.name);
|
|
2663
2777
|
}
|
|
2664
2778
|
for (const diagnostic of payload.diagnostics) {
|
|
@@ -2666,12 +2780,12 @@ class ListReporter extends BaseReporter {
|
|
|
2666
2780
|
}
|
|
2667
2781
|
break;
|
|
2668
2782
|
case "test:fail":
|
|
2669
|
-
if (this.#
|
|
2783
|
+
if (this.#isVerbose) {
|
|
2670
2784
|
this.#fileView.addTest("failed", payload.result.test.name);
|
|
2671
2785
|
}
|
|
2672
2786
|
break;
|
|
2673
2787
|
case "test:pass":
|
|
2674
|
-
if (this.#
|
|
2788
|
+
if (this.#isVerbose) {
|
|
2675
2789
|
this.#fileView.addTest("passed", payload.result.test.name);
|
|
2676
2790
|
}
|
|
2677
2791
|
break;
|
|
@@ -2954,7 +3068,7 @@ class Glob {
|
|
|
2954
3068
|
class SelectDiagnosticText {
|
|
2955
3069
|
static #pathSelectOptions(resolvedConfig) {
|
|
2956
3070
|
const text = [
|
|
2957
|
-
`Root
|
|
3071
|
+
`Root directory: ${resolvedConfig.rootPath}`,
|
|
2958
3072
|
`Test file match: ${resolvedConfig.testFileMatch.join(", ")}`,
|
|
2959
3073
|
];
|
|
2960
3074
|
if (resolvedConfig.pathMatch.length > 0) {
|
|
@@ -5914,7 +6028,7 @@ class FileRunner {
|
|
|
5914
6028
|
class Runner {
|
|
5915
6029
|
#eventEmitter = new EventEmitter();
|
|
5916
6030
|
#resolvedConfig;
|
|
5917
|
-
static version = "6.0
|
|
6031
|
+
static version = "6.2.0";
|
|
5918
6032
|
constructor(resolvedConfig) {
|
|
5919
6033
|
this.#resolvedConfig = resolvedConfig;
|
|
5920
6034
|
}
|
|
@@ -5933,14 +6047,16 @@ class Runner {
|
|
|
5933
6047
|
}
|
|
5934
6048
|
for (const reporter of this.#resolvedConfig.reporters) {
|
|
5935
6049
|
switch (reporter) {
|
|
6050
|
+
case "dot": {
|
|
6051
|
+
this.#eventEmitter.addReporter(new DotReporter(this.#resolvedConfig));
|
|
6052
|
+
break;
|
|
6053
|
+
}
|
|
5936
6054
|
case "list": {
|
|
5937
|
-
|
|
5938
|
-
this.#eventEmitter.addReporter(listReporter);
|
|
6055
|
+
this.#eventEmitter.addReporter(new ListReporter(this.#resolvedConfig));
|
|
5939
6056
|
break;
|
|
5940
6057
|
}
|
|
5941
6058
|
case "summary": {
|
|
5942
|
-
|
|
5943
|
-
this.#eventEmitter.addReporter(summaryReporter);
|
|
6059
|
+
this.#eventEmitter.addReporter(new SummaryReporter(this.#resolvedConfig));
|
|
5944
6060
|
break;
|
|
5945
6061
|
}
|
|
5946
6062
|
default: {
|
|
@@ -5952,6 +6068,9 @@ class Runner {
|
|
|
5952
6068
|
}
|
|
5953
6069
|
}
|
|
5954
6070
|
async run(files, cancellationToken = new CancellationToken()) {
|
|
6071
|
+
if (this.#resolvedConfig.quiet) {
|
|
6072
|
+
OutputService.outputStream.disable();
|
|
6073
|
+
}
|
|
5955
6074
|
if (!this.#resolvedConfig.watch) {
|
|
5956
6075
|
OutputService.writeMessage(prologueText(Runner.version, this.#resolvedConfig.rootPath));
|
|
5957
6076
|
}
|
|
@@ -5964,6 +6083,9 @@ class Runner {
|
|
|
5964
6083
|
}
|
|
5965
6084
|
this.#eventEmitter.removeReporters();
|
|
5966
6085
|
this.#eventEmitter.removeHandlers();
|
|
6086
|
+
if (this.#resolvedConfig.quiet) {
|
|
6087
|
+
OutputService.outputStream.enable();
|
|
6088
|
+
}
|
|
5967
6089
|
}
|
|
5968
6090
|
async #run(files, cancellationToken) {
|
|
5969
6091
|
const result = new Result(files);
|
|
@@ -5995,11 +6117,15 @@ class Runner {
|
|
|
5995
6117
|
|
|
5996
6118
|
class Cli {
|
|
5997
6119
|
#eventEmitter = new EventEmitter();
|
|
6120
|
+
#noErrorExitCode;
|
|
6121
|
+
constructor(options) {
|
|
6122
|
+
this.#noErrorExitCode = options?.noErrorExitCode ?? false;
|
|
6123
|
+
}
|
|
5998
6124
|
async run(commandLine, cancellationToken = new CancellationToken()) {
|
|
5999
6125
|
const cancellationHandler = new CancellationHandler(cancellationToken, "configError");
|
|
6000
6126
|
this.#eventEmitter.addHandler(cancellationHandler);
|
|
6001
6127
|
const exitCodeHandler = new ExitCodeHandler();
|
|
6002
|
-
this.#eventEmitter.addHandler(exitCodeHandler);
|
|
6128
|
+
!this.#noErrorExitCode && this.#eventEmitter.addHandler(exitCodeHandler);
|
|
6003
6129
|
const setupReporter = new SetupReporter();
|
|
6004
6130
|
this.#eventEmitter.addReporter(setupReporter);
|
|
6005
6131
|
if (commandLine.includes("--help")) {
|
|
@@ -6038,7 +6164,7 @@ class Cli {
|
|
|
6038
6164
|
this.#eventEmitter.addHandler(cancellationHandler);
|
|
6039
6165
|
this.#eventEmitter.addReporter(setupReporter);
|
|
6040
6166
|
}
|
|
6041
|
-
const { configFileOptions, configFilePath } = await Config.parseConfigFile(commandLineOptions.config);
|
|
6167
|
+
const { configFileOptions, configFilePath } = await Config.parseConfigFile(commandLineOptions.config, commandLineOptions.root);
|
|
6042
6168
|
const resolvedConfig = Config.resolve({
|
|
6043
6169
|
configFileOptions,
|
|
6044
6170
|
configFilePath,
|
|
@@ -6110,4 +6236,4 @@ class Cli {
|
|
|
6110
6236
|
}
|
|
6111
6237
|
}
|
|
6112
6238
|
|
|
6113
|
-
export { BaseReporter, CancellationReason, CancellationToken, Cli, Color, Config, ConfigDiagnosticText, DescribeResult, Diagnostic, DiagnosticCategory, DiagnosticOrigin, Directive, EventEmitter, ExpectResult, FileLocation, FileResult, Line, ListReporter, OptionBrand, OptionGroup, Options, OutputService, Path, ProjectResult, Result, ResultStatus, Runner, Scribbler, Select, SelectDiagnosticText, SetupReporter, Store, SummaryReporter, SuppressedResult, TargetResult, TestResult, Text, Version, WatchReporter, addsPackageText, defaultOptions, describeNameText, diagnosticBelongsToNode, diagnosticText, environmentOptions, fileStatusText,
|
|
6239
|
+
export { BaseReporter, CancellationReason, CancellationToken, Cli, Color, Config, ConfigDiagnosticText, DescribeResult, Diagnostic, DiagnosticCategory, DiagnosticOrigin, Directive, DotReporter, EventEmitter, ExpectResult, FileLocation, FileResult, Line, ListReporter, OptionBrand, OptionGroup, Options, OutputService, Path, ProjectResult, Result, ResultStatus, Runner, Scribbler, Select, SelectDiagnosticText, SetupReporter, Store, StreamController, SummaryReporter, SuppressedResult, TargetResult, TestResult, Text, Version, WatchReporter, addsPackageText, defaultOptions, describeNameText, diagnosticBelongsToNode, diagnosticText, dotText, environmentOptions, fileStatusText, formattedText, getDiagnosticMessageText, getTextSpanEnd, helpText, isDiagnosticWithLocation, prologueText, summaryText, testNameText, usesCompilerText, waitingForFileChangesText, watchUsageText };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tstyche",
|
|
3
|
-
"version": "6.0
|
|
3
|
+
"version": "6.2.0",
|
|
4
4
|
"description": "Everything You Need for Type Testing.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"typescript",
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
"import": "./dist/index.js",
|
|
26
26
|
"require": "./dist/index.cjs"
|
|
27
27
|
},
|
|
28
|
+
"./tag": "./dist/tag.js",
|
|
28
29
|
"./tstyche": "./dist/tstyche.js",
|
|
29
30
|
"./package.json": "./package.json"
|
|
30
31
|
},
|