Skip to content

Commit 6a7e25e

Browse files
committed
feat: throw when jest globals are used
1 parent 12ccf5f commit 6a7e25e

6 files changed

Lines changed: 79 additions & 4 deletions

File tree

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { describe, it, expect } from 'react-native-harness';
2+
3+
describe('Jest globals warning', () => {
4+
it('should throw when accessing jest global', () => {
5+
expect(() => {
6+
// @ts-expect-error - jest is not available in Harness tests
7+
jest.fn();
8+
}).toThrow('Jest globals are not available in Harness tests');
9+
});
10+
11+
it('should throw when importing @jest/globals', () => {
12+
expect(() => require('@jest/globals')).toThrow(
13+
"Importing '@jest/globals' is not supported in Harness tests"
14+
);
15+
});
16+
});
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// Mock module for @jest/globals imports
2+
// This module throws immediately when imported to warn users about using Jest APIs
3+
4+
throw new Error(
5+
"Importing '@jest/globals' is not supported in Harness tests. Import from 'react-native-harness' instead."
6+
);

packages/metro/src/resolver.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,14 @@ export const getHarnessResolver = (
3030
};
3131
}
3232

33+
// Intercept @jest/globals imports and redirect to mock module
34+
if (moduleName === '@jest/globals') {
35+
return {
36+
type: 'sourceFile',
37+
filePath: require.resolve('./jest-globals-mock'),
38+
};
39+
}
40+
3341
return resolvedModule;
3442
};
3543
};

packages/runtime/assets/moduleSystem.flow.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -588,11 +588,14 @@ function loadModuleImplementation(
588588
// keep args in sync with with defineModuleCode in
589589
// metro/src/Resolver/index.js
590590
// and metro/src/ModuleGraph/worker.js
591+
const capturedRequire = (...args) => global.__r(...args);
592+
Object.assign(capturedRequire, global.__r);
593+
591594
factory(
592595
global,
593-
(...args) => global.__r(...args),
594-
(...args) => global.__r.importDefault(...args),
595-
(...args) => global.__r.importAll(...args),
596+
capturedRequire,
597+
capturedRequire.importDefault,
598+
capturedRequire.importAll,
596599
moduleObject,
597600
moduleObject.exports,
598601
dependencyMap

packages/runtime/src/initialize.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,23 @@
11
import { getDeviceDescriptor } from './client/getDeviceDescriptor.js';
22
import { getClient } from './client/index.js';
3+
import { setupJestMock } from './jest-mock.js';
34

45
// Polyfill for EventTarget
56
const Shim = require('event-target-shim');
67
globalThis.Event = Shim.Event;
78
globalThis.EventTarget = Shim.EventTarget;
89

10+
// Setup jest mock to warn users about using Jest APIs
11+
setupJestMock();
12+
913
// Turn off LogBox
1014
const { LogBox } = require('react-native');
1115
LogBox.ignoreAllLogs(true);
1216

1317
// Turn off HMR
1418
const HMRClientModule = require('react-native/Libraries/Utilities/HMRClient');
15-
const HMRClient = 'default' in HMRClientModule ? HMRClientModule.default : HMRClientModule;
19+
const HMRClient =
20+
'default' in HMRClientModule ? HMRClientModule.default : HMRClientModule;
1621

1722
// Wait for HMRClient to be initialized
1823
setTimeout(() => {
@@ -23,3 +28,8 @@ setTimeout(() => {
2328
client.rpc.reportReady(getDeviceDescriptor())
2429
);
2530
});
31+
32+
// Re-throw fatal errors
33+
ErrorUtils.setGlobalHandler((error) => {
34+
throw error;
35+
});

packages/runtime/src/jest-mock.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Mock jest global to warn users about using Jest APIs in Harness tests
2+
export const setupJestMock = (): void => {
3+
function throwError(): never {
4+
throw new Error(
5+
`Jest globals are not available in Harness tests. Import from 'react-native-harness' instead (e.g., import { harness } from 'react-native-harness'; harness.fn())`
6+
);
7+
}
8+
9+
const jestMock = new Proxy(
10+
{},
11+
{
12+
get() {
13+
throwError();
14+
},
15+
set() {
16+
throwError();
17+
},
18+
has() {
19+
throwError();
20+
},
21+
ownKeys() {
22+
throwError();
23+
},
24+
}
25+
);
26+
27+
Object.defineProperty(globalThis, 'jest', {
28+
value: jestMock,
29+
writable: false,
30+
configurable: false,
31+
});
32+
};

0 commit comments

Comments
 (0)