@c9up/helix 0.1.8 → 0.1.10

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 (123) hide show
  1. package/README.md +274 -5
  2. package/bin/helix.js +312 -13
  3. package/dist/cli/failed-cache.d.ts +27 -0
  4. package/dist/cli/failed-cache.d.ts.map +1 -0
  5. package/dist/cli/failed-cache.js +64 -0
  6. package/dist/cli/failed-cache.js.map +1 -0
  7. package/dist/cli/glob.d.ts +36 -0
  8. package/dist/cli/glob.d.ts.map +1 -0
  9. package/dist/cli/glob.js +193 -0
  10. package/dist/cli/glob.js.map +1 -0
  11. package/dist/cli/native.d.ts +4 -0
  12. package/dist/cli/native.d.ts.map +1 -1
  13. package/dist/cli/native.js.map +1 -1
  14. package/dist/cli/pool.d.ts +11 -0
  15. package/dist/cli/pool.d.ts.map +1 -1
  16. package/dist/cli/pool.js +13 -7
  17. package/dist/cli/pool.js.map +1 -1
  18. package/dist/cli/reporter.d.ts +11 -0
  19. package/dist/cli/reporter.d.ts.map +1 -1
  20. package/dist/cli/reporter.js +53 -0
  21. package/dist/cli/reporter.js.map +1 -1
  22. package/dist/cli/run.d.ts +41 -0
  23. package/dist/cli/run.d.ts.map +1 -1
  24. package/dist/cli/run.js +181 -21
  25. package/dist/cli/run.js.map +1 -1
  26. package/dist/cli/runner.d.ts +19 -0
  27. package/dist/cli/runner.d.ts.map +1 -0
  28. package/dist/cli/runner.js +15 -0
  29. package/dist/cli/runner.js.map +1 -0
  30. package/dist/cli/suites.d.ts +102 -0
  31. package/dist/cli/suites.d.ts.map +1 -0
  32. package/dist/cli/suites.js +226 -0
  33. package/dist/cli/suites.js.map +1 -0
  34. package/dist/index.d.ts +10 -9
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +9 -8
  37. package/dist/index.js.map +1 -1
  38. package/dist/japa/core.d.ts +106 -0
  39. package/dist/japa/core.d.ts.map +1 -0
  40. package/dist/japa/core.js +128 -0
  41. package/dist/japa/core.js.map +1 -0
  42. package/dist/runtime/assert.d.ts +174 -0
  43. package/dist/runtime/assert.d.ts.map +1 -0
  44. package/dist/runtime/assert.js +591 -0
  45. package/dist/runtime/assert.js.map +1 -0
  46. package/dist/runtime/asymmetric-brand.d.ts +20 -0
  47. package/dist/runtime/asymmetric-brand.d.ts.map +1 -0
  48. package/dist/runtime/asymmetric-brand.js +18 -0
  49. package/dist/runtime/asymmetric-brand.js.map +1 -0
  50. package/dist/runtime/asymmetric.d.ts +2 -10
  51. package/dist/runtime/asymmetric.d.ts.map +1 -1
  52. package/dist/runtime/asymmetric.js +3 -7
  53. package/dist/runtime/asymmetric.js.map +1 -1
  54. package/dist/runtime/bootstrap.d.ts +47 -0
  55. package/dist/runtime/bootstrap.d.ts.map +1 -0
  56. package/dist/runtime/bootstrap.js +166 -0
  57. package/dist/runtime/bootstrap.js.map +1 -0
  58. package/dist/runtime/cli-args.d.ts +77 -0
  59. package/dist/runtime/cli-args.d.ts.map +1 -0
  60. package/dist/runtime/cli-args.js +85 -0
  61. package/dist/runtime/cli-args.js.map +1 -0
  62. package/dist/runtime/cli-worker.js +1 -2
  63. package/dist/runtime/cli-worker.js.map +1 -1
  64. package/dist/runtime/configure.d.ts +214 -0
  65. package/dist/runtime/configure.d.ts.map +1 -0
  66. package/dist/runtime/configure.js +164 -0
  67. package/dist/runtime/configure.js.map +1 -0
  68. package/dist/runtime/context.d.ts +84 -0
  69. package/dist/runtime/context.d.ts.map +1 -0
  70. package/dist/runtime/context.js +146 -0
  71. package/dist/runtime/context.js.map +1 -0
  72. package/dist/runtime/emitter.d.ts +141 -0
  73. package/dist/runtime/emitter.d.ts.map +1 -0
  74. package/dist/runtime/emitter.js +79 -0
  75. package/dist/runtime/emitter.js.map +1 -0
  76. package/dist/runtime/equals.d.ts.map +1 -1
  77. package/dist/runtime/equals.js +6 -10
  78. package/dist/runtime/equals.js.map +1 -1
  79. package/dist/runtime/global-hooks.d.ts +31 -0
  80. package/dist/runtime/global-hooks.d.ts.map +1 -0
  81. package/dist/runtime/global-hooks.js +126 -0
  82. package/dist/runtime/global-hooks.js.map +1 -0
  83. package/dist/runtime/index.d.ts +14 -3
  84. package/dist/runtime/index.d.ts.map +1 -1
  85. package/dist/runtime/index.js +7 -2
  86. package/dist/runtime/index.js.map +1 -1
  87. package/dist/runtime/ipc-protocol.d.ts +21 -0
  88. package/dist/runtime/ipc-protocol.d.ts.map +1 -0
  89. package/dist/runtime/ipc-protocol.js +21 -0
  90. package/dist/runtime/ipc-protocol.js.map +1 -0
  91. package/dist/runtime/run.d.ts +49 -2
  92. package/dist/runtime/run.d.ts.map +1 -1
  93. package/dist/runtime/run.js +618 -94
  94. package/dist/runtime/run.js.map +1 -1
  95. package/dist/runtime/runner.d.ts +97 -0
  96. package/dist/runtime/runner.d.ts.map +1 -0
  97. package/dist/runtime/runner.js +160 -0
  98. package/dist/runtime/runner.js.map +1 -0
  99. package/dist/runtime/suite-config.d.ts +23 -0
  100. package/dist/runtime/suite-config.d.ts.map +1 -0
  101. package/dist/runtime/suite-config.js +52 -0
  102. package/dist/runtime/suite-config.js.map +1 -0
  103. package/dist/runtime/suite-taps.d.ts +122 -0
  104. package/dist/runtime/suite-taps.d.ts.map +1 -0
  105. package/dist/runtime/suite-taps.js +218 -0
  106. package/dist/runtime/suite-taps.js.map +1 -0
  107. package/dist/runtime/suite.d.ts +277 -8
  108. package/dist/runtime/suite.d.ts.map +1 -1
  109. package/dist/runtime/suite.js +255 -4
  110. package/dist/runtime/suite.js.map +1 -1
  111. package/dist/runtime/test-context.d.ts +50 -3
  112. package/dist/runtime/test-context.d.ts.map +1 -1
  113. package/dist/runtime/test-context.js +83 -5
  114. package/dist/runtime/test-context.js.map +1 -1
  115. package/dist/runtime/worker.d.ts.map +1 -1
  116. package/dist/runtime/worker.js +86 -29
  117. package/dist/runtime/worker.js.map +1 -1
  118. package/index.darwin-arm64.node +0 -0
  119. package/index.darwin-x64.node +0 -0
  120. package/index.linux-arm64-gnu.node +0 -0
  121. package/index.linux-x64-gnu.node +0 -0
  122. package/index.win32-x64-msvc.node +0 -0
  123. package/package.json +8 -1
