@aljazmc/testero 0.4.2 → 0.5.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.
@@ -2,12 +2,16 @@ import type { Rules } from "./rules.js";
2
2
  import type { Options } from "./testero.js";
3
3
  /** Command line arguments, named like Jest's. */
4
4
  export default class Arguments {
5
- static readonly usage = "Usage: testero [patterns...] [options]\n\nRuns the test files whose paths match a pattern, every test file without patterns.\n\nOptions:\n -t, --testNamePattern <regex> run only tests whose name matches\n --bail stop after the first failing test file\n --verbose list every test\n --listTests print the test files instead of running them\n --passWithNoTests succeed when there are no test files\n --testTimeout <ms> milliseconds a test or hook may take\n --config [js] write the default testero.config.ts, or .js\n -h, --help show this help\n";
5
+ static readonly usage = "Usage: testero [patterns...] [options]\n\nRuns the test files whose paths match a pattern, every test file without patterns.\n\nOptions:\n -t, --testNamePattern <regex> run only tests whose name matches\n --bail stop after the first failing test file\n --verbose list every test\n --listTests print the test files instead of running them\n --passWithNoTests succeed when there are no test files\n --testTimeout <ms> milliseconds a test or hook may take\n --coverage report which lines and functions the tests run\n --watch rerun the tests of changed files and what imports them\n --watchAll rerun every test when a file changes\n --config [js] write the default testero.config.ts, or .js\n -h, --help show this help\n";
6
6
  readonly patterns: string[];
7
7
  readonly rules: Partial<Rules>;
8
8
  namePattern: RegExp | undefined;
9
9
  listTests: boolean;
10
10
  help: boolean;
11
+ /** Reruns the tests of changed files, or all of them, when files change. */
12
+ watch: "related" | "all" | undefined;
13
+ /** The options, without the patterns and the watch ones, for the runs of watch mode. */
14
+ readonly flags: string[];
11
15
  constructor(argv: string[]);
12
16
  /** The configured rules, with the ones given on the command line instead. */
13
17
  options(rules: Rules): Options;
@@ -0,0 +1,63 @@
1
+ /** How often the tests called a function of a file. */
2
+ export interface FunctionCoverage {
3
+ name: string;
4
+ /** The line it starts on, from 1. */
5
+ line: number;
6
+ count: number;
7
+ }
8
+ /** The coverage of one source file. */
9
+ export interface FileCoverage {
10
+ /** The path of the file, relative to the root. */
11
+ file: string;
12
+ /** How often each line with code ran, by its number from 1. */
13
+ lines: Map<number, number>;
14
+ /** The functions by where they start, like `3:10`. */
15
+ functions: Map<string, FunctionCoverage>;
16
+ /** Whether a test loaded the file, one no test loads is not covered at all. */
17
+ loaded: boolean;
18
+ }
19
+ /** How much of something ran. */
20
+ export interface Ratio {
21
+ covered: number;
22
+ total: number;
23
+ }
24
+ /** A source map mapping, from a place in the generated code to one in a source, all from 0. */
25
+ export interface Segment {
26
+ line: number;
27
+ column: number;
28
+ source: number;
29
+ sourceLine: number;
30
+ sourceColumn: number;
31
+ }
32
+ /**
33
+ * Measures which lines and functions of the sources the tests run, with V8's
34
+ * own coverage, mapped back to the sources by the source maps of the bundles.
35
+ * Every test file is bundled with the sources it imports, so the counts of a
36
+ * source are the sums of its copies.
37
+ */
38
+ export default class Coverage {
39
+ #private;
40
+ /** Reports the files, relative to the root, that `tracks` takes. */
41
+ constructor(root: string, tracks: (file: string) => boolean);
42
+ /** Starts counting, before the tests load. */
43
+ start(): Promise<void>;
44
+ /**
45
+ * The coverage of the tracked sources of the bundles, by their paths,
46
+ * and of the files no test loaded, sorted by path.
47
+ */
48
+ collect(bundles: ReadonlyMap<string, string>, unloaded?: Iterable<string>): Promise<FileCoverage[]>;
49
+ /** The mappings of a source map with a source, in order, its base64 VLQs decoded. */
50
+ static decode(mappings: string): Segment[];
51
+ /** How many of the lines with code ran. */
52
+ static lines(coverage: FileCoverage): Ratio;
53
+ /** How many of the functions ran. */
54
+ static functions(coverage: FileCoverage): Ratio;
55
+ /** The sums of ratios. */
56
+ static sum(ratios: Ratio[]): Ratio;
57
+ /** A percentage like Jest's, 100 when there is nothing to run, unless nothing loaded it. */
58
+ static percent(ratio: Ratio, loaded?: boolean): number;
59
+ /** The lines that did not run, in ranges like `3-5,9`. */
60
+ static uncovered(coverage: FileCoverage): string;
61
+ /** The coverage in the lcov format editors and services read. */
62
+ static lcov(root: string, files: FileCoverage[]): string;
63
+ }
@@ -52,7 +52,10 @@ export default class Assertion {
52
52
  get resolves(): Assertion & Matchers;
53
53
  /** The assertion on why a promise rejects, its matchers return promises. */
54
54
  get rejects(): Assertion & Matchers;
55
- /** Adds a matcher to every assertion, like `expect.extend`. */
56
- static define(name: string, matcher: Matcher): void;
55
+ /**
56
+ * Adds a matcher to the assertions of a class: Assertion itself for the
57
+ * built in ones, the class of one test file for `expect.extend`.
58
+ */
59
+ static define(target: typeof Assertion, name: string, matcher: Matcher): void;
57
60
  }
58
61
  export {};
@@ -12,4 +12,6 @@ export default class Equality {
12
12
  static equals(a: unknown, b: unknown, strict?: boolean): boolean;
13
13
  /** Whether received has every property expected has, recursively, like `toMatchObject`. */
14
14
  static matches(received: unknown, expected: unknown): boolean;
15
+ /** The bytes of an ArrayBuffer, SharedArrayBuffer or DataView, undefined for other values. */
16
+ static bytes(value: unknown): Uint8Array | undefined;
15
17
  }
@@ -8,7 +8,7 @@ export interface MatcherContext {
8
8
  isNot: boolean;
9
9
  promise: "" | "resolves" | "rejects";
10
10
  }
11
- export type Matcher = (this: MatcherContext, received: unknown, ...expected: any[]) => MatcherResult;
11
+ export type Matcher = (this: MatcherContext, received: unknown, ...expected: any[]) => MatcherResult | Promise<MatcherResult>;
12
12
  /** The first line of a failure message, like `expect(received).not.toBe(expected)`. */
13
13
  export declare const hint: (context: MatcherContext, name: string, expected?: string) => string;
14
14
  /** Jest's matchers, `this` tells whether `.not`, `.resolves` or `.rejects` were used. */
@@ -1,3 +1,4 @@
1
+ import { type FileCoverage } from "./coverage.js";
1
2
  import type { Result } from "./runner.js";
2
3
  /** The outcome of one test file. */
3
4
  export interface FileResult {
@@ -22,6 +23,8 @@ export default class Reporter {
22
23
  file(result: FileResult): void;
23
24
  /** Counts of test files and tests, and the time they took. */
24
25
  summary(files: FileResult[], duration: number): void;
26
+ /** The coverage of each file in a table like Jest's, under the totals. */
27
+ coverage(files: FileCoverage[]): void;
25
28
  /** Explains that no test files were found. */
26
29
  none(patterns: string[]): void;
27
30
  }
@@ -16,4 +16,13 @@ export interface Rules {
16
16
  resetMocks: boolean;
17
17
  /** Restores every spy to the original before each test. */
18
18
  restoreMocks: boolean;
19
+ /** Measures which lines and functions of the sources the tests run. */
20
+ collectCoverage: boolean;
21
+ /**
22
+ * Globs of the files coverage is reported for, also when no test loads
23
+ * them, "!" excludes; empty reports the files the tests load.
24
+ */
25
+ collectCoverageFrom: string[];
26
+ /** Where `lcov.info` is written, relative to the root. */
27
+ coverageDirectory: string;
19
28
  }
@@ -26,6 +26,11 @@ export default class Runner {
26
26
  results: Result[];
27
27
  errors: unknown[];
28
28
  }>;
29
+ /**
30
+ * Fails the running test or hook with an error thrown outside of it, like
31
+ * from a timer it started. Returns false when nothing is running.
32
+ */
33
+ fail(error: unknown): boolean;
29
34
  /** Whether a test runs: not skipped, focused when others are, matching the name pattern. */
30
35
  runs(test: Test): boolean;
31
36
  }
@@ -1,3 +1,4 @@
1
+ import { type Loader } from "esbuild";
1
2
  /**
2
3
  * Compiles a test file and the local files it imports with esbuild, into one
3
4
  * module Node can import. Installed packages stay external, and the globals
@@ -9,9 +10,16 @@ export default class Transformer {
9
10
  static readonly modules: string[];
10
11
  /** Where compiled test files go, stack frames there are testero's own. */
11
12
  static readonly prefix: string;
12
- constructor();
13
+ /** The code of each compiled module by its path, with an inline source map, for coverage. */
14
+ readonly bundles: Map<string, string>;
15
+ /** Keeps the code of the compiled modules in `bundles` when told. */
16
+ constructor(keep?: boolean);
13
17
  /** Bundles a test file, returns the URL of the module to import. */
14
18
  compile(file: string): Promise<string>;
19
+ /** The absolute paths of the local files a test file is bundled from, itself included. */
20
+ inputs(file: string): Promise<string[]>;
21
+ /** The esbuild loader of a source file, undefined for files it does not compile. */
22
+ static loader(path: string): Loader | undefined;
15
23
  /** Removes the compiled files. */
16
24
  dispose(): void;
17
25
  }
