@react-native-harness/runtime 1.0.0-alpha.10 → 1.0.0-alpha.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/README.md +23 -4
  2. package/assets/moduleSystem.flow.js +8 -0
  3. package/dist/bundler/factory.d.ts +3 -0
  4. package/dist/bundler/factory.d.ts.map +1 -0
  5. package/dist/bundler/factory.js +36 -0
  6. package/dist/bundler/index.d.ts +2 -1
  7. package/dist/bundler/index.d.ts.map +1 -1
  8. package/dist/bundler/index.js +1 -1
  9. package/dist/bundler/types.d.ts +7 -0
  10. package/dist/bundler/types.d.ts.map +1 -0
  11. package/dist/bundler/types.js +1 -0
  12. package/dist/client/factory.d.ts.map +1 -1
  13. package/dist/client/factory.js +12 -5
  14. package/dist/client/getDeviceDescriptor.d.ts +1 -1
  15. package/dist/client/getDeviceDescriptor.d.ts.map +1 -1
  16. package/dist/client/getDeviceDescriptor.js +18 -6
  17. package/dist/collector/functions.d.ts.map +1 -1
  18. package/dist/collector/functions.js +8 -0
  19. package/dist/filtering/index.d.ts +2 -0
  20. package/dist/filtering/index.d.ts.map +1 -0
  21. package/dist/filtering/index.js +1 -0
  22. package/dist/filtering/testNameFilter.d.ts +6 -0
  23. package/dist/filtering/testNameFilter.d.ts.map +1 -0
  24. package/dist/filtering/testNameFilter.js +25 -0
  25. package/dist/index.d.ts +2 -0
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +2 -0
  28. package/dist/mocker/index.d.ts +1 -1
  29. package/dist/mocker/index.d.ts.map +1 -1
  30. package/dist/mocker/index.js +1 -1
  31. package/dist/mocker/registry.d.ts +2 -2
  32. package/dist/mocker/registry.d.ts.map +1 -1
  33. package/dist/mocker/registry.js +10 -4
  34. package/dist/namespace.d.ts +18 -0
  35. package/dist/namespace.d.ts.map +1 -0
  36. package/dist/namespace.js +19 -0
  37. package/dist/runner/runSuite.d.ts.map +1 -1
  38. package/dist/runner/runSuite.js +37 -0
  39. package/dist/tsconfig.lib.tsbuildinfo +1 -1
  40. package/dist/ui/state.d.ts +1 -1
  41. package/dist/utils/progressLogger.d.ts +2 -2
  42. package/dist/utils/progressLogger.d.ts.map +1 -1
  43. package/dist/utils/progressLogger.js +6 -0
  44. package/dist/waitFor.d.ts +21 -0
  45. package/dist/waitFor.d.ts.map +1 -0
  46. package/dist/waitFor.js +133 -0
  47. package/package.json +2 -2
  48. package/src/bundler/factory.ts +43 -0
  49. package/src/bundler/index.ts +2 -1
  50. package/src/bundler/types.ts +7 -0
  51. package/src/client/factory.ts +26 -7
  52. package/src/client/getDeviceDescriptor.ts +29 -8
  53. package/src/collector/functions.ts +14 -0
  54. package/src/filtering/index.ts +1 -0
  55. package/src/filtering/testNameFilter.ts +37 -0
  56. package/src/index.ts +2 -0
  57. package/src/mocker/index.ts +7 -1
  58. package/src/mocker/metro-require.d.ts +1 -0
  59. package/src/mocker/registry.ts +13 -5
  60. package/src/namespace.ts +41 -0
  61. package/src/runner/runSuite.ts +43 -0
  62. package/src/utils/progressLogger.ts +8 -1
  63. package/src/waitFor.ts +194 -0