@@ -0,0 +1,226 @@
1
+ /**
2
+ * Named test suites — helix's equivalent of the `tests` block AdonisJS puts in
3
+ * `adonisrc.ts`, so `helix test unit` runs a suite rather than a path. The
4
+ * SHAPE is Adonis's (`timeout`, `forceExit`, `suites[{ name, files, timeout }]`)
5
+ * and the glob syntax is portable verbatim, but the file read is
6
+ * `helix.config.*`: helix is framework-agnostic, and `adonisrc.ts` belongs to
7
+ * the framework that owns it — in Adonis it is `@adonisjs/core`, not Japa, that
8
+ * reads the file and hands the suites to the runner.
9
+ *
10
+ * // helix.config.ts
11
+ * export default {
12
+ * timeout: 2_000,
13
+ * suites: [
14
+ * { name: "unit", files: ["tests/unit/**​/*.spec.(js|ts)"] },
15
+ * { name: "functional", files: ["tests/functional"], timeout: 30_000 },
16
+ * ],
17
+ * }
18
+ *
19
+ * A suite's `files` are plain paths (a directory is walked with helix's suffix
20
+ * discovery) or globs — including AdonisJS's own defaults, verbatim:
21
+ * `tests/unit/**​/*.spec.(js|ts)`. See `glob.ts` for the compiled subset and the
22
+ * two forms it refuses rather than half-honours.
23
+ */
24
+ import { existsSync, statSync } from "node:fs";
25
+ import path from "node:path";
26
+ import { fileURLToPath, pathToFileURL } from "node:url";
27
+ import { discover } from "./discover.js";
28
+ import { globBaseDir, globRejection, globToRegExp, isGlob, isNegated, withoutNegation, } from "./glob.js";
29
+ /** Config file names probed at the project root, in order. */
30
+ const CONFIG_FILENAMES = [
31
+ "helix.config.ts",
32
+ "helix.config.js",
33
+ "helix.config.mjs",
34
+ ];
35
+ /** Narrow an imported module's default export to a {@link HelixConfig}. */
36
+ function toConfig(imported) {
37
+ const source = imported !== null && typeof imported === "object"
38
+ ? (Reflect.get(imported, "default") ?? imported)
39
+ : imported;
40
+ if (source === null || typeof source !== "object")
41
+ return {};
42
+ const rawBootstrap = Reflect.get(source, "bootstrap");
43
+ const bootstrap = typeof rawBootstrap === "string" ? rawBootstrap : undefined;
44
+ const rawTimeout = Reflect.get(source, "timeout");
45
+ const timeout = typeof rawTimeout === "number" ? rawTimeout : undefined;
46
+ const forceExit = Reflect.get(source, "forceExit") === true ? true : undefined;
47
+ const japaPlugins = Reflect.get(source, "japaPlugins") === true ? true : undefined;
48
+ const runner = { bootstrap, timeout, forceExit, japaPlugins };
49
+ const suites = Reflect.get(source, "suites");
50
+ if (!Array.isArray(suites))
51
+ return runner;
52
+ const parsed = [];
53
+ for (const entry of suites) {
54
+ if (entry === null || typeof entry !== "object")
55
+ continue;
56
+ const name = Reflect.get(entry, "name");
57
+ const files = toSuiteFiles(Reflect.get(entry, "files"));
58
+ if (typeof name !== "string" || files === undefined)
59
+ continue;
60
+ const timeout = Reflect.get(entry, "timeout");
61
+ const retries = Reflect.get(entry, "retries");
62
+ const configure = Reflect.get(entry, "configure");
63
+ parsed.push({
64
+ name,
65
+ files,
66
+ timeout: typeof timeout === "number" ? timeout : undefined,
67
+ retries: typeof retries === "number" ? retries : undefined,
68
+ configure: typeof configure === "function"
69
+ ? (suite) => {
70
+ configure(suite);
71
+ }
72
+ : undefined,
73
+ });
74
+ }
75
+ return { ...runner, suites: parsed };
76
+ }
77
+ /** Narrow a declared `files` value to one of Japa's three accepted forms. */
78
+ function toSuiteFiles(value) {
79
+ if (typeof value === "string")
80
+ return value;
81
+ if (typeof value === "function") {
82
+ return () => {
83
+ const produced = value();
84
+ return normaliseUrls(produced);
85
+ };
86
+ }
87
+ if (Array.isArray(value)) {
88
+ return value.filter((entry) => typeof entry === "string");
89
+ }
90
+ return undefined;
91
+ }
92
+ /** A files-callback's return value, awaited and reduced to the URLs in it. */
93
+ async function normaliseUrls(produced) {
94
+ const resolved = await produced;
95
+ if (!Array.isArray(resolved))
96
+ return [];
97
+ return resolved.filter((entry) => entry instanceof URL);
98
+ }
99
+ /**
100
+ * Load `helix.config.*` from `root`, or `{}` when there is none. A config that
101
+ * throws on import is a hard error — silently ignoring it would run the wrong
102
+ * set of tests.
103
+ */
104
+ export async function loadHelixConfig(root) {
105
+ const file = resolveHelixConfig(root);
106
+ if (file === undefined)
107
+ return {};
108
+ const imported = await import(pathToFileURL(file).href);
109
+ return toConfig(imported);
110
+ }
111
+ /**
112
+ * The config file helix would load, or `undefined` when there is none. Exposed
113
+ * because a `suites[].configure` callback has to be re-imported in the worker —
114
+ * a function does not cross a process boundary.
115
+ */
116
+ export function resolveHelixConfig(root) {
117
+ for (const name of CONFIG_FILENAMES) {
118
+ const candidate = path.join(root, name);
119
+ if (existsSync(candidate))
120
+ return candidate;
121
+ }
122
+ return undefined;
123
+ }
124
+ /**
125
+ * Extensions a pattern entry is allowed to select. The GLOB decides which files
126
+ * belong to the suite, so the walk only has to stop at things that could not be
127
+ * a module — `--include`, which constrains path-mode discovery, does not apply.
128
+ */
129
+ const GLOB_EXTENSIONS = [".ts", ".tsx", ".js", ".mjs", ".cjs"];
130
+ /** `path.relative` output, normalised to the `/` separators a glob speaks. */
131
+ function toPosix(relative) {
132
+ return relative.split(path.sep).join("/");
133
+ }
134
+ /** Every file a pattern entry selects, walked from its wildcard-free prefix. */
135
+ async function resolveGlobEntry(entry, suiteName, root, discovery) {
136
+ const rejection = globRejection(entry);
137
+ if (rejection !== undefined) {
138
+ process.stderr.write(`helix: suite "${suiteName}": ${entry}: ${rejection}\n`);
139
+ return [];
140
+ }
141
+ const base = globBaseDir(entry);
142
+ const absBase = path.isAbsolute(base) ? base : path.resolve(root, base);
143
+ if (!existsSync(absBase)) {
144
+ process.stderr.write(`helix: suite "${suiteName}": path not found: ${entry}\n`);
145
+ return [];
146
+ }
147
+ const pattern = globToRegExp(entry);
148
+ const candidates = await discover(absBase, {
149
+ ...discovery,
150
+ suffixes: GLOB_EXTENSIONS,
151
+ });
152
+ return candidates.filter((file) => pattern.test(toPosix(path.relative(root, file))));
153
+ }
154
+ /**
155
+ * Resolve a suite's `files` into absolute test file paths. A plain path is a
156
+ * directory to walk (helix's suffix discovery) or a file; anything with a
157
+ * pattern character goes through the glob matcher, so AdonisJS's own
158
+ * `tests/unit/**​/*.spec.(js|ts)` ports over verbatim. A `!pattern` entry
159
+ * subtracts from what the others selected.
160
+ */
161
+ export async function resolveSuiteFiles(suite, root, discovery) {
162
+ // A callback picks the files itself (Japa `TestFiles`); there is no pattern
163
+ // to compile and nothing to exclude, so it short-circuits the whole loop.
164
+ if (typeof suite.files === "function") {
165
+ return [...new Set((await suite.files()).map((url) => fileURLToPath(url)))];
166
+ }
167
+ const entries = typeof suite.files === "string" ? [suite.files] : suite.files;
168
+ const out = [];
169
+ // `!pattern` entries subtract from whatever the selecting entries gathered,
170
+ // so they are applied once at the end regardless of where they were written.
171
+ const excluded = [];
172
+ for (const entry of entries) {
173
+ if (isNegated(entry)) {
174
+ const pattern = withoutNegation(entry);
175
+ const rejection = globRejection(pattern);
176
+ if (rejection !== undefined) {
177
+ process.stderr.write(`helix: suite "${suite.name}": ${entry}: ${rejection}\n`);
178
+ continue;
179
+ }
180
+ excluded.push(globToRegExp(pattern));
181
+ continue;
182
+ }
183
+ if (isGlob(entry)) {
184
+ out.push(...(await resolveGlobEntry(entry, suite.name, root, discovery)));
185
+ continue;
186
+ }
187
+ const abs = path.isAbsolute(entry) ? entry : path.resolve(root, entry);
188
+ if (!existsSync(abs)) {
189
+ process.stderr.write(`helix: suite "${suite.name}": path not found: ${entry}\n`);
190
+ continue;
191
+ }
192
+ if (statSync(abs).isDirectory()) {
193
+ out.push(...(await discover(abs, discovery)));
194
+ continue;
195
+ }
196
+ out.push(abs);
197
+ }
198
+ // A file listed by two entries runs once.
199
+ const selected = [...new Set(out)];
200
+ if (excluded.length === 0)
201
+ return selected;
202
+ return selected.filter((file) => {
203
+ const relative = toPosix(path.relative(root, file));
204
+ return !excluded.some((pattern) => pattern.test(relative));
205
+ });
206
+ }
207
+ /**
208
+ * Pick the suites named on the command line. Returns `undefined` when the
209
+ * positionals are NOT suite names — the caller then treats them as paths, which
210
+ * is what every helix project without a config file does.
211
+ */
212
+ export function selectSuites(config, positionals) {
213
+ const suites = config.suites ?? [];
214
+ if (suites.length === 0)
215
+ return undefined;
216
+ // No positionals: Adonis runs every configured suite.
217
+ if (positionals.length === 0)
218
+ return suites;
219
+ const byName = new Map(suites.map((s) => [s.name, s]));
220
+ const selected = positionals.map((p) => byName.get(p));
221
+ // All-or-nothing: a mix of suite names and paths is a typo, not a feature.
222
+ if (selected.some((s) => s === undefined))
223
+ return undefined;
224
+ return selected.filter((s) => s !== undefined);
225
+ }
226
+ //# sourceMappingURL=suites.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"suites.js","sourceRoot":"","sources":["../../src/cli/suites.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -5,16 +5,17 @@
5
5
  * spies/lifecycle), the container facade, and time-travel — none of which import
