jest-expo 50.0.0-alpha.2 → 50.0.0-alpha.4

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jest-expo",
3
- "version": "50.0.0-alpha.2",
3
+ "version": "50.0.0-alpha.4",
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.3.0",
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": "ee2c866ba3c7fbc35ff2a3e896041cf15d3bd7c5"
51
+ "gitHead": "3142a086578deffd8704a8f1b6f0f661527d836c"
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
  ],
@@ -296,6 +269,9 @@ module.exports = {
296
269
  { name: 'clearDiskCache', argumentsCount: 0, key: 'clearDiskCache' },
297
270
  { name: 'clearMemoryCache', argumentsCount: 0, key: 'clearMemoryCache' },
298
271
  { name: 'prefetch', argumentsCount: 1, key: 'prefetch' },
272
+ { name: 'getCachePathAsync', argumentsCount: 1, key: 'getCachePathAsync' },
273
+ { name: 'startAnimating', argumentsCount: 0, key: 'startAnimating' },
274
+ { name: 'stopAnimating', argumentsCount: 0, key: 'stopAnimating' },
299
275
  ],
300
276
  ExpoImageManipulator: [
301
277
  { name: 'manipulateAsync', argumentsCount: 3, key: 'manipulateAsync' },
@@ -397,7 +373,7 @@ module.exports = {
397
373
  { name: 'getCurrentInput', argumentsCount: 0, key: 21 },
398
374
  { name: 'startAudioRecording', argumentsCount: 0, key: 22 },
399
375
  ],
400
- ExponentCamera: [
376
+ ExpoCamera: [
401
377
  { name: 'getAvailablePictureSizes', argumentsCount: 2, key: 'getAvailablePictureSizes' },
402
378
  {
403
379
  name: 'getAvailableVideoCodecsAsync',
@@ -441,7 +417,7 @@ module.exports = {
441
417
  ],
442
418
  ExponentFileSystem: [
443
419
  { name: 'uploadAsync', argumentsCount: 3, key: 0 },
444
- { name: 'readDirectoryAsync', argumentsCount: 2, key: 1 },
420
+ { name: 'readDirectoryAsync', argumentsCount: 1, key: 1 },
445
421
  { name: 'getTotalDiskCapacityAsync', argumentsCount: 0, key: 2 },
446
422
  { name: 'getInfoAsync', argumentsCount: 2, key: 3 },
447
423
  { name: 'downloadAsync', argumentsCount: 3, key: 4 },
@@ -687,8 +663,6 @@ module.exports = {
687
663
  mobileCountryCode: { type: 'object', mock: null },
688
664
  mobileNetworkCode: { type: 'object', mock: null },
689
665
  },
690
- ExpoClipboard: {},
691
- ExpoCrypto: {},
692
666
  ExpoDevice: {
693
667
  brand: { type: 'string' },
694
668
  deviceName: { type: 'string' },
@@ -731,7 +705,7 @@ module.exports = {
731
705
  SortBy: { type: 'object' },
732
706
  },
733
707
  ExponentAV: { Qualities: { type: 'object' } },
734
- ExponentCamera: {
708
+ ExpoCamera: {
735
709
  AutoFocus: { type: 'object' },
736
710
  FlashMode: { type: 'object' },
737
711
  Type: { type: 'object' },
@@ -742,9 +716,8 @@ module.exports = {
742
716
  },
743
717
  ExponentConstants: {
744
718
  appOwnership: { type: 'string' },
745
- debugMode: { type: 'boolean', mock: true },
719
+ debugMode: { type: 'boolean', mock: false },
746
720
  deviceName: { type: 'string' },
747
- deviceYearClass: { type: 'number', mock: 2023 },
748
721
  executionEnvironment: { type: 'string' },
749
722
  experienceUrl: { type: 'string' },
750
723
  expoRuntimeVersion: { type: 'string' },
@@ -773,7 +746,7 @@ module.exports = {
773
746
  ExponentGLView: {},
774
747
  ExponentImagePicker: {},
775
748
  ExpoNetwork: {},
776
- ExpoPrint: {},
749
+ ExpoPrint: { Orientation: { type: 'object' } },
777
750
  ExpoRandom: {},
778
751
  ExpoScreenOrientation: {},
779
752
  ExpoSecureStore: {
@@ -818,16 +791,6 @@ module.exports = {
818
791
  ExpoAppleAuthentication: { propsNames: ['buttonStyle', 'buttonType', 'cornerRadius'] },
819
792
  ExpoBarCodeScanner: { propsNames: ['barCodeTypes', 'type'] },
820
793
  ExpoBlurView: { propsNames: ['intensity', 'tint'] },
821
- ExpoClipboard: {
822
- propsNames: [
823
- 'acceptedContentTypes',
824
- 'backgroundColor',
825
- 'cornerStyle',
826
- 'displayMode',
827
- 'foregroundColor',
828
- 'imageOptions',
829
- ],
830
- },
831
794
  ExpoImage: {
832
795
  propsNames: [
833
796
  'accessibilityLabel',
@@ -847,7 +810,7 @@ module.exports = {
847
810
  ],
848
811
  },
849
812
  ExpoLinearGradient: { propsNames: ['colors', 'endPoint', 'locations', 'startPoint'] },
850
- ExponentCamera: {
813
+ ExpoCamera: {
851
814
  propsNames: [
852
815
  'autoFocus',
853
816
  'barCodeScannerEnabled',
@@ -946,7 +909,6 @@ module.exports = {
946
909
  getCurrentState: { type: 'function', functionType: 'promise' },
947
910
  removeListeners: { type: 'function', functionType: 'async' },
948
911
  },
949
- RNCPickerManager: {},
950
912
  RNCSafeAreaContext: {
951
913
  getConstants: { type: 'function' },
952
914
  initialWindowMetrics: { type: 'object' },
@@ -989,10 +951,6 @@ module.exports = {
989
951
  updateGestureHandler: { type: 'function', functionType: 'async' },
990
952
  },
991
953
  RNSFullWindowOverlayManager: {},
992
- RNSharedElementTransition: {
993
- configure: { type: 'function', functionType: 'promise' },
994
- getConstants: { type: 'function' },
995
- },
996
954
  RNSkia: {
997
955
  getConstants: { type: 'function' },
998
956
  install: { type: 'function', functionType: 'sync' },
@@ -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');
@@ -37,6 +40,10 @@ const expoModules = {
37
40
  ...internalExpoModules,
38
41
  };
39
42
 
43
+ // Mock the experience URL in development mode for asset setup
44
+ expoModules.NativeUnimoduleProxy.modulesConstants.mockDefinition.ExponentConstants.experienceUrl.mock =
45
+ 'exp://192.168.1.200:8081';
46
+
40
47
  function mock(property, customMock) {
41
48
  const propertyType = property.type;
42
49
  let mockValue;
@@ -125,7 +132,7 @@ try {
125
132
  }
126
133
  }
127
134
 
128
- jest.mock('react-native/Libraries/Image/AssetRegistry', () => ({
135
+ jest.mock('@react-native/assets-registry/registry', () => ({
129
136
  registerAsset: jest.fn(() => 1),
130
137
  getAssetByID: jest.fn(() => ({
131
138
  fileSystemLocation: '/full/path/to/directory',
@@ -159,13 +166,35 @@ jest.doMock('react-native/Libraries/LogBox/LogBox', () => ({
159
166
  },
160
167
  }));
161
168
 
169
+ function attemptLookup(moduleName) {
170
+ // hack to get the package name from the module name
171
+ const filePath = stackTrace.getSync().find((line) => line.fileName.includes(moduleName));
172
+ if (!filePath) {
173
+ return null;
174
+ }
175
+ const modulePath = findUp.sync('package.json', { cwd: filePath.fileName });
176
+ const moduleMockPath = path.join(modulePath, '..', 'mocks', moduleName);
177
+
178
+ try {
179
+ const mockedPackageNativeModule = jest.requireActual(moduleMockPath);
180
+ return mockedPackageNativeModule;
181
+ } catch {
182
+ return null;
183
+ }
184
+ }
185
+
162
186
  try {
163
- jest.mock('expo-modules-core', () => {
187
+ jest.doMock('expo-modules-core', () => {
164
188
  const ExpoModulesCore = jest.requireActual('expo-modules-core');
165
189
  const uuid = jest.requireActual('expo-modules-core/build/uuid/uuid.web');
166
190
 
191
+ // support old hard-coded mocks TODO: remove this
167
192
  const { NativeModulesProxy } = ExpoModulesCore;
168
193
 
194
+ // Mock the `uuid` object with the implementation for web.
195
+ ExpoModulesCore.uuid.v4 = uuid.default.v4;
196
+ ExpoModulesCore.uuid.v5 = uuid.default.v5;
197
+
169
198
  // After the NativeModules mock is set up, we can mock NativeModuleProxy's functions that call
170
199
  // into the native proxy module. We're not really interested in checking whether the underlying
171
200
  // method is called, just that the proxy method is called, since we have unit tests for the
@@ -174,10 +203,6 @@ try {
174
203
  // NOTE: The adapter validates the number of arguments, which we don't do in the mocked functions.
175
204
  // This means the mock functions will not throw validation errors the way they would in an app.
176
205
 
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
206
  for (const moduleName of Object.keys(NativeModulesProxy)) {
182
207
  const nativeModule = NativeModulesProxy[moduleName];
183
208
  for (const propertyName of Object.keys(nativeModule)) {
@@ -186,8 +211,26 @@ try {
186
211
  }
187
212
  }
188
213
  }
189
-
190
- return ExpoModulesCore;
214
+ return {
215
+ ...ExpoModulesCore,
216
+ requireNativeModule: (name) => {
217
+ // Support auto-mocking of expo-modules that:
218
+ // 1. have a mock in the `mocks` directory
219
+ // 2. the native module (e.g. ExpoCrypto) name matches the package name (expo-crypto)
220
+ const nativeModuleMock = attemptLookup(name);
221
+ if (!nativeModuleMock) {
222
+ return ExpoModulesCore.requireNativeModule(name);
223
+ }
224
+ return Object.fromEntries(
225
+ Object.entries(nativeModuleMock).map(([k, v]) => {
226
+ if (typeof v === 'function') {
227
+ return [k, jest.fn(v)];
228
+ }
229
+ return [k, v];
230
+ })
231
+ );
232
+ },
233
+ };
191
234
  });
192
235
  } catch (error) {
193
236
  // Allow this module to be optional for bare-workflow
@@ -195,3 +238,6 @@ try {
195
238
  throw error;
196
239
  }
197
240
  }
241
+
242
+ // Ensure the environment globals are installed before the first test runs.
243
+ require('expo/build/winter');