tstyche 2.0.0-rc.1 → 2.0.0-rc.2

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.
@@ -224,46 +224,34 @@ declare enum Color {
224
224
  Gray = "90"
225
225
  }
226
226
 
227
- type ElementChildren = Array<ElementChildren> | ScribblerJsx.Element | string | undefined;
228
- type ComponentConstructor = new (props: Record<string, unknown>) => ScribblerJsx.ElementClass;
227
+ type ScribblerNode = Array<ScribblerNode> | ScribblerJsx.Element | string | undefined;
228
+ type FunctionComponent = (props: Record<string, unknown>) => ScribblerJsx.Element;
229
229
  declare namespace ScribblerJsx {
230
230
  interface Element {
231
231
  props: Record<string, unknown>;
232
- type: ComponentConstructor | string;
233
- }
234
- interface ElementAttributesProperty {
235
- props: Record<string, unknown>;
236
- }
237
- interface ElementClass {
238
- render: () => ScribblerJsx.Element;
232
+ type: FunctionComponent | string;
239
233
  }
240
234
  interface ElementChildrenAttribute {
241
- children: ElementChildren;
235
+ children: ScribblerNode;
242
236
  }
243
237
  interface IntrinsicElements {
244
238
  ansi: {
245
239
  escapes: Color | Array<Color>;
246
240
  };
247
- newLine: {
248
- [key: string]: never;
249
- };
241
+ newLine: {};
250
242
  text: {
251
- children: Array<ElementChildren>;
243
+ children: Array<ScribblerNode>;
252
244
  indent: number;
253
245
  };
254
246
  }
255
247
  }
256
248
 
257
249
  interface LineProps {
258
- children?: ScribblerJsx.ElementChildrenAttribute["children"];
250
+ children?: ScribblerNode;
259
251
  color?: Color;
260
252
  indent?: number;
261
253
  }
262
- declare class Line implements ScribblerJsx.ElementClass {
263
- props: LineProps;
264
- constructor(props: LineProps);
265
- render(): ScribblerJsx.Element;
266
- }
254
+ declare function Line({ children, color, indent }: LineProps): ScribblerJsx.Element;
267
255
 
268
256
  interface ScribblerOptions {
269
257
  newLine?: string;
@@ -276,15 +264,11 @@ declare class Scribbler {
276
264
  }
277
265
 
278
266
  interface TextProps {
279
- children?: ScribblerJsx.ElementChildrenAttribute["children"];
267
+ children?: ScribblerNode;
280
268
  color?: Color | undefined;
281
269
  indent?: number | undefined;
282
270
  }
283
- declare class Text implements ScribblerJsx.ElementClass {
284
- props: TextProps;
285
- constructor(props: TextProps);
286
- render(): ScribblerJsx.Element;
287
- }
271
+ declare function Text({ children, color, indent }: TextProps): ScribblerJsx.Element;
288
272
 
289
273
  declare function addsPackageStepText(compilerVersion: string, installationPath: string): ScribblerJsx.Element;
290
274
 
package/build/tstyche.js CHANGED
@@ -209,28 +209,16 @@ var Color;
209
209
  Color["Gray"] = "90";
210
210
  })(Color || (Color = {}));
211
211
 