6
6
  * an ecosystem package. It is fully agnostic: usable in any project.
7
7
  *
8
- * Per-package test fakes/helpers live in EACH package's own `/testing` subpath
9
- * (a package owns its test surface, not helix): `@c9up/ream/testing`
10
- * (TestClient, FakeBus, assertEmitted), `@c9up/atlas/testing` (factory,
11
- * useTransaction), `@c9up/rover/testing` (FakeMail), `@c9up/bay/testing`
12
- * (FakeQueue), `@c9up/spectrum/testing` (FakeLogger), `@c9up/nova/testing`
13
- * (FakeNova), `@c9up/relay/testing` (FakeRelay), `@c9up/archive/testing`
14
- * (FakeStorage). Install a package → you get its testing surface.
8
+ * Capabilities ship as PLUGINS (the Japa/AdonisJS topology): each package's
9
+ * `/testing` subpath exports plugins that extend the injected test context via
10
+ * `configure({ plugins: [...] })` `@c9up/ream/testing` (apiClient → `client`,
11
+ * FakeBus), `@c9up/atlas/testing` (factory, useTransaction, db), `@c9up/rover/
12
+ * testing` (FakeMail), `@c9up/bay/testing` (FakeQueue), `@c9up/spectrum/testing`
13
+ * (FakeLogger), `@c9up/nova/testing` (FakeNova), `@c9up/relay/testing`
14
+ * (FakeRelay), `@c9up/archive/testing` (FakeStorage). The plugins depend on
15
+ * helix, never the other way round — the core stays agnostic.
15
16
  */