package/README.md CHANGED
@@ -1,7 +1,26 @@
1
- # @react-native-harness/runtime
1
+ ![harness-banner](https://react-native-harness.dev/harness-banner.jpg)
2
2
 
3
- This library was generated with [Nx](https://nx.dev).
3
+ ### Test Runtime for React Native Harness
4
4
 
5
- ## Running unit tests
5
+ [![mit licence][license-badge]][license]
6
+ [![npm downloads][npm-downloads-badge]][npm-downloads]
7
+ [![Chat][chat-badge]][chat]
8
+ [![PRs Welcome][prs-welcome-badge]][prs-welcome]
6
9
 
7
- Run `nx test @react-native-harness/runtime` to execute the unit tests via [Jest](https://jestjs.io).
10
+ The core test runtime that executes on React Native devices, providing Jest-compatible APIs (describe, it, expect) and managing test collection, execution, and result reporting in native environments.
11
+
12
+ ## Made with ❤️ at Callstack
13
+
14
+ `@react-native-harness/runtime` is an open source project and will always remain free to use. If you think it's cool, please star it 🌟. [Callstack][callstack-readme-with-love] is a group of React and React Native geeks, contact us at [hello@callstack.com](mailto:hello@callstack.com) if you need any help with these or just want to say hi!
15
+
16
+ Like the project? ⚛️ [Join the team](https://callstack.com/careers/?utm_campaign=Senior_RN&utm_source=github&utm_medium=readme) who does amazing stuff for clients and drives React Native Open Source! 🔥
17
+
18
+ [callstack-readme-with-love]: https://callstack.com/?utm_source=github.com&utm_medium=referral&utm_campaign=react-native-harness&utm_term=readme-with-love
19
+ [license-badge]: https://img.shields.io/npm/l/@react-native-harness/runtime?style=for-the-badge
20
+ [license]: https://github.com/callstackincubator/react-native-harness/blob/main/LICENSE
21
+ [npm-downloads-badge]: https://img.shields.io/npm/dm/@react-native-harness/runtime?style=for-the-badge
22
+ [npm-downloads]: https://www.npmjs.com/package/@react-native-harness/runtime
23
+ [prs-welcome-badge]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=for-the-badge
24
+ [prs-welcome]: ../../CONTRIBUTING.md
25
+ [chat-badge]: https://img.shields.io/discord/426714625279524876.svg?style=for-the-badge
26
+ [chat]: https://discord.gg/xgGt7KAjxv
@@ -84,9 +84,17 @@ global.__r = (metroRequire: RequireFn);
84
84
  global[`${__METRO_GLOBAL_PREFIX__}__d`] = (define: DefineFn);
85
85
  global.__c = clear;
86
86
  global.__registerSegment = registerSegment;
87
+ global.__resetAllModules = resetAllModules;
87
88
 
88
89
  var modules = clear();
89
90
 
91
+ function resetAllModules() {
92
+ modules.forEach((mod) => {
93
+ // Mutating existing module doesn't work for some reason
94
+ modules.set(mod.id, { ...mod, isInitialized: false });
95
+ });
96
+ }
97
+
90
98
  // Don't use a Symbol here, it would pull in an extra polyfill with all sorts of
91
99
  // additional stuff (e.g. Array.from).
92
100
  const EMPTY = {};
@@ -0,0 +1,3 @@
1
+ import { Bundler } from './types.js';
2
+ export declare const getBundler: () => Bundler;
3
+ //# sourceMappingURL=factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/bundler/factory.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAIrC,eAAO,MAAM,UAAU,QAAO,OAoC7B,CAAC"}
@@ -0,0 +1,36 @@
1
+ import { getEmitter } from '../utils/emitter.js';
2
+ import { fetchModule } from './bundle.js';
3
+ import { BundlingFailedError } from './errors.js';
4
+ export const getBundler = () => {
5
+ const events = getEmitter();
6
+ return {
7
+ events,
8
+ getModule: async (filePath) => {
9
+ const bundlingStartTime = Date.now();
10
+ events.emit({
11
+ type: 'module-bundling-started',
12
+ file: filePath,
13
+ });
14
+ try {
15
+ const moduleJs = await fetchModule(filePath);
16
+ events.emit({
17
+ type: 'module-bundling-finished',
18
+ file: filePath,
19
+ duration: Date.now() - bundlingStartTime,
20
+ });
21
+ return moduleJs;
22
+ }
23
+ catch (error) {
24
+ events.emit({
25
+ type: 'module-bundling-failed',
26
+ file: filePath,
27
+ duration: Date.now() - bundlingStartTime,
28
+ error: error instanceof BundlingFailedError
29
+ ? error.reason
30
+ : 'Unknown error',
31
+ });
32
+ throw error;
33
+ }
34
+ },
35
+ };
36
+ };
@@ -1,3 +1,4 @@
1
- export { fetchModule } from './bundle.js';
2
1
  export { evaluateModule } from './evaluate.js';
2
+ export { getBundler } from './factory.js';
3
+ export type { Bundler } from './types.js';
3
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/bundler/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/bundler/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,YAAY,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC"}
@@ -1,2 +1,2 @@
1
- export { fetchModule } from './bundle.js';
2
1
  export { evaluateModule } from './evaluate.js';
2
+ export { getBundler } from './factory.js';
@@ -0,0 +1,7 @@
1
+ import { BundlerEvents } from '@react-native-harness/bridge';
2
+ import { EventEmitter } from '../utils/emitter.js';
3
+ export type Bundler = {
4
+ events: EventEmitter<BundlerEvents>;
5
+ getModule: (filePath: string) => Promise<string>;
6
+ };
7
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/bundler/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,MAAM,MAAM,OAAO,GAAG;IACpB,MAAM,EAAE,YAAY,CAAC,aAAa,CAAC,CAAC;IACpC,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CAClD,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -1 +1 @@
1
- {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/client/factory.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,SAAS,2EAiDrB,CAAC"}
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/client/factory.ts"],"names":[],"mappings":"AAgBA,eAAO,MAAM,SAAS,2EAiErB,CAAC"}
@@ -5,14 +5,15 @@ import { getTestCollector } from '../collector/index.js';
5
5
  import { combineEventEmitters } from '../utils/emitter.js';
6
6
  import { attachProgressLogger } from '../utils/progressLogger.js';
7
7
  import { getWSServer } from './getWSServer.js';
8
- import { fetchModule, evaluateModule } from '../bundler/index.js';
8
+ import { getBundler, evaluateModule } from '../bundler/index.js';
9
+ import { filterTestsByName } from '../filtering/index.js';
9
10
  export const getClient = async () => {
10
11
  const client = await getBridgeClient(getWSServer(), {
11
12
  runTests: async () => {
12
13
  throw new Error('Not implemented');
13
14
  },
14
15
  });
15
- client.rpc.$functions.runTests = async (path) => {
16
+ client.rpc.$functions.runTests = async (path, options = {}) => {
16
17
  if (store.getState().status === 'running') {
17
18
  throw new Error('Already running tests');
18
19
  }
@@ -20,18 +21,24 @@ export const getClient = async () => {
20
21
  let collector = null;
21
22
  let runner = null;
22
23
  let events = null;
24
+ let bundler = null;
23
25
  try {
24
26
  collector = getTestCollector();
25
27
  runner = getTestRunner();
26
- events = combineEventEmitters(collector.events, runner.events);
28
+ bundler = getBundler();
29
+ events = combineEventEmitters(collector.events, runner.events, bundler.events);
27
30
  events.addListener((event) => {
28
31
  client.rpc.emitEvent(event.type, event);
29
32
  });
30
33
  // Add console logging for progress information
31
34
  attachProgressLogger(events, path);
32
- const moduleJs = await fetchModule(path);
35
+ const moduleJs = await bundler.getModule(path);
33
36
  const collectionResult = await collector.collect(() => evaluateModule(moduleJs, path), path);
34
- const result = await runner.run(collectionResult.testSuite, path);
37
+ // Apply test name filtering if specified
38
+ const filteredTestSuite = options.testNamePattern
39
+ ? filterTestsByName(collectionResult.testSuite, options.testNamePattern)
40
+ : collectionResult.testSuite;
41
+ const result = await runner.run(filteredTestSuite, path);
35
42
  return result;
36
43
  }
37
44
  catch (error) {
@@ -1,5 +1,5 @@
1
1
  export type DeviceDescriptor = {
2
- platform: 'ios' | 'android';
2
+ platform: 'ios' | 'android' | 'vega';
3
3
  manufacturer: string;
4
4
  model: string;
5
5
  osVersion: string;
@@ -1 +1 @@
1
- {"version":3,"file":"getDeviceDescriptor.d.ts","sourceRoot":"","sources":["../../src/client/getDeviceDescriptor.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,EAAE,KAAK,GAAG,SAAS,CAAC;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,eAAO,MAAM,mBAAmB,QAAO,gBAoBtC,CAAC"}
1
+ {"version":3,"file":"getDeviceDescriptor.d.ts","sourceRoot":"","sources":["../../src/client/getDeviceDescriptor.ts"],"names":[],"mappings":"AAYA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,EAAE,KAAK,GAAG,SAAS,GAAG,MAAM,CAAC;IACrC,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,eAAO,MAAM,mBAAmB,QAAO,gBA+BtC,CAAC"}
@@ -1,19 +1,31 @@
1
1
  import { Platform } from 'react-native';
2
+ const getPlatform = () => {
3
+ return Platform;
4
+ };
2
5
  export const getDeviceDescriptor = () => {
3
- if (Platform.OS === 'ios') {
6
+ const platform = getPlatform();
7
+ if (platform.OS === 'ios') {
4
8
  return {
5
9
  platform: 'ios',
6
10
  manufacturer: 'Apple',
7
11
  model: 'Unknown',
8
- osVersion: Platform.constants.osVersion,
12
+ osVersion: platform.constants.osVersion,
9
13
  };
10
14
  }
11
- if (Platform.OS === 'android') {
15
+ if (platform.OS === 'android') {
12
16
  return {
13
17
  platform: 'android',
14
- manufacturer: Platform.constants.Manufacturer,
15
- model: Platform.constants.Model,
16
- osVersion: Platform.constants.Release,
18
+ manufacturer: platform.constants.Manufacturer,
19
+ model: platform.constants.Model,
20
+ osVersion: platform.constants.Release,
21
+ };
22
+ }
23
+ if (platform.OS === 'kepler') {
24
+ return {
25
+ platform: 'vega',
26
+ manufacturer: '',
27
+ model: '',
28
+ osVersion: '',
17
29
  };
18
30
  }
19
31
  throw new Error('Unsupported platform');
@@ -1 +1 @@
1
- {"version":3,"file":"functions.d.ts","sourceRoot":"","sources":["../../src/collector/functions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,gBAAgB,EACjB,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AA8KzC,eAAO,MAAM,QAAQ,UACZ,MAAM,MAAM,MAAM,IAAI;iBAsBd,MAAM,MAAM,MAAM,IAAI;iBAqBtB,MAAM,MAAM,MAAM,IAAI;CAsBtC,CAAC;AAEF,eAAO,MAAM,IAAI,UACR,MAAM,MAAM,MAAM;iBAaV,MAAM,MAAM,MAAM;iBAWlB,MAAM,MAAM,MAAM;iBAWlB,MAAM;CAiBtB,CAAC;AAEF,eAAO,MAAM,EAAE,UAtDN,MAAM,MAAM,MAAM;iBAaV,MAAM,MAAM,MAAM;iBAWlB,MAAM,MAAM,MAAM;iBAWlB,MAAM;CAmBD,CAAC;AAEvB,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,QAQnC;AAED,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,QAQlC;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,QAQpC;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,QAQnC;AAgBD,eAAO,MAAM,YAAY,GAAI,IAAI,MAAM,IAAI,KAAG,gBAiB7C,CAAC"}
1
+ {"version":3,"file":"functions.d.ts","sourceRoot":"","sources":["../../src/collector/functions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,gBAAgB,EACjB,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AA4LzC,eAAO,MAAM,QAAQ,UACZ,MAAM,MAAM,MAAM,IAAI;iBAsBd,MAAM,MAAM,MAAM,IAAI;iBAqBtB,MAAM,MAAM,MAAM,IAAI;CAsBtC,CAAC;AAEF,eAAO,MAAM,IAAI,UACR,MAAM,MAAM,MAAM;iBAaV,MAAM,MAAM,MAAM;iBAWlB,MAAM,MAAM,MAAM;iBAWlB,MAAM;CAiBtB,CAAC;AAEF,eAAO,MAAM,EAAE,UAtDN,MAAM,MAAM,MAAM;iBAaV,MAAM,MAAM,MAAM;iBAWlB,MAAM,MAAM,MAAM;iBAWlB,MAAM;CAmBD,CAAC;AAEvB,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,QAQnC;AAED,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,QAQlC;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,QAQpC;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,QAQnC;AAgBD,eAAO,MAAM,YAAY,GAAI,IAAI,MAAM,IAAI,KAAG,gBAiB7C,CAAC"}
@@ -17,6 +17,14 @@ const computeSuiteStatus = (suite, parentContext) => {
17
17
  return 'skipped';
18
18
  if (suite.options.only)
19
19
  return 'active';
20
+ // Check if this suite has any focused content (tests or child suites)
21
+ const hasFocusedTests = suite.tests.some((test) => test.options.only);
22
+ const hasFocusedChildren = suite.suites.some((childSuite) => childSuite.options.only ||
23
+ childSuite.tests.some((test) => test.options.only));
24
+ // If this suite has focused content, it should be active
25
+ if (hasFocusedTests || hasFocusedChildren)
26
+ return 'active';
27
+ // If parent has focused children and this suite has no focused content, skip it
20
28
  if (parentContext.hasFocusedChildren)
21
29
  return 'skipped';
22
30
  return 'active';
@@ -0,0 +1,2 @@
1
+ export { filterTestsByName } from './testNameFilter.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/filtering/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1 @@
1
+ export { filterTestsByName } from './testNameFilter.js';
@@ -0,0 +1,6 @@
1
+ import { TestSuite } from '@react-native-harness/bridge';
2
+ /**
3
+ * Filters tests by name pattern, matching against test names and suite+test combinations
4
+ */
5
+ export declare const filterTestsByName: (suite: TestSuite, testNamePattern: string) => TestSuite;
6
+ //# sourceMappingURL=testNameFilter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testNameFilter.d.ts","sourceRoot":"","sources":["../../src/filtering/testNameFilter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAEzD;;GAEG;AACH,eAAO,MAAM,iBAAiB,GAC5B,OAAO,SAAS,EAChB,iBAAiB,MAAM,KACtB,SAGF,CAAC"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Filters tests by name pattern, matching against test names and suite+test combinations
3
+ */
4
+ export const filterTestsByName = (suite, testNamePattern) => {
5
+ const regex = new RegExp(testNamePattern);
6
+ return filterSuiteRecursively(suite, regex);
7
+ };
8
+ const filterSuiteRecursively = (suite, regex) => {
9
+ // Filter tests in current suite - match against test name or "suite test" combination
10
+ const filteredTests = suite.tests.filter(test => regex.test(test.name) || regex.test(`${suite.name} ${test.name}`));
11
+ // Recursively filter child suites
12
+ const filteredChildSuites = suite.suites
13
+ .map(childSuite => filterSuiteRecursively(childSuite, regex))
14
+ .filter(childSuite => hasAnyActiveTests(childSuite));
15
+ return {
16
+ ...suite,
17
+ tests: filteredTests,
18
+ suites: filteredChildSuites,
19
+ };
20
+ };
21
+ const hasAnyActiveTests = (suite) => {
22
+ const hasDirectTests = suite.tests.some(test => test.status === 'active');
23
+ const hasChildTests = suite.suites.some(childSuite => hasAnyActiveTests(childSuite));
24
+ return hasDirectTests || hasChildTests;
25
+ };
package/dist/index.d.ts CHANGED
@@ -4,4 +4,6 @@ export * from './spy/index.js';
4
4
  export * from './expect/index.js';
5
5
  export * from './collector/index.js';
6
6
  export * from './mocker/index.js';
7
+ export * from './namespace.js';
8
+ export * from './waitFor.js';
7
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,gBAAgB,CAAC;AAExB,OAAO,EAAE,EAAE,IAAI,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACzD,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,gBAAgB,CAAC;AAExB,OAAO,EAAE,EAAE,IAAI,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACzD,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC"}
package/dist/index.js CHANGED
@@ -4,3 +4,5 @@ export * from './spy/index.js';
4
4
  export * from './expect/index.js';
5
5
  export * from './collector/index.js';
6
6
  export * from './mocker/index.js';
7
+ export * from './namespace.js';
8
+ export * from './waitFor.js';
@@ -1,2 +1,2 @@
1
- export { mock, requireActual, clearMocks } from './registry.js';
1
+ export { mock, requireActual, clearMocks, unmock, resetModules, } from './registry.js';
2
2
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mocker/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mocker/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,IAAI,EACJ,aAAa,EACb,UAAU,EACV,MAAM,EACN,YAAY,GACb,MAAM,eAAe,CAAC"}
@@ -1 +1 @@
1
- export { mock, requireActual, clearMocks } from './registry.js';
1
+ export { mock, requireActual, clearMocks, unmock, resetModules, } from './registry.js';
@@ -1,7 +1,7 @@
1
1
  import { ModuleFactory } from './types.js';
2
2
  export declare const mock: (moduleId: string, factory: ModuleFactory) => void;
3
3
  export declare const clearMocks: () => void;
4
- export declare const getMockRegistry: () => Map<number, ModuleFactory>;
5
- export declare const getMockImplementation: (moduleId: number) => unknown | null;
6
4
  export declare const requireActual: <T = any>(moduleId: string) => T;
5
+ export declare const unmock: (moduleId: string) => void;
6
+ export declare const resetModules: () => void;
7
7
  //# sourceMappingURL=registry.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/mocker/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAqB,MAAM,YAAY,CAAC;AAO9D,eAAO,MAAM,IAAI,GAAI,UAAU,MAAM,EAAE,SAAS,aAAa,KAAG,IAG/D,CAAC;AAEF,eAAO,MAAM,UAAU,QAAO,IAG7B,CAAC;AAEF,eAAO,MAAM,eAAe,QAAO,GAAG,CAAC,MAAM,EAAE,aAAa,CAE3D,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAI,UAAU,MAAM,KAAG,OAAO,GAAG,IAalE,CAAC;AAGF,eAAO,MAAM,aAAa,GAAI,CAAC,GAAG,GAAG,EAAE,UAAU,MAAM,KAAG,CAEH,CAAC"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/mocker/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAqB,MAAM,YAAY,CAAC;AAO9D,eAAO,MAAM,IAAI,GAAI,UAAU,MAAM,EAAE,SAAS,aAAa,KAAG,IAG/D,CAAC;AAEF,eAAO,MAAM,UAAU,QAAO,IAG7B,CAAC;AAkBF,eAAO,MAAM,aAAa,GAAI,CAAC,GAAG,GAAG,EAAE,UAAU,MAAM,KAAG,CAEH,CAAC;AAExD,eAAO,MAAM,MAAM,GAAI,UAAU,MAAM,SAGtC,CAAC;AAEF,eAAO,MAAM,YAAY,QAAO,IAK/B,CAAC"}
@@ -9,10 +9,7 @@ export const clearMocks = () => {
9
9
  mockRegistry.clear();
10
10
  mockCache.clear();
11
11
  };
12
- export const getMockRegistry = () => {
13
- return mockRegistry;
14
- };
15
- export const getMockImplementation = (moduleId) => {
12
+ const getMockImplementation = (moduleId) => {
16
13
  if (mockCache.has(moduleId)) {
17
14
  return mockCache.get(moduleId);
18
15
  }
@@ -28,6 +25,15 @@ export const getMockImplementation = (moduleId) => {
28
25
  export const requireActual = (moduleId) =>
29
26
  // babel plugin will transform 'moduleId' to a number
30
27
  originalRequire(moduleId);
28
+ export const unmock = (moduleId) => {
29
+ mockRegistry.delete(moduleId);
30
+ mockCache.delete(moduleId);
31
+ };
32
+ export const resetModules = () => {
33
+ mockCache.clear();
34
+ // Reset Metro's module cache
35
+ global.__resetAllModules();
36
+ };
31
37
  const mockRequire = (moduleId) => {
32
38
  // babel plugin will transform 'moduleId' to a number
33
39
  const mockedModule = getMockImplementation(moduleId);
@@ -0,0 +1,18 @@
1
+ import { spyOn, fn, clearAllMocks, resetAllMocks, restoreAllMocks } from './spy/index.js';
2
+ import { mock, unmock, requireActual, resetModules } from './mocker/index.js';
3
+ import { waitFor, waitUntil } from './waitFor.js';
4
+ export type HarnessNamespace = {
5
+ spyOn: typeof spyOn;
6
+ fn: typeof fn;
7
+ mock: typeof mock;
8
+ unmock: typeof unmock;
9
+ requireActual: typeof requireActual;
10
+ clearAllMocks: typeof clearAllMocks;
11
+ resetAllMocks: typeof resetAllMocks;
12
+ restoreAllMocks: typeof restoreAllMocks;
13
+ resetModules: typeof resetModules;
14
+ waitFor: typeof waitFor;
15
+ waitUntil: typeof waitUntil;
16
+ };
17
+ export declare const harness: HarnessNamespace;
18
+ //# sourceMappingURL=namespace.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"namespace.d.ts","sourceRoot":"","sources":["../src/namespace.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,EACL,EAAE,EACF,aAAa,EACb,aAAa,EACb,eAAe,EAChB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC9E,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAElD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAE,OAAO,KAAK,CAAC;IACpB,EAAE,EAAE,OAAO,EAAE,CAAC;IACd,IAAI,EAAE,OAAO,IAAI,CAAC;IAClB,MAAM,EAAE,OAAO,MAAM,CAAC;IACtB,aAAa,EAAE,OAAO,aAAa,CAAC;IACpC,aAAa,EAAE,OAAO,aAAa,CAAC;IACpC,aAAa,EAAE,OAAO,aAAa,CAAC;IACpC,eAAe,EAAE,OAAO,eAAe,CAAC;IACxC,YAAY,EAAE,OAAO,YAAY,CAAC;IAClC,OAAO,EAAE,OAAO,OAAO,CAAC;IACxB,SAAS,EAAE,OAAO,SAAS,CAAC;CAC7B,CAAC;AAkBF,eAAO,MAAM,OAAO,kBAA2B,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { spyOn, fn, clearAllMocks, resetAllMocks, restoreAllMocks, } from './spy/index.js';
2
+ import { mock, unmock, requireActual, resetModules } from './mocker/index.js';
3
+ import { waitFor, waitUntil } from './waitFor.js';
4
+ const createHarnessNamespace = () => {
5
+ return {
6
+ spyOn,
7
+ fn,
8
+ mock,
9
+ unmock,
10
+ requireActual,
11
+ clearAllMocks,
12
+ resetAllMocks,
13
+ restoreAllMocks,
14
+ resetModules,
15
+ waitFor,
16
+ waitUntil,
17
+ };
18
+ };
19
+ export const harness = createHarnessNamespace();
@@ -1 +1 @@
1
- {"version":3,"file":"runSuite.d.ts","sourceRoot":"","sources":["../../src/runner/runSuite.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,SAAS,EACT,eAAe,EAChB,MAAM,8BAA8B,CAAC;AAGtC,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAsH/C,eAAO,MAAM,QAAQ,GACnB,OAAO,SAAS,EAChB,SAAS,iBAAiB,KACzB,OAAO,CAAC,eAAe,CAyFzB,CAAC"}
1
+ {"version":3,"file":"runSuite.d.ts","sourceRoot":"","sources":["../../src/runner/runSuite.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,SAAS,EACT,eAAe,EAChB,MAAM,8BAA8B,CAAC;AAGtC,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAsH/C,eAAO,MAAM,QAAQ,GACnB,OAAO,SAAS,EAChB,SAAS,iBAAiB,KACzB,OAAO,CAAC,eAAe,CAoIzB,CAAC"}
@@ -98,6 +98,43 @@ export const runSuite = async (suite, context) => {
98
98
  name: suite.name,
99
99
  file: context.testFilePath,
100
100
  });
101
+ // Check if suite should be skipped or is todo
102
+ if (suite.status === 'skipped') {
103
+ const result = {
104
+ name: suite.name,
105
+ tests: [],
106
+ suites: [],
107
+ status: 'skipped',
108
+ duration: 0,
109
+ };
110
+ // Emit suite-finished event
111
+ context.events.emit({
112
+ type: 'suite-finished',
113
+ file: context.testFilePath,
114
+ name: suite.name,
115
+ duration: 0,
116
+ status: 'skipped',
117
+ });
118
+ return result;
119
+ }
120
+ if (suite.status === 'todo') {
121
+ const result = {
122
+ name: suite.name,
123
+ tests: [],
124
+ suites: [],
125
+ status: 'todo',
126
+ duration: 0,
127
+ };
128
+ // Emit suite-finished event
129
+ context.events.emit({
130
+ type: 'suite-finished',
131
+ file: context.testFilePath,
132
+ name: suite.name,
133
+ duration: 0,
134
+ status: 'todo',
135
+ });
136
+ return result;
137
+ }
101
138
  const testResults = [];
102
139
  const suiteResults = [];
103
140
  // Run beforeAll hooks