jest-expo 49.0.0 → 50.0.0-alpha.1

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.
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
  const { getBareExtensions } = require('@expo/config/paths');
3
3
 
4
- const expoPreset = require('../jest-preset');
5
4
  const { withWatchPlugins } = require('./withWatchPlugins');
5
+ const expoPreset = require('../jest-preset');
6
6
 
7
7
  function getPlatformPreset(displayOptions, extensions) {
8
8
  const moduleFileExtensions = getBareExtensions(extensions, {
@@ -10,16 +10,15 @@ function getPlatformPreset(displayOptions, extensions) {
10
10
  isReact: true,
11
11
  isModern: false,
12
12
  });
13
- const testMatch = ['', ...extensions].reduce((arr, cur) => {
14
- const platformExtension = cur ? `.${cur}` : '';
13
+ const testMatch = ['', ...extensions].flatMap((extension) => {
14
+ const platformExtension = extension ? `.${extension}` : '';
15
15
  const sourceExtension = `.[jt]s?(x)`;
16
16
  return [
17
- ...arr,
18
17
  `**/__tests__/**/*spec${platformExtension}${sourceExtension}`,
19
18
  `**/__tests__/**/*test${platformExtension}${sourceExtension}`,
20
19
  `**/?(*.)+(spec|test)${platformExtension}${sourceExtension}`,
21
20
  ];
22
- }, []);
21
+ });
23
22
 
24
23
  return withWatchPlugins({
25
24
  displayName: displayOptions,
package/jest-preset.js CHANGED
@@ -5,6 +5,8 @@ const isEqual = require('lodash/isEqual');
5
5
  // Derive the Expo Jest preset from the React Native one
6
6
  const jestPreset = cloneDeep(require('react-native/jest-preset'));
7
7
 
8
+ const { withTypescriptMapping } = require('./src/preset/withTypescriptMapping');
9
+
8
10
  // transform
9
11
  if (!jestPreset.transform) {
10
12
  jestPreset.transform = {
@@ -40,7 +42,8 @@ if (!Array.isArray(jestPreset.transformIgnorePatterns)) {
40
42
 
41
43
  // Also please keep `testing-with-jest.md` file up to date
42
44
  jestPreset.transformIgnorePatterns = [
43
- 'node_modules/(?!((jest-)?react-native|@react-native(-community)?)|expo(nent)?|@expo(nent)?/.*|@expo-google-fonts/.*|react-navigation|@react-navigation/.*|@unimodules/.*|unimodules|sentry-expo|native-base|react-native-svg)',
45
+ '/node_modules/(?!((jest-)?react-native|@react-native(-community)?)|expo(nent)?|@expo(nent)?/.*|@expo-google-fonts/.*|react-navigation|@react-navigation/.*|@unimodules/.*|unimodules|sentry-expo|native-base|react-native-svg)',
46
+ '/node_modules/react-native-reanimated/plugin/',
44
47
  ];
45
48
 
46
49
  // setupFiles
@@ -49,4 +52,5 @@ if (!Array.isArray(jestPreset.setupFiles)) {
49
52
  }
50
53
  jestPreset.setupFiles.push(require.resolve('jest-expo/src/preset/setup.js'));
51
54
 
52
- module.exports = jestPreset;
55
+ // Add typescript custom mapping
56
+ module.exports = withTypescriptMapping(jestPreset);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jest-expo",
3
- "version": "49.0.0",
3
+ "version": "50.0.0-alpha.1",
4
4
  "description": "A Jest preset to painlessly test your Expo / React Native apps.",
5
5
  "license": "MIT",
6
6
  "main": "src",
@@ -31,13 +31,14 @@
31
31
  "preset": "jest-expo/universal"
32
32
  },
33
33
  "dependencies": {
34
- "@expo/config": "~8.1.0",
34
+ "@expo/config": "~8.3.0",
35
+ "@expo/json-file": "^8.2.37",
35
36
  "@jest/create-cache-key-function": "^29.2.1",
36
37
  "babel-jest": "^29.2.1",
37
38
  "find-up": "^5.0.0",
39
+ "jest-environment-jsdom": "^29.2.1",
38
40
  "jest-watch-select-projects": "^2.0.0",
39
41
  "jest-watch-typeahead": "2.2.1",
40
- "jest-environment-jsdom": "^29.2.1",
41
42
  "json5": "^2.2.3",
42
43
  "lodash": "^4.17.19",
43
44
  "react-test-renderer": "18.2.0"
@@ -46,5 +47,5 @@
46
47
  "url": "https://github.com/expo/expo/issues"
47
48
  },
48
49
  "homepage": "https://github.com/expo/expo/tree/main/packages/jest-expo",
49
- "gitHead": "4a38f32842594bb0ef39228dacde53042f12a47b"
50
+ "gitHead": "79607a7325f47aa17c36d266100d09a4ff2cc544"
50
51
  }
@@ -0,0 +1,103 @@
1
+ const JsonFile = require('@expo/json-file');
2
+ const path = require('path');
3
+
4
+ /**
5
+ * Convert typescript paths to jest module mapping.
6
+ *
7
+ * @param {Record<string, string[]>} paths
8
+ * @param {string} [prefix="<rootDir>"]
9
+ * @return {Record<string, string>}
10
+ */
11
+ function jestMappingFromTypescriptPaths(paths, prefix = '<rootDir>') {
12
+ const mapping = {};
13
+
14
+ for (const path in paths) {
15
+ if (!paths[path].length) {
16
+ console.warn(`Skipping empty typescript path map: ${path}`);
17
+ continue;
18
+ }
19
+
20
+ const jestRegex = convertTypescriptMatchToJestRegex(path);
21
+ const jestTarget = paths[path].map((target) =>
22
+ convertTypescriptTargetToJestTarget(target, prefix)
23
+ );
24
+
25
+ mapping[jestRegex] = jestTarget.length === 1 ? jestTarget[0] : jestTarget;
26
+ }
27
+
28
+ return mapping;
29
+ }
30
+
31
+ /** Convert a typescript match rule key to jest regex */
32
+ function convertTypescriptMatchToJestRegex(match) {
33
+ const regex = match
34
+ .split('/')
35
+ .map((segment) =>
36
+ segment.trim() === '*' ? '(.*)' : segment.replace(/[-\\^$*+?.()|[\]{}]/g, '\\$&')
37
+ )
38
+ .join('/');
39
+
40
+ return `^${regex}$`;
41
+ }
42
+
43
+ /** Convert a typescript match rule value to jest regex target */
44
+ function convertTypescriptTargetToJestTarget(target, prefix = '<rootDir>') {
45
+ const segments = target.split('/').map((segment) => (segment.trim() === '*' ? '$1' : segment));
46
+ return [prefix, ...segments].join('/');
47
+ }
48
+
49
+ function mutateJestMappingFromConfig(jestConfig, configFile) {
50
+ const readJsonFile = JsonFile.default?.read || JsonFile.read;
51
+
52
+ try {
53
+ // The path to jsconfig.json or tsconfig.json is resolved relative to cwd
54
+ // See: _createTypeScriptConfiguration() in `createJestPreset`
55
+ const configPath = path.resolve(configFile);
56
+ const config = readJsonFile(configPath, { json5: true });
57
+ let pathPrefix = '<rootDir>';
58
+
59
+ if (config?.compilerOptions?.baseUrl) {
60
+ pathPrefix = path.join(pathPrefix, config.compilerOptions.baseUrl);
61
+ }
62
+
63
+ if (config?.compilerOptions?.paths) {
64
+ jestConfig.moduleNameMapper = {
65
+ ...jestMappingFromTypescriptPaths(config.compilerOptions.paths || {}, pathPrefix),
66
+ ...(jestConfig.moduleNameMapper || {}),
67
+ };
68
+ }
69
+
70
+ return true;
71
+ } catch (error) {
72
+ // If the user is not using typescript, we can safely ignore this error
73
+ if (error.code === 'MODULE_NOT_FOUND' || error.code === 'ENOENT') {
74
+ return undefined;
75
+ }
76
+
77
+ // Other errors are unexpected, but should not block the jest configuration
78
+ return false;
79
+ }
80
+ }
81
+
82
+ /** Try to add the `moduleNameMapper` configuration from the typescript `paths` configuration. */
83
+ function withTypescriptMapping(jestConfig) {
84
+ const fromTsConfig = mutateJestMappingFromConfig(jestConfig, 'tsconfig.json');
85
+ const fromJsConfig = !fromTsConfig
86
+ ? mutateJestMappingFromConfig(jestConfig, 'jsconfig.json')
87
+ : undefined;
88
+
89
+ if (fromTsConfig === false || fromJsConfig === false) {
90
+ console.warn('Failed to set custom typescript paths for jest.');
91
+ console.warn('You need to configure jest moduleNameMapper manually.');
92
+ console.warn(
93
+ 'See: https://jestjs.io/docs/configuration#modulenamemapper-objectstring-string--arraystring'
94
+ );
95
+ }
96
+
97
+ return jestConfig;
98
+ }
99
+
100
+ module.exports = {
101
+ _jestMappingFromTypescriptPaths: jestMappingFromTypescriptPaths, // Exported for testing
102
+ withTypescriptMapping,
103
+ };