16
17
  export * from "./container/index.js";
17
- export type { Assertion, AsymmetricMatcher, CleanupFn, ExpectStatic, FileResult, Hook, HookFn, HookType, MatcherName, MatcherResult, Spy, SuiteResult, TestHandle, TestOptions, TestResult, Vi, } from "./runtime/index.js";
18
- export { AssertionError, afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, onTestFailed, onTestFinished, test, vi, } from "./runtime/index.js";
18
+ export type { Assert, Assertion, AsymmetricMatcher, CLIArgs, CleanupFn, ConfigureOptions, DatasetHandle, DatasetSource, DoneFn, EmittedDataset, EmittedError, EmittedTitle, ErrorPhase, EventHandler, ExpectStatic, FileResult, Group, GroupEndNode, GroupInstance, GroupStartNode, Hook, HookFn, HookType, MatcherName, MatcherResult, Plugin, PluginApi, PluginContext, RunnerEndNode, RunnerEvents, RunnerHook, RunnerStartNode, RunnerSummary, Spy, SuiteEndNode, SuiteResult, SuiteStartNode, SummaryAggregates, TapHandle, TapOptions, TestEndNode, TestHandle, TestInstance, TestOptions, TestResult, TestStartNode, Vi, } from "./runtime/index.js";
19
+ export { AssertionError, afterAll, afterEach, beforeAll, beforeEach, buildTestContext, configure, createAssert, describe, drainRunnerTeardowns, Emitter, emitter, expect, getActiveTest, getActiveTestOrFail, it, onTestFailed, onTestFinished, Runner, Test, TestContext, TestContextRegistry, test, vi, } from "./runtime/index.js";
19
20
  export * as time from "./time/index.js";
