@isentinel/jest-roblox 0.3.6 → 0.3.8
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/README.md +80 -14
- package/bin/jest-roblox.js +4 -2
- package/dist/cli.d.mts +1 -1
- package/dist/cli.mjs +11 -2
- package/dist/index.d.mts +207 -9
- package/dist/index.mjs +2 -2
- package/dist/{run-C4GuftZH.mjs → run-Cirdb_CB.mjs} +1374 -252
- package/dist/{schema-BCTnsaiC.d.mts → schema-i-pZhLCV.d.mts} +240 -8
- package/loaders/luau-raw.d.mts +4 -4
- package/loaders/luau-raw.mjs +5 -5
- package/package.json +3 -3
- package/plugin/JestRobloxRunner.rbxm +0 -0
- package/plugin/src/init.server.luau +11 -4
- package/plugin/src/test-in-run-mode.server.luau +73 -20
package/README.md
CHANGED
|
@@ -15,10 +15,13 @@ Run your roblox-ts and Luau tests inside Roblox, get results in your terminal.
|
|
|
15
15
|
- roblox-ts and pure Luau
|
|
16
16
|
- Source-mapped errors (Luau line numbers back to `.ts` files)
|
|
17
17
|
- Code coverage (via [Lute](https://github.com/luau-lang/lute) instrumentation)
|
|
18
|
-
-
|
|
18
|
+
- Three backends: Open Cloud (remote), Studio (attached, local), and Studio CLI
|
|
19
|
+
(self-launched headless Studio, local)
|
|
19
20
|
- Multiple output formatters (human, agent, JSON, GitHub Actions)
|
|
20
21
|
|
|
21
|
-
|
|
22
|
+
<!-- prettier-ignore -->
|
|
23
|
+
> [!NOTE]
|
|
24
|
+
> roblox-ts projects currently require
|
|
22
25
|
> [@isentinel/roblox-ts](https://npmx.dev/package/@isentinel/roblox-ts) for
|
|
23
26
|
> source maps and coverage support.
|
|
24
27
|
|
|
@@ -68,6 +71,15 @@ Then run:
|
|
|
68
71
|
jest-roblox
|
|
69
72
|
```
|
|
70
73
|
|
|
74
|
+
<!-- prettier-ignore -->
|
|
75
|
+
> [!NOTE]
|
|
76
|
+
> `projects` is optional. With it omitted, the CLI derives one project per
|
|
77
|
+
> `luauRoots` mount (the compiled-output dirs your Rojo project mounts,
|
|
78
|
+
> auto-detected from your tsconfig `outDir`), generating each project's
|
|
79
|
+
> `jest.config` stub for you. Set `projects` explicitly when you need
|
|
80
|
+
> per-project overrides (a distinct `displayName`, `setupFiles`, `include`,
|
|
81
|
+
> etc.) or a tighter project layout than the luau roots imply.
|
|
82
|
+
|
|
71
83
|
## Usage
|
|
72
84
|
|
|
73
85
|
```bash
|
|
@@ -88,6 +100,7 @@ jest-roblox --testPathPattern="modifiers|define\\.spec|triggers"
|
|
|
88
100
|
# Use a specific backend (default "auto" picks Studio if the plugin is
|
|
89
101
|
# connected, else Open Cloud if credentials are set — see Backends below)
|
|
90
102
|
jest-roblox --backend studio
|
|
103
|
+
jest-roblox --backend studio-cli
|
|
91
104
|
jest-roblox --backend open-cloud
|
|
92
105
|
|
|
93
106
|
# Collect coverage
|
|
@@ -133,7 +146,7 @@ per-package declarations error loudly.
|
|
|
133
146
|
|
|
134
147
|
| Field | What it does | Default |
|
|
135
148
|
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
|
|
136
|
-
| `backend` | `"auto"`, `"open-cloud"`, or `"studio"`
|
|
149
|
+
| `backend` | `"auto"`, `"open-cloud"`, `"studio"`, or `"studio-cli"` | `"auto"` |
|
|
137
150
|
| `color` | Use ANSI colors in console output | `true` |
|
|
138
151
|
| `formatters` | Output formatters (`"default"`, `"agent"`, `"json"`, `"github-actions"`) | `["default"]` |
|
|
139
152
|
| `gameOutput` | Write Game Output to a file — a path, or `true` for `game-output.log` under the root. In `--workspace` mode this is one grouped aggregate file across every package | — |
|
|
@@ -144,6 +157,7 @@ per-package declarations error loudly.
|
|
|
144
157
|
| `placeId` | Open Cloud place ID | — |
|
|
145
158
|
| `port` | WebSocket port for Studio backend | `3001` |
|
|
146
159
|
| `silent` | Suppress console output | `false` |
|
|
160
|
+
| `studioPath` | Roblox Studio executable for the `studio-cli` backend (auto-detected if unset; also `--studioPath` / `JEST_ROBLOX_STUDIO_PATH`) | — |
|
|
147
161
|
| `universeId` | Open Cloud universe ID | — |
|
|
148
162
|
|
|
149
163
|
#### Per-package fields
|
|
@@ -169,7 +183,7 @@ Put these under `test: { ... }`.
|
|
|
169
183
|
|
|
170
184
|
| Field | What it does | Default |
|
|
171
185
|
| ------------------------ | ------------------------------------------------ | ------------------------------------ |
|
|
172
|
-
| `projects` | Where to look for tests in the DataModel |
|
|
186
|
+
| `projects` | Where to look for tests in the DataModel | one project per `luauRoots` mount |
|
|
173
187
|
| `testMatch` | Glob patterns that find test files | `**/*.spec.ts`, `**/*.test.ts`, etc. |
|
|
174
188
|
| `testPathIgnorePatterns` | Patterns to skip | `/node_modules/`, `/dist/`, `/out/` |
|
|
175
189
|
| `setupFiles` | Scripts to run before the test environment loads | — |
|
|
@@ -181,7 +195,9 @@ Put these under `test: { ... }`.
|
|
|
181
195
|
|
|
182
196
|
Put these under `test: { ... }`.
|
|
183
197
|
|
|
184
|
-
|
|
198
|
+
<!-- prettier-ignore -->
|
|
199
|
+
> [!IMPORTANT]
|
|
200
|
+
> Coverage requires [Lute](https://github.com/luau-lang/lute) to be
|
|
185
201
|
> installed and on your `PATH`. Lute parses Luau ASTs so the CLI can insert
|
|
186
202
|
> coverage probes.
|
|
187
203
|
|
|
@@ -194,7 +210,9 @@ Put these under `test: { ... }`.
|
|
|
194
210
|
| `coveragePathIgnorePatterns` | Files to leave out of coverage | test files, `node_modules`, `rbxts_include` |
|
|
195
211
|
| `collectCoverageFrom` | Globs for files to include in coverage | — |
|
|
196
212
|
|
|
197
|
-
|
|
213
|
+
<!-- prettier-ignore -->
|
|
214
|
+
> [!NOTE]
|
|
215
|
+
> Coverage uses vitest `all` / Istanbul semantics: every instrumented
|
|
198
216
|
> file matching the include globs is reported, so a source file with no test
|
|
199
217
|
> shows **0%** (and fails `coverageThreshold`) instead of being silently
|
|
200
218
|
> omitted. When `collectCoverageFrom` is unset for a multi-project run, the
|
|
@@ -258,7 +276,7 @@ export default defineConfig({
|
|
|
258
276
|
|
|
259
277
|
## Backends
|
|
260
278
|
|
|
261
|
-
|
|
279
|
+
Three ways to run tests, plus an auto-pick:
|
|
262
280
|
|
|
263
281
|
### Auto (default)
|
|
264
282
|
|
|
@@ -320,7 +338,9 @@ Connects to Roblox Studio over WebSocket. Faster than Open Cloud (no upload
|
|
|
320
338
|
step), but Studio must be open with the plugin running. Studio doesn't expose
|
|
321
339
|
which place is open, so multiple concurrent projects aren't supported yet.
|
|
322
340
|
|
|
323
|
-
|
|
341
|
+
<!-- prettier-ignore -->
|
|
342
|
+
> [!NOTE]
|
|
343
|
+
> For `--coverage`, prefer `--backend open-cloud` since the coverage
|
|
324
344
|
> output is built to a separate output under `.jest-roblox/coverage/` that is
|
|
325
345
|
> likely not the studio place being served.
|
|
326
346
|
|
|
@@ -332,7 +352,7 @@ Create a file named drillbit.toml in your project's directory.
|
|
|
332
352
|
|
|
333
353
|
```toml
|
|
334
354
|
[plugins.jest_roblox]
|
|
335
|
-
github = "https://github.com/christopher-buss/jest-roblox-cli/releases/download/v0.
|
|
355
|
+
github = "https://github.com/christopher-buss/jest-roblox-cli/releases/download/v0.3.8/JestRobloxRunner.rbxm"
|
|
336
356
|
```
|
|
337
357
|
|
|
338
358
|
Then run `drillbit` and it will download the plugin and install it in Studio for
|
|
@@ -342,12 +362,54 @@ Or download `JestRobloxRunner.rbxm` from the
|
|
|
342
362
|
[latest release](https://github.com/christopher-buss/jest-roblox-cli/releases)
|
|
343
363
|
and drop it into your Studio plugins folder.
|
|
344
364
|
|
|
365
|
+
### Studio CLI (self-launched, local)
|
|
366
|
+
|
|
367
|
+
`--backend studio-cli` owns the whole Studio lifecycle: it builds its own place,
|
|
368
|
+
launches Roblox Studio headless via Studio's `--task RunScript` interface,
|
|
369
|
+
drives the installed plugin's Run mode, reads the result from Studio's output
|
|
370
|
+
log, and quits Studio. No API key, no upload, no pre-opened editor — you just
|
|
371
|
+
need Studio installed (logged in) with the jest plugin. It spawns its own
|
|
372
|
+
isolated Studio instance, so any editor you already have open is untouched.
|
|
373
|
+
|
|
374
|
+
It is selected only when you ask for it explicitly — `auto` never launches a
|
|
375
|
+
Studio process on its own. Studio is auto-discovered per-OS; override the
|
|
376
|
+
executable with `studioPath` (config key), `--studioPath`, or
|
|
377
|
+
`JEST_ROBLOX_STUDIO_PATH`. The backend is serial: `--parallel > 1` errors.
|
|
378
|
+
|
|
379
|
+
Pass `--headed` to show the Studio window during the run instead of the default
|
|
380
|
+
hidden one — useful for watching a slow run or a hang (Studio still self-quits
|
|
381
|
+
when tests finish, so a fast run just flashes). It is a per-run debugging flag,
|
|
382
|
+
CLI-only and inert on every other backend.
|
|
383
|
+
|
|
384
|
+
Once the result lands, Studio is shut down gracefully: it is allowed to close
|
|
385
|
+
the place — running any edit-mode plugin `BindToClose` handlers and freeing the
|
|
386
|
+
place lock — and is then killed the instant the lock releases, skipping Studio's
|
|
387
|
+
slow telemetry teardown. The shutdown is decoupled from the result, so pass/fail
|
|
388
|
+
prints immediately and the process exits once teardown finishes.
|
|
389
|
+
|
|
390
|
+
Unlike the attached `studio` backend, `--coverage` works here: studio-cli opens
|
|
391
|
+
the Coverage-Instrumented Place instead of the Clean Place, so the report
|
|
392
|
+
universe, thresholds, reporters, and exclusions behave identically to the
|
|
393
|
+
open-cloud backend (including the all-files semantics where an untested included
|
|
394
|
+
file reports **0%** and fails `coverageThreshold`).
|
|
395
|
+
|
|
396
|
+
<!-- prettier-ignore -->
|
|
397
|
+
> [!NOTE]
|
|
398
|
+
> studio-cli is a local-developer convenience backend (it needs a logged-in
|
|
399
|
+
> Studio and the installed plugin), not a CI path.
|
|
400
|
+
|
|
345
401
|
## Workspace mode
|
|
346
402
|
|
|
347
403
|
Run tests across multiple packages in a pnpm workspace in a single invocation.
|
|
348
|
-
Open Cloud
|
|
349
|
-
|
|
350
|
-
|
|
404
|
+
Works on every backend: Open Cloud (fans packages across parallel tasks),
|
|
405
|
+
`studio-cli` (one self-launched Studio process drives every package, no
|
|
406
|
+
sharding), and the attached `studio` backend (runs the workspace inside an open
|
|
407
|
+
Studio — handy for debugging the flow). `studio-cli` is serial, so
|
|
408
|
+
`--parallel > 1` is rejected with `--workspace`.
|
|
409
|
+
|
|
410
|
+
<!-- prettier-ignore -->
|
|
411
|
+
> [!NOTE]
|
|
412
|
+
> Package discovery uses one of two sources. By default it reads
|
|
351
413
|
> `pnpm-workspace.yaml` at the workspace root. Alternatively, declare a
|
|
352
414
|
> `workspace` block in your jest config (see
|
|
353
415
|
> [Workspaces without pnpm](#workspaces-without-pnpm)) to enumerate packages by
|
|
@@ -440,8 +502,10 @@ project) under `.jest-roblox/output/`.
|
|
|
440
502
|
|
|
441
503
|
| Flag | What it does |
|
|
442
504
|
| -------------------------------- | ----------------------------------------------------------------------------------------------------------- |
|
|
443
|
-
| `--backend <type>` | Choose `auto`, `open-cloud`, or `studio`
|
|
505
|
+
| `--backend <type>` | Choose `auto`, `open-cloud`, `studio`, or `studio-cli` |
|
|
444
506
|
| `--port <n>` | WebSocket port for Studio |
|
|
507
|
+
| `--studioPath <path>` | Roblox Studio executable for `studio-cli` (auto-detected if unset) |
|
|
508
|
+
| `--headed` | Show the Studio window during the run (`studio-cli` only; default: hidden) |
|
|
445
509
|
| `--config <path>` | Path to config file |
|
|
446
510
|
| `--testPathPattern <regex>` | Filter test files by path |
|
|
447
511
|
| `-t, --testNamePattern <regex>` | Filter tests by name |
|
|
@@ -486,7 +550,9 @@ project) under `.jest-roblox/output/`.
|
|
|
486
550
|
5. Maps Luau line numbers to TypeScript via source maps (roblox-ts only)
|
|
487
551
|
6. Prints results
|
|
488
552
|
|
|
489
|
-
|
|
553
|
+
<!-- prettier-ignore -->
|
|
554
|
+
> [!NOTE]
|
|
555
|
+
> Coverage adds extra steps: copy Luau files, insert tracking probes,
|
|
490
556
|
> build a separate place file, then map hit counts back to source. For
|
|
491
557
|
> roblox-ts, this goes through source maps to report TypeScript lines.
|
|
492
558
|
|
package/bin/jest-roblox.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { existsSync } from "node:fs";
|
|
3
|
+
import { registerHooks } from "node:module";
|
|
3
4
|
import { dirname, resolve } from "node:path";
|
|
4
5
|
import { fileURLToPath } from "node:url";
|
|
5
6
|
|
|
7
|
+
import { load, resolve as resolveLuau } from "../loaders/luau-raw.mjs";
|
|
8
|
+
|
|
6
9
|
const sourceEntry = resolve(dirname(fileURLToPath(import.meta.url)), "../src/cli.ts");
|
|
7
10
|
|
|
8
|
-
|
|
9
|
-
register("../loaders/luau-raw.mjs", import.meta.url);
|
|
11
|
+
registerHooks({ load, resolve: resolveLuau });
|
|
10
12
|
|
|
11
13
|
if (existsSync(sourceEntry)) {
|
|
12
14
|
const { main } = await import("../src/cli.ts");
|
package/dist/cli.d.mts
CHANGED
package/dist/cli.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { A as outputSingleResult, I as parseGameOutput, W as formatBanner, Z as LuauScriptError, ct as VALID_BACKENDS, dt as isValidBackend, et as mergeCliWithConfig, ft as ConfigError, h as walkErrorChain, k as outputMultiResult, m as formatMissingScopes, n as runJestRoblox, pt as version, tt as loadConfig } from "./run-Cirdb_CB.mjs";
|
|
2
2
|
import { OpenCloudError } from "@bedrock-rbx/ocale";
|
|
3
3
|
import process from "node:process";
|
|
4
4
|
import { parseArgs as parseArgs$1 } from "node:util";
|
|
@@ -9,8 +9,13 @@ const HELP_TEXT = `
|
|
|
9
9
|
Usage: jest-roblox [options] [files...]
|
|
10
10
|
|
|
11
11
|
Options:
|
|
12
|
-
--backend <type> Backend: "auto", "open-cloud",
|
|
12
|
+
--backend <type> Backend: "auto", "open-cloud", "studio", or
|
|
13
|
+
"studio-cli" (default: auto)
|
|
13
14
|
--port <number> WebSocket port for studio backend (default: 3001)
|
|
15
|
+
--studioPath <path> Roblox Studio executable for the studio-cli
|
|
16
|
+
backend (auto-detected if not set)
|
|
17
|
+
--headed Show the Studio window during the run
|
|
18
|
+
(studio-cli backend only; default: hidden)
|
|
14
19
|
--config <path> Path to config file
|
|
15
20
|
--testPathPattern <regex> Filter test files by path pattern
|
|
16
21
|
-t, --testNamePattern <regex> Filter tests by name pattern
|
|
@@ -96,6 +101,7 @@ function parseArgs(args) {
|
|
|
96
101
|
type: "string"
|
|
97
102
|
},
|
|
98
103
|
"gameOutput": { type: "string" },
|
|
104
|
+
"headed": { type: "boolean" },
|
|
99
105
|
"help": {
|
|
100
106
|
default: false,
|
|
101
107
|
type: "boolean"
|
|
@@ -126,6 +132,7 @@ function parseArgs(args) {
|
|
|
126
132
|
"showLuau": { type: "boolean" },
|
|
127
133
|
"silent": { type: "boolean" },
|
|
128
134
|
"sourceMap": { type: "boolean" },
|
|
135
|
+
"studioPath": { type: "string" },
|
|
129
136
|
"testNamePattern": {
|
|
130
137
|
short: "t",
|
|
131
138
|
type: "string"
|
|
@@ -166,6 +173,7 @@ function parseArgs(args) {
|
|
|
166
173
|
files: positionals.length > 0 ? positionals : void 0,
|
|
167
174
|
formatters: values.formatters,
|
|
168
175
|
gameOutput: values.gameOutput,
|
|
176
|
+
headed: values.headed,
|
|
169
177
|
help: values.help,
|
|
170
178
|
outputFile: values.outputFile,
|
|
171
179
|
packages: values.packages,
|
|
@@ -180,6 +188,7 @@ function parseArgs(args) {
|
|
|
180
188
|
showLuau: values["no-show-luau"] === true ? false : values.showLuau,
|
|
181
189
|
silent: values.silent,
|
|
182
190
|
sourceMap: values.sourceMap,
|
|
191
|
+
studioPath: values.studioPath,
|
|
183
192
|
testNamePattern: values.testNamePattern,
|
|
184
193
|
testPathPattern: values.testPathPattern,
|
|
185
194
|
timeout,
|
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { _ as SnapshotFormatOptions, a as DisplayName, b as defineProject, c as GlobalTestConfig, d as ProjectEntry, f as ProjectTestConfig, g as SharedTestConfig, h as SHARED_TEST_KEYS, i as DEFAULT_CONFIG, l as InlineProjectConfig, m as ResolvedConfig, n as Config, o as FormatterEntry, p as ROOT_CLI_KEYS, r as ConfigInput, s as GLOBAL_TEST_KEYS, t as CliOptions, u as JEST_ARGV_EXCLUDED_KEYS, v as WorkspaceConfig, x as TypecheckConfig, y as defineConfig } from "./schema-
|
|
1
|
+
import { _ as SnapshotFormatOptions, a as DisplayName, b as defineProject, c as GlobalTestConfig, d as ProjectEntry, f as ProjectTestConfig, g as SharedTestConfig, h as SHARED_TEST_KEYS, i as DEFAULT_CONFIG, l as InlineProjectConfig, m as ResolvedConfig, n as Config, o as FormatterEntry, p as ROOT_CLI_KEYS, r as ConfigInput, s as GLOBAL_TEST_KEYS, t as CliOptions, u as JEST_ARGV_EXCLUDED_KEYS, v as WorkspaceConfig, x as TypecheckConfig, y as defineConfig } from "./schema-i-pZhLCV.mjs";
|
|
2
2
|
import { type } from "arktype";
|
|
3
|
-
import { WebSocket, WebSocketServer } from "ws";
|
|
4
3
|
import { StorageClient } from "@bedrock-rbx/ocale/storage";
|
|
4
|
+
import { WebSocket, WebSocketServer } from "ws";
|
|
5
5
|
|
|
6
6
|
//#region src/coverage-pipeline/build-manifest.d.ts
|
|
7
7
|
/**
|
|
@@ -352,7 +352,16 @@ interface Backend {
|
|
|
352
352
|
readonly kind: BackendKind;
|
|
353
353
|
runTests(options: BackendOptions): Promise<BackendResult>;
|
|
354
354
|
}
|
|
355
|
-
type BackendKind = "open-cloud" | "studio";
|
|
355
|
+
type BackendKind = "open-cloud" | "studio" | "studio-cli";
|
|
356
|
+
/**
|
|
357
|
+
* Whether this is a workspace (multi-package) run. Workspace jobs each carry
|
|
358
|
+
* their owning package name (`pkg`); single-/multi-project jobs never do, and
|
|
359
|
+
* the run layer builds them all-or-none — so any job with `pkg` means the whole
|
|
360
|
+
* run is a workspace run. The Studio backends key off this to drive the plugin's
|
|
361
|
+
* staged-materializer dispatch (`workspace.entries`) instead of the configs
|
|
362
|
+
* path. `buildWorkspaceEntries` then fails fast if a job is missing `pkg`, so a
|
|
363
|
+
* malformed (mixed) array surfaces as a clear error rather than a bad payload.
|
|
364
|
+
*/
|
|
356
365
|
//#endregion
|
|
357
366
|
//#region packages/roblox-runner/dist/index.d.mts
|
|
358
367
|
//#endregion
|
|
@@ -366,8 +375,12 @@ interface UploadPlaceOptions {
|
|
|
366
375
|
placeFilePath: string;
|
|
367
376
|
/**
|
|
368
377
|
* Publish as the live version instead of a Saved draft. Open Cloud Luau
|
|
369
|
-
* Execution boots
|
|
370
|
-
* so a
|
|
378
|
+
* Execution boots whatever version is currently live on fresh and recycled
|
|
379
|
+
* servers, so without version pinning a concurrent upload can be picked up
|
|
380
|
+
* mid-run when a warm server recycles. Pinning execution to the uploaded
|
|
381
|
+
* version (see {@link ExecuteScriptOptions.placeVersion}) removes that
|
|
382
|
+
* hazard, so a Saved upload plus a pinned run isolates concurrent runs
|
|
383
|
+
* without disturbing the live slot — making this flag moot for that path.
|
|
371
384
|
*/
|
|
372
385
|
publish?: boolean;
|
|
373
386
|
}
|
|
@@ -376,6 +389,14 @@ interface UploadPlaceResult {
|
|
|
376
389
|
versionNumber: number;
|
|
377
390
|
}
|
|
378
391
|
interface ExecuteScriptOptions {
|
|
392
|
+
/**
|
|
393
|
+
* Pin execution to a specific place version (the `versionNumber` returned
|
|
394
|
+
* by {@link RemoteRunner.uploadPlace}). Open Cloud Luau Execution otherwise
|
|
395
|
+
* boots whatever version is currently live, so a concurrent upload to the
|
|
396
|
+
* same place clobbers an in-flight run; pinning isolates each run to the
|
|
397
|
+
* version it uploaded. Omitted ⇒ run against the live (head) version.
|
|
398
|
+
*/
|
|
399
|
+
placeVersion?: number;
|
|
379
400
|
script: string;
|
|
380
401
|
timeout: number;
|
|
381
402
|
}
|
|
@@ -407,11 +428,158 @@ declare class OpenCloudBackend implements Backend {
|
|
|
407
428
|
runTests(options: BackendOptions): Promise<BackendResult>;
|
|
408
429
|
private runBucket;
|
|
409
430
|
private runStaticBuckets;
|
|
410
|
-
private runStealingTask;
|
|
411
431
|
private runWorkStealing;
|
|
412
432
|
}
|
|
413
433
|
declare function createOpenCloudBackend(credentials: OpenCloudCredentials): OpenCloudBackend;
|
|
414
434
|
//#endregion
|
|
435
|
+
//#region src/staging/synthesizer.d.ts
|
|
436
|
+
interface StubMount {
|
|
437
|
+
absStubPath: string;
|
|
438
|
+
dataModelPath: string;
|
|
439
|
+
}
|
|
440
|
+
interface CoverageRoot {
|
|
441
|
+
/** Path relative to `packageDirectory` that points at the original luau root. */
|
|
442
|
+
luauRoot: string;
|
|
443
|
+
/** Absolute path to the instrumented shadow directory for the same root. */
|
|
444
|
+
shadowDir: string;
|
|
445
|
+
}
|
|
446
|
+
interface PackageDescriptor {
|
|
447
|
+
name: string;
|
|
448
|
+
/**
|
|
449
|
+
* Per-package `coverageCache` opt-out, forwarded to
|
|
450
|
+
* `prepareWorkspaceCoverage` so the cache gate honors each package's own
|
|
451
|
+
* declaration. Not read by synthesis itself.
|
|
452
|
+
*/
|
|
453
|
+
coverageCache?: boolean;
|
|
454
|
+
/**
|
|
455
|
+
* Per-package coverage ignore patterns, forwarded to
|
|
456
|
+
* `prepareWorkspaceCoverage` so the matcher reflects the merged pkgConfig
|
|
457
|
+
* instead of the workspace-root default. Not read by synthesis itself.
|
|
458
|
+
*/
|
|
459
|
+
coveragePathIgnorePatterns?: Array<string>;
|
|
460
|
+
/**
|
|
461
|
+
* When set, $path entries that fall inside any listed `luauRoot` are
|
|
462
|
+
* redirected to the corresponding `shadowDir` so the synthesized place
|
|
463
|
+
* picks up instrumented sources for this package only. Packages without
|
|
464
|
+
* `coverageRoots` use their original $path entries unchanged.
|
|
465
|
+
*/
|
|
466
|
+
coverageRoots?: Array<CoverageRoot>;
|
|
467
|
+
/**
|
|
468
|
+
* Per-package `luauRoots`, forwarded to `prepareWorkspaceCoverage` so the
|
|
469
|
+
* short-circuit honors the user-listed source dirs. Not read by synthesis
|
|
470
|
+
* itself.
|
|
471
|
+
*/
|
|
472
|
+
luauRoots?: Array<string>;
|
|
473
|
+
packageDirectory: string;
|
|
474
|
+
rojoProjectPath: string;
|
|
475
|
+
stubMounts?: Array<StubMount>;
|
|
476
|
+
}
|
|
477
|
+
//#endregion
|
|
478
|
+
//#region src/staging/place-builder.d.ts
|
|
479
|
+
interface BuildPlaceOptions {
|
|
480
|
+
/**
|
|
481
|
+
* Force `ServerScriptService.LoadStringEnabled = true` on the built place.
|
|
482
|
+
* Used by studio-cli's Clean Place, whose Run-mode runner gates on
|
|
483
|
+
* LoadString. Forwarded verbatim to {@link synthesize}.
|
|
484
|
+
*/
|
|
485
|
+
loadStringEnabled?: boolean;
|
|
486
|
+
packages: Array<PackageDescriptor>;
|
|
487
|
+
placeFile: string;
|
|
488
|
+
projectFile: string;
|
|
489
|
+
wrap?: boolean;
|
|
490
|
+
}
|
|
491
|
+
//#endregion
|
|
492
|
+
//#region src/backends/studio-cli.d.ts
|
|
493
|
+
interface StudioCliLaunchRequest {
|
|
494
|
+
/** Full Studio CLI argument vector (already absolute paths). */
|
|
495
|
+
args: Array<string>;
|
|
496
|
+
/**
|
|
497
|
+
* Show the Studio window during the run (`--headed`) instead of the default
|
|
498
|
+
* hidden window. Maps to `windowsHide: !headed` in {@link spawnStudio}.
|
|
499
|
+
*/
|
|
500
|
+
headed: boolean;
|
|
501
|
+
/**
|
|
502
|
+
* Absolute path of the place Studio opens. Used only to clear a stale
|
|
503
|
+
* `<place>.lock` a previously killed Studio could not remove itself.
|
|
504
|
+
*/
|
|
505
|
+
placeFile: string;
|
|
506
|
+
/** Absolute path to the Studio executable. */
|
|
507
|
+
studioPath: string;
|
|
508
|
+
}
|
|
509
|
+
/**
|
|
510
|
+
* A launched Studio the host can kill once the result arrives (or on timeout).
|
|
511
|
+
* The injected seam: unit tests return a fake that drives a canned result frame
|
|
512
|
+
* over the mock WebSocket server instead of launching Studio.
|
|
513
|
+
*/
|
|
514
|
+
interface StudioCliProcess {
|
|
515
|
+
/**
|
|
516
|
+
* Terminate Studio immediately (`TerminateProcess`), skipping graceful
|
|
517
|
+
* shutdown. Used on every hung/error/timeout path.
|
|
518
|
+
*/
|
|
519
|
+
kill: () => void;
|
|
520
|
+
/**
|
|
521
|
+
* Graceful teardown: wait for Studio to release
|
|
522
|
+
* `<place>.lock` — which happens only after every edit-mode `BindToClose`
|
|
523
|
+
* handler ran and `ClosePlace` finished — then terminate it, skipping
|
|
524
|
+
* Studio's ~30s post-close telemetry drain. Hard-kills anyway after
|
|
525
|
+
* `graceCapMs` (a long-yielding handler). Returns immediately; the watch runs
|
|
526
|
+
* in the background, keeping node's event loop alive (the child handle + a
|
|
527
|
+
* poll timer) until it fires, so the CLI prints results now and the process
|
|
528
|
+
* exits once teardown completes. The caller closes the result server first,
|
|
529
|
+
* which is what lets the bootstrap return and `--quitAfterExecution` begin
|
|
530
|
+
* the graceful close.
|
|
531
|
+
*/
|
|
532
|
+
killOnLockRelease: (graceCapMs: number) => void;
|
|
533
|
+
/** Subscribe to a spawn failure (e.g. a bad `studioPath`). */
|
|
534
|
+
onError: (listener: (error: Error) => void) => void;
|
|
535
|
+
}
|
|
536
|
+
/** Spawns Studio and returns the handle the host kills. */
|
|
537
|
+
type StudioCliLauncher = (request: StudioCliLaunchRequest) => StudioCliProcess;
|
|
538
|
+
interface StudioCliOptions {
|
|
539
|
+
/** Place Builder seam; defaults to the real {@link defaultBuildPlace}. */
|
|
540
|
+
buildPlace?: (options: BuildPlaceOptions) => BuildManifestArtifact;
|
|
541
|
+
/** Result-server factory seam; defaults to an ephemeral-port `ws` server. */
|
|
542
|
+
createServer?: () => WebSocketServer;
|
|
543
|
+
/** Studio-executable resolver seam; defaults to {@link discoverStudioPath}. */
|
|
544
|
+
discover?: (override: string | undefined) => string;
|
|
545
|
+
/**
|
|
546
|
+
* Backstop for the graceful teardown: hard-kill if `<place>.lock` isn't
|
|
547
|
+
* released within this many ms. Defaults to {@link GRACEFUL_SHUTDOWN_CAP_MS}.
|
|
548
|
+
*/
|
|
549
|
+
gracefulShutdownTimeout?: number;
|
|
550
|
+
/**
|
|
551
|
+
* Show the Studio window during the run (`--headed`). CLI-only — never read
|
|
552
|
+
* from config. Defaults to false (hidden window).
|
|
553
|
+
*/
|
|
554
|
+
headed?: boolean;
|
|
555
|
+
/** Process launcher seam; defaults to the real {@link spawnStudio}. */
|
|
556
|
+
launch?: StudioCliLauncher;
|
|
557
|
+
/** Explicit Studio executable path (override from config / CLI / env). */
|
|
558
|
+
studioPath?: string;
|
|
559
|
+
/** Run timeout in milliseconds. Defaults to 300000. */
|
|
560
|
+
timeout?: number;
|
|
561
|
+
}
|
|
562
|
+
declare class StudioCliBackend implements Backend {
|
|
563
|
+
private readonly buildPlace;
|
|
564
|
+
private readonly createServer;
|
|
565
|
+
private readonly discover;
|
|
566
|
+
private readonly gracefulShutdownTimeout;
|
|
567
|
+
private readonly headed;
|
|
568
|
+
private readonly launch;
|
|
569
|
+
private readonly studioPath?;
|
|
570
|
+
private readonly timeout;
|
|
571
|
+
readonly kind = "studio-cli";
|
|
572
|
+
constructor(options?: StudioCliOptions);
|
|
573
|
+
runTests(options: BackendOptions): Promise<BackendResult>;
|
|
574
|
+
/**
|
|
575
|
+
* Build the Clean Place for a normal (non-coverage) run and return its path.
|
|
576
|
+
* `loadStringEnabled` is forced on so the Run-mode runner's LoadString gate
|
|
577
|
+
* passes. Coverage runs skip this and open the instrumented place instead.
|
|
578
|
+
*/
|
|
579
|
+
private buildCleanPlace;
|
|
580
|
+
}
|
|
581
|
+
declare function createStudioCliBackend(options?: StudioCliOptions): StudioCliBackend;
|
|
582
|
+
//#endregion
|
|
415
583
|
//#region src/backends/studio.d.ts
|
|
416
584
|
interface PreConnected {
|
|
417
585
|
server: WebSocketServer;
|
|
@@ -931,6 +1099,16 @@ interface MappedCoverageResult {
|
|
|
931
1099
|
files: Record<string, MappedFileCoverage>;
|
|
932
1100
|
}
|
|
933
1101
|
//#endregion
|
|
1102
|
+
//#region src/coverage-pipeline/agent-table-filter.d.ts
|
|
1103
|
+
/**
|
|
1104
|
+
* Decides whether a single coverage-universe source file is shown in the agent
|
|
1105
|
+
* **text table**. Receives a normalized-absolute source path (see
|
|
1106
|
+
* {@link narrowMappedForAgentTable}). This is a display-only narrowing layered
|
|
1107
|
+
* on top of `filterCoverageUniverse`: thresholds, the totals line, and the
|
|
1108
|
+
* lcov/html/json artifacts always keep the full universe.
|
|
1109
|
+
*/
|
|
1110
|
+
type CoverageDisplayPredicate = (normalizedAbsolutePath: string) => boolean;
|
|
1111
|
+
//#endregion
|
|
934
1112
|
//#region src/run/types.d.ts
|
|
935
1113
|
type RunMode = "multi" | "single" | "workspace";
|
|
936
1114
|
interface ProjectResult {
|
|
@@ -950,6 +1128,13 @@ interface SingleRunResult {
|
|
|
950
1128
|
* place set it has.
|
|
951
1129
|
*/
|
|
952
1130
|
coverageArtifacts?: CoverageArtifacts;
|
|
1131
|
+
/**
|
|
1132
|
+
* Narrows the agent coverage **text table** to the directly-filtered source
|
|
1133
|
+
* files on a filtered run (single file / `--testPathPattern`). Display-only:
|
|
1134
|
+
* thresholds, totals, and lcov/html/json keep the full universe. Undefined on
|
|
1135
|
+
* a full run.
|
|
1136
|
+
*/
|
|
1137
|
+
coverageDisplayFilter?: CoverageDisplayPredicate;
|
|
953
1138
|
mode: "single";
|
|
954
1139
|
preCoverageMs: number;
|
|
955
1140
|
runtimeResult?: ExecuteResult;
|
|
@@ -960,6 +1145,13 @@ interface MultiRunResult {
|
|
|
960
1145
|
collectCoverageFrom?: Array<string>;
|
|
961
1146
|
/** Producer record for the entry point to emit a Build Manifest from. */
|
|
962
1147
|
coverageArtifacts?: CoverageArtifacts;
|
|
1148
|
+
/**
|
|
1149
|
+
* Narrows the agent coverage **text table** to the directly-filtered source
|
|
1150
|
+
* files on a filtered run (positional files / `--testPathPattern`, or the
|
|
1151
|
+
* selected `--project` scope). Display-only: thresholds, totals, and
|
|
1152
|
+
* lcov/html/json keep the full universe. Undefined on a full run.
|
|
1153
|
+
*/
|
|
1154
|
+
coverageDisplayFilter?: CoverageDisplayPredicate;
|
|
963
1155
|
merged: MultiProjectMerged;
|
|
964
1156
|
mode: "multi";
|
|
965
1157
|
preCoverageMs: number;
|
|
@@ -1105,10 +1297,16 @@ interface TypecheckOptions {
|
|
|
1105
1297
|
ignoreSourceErrors?: boolean;
|
|
1106
1298
|
rootDir: string;
|
|
1107
1299
|
/**
|
|
1108
|
-
* Milliseconds the tsgo
|
|
1109
|
-
* throws.
|
|
1300
|
+
* Milliseconds to wait for the tsgo process to launch before the pass
|
|
1301
|
+
* throws. The timer is cleared the instant tsgo reports it spawned; it does
|
|
1302
|
+
* not bound the compile. Defaults to {@link DEFAULT_SPAWN_TIMEOUT}.
|
|
1110
1303
|
*/
|
|
1111
1304
|
spawnTimeout?: number;
|
|
1305
|
+
/**
|
|
1306
|
+
* Milliseconds the tsgo *compile* may run before it is killed and the pass
|
|
1307
|
+
* throws. The run-level `timeout`. Defaults to {@link DEFAULT_RUN_TIMEOUT}.
|
|
1308
|
+
*/
|
|
1309
|
+
timeout?: number;
|
|
1112
1310
|
tsconfig?: string;
|
|
1113
1311
|
}
|
|
1114
1312
|
declare function runTypecheck(options: TypecheckOptions): Promise<JestResult>;
|
|
@@ -1410,4 +1608,4 @@ declare function visitExpression(expression: AstExpr, visitor: LuauVisitor): voi
|
|
|
1410
1608
|
declare function visitStatement(statement: AstStat, visitor: LuauVisitor): void;
|
|
1411
1609
|
declare function visitBlock(block: AstStatBlock, visitor: LuauVisitor): void; //#endregion
|
|
1412
1610
|
//#endregion
|
|
1413
|
-
export { type ArtifactBundle, type AstExpr, type AstExprBinary, type AstExprCall, type AstExprFunction, type AstStat, type AstStatBlock, BUILD_MANIFEST_VERSION, type Backend, type BackendOptions, type BuildManifest, type BuildManifestArtifact, type BuildManifestFileRecord, type BuildManifestProject, type CliOptions, type Config, type ConfigInput, type CoverageManifest, DEFAULT_CONFIG, type DisplayName, type ExecuteResult, type FormatOutputOptions, type FormatterEntry, GLOBAL_TEST_KEYS, type GameOutputEntry, type GitHubActionsFormatterOptions, type GlobalTestConfig, type InlineProjectConfig, type InstrumentedFileRecord, JEST_ARGV_EXCLUDED_KEYS, type JestArgv, type JestResult, type LuauSpan, type LuauVisitor, MANIFEST_VERSION, type MultiProjectMerged, type MultiRunResult, type NonInstrumentedFileRecord, OpenCloudBackend, type ProjectEntry, type ProjectInput, type ProjectResult, type ProjectTestConfig, ROOT_CLI_KEYS, type ReadBuildManifestOptions, type ReadBuildManifestResult, type ReadManifestResult as ReadCoverageManifestResult, type ResolvedConfig, type ResolvedProjectConfig, type RunMode, type RunOptions, type RunProjectsOptions, type RunProjectsResult, type RunResult, SHARED_TEST_KEYS, type SharedTestConfig, type SingleRunResult, StudioBackend, type TestCaseResult, type TestDefinition, type TestFileResult, type TestRecord, type TestStatus, type TscErrorInfo, type TypecheckOptions, type WorkspaceConfig, type WorkspaceRunResult, buildJestArgv, buildManifestSchema, manifestSchema as coverageManifestSchema, createOpenCloudBackend, createStudioBackend, defineConfig, defineProject, extractJsonFromOutput, formatAnnotations, formatExecuteOutput, formatFailure, formatGameOutputNotice, formatJobSummary, formatJson, formatResult, formatTestSummary, generateTestScript, hashFile, loadConfig, parseGameOutput, parseJestOutput, prepareArtifacts, readBuildManifest, readManifest as readCoverageManifest, resolveConfig, runJestRoblox, runProjects, runTypecheck, visitBlock, visitExpression, visitStatement, writeGameOutput, writeJsonFile };
|
|
1611
|
+
export { type ArtifactBundle, type AstExpr, type AstExprBinary, type AstExprCall, type AstExprFunction, type AstStat, type AstStatBlock, BUILD_MANIFEST_VERSION, type Backend, type BackendOptions, type BuildManifest, type BuildManifestArtifact, type BuildManifestFileRecord, type BuildManifestProject, type CliOptions, type Config, type ConfigInput, type CoverageManifest, DEFAULT_CONFIG, type DisplayName, type ExecuteResult, type FormatOutputOptions, type FormatterEntry, GLOBAL_TEST_KEYS, type GameOutputEntry, type GitHubActionsFormatterOptions, type GlobalTestConfig, type InlineProjectConfig, type InstrumentedFileRecord, JEST_ARGV_EXCLUDED_KEYS, type JestArgv, type JestResult, type LuauSpan, type LuauVisitor, MANIFEST_VERSION, type MultiProjectMerged, type MultiRunResult, type NonInstrumentedFileRecord, OpenCloudBackend, type ProjectEntry, type ProjectInput, type ProjectResult, type ProjectTestConfig, ROOT_CLI_KEYS, type ReadBuildManifestOptions, type ReadBuildManifestResult, type ReadManifestResult as ReadCoverageManifestResult, type ResolvedConfig, type ResolvedProjectConfig, type RunMode, type RunOptions, type RunProjectsOptions, type RunProjectsResult, type RunResult, SHARED_TEST_KEYS, type SharedTestConfig, type SingleRunResult, StudioBackend, StudioCliBackend, type TestCaseResult, type TestDefinition, type TestFileResult, type TestRecord, type TestStatus, type TscErrorInfo, type TypecheckOptions, type WorkspaceConfig, type WorkspaceRunResult, buildJestArgv, buildManifestSchema, manifestSchema as coverageManifestSchema, createOpenCloudBackend, createStudioBackend, createStudioCliBackend, defineConfig, defineProject, extractJsonFromOutput, formatAnnotations, formatExecuteOutput, formatFailure, formatGameOutputNotice, formatJobSummary, formatJson, formatResult, formatTestSummary, generateTestScript, hashFile, loadConfig, parseGameOutput, parseJestOutput, prepareArtifacts, readBuildManifest, readManifest as readCoverageManifest, resolveConfig, runJestRoblox, runProjects, runTypecheck, visitBlock, visitExpression, visitStatement, writeGameOutput, writeJsonFile };
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as
|
|
1
|
+
import { $ as parseJestOutput, B as writeJsonFile, C as visitStatement, D as emitBuildManifest, E as buildManifestSchema, F as formatGameOutputNotice, G as hashFile, H as formatResult, I as parseGameOutput, J as readManifest, K as MANIFEST_VERSION, L as writeGameOutput, M as formatJobSummary, N as formatExecuteOutput, O as readBuildManifest, P as runProjects, Q as extractJsonFromOutput, R as createTimingCollector, S as visitExpression, T as BUILD_MANIFEST_VERSION, U as formatTestSummary, V as formatFailure, X as applyAttribution, Y as writeManifest, _ as generateTestScript, a as loadRojoTree, at as JEST_ARGV_EXCLUDED_KEYS, b as findRojoProject, c as StudioBackend, d as createStudioCliBackend, et as mergeCliWithConfig, f as OpenCloudBackend, g as buildJestArgv, i as collectStubMounts, it as GLOBAL_TEST_KEYS, j as formatAnnotations, l as createStudioBackend, lt as defineConfig, n as runJestRoblox, nt as resolveConfig, o as runTypecheck, ot as ROOT_CLI_KEYS, p as createOpenCloudBackend, q as manifestSchema, r as runSingleOrMulti, rt as DEFAULT_CONFIG, s as resolveAllProjects, st as SHARED_TEST_KEYS, t as getRawProjects, tt as loadConfig, u as StudioCliBackend, ut as defineProject, v as COVERAGE_BUILD_MANIFEST_PATH, w as buildPlace, x as visitBlock, y as COVERAGE_MANIFEST_PATH, z as formatJson } from "./run-Cirdb_CB.mjs";
|
|
2
2
|
import * as path$1 from "node:path";
|
|
3
3
|
//#region src/artifacts/prepare-artifacts.ts
|
|
4
4
|
const COVERAGE_DIR = path$1.dirname(COVERAGE_BUILD_MANIFEST_PATH);
|
|
@@ -81,4 +81,4 @@ async function buildCleanPlace(config) {
|
|
|
81
81
|
});
|
|
82
82
|
}
|
|
83
83
|
//#endregion
|
|
84
|
-
export { BUILD_MANIFEST_VERSION, DEFAULT_CONFIG, GLOBAL_TEST_KEYS, JEST_ARGV_EXCLUDED_KEYS, MANIFEST_VERSION, OpenCloudBackend, ROOT_CLI_KEYS, SHARED_TEST_KEYS, StudioBackend, buildJestArgv, buildManifestSchema, manifestSchema as coverageManifestSchema, createOpenCloudBackend, createStudioBackend, defineConfig, defineProject, extractJsonFromOutput, formatAnnotations, formatExecuteOutput, formatFailure, formatGameOutputNotice, formatJobSummary, formatJson, formatResult, formatTestSummary, generateTestScript, hashFile, loadConfig, parseGameOutput, parseJestOutput, prepareArtifacts, readBuildManifest, readManifest as readCoverageManifest, resolveConfig, runJestRoblox, runProjects, runTypecheck, visitBlock, visitExpression, visitStatement, writeGameOutput, writeJsonFile };
|
|
84
|
+
export { BUILD_MANIFEST_VERSION, DEFAULT_CONFIG, GLOBAL_TEST_KEYS, JEST_ARGV_EXCLUDED_KEYS, MANIFEST_VERSION, OpenCloudBackend, ROOT_CLI_KEYS, SHARED_TEST_KEYS, StudioBackend, StudioCliBackend, buildJestArgv, buildManifestSchema, manifestSchema as coverageManifestSchema, createOpenCloudBackend, createStudioBackend, createStudioCliBackend, defineConfig, defineProject, extractJsonFromOutput, formatAnnotations, formatExecuteOutput, formatFailure, formatGameOutputNotice, formatJobSummary, formatJson, formatResult, formatTestSummary, generateTestScript, hashFile, loadConfig, parseGameOutput, parseJestOutput, prepareArtifacts, readBuildManifest, readManifest as readCoverageManifest, resolveConfig, runJestRoblox, runProjects, runTypecheck, visitBlock, visitExpression, visitStatement, writeGameOutput, writeJsonFile };
|