@jterrazz/test 17.0.0 → 18.0.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.
Files changed (53) hide show
  1. package/dist/browser/index.js +1 -2
  2. package/dist/browser/services.js +1 -2
  3. package/dist/browser/stubs.js +1 -2
  4. package/dist/{shared-index.browser.js → browser-shared-index.browser.js} +82 -40
  5. package/dist/checker.js +15 -824
  6. package/dist/in-place.global-setup.d.ts +1 -0
  7. package/dist/in-place.global-setup.js +1 -1
  8. package/dist/index.d.ts +2 -14
  9. package/dist/index.js +83 -204
  10. package/dist/mobile-session.global-setup.d.ts +1 -0
  11. package/dist/oxlint.cjs +2 -2
  12. package/dist/oxlint.js +67 -2321
  13. package/dist/route-coverage.global-setup.d.ts +1 -0
  14. package/dist/route-coverage.global-setup.js +1 -2
  15. package/dist/services.global-setup.d.ts +1 -1
  16. package/dist/services.global-setup.js +1 -2
  17. package/dist/services.js +1 -1
  18. package/dist/shared-appium.adapter.js +14 -14
  19. package/dist/shared-artifacts.js +7 -5
  20. package/dist/shared-derived-projects.js +23 -8
  21. package/dist/shared-in-place.js +1 -1
  22. package/dist/shared-ledger.js +1 -1
  23. package/dist/shared-listened-port.js +19 -0
  24. package/dist/shared-literate-plugin.js +2 -1
  25. package/dist/shared-pause.js +12 -1
  26. package/dist/shared-playwright.adapter.js +17 -19
  27. package/dist/shared-process-alive.js +13 -0
  28. package/dist/shared-record-key.js +13 -0
  29. package/dist/shared-serve.js +107 -65
  30. package/dist/shared-services.global-setup.js +4 -9
  31. package/dist/shared-session-ledger.js +10 -6
  32. package/dist/shared-spec-document.js +2 -64
  33. package/dist/shared-spec-grammar.js +66 -0
  34. package/dist/shared-specs-modules.js +1033 -0
  35. package/dist/{shared-stream-body.js → shared-stub-reply.js} +40 -3
  36. package/dist/shared-stub-server.js +30 -78
  37. package/dist/shared-temp-root.global-setup.js +3 -10
  38. package/dist/shared-testcontainers.adapter.js +111 -8
  39. package/dist/temp-root.global-setup.js +1 -2
  40. package/dist/vitest.d.ts +17 -22
  41. package/dist/vitest.js +37 -53
  42. package/docs/concepts/architecture.md +20 -20
  43. package/docs/concepts/conventions.md +2 -2
  44. package/docs/guides/cli-specs.md +2 -0
  45. package/docs/guides/develop.md +20 -17
  46. package/docs/guides/mobile-specs.md +3 -3
  47. package/docs/guides/release.md +4 -3
  48. package/docs/guides/website-specs.md +1 -1
  49. package/docs/reference/linting.md +2 -2
  50. package/docs/reference/services.md +9 -9
  51. package/docs/reference/stubs.md +4 -2
  52. package/docs/start/set-up-a-project.md +31 -17
  53. package/package.json +10 -10
@@ -1,8 +1,9 @@
1
1
  import { n as refusal } from "./shared-refusal.js";
2
- import { a as field, i as RunContainers, o as serveContainers, r as TestcontainersAdapter, t as OWNER_LABEL } from "./shared-testcontainers.adapter.js";
2
+ import { a as field, i as RunContainers, o as serveContainers, r as TestcontainersAdapter, s as DOCKER_ABSENT, t as OWNER_LABEL } from "./shared-testcontainers.adapter.js";
3
3
  import { t as loadPeer } from "./shared-peer.js";
4
4
  import { t as SERVICE_IMAGES } from "./shared-service-images.js";
5
5
  import { t as setupEntry } from "./shared-setup-entry.js";
