jest-expo 50.0.0-alpha.2 → 50.0.0-alpha.3
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/package.json +5 -4
- package/src/preset/expoModules.js +3 -48
- package/src/preset/setup.js +46 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jest-expo",
|
|
3
|
-
"version": "50.0.0-alpha.
|
|
3
|
+
"version": "50.0.0-alpha.3",
|
|
4
4
|
"description": "A Jest preset to painlessly test your Expo / React Native apps.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "src",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"preset": "jest-expo/universal"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@expo/config": "~8.
|
|
34
|
+
"@expo/config": "~8.4.0",
|
|
35
35
|
"@expo/json-file": "^8.2.37",
|
|
36
36
|
"@jest/create-cache-key-function": "^29.2.1",
|
|
37
37
|
"babel-jest": "^29.2.1",
|
|
@@ -41,11 +41,12 @@
|
|
|
41
41
|
"jest-watch-typeahead": "2.2.1",
|
|
42
42
|
"json5": "^2.2.3",
|
|
43
43
|
"lodash": "^4.17.19",
|
|
44
|
-
"react-test-renderer": "18.2.0"
|
|
44
|
+
"react-test-renderer": "18.2.0",
|
|
45
|
+
"stacktrace-js": "^2.0.2"
|
|
45
46
|
},
|
|
46
47
|
"bugs": {
|
|
47
48
|
"url": "https://github.com/expo/expo/issues"
|
|
48
49
|
},
|
|
49
50
|
"homepage": "https://github.com/expo/expo/tree/main/packages/jest-expo",
|
|
50
|
-
"gitHead": "
|
|
51
|
+
"gitHead": "da25937e2a99661cbe5eb60ca1d8d6245fc96a50"
|
|
51
52
|
}
|
|
@@ -227,19 +227,6 @@ module.exports = {
|
|
|
227
227
|
key: 'getMobileNetworkCodeAsync',
|
|
228
228
|
},
|
|
229
229
|
],
|
|
230
|
-
ExpoClipboard: [
|
|
231
|
-
{ name: 'getImageAsync', argumentsCount: 1, key: 'getImageAsync' },
|
|
232
|
-
{ name: 'getStringAsync', argumentsCount: 1, key: 'getStringAsync' },
|
|
233
|
-
{ name: 'getUrlAsync', argumentsCount: 0, key: 'getUrlAsync' },
|
|
234
|
-
{ name: 'hasImageAsync', argumentsCount: 0, key: 'hasImageAsync' },
|
|
235
|
-
{ name: 'hasStringAsync', argumentsCount: 0, key: 'hasStringAsync' },
|
|
236
|
-
{ name: 'hasUrlAsync', argumentsCount: 0, key: 'hasUrlAsync' },
|
|
237
|
-
{ name: 'setImageAsync', argumentsCount: 1, key: 'setImageAsync' },
|
|
238
|
-
{ name: 'setStringAsync', argumentsCount: 2, key: 'setStringAsync' },
|
|
239
|
-
{ name: 'setUrlAsync', argumentsCount: 1, key: 'setUrlAsync' },
|
|
240
|
-
{ name: 'startObserving', argumentsCount: 0, key: 'startObserving' },
|
|
241
|
-
{ name: 'stopObserving', argumentsCount: 0, key: 'stopObserving' },
|
|
242
|
-
],
|
|
243
230
|
ExpoContacts: [
|
|
244
231
|
{ name: 'getDefaultContainerIdentifierAsync', argumentsCount: 0, key: 0 },
|
|
245
232
|
{ name: 'addExistingGroupToContainerAsync', argumentsCount: 2, key: 1 },
|
|
@@ -260,19 +247,6 @@ module.exports = {
|
|
|
260
247
|
{ name: 'writeContactToFileAsync', argumentsCount: 1, key: 16 },
|
|
261
248
|
{ name: 'dismissFormAsync', argumentsCount: 0, key: 17 },
|
|
262
249
|
],
|
|
263
|
-
ExpoCrypto: [
|
|
264
|
-
{ name: 'digest', argumentsCount: 3, key: 'digest' },
|
|
265
|
-
{ name: 'digestString', argumentsCount: 3, key: 'digestString' },
|
|
266
|
-
{ name: 'digestStringAsync', argumentsCount: 3, key: 'digestStringAsync' },
|
|
267
|
-
{ name: 'getRandomBase64String', argumentsCount: 1, key: 'getRandomBase64String' },
|
|
268
|
-
{
|
|
269
|
-
name: 'getRandomBase64StringAsync',
|
|
270
|
-
argumentsCount: 1,
|
|
271
|
-
key: 'getRandomBase64StringAsync',
|
|
272
|
-
},
|
|
273
|
-
{ name: 'getRandomValues', argumentsCount: 1, key: 'getRandomValues' },
|
|
274
|
-
{ name: 'randomUUID', argumentsCount: 0, key: 'randomUUID' },
|
|
275
|
-
],
|
|
276
250
|
ExpoDevice: [
|
|
277
251
|
{ name: 'getDeviceTypeAsync', argumentsCount: 0, key: 'getDeviceTypeAsync' },
|
|
278
252
|
{ name: 'getUptimeAsync', argumentsCount: 0, key: 'getUptimeAsync' },
|
|
@@ -282,7 +256,6 @@ module.exports = {
|
|
|
282
256
|
key: 'isRootedExperimentalAsync',
|
|
283
257
|
},
|
|
284
258
|
],
|
|
285
|
-
ExpoDevMenu: [],
|
|
286
259
|
ExpoDocumentPicker: [
|
|
287
260
|
{ name: 'getDocumentAsync', argumentsCount: 1, key: 'getDocumentAsync' },
|
|
288
261
|
],
|
|
@@ -441,7 +414,7 @@ module.exports = {
|
|
|
441
414
|
],
|
|
442
415
|
ExponentFileSystem: [
|
|
443
416
|
{ name: 'uploadAsync', argumentsCount: 3, key: 0 },
|
|
444
|
-
{ name: 'readDirectoryAsync', argumentsCount:
|
|
417
|
+
{ name: 'readDirectoryAsync', argumentsCount: 1, key: 1 },
|
|
445
418
|
{ name: 'getTotalDiskCapacityAsync', argumentsCount: 0, key: 2 },
|
|
446
419
|
{ name: 'getInfoAsync', argumentsCount: 2, key: 3 },
|
|
447
420
|
{ name: 'downloadAsync', argumentsCount: 3, key: 4 },
|
|
@@ -687,8 +660,6 @@ module.exports = {
|
|
|
687
660
|
mobileCountryCode: { type: 'object', mock: null },
|
|
688
661
|
mobileNetworkCode: { type: 'object', mock: null },
|
|
689
662
|
},
|
|
690
|
-
ExpoClipboard: {},
|
|
691
|
-
ExpoCrypto: {},
|
|
692
663
|
ExpoDevice: {
|
|
693
664
|
brand: { type: 'string' },
|
|
694
665
|
deviceName: { type: 'string' },
|
|
@@ -742,9 +713,8 @@ module.exports = {
|
|
|
742
713
|
},
|
|
743
714
|
ExponentConstants: {
|
|
744
715
|
appOwnership: { type: 'string' },
|
|
745
|
-
debugMode: { type: 'boolean', mock:
|
|
716
|
+
debugMode: { type: 'boolean', mock: false },
|
|
746
717
|
deviceName: { type: 'string' },
|
|
747
|
-
deviceYearClass: { type: 'number', mock: 2023 },
|
|
748
718
|
executionEnvironment: { type: 'string' },
|
|
749
719
|
experienceUrl: { type: 'string' },
|
|
750
720
|
expoRuntimeVersion: { type: 'string' },
|
|
@@ -773,7 +743,7 @@ module.exports = {
|
|
|
773
743
|
ExponentGLView: {},
|
|
774
744
|
ExponentImagePicker: {},
|
|
775
745
|
ExpoNetwork: {},
|
|
776
|
-
ExpoPrint: {},
|
|
746
|
+
ExpoPrint: { Orientation: { type: 'object' } },
|
|
777
747
|
ExpoRandom: {},
|
|
778
748
|
ExpoScreenOrientation: {},
|
|
779
749
|
ExpoSecureStore: {
|
|
@@ -818,16 +788,6 @@ module.exports = {
|
|
|
818
788
|
ExpoAppleAuthentication: { propsNames: ['buttonStyle', 'buttonType', 'cornerRadius'] },
|
|
819
789
|
ExpoBarCodeScanner: { propsNames: ['barCodeTypes', 'type'] },
|
|
820
790
|
ExpoBlurView: { propsNames: ['intensity', 'tint'] },
|
|
821
|
-
ExpoClipboard: {
|
|
822
|
-
propsNames: [
|
|
823
|
-
'acceptedContentTypes',
|
|
824
|
-
'backgroundColor',
|
|
825
|
-
'cornerStyle',
|
|
826
|
-
'displayMode',
|
|
827
|
-
'foregroundColor',
|
|
828
|
-
'imageOptions',
|
|
829
|
-
],
|
|
830
|
-
},
|
|
831
791
|
ExpoImage: {
|
|
832
792
|
propsNames: [
|
|
833
793
|
'accessibilityLabel',
|
|
@@ -946,7 +906,6 @@ module.exports = {
|
|
|
946
906
|
getCurrentState: { type: 'function', functionType: 'promise' },
|
|
947
907
|
removeListeners: { type: 'function', functionType: 'async' },
|
|
948
908
|
},
|
|
949
|
-
RNCPickerManager: {},
|
|
950
909
|
RNCSafeAreaContext: {
|
|
951
910
|
getConstants: { type: 'function' },
|
|
952
911
|
initialWindowMetrics: { type: 'object' },
|
|
@@ -989,10 +948,6 @@ module.exports = {
|
|
|
989
948
|
updateGestureHandler: { type: 'function', functionType: 'async' },
|
|
990
949
|
},
|
|
991
950
|
RNSFullWindowOverlayManager: {},
|
|
992
|
-
RNSharedElementTransition: {
|
|
993
|
-
configure: { type: 'function', functionType: 'promise' },
|
|
994
|
-
getConstants: { type: 'function' },
|
|
995
|
-
},
|
|
996
951
|
RNSkia: {
|
|
997
952
|
getConstants: { type: 'function' },
|
|
998
953
|
install: { type: 'function', functionType: 'sync' },
|
package/src/preset/setup.js
CHANGED
|
@@ -4,7 +4,10 @@
|
|
|
4
4
|
*/
|
|
5
5
|
'use strict';
|
|
6
6
|
|
|
7
|
+
const findUp = require('find-up');
|
|
8
|
+
const path = require('path');
|
|
7
9
|
const mockNativeModules = require('react-native/Libraries/BatchedBridge/NativeModules');
|
|
10
|
+
const stackTrace = require('stacktrace-js');
|
|
8
11
|
|
|
9
12
|
const publicExpoModules = require('./expoModules');
|
|
10
13
|
const internalExpoModules = require('./internalExpoModules');
|
|
@@ -159,13 +162,35 @@ jest.doMock('react-native/Libraries/LogBox/LogBox', () => ({
|
|
|
159
162
|
},
|
|
160
163
|
}));
|
|
161
164
|
|
|
165
|
+
function attemptLookup(moduleName) {
|
|
166
|
+
// hack to get the package name from the module name
|
|
167
|
+
const filePath = stackTrace.getSync().find((line) => line.fileName.includes(moduleName));
|
|
168
|
+
if (!filePath) {
|
|
169
|
+
return null;
|
|
170
|
+
}
|
|
171
|
+
const modulePath = findUp.sync('package.json', { cwd: filePath.fileName });
|
|
172
|
+
const moduleMockPath = path.join(modulePath, '..', 'mocks', moduleName);
|
|
173
|
+
|
|
174
|
+
try {
|
|
175
|
+
const mockedPackageNativeModule = jest.requireActual(moduleMockPath);
|
|
176
|
+
return mockedPackageNativeModule;
|
|
177
|
+
} catch {
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
162
182
|
try {
|
|
163
|
-
jest.
|
|
183
|
+
jest.doMock('expo-modules-core', () => {
|
|
164
184
|
const ExpoModulesCore = jest.requireActual('expo-modules-core');
|
|
165
185
|
const uuid = jest.requireActual('expo-modules-core/build/uuid/uuid.web');
|
|
166
186
|
|
|
187
|
+
// support old hard-coded mocks TODO: remove this
|
|
167
188
|
const { NativeModulesProxy } = ExpoModulesCore;
|
|
168
189
|
|
|
190
|
+
// Mock the `uuid` object with the implementation for web.
|
|
191
|
+
ExpoModulesCore.uuid.v4 = uuid.default.v4;
|
|
192
|
+
ExpoModulesCore.uuid.v5 = uuid.default.v5;
|
|
193
|
+
|
|
169
194
|
// After the NativeModules mock is set up, we can mock NativeModuleProxy's functions that call
|
|
170
195
|
// into the native proxy module. We're not really interested in checking whether the underlying
|
|
171
196
|
// method is called, just that the proxy method is called, since we have unit tests for the
|
|
@@ -174,10 +199,6 @@ try {
|
|
|
174
199
|
// NOTE: The adapter validates the number of arguments, which we don't do in the mocked functions.
|
|
175
200
|
// This means the mock functions will not throw validation errors the way they would in an app.
|
|
176
201
|
|
|
177
|
-
// Mock the `uuid` object with the implementation for web.
|
|
178
|
-
ExpoModulesCore.uuid.v4 = uuid.default.v4;
|
|
179
|
-
ExpoModulesCore.uuid.v5 = uuid.default.v5;
|
|
180
|
-
|
|
181
202
|
for (const moduleName of Object.keys(NativeModulesProxy)) {
|
|
182
203
|
const nativeModule = NativeModulesProxy[moduleName];
|
|
183
204
|
for (const propertyName of Object.keys(nativeModule)) {
|
|
@@ -186,8 +207,26 @@ try {
|
|
|
186
207
|
}
|
|
187
208
|
}
|
|
188
209
|
}
|
|
189
|
-
|
|
190
|
-
|
|
210
|
+
return {
|
|
211
|
+
...ExpoModulesCore,
|
|
212
|
+
requireNativeModule: (name) => {
|
|
213
|
+
// Support auto-mocking of expo-modules that:
|
|
214
|
+
// 1. have a mock in the `mocks` directory
|
|
215
|
+
// 2. the native module (e.g. ExpoCrypto) name matches the package name (expo-crypto)
|
|
216
|
+
const nativeModuleMock = attemptLookup(name);
|
|
217
|
+
if (!nativeModuleMock) {
|
|
218
|
+
return ExpoModulesCore.requireNativeModule(name);
|
|
219
|
+
}
|
|
220
|
+
return Object.fromEntries(
|
|
221
|
+
Object.entries(nativeModuleMock).map(([k, v]) => {
|
|
222
|
+
if (typeof v === 'function') {
|
|
223
|
+
return [k, jest.fn(v)];
|
|
224
|
+
}
|
|
225
|
+
return [k, v];
|
|
226
|
+
})
|
|
227
|
+
);
|
|
228
|
+
},
|
|
229
|
+
};
|
|
191
230
|
});
|
|
192
231
|
} catch (error) {
|
|
193
232
|
// Allow this module to be optional for bare-workflow
|