20
21
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,cAAc,sBAAsB,CAAC;AACrC,YAAY,EACX,SAAS,EACT,iBAAiB,EACjB,SAAS,EACT,YAAY,EACZ,UAAU,EACV,IAAI,EACJ,MAAM,EACN,QAAQ,EACR,WAAW,EACX,aAAa,EACb,GAAG,EACH,WAAW,EACX,UAAU,EACV,WAAW,EACX,UAAU,EACV,EAAE,GACF,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACN,cAAc,EACd,QAAQ,EACR,SAAS,EACT,SAAS,EACT,UAAU,EACV,QAAQ,EACR,MAAM,EACN,EAAE,EACF,YAAY,EACZ,cAAc,EACd,IAAI,EACJ,EAAE,GACF,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,cAAc,sBAAsB,CAAC;AACrC,YAAY,EACX,MAAM,EACN,SAAS,EACT,iBAAiB,EACjB,OAAO,EACP,SAAS,EACT,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,MAAM,EACN,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,KAAK,EACL,YAAY,EACZ,aAAa,EACb,cAAc,EACd,IAAI,EACJ,MAAM,EACN,QAAQ,EACR,WAAW,EACX,aAAa,EACb,MAAM,EACN,SAAS,EACT,aAAa,EACb,aAAa,EACb,YAAY,EACZ,UAAU,EACV,eAAe,EACf,aAAa,EACb,GAAG,EACH,YAAY,EACZ,WAAW,EACX,cAAc,EACd,iBAAiB,EACjB,SAAS,EACT,UAAU,EACV,WAAW,EACX,UAAU,EACV,YAAY,EACZ,WAAW,EACX,UAAU,EACV,aAAa,EACb,EAAE,GACF,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACN,cAAc,EACd,QAAQ,EACR,SAAS,EACT,SAAS,EACT,UAAU,EACV,gBAAgB,EAChB,SAAS,EACT,YAAY,EACZ,QAAQ,EACR,oBAAoB,EACpB,OAAO,EACP,OAAO,EACP,MAAM,EACN,aAAa,EACb,mBAAmB,EACnB,EAAE,EACF,YAAY,EACZ,cAAc,EACd,MAAM,EACN,IAAI,EACJ,WAAW,EACX,mBAAmB,EACnB,IAAI,EACJ,EAAE,GACF,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAC"}
package/dist/index.js CHANGED
@@ -5,15 +5,16 @@
5
5
  * spies/lifecycle), the container facade, and time-travel — none of which import
6
6
  * an ecosystem package. It is fully agnostic: usable in any project.
7
7
  *
8
- * Per-package test fakes/helpers live in EACH package's own `/testing` subpath
9
- * (a package owns its test surface, not helix): `@c9up/ream/testing`
10
- * (TestClient, FakeBus, assertEmitted), `@c9up/atlas/testing` (factory,
11
- * useTransaction), `@c9up/rover/testing` (FakeMail), `@c9up/bay/testing`
12
- * (FakeQueue), `@c9up/spectrum/testing` (FakeLogger), `@c9up/nova/testing`
13
- * (FakeNova), `@c9up/relay/testing` (FakeRelay), `@c9up/archive/testing`
14
- * (FakeStorage). Install a package → you get its testing surface.
8
+ * Capabilities ship as PLUGINS (the Japa/AdonisJS topology): each package's
9
+ * `/testing` subpath exports plugins that extend the injected test context via
10
+ * `configure({ plugins: [...] })` `@c9up/ream/testing` (apiClient → `client`,
11
+ * FakeBus), `@c9up/atlas/testing` (factory, useTransaction, db), `@c9up/rover/
12
+ * testing` (FakeMail), `@c9up/bay/testing` (FakeQueue), `@c9up/spectrum/testing`
13
+ * (FakeLogger), `@c9up/nova/testing` (FakeNova), `@c9up/relay/testing`
14
+ * (FakeRelay), `@c9up/archive/testing` (FakeStorage). The plugins depend on
15
+ * helix, never the other way round — the core stays agnostic.
15
16
  */
16
17
  export * from "./container/index.js";
17
- export { AssertionError, afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, onTestFailed, onTestFinished, test, vi, } from "./runtime/index.js";
18
+ export { AssertionError, afterAll, afterEach, beforeAll, beforeEach, buildTestContext, configure, createAssert, describe, drainRunnerTeardowns, Emitter, emitter, expect, getActiveTest, getActiveTestOrFail, it, onTestFailed, onTestFinished, Runner, Test, TestContext, TestContextRegistry, test, vi, } from "./runtime/index.js";
18
19
  export * as time from "./time/index.js";
