@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.
@@ -788,7 +788,12 @@ type _Except<ObjectType, KeysType extends keyof ObjectType, Options extends Requ
788
788
  //#region src/config/resolve-typecheck-config.d.ts
789
789
  /** Host-only Type Test config. Valid at root `test:` and per-project `test:`. */
790
790
  interface TypecheckConfig {
791
+ /**
792
+ * Enable Type Tests (`*.spec-d.ts`/`*.test-d.ts`). This is the only gate —
793
+ * setting other typecheck fields does not auto-enable. Default `false`.
794
+ */
791
795
  enabled?: boolean;
796
+ /** Globs excluded from Type Test discovery. */
792
797
  exclude?: Array<string>;
793
798
  /**
794
799
  * When `false` (default), type errors in non-test source files surface as
@@ -796,50 +801,111 @@ interface TypecheckConfig {
796
801
  * discovered Type Test files are suppressed.
797
802
  */
798
803
  ignoreSourceErrors?: boolean;
804
+ /**
805
+ * Globs selecting Type Test files. When unset, derived from the project's
806
+ * runtime `include` (`.spec.` → `.spec-d.`).
807
+ */
799
808
  include?: Array<string>;
809
+ /** Run only Type Tests and skip Runtime Tests. Implies `enabled`. Default `false`. */
800
810
  only?: boolean;
801
- /** Milliseconds the tsgo spawn may run before it is killed and the pass throws. */
811
+ /**
812
+ * Milliseconds to wait for the tsgo process to start before the pass
813
+ * throws. Bounds only startup, not the type-check itself — a slow check is
814
+ * governed by the run-level `timeout`. Default `10000`.
815
+ */
802
816
  spawnTimeout?: number;
817
+ /** Custom tsconfig used for type checking (root-only in projects mode). */
803
818
  tsconfig?: string;
804
819
  }
805
820
  //#endregion
806
821
  //#region src/config/schema.d.ts
807
- type Backend = "auto" | "open-cloud" | "studio";
822
+ type Backend = "auto" | "open-cloud" | "studio" | "studio-cli";
808
823
  type CoverageReporter = keyof ReportOptions;
809
824
  type FormatterEntry = [string, Record<string, unknown>] | string;
825
+ /** pretty-format options controlling how snapshots are serialized. */
810
826
  interface SnapshotFormatOptions {
827
+ /** Call a value's `toJSON` method (when present) before serializing it. */
811
828
  callToJSON?: boolean;
829
+ /** Escape regex special characters in string snapshots. */
812
830
  escapeRegex?: boolean;
831
+ /** Escape backslashes and quotes in string snapshots. */
813
832
  escapeString?: boolean;
833
+ /** Number of spaces per indentation level. */
814
834
  indent?: number;
835
+ /** Maximum depth of nested objects/arrays to print before collapsing. */
815
836
  maxDepth?: number;
837
+ /** Print on a single line with no indentation. */
816
838
  min?: boolean;
839
+ /** Print the `Object`/class prototype name for plain objects. */
817
840
  printBasicPrototype?: boolean;
841
+ /** Print function names instead of `[Function]`. */
818
842
  printFunctionName?: boolean;
819
843
  }
844
+ /** A reporter label with a colour, used to tag a project's output. */
820
845
  interface DisplayName {
846
+ /** The label shown in reporter output. */
821
847
  name: string;
848
+ /** Colour applied to the label (e.g. `"magenta"`, `"white"`). */
822
849
  color: string;
823
850
  }
824
851
  /** Jest-passthrough keys valid both at `test:` and per-project. */