212
- class Text {
213
- props;
214
- constructor(props) {
215
- this.props = props;
216
- }
217
- render() {
218
- const ansiEscapes = [];
219
- if (this.props.color != null) {
220
- ansiEscapes.push(this.props.color);
221
- }
222
- return (jsx("text", { indent: this.props.indent ?? 0, children: [ansiEscapes.length > 0 ? jsx("ansi", { escapes: ansiEscapes }) : undefined, this.props.children, ansiEscapes.length > 0 ? jsx("ansi", { escapes: "0" }) : undefined] }));
212
+ function Text({ children, color, indent }) {
213
+ const ansiEscapes = [];
214
+ if (color != null) {
215
+ ansiEscapes.push(color);
223
216
  }
217
+ return (jsx("text", { indent: indent ?? 0, children: [ansiEscapes.length > 0 ? jsx("ansi", { escapes: ansiEscapes }) : undefined, children, ansiEscapes.length > 0 ? jsx("ansi", { escapes: "0" }) : undefined] }));
224
218
  }
225
219
 
226
- class Line {
227
- props;
228
- constructor(props) {
229
- this.props = props;
230
- }
231
- render() {
232
- return (jsx(Text, { color: this.props.color, indent: this.props.indent, children: [this.props.children, jsx("newLine", {})] }));
233
- }
220
+ function Line({ children, color, indent }) {
221
+ return (jsx(Text, { color: color, indent: indent, children: [children, jsx("newLine", {})] }));
234
222
  }
235
223
 
236
224
  class Scribbler {
@@ -253,8 +241,7 @@ class Scribbler {
253
241
  }
254
242
  render(element) {
255
243
  if (typeof element.type === "function") {
256
- const instance = new element.type({ ...element.props });
257
- return this.render(instance.render());
244
+ return this.render(element.type({ ...element.props }));
258
245
  }
259
246
  if (element.type === "ansi" && !this.#noColor) {
260
247
  return this.#escapeSequence(element.props.escapes);
@@ -295,54 +282,42 @@ function describeNameText(name, indent = 0) {
295
282
  return jsx(Line, { indent: indent + 1, children: name });
296
283
  }
297
284
 
298
- class CodeSpanText {
299
- props;
300
- constructor(props) {
301
- this.props = props;
302
- }
303
- render() {
304
- const lastLineInFile = this.props.sourceFile.getLineAndCharacterOfPosition(this.props.sourceFile.text.length).line;
305
- const { character: markedCharacter, line: markedLine } = this.props.sourceFile.getLineAndCharacterOfPosition(this.props.start);
306
- const firstLine = Math.max(markedLine - 2, 0);
307
- const lastLine = Math.min(firstLine + 5, lastLineInFile);
308
- const lineNumberMaxWidth = String(lastLine + 1).length;
309
- const codeSpan = [];
310
- for (let index = firstLine; index <= lastLine; index++) {
311
- const lineStart = this.props.sourceFile.getPositionOfLineAndCharacter(index, 0);
312
- const lineEnd = index === lastLineInFile
313
- ? this.props.sourceFile.text.length
314
- : this.props.sourceFile.getPositionOfLineAndCharacter(index + 1, 0);
315
- const lineNumberText = String(index + 1);
316
- const lineText = this.props.sourceFile.text.slice(lineStart, lineEnd).trimEnd().replace(/\t/g, " ");
317
- if (index === markedLine) {
318
- codeSpan.push(jsx(Line, { children: [jsx(Text, { color: "31", children: ">" }), jsx(Text, { children: " " }), lineNumberText.padStart(lineNumberMaxWidth), jsx(Text, { children: " " }), jsx(Text, { color: "90", children: "|" }), " ", lineText] }), jsx(Line, { children: [" ".repeat(lineNumberMaxWidth + 3), jsx(Text, { color: "90", children: "|" }), " ".repeat(markedCharacter + 1), jsx(Text, { color: "31", children: "^" })] }));
319
- }
320
- else {
321
- codeSpan.push(jsx(Line, { children: [" ".repeat(2), jsx(Text, { color: "90", children: [lineNumberText.padStart(lineNumberMaxWidth), " | ", lineText || ""] })] }));
322
- }
285
+ function CodeSpanText(diagnosticOrigin) {
286
+ const lastLineInFile = diagnosticOrigin.sourceFile.getLineAndCharacterOfPosition(diagnosticOrigin.sourceFile.text.length).line;
287
+ const { character: markedCharacter, line: markedLine } = diagnosticOrigin.sourceFile.getLineAndCharacterOfPosition(diagnosticOrigin.start);
288
+ const firstLine = Math.max(markedLine - 2, 0);
289
+ const lastLine = Math.min(firstLine + 5, lastLineInFile);
290
+ const lineNumberMaxWidth = String(lastLine + 1).length;
291
+ const codeSpan = [];
292
+ for (let index = firstLine; index <= lastLine; index++) {
293
+ const lineStart = diagnosticOrigin.sourceFile.getPositionOfLineAndCharacter(index, 0);
294
+ const lineEnd = index === lastLineInFile
295
+ ? diagnosticOrigin.sourceFile.text.length
296
+ : diagnosticOrigin.sourceFile.getPositionOfLineAndCharacter(index + 1, 0);
297
+ const lineNumberText = String(index + 1);
298
+ const lineText = diagnosticOrigin.sourceFile.text.slice(lineStart, lineEnd).trimEnd().replace(/\t/g, " ");
299
+ if (index === markedLine) {
300
+ codeSpan.push(jsx(Line, { children: [jsx(Text, { color: "31", children: ">" }), jsx(Text, { children: " " }), lineNumberText.padStart(lineNumberMaxWidth), jsx(Text, { children: " " }), jsx(Text, { color: "90", children: "|" }), " ", lineText] }), jsx(Line, { children: [" ".repeat(lineNumberMaxWidth + 3), jsx(Text, { color: "90", children: "|" }), " ".repeat(markedCharacter + 1), jsx(Text, { color: "31", children: "^" })] }));
301
+ }
302
+ else {
303
+ codeSpan.push(jsx(Line, { children: [" ".repeat(2), jsx(Text, { color: "90", children: [lineNumberText.padStart(lineNumberMaxWidth), " | ", lineText || ""] })] }));
323
304
  }
324
- const breadcrumbs = this.props.breadcrumbs?.flatMap((ancestor) => [
325
- jsx(Text, { color: "90", children: " ❭ " }),
326
- jsx(Text, { children: ancestor }),
327
- ]);
328
- const location = (jsx(Line, { children: [" ".repeat(lineNumberMaxWidth + 5), jsx(Text, { color: "90", children: "at" }), jsx(Text, { children: " " }), jsx(Text, { color: "36", children: Path.relative("", this.props.sourceFile.fileName) }), jsx(Text, { color: "90", children: [":", String(markedLine + 1), ":", String(markedCharacter + 1)] }), breadcrumbs] }));
329
- return (jsx(Text, { children: [codeSpan, jsx(Line, {}), location] }));
330
305
  }
306
+ const breadcrumbs = diagnosticOrigin.breadcrumbs?.flatMap((ancestor) => [
307
+ jsx(Text, { color: "90", children: " ❭ " }),
308
+ jsx(Text, { children: ancestor }),
309
+ ]);
310
+ const location = (jsx(Line, { children: [" ".repeat(lineNumberMaxWidth + 5), jsx(Text, { color: "90", children: "at" }), jsx(Text, { children: " " }), jsx(Text, { color: "36", children: Path.relative("", diagnosticOrigin.sourceFile.fileName) }), jsx(Text, { color: "90", children: [":", String(markedLine + 1), ":", String(markedCharacter + 1)] }), breadcrumbs] }));
311
+ return (jsx(Text, { children: [codeSpan, jsx(Line, {}), location] }));
331
312
  }
332
313
 
333
- class DiagnosticText {
334
- props;
335
- constructor(props) {
336
- this.props = props;
337
- }
338
- render() {
339
- const code = typeof this.props.diagnostic.code === "string" ? (jsx(Text, { color: "90", children: [" ", this.props.diagnostic.code] })) : undefined;
340
- const text = Array.isArray(this.props.diagnostic.text) ? this.props.diagnostic.text : [this.props.diagnostic.text];
341
- const message = text.map((text, index) => (jsx(Text, { children: [index === 1 ? jsx(Line, {}) : undefined, jsx(Line, { children: [text, code] })] })));
342
- const related = this.props.diagnostic.related?.map((relatedDiagnostic) => (jsx(DiagnosticText, { diagnostic: relatedDiagnostic })));
343
- const codeSpan = this.props.diagnostic.origin ? (jsx(Text, { children: [jsx(Line, {}), jsx(CodeSpanText, { ...this.props.diagnostic.origin })] })) : undefined;
344
- return (jsx(Text, { children: [message, codeSpan, jsx(Line, {}), jsx(Text, { indent: 2, children: related })] }));
345
- }
314
+ function DiagnosticText({ diagnostic }) {
315
+ const code = typeof diagnostic.code === "string" ? jsx(Text, { color: "90", children: [" ", diagnostic.code] }) : undefined;
316
+ const text = Array.isArray(diagnostic.text) ? diagnostic.text : [diagnostic.text];
317
+ const message = text.map((text, index) => (jsx(Text, { children: [index === 1 ? jsx(Line, {}) : undefined, jsx(Line, { children: [text, code] })] })));
318
+ const related = diagnostic.related?.map((relatedDiagnostic) => jsx(DiagnosticText, { diagnostic: relatedDiagnostic }));
319
+ const codeSpan = diagnostic.origin ? (jsx(Text, { children: [jsx(Line, {}), jsx(CodeSpanText, { ...diagnostic.origin })] })) : undefined;
320
+ return (jsx(Text, { children: [message, codeSpan, jsx(Line, {}), jsx(Text, { indent: 2, children: related })] }));
346
321
  }
347
322
  function diagnosticText(diagnostic) {
348
323
  let prefix;
@@ -359,18 +334,12 @@ function diagnosticText(diagnostic) {
359
334
  return (jsx(Text, { children: [prefix, jsx(DiagnosticText, { diagnostic: diagnostic })] }));
360
335
  }
361
336
 
362
- class FileNameText {
363
- props;
364
- constructor(props) {
365
- this.props = props;
366
- }
367
- render() {
368
- const relativePath = Path.relative("", this.props.filePath);
369
- const lastPathSeparator = relativePath.lastIndexOf("/");
370
- const directoryNameText = relativePath.slice(0, lastPathSeparator + 1);
371
- const fileNameText = relativePath.slice(lastPathSeparator + 1);
372
- return (jsx(Text, { children: [jsx(Text, { color: "90", children: directoryNameText }), fileNameText] }));
373
- }
337
+ function FileNameText({ filePath }) {
338
+ const relativePath = Path.relative("", filePath);
339
+ const lastPathSeparator = relativePath.lastIndexOf("/");
340
+ const directoryNameText = relativePath.slice(0, lastPathSeparator + 1);
341
+ const fileNameText = relativePath.slice(lastPathSeparator + 1);
342
+ return (jsx(Text, { children: [jsx(Text, { color: "90", children: directoryNameText }), fileNameText] }));
374
343
  }
375
344
  function fileStatusText(status, testFile) {
376
345
  let statusColor;
@@ -399,18 +368,14 @@ function fileViewText(lines, addEmptyFinalLine) {
399
368
  return (jsx(Text, { children: [[...lines], addEmptyFinalLine ? jsx(Line, {}) : undefined] }));
400
369
  }
401
370
 
402
- class JsonText {
403
- props;
404
- constructor(props) {
405
- this.props = props;
371
+ function formattedText(input) {
372
+ if (typeof input === "string") {
373
+ return jsx(Line, { children: input });
406
374
  }
407
- render() {
408
- return jsx(Line, { children: JSON.stringify(this.#sortObject(this.props.input), null, 2) });
375
+ if (Array.isArray(input)) {
376
+ return jsx(Line, { children: JSON.stringify(input, null, 2) });
409
377
  }
410
- #sortObject(target) {
411
- if (Array.isArray(target)) {
412
- return target;
413
- }
378
+ function sortObject(target) {
414
379
  return Object.keys(target)
415
380
  .sort()
416
381
  .reduce((result, key) => {
@@ -418,12 +383,7 @@ class JsonText {
418
383
  return result;
419
384
  }, {});
420
385
  }
421
- }
422
- function formattedText(input) {
423
- if (typeof input === "string") {
424
- return jsx(Line, { children: input });
425
- }
426
- return jsx(JsonText, { input: input });
386
+ return jsx(Line, { children: JSON.stringify(sortObject(input), null, 2) });
427
387
  }
428
388
 
429
389
  const usageExamples = [
@@ -431,95 +391,48 @@ const usageExamples = [
431
391
  ["tstyche path/to/first.test.ts", "Only run the test files with matching path."],
432
392
  ["tstyche --target 4.9,5.3.2,current", "Test on all specified versions of TypeScript."],
433
393
  ];
434
- class HintText {
435
- props;
436
- constructor(props) {
437
- this.props = props;
438
- }
439
- render() {
440
- return (jsx(Text, { indent: 1, color: "90", children: this.props.children }));
441
- }
394
+ function HintText({ children }) {
395
+ return (jsx(Text, { indent: 1, color: "90", children: children }));
442
396
  }
443
- class HelpHeaderText {
444
- props;
445
- constructor(props) {
446
- this.props = props;
447
- }
448
- render() {
449
- const hint = (jsx(HintText, { children: jsx(Text, { children: this.props.tstycheVersion }) }));
450
- return (jsx(Line, { children: [jsx(Text, { children: "The TSTyche Type Test Runner" }), hint] }));
451
- }
397
+ function HelpHeaderText({ tstycheVersion }) {
398
+ return (jsx(Line, { children: ["The TSTyche Type Test Runner", jsx(HintText, { children: tstycheVersion })] }));
452
399
  }
453
- class CommandText {
454
- props;
455
- constructor(props) {
456
- this.props = props;
457
- }
458
- render() {
459
- let hint;
460
- if (this.props.hint != null) {
461
- hint = jsx(HintText, { children: this.props.hint });
462
- }
463
- return (jsx(Line, { indent: 1, children: [jsx(Text, { color: "34", children: this.props.text }), hint] }));
400
+ function CommandText({ hint, text }) {
401
+ let hintText;
402
+ if (hint != null) {
403
+ hintText = jsx(HintText, { children: hint });
464
404
  }
405
+ return (jsx(Line, { indent: 1, children: [jsx(Text, { color: "34", children: text }), hintText] }));
465
406
  }
466
- class OptionDescriptionText {
467
- props;
468
- constructor(props) {
469
- this.props = props;
470
- }
471
- render() {
472
- return jsx(Line, { indent: 1, children: this.props.text });
473
- }
407
+ function OptionDescriptionText({ text }) {
408
+ return jsx(Line, { indent: 1, children: text });
474
409
  }
475
- class CommandLineUsageText {
476
- render() {
477
- const usageText = usageExamples.map(([commandText, descriptionText]) => (jsx(Text, { children: [jsx(CommandText, { text: commandText }), jsx(OptionDescriptionText, { text: descriptionText }), jsx(Line, {})] })));
478
- return jsx(Text, { children: usageText });
479
- }
410
+ function CommandLineUsageText() {
411
+ const usageText = usageExamples.map(([commandText, descriptionText]) => (jsx(Text, { children: [jsx(CommandText, { text: commandText }), jsx(OptionDescriptionText, { text: descriptionText }), jsx(Line, {})] })));
412
+ return jsx(Text, { children: usageText });
480
413
  }
481
- class CommandLineOptionNameText {
482
- props;
483
- constructor(props) {
484
- this.props = props;
485
- }
486
- render() {
487
- return jsx(Text, { children: ["--", this.props.text] });
488
- }
414
+ function CommandLineOptionNameText({ text }) {
415
+ return jsx(Text, { children: ["--", text] });
489
416
  }
490
- class CommandLineOptionHintText {
491
- props;
492
- constructor(props) {
493
- this.props = props;
494
- }
495
- render() {
496
- if (this.props.definition.brand === "list") {
497
- return (jsx(Text, { children: [this.props.definition.brand, " of ", this.props.definition.items.brand, "s"] }));
498
- }
499
- return jsx(Text, { children: this.props.definition.brand });
417
+ function CommandLineOptionHintText({ definition }) {
418
+ if (definition.brand === "list") {
419
+ return (jsx(Text, { children: [definition.brand, " of ", definition.items.brand, "s"] }));
500
420
  }
421
+ return jsx(Text, { children: definition.brand });
501
422
  }
502
- class CommandLineOptionsText {
503
- props;
504
- constructor(props) {
505
- this.props = props;
506
- }
507
- render() {
508
- const definitions = [...this.props.optionDefinitions.values()];
509
- const optionsText = definitions.map((definition) => {
510
- let hint;
511
- if (definition.brand !== "bareTrue") {
512
- hint = jsx(CommandLineOptionHintText, { definition: definition });
513
- }
514
- return (jsx(Text, { children: [jsx(CommandText, { text: jsx(CommandLineOptionNameText, { text: definition.name }), hint: hint }), jsx(OptionDescriptionText, { text: definition.description }), jsx(Line, {})] }));
515
- });
516
- return (jsx(Text, { children: [jsx(Line, { children: "Command Line Options" }), jsx(Line, {}), optionsText] }));
517
- }
423
+ function CommandLineOptionsText({ optionDefinitions }) {
424
+ const definitions = [...optionDefinitions.values()];
425
+ const optionsText = definitions.map((definition) => {
426
+ let hint;
427
+ if (definition.brand !== "bareTrue") {
428
+ hint = jsx(CommandLineOptionHintText, { definition: definition });
429
+ }
430
+ return (jsx(Text, { children: [jsx(CommandText, { text: jsx(CommandLineOptionNameText, { text: definition.name }), hint: hint }), jsx(OptionDescriptionText, { text: definition.description }), jsx(Line, {})] }));
431
+ });
432
+ return (jsx(Text, { children: [jsx(Line, { children: "Command Line Options" }), jsx(Line, {}), optionsText] }));
518
433
  }
519
- class HelpFooterText {
520
- render() {
521
- return jsx(Line, { children: "To learn more, visit https://tstyche.org" });
522
- }
434
+ function HelpFooterText() {
435
+ return jsx(Line, { children: "To learn more, visit https://tstyche.org" });
523
436
  }
524
437
  function helpText(optionDefinitions, tstycheVersion) {
525
438
  return (jsx(Text, { children: [jsx(HelpHeaderText, { tstycheVersion: tstycheVersion }), jsx(Line, {}), jsx(CommandLineUsageText, {}), jsx(Line, {}), jsx(CommandLineOptionsText, { optionDefinitions: optionDefinitions }), jsx(Line, {}), jsx(HelpFooterText, {}), jsx(Line, {})] }));
@@ -564,118 +477,72 @@ class OutputService {
564
477
  }
565
478
  }
566
479
 
567
- class RowText {
568
- props;
569
- constructor(props) {
570
- this.props = props;
571
- }
572
- render() {
573
- return (jsx(Line, { children: [`${this.props.label}:`.padEnd(12), this.props.text] }));
574
- }
480
+ function RowText({ label, text }) {
481
+ return (jsx(Line, { children: [`${label}:`.padEnd(12), text] }));
575
482
  }
576
- class CountText {
577
- props;
578
- constructor(props) {
579
- this.props = props;
580
- }
581
- render() {
582
- return (jsx(Text, { children: [this.props.failed > 0 ? (jsx(Text, { children: [jsx(Text, { color: "31", children: [String(this.props.failed), " failed"] }), jsx(Text, { children: ", " })] })) : undefined, this.props.skipped > 0 ? (jsx(Text, { children: [jsx(Text, { color: "33", children: [String(this.props.skipped), " skipped"] }), jsx(Text, { children: ", " })] })) : undefined, this.props.todo > 0 ? (jsx(Text, { children: [jsx(Text, { color: "35", children: [String(this.props.todo), " todo"] }), jsx(Text, { children: ", " })] })) : undefined, this.props.passed > 0 ? (jsx(Text, { children: [jsx(Text, { color: "32", children: [String(this.props.passed), " passed"] }), jsx(Text, { children: ", " })] })) : undefined, jsx(Text, { children: [String(this.props.total), jsx(Text, { children: " total" })] })] }));
583
- }
483
+ function CountText({ failed, passed, skipped, todo, total }) {
484
+ return (jsx(Text, { children: [failed > 0 ? (jsx(Text, { children: [jsx(Text, { color: "31", children: [String(failed), " failed"] }), jsx(Text, { children: ", " })] })) : undefined, skipped > 0 ? (jsx(Text, { children: [jsx(Text, { color: "33", children: [String(skipped), " skipped"] }), jsx(Text, { children: ", " })] })) : undefined, todo > 0 ? (jsx(Text, { children: [jsx(Text, { color: "35", children: [String(todo), " todo"] }), jsx(Text, { children: ", " })] })) : undefined, passed > 0 ? (jsx(Text, { children: [jsx(Text, { color: "32", children: [String(passed), " passed"] }), jsx(Text, { children: ", " })] })) : undefined, jsx(Text, { children: [String(total), jsx(Text, { children: " total" })] })] }));
485
+ }
486
+ function DurationText({ duration }) {
487
+ const minutes = Math.floor(duration / 60);
488
+ const seconds = duration % 60;
489
+ return (jsx(Text, { children: [minutes > 0 ? `${String(minutes)}m ` : undefined, `${String(Math.round(seconds * 10) / 10)}s`] }));
584
490
  }
585
- class DurationText {
586
- props;
587
- constructor(props) {
588
- this.props = props;
491
+ function MatchText({ text }) {
492
+ if (typeof text === "string") {
493
+ return jsx(Text, { children: ["'", text, "'"] });
589
494
  }
590
- render() {
591
- const duration = this.props.duration / 1000;
592
- const minutes = Math.floor(duration / 60);
593
- const seconds = duration % 60;
594
- return (jsx(Text, { children: [minutes > 0 ? `${String(minutes)}m ` : undefined, `${String(Math.round(seconds * 10) / 10)}s`] }));
495
+ if (text.length <= 1) {
496
+ return jsx(Text, { children: ["'", ...text, "'"] });
595
497
  }
498
+ const lastItem = text.pop();
499
+ return (jsx(Text, { children: [text.map((match, index, list) => (jsx(Text, { children: ["'", match, "'", index === list.length - 1 ? jsx(Text, { children: " " }) : jsx(Text, { color: "90", children: ", " })] }))), jsx(Text, { color: "90", children: "or" }), " '", lastItem, "'"] }));
596
500
  }
597
- class MatchText {
598
- props;
599
- constructor(props) {
600
- this.props = props;
501
+ function RanFilesText({ onlyMatch, pathMatch, skipMatch }) {
502
+ const testNameMatchText = [];
503
+ if (onlyMatch != null) {
504
+ testNameMatchText.push(jsx(Text, { children: [jsx(Text, { color: "90", children: "matching " }), jsx(MatchText, { text: onlyMatch })] }));
601
505
  }
602
- render() {
603
- if (typeof this.props.text === "string") {
604
- return jsx(Text, { children: ["'", this.props.text, "'"] });
605
- }
606
- if (this.props.text.length <= 1) {
607
- return jsx(Text, { children: ["'", ...this.props.text, "'"] });
608
- }
609
- const lastItem = this.props.text.pop();
610
- return (jsx(Text, { children: [this.props.text.map((match, index, list) => (jsx(Text, { children: ["'", match, "'", index === list.length - 1 ? jsx(Text, { children: " " }) : jsx(Text, { color: "90", children: ", " })] }))), jsx(Text, { color: "90", children: "or" }), " '", lastItem, "'"] }));
506
+ if (skipMatch != null) {
507
+ testNameMatchText.push(jsx(Text, { children: [onlyMatch == null ? undefined : jsx(Text, { color: "90", children: " and " }), jsx(Text, { color: "90", children: "not matching " }), jsx(MatchText, { text: skipMatch })] }));
611
508
  }
612
- }
613
- class RanFilesText {
614
- props;
615
- constructor(props) {
616
- this.props = props;
509
+ let pathMatchText;
510
+ if (pathMatch.length > 0) {
511
+ pathMatchText = (jsx(Text, { children: [jsx(Text, { color: "90", children: "test files matching " }), jsx(MatchText, { text: pathMatch }), jsx(Text, { color: "90", children: "." })] }));
617
512
  }
618
- render() {
619
- const testNameMatchText = [];
620
- if (this.props.onlyMatch != null) {
621
- testNameMatchText.push(jsx(Text, { children: [jsx(Text, { color: "90", children: "matching " }), jsx(MatchText, { text: this.props.onlyMatch })] }));
622
- }
623
- if (this.props.skipMatch != null) {
624
- testNameMatchText.push(jsx(Text, { children: [this.props.onlyMatch == null ? undefined : jsx(Text, { color: "90", children: " and " }), jsx(Text, { color: "90", children: "not matching " }), jsx(MatchText, { text: this.props.skipMatch })] }));
625
- }
626
- let pathMatchText;
627
- if (this.props.pathMatch.length > 0) {
628
- pathMatchText = (jsx(Text, { children: [jsx(Text, { color: "90", children: "test files matching " }), jsx(MatchText, { text: this.props.pathMatch }), jsx(Text, { color: "90", children: "." })] }));
629
- }
630
- else {
631
- pathMatchText = jsx(Text, { color: "90", children: "all test files." });
632
- }
633
- return (jsx(Line, { children: [jsx(Text, { color: "90", children: "Ran " }), testNameMatchText.length > 0 ? jsx(Text, { color: "90", children: "tests " }) : undefined, testNameMatchText, testNameMatchText.length > 0 ? jsx(Text, { color: "90", children: " in " }) : undefined, pathMatchText] }));
513
+ else {
514
+ pathMatchText = jsx(Text, { color: "90", children: "all test files." });
634
515
  }
516
+ return (jsx(Line, { children: [jsx(Text, { color: "90", children: "Ran " }), testNameMatchText.length > 0 ? jsx(Text, { color: "90", children: "tests " }) : undefined, testNameMatchText, testNameMatchText.length > 0 ? jsx(Text, { color: "90", children: " in " }) : undefined, pathMatchText] }));
635
517
  }
636
518
  function summaryText({ duration, expectCount, fileCount, onlyMatch, pathMatch, skipMatch, targetCount, testCount, }) {
637
519
  const targetCountText = (jsx(RowText, { label: "Targets", text: jsx(CountText, { failed: targetCount.failed, passed: targetCount.passed, skipped: targetCount.skipped, todo: targetCount.todo, total: targetCount.total }) }));
638
520
  const fileCountText = (jsx(RowText, { label: "Test files", text: jsx(CountText, { failed: fileCount.failed, passed: fileCount.passed, skipped: fileCount.skipped, todo: fileCount.todo, total: fileCount.total }) }));
639
521
  const testCountText = (jsx(RowText, { label: "Tests", text: jsx(CountText, { failed: testCount.failed, passed: testCount.passed, skipped: testCount.skipped, todo: testCount.todo, total: testCount.total }) }));
640
522
  const assertionCountText = (jsx(RowText, { label: "Assertions", text: jsx(CountText, { failed: expectCount.failed, passed: expectCount.passed, skipped: expectCount.skipped, todo: expectCount.todo, total: expectCount.total }) }));
641
- return (jsx(Text, { children: [targetCountText, fileCountText, testCount.total > 0 ? testCountText : undefined, expectCount.total > 0 ? assertionCountText : undefined, jsx(RowText, { label: "Duration", text: jsx(DurationText, { duration: duration }) }), jsx(Line, {}), jsx(RanFilesText, { onlyMatch: onlyMatch, pathMatch: pathMatch, skipMatch: skipMatch })] }));
523
+ return (jsx(Text, { children: [targetCountText, fileCountText, testCount.total > 0 ? testCountText : undefined, expectCount.total > 0 ? assertionCountText : undefined, jsx(RowText, { label: "Duration", text: jsx(DurationText, { duration: duration / 1000 }) }), jsx(Line, {}), jsx(RanFilesText, { onlyMatch: onlyMatch, pathMatch: pathMatch, skipMatch: skipMatch })] }));
642
524
  }
643
525
 
644
- class StatusText {
645
- props;
646
- constructor(props) {
647
- this.props = props;
648
- }
649
- render() {
650
- switch (this.props.status) {
651
- case "fail":
652
- return jsx(Text, { color: "31", children: "\u00D7" });
653
- case "pass":
654
- return jsx(Text, { color: "32", children: "+" });
655
- case "skip":
656
- return jsx(Text, { color: "33", children: "- skip" });
657
- case "todo":
658
- return jsx(Text, { color: "35", children: "- todo" });
659
- }
526
+ function StatusText({ status }) {
527
+ switch (status) {
528
+ case "fail":
529
+ return jsx(Text, { color: "31", children: "\u00D7" });
530
+ case "pass":
531
+ return jsx(Text, { color: "32", children: "+" });
532
+ case "skip":
533
+ return jsx(Text, { color: "33", children: "- skip" });
534
+ case "todo":
535
+ return jsx(Text, { color: "35", children: "- todo" });
660
536
  }
661
537
  }
662
538
  function testNameText(status, name, indent = 0) {
663
539
  return (jsx(Line, { indent: indent + 1, children: [jsx(StatusText, { status: status }), " ", jsx(Text, { color: "90", children: name })] }));
664
540
  }
665
541
 
666
- class ProjectNameText {
667
- props;
668
- constructor(props) {
669
- this.props = props;
670
- }
671
- render() {
672
- return (jsx(Text, { color: "90", children: [" with ", Path.relative("", this.props.filePath)] }));
673
- }
674
- }
675
542
  function usesCompilerStepText(compilerVersion, tsconfigFilePath, options) {
676
543
  let projectPathText;
677
544
  if (tsconfigFilePath != null) {
678
- projectPathText = jsx(ProjectNameText, { filePath: tsconfigFilePath });
545
+ projectPathText = (jsx(Text, { color: "90", children: [" with ", Path.relative("", tsconfigFilePath)] }));
679
546
  }
680
547
  return (jsx(Text, { children: [options?.prependEmptyLine === true ? jsx(Line, {}) : undefined, jsx(Line, { children: [jsx(Text, { color: "34", children: "uses" }), " TypeScript ", compilerVersion, projectPathText] }), jsx(Line, {})] }));
681
548
  }
@@ -2089,6 +1956,8 @@ class WatchService {
2089
1956
  case "\u0003":
2090
1957
  case "\u0004":
2091
1958
  case "\u001B":
1959
+ case "\u0051":
1960
+ case "\u0071":
2092
1961
  case "\u0058":
2093
1962
  case "\u0078": {
2094
1963
  this.close();
@@ -3377,7 +3246,7 @@ class TSTyche {
3377
3246
  #selectService;
3378
3247
  #storeService;
3379
3248
  #taskRunner;
3380
- static version = "2.0.0-rc.1";
3249
+ static version = "2.0.0-rc.2";
3381
3250
  constructor(resolvedConfig, outputService, selectService, storeService) {
3382
3251
  this.#resolvedConfig = resolvedConfig;
3383
3252
  this.#outputService = outputService;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tstyche",
3
- "version": "2.0.0-rc.1",
3
+ "version": "2.0.0-rc.2",
4
4
  "description": "The Essential Type Testing Tool.",
5
5
  "keywords": [
6
6
  "typescript",
@@ -42,11 +42,11 @@
42
42
  "check:spelling": "cspell --config cspell.config.json --quiet",
43
43
  "check:types": "tsc --noEmit --project tsconfig.json",
44
44
  "clean": "rm -rf build",
45
- "format": "biome format . --write",
45
+ "format": "biome format --write",
46
46
  "generate": "yarn generate:schema && yarn generate:types",
47
47
  "generate:schema": "node ./models/__scripts__/generate-schema.js",
48
48
  "generate:types": "node ./models/__scripts__/generate-types.js",
49
- "lint": "biome lint . --apply",
49
+ "lint": "biome lint --write",
50
50
  "prepublish": "yarn clean && yarn build && yarn test",
51
51
  "test": "yarn test:unit && yarn test:e2e",
52
52
  "test:coverage": "yarn build --sourcemap && c8 --config c8.config.json yarn test:e2e",
@@ -59,11 +59,11 @@
59
59
  "test:unit": "yarn test:run **/__tests__/*.test.* --parallel --reporter dot"
60
60
  },
61
61
  "devDependencies": {
62
- "@biomejs/biome": "1.7.3",
62
+ "@biomejs/biome": "1.8.0",
63
63
  "@rollup/plugin-typescript": "11.1.6",
64
64
  "@types/mocha": "10.0.6",
65
- "@types/node": "20.14.1",
66
- "ajv": "8.15.0",
65
+ "@types/node": "20.14.2",
66
+ "ajv": "8.16.0",
67
67
  "c8": "9.1.0",
68
68
  "cspell": "8.8.4",
69
69
  "magic-string": "0.30.10",
@@ -71,7 +71,7 @@
71
71
  "pretty-ansi": "2.0.0",
72
72
  "rollup": "4.18.0",
73
73
  "rollup-plugin-dts": "6.1.1",
74
- "tslib": "2.6.2",
74
+ "tslib": "2.6.3",
75
75
  "typescript": "5.4.5"
76
76
  },
77
77
  "peerDependencies": {