19
20
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,cAAc,sBAAsB,CAAC;AAmBrC,OAAO,EACN,cAAc,EACd,QAAQ,EACR,SAAS,EACT,SAAS,EACT,UAAU,EACV,QAAQ,EACR,MAAM,EACN,EAAE,EACF,YAAY,EACZ,cAAc,EACd,IAAI,EACJ,EAAE,GACF,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,cAAc,sBAAsB,CAAC;AAkDrC,OAAO,EACN,cAAc,EACd,QAAQ,EACR,SAAS,EACT,SAAS,EACT,UAAU,EACV,gBAAgB,EAChB,SAAS,EACT,YAAY,EACZ,QAAQ,EACR,oBAAoB,EACpB,OAAO,EACP,OAAO,EACP,MAAM,EACN,aAAa,EACb,mBAAmB,EACnB,EAAE,EACF,YAAY,EACZ,cAAc,EACd,MAAM,EACN,IAAI,EACJ,WAAW,EACX,mBAAmB,EACnB,IAAI,EACJ,EAAE,GACF,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,106 @@
1
+ /**
2
+ * `@japa/runner/core`, as much of it as a PLUGIN touches.
3
+ *
4
+ * An official Japa plugin does not talk to the runner through an interface — it
5
+ * imports the classes and instruments them:
6
+ *
7
+ * import { Test, TestContext } from "@japa/runner/core"
8
+ * TestContext.getter("assert", () => new Assert(), true)
9
+ * Test.executed((test, hasError) => { … })
10
+ *
11
+ * Nothing helix does at runtime can change what that import resolves to, which
12
+ * is why "the API is the same shape" was never enough. What CAN change it is
13
+ * module resolution: `japa-alias.mjs` redirects the specifier to this file, and
14
+ * these two classes forward to helix's own registry. The plugin is then
15
+ * instrumenting helix without knowing it.
16
+ *
17
+ * Deliberately not a reimplementation of Japa's classes: only the STATIC
18
+ * surface a plugin uses is here. Anything else a plugin reached for would be
19
+ * absent rather than wrong, which is the failure mode to prefer.
20
+ */
21
+ import { Emitter } from "../runtime/emitter.js";
22
+ /**
23
+ * `Emitter` is helix's own — same event names, same node shapes, verified by
24
+ * the golden journals. A plugin subscribing through it subscribes to the run.
25
+ */
26
+ export { Emitter };
27
+ /**
28
+ * Japa's `Refiner` — a filter collector. Standalone until something reads it,
29
+ * which is why `configure({ refiner })` is where one becomes load-bearing; this
30
+ * class is what a plugin constructs to put there.
31
+ */
32
+ export declare class Refiner {
33
+ readonly filters: {
34
+ tests: string[];
35
+ groups: string[];
36
+ tags: string[];
37
+ matchAll: boolean;
38
+ };
39
+ add(layer: "tests" | "groups" | "tags", values: string[]): this;
40
+ matchAllTags(toggle?: boolean): this;
41
+ }
42
+ /**
43
+ * Raised by the classes a plugin can IMPORT but not construct.
44
+ *
45
+ * They exist so an import resolves and `instanceof` answers — a helix group is
46
+ * not a Japa `Group`, and `false` is the right answer. Constructing one is what
47
+ * cannot work: helix builds its own tree and drives its own run, so a Japa
48
+ * `Suite` or `Runner` built here would be an object nothing ever looks at.
49
+ */
50
+ export declare class JapaClassNotConstructibleError extends Error {
51
+ constructor(name: string);
52
+ }
53
+ /** Japa's `BaseReporter`. Reporters are the CLI's — see `runner.registerReporter`. */
54
+ export declare class BaseReporter {
55
+ constructor();
56
+ }
57
+ /** Japa's `Group`. helix builds groups from the file's own `describe`/`test`. */
58
+ export declare class Group {
59
+ constructor();
60
+ }
61
+ /** Japa's `Suite`. helix's suites come from the config, one per worker. */
62
+ export declare class Suite {
63
+ constructor();
64
+ }
65
+ /** Japa's `Runner`. The CLI owns execution — see `RunnerNotDrivableError`. */
66
+ export declare class Runner {
67
+ constructor();
68
+ }
69
+ /** What a plugin's `Test.executed` callback receives. */
70
+ export type ExecutedCallback = (test: {
71
+ options: unknown;
72
+ context: unknown;
73
+ }, hasError: boolean) => void | Promise<void>;
74
+ /**
75
+ * Japa's `Test` — the static hooks a plugin registers on it. Instances come
76
+ * from helix's own runtime, so nothing here constructs a test.
77
+ */
78
+ export declare class Test {
79
+ /**
80
+ * Tells the shim apart from the real `@japa/runner/core`. A plugin never
81
+ * needs it; it exists so "which one did this import resolve to?" has an
82
+ * answer, which is a question that costs an afternoon otherwise.
83
+ */
84
+ static readonly isHelixShim = true;
85
+ /** Run after every test of the run (Japa `Test.executed`). */
86
+ static executed(callback: ExecutedCallback): void;
87
+ /** Japa's `Test.macro`, mapped onto helix's context registry. */
88
+ static macro(name: string, value: unknown): void;
89
+ }
90
+ /**
91
+ * Japa's `TestContext` — the registrars a plugin uses to put something on every
92
+ * test's context.
93
+ */
94
+ export declare class TestContext {
95
+ /** @see Test.isHelixShim */
96
+ static readonly isHelixShim = true;
97
+ /**
98
+ * Add a lazily-computed property (Japa `TestContext.getter`). Japa's third
99
+ * argument asks for the value to be cached per context; helix's getters are
100
+ * always cached per context, so it is accepted and has nothing to change.
101
+ */
102
+ static getter(name: string, accumulator: () => unknown, _singleton?: boolean): void;
103
+ /** Add a shared property (Japa `TestContext.macro`). */
104
+ static macro(name: string, value: unknown): void;
105
+ }
106
+ //# sourceMappingURL=core.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../src/japa/core.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAGH,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAGhD;;;GAGG;AACH,OAAO,EAAE,OAAO,EAAE,CAAC;AAEnB;;;;GAIG;AACH,qBAAa,OAAO;IACnB,QAAQ,CAAC,OAAO,EAAE;QACjB,KAAK,EAAE,MAAM,EAAE,CAAC;QAChB,MAAM,EAAE,MAAM,EAAE,CAAC;QACjB,IAAI,EAAE,MAAM,EAAE,CAAC;QACf,QAAQ,EAAE,OAAO,CAAC;KAClB,CAAwD;IAEzD,GAAG,CAAC,KAAK,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI;IAK/D,YAAY,CAAC,MAAM,UAAO,GAAG,IAAI;CAIjC;AAED;;;;;;;GAOG;AACH,qBAAa,8BAA+B,SAAQ,KAAK;gBAC5C,IAAI,EAAE,MAAM;CASxB;AAED,sFAAsF;AACtF,qBAAa,YAAY;;CAIxB;AAED,iFAAiF;AACjF,qBAAa,KAAK;;CAIjB;AAED,2EAA2E;AAC3E,qBAAa,KAAK;;CAIjB;AAED,8EAA8E;AAC9E,qBAAa,MAAM;;CAIlB;AAED,yDAAyD;AACzD,MAAM,MAAM,gBAAgB,GAAG,CAC9B,IAAI,EAAE;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,EAC5C,QAAQ,EAAE,OAAO,KACb,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE1B;;;GAGG;AAEH,qBAAa,IAAI;IAChB;;;;OAIG;IACH,MAAM,CAAC,QAAQ,CAAC,WAAW,QAAQ;IAEnC,8DAA8D;IAC9D,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,GAAG,IAAI;IAIjD,iEAAiE;IACjE,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;CAGhD;AAED;;;GAGG;AAEH,qBAAa,WAAW;IACvB,4BAA4B;IAC5B,MAAM,CAAC,QAAQ,CAAC,WAAW,QAAQ;IAEnC;;;;OAIG;IACH,MAAM,CAAC,MAAM,CACZ,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,OAAO,EAC1B,UAAU,CAAC,EAAE,OAAO,GAClB,IAAI;IAIP,wDAAwD;IACxD,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;CAGhD"}
@@ -0,0 +1,128 @@
1
+ /**
2
+ * `@japa/runner/core`, as much of it as a PLUGIN touches.
3
+ *
4
+ * An official Japa plugin does not talk to the runner through an interface — it
5
+ * imports the classes and instruments them:
6
+ *
7
+ * import { Test, TestContext } from "@japa/runner/core"
8
+ * TestContext.getter("assert", () => new Assert(), true)
9
+ * Test.executed((test, hasError) => { … })
10
+ *
11
+ * Nothing helix does at runtime can change what that import resolves to, which
12
+ * is why "the API is the same shape" was never enough. What CAN change it is
13
+ * module resolution: `japa-alias.mjs` redirects the specifier to this file, and
14
+ * these two classes forward to helix's own registry. The plugin is then
15
+ * instrumenting helix without knowing it.
16
+ *
17
+ * Deliberately not a reimplementation of Japa's classes: only the STATIC
18
+ * surface a plugin uses is here. Anything else a plugin reached for would be
19
+ * absent rather than wrong, which is the failure mode to prefer.
20
+ */
21
+ import { TestContextRegistry } from "../runtime/context.js";
22
+ import { Emitter } from "../runtime/emitter.js";
23
+ import { registerExecutedHook } from "../runtime/test-context.js";
24
+ /**
25
+ * `Emitter` is helix's own — same event names, same node shapes, verified by
26
+ * the golden journals. A plugin subscribing through it subscribes to the run.
27
+ */
28
+ export { Emitter };
29
+ /**
30
+ * Japa's `Refiner` — a filter collector. Standalone until something reads it,
31
+ * which is why `configure({ refiner })` is where one becomes load-bearing; this
32
+ * class is what a plugin constructs to put there.
33
+ */
34
+ export class Refiner {
35
+ filters = { tests: [], groups: [], tags: [], matchAll: false };
36
+ add(layer, values) {
37
+ this.filters[layer].push(...values);
38
+ return this;
39
+ }
40
+ matchAllTags(toggle = true) {
41
+ this.filters.matchAll = toggle;
42
+ return this;
43
+ }
44
+ }
45
+ /**
46
+ * Raised by the classes a plugin can IMPORT but not construct.
47
+ *
48
+ * They exist so an import resolves and `instanceof` answers — a helix group is
49
+ * not a Japa `Group`, and `false` is the right answer. Constructing one is what
50
+ * cannot work: helix builds its own tree and drives its own run, so a Japa
51
+ * `Suite` or `Runner` built here would be an object nothing ever looks at.
52
+ */
53
+ export class JapaClassNotConstructibleError extends Error {
54
+ constructor(name) {
55
+ super(`new ${name}() is not available on helix: it builds its own test tree ` +
56
+ "and drives its own run, so an instance here would be one nothing " +
57
+ `reads. The class exists so \`import { ${name} }\` resolves and ` +
58
+ "`instanceof` answers.");
59
+ this.name = "JapaClassNotConstructibleError";
60
+ }
61
+ }
62
+ /** Japa's `BaseReporter`. Reporters are the CLI's — see `runner.registerReporter`. */
63
+ export class BaseReporter {
64
+ constructor() {
65
+ throw new JapaClassNotConstructibleError("BaseReporter");
66
+ }
67
+ }
68
+ /** Japa's `Group`. helix builds groups from the file's own `describe`/`test`. */
69
+ export class Group {
70
+ constructor() {
71
+ throw new JapaClassNotConstructibleError("Group");
72
+ }
73
+ }
74
+ /** Japa's `Suite`. helix's suites come from the config, one per worker. */
75
+ export class Suite {
76
+ constructor() {
77
+ throw new JapaClassNotConstructibleError("Suite");
78
+ }
79
+ }
80
+ /** Japa's `Runner`. The CLI owns execution — see `RunnerNotDrivableError`. */
81
+ export class Runner {
82
+ constructor() {
83
+ throw new JapaClassNotConstructibleError("Runner");
84
+ }
85
+ }
86
+ /**
87
+ * Japa's `Test` — the static hooks a plugin registers on it. Instances come
88
+ * from helix's own runtime, so nothing here constructs a test.
89
+ */
90
+ // biome-ignore lint/complexity/noStaticOnlyClass: stands in for a class Japa exports — an object literal breaks the day a plugin writes `instanceof` or `extends`, which is the one place being a class is the point.
91
+ export class Test {
92
+ /**
93
+ * Tells the shim apart from the real `@japa/runner/core`. A plugin never
94
+ * needs it; it exists so "which one did this import resolve to?" has an
95
+ * answer, which is a question that costs an afternoon otherwise.
96
+ */
97
+ static isHelixShim = true;
98
+ /** Run after every test of the run (Japa `Test.executed`). */
99
+ static executed(callback) {
100
+ registerExecutedHook(callback);
101
+ }
102
+ /** Japa's `Test.macro`, mapped onto helix's context registry. */
103
+ static macro(name, value) {
104
+ TestContextRegistry.macro(name, value);
105
+ }
106
+ }
107
+ /**
108
+ * Japa's `TestContext` — the registrars a plugin uses to put something on every
109
+ * test's context.
110
+ */
111
+ // biome-ignore lint/complexity/noStaticOnlyClass: same as `Test` above — it replaces an exported class, not a namespace.
112
+ export class TestContext {
113
+ /** @see Test.isHelixShim */
114
+ static isHelixShim = true;
115
+ /**
116
+ * Add a lazily-computed property (Japa `TestContext.getter`). Japa's third
117
+ * argument asks for the value to be cached per context; helix's getters are
118
+ * always cached per context, so it is accepted and has nothing to change.
119
+ */
120
+ static getter(name, accumulator, _singleton) {
121
+ TestContextRegistry.getter(name, () => accumulator());
122
+ }
123
+ /** Add a shared property (Japa `TestContext.macro`). */
124
+ static macro(name, value) {
125
+ TestContextRegistry.macro(name, value);
126
+ }
127
+ }
128
+ //# sourceMappingURL=core.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core.js","sourceRoot":"","sources":["../../src/japa/core.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAElE;;;GAGG;AACH,OAAO,EAAE,OAAO,EAAE,CAAC;AAEnB;;;;GAIG;AACH,MAAM,OAAO,OAAO;IACV,OAAO,GAKZ,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;IAEzD,GAAG,CAAC,KAAkC,EAAE,MAAgB;QACvD,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC;QACpC,OAAO,IAAI,CAAC;IACb,CAAC;IAED,YAAY,CAAC,MAAM,GAAG,IAAI;QACzB,IAAI,CAAC,OAAO,CAAC,QAAQ,GAAG,MAAM,CAAC;QAC/B,OAAO,IAAI,CAAC;IACb,CAAC;CACD;AAED;;;;;;;GAOG;AACH,MAAM,OAAO,8BAA+B,SAAQ,KAAK;IACxD,YAAY,IAAY;QACvB,KAAK,CACJ,OAAO,IAAI,4DAA4D;YACtE,mEAAmE;YACnE,yCAAyC,IAAI,oBAAoB;YACjE,uBAAuB,CACxB,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,gCAAgC,CAAC;IAC9C,CAAC;CACD;AAED,sFAAsF;AACtF,MAAM,OAAO,YAAY;IACxB;QACC,MAAM,IAAI,8BAA8B,CAAC,cAAc,CAAC,CAAC;IAC1D,CAAC;CACD;AAED,iFAAiF;AACjF,MAAM,OAAO,KAAK;IACjB;QACC,MAAM,IAAI,8BAA8B,CAAC,OAAO,CAAC,CAAC;IACnD,CAAC;CACD;AAED,2EAA2E;AAC3E,MAAM,OAAO,KAAK;IACjB;QACC,MAAM,IAAI,8BAA8B,CAAC,OAAO,CAAC,CAAC;IACnD,CAAC;CACD;AAED,8EAA8E;AAC9E,MAAM,OAAO,MAAM;IAClB;QACC,MAAM,IAAI,8BAA8B,CAAC,QAAQ,CAAC,CAAC;IACpD,CAAC;CACD;AAQD;;;GAGG;AACH,sNAAsN;AACtN,MAAM,OAAO,IAAI;IAChB;;;;OAIG;IACH,MAAM,CAAU,WAAW,GAAG,IAAI,CAAC;IAEnC,8DAA8D;IAC9D,MAAM,CAAC,QAAQ,CAAC,QAA0B;QACzC,oBAAoB,CAAC,QAAQ,CAAC,CAAC;IAChC,CAAC;IAED,iEAAiE;IACjE,MAAM,CAAC,KAAK,CAAC,IAAY,EAAE,KAAc;QACxC,mBAAmB,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACxC,CAAC;;AAGF;;;GAGG;AACH,yHAAyH;AACzH,MAAM,OAAO,WAAW;IACvB,4BAA4B;IAC5B,MAAM,CAAU,WAAW,GAAG,IAAI,CAAC;IAEnC;;;;OAIG;IACH,MAAM,CAAC,MAAM,CACZ,IAAY,EACZ,WAA0B,EAC1B,UAAoB;QAEpB,mBAAmB,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;IACvD,CAAC;IAED,wDAAwD;IACxD,MAAM,CAAC,KAAK,CAAC,IAAY,EAAE,KAAc;QACxC,mBAAmB,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACxC,CAAC"}