@@ -0,0 +1,52 @@
1
+ /** Test files to run, or all of them. */
2
+ export type Selection = string[] | "all";
3
+ /** A run in progress. */
4
+ export interface Run {
5
+ /** Settles when the run is over, also when it was stopped. */
6
+ done: Promise<unknown>;
7
+ stop(): void;
8
+ }
9
+ export interface WatcherOptions {
10
+ /** Reruns every test file on a change, or only the ones it concerns. */
11
+ mode: "all" | "related";
12
+ /** Starts a run of test files, of all of them when undefined. */
13
+ run: (files: string[] | undefined) => Run;
14
+ /** The test files that changed paths, relative to the root, concern. */
15
+ related: (changed: ReadonlySet<string>) => Promise<string[]>;
16
+ /** Calls back with each changed path relative to the root, returns how to stop. */
17
+ subscribe: (listener: (path: string) => void) => () => void;
18
+ /** Whether a change to a path, relative to the root, is left alone. */
19
+ ignores?: (path: string) => boolean;
20
+ /** Keys, like `a` to run all tests, come from it when given. */
21
+ input?: NodeJS.ReadStream | undefined;
22
+ write?: (text: string) => void;
23
+ /** Clears the screen before each run. */
24
+ clear?: boolean;
25
+ /** Milliseconds to wait for more changes, as saving often writes several files. */
26
+ delay?: number;
27
+ }
28
+ /**
29
+ * Reruns tests when files change. A change during a run stops it, the next
30
+ * run takes its files too.
31
+ */
32
+ export default class Watcher {
33
+ #private;
34
+ constructor(options: WatcherOptions);
35
+ /** Runs all tests, then watches. */
36
+ start(): void;
37
+ /** Stops watching and the run in progress. */
38
+ close(): void;
39
+ /** Two selections in one, all when either is. */
40
+ static merge(a: Selection | undefined, b: Selection): Selection;
41
+ }
42
+ /**
43
+ * Which test files changed paths concern: changed ones, and the ones bundled
44
+ * from a changed file. The files of each test are remembered until one of
45
+ * them changes; a test file that does not compile always counts.
46
+ */
47
+ export declare class Dependencies {
48
+ #private;
49
+ /** `list` gives the files a test file is bundled from, all relative to the root. */
50
+ constructor(list: (file: string) => Promise<string[]>);
51
+ related(tests: string[], changed: ReadonlySet<string>): Promise<string[]>;
52
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aljazmc/testero",
3
- "version": "0.4.2",
3
+ "version": "0.5.0",
4
4
  "description": "A simple, Jest-like test runner for JavaScript, TypeScript and JSX, compiling tests with esbuild. Easy to understand, easy to customize and easy to extend.",
5
5
  "author": "aljazmc",
6
6
  "license": "MIT",
@@ -35,11 +35,10 @@
35
35
  "./package.json": "./package.json"
36
36
  },
37
37
  "devDependencies": {
38
- "@jest/globals": "^30.5.2",
39
38
  "@types/node": "^26.6.6"
40
39
  },
41
40
  "dependencies": {
42
- "@aljazmc/config": "^0.3.1",
41
+ "@aljazmc/config": "^0.3.2",
43
42
  "esbuild": "0.28.2"
44
43
  }
45
44
  }