825
852
  interface SharedTestConfig {
853
+ /** Automatically mock every required module. Default `false`. */
826
854
  automock?: boolean;
855
+ /**
856
+ * Clear `mock.calls`/`instances`/`results` on every mock before each test
857
+ * (like `jest.clearAllMocks()`). Default `false`.
858
+ */
827
859
  clearMocks?: boolean;
860
+ /**
861
+ * Inject Jest's globals (`describe`, `it`, `expect`, …) into the test
862
+ * environment instead of requiring them explicitly. Default `true`.
863
+ */
828
864
  injectGlobals?: boolean;
865
+ /**
866
+ * Swap the live Roblox DataModel for a fresh mock instance per test file so
867
+ * tests can mutate the tree in isolation. Default `false`.
868
+ */
829
869
  mockDataModel?: boolean;
870
+ /**
871
+ * Reset mock state and remove any mocked implementation before each test
872
+ * (like `jest.resetAllMocks()`). Default `false`.
873
+ */
830
874
  resetMocks?: boolean;
875
+ /**
876
+ * Reset the module registry before each test so every test re-requires a
877
+ * fresh module graph. Default `false`.
878
+ */
831
879
  resetModules?: boolean;
880
+ /**
881
+ * Restore `spyOn` mocks to their original implementations before each test
882
+ * (like `jest.restoreAllMocks()`). Default `false`.
883
+ */
832
884
  restoreMocks?: boolean;
885
+ /** DataModel paths to scripts run once before the test framework is installed. */
833
886
  setupFiles?: Array<string>;
887
+ /**
888
+ * DataModel paths to scripts run after the framework is installed, before
889
+ * each test file — the place for global hooks and custom matchers.
890
+ */
834
891
  setupFilesAfterEnv?: Array<string>;
892
+ /** Seconds after which a single test is reported as slow. Default `5`. */
835
893
  slowTestThreshold?: number;
894
+ /** pretty-format options controlling how snapshots are serialized. */
836
895
  snapshotFormat?: SnapshotFormatOptions;
896
+ /** DataModel paths to custom snapshot serializer modules. */
837
897
  snapshotSerializers?: Array<string>;
898
+ /** Test environment used to run the tests. */
838
899
  testEnvironment?: string;
900
+ /** Options forwarded to the test environment. */
839
901
  testEnvironmentOptions?: Record<string, unknown> | string;
902
+ /** Glob patterns Jest uses to detect test files. */
840
903
  testMatch?: Array<string>;
904
+ /** Regex patterns; a test file is skipped when its path matches any of them. */
841
905
  testPathIgnorePatterns?: Array<string>;
906
+ /** Regex pattern(s) Jest uses to detect test files (alternative to `testMatch`). */
842
907
  testRegex?: Array<string> | string;
908
+ /** Default per-test timeout in milliseconds. Default `5000`. */
843
909
  testTimeout?: number;
844
910
  /**
845
911
  * Host-only Type Test config. Never forwarded to the Roblox runtime.
@@ -849,10 +915,27 @@ interface SharedTestConfig {
849
915
  }
850
916
  /** Jest-passthrough keys valid only per-project (under `projects[N].test`). */
851
917
  interface ProjectTestConfig extends SharedTestConfig {
918
+ /**
919
+ * Reporter label identifying this project's tests — a string, or
920
+ * `{ name, color }` to tint it. Must be unique across projects.
921
+ */
852
922
  displayName: DisplayName | string;
923
+ /** Globs subtracted from this project's Runtime Test discovery. */
853
924
  exclude?: Array<string>;
925
+ /**
926
+ * Globs (with TS extensions) selecting this project's test files, relative
927
+ * to `root`. The static directory prefix of each glob maps to a Rojo
928
+ * `$path`/DataModel mount.
929
+ */
854
930
  include: Array<string>;
931
+ /**
932
+ * Compiled-output directory the project's `.luau` lives in. Setting it pins
933
+ * the project to a single DataModel mount (exact Rojo lookup, no
934
+ * auto-expand). roblox-ts users point this at the compiled output (e.g.
935
+ * `"out/client"`), not `"src/…"`.
936
+ */
855
937
  outDir?: string;
938
+ /** Base path prepended to this project's `include`, `exclude`, and `outDir`. */
856
939
  root?: string;
857
940
  }
858
941
  interface InlineProjectConfig {
@@ -890,47 +973,109 @@ interface WorkspaceConfig {
890
973
  type ProjectEntry = InlineProjectConfig | string;
891
974
  /** Jest-passthrough keys valid only at root `test:` (not per-project). */
892
975
  interface GlobalTestConfig extends SharedTestConfig {
976
+ /**
977
+ * Report coverage for every file matched by the coverage globs, even those
978
+ * no test exercised (untested files count as 0%). Default `false`.
979
+ */
893
980
  all?: boolean;
981
+ /**
982
+ * Stop the run after `n` failing test suites (`true` ⇒ after the first).
983
+ * Default `0` (never bail).
984
+ */
894
985
  bail?: boolean | number;
986
+ /** Run only tests affected by files changed since the given git ref. */
895
987
  changedSince?: string;
988
+ /** Assume a CI environment, which disables writing new snapshots. */
896
989
  ci?: boolean;
990
+ /** Clear Jest's transform cache before running, then exit. */
897
991
  clearCache?: boolean;
992
+ /** Collect code coverage during the run. Default `false`. */
898
993
  collectCoverage?: boolean;
994
+ /** Globs selecting which source files coverage is collected from. */
899
995
  collectCoverageFrom?: Array<string>;
996
+ /** Alias for {@link collectCoverage}. */
900
997
  coverage?: boolean;
998
+ /** Directory coverage reports are written to. Default `"coverage"`. */
901
999
  coverageDirectory?: string;
1000
+ /** Globs excluded from coverage collection. */
902
1001
  coveragePathIgnorePatterns?: Array<string>;
1002
+ /**
1003
+ * Istanbul reporters to emit (e.g. `"text"`, `"lcov"`, `"html"`). Default
1004
+ * `["text", "lcov"]`.
1005
+ */
903
1006
  coverageReporters?: Array<CoverageReporter>;
1007
+ /**
1008
+ * Minimum coverage percentages (0–100); the run fails when any is not met.
1009
+ */
904
1010
  coverageThreshold?: {
905
1011
  branches?: number;
906
1012
  functions?: number;
907
1013
  lines?: number;
908
1014
  statements?: number;
909
1015
  };
1016
+ /** Print Jest's resolved config and debugging info. */
910
1017
  debug?: boolean;
1018
+ /** Reporter label for the whole run — a string, or `{ name, color }`. */
911
1019
  displayName?: DisplayName | string;
1020
+ /** Test environment to use, forwarded to the Jest runtime. */
912
1021
  env?: string;
1022
+ /**
1023
+ * Globs subtracted from Runtime Test discovery. Applies to single-,
1024
+ * multi-project, and `--workspace` runs (skipped for explicit file args).
1025
+ */
913
1026
  exclude?: Array<string>;
1027
+ /** Show full diffs and error output instead of truncating. */
914
1028
  expand?: boolean;
1029
+ /** A JSON string of globals to expose in every test environment. */
915
1030
  globals?: string;
1031
+ /**
1032
+ * Per-project globs selecting Runtime Test files. With no `projects`
1033
+ * configured, the run derives one project per `luauRoots` mount and runtime
1034
+ * discovery uses `testMatch` — this root-level `include` is not consumed
1035
+ * there.
1036
+ */
916
1037
  include?: Array<string>;
1038
+ /**
1039
+ * Maximum worker count, or a percentage string like `"50%"`, for parallel
1040
+ * test execution.
1041
+ */
917
1042
  maxWorkers?: number | string;
1043
+ /** Omit stack traces from failure output. */
918
1044
  noStackTrace?: boolean;
1045
+ /** Default compiled-output directory for test discovery when not set per-project. */
919
1046
  outDir?: string;
1047
+ /** Exit `0` even when no tests are found. Default `false`. */
920
1048
  passWithNoTests?: boolean;
1049
+ /** Name of a preset that supplies base Jest config. */
921
1050
  preset?: string;
1051
+ /**
1052
+ * Per-project configs for a multi-project run. Each entry is a DataModel
1053
+ * path string, or an inline {@link defineProject} object.
1054
+ */
922
1055
  projects?: Array<ProjectEntry>;
1056
+ /** Reporter modules (DataModel paths) used to format results. */
923
1057
  reporters?: Array<string>;
1058
+ /** Root directories Jest scans for tests and modules. */
924
1059
  roots?: Array<string>;
1060
+ /** Run all tests serially in the current process instead of in workers. */
925
1061
  runInBand?: boolean;
1062
+ /** Run only the projects whose `displayName` is listed. */
926
1063
  selectProjects?: Array<string>;
1064
+ /** Print the resolved config and exit without running tests. */
927
1065
  showConfig?: boolean;
1066
+ /** Suppress test `print`/console output. Default `false`. */
928
1067
  silent?: boolean;
1068
+ /** Process exit code used when tests fail. */
929
1069
  testFailureExitCode?: string;
1070
+ /** Run only tests whose full name matches this regex. */
930
1071
  testNamePattern?: string;
1072
+ /** Run only test files whose path matches this regex. */
931
1073
  testPathPattern?: string;
1074
+ /** Fake-timers mode (e.g. `"real"`, `"fake"`). */
932
1075
  timers?: string;
1076
+ /** Update stored snapshots to match current output. */
933
1077
  updateSnapshot?: boolean;
1078
+ /** Report each individual test result, not just suite summaries. Default `false`. */
934
1079
  verbose?: boolean;
935
1080
  }
936
1081
  /**
@@ -938,10 +1083,32 @@ interface GlobalTestConfig extends SharedTestConfig {
938
1083
  * jest-passthrough options live.
939
1084
  */
940
1085
  interface Config {
1086
+ /**
1087
+ * Execution backend. `"auto"` probes for a running Studio then falls back to
1088
+ * Open Cloud; `"open-cloud"` uploads and runs via Roblox Open Cloud;
1089
+ * `"studio"` drives a locally running Studio; `"studio-cli"` launches its own
1090
+ * headless Studio via `--task RunScript` and quits it (pass `--headed` to show
1091
+ * the Studio window during the run). Default `"auto"`. `"studio-cli"` is never
1092
+ * selected by `"auto"` — request it explicitly.
1093
+ */
941
1094
  backend?: Backend;
1095
+ /** Force ANSI colour in output. Default `true`. */
942
1096
  color?: boolean;
1097
+ /**
1098
+ * Reuse the incrementally-instrumented coverage place between runs when
1099
+ * nothing changed. Default `true`.
1100
+ */
943
1101
  coverageCache?: boolean;
1102
+ /**
1103
+ * One or more config files to inherit from (c12 layering), relative to this
1104
+ * file. Local keys win over extended ones.
1105
+ */
944
1106
  extends?: Array<string> | string;
1107
+ /**
1108
+ * Output formatters — `"default"`, `"agent"`, `"json"`,
1109
+ * `"github-actions"` — each a name or a `[name, options]` pair. Default
1110
+ * `["default"]`.
1111
+ */
945
1112
  formatters?: Array<FormatterEntry>;
946
1113
  /**
947
1114
  * Where to write Game Output. A path, or `true` to default to
@@ -949,7 +1116,16 @@ interface Config {
949
1116
  * single Aggregated Game Output file (consensus-resolved).
950
1117
  */
951
1118
  gameOutput?: string | true;
1119
+ /**
1120
+ * DataModel path to the Jest module the runner requires (e.g.
1121
+ * `"ReplicatedStorage/Packages/Jest"`). Defaults to auto-detection in
1122
+ * ReplicatedStorage.
1123
+ */
952
1124
  jestPath?: string;
1125
+ /**
1126
+ * Compiled-Luau directories to instrument for coverage. Defaults to the
1127
+ * tsconfig `outDir`.
1128
+ */
953
1129
  luauRoots?: Array<string>;
954
1130
  /**
955
1131
  * Where to write the Jest result JSON. A path, or `true` to default to
@@ -957,17 +1133,50 @@ interface Config {
957
1133
  * single aggregated result file (consensus-resolved).
958
1134
  */
959
1135
  outputFile?: string | true;
1136
+ /** Number of places to shard the run across, or `"auto"` to pick automatically. */
960
1137
  parallel?: "auto" | number;
1138
+ /** Path to the `.rbxl` place uploaded and run. Default `"./game.rbxl"`. */
961
1139
  placeFile?: string;
1140
+ /** Open Cloud place id to publish/run against. */
962
1141
  placeId?: string;
1142
+ /** WebSocket port for the Studio backend. Default `3001`. */
963
1143
  port?: number;
1144
+ /**
1145
+ * Path to the Rojo project file used to map DataModel paths to source.
1146
+ * Auto-detected when unset.
1147
+ */
964
1148
  rojoProject?: string;
1149
+ /**
1150
+ * Base directory for resolving relative paths. Defaults to the current
1151
+ * working directory.
1152
+ */
965
1153
  rootDir?: string;
1154
+ /** Include the translated Luau line in error/stack output. Default `true`. */
966
1155
  showLuau?: boolean;
1156
+ /** Map Luau stack traces back to TypeScript source. Default `true`. */
967
1157
  sourceMap?: boolean;
1158
+ /**
1159
+ * Path to the Roblox Studio executable the `"studio-cli"` backend launches.
1160
+ * Overrides per-OS auto-discovery. Also settable via `--studioPath` or the
1161
+ * `JEST_ROBLOX_STUDIO_PATH` environment variable.
1162
+ */
1163
+ studioPath?: string;
1164
+ /**
1165
+ * The Jest options block. Every jest-passthrough setting lives here, kept
1166
+ * separate from the CLI/runner keys above.
1167
+ */
968
1168
  test?: GlobalTestConfig;
1169
+ /**
1170
+ * Maximum remote execution time in milliseconds before the run is
1171
+ * abandoned. Default `300000`.
1172
+ */
969
1173
  timeout?: number;
1174
+ /** Open Cloud universe id that owns the place. */
970
1175
  universeId?: string;
1176
+ /**
1177
+ * Workspace-mode knobs for multi-package runs. Ignored outside
1178
+ * `--workspace`.
1179
+ */
971
1180
  workspace?: WorkspaceConfig;
972
1181
  }
973
1182
  /**
@@ -1019,6 +1228,11 @@ interface CliOptions {
1019
1228
  files?: Array<string>;
1020
1229
  formatters?: Array<string>;
1021
1230
  gameOutput?: string;
1231
+ /**
1232
+ * Show the Studio window during a `studio-cli` run (`--headed`). CLI-only;
1233
+ * inert for every other backend. Never sourced from config or env.
1234
+ */
1235
+ headed?: boolean;
1022
1236
  help?: boolean;
1023
1237
  outputFile?: string;
1024
1238
  packages?: string;
@@ -1034,6 +1248,7 @@ interface CliOptions {
1034
1248
  showLuau?: boolean;
1035
1249
  silent?: boolean;
1036
1250
  sourceMap?: boolean;
1251
+ studioPath?: string;
1037
1252
  testNamePattern?: string;
1038
1253
  testPathPattern?: string;
1039
1254
  timeout?: number;
@@ -1048,13 +1263,9 @@ interface CliOptions {
1048
1263
  /** Directory to load the workspace config from when run outside a package. */
1049
1264
  workspaceRoot?: string;
1050
1265
  }
1051
- interface ConfigInput extends Except<Config, "formatters" | "luauRoots" | "test"> {
1052
- formatters?: Mergeable<Array<FormatterEntry>>;
1053
- luauRoots?: Mergeable<Array<string>>;
1054
- test?: GlobalTestConfigInput;
1055
- }
1266
+ type ConfigInput = { [K in keyof Config]?: K extends "formatters" ? Mergeable<Array<FormatterEntry>> : K extends "luauRoots" ? Mergeable<Array<string>> : K extends "test" ? GlobalTestConfigInput : Config[K] };
1056
1267
  type MergeableTestKey = "collectCoverageFrom" | "coveragePathIgnorePatterns" | "coverageReporters" | "coverageThreshold" | "reporters" | "roots" | "selectProjects" | "setupFiles" | "setupFilesAfterEnv" | "snapshotFormat" | "snapshotSerializers" | "testMatch" | "testPathIgnorePatterns";
1057
- type GlobalTestConfigInput = Except<GlobalTestConfig, MergeableTestKey> & { [K in MergeableTestKey]?: Mergeable<NonNullable<GlobalTestConfig[K]>> };
1268
+ type GlobalTestConfigInput = { [K in keyof GlobalTestConfig]?: K extends MergeableTestKey ? Mergeable<NonNullable<GlobalTestConfig[K]>> : GlobalTestConfig[K] };
1058
1269
  declare const SHARED_TEST_KEYS: ReadonlySet<string>;
1059
1270
  /** Keys valid in `test:` (root) but not per-project (`projects[N].test`). */
1060
1271
  declare const GLOBAL_TEST_KEYS: ReadonlySet<string>;
@@ -1067,7 +1278,28 @@ declare const ROOT_CLI_KEYS: ReadonlySet<string>;
1067
1278
  * (not jest itself).
1068
1279
  */
1069
1280
  declare const JEST_ARGV_EXCLUDED_KEYS: ReadonlySet<string>;
1281
+ /**
1282
+ * Identity helper for authoring a typed `jest.config.*` file. Returns its
1283
+ * input unchanged; it exists purely to give editors autocompletion and
1284
+ * type-checking for the root config shape (`Config` plus the c12 layer props
1285
+ * on `ConfigInput`).
1286
+ *
1287
+ * Use it as the default export of a config file discovered by c12 (`.ts`,
1288
+ * `.js`, `.mjs`, `.cjs`, `.json`, `.yaml`, `.toml`). All jest-passthrough
1289
+ * options live under the `test:` block; root keys are CLI/runner-level.
1290
+ * Configs may extend a shared base via `extends`, and any `Mergeable` array
1291
+ * field (e.g. `test.testMatch`) accepts a function that receives the inherited
1292
+ * defaults and returns the merged value. Precedence is CLI flags > config file
1293
+ * > extended config > defaults.
1294
+ */
1070
1295
  declare const defineConfig: (input: ConfigInput) => ConfigInput;
1296
+ /**
1297
+ * Identity helper for a single entry inside `test.projects`, mirroring
1298
+ * {@link defineConfig} for per-project overrides. Returns its input unchanged
1299
+ * and exists only for editor autocompletion and type-checking of the
1300
+ * `InlineProjectConfig` shape — a `test:` block carrying the project's
1301
+ * `include`/`displayName` plus any shared per-project jest options.
1302
+ */
1071
1303
  declare const defineProject: (input: InlineProjectConfig) => InlineProjectConfig;
1072
1304
  //#endregion
1073
1305
  export { SnapshotFormatOptions as _, DisplayName as a, defineProject as b, GlobalTestConfig as c, ProjectEntry as d, ProjectTestConfig as f, SharedTestConfig as g, SHARED_TEST_KEYS as h, DEFAULT_CONFIG as i, InlineProjectConfig as l, ResolvedConfig as m, Config as n, FormatterEntry as o, ROOT_CLI_KEYS as p, ConfigInput as r, GLOBAL_TEST_KEYS as s, CliOptions as t, JEST_ARGV_EXCLUDED_KEYS as u, WorkspaceConfig as v, TypecheckConfig as x, defineConfig as y };
@@ -9,7 +9,7 @@ interface ResolveResult {
9
9
  url: string;
10
10
  }
11
11
 
12
- type NextResolve = (specifier: string, context: ResolveContext) => Promise<ResolveResult>;
12
+ type NextResolve = (specifier: string, context: ResolveContext) => ResolveResult;
13
13
 
14
14
  interface LoadContext {
15
15
  conditions?: Array<string>;
@@ -23,12 +23,12 @@ interface LoadResult {
23
23
  source: string;
24
24
  }
25
25
 
26
- type NextLoad = (url: string, context: LoadContext) => Promise<LoadResult>;
26
+ type NextLoad = (url: string, context: LoadContext) => LoadResult;
27
27
 
28
28
  export function resolve(
29
29
  specifier: string,
30
30
  context: ResolveContext,
31
31
  nextResolve: NextResolve,
32
- ): Promise<ResolveResult>;
32
+ ): ResolveResult;
33
33
 
34
- export function load(url: string, context: LoadContext, nextLoad: NextLoad): Promise<LoadResult>;
34
+ export function load(url: string, context: LoadContext, nextLoad: NextLoad): LoadResult;
@@ -1,8 +1,8 @@
1
- import { readFile } from "node:fs/promises";
1
+ import { readFileSync } from "node:fs";
2
2
  import { fileURLToPath } from "node:url";
3
3
 
4
- export async function resolve(specifier, context, nextResolve) {
5
- const resolved = await nextResolve(specifier, context);
4
+ export function resolve(specifier, context, nextResolve) {
5
+ const resolved = nextResolve(specifier, context);
6
6
 
7
7
  if (resolved.url.endsWith(".luau") || resolved.url.endsWith(".lua")) {
8
8
  return { ...resolved, format: "luau-raw" };
@@ -11,7 +11,7 @@ export async function resolve(specifier, context, nextResolve) {
11
11
  return resolved;
12
12
  }
13
13
 
14
- export async function load(url, context, nextLoad) {
14
+ export function load(url, context, nextLoad) {
15
15
  if (context.format === "luau-raw") {
16
16
  if (url.endsWith(".lua")) {
17
17
  return {
@@ -21,7 +21,7 @@ export async function load(url, context, nextLoad) {
21
21
  };
22
22
  }
23
23
 
24
- const content = await readFile(fileURLToPath(url), "utf-8");
24
+ const content = readFileSync(fileURLToPath(url), "utf-8");
25
25
  return {
26
26
  format: "module",
27
27
  shortCircuit: true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@isentinel/jest-roblox",
3
- "version": "0.3.6",
3
+ "version": "0.3.8",
4
4
  "description": "Jest-compatible CLI for running roblox-ts tests via Roblox Open Cloud",
5
5
  "keywords": [
6
6
  "jest",
@@ -48,7 +48,7 @@
48
48
  "!dist/**/*.tsbuildinfo"
49
49
  ],
50
50
  "dependencies": {
51
- "@bedrock-rbx/ocale": "0.1.0-beta.18",
51
+ "@bedrock-rbx/ocale": "0.1.0-beta.19",
52
52
  "@jridgewell/trace-mapping": "0.3.31",
53
53
  "arktype": "2.2.0",
54
54
  "c12": "4.0.0-beta.5",
@@ -67,7 +67,7 @@
67
67
  },
68
68
  "devDependencies": {
69
69
  "@isentinel/eslint-config": "5.2.0",
70
- "@isentinel/roblox-ts": "4.0.7",
70
+ "@isentinel/roblox-ts": "4.0.10",
71
71
  "@isentinel/tsconfig": "1.2.0",
72
72
  "@isentinel/weld": "0.2.0",
73
73
  "@oxc-project/types": "0.123.0",
Binary file
@@ -12,11 +12,11 @@ local WEBSOCKET_URL = "ws://localhost:3001"
12
12
  local RECONNECT_DELAY = 0.1
13
13
 
14
14
  -- Plugin/CLI protocol version. Must match `STUDIO_PROTOCOL_VERSION` in
15
- -- `src/backends/studio.ts`. Bumped when the runtime contract changes (e.g.
16
- -- runtime-injection payload shape). The plugin rejects mismatched CLI
17
- -- versions with a `version_mismatch` response so users see a clear upgrade
15
+ -- `src/backends/studio.ts`. Bumped when the runtime contract changes — v3 added
16
+ -- the run-mode workspace dispatch + version echo. The plugin rejects mismatched
17
+ -- CLI versions with a `version_mismatch` response so users see a clear upgrade
18
18
  -- message rather than running with stale behaviour or an opaque timeout.
19
- local PROTOCOL_VERSION = 2
19
+ local PROTOCOL_VERSION = 3
20
20
 
21
21
  local IsDebug = ReplicatedStorage:GetAttribute("JEST_ROBLOX_DEBUG") == true
22
22
  ReplicatedStorage:GetAttributeChangedSignal("JEST_ROBLOX_DEBUG"):Connect(function(): ()
@@ -130,11 +130,18 @@ local function connect(): ()
130
130
  local runOk, result = pcall(function(): any
131
131
  return StudioTestService:ExecuteRunModeAsync({
132
132
  test = true,
133
+ -- Echo the negotiated version into the Run-mode payload so
134
+ -- the run-mode runner's own handshake passes (it validates
135
+ -- `protocolVersion`, shared with the studio-cli path).
136
+ protocolVersion = PROTOCOL_VERSION,
133
137
  config = message.config,
134
138
  -- Filtered injection targets (parallel to configs)
135
139
  -- so the Run Mode runner skips mounts that already
136
140
  -- have a user-authored jest.config on disk.
137
141
  runtimeStubMounts = message.runtimeStubMounts,
142
+ -- Present only for workspace runs: the staged entries the
143
+ -- run-mode runner dispatches to the embedded materializer.
144
+ workspace = message.workspace,
138
145
  })
139
146
  end)
140
147