1import { isModuleSymlinked } from '../../utils/isModuleSymlinked';
2import {
3  hashForDependencyMap,
4  isPkgMainExpoAppEntry,
5  shouldDeleteMainField,
6  updatePkgDependencies,
7} from '../updatePackageJson';
8
9jest.mock('../../utils/isModuleSymlinked');
10
11describe(hashForDependencyMap, () => {
12  it(`dependencies in any order hash to the same value`, () => {
13    expect(hashForDependencyMap({ a: '1.0.0', b: 2, c: '~3.0' })).toBe(
14      hashForDependencyMap({ c: '~3.0', b: 2, a: '1.0.0' })
15    );
16  });
17});
18
19describe(shouldDeleteMainField, () => {
20  it(`should delete non index field`, () => {
21    expect(shouldDeleteMainField(null)).toBe(false);
22    expect(shouldDeleteMainField()).toBe(false);
23    expect(shouldDeleteMainField('expo/AppEntry')).toBe(true);
24    // non-expo fields
25    expect(shouldDeleteMainField('.src/other.js')).toBe(false);
26    expect(shouldDeleteMainField('index.js')).toBe(false);
27    expect(shouldDeleteMainField('index.ios.js')).toBe(false);
28    expect(shouldDeleteMainField('index.ts')).toBe(false);
29    expect(shouldDeleteMainField('./index')).toBe(false);
30  });
31});
32
33describe(isPkgMainExpoAppEntry, () => {
34  it(`matches expo app entry`, () => {
35    expect(isPkgMainExpoAppEntry('./node_modules/expo/AppEntry.js')).toBe(true);
36    expect(isPkgMainExpoAppEntry('./node_modules/expo/AppEntry')).toBe(true);
37    expect(isPkgMainExpoAppEntry('expo/AppEntry.js')).toBe(true);
38    expect(isPkgMainExpoAppEntry('expo/AppEntry')).toBe(true);
39  });
40  it(`doesn't match expo app entry`, () => {
41    expect(isPkgMainExpoAppEntry()).toBe(false);
42    expect(isPkgMainExpoAppEntry(null)).toBe(false);
43    expect(isPkgMainExpoAppEntry('./expo/AppEntry')).toBe(false);
44    expect(isPkgMainExpoAppEntry('./expo/AppEntry.js')).toBe(false);
45  });
46});
47
48describe(updatePkgDependencies, () => {
49  beforeAll(() => {
50    (isModuleSymlinked as any).mockImplementation(() => false);
51  });
52  const requiredPackages = {
53    react: 'version-from-template-required-1',
54    'react-native': 'version-from-template-required-1',
55    'react-native-unimodules': 'version-from-template-required-1',
56    'expo-updates': 'version-from-template-required-1',
57  };
58
59  test('default bahaviour', () => {
60    const pkg = {
61      dependencies: {
62        'react-native': 'version-from-project',
63        'optional-package': 'version-from-project-1',
64        'optional-package-3': 'version-from-project-3',
65      },
66      devDependencies: {},
67    };
68    updatePkgDependencies('fake path', {
69      templatePkg: {
70        dependencies: {
71          ...requiredPackages,
72          'optional-package': 'version-from-template-1',
73          'optional-package-2': 'version-from-template-2',
74        },
75        devDependencies: {},
76      },
77      pkg,
78    });
79    expect(pkg.dependencies).toStrictEqual({
80      ...requiredPackages,
81      'optional-package': 'version-from-project-1',
82      'optional-package-2': 'version-from-template-2',
83      'optional-package-3': 'version-from-project-3',
84    });
85  });
86  test('with skipDependencyUpdate', () => {
87    const pkg = {
88      dependencies: {
89        'react-native': 'version-from-project',
90        'optional-package': 'version-from-project-1',
91        'optional-package-3': 'version-from-project-3',
92      },
93      devDependencies: {},
94    };
95    updatePkgDependencies('fake path', {
96      pkg,
97      templatePkg: {
98        dependencies: {
99          ...requiredPackages,
100          'react-native': 'version-from-project',
101          'optional-package': 'version-from-template-1',
102          'optional-package-2': 'version-from-template-2',
103        },
104        devDependencies: {},
105      },
106      skipDependencyUpdate: ['react-native'],
107    });
108    expect(pkg.dependencies).toStrictEqual({
109      ...requiredPackages,
110      'react-native': 'version-from-project',
111      'optional-package': 'version-from-project-1',
112      'optional-package-2': 'version-from-template-2',
113      'optional-package-3': 'version-from-project-3',
114    });
115  });
116  test('test expo-updates not required by default in sdk 44', () => {
117    const sdk44RequiredPackages = {
118      react: 'version-from-template-required-1',
119      'react-native': 'version-from-template-required-1',
120    };
121    const pkg = {
122      dependencies: {
123        'react-native': 'version-from-project',
124        'optional-package': 'version-from-project-1',
125        'optional-package-3': 'version-from-project-3',
126      },
127      devDependencies: {},
128    };
129    updatePkgDependencies('fake path', {
130      templatePkg: {
131        dependencies: {
132          ...sdk44RequiredPackages,
133          'optional-package': 'version-from-template-1',
134          'optional-package-2': 'version-from-template-2',
135        },
136        devDependencies: {},
137      },
138      pkg,
139    });
140    expect(pkg.dependencies).toStrictEqual({
141      ...sdk44RequiredPackages,
142      'optional-package': 'version-from-project-1',
143      'optional-package-2': 'version-from-template-2',
144      'optional-package-3': 'version-from-project-3',
145    });
146  });
147});
148