@sdeverywhere/plugin-check 0.3.0 → 0.3.2

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/dist/index.js CHANGED
@@ -37,8 +37,8 @@ async function runTestSuite(context, config, verbose) {
37
37
  context.log("info", `
38
38
  Test suite completed in ${elapsed}s`);
39
39
  const allChecksPassed = printCheckSummary(context, report.checkReport, verbose);
40
- if (report.compareReport) {
41
- printPerfStats(context, config.compare, report.compareReport);
40
+ if (report.comparisonReport) {
41
+ printPerfStats(context, config.comparison, report.comparisonReport);
42
42
  }
43
43
  const suiteSummary = suiteSummaryFromReport(report);
44
44
  resolve({
@@ -119,18 +119,18 @@ function printPerfReportLine(context, perfReport) {
119
119
  const max = stat("max", perfReport.maxTime);
120
120
  context.log("info", ` ${avg} ${min} ${max}`);
121
121
  }
122
- function printPerfStats(context, compareConfig, report) {
122
+ function printPerfStats(context, comparisonConfig, report) {
123
123
  context.log("info", "\nPerformance stats:");
124
- context.log("info", ` ${compareConfig.bundleL.name}:`);
124
+ context.log("info", ` ${comparisonConfig.bundleL.name}:`);
125
125
  printPerfReportLine(context, report.perfReportL);
126
- context.log("info", ` ${compareConfig.bundleR.name}:`);
126
+ context.log("info", ` ${comparisonConfig.bundleR.name}:`);
127
127
  printPerfReportLine(context, report.perfReportR);
128
128
  context.log("info", "");
129
129
  }
130
130
 
131
131
  // src/vite-config-for-bundle.ts
132
132
  import { existsSync, statSync } from "fs";
133
- import { dirname, join as joinPath, relative, resolve as resolvePath } from "path";
133
+ import { basename, dirname, join as joinPath, relative, resolve as resolvePath } from "path";
134
134
  import { fileURLToPath } from "url";
135
135
  import { nodeResolve } from "@rollup/plugin-node-resolve";
136
136
 
@@ -152,12 +152,15 @@ function sdeNameForVensimVarName(varName) {
152
152
  }
153
153
 
154
154
  // src/vite-config-for-bundle.ts
155
- var __filename = fileURLToPath(import.meta.url);
156
- var __dirname = dirname(__filename);
155
+ var __filename2 = fileURLToPath(import.meta.url);
156
+ var __dirname2 = dirname(__filename2);
157
157
  function injectModelSpec(prepDir, modelSpec) {
158
158
  const inputSpecs = modelSpec.inputs.map((i) => {
159
+ const varId = sdeNameForVensimVarName(i.varName);
160
+ const inputId = i.inputId || varId;
159
161
  return {
160
- varId: sdeNameForVensimVarName(i.varName),
162
+ inputId,
163
+ varId,
161
164
  ...i
162
165
  };
163
166
  });
@@ -199,20 +202,58 @@ export const dataSizeInBytes = ${dataSizeInBytes};
199
202
  }
200
203
  };
201
204
  }
205
+ function overrideViteResolvePlugin(viteConfig) {
206
+ const resolvePlugin = viteConfig.plugins.find((p) => p.name === "vite:resolve");
207
+ if (resolvePlugin === void 0) {
208
+ throw new Error("Failed to locate the built-in vite:resolve plugin");
209
+ }
210
+ const originalResolveId = resolvePlugin.resolveId;
211
+ resolvePlugin.resolveId = async function resolveId(id, importer, options) {
212
+ if (id.startsWith("./implementation") && importer.includes("threads/dist-esm")) {
213
+ const idFileName = id.replace("./", "");
214
+ const importerFileName = basename(importer);
215
+ const resolvedId = importer.replace(importerFileName, `${idFileName}.js`);
216
+ return {
217
+ id: resolvedId,
218
+ moduleSideEffects: false
219
+ };
220
+ }
221
+ return originalResolveId.call(this, id, importer, options);
222
+ };
223
+ }
202
224
  async function createViteConfigForBundle(prepDir, modelSpec) {
203
- const root = resolvePath(__dirname, "..", "template-bundle");
225
+ const root = resolvePath(__dirname2, "..", "template-bundle");
204
226
  const outDir = relative(root, prepDir);
205
227
  const modelWorkerPath = joinPath(prepDir, "staged", "model", "worker.js?raw");
206
228
  return {
229
+ // Don't use an external config file
207
230
  configFile: false,
231
+ // Use the root directory configured above
208
232
  root,
233
+ // Don't clear the screen in dev mode so that we can see builder output
209
234
  clearScreen: false,
235
+ // TODO: Disable vite output by default?
236
+ // logLevel: 'silent',
237
+ // Configure path aliases
210
238
  resolve: {
211
239
  alias: [
240
+ // Inject the configured model worker
212
241
  {
213
242
  find: "@_model_worker_",
214
243
  replacement: modelWorkerPath
215
244
  },
245
+ // XXX: Prevent Vite from using the `browser` section of `threads/package.json`
246
+ // since we want to force the use of the general module (under dist-esm) that chooses
247
+ // the correct implementation (Web Worker vs worker_threads) at runtime. Currently
248
+ // Vite's library mode is browser focused and generally chooses the right imports,
249
+ // except in the case of the threads package where we want to use the generic
250
+ // `implementation.js` that chooses between Web Worker and worker_threads at runtime.
251
+ // Note that we could in theory set `resolve.browserField` to false, but that would
252
+ // make Vite not use the browser field for all other packages, and there is not
253
+ // currently a way to tell Vite to use the browser field on a case-by-case basis.
254
+ // So for now we need this workaround here to make it resolve to `dist-esm`, and then
255
+ // a second workaround in `overrideViteResolvePlugin` to prevent the resolver from
256
+ // using the browser field when resolving the threads package.
216
257
  {
217
258
  find: "threads",
218
259
  replacement: "threads",
@@ -229,18 +270,40 @@ async function createViteConfigForBundle(prepDir, modelSpec) {
229
270
  ]
230
271
  },
231
272
  plugins: [
232
- injectModelSpec(prepDir, modelSpec)
273
+ // Use a virtual module plugin to inject the model spec values
274
+ injectModelSpec(prepDir, modelSpec),
275
+ // XXX: Install a wrapper around the built-in `vite:resolve` plugin so that we can
276
+ // override the default resolver behavior that tries to resolve the `browser` section
277
+ // of the `package.json` for the threads package.
278
+ {
279
+ name: "vite-plugin-override-resolve",
280
+ configResolved(viteConfig) {
281
+ overrideViteResolvePlugin(viteConfig);
282
+ }
283
+ }
233
284
  ],
234
285
  build: {
286
+ // Write output files to the configured directory (instead of the default `dist`);
287
+ // note that this must be relative to the project `root`
235
288
  outDir,
236
289
  emptyOutDir: false,
290
+ // Uncomment for debugging purposes
291
+ // minify: false,
237
292
  lib: {
238
293
  entry: "./src/index.ts",
239
294
  formats: ["es"],
240
295
  fileName: () => "check-bundle.js"
241
296
  },
242
297
  rollupOptions: {
298
+ // Don't transform Node imports used by threads.js
243
299
  external: ["events", "os", "path", "url"],
300
+ // XXX: Insert custom code at the top of the generated bundle that defines
301
+ // the special `__non_webpack_require__` function that is used by threads.js
302
+ // in its Node implementation. This import ensures that threads.js uses
303
+ // the native `worker_threads` implementation when using the bundle in a
304
+ // Node environment. When importing the bundle for use in the browser,
305
+ // Vite will transform this import into an empty module due to the empty
306
+ // polyfill that is configured in `vite-config-for-report.ts`.
244
307
  output: {
245
308
  banner: `
246
309
  import * as worker_threads from 'worker_threads'
@@ -263,17 +326,16 @@ let __non_webpack_require__ = () => {
263
326
  import { dirname as dirname2, relative as relative2, join as joinPath2, resolve as resolvePath2 } from "path";
264
327
  import { fileURLToPath as fileURLToPath2 } from "url";
265
328
  import replace from "@rollup/plugin-replace";
266
- var __filename2 = fileURLToPath2(import.meta.url);
267
- var __dirname2 = dirname2(__filename2);
329
+ var __filename3 = fileURLToPath2(import.meta.url);
330
+ var __dirname3 = dirname2(__filename3);
268
331
  function createViteConfigForReport(options, projDir, prepDir, currentBundleName, currentBundlePath, testConfigPath, suiteSummary) {
269
- var _a;
270
- const root = resolvePath2(__dirname2, "..", "template-report");
332
+ const root = resolvePath2(__dirname3, "..", "template-report");
271
333
  const templateSrcDir = resolvePath2(root, "src");
272
334
  const relProjDir = relative2(templateSrcDir, projDir);
273
335
  const relProjDirPath = relProjDir.replaceAll("\\", "/");
274
336
  const baselinesPath = `${relProjDirPath}/baselines/*.js`;
275
337
  let reportPath;
276
- if (options == null ? void 0 : options.reportPath) {
338
+ if (options?.reportPath) {
277
339
  reportPath = options.reportPath;
278
340
  } else {
279
341
  reportPath = joinPath2(prepDir, "check-report");
@@ -293,57 +355,113 @@ function createViteConfigForReport(options, projDir, prepDir, currentBundleName,
293
355
  };
294
356
  };
295
357
  return {
358
+ // Don't use an external config file
296
359
  configFile: false,
360
+ // Use the root directory configured above
297
361
  root,
362
+ // Use `.` as the base directory (instead of the default `/`); this controls
363
+ // how the path to the js/css files are generated in `index.html`
298
364
  base: "",
365
+ // Use a custom cache directory under `prepDir`, as otherwise Vite will use
366
+ // `packages/plugin-check/template-report/node_modules/.vite`, and we want to
367
+ // avoid generating files in `template-report` (which should be read-only)
299
368
  cacheDir: joinPath2(prepDir, ".vite-check-report"),
369
+ // Load static files from `static` (instead of the default `public`)
370
+ // publicDir: 'static',
371
+ // Don't clear the screen in dev mode so that we can see builder output
300
372
  clearScreen: false,
373
+ // TODO
374
+ // logLevel: 'silent',
301
375
  optimizeDeps: {
376
+ // Prevent Vite from examining other html files when scanning entrypoints
377
+ // for dependency optimization
302
378
  entries: ["index.html"],
379
+ // XXX: When plugin-check is installed via pnpm, the Vite dev server seems
380
+ // to have no trouble resolving other dependencies using the optimizeDeps
381
+ // mechanism. However, this fails when the package is installed via yarn
382
+ // or npm (probably due to the fact that the `template-report` directory
383
+ // is located under the top-level `node_modules` directory); in the browser,
384
+ // there will be "import not found" errors for the packages referenced below.
385
+ // As a terrible workaround, explicitly include the direct dependencies so
386
+ // that Vite optimizes them; this works for pnpm, yarn, and npm. We should
387
+ // find a less fragile solution.
303
388
  include: [
304
- "assert-never",
305
- "ajv",
306
- "neverthrow",
307
- "yaml",
308
- "fontfaceobserver",
309
- "copy-text-to-clipboard",
310
- "chart.js"
389
+ // from check-core
390
+ "@sdeverywhere/check-core > assert-never",
391
+ "@sdeverywhere/check-core > ajv",
392
+ "@sdeverywhere/check-core > neverthrow",
393
+ "@sdeverywhere/check-core > yaml",
394
+ // from check-ui-shell
395
+ "@sdeverywhere/check-ui-shell > fontfaceobserver",
396
+ "@sdeverywhere/check-ui-shell > copy-text-to-clipboard",
397
+ "@sdeverywhere/check-ui-shell > chart.js"
311
398
  ],
312
399
  exclude: [
313
- "tiny-worker",
314
- "moment"
400
+ // XXX: The threads.js implementation references `tiny-worker` as an optional
401
+ // dependency, but it doesn't get used at runtime, so we can just exclude it
402
+ // so that Vite doesn't complain in dev mode
403
+ "tiny-worker"
404
+ // XXX: Similarly, chart.js treats `moment` as an optional dependency, but we
405
+ // don't use it at runtime; we need to exclude it here, otherwise Vite will
406
+ // complain about missing dependencies in dev mode
407
+ // 'moment'
315
408
  ]
316
409
  },
410
+ // Configure path aliases
317
411
  resolve: {
318
412
  alias: [
319
- alias("@_baseline_bundle_", (options == null ? void 0 : options.baseline) ? options.baseline.path : "/src/empty-bundle.ts"),
413
+ // Use the configured "baseline" bundle if defined, otherwise use the "empty" bundle
414
+ // (which will cause comparison tests to be skipped)
415
+ alias("@_baseline_bundle_", options?.baseline ? options.baseline.path : "/src/empty-bundle.ts"),
416
+ // Use the configured "current" bundle
320
417
  alias("@_current_bundle_", currentBundlePath),
418
+ // Use the configured test config file
321
419
  alias("@_test_config_", testConfigPath),
420
+ // Make the overlay use the `messages.html` file that is written to the prep directory
322
421
  alias("@_prep_", prepDir),
422
+ // XXX: Include no-op polyfills for these modules that are used in the Node-specific
423
+ // implementation of threads.js; this allows us to use one bundle that works in both
424
+ // Node and browser environments
323
425
  noopPolyfillAlias("events"),
426
+ noopPolyfillAlias("fs"),
324
427
  noopPolyfillAlias("os"),
325
428
  noopPolyfillAlias("path"),
326
- noopPolyfillAlias("url")
429
+ noopPolyfillAlias("url"),
430
+ noopPolyfillAlias("worker_threads")
327
431
  ]
328
432
  },
433
+ // Inject special values into the generated JS
329
434
  define: {
435
+ // Inject the summary JSON into the build
330
436
  __SUITE_SUMMARY_JSON__: JSON.stringify(suiteSummaryJson),
331
- __BASELINE_NAME__: JSON.stringify(((_a = options == null ? void 0 : options.baseline) == null ? void 0 : _a.name) || ""),
437
+ // Inject the baseline branch name
438
+ __BASELINE_NAME__: JSON.stringify(options?.baseline?.name || ""),
439
+ // Inject the current branch name
332
440
  __CURRENT_NAME__: JSON.stringify(currentBundleName)
333
441
  },
334
442
  plugins: [
443
+ // Inject special values into the generated JS
444
+ // TODO: We currently have to use `@rollup/plugin-replace` instead of Vite's
445
+ // built-in `define` feature because the latter does not seem to run before
446
+ // the glob handler (which requires the glob to be injected as a literal)
335
447
  replace({
336
448
  preventAssignment: true,
449
+ delimiters: ["", ""],
337
450
  values: {
338
- __BASELINE_BUNDLES_PATH__: JSON.stringify(baselinesPath)
451
+ // Inject the path for baseline bundles
452
+ "./__BASELINE_BUNDLES_PATH__": baselinesPath
339
453
  }
340
454
  })
341
455
  ],
342
456
  build: {
457
+ // Write output files to the configured directory (instead of the default `dist`);
458
+ // note that this must be relative to the project `root`
343
459
  outDir,
460
+ // Write js/css files to `public` (instead of the default `<outDir>/assets`)
344
461
  assetsDir: "",
345
462
  rollupOptions: {
346
463
  output: {
464
+ // XXX: Prevent vite from creating a separate `vendor.js` file
347
465
  manualChunks: void 0
348
466
  },
349
467
  onwarn: (warning, warn) => {
@@ -354,8 +472,14 @@ function createViteConfigForReport(options, projDir, prepDir, currentBundleName,
354
472
  }
355
473
  },
356
474
  server: {
357
- port: (options == null ? void 0 : options.serverPort) || 8081,
475
+ // Run the dev server at `localhost:8081` by default
476
+ port: options?.serverPort || 8081,
477
+ // Open the app in the browser by default
358
478
  open: "/index.html",
479
+ // XXX: Add a small delay, otherwise on macOS we sometimes get multiple
480
+ // change events when a file is saved just once. That is a relatively
481
+ // harmless issue except that it causes redundant messages in the console
482
+ // and can cause extra churn when refreshing the app.
359
483
  watch: {
360
484
  awaitWriteFinish: {
361
485
  stabilityThreshold: 100
@@ -368,23 +492,42 @@ function createViteConfigForReport(options, projDir, prepDir, currentBundleName,
368
492
  // src/vite-config-for-tests.ts
369
493
  import { dirname as dirname3, relative as relative3, resolve as resolvePath3 } from "path";
370
494
  import { fileURLToPath as fileURLToPath3 } from "url";
371
- var __filename3 = fileURLToPath3(import.meta.url);
372
- var __dirname3 = dirname3(__filename3);
495
+ import replace2 from "@rollup/plugin-replace";
496
+ var __filename4 = fileURLToPath3(import.meta.url);
497
+ var __dirname4 = dirname3(__filename4);
373
498
  function createViteConfigForTests(projDir, prepDir, mode) {
374
- const root = resolvePath3(__dirname3, "..", "template-tests");
499
+ const root = resolvePath3(__dirname4, "..", "template-tests");
375
500
  const templateSrcDir = resolvePath3(root, "src");
376
501
  const relProjDir = relative3(templateSrcDir, projDir);
377
502
  const relProjDirPath = relProjDir.replaceAll("\\", "/");
378
503
  const yamlPath = `${relProjDirPath}/**/*.check.yaml`;
379
504
  const outDir = relative3(root, prepDir);
380
505
  return {
506
+ // Don't use an external config file
381
507
  configFile: false,
508
+ // Use the root directory configured above
382
509
  root,
510
+ // Don't clear the screen in dev mode so that we can see builder output
383
511
  clearScreen: false,
384
- define: {
385
- __YAML_PATH__: JSON.stringify(yamlPath)
386
- },
512
+ // TODO: Disable vite output by default?
513
+ // logLevel: 'silent',
514
+ plugins: [
515
+ // Inject special values into the generated JS
516
+ // TODO: We currently have to use `@rollup/plugin-replace` instead of Vite's
517
+ // built-in `define` feature because the latter does not seem to run before
518
+ // the glob handler (which requires the glob to be injected as a literal)
519
+ replace2({
520
+ preventAssignment: true,
521
+ delimiters: ["", ""],
522
+ values: {
523
+ // Inject the glob pattern for matching check yaml files
524
+ "./__YAML_PATH__": yamlPath
525
+ }
526
+ })
527
+ ],
387
528
  build: {
529
+ // Write output files to the configured directory (instead of the default `dist`);
530
+ // note that this must be relative to the project `root`
388
531
  outDir,
389
532
  emptyOutDir: false,
390
533
  lib: {
@@ -392,8 +535,19 @@ function createViteConfigForTests(projDir, prepDir, mode) {
392
535
  formats: ["es"],
393
536
  fileName: () => "check-tests.js"
394
537
  },
538
+ // Enable watch mode if requested
395
539
  watch: mode === "watch" && {},
396
- rollupOptions: {}
540
+ rollupOptions: {
541
+ // Prevent dependencies from being included in packaged library
542
+ // TODO: For now we include check-core in the packaged library so that its
543
+ // dependencies are correctly resolved at runtime. Ideally this would only
544
+ // include a couple functions that are used for defining tests, but Vite 2.x
545
+ // does not implement tree shaking for ES libraries, which means the generated
546
+ // library is much larger than it needs to be. Once we upgrade to Vite 3.x,
547
+ // the generated library should be smaller; see related fix:
548
+ // https://github.com/vitejs/vite/pull/8737
549
+ // external: Object.keys(pkg.dependencies)
550
+ }
397
551
  }
398
552
  };
399
553
  }
@@ -408,8 +562,7 @@ var CheckPlugin = class {
408
562
  this.firstBuild = true;
409
563
  }
410
564
  async watch(config) {
411
- var _a;
412
- if (((_a = this.options) == null ? void 0 : _a.testConfigPath) === void 0) {
565
+ if (this.options?.testConfigPath === void 0) {
413
566
  await this.genTestConfig(config, "watch");
414
567
  }
415
568
  const testOptions = this.resolveTestOptions(config);
@@ -418,8 +571,12 @@ var CheckPlugin = class {
418
571
  await server.listen();
419
572
  const baselinesDir = "baselines";
420
573
  const watcher = chokidar.watch(baselinesDir, {
574
+ // Watch paths are resolved relative to the project root directory
421
575
  cwd: config.rootDir,
576
+ // Don't send initial "file added" events
422
577
  ignoreInitial: true,
578
+ // XXX: Include a delay, otherwise on macOS we sometimes get multiple
579
+ // change events when a file is saved just once
423
580
  awaitWriteFinish: {
424
581
  stabilityThreshold: 200
425
582
  }
@@ -427,18 +584,22 @@ var CheckPlugin = class {
427
584
  watcher.on("add", () => server.restart());
428
585
  watcher.on("unlink", () => server.restart());
429
586
  }
587
+ // TODO: Note that this plugin runs as a `postBuild` step because it currently
588
+ // needs to run after other plugins, and those plugins need to run after the
589
+ // staged files are copied to their final destination(s). We should probably
590
+ // make it configurable so that it can either be run as a `postGenerate` or a
591
+ // `postBuild` step.
430
592
  async postBuild(context, modelSpec) {
431
- var _a, _b;
432
593
  const firstBuild = this.firstBuild;
433
594
  this.firstBuild = false;
434
- if (((_a = this.options) == null ? void 0 : _a.current) === void 0) {
595
+ if (this.options?.current === void 0) {
435
596
  if (context.config.mode === "development") {
436
597
  await this.copyPreviousBundle(context.config);
437
598
  }
438
599
  context.log("info", "Generating model check bundle...");
439
600
  await this.genCurrentBundle(context.config, modelSpec);
440
601
  }
441
- if (((_b = this.options) == null ? void 0 : _b.testConfigPath) === void 0) {
602
+ if (this.options?.testConfigPath === void 0) {
442
603
  if (context.config.mode === "production" || firstBuild) {
443
604
  context.log("info", "Generating model check test configuration...");
444
605
  await this.genTestConfig(context.config, "build");
@@ -474,38 +635,42 @@ var CheckPlugin = class {
474
635
  await build(viteConfig);
475
636
  }
476
637
  async runChecks(context, testOptions) {
477
- var _a;
478
638
  context.log("info", "Running model checks...");
479
639
  const moduleR = await import(relativeToSourcePath(testOptions.currentBundlePath));
480
640
  const bundleR = moduleR.createBundle();
481
- const nameR = testOptions.currentBundleName;
641
+ const bundleNameR = testOptions.currentBundleName;
482
642
  let bundleL;
483
- let nameL;
484
- if ((_a = this.options) == null ? void 0 : _a.baseline) {
643
+ let bundleNameL;
644
+ if (this.options?.baseline) {
485
645
  const moduleL = await import(relativeToSourcePath(this.options.baseline.path));
486
646
  const rawBundleL = moduleL.createBundle();
487
647
  if (rawBundleL.version === bundleR.version) {
488
648
  bundleL = rawBundleL;
489
- nameL = this.options.baseline.name;
649
+ bundleNameL = this.options.baseline.name;
490
650
  }
491
651
  }
492
652
  const testConfigModule = await import(relativeToSourcePath(testOptions.testConfigPath));
493
- const checkOptions = await testConfigModule.getConfigOptions(bundleL, bundleR, {
494
- nameL,
495
- nameR
496
- });
497
- const checkConfig = await createConfig(checkOptions);
498
- const result = await runTestSuite(context, checkConfig, false);
653
+ const configInitOptions = {
654
+ bundleNameL,
655
+ bundleNameR
656
+ };
657
+ const configOptions = await testConfigModule.getConfigOptions(bundleL, bundleR, configInitOptions);
658
+ const checkConfig = await createConfig(configOptions);
659
+ const result = await runTestSuite(
660
+ context,
661
+ checkConfig,
662
+ /*verbose=*/
663
+ false
664
+ );
499
665
  context.log("info", "Building model check report");
500
666
  const viteConfig = this.createViteConfigForReport(context.config, testOptions, result.suiteSummary);
501
667
  await build(viteConfig);
502
668
  return result.allChecksPassed;
503
669
  }
504
670
  resolveTestOptions(config) {
505
- var _a, _b;
506
671
  let currentBundleName;
507
672
  let currentBundlePath;
508
- if (((_a = this.options) == null ? void 0 : _a.current) === void 0) {
673
+ if (this.options?.current === void 0) {
509
674
  currentBundleName = "current";
510
675
  currentBundlePath = joinPath3(config.prepDir, "check-bundle.js");
511
676
  } else {
@@ -513,7 +678,7 @@ var CheckPlugin = class {
513
678
  currentBundlePath = this.options.current.path;
514
679
  }
515
680
  let testConfigPath;
516
- if (((_b = this.options) == null ? void 0 : _b.testConfigPath) === void 0) {
681
+ if (this.options?.testConfigPath === void 0) {
517
682
  testConfigPath = joinPath3(config.prepDir, "check-tests.js");
518
683
  } else {
519
684
  testConfigPath = this.options.testConfigPath;