@matter/testing 0.13.0-alpha.0-20250318-c1aa38b08 → 0.13.0-alpha.0-20250322-f085fa576

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/src/runner.ts CHANGED
@@ -6,7 +6,8 @@
6
6
 
7
7
  import { ansi, Package, Progress, std } from "#tools";
8
8
  import debug from "debug";
9
- import { relative } from "node:path";
9
+ import { readFile } from "node:fs/promises";
10
+ import { dirname, relative, resolve } from "node:path";
10
11
  import { chip } from "./chip/chip.js";
11
12
  import { FailureDetail } from "./failure-detail.js";
12
13
  import { FailureReporter } from "./failure-reporter.js";
@@ -55,15 +56,15 @@ export class TestRunner {
55
56
  }
56
57
 
57
58
  async runNode(format: "esm" | "cjs" = "esm") {
58
- await this.run(this.progress, () => testNodejs(this, format));
59
+ await this.#run(this.progress, () => testNodejs(this, format));
59
60
  }
60
61
 
61
62
  async runWeb(manual = false) {
62
- await this.run(this.progress, () => testWeb(this, manual));
63
+ await this.#run(this.progress, () => testWeb(this, manual));
63
64
  }
64
65
 
65
66
  async loadFiles(format: "esm" | "cjs") {
66
- const tests = [];
67
+ const tests = Array<string>();
67
68
  for (let spec of this.spec) {
68
69
  spec = spec.replace(/\.ts$/, ".js");
69
70
  spec = relative(this.pkg.path, spec);
@@ -74,6 +75,15 @@ export class TestRunner {
74
75
  tests.push(...(await this.pkg.glob(spec)));
75
76
  }
76
77
 
78
+ // Automatically map source files to an appropriate test file
79
+ for (let i = 0; i < tests.length; i++) {
80
+ if (tests[i].indexOf("/src/") === -1) {
81
+ continue;
82
+ }
83
+
84
+ tests[i] = await this.#mapSourceToTest(tests[i]);
85
+ }
86
+
77
87
  if (!tests.length) {
78
88
  fatal(`No files match ${this.spec.join(", ")}`);
79
89
  }
@@ -81,12 +91,84 @@ export class TestRunner {
81
91
  return [...listSupportFiles(format), ...tests];
82
92
  }
83
93
 
84
- private async run(progress: Progress, runner: () => Promise<void>) {
94
+ async #run(progress: Progress, runner: () => Promise<void>) {
85
95
  await runner();
86
96
  if (progress.status !== Progress.Status.Success) {
87
97
  fatal(`Test ${progress.status.toLowerCase()}, aborting`);
88
98
  }
89
99
  }
100
+
101
+ async #mapSourceToTest(filename: string) {
102
+ // First look for special "// matter-test" marker that manually maps to test file
103
+ try {
104
+ const src = await readFile(filename, "utf-8");
105
+ const [, args] = src.match(/\/\/ matter-test (.*)/) ?? [];
106
+ if (args) {
107
+ return this.#parseMarkerArgs(args, filename);
108
+ }
109
+ } catch (e) {
110
+ // Ignore errors as file errors will be handled by Mocha
111
+ }
112
+
113
+ // By default we just map from src directory to test directory
114
+ return filename.replace("/src/", "/test/");
115
+ }
116
+
117
+ #parseMarkerArgs(args: string, filename: string) {
118
+ const parts = args.match(/[a-z]+=(?:"(?:[^"\\]|\\.)+"|[^"]\S+)/g);
119
+ if (!parts) {
120
+ throw new Error("No matter-test parameters detected");
121
+ }
122
+
123
+ let file: string | undefined;
124
+ let module: string | undefined;
125
+ for (const part of parts) {
126
+ const equalPos = part.indexOf("=");
127
+
128
+ const name = part.substring(0, equalPos);
129
+
130
+ let value = part.substring(equalPos + 1);
131
+ if (value[0] === '"') {
132
+ value = value
133
+ .substring(1, value.length - 2)
134
+ .replace(/\\"/g, '"')
135
+ .replace(/\\\\/g, '"');
136
+ }
137
+
138
+ switch (name) {
139
+ case "file":
140
+ file = value;
141
+ break;
142
+
143
+ case "module":
144
+ module = value;
145
+ break;
146
+
147
+ default:
148
+ throw new Error(`Unrecognized matter-test parameter "${name}"`);
149
+ }
150
+ }
151
+
152
+ if (file === undefined) {
153
+ throw new Error(`matter-test parameter "file" is required`);
154
+ }
155
+
156
+ if (file.startsWith("./") || file.startsWith("../")) {
157
+ file = resolve(dirname(filename), file);
158
+ }
159
+
160
+ let testPkg;
161
+ if (module === undefined) {
162
+ testPkg = this.pkg;
163
+ } else {
164
+ testPkg = this.pkg.findPackage(module);
165
+ if (testPkg === undefined) {
166
+ throw new Error(`Unknown matter-test module "${module}"`);
167
+ }
168
+ }
169
+
170
+ return testPkg.resolve("test", file);
171
+ }
90
172
  }
91
173
 
92
174
  function fatal(message: string) {