@rstest/core 0.0.4 → 0.0.6

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/worker.js CHANGED
@@ -5081,18 +5081,23 @@ var __webpack_modules__ = {
5081
5081
  arr
5082
5082
  ];
5083
5083
  };
5084
- const prettyTime = (milliseconds, shouldFormat = true)=>{
5085
- const format = (time)=>shouldFormat ? picocolors__WEBPACK_IMPORTED_MODULE_2___default().bold(time) : time;
5086
- const indent = shouldFormat ? ' ' : '';
5087
- if (milliseconds < 1000) return `${Math.round(milliseconds)}${indent}ms`;
5084
+ const prettyTime = (milliseconds)=>{
5085
+ if (milliseconds < 1000) return `${Math.round(milliseconds)}ms`;
5088
5086
  const seconds = milliseconds / 1000;
5089
- if (seconds < 10) {
5090
- const digits = seconds >= 0.01 ? 2 : 3;
5091
- return `${format(seconds.toFixed(digits))}${indent}s`;
5087
+ const getSecond = (seconds, needDigits)=>{
5088
+ if (!needDigits || seconds === Math.ceil(seconds)) return `${Math.round(seconds).toString()}s`;
5089
+ const digits = seconds < 10 ? seconds >= 0.01 ? 2 : 3 : 1;
5090
+ return `${seconds.toFixed(digits)}s`;
5091
+ };
5092
+ const minutes = Math.floor(seconds / 60);
5093
+ const secondsRemainder = seconds % 60;
5094
+ let time = '';
5095
+ if (minutes > 0) time += `${minutes}m`;
5096
+ if (secondsRemainder > 0) {
5097
+ if (minutes > 0) time += ' ';
5098
+ time += getSecond(secondsRemainder, !minutes);
5092
5099
  }
5093
- if (seconds < 60) return `${format(seconds.toFixed(1))}${indent}s`;
5094
- const minutes = seconds / 60;
5095
- return `${format(minutes.toFixed(2))}${indent}m`;
5100
+ return time;
5096
5101
  };
5097
5102
  const getTaskNames = (test)=>(test.parentNames || []).concat(test.name).filter(Boolean);
5098
5103
  const getTaskNameWithPrefix = (test, delimiter = _constants__WEBPACK_IMPORTED_MODULE_1__.Qd)=>getTaskNames(test).join(` ${delimiter} `);
@@ -5649,6 +5654,7 @@ const loadModule_createRequire = (filename, distPath, rstestContext, assetFiles,
5649
5654
  const defineRstestDynamicImport = ({ testPath, interopDefault, returnModule = false })=>async (specifier, importAttributes)=>{
5650
5655
  const resolvedPath = isAbsolute(specifier) ? pathToFileURL(specifier) : await import.meta.resolve(specifier, pathToFileURL(testPath));
5651
5656
  const modulePath = 'string' == typeof resolvedPath ? resolvedPath : resolvedPath.pathname;
5657
+ if (importAttributes?.with?.rstest) delete importAttributes.with.rstest;
5652
5658
  const importedModule = await import(modulePath, importAttributes);
5653
5659
  if (shouldInterop({
5654
5660
  interopDefault,
@@ -5767,6 +5773,8 @@ const getGlobalApi = (api)=>constants.io.reduce((apis, key)=>{
5767
5773
  apis[key] = api[key];
5768
5774
  return apis;
5769
5775
  }, {});
5776
+ const listeners = [];
5777
+ let isTeardown = false;
5770
5778
  const preparePool = async ({ entryInfo: { distPath, testPath }, sourceMaps, updateSnapshot, context })=>{
5771
5779
  context.runtimeConfig = (0, helper.PQ)(context.runtimeConfig);
5772
5780
  const cleanupFns = [];
@@ -5805,25 +5813,36 @@ const preparePool = async ({ entryInfo: { distPath, testPath }, sourceMaps, upda
5805
5813
  return null;
5806
5814
  }
5807
5815
  });
5816
+ listeners.forEach((fn)=>fn());
5817
+ listeners.length = 0;
5808
5818
  const unhandledErrors = [];
5809
5819
  const handleError = (e, type)=>{
5810
5820
  e.name = type;
5811
- console.error(e);
5812
- unhandledErrors.push(e);
5821
+ if (isTeardown) {
5822
+ e.stack = `${helper.$_.yellow('Caught error after test environment was torn down:')}\n\n${e.stack}`;
5823
+ console.error(e);
5824
+ } else {
5825
+ console.error(e);
5826
+ unhandledErrors.push(e);
5827
+ }
5813
5828
  };
5814
5829
  const uncaughtException = (e)=>handleError(e, 'uncaughtException');
5815
5830
  const unhandledRejection = (e)=>handleError(e, 'unhandledRejection');
5816
5831
  process.on('uncaughtException', uncaughtException);
5817
5832
  process.on('unhandledRejection', unhandledRejection);
5818
- cleanupFns.push(()=>{
5833
+ listeners.push(()=>{
5819
5834
  process.off('uncaughtException', uncaughtException);
5820
5835
  process.off('unhandledRejection', unhandledRejection);
5821
5836
  });
5822
5837
  const { api, runner } = createRstestRuntime(workerState);
5823
5838
  if ('jsdom' === testEnvironment) {
5824
- const { environment } = await __webpack_require__.e("202").then(__webpack_require__.bind(__webpack_require__, "./src/runtime/worker/env/jsdom.ts"));
5839
+ const { environment } = await __webpack_require__.e("965").then(__webpack_require__.bind(__webpack_require__, "./src/runtime/worker/env/jsdom.ts"));
5825
5840
  const { teardown } = await environment.setup(global, {});
5826
5841
  cleanupFns.push(()=>teardown(global));
5842
+ } else if ('happy-dom' === testEnvironment) {
5843
+ const { environment } = await __webpack_require__.e("44").then(__webpack_require__.bind(__webpack_require__, "./src/runtime/worker/env/happyDom.ts"));
5844
+ const { teardown } = await environment.setup(global, {});
5845
+ cleanupFns.push(async ()=>await teardown(global));
5827
5846
  }
5828
5847
  const rstestContext = {
5829
5848
  global,
@@ -5844,10 +5863,20 @@ const preparePool = async ({ entryInfo: { distPath, testPath }, sourceMaps, upda
5844
5863
  }
5845
5864
  };
5846
5865
  };
5847
- const loadFiles = async ({ setupEntries, assetFiles, rstestContext, distPath, testPath, interopDefault })=>{
5866
+ const loadFiles = async ({ setupEntries, assetFiles, rstestContext, distPath, testPath, interopDefault, isolate })=>{
5867
+ if (!isolate) await loadModule({
5868
+ codeContent: `if (global && typeof global.__rstest_clean_core_cache__ === 'function') {
5869
+ global.__rstest_clean_core_cache__();
5870
+ }`,
5871
+ distPath,
5872
+ testPath,
5873
+ rstestContext,
5874
+ assetFiles,
5875
+ interopDefault
5876
+ });
5848
5877
  for (const { distPath, testPath } of setupEntries){
5849
5878
  const setupCodeContent = assetFiles[distPath];
5850
- await cacheableLoadModule({
5879
+ await loadModule({
5851
5880
  codeContent: setupCodeContent,
5852
5881
  distPath,
5853
5882
  testPath,
@@ -5856,7 +5885,7 @@ const loadFiles = async ({ setupEntries, assetFiles, rstestContext, distPath, te
5856
5885
  interopDefault
5857
5886
  });
5858
5887
  }
5859
- await cacheableLoadModule({
5888
+ await loadModule({
5860
5889
  codeContent: assetFiles[distPath],
5861
5890
  distPath,
5862
5891
  testPath,
@@ -5866,8 +5895,16 @@ const loadFiles = async ({ setupEntries, assetFiles, rstestContext, distPath, te
5866
5895
  });
5867
5896
  };
5868
5897
  const runInPool = async (options)=>{
5869
- const { entryInfo: { distPath, testPath }, setupEntries, assetFiles, type } = options;
5898
+ isTeardown = false;
5899
+ const { entryInfo: { distPath, testPath }, setupEntries, assetFiles, type, context: { runtimeConfig: { isolate } } } = options;
5870
5900
  const cleanups = [];
5901
+ const exit = process.exit;
5902
+ process.exit = (code = process.exitCode || 0)=>{
5903
+ throw new Error(`process.exit unexpectedly called with "${code}"`);
5904
+ };
5905
+ cleanups.push(()=>{
5906
+ process.exit = exit;
5907
+ });
5871
5908
  if ('collect' === type) try {
5872
5909
  const { rstestContext, runner, cleanup, unhandledErrors, interopDefault } = await preparePool(options);
5873
5910
  cleanups.push(cleanup);
@@ -5877,7 +5914,8 @@ const runInPool = async (options)=>{
5877
5914
  testPath,
5878
5915
  assetFiles,
5879
5916
  setupEntries,
5880
- interopDefault
5917
+ interopDefault,
5918
+ isolate
5881
5919
  });
5882
5920
  const tests = await runner.collectTests();
5883
5921
  return {
@@ -5893,12 +5931,9 @@ const runInPool = async (options)=>{
5893
5931
  };
5894
5932
  } finally{
5895
5933
  await Promise.all(cleanups.map((fn)=>fn()));
5934
+ isTeardown = true;
5896
5935
  }
5897
- const exit = process.exit;
5898
5936
  try {
5899
- process.exit = (code = process.exitCode || 0)=>{
5900
- throw new Error(`process.exit unexpectedly called with "${code}"`);
5901
- };
5902
5937
  const { rstestContext, runner, rpc, api, cleanup, unhandledErrors, interopDefault } = await preparePool(options);
5903
5938
  cleanups.push(cleanup);
5904
5939
  await loadFiles({
@@ -5907,7 +5942,8 @@ const runInPool = async (options)=>{
5907
5942
  testPath,
5908
5943
  assetFiles,
5909
5944
  setupEntries,
5910
- interopDefault
5945
+ interopDefault,
5946
+ isolate
5911
5947
  });
5912
5948
  const results = await runner.runTests(testPath, {
5913
5949
  onTestFileStart: async (test)=>{
@@ -5935,7 +5971,7 @@ const runInPool = async (options)=>{
5935
5971
  };
5936
5972
  } finally{
5937
5973
  await Promise.all(cleanups.map((fn)=>fn()));
5938
- process.exit = exit;
5974
+ isTeardown = true;
5939
5975
  }
5940
5976
  };
5941
5977
  const worker = runInPool;
@@ -197,7 +197,7 @@ export declare interface RstestConfig {
197
197
  *
198
198
  * @default 'node'
199
199
  */
200
- testEnvironment?: 'node' | 'jsdom';
200
+ testEnvironment?: 'node' | 'jsdom' | 'happy-dom';
201
201
  /**
202
202
  * print console traces when calling any console method.
203
203
  *
@@ -230,6 +230,11 @@ export declare interface RstestConfig {
230
230
  * @default 5000
231
231
  */
232
232
  testTimeout?: number;
233
+ /**
234
+ * Timeout of hook in milliseconds.
235
+ * @default 10000
236
+ */
237
+ hookTimeout?: number;
233
238
  /**
234
239
  * Automatically clear mock calls, instances, contexts and results before every test.
235
240
  * @default false
@@ -587,7 +587,7 @@ export declare interface RstestConfig {
587
587
  *
588
588
  * @default 'node'
589
589
  */
590
- testEnvironment?: 'node' | 'jsdom';
590
+ testEnvironment?: 'node' | 'jsdom' | 'happy-dom';
591
591
  /**
592
592
  * print console traces when calling any console method.
593
593
  *
@@ -620,6 +620,11 @@ export declare interface RstestConfig {
620
620
  * @default 5000
621
621
  */
622
622
  testTimeout?: number;
623
+ /**
624
+ * Timeout of hook in milliseconds.
625
+ * @default 10000
626
+ */
627
+ hookTimeout?: number;
623
628
  /**
624
629
  * Automatically clear mock calls, instances, contexts and results before every test.
625
630
  * @default false
@@ -715,42 +720,46 @@ declare type RstestUtilities = {
715
720
  */
716
721
  restoreAllMocks: () => RstestUtilities;
717
722
  /**
718
- * @todo
719
723
  * Mock a module
720
724
  */
721
725
  mock: <T = unknown>(moduleName: string, moduleFactory?: () => T) => void;
722
726
  /**
723
- * @todo
727
+ * Mock a module
728
+ */
729
+ mockRequire: <T = unknown>(moduleName: string, moduleFactory?: () => T) => void;
730
+ /**
724
731
  * Mock a module, not hoisted.
725
732
  */
726
733
  doMock: <T = unknown>(moduleName: string, moduleFactory?: () => T) => void;
727
734
  /**
728
- * @todo
735
+ * Mock a module, not hoisted.
736
+ */
737
+ doMockRequire: <T = unknown>(moduleName: string, moduleFactory?: () => T) => void;
738
+ /**
729
739
  * Removes module from the mocked registry.
730
740
  */
731
- unMock: (path: string) => void;
741
+ unmock: (path: string) => void;
732
742
  /**
733
- * @todo
734
743
  * Removes module from the mocked registry, not hoisted.
735
744
  */
736
- doUnMock: (path: string) => void;
745
+ doUnmock: (path: string) => void;
737
746
  /**
738
- * @todo
739
747
  * Imports a module with all of its properties (including nested properties) mocked.
740
748
  */
741
749
  importMock: <T = Record<string, unknown>>(path: string) => Promise<T>;
742
750
  /**
743
- * @todo
751
+ * Imports a module with all of its properties (including nested properties) mocked.
752
+ */
753
+ requireMock: <T = Record<string, unknown>>(path: string) => T;
754
+ /**
744
755
  * Import and return the actual module instead of a mock, bypassing all checks on whether the module should receive a mock implementation or not.
745
756
  */
746
757
  importActual: <T = Record<string, unknown>>(path: string) => Promise<T>;
747
758
  /**
748
- * @todo
749
759
  * Require and return the actual module instead of a mock, bypassing all checks on whether the module should receive a mock implementation or not.
750
760
  */
751
761
  requireActual: <T = Record<string, unknown>>(path: string) => T;
752
762
  /**
753
- * @todo
754
763
  * Resets modules registry by clearing the cache of all modules.
755
764
  */
756
765
  resetModules: () => RstestUtilities;
@@ -335,7 +335,7 @@ declare interface RstestConfig {
335
335
  *
336
336
  * @default 'node'
337
337
  */
338
- testEnvironment?: 'node' | 'jsdom';
338
+ testEnvironment?: 'node' | 'jsdom' | 'happy-dom';
339
339
  /**
340
340
  * print console traces when calling any console method.
341
341
  *
@@ -368,6 +368,11 @@ declare interface RstestConfig {
368
368
  * @default 5000
369
369
  */
370
370
  testTimeout?: number;
371
+ /**
372
+ * Timeout of hook in milliseconds.
373
+ * @default 10000
374
+ */
375
+ hookTimeout?: number;
371
376
  /**
372
377
  * Automatically clear mock calls, instances, contexts and results before every test.
373
378
  * @default false
@@ -457,7 +462,7 @@ declare const runInPool: (options: RunWorkerOptions["options"]) => Promise<{
457
462
  } | TestFileResult>;
458
463
  export default runInPool;
459
464
 
460
- declare type RuntimeConfig = Pick<RstestContext['normalizedConfig'], 'testTimeout' | 'testNamePattern' | 'globals' | 'passWithNoTests' | 'retry' | 'clearMocks' | 'resetMocks' | 'restoreMocks' | 'unstubEnvs' | 'unstubGlobals' | 'maxConcurrency' | 'printConsoleTrace' | 'disableConsoleIntercept' | 'testEnvironment'>;
465
+ declare type RuntimeConfig = Pick<RstestContext['normalizedConfig'], 'testTimeout' | 'testNamePattern' | 'globals' | 'passWithNoTests' | 'retry' | 'clearMocks' | 'resetMocks' | 'restoreMocks' | 'unstubEnvs' | 'unstubGlobals' | 'maxConcurrency' | 'printConsoleTrace' | 'disableConsoleIntercept' | 'testEnvironment' | 'isolate' | 'hookTimeout'>;
461
466
 
462
467
  /** Runtime to Server */
463
468
  declare type RuntimeRPC = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rstest/core",
3
- "version": "0.0.4",
3
+ "version": "0.0.6",
4
4
  "description": "The Rsbuild-based test tool.",
5
5
  "bugs": {
6
6
  "url": "https://github.com/web-infra-dev/rstest/issues"
@@ -48,7 +48,7 @@
48
48
  "importMeta.d.ts"
49
49
  ],
50
50
  "dependencies": {
51
- "@rsbuild/core": "1.4.2",
51
+ "@rsbuild/core": "1.4.3",
52
52
  "@types/chai": "^5.2.2",
53
53
  "@vitest/expect": "^3.2.4",
54
54
  "@vitest/snapshot": "^3.2.4",
@@ -59,21 +59,22 @@
59
59
  "tinypool": "^1.1.1"
60
60
  },
61
61
  "devDependencies": {
62
- "@sinonjs/fake-timers": "^14.0.0",
63
62
  "@babel/code-frame": "^7.27.1",
64
- "@jridgewell/trace-mapping": "0.3.27",
63
+ "@jridgewell/trace-mapping": "0.3.29",
65
64
  "@microsoft/api-extractor": "^7.52.8",
66
65
  "@rslib/core": "0.10.4",
66
+ "@sinonjs/fake-timers": "^14.0.0",
67
67
  "@types/babel__code-frame": "^7.0.6",
68
- "@types/sinonjs__fake-timers": "^8.1.5",
69
68
  "@types/jsdom": "^21.1.7",
70
- "jsdom": "^26.1.0",
69
+ "@types/sinonjs__fake-timers": "^8.1.5",
71
70
  "@types/source-map-support": "^0.5.10",
72
71
  "cac": "^6.7.14",
72
+ "happy-dom": "^18.0.1",
73
73
  "jest-diff": "^30.0.3",
74
+ "jsdom": "^26.1.0",
74
75
  "license-webpack-plugin": "^4.0.2",
75
76
  "picocolors": "^1.1.1",
76
- "rslog": "^1.2.8",
77
+ "rslog": "^1.2.9",
77
78
  "source-map-support": "^0.5.21",
78
79
  "stacktrace-parser": "0.1.11",
79
80
  "tinyglobby": "^0.2.14",
@@ -81,9 +82,13 @@
81
82
  "@rstest/tsconfig": "0.0.1"
82
83
  },
83
84
  "peerDependencies": {
85
+ "happy-dom": "*",
84
86
  "jsdom": "*"
85
87
  },
86
88
  "peerDependenciesMeta": {
89
+ "happy-dom": {
90
+ "optional": true
91
+ },
87
92
  "jsdom": {
88
93
  "optional": true
89
94
  }