6
+ import { t as processAlive } from "./shared-process-alive.js";
6
7
  import { existsSync, readFileSync } from "node:fs";
7
8
  import { dirname, join } from "node:path";
8
9
  import { hostname } from "node:os";
@@ -15,12 +16,7 @@ function ownerAlive(owner, host = hostname(), probe = (pid) => process.kill(pid,
15
16
  const separator = owner.lastIndexOf(":");
16
17
  const pid = Number(owner.slice(separator + 1));
17
18
  if (separator === -1 || owner.slice(0, separator) !== host || !Number.isSafeInteger(pid) || pid <= 0) return true;
18
- try {
19
- probe(pid);
20
- return true;
21
- } catch (error) {
22
- return Reflect.get(new Object(error), "code") !== "ESRCH";
23
- }
19
+ return processAlive(pid, probe);
24
20
  }
25
21
  function orphans(containers, alive) {
26
22
  const reaped = new Set(containers.filter((container) => container.State === "running" && container.Labels[REAPER_LABEL] === "true").map((reaper) => reaper.Labels[SESSION_LABEL]));
@@ -50,7 +46,6 @@ async function sweepOrphans(runtime, alive = ownerAlive) {
50
46
  //#endregion
51
47
  //#region src/services/containers/services.global-setup.ts
52
48
  /** Every project's setup joins the one run's containers. Default images are pulled in the background, so the first file waits on a pull at most once; a project declaring no service needs no Docker. */
53
- const DOCKER_ABSENT = "no Docker daemon answered";
54
49
  /** `connect` stands in for the runtime's own client lookup, so the refusal is reachable without a daemon to stop. */
55
50
  async function prepareDocker(connect) {
56
51
  const { getContainerRuntimeClient, ImageName } = await loadPeer("testcontainers", "a declared service", async () => await import("testcontainers"));
@@ -174,6 +169,6 @@ async function setup(project, seams = {}) {
174
169
  return joined.leave;
175
170
  }
176
171
  //#endregion
177
- export { setup as i, prepareDocker as n, servicesSetup as r, DOCKER_ABSENT as t };
172
+ export { servicesSetup as n, setup as r, prepareDocker as t };
178
173
 
179
174
  //# sourceMappingURL=shared-services.global-setup.js.map
@@ -1,7 +1,7 @@
1
1
  import { t as ServedProcess } from "./shared-serve.js";
2
2
  import { t as isRecord } from "./shared-json-shape.js";
3
3
  import { n as refusal } from "./shared-refusal.js";
4
- import { l as VITEST_ARTIFACTS_DIR } from "./shared-artifacts.js";
4
+ import { u as VITEST_ARTIFACTS_DIR } from "./shared-artifacts.js";
5
5
  import { existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync } from "node:fs";
6
6
  import { join, resolve } from "node:path";
7
7
  import { execFile } from "node:child_process";
@@ -227,9 +227,13 @@ async function reachAppium({ appium: declared, device }, root, run) {
227
227
  //#region src/specifications/mobile/session/session-ledger.ts
228
228
  const SERVER_CALL_TIMEOUT_MS = 1e4;
229
229
  const MOBILE_SESSIONS_DIR = `${VITEST_ARTIFACTS_DIR}/mobile-sessions`;
230
- function keyOf(serverUrl, requested) {
230
+ function keyOf(serverUrl, requested, worker) {
231
231
  const sorted = Object.entries(requested).toSorted(([a], [b]) => a.localeCompare(b));
232
- return JSON.stringify([serverUrl, sorted]);
232
+ return JSON.stringify([
233
+ serverUrl,
234
+ sorted,
235
+ worker
236
+ ]);
233
237
  }
234
238
  function isEntry(value) {
235
239
  return isRecord(value) && [
@@ -249,13 +253,13 @@ function entries(directory) {
249
253
  const parsed = (name) => JSON.parse(readFileSync(join(directory, name), "utf8"));
250
254
  return entryFiles(directory).map((name) => parsed(name)).filter((entry) => isEntry(entry));
251
255
  }
252
- function sessionLedger(directory) {
256
+ function sessionLedger(directory, worker = process.env.VITEST_POOL_ID ?? "") {
253
257
  return {
254
258
  forget: (sessionId) => {
255
259
  rmSync(join(directory, `${sessionId}.json`), { force: true });
256
260
  },
257
261
  lookup: (serverUrl, requested) => {
258
- const key = keyOf(serverUrl, requested);
262
+ const key = keyOf(serverUrl, requested, worker);
259
263
  return entries(directory).filter((entry) => entry.key === key).map(({ capabilities, serverUrl: url, sessionId }) => ({
260
264
  capabilities,
261
265
  serverUrl: url,
@@ -265,7 +269,7 @@ function sessionLedger(directory) {
265
269
  record: (requested, session) => {
266
270
  const entry = {
267
271
  ...session,
268
- key: keyOf(session.serverUrl, requested)
272
+ key: keyOf(session.serverUrl, requested, worker)
269
273
  };
270
274
  mkdirSync(directory, { recursive: true });
271
275
  writeFileSync(join(directory, `${session.sessionId}.json`), `${JSON.stringify(entry)}\n`);
@@ -1,10 +1,6 @@
1
+ import { a as RUN_KEYS, c as isRelativePath, i as PRESENCE, n as FILE_CONTENT_KEYS, r as FILE_STATES, s as SpecSyntaxError, t as DOCUMENT_KEYS } from "./shared-spec-grammar.js";
1
2
  import { a as isPair, c as nodeItems, f as yamlSyntaxErrors, i as isNode, l as nodePairs, o as isScalar, r as isMap, s as isSeq, u as parseYamlSource } from "./shared-yaml-document.js";
2
3
  import { GROUND_FIXTURES, isGroundFolder } from "@jterrazz/typescript/rules";
3
- //#region lint/kit/project/relative-path.ts
4
- function isRelativePath(value) {
5
- return value.startsWith("./") || value.startsWith("../");
6
- }
7
- //#endregion
8
4
  //#region lint/kit/project/dedent.ts
9
5
  function indentOf(line) {
10
6
  return /^[\t ]*/u.exec(line)?.[0].length ?? 0;
@@ -19,64 +15,6 @@ function dedent(text) {
19
15
  return lines.map((line) => line.slice(common)).join("\n");
20
16
  }
21
17
  //#endregion
22
- //#region lint/kit/project/spec-grammar.ts
23
- const SPEC_EXTENSION = ".spec.yaml";
24
- const DOCUMENT_KEYS = [
25
- "description",
26
- "fixture",
27
- "env",
28
- "serve",
29
- "runs"
30
- ];
31
- const RUN_KEYS = [
32
- "command",
33
- "stdin",
34
- "timeout",
35
- "waitFor",
36
- "exit",
37
- "stdout",
38
- "stderr",
39
- "files"
40
- ];
41
- const FILE_CONTENT_KEYS = ["contains", "equals"];
42
- const FILE_STATES = ["absent", "exists"];
43
- const PRESENCE = {
44
- document: [{
45
- keys: ["description"],
46
- law: "each",
47
- refusal: () => "missing \"description:\": every document is one test, and this is its title"
48
- }, {
49
- keys: ["runs"],
50
- law: "each",
51
- refusal: () => "missing \"runs:\": description and runs are mandatory"
52
- }],
53
- files: [{
54
- keys: FILE_CONTENT_KEYS,
55
- law: "some",
56
- refusal: (path) => `files: ${path} asserts nothing: give it contains: or equals:`
57
- }],
58
- run: [{
59
- keys: ["command", "exit"],
60
- law: "each",
61
- refusal: (_subject, key) => `a run is missing "${key}:": command and exit are mandatory`
62
- }, {
63
- keys: ["waitFor"],
64
- law: "apart",
65
- refusal: () => "waitFor: and stdin: cannot share a run: the pattern is watched on a process nobody closed the input of",
66
- with: "stdin"
67
- }]
68
- };
69
- var SpecSyntaxError = class extends Error {
70
- line;
71
- reason;
72
- constructor(fileName, line, message) {
73
- super(`${fileName}:${line}: ${message}`);
74
- this.line = line;
75
- this.reason = message;
76
- this.name = "SpecSyntaxError";
77
- }
78
- };
79
- //#endregion
80
18
  //#region lint/kit/project/spec-node.ts
81
19
  function fail(context, node, message) {
82
20
  throw new SpecSyntaxError(context.fileName, lineOf(context, node), message);
@@ -360,6 +298,6 @@ function parseSpecDocument(content, fileName) {
360
298
  return readSpecFile(content, fileName).document;
361
299
  }
362
300
  //#endregion
363
- export { scalarString as a, SPEC_EXTENSION as c, isRelativePath as d, readSpecFile as i, SpecSyntaxError as l, documentPaths as n, DOCUMENT_KEYS as o, parseSpecDocument as r, RUN_KEYS as s, assertedStreams as t, dedent as u };
301
+ export { scalarString as a, readSpecFile as i, documentPaths as n, dedent as o, parseSpecDocument as r, assertedStreams as t };
364
302
 
365
303
  //# sourceMappingURL=shared-spec-document.js.map
@@ -0,0 +1,66 @@
1
+ //#region lint/kit/project/relative-path.ts
2
+ function isRelativePath(value) {
3
+ return value.startsWith("./") || value.startsWith("../");
4
+ }
5
+ //#endregion
6
+ //#region lint/kit/project/spec-grammar.ts
7
+ const SPEC_EXTENSION = ".spec.yaml";
8
+ const DOCUMENT_KEYS = [
9
+ "description",
10
+ "fixture",
11
+ "env",
12
+ "serve",
13
+ "runs"
14
+ ];
15
+ const RUN_KEYS = [
16
+ "command",
17
+ "stdin",
18
+ "timeout",
19
+ "waitFor",
20
+ "exit",
21
+ "stdout",
22
+ "stderr",
23
+ "files"
24
+ ];
25
+ const FILE_CONTENT_KEYS = ["contains", "equals"];
26
+ const FILE_STATES = ["absent", "exists"];
27
+ const PRESENCE = {
28
+ document: [{
29
+ keys: ["description"],
30
+ law: "each",
31
+ refusal: () => "missing \"description:\": every document is one test, and this is its title"
32
+ }, {
33
+ keys: ["runs"],
34
+ law: "each",
35
+ refusal: () => "missing \"runs:\": description and runs are mandatory"
36
+ }],
37
+ files: [{
38
+ keys: FILE_CONTENT_KEYS,
39
+ law: "some",
40
+ refusal: (path) => `files: ${path} asserts nothing: give it contains: or equals:`
41
+ }],
42
+ run: [{
43
+ keys: ["command", "exit"],
44
+ law: "each",
45
+ refusal: (_subject, key) => `a run is missing "${key}:": command and exit are mandatory`
46
+ }, {
47
+ keys: ["waitFor"],
48
+ law: "apart",
49
+ refusal: () => "waitFor: and stdin: cannot share a run: the pattern is watched on a process nobody closed the input of",
50
+ with: "stdin"
51
+ }]
52
+ };
53
+ var SpecSyntaxError = class extends Error {
54
+ line;
55
+ reason;
56
+ constructor(fileName, line, message) {
57
+ super(`${fileName}:${line}: ${message}`);
58
+ this.line = line;
59
+ this.reason = message;
60
+ this.name = "SpecSyntaxError";
61
+ }
62
+ };
63
+ //#endregion
64
+ export { RUN_KEYS as a, isRelativePath as c, PRESENCE as i, FILE_CONTENT_KEYS as n, SPEC_EXTENSION as o, FILE_STATES as r, SpecSyntaxError as s, DOCUMENT_KEYS as t };
65
+
66
+ //# sourceMappingURL=shared-spec-grammar.js.map