18d3f3824SCedric van Puttenimport spawnAsync from '@expo/spawn-async'; 28d3f3824SCedric van Puttenimport { vol } from 'memfs'; 38d3f3824SCedric van Puttenimport path from 'path'; 48d3f3824SCedric van Putten 58d3f3824SCedric van Puttenimport { mockSpawnPromise, mockedSpawnAsync, STUB_SPAWN_CHILD } from '../../__tests__/spawn-utils'; 68d3f3824SCedric van Puttenimport { NpmPackageManager } from '../NpmPackageManager'; 78d3f3824SCedric van Putten 88d3f3824SCedric van Puttenjest.mock('@expo/spawn-async'); 98d3f3824SCedric van Puttenjest.mock('fs'); 108d3f3824SCedric van Putten 118d3f3824SCedric van PuttenbeforeAll(() => { 128d3f3824SCedric van Putten // Disable logging to clean up test ouput 138d3f3824SCedric van Putten jest.spyOn(console, 'log').mockImplementation(); 148d3f3824SCedric van Putten}); 158d3f3824SCedric van Putten 168d3f3824SCedric van Puttendescribe('NpmPackageManager', () => { 178d3f3824SCedric van Putten const projectRoot = '/project/with-npm'; 188d3f3824SCedric van Putten 198d3f3824SCedric van Putten it('name is set to npm', () => { 208d3f3824SCedric van Putten const npm = new NpmPackageManager({ cwd: projectRoot }); 218d3f3824SCedric van Putten expect(npm.name).toBe('npm'); 228d3f3824SCedric van Putten }); 238d3f3824SCedric van Putten 248d3f3824SCedric van Putten describe('getDefaultEnvironment', () => { 258d3f3824SCedric van Putten it('runs npm with ADBLOCK=1 and DISABLE_OPENCOLLECTIVE=1', async () => { 268d3f3824SCedric van Putten const npm = new NpmPackageManager({ cwd: projectRoot }); 278d3f3824SCedric van Putten await npm.installAsync(); 288d3f3824SCedric van Putten 298d3f3824SCedric van Putten expect(spawnAsync).toBeCalledWith( 308d3f3824SCedric van Putten expect.anything(), 318d3f3824SCedric van Putten expect.anything(), 328d3f3824SCedric van Putten expect.objectContaining({ 338d3f3824SCedric van Putten env: expect.objectContaining({ ADBLOCK: '1', DISABLE_OPENCOLLECTIVE: '1' }), 348d3f3824SCedric van Putten }) 358d3f3824SCedric van Putten ); 368d3f3824SCedric van Putten }); 378d3f3824SCedric van Putten 388d3f3824SCedric van Putten it('runs with overwritten default environment', async () => { 398d3f3824SCedric van Putten const npm = new NpmPackageManager({ cwd: projectRoot, env: { ADBLOCK: '0' } }); 408d3f3824SCedric van Putten await npm.installAsync(); 418d3f3824SCedric van Putten 428d3f3824SCedric van Putten expect(spawnAsync).toBeCalledWith( 438d3f3824SCedric van Putten expect.anything(), 448d3f3824SCedric van Putten expect.anything(), 458d3f3824SCedric van Putten expect.objectContaining({ 468d3f3824SCedric van Putten env: { ADBLOCK: '0', DISABLE_OPENCOLLECTIVE: '1' }, 478d3f3824SCedric van Putten }) 488d3f3824SCedric van Putten ); 498d3f3824SCedric van Putten }); 508d3f3824SCedric van Putten }); 518d3f3824SCedric van Putten 528d3f3824SCedric van Putten describe('runAsync', () => { 538d3f3824SCedric van Putten it('logs executed command', async () => { 548d3f3824SCedric van Putten const log = jest.fn(); 558d3f3824SCedric van Putten const npm = new NpmPackageManager({ cwd: projectRoot, log }); 568d3f3824SCedric van Putten await npm.runAsync(['install', '--some-flag']); 578d3f3824SCedric van Putten expect(log).toHaveBeenCalledWith('> npm install --some-flag'); 588d3f3824SCedric van Putten }); 598d3f3824SCedric van Putten 60*efdcf92fSCedric van Putten it('inherits stdio output without silent', async () => { 618d3f3824SCedric van Putten const npm = new NpmPackageManager({ cwd: projectRoot }); 62*efdcf92fSCedric van Putten await npm.runAsync(['install']); 638d3f3824SCedric van Putten 64*efdcf92fSCedric van Putten expect(spawnAsync).toBeCalledWith( 65*efdcf92fSCedric van Putten expect.anything(), 66*efdcf92fSCedric van Putten expect.anything(), 67*efdcf92fSCedric van Putten expect.objectContaining({ stdio: 'inherit' }) 688d3f3824SCedric van Putten ); 698d3f3824SCedric van Putten }); 708d3f3824SCedric van Putten 71*efdcf92fSCedric van Putten it('does not inherit stdio with silent', async () => { 728d3f3824SCedric van Putten const npm = new NpmPackageManager({ cwd: projectRoot, silent: true }); 73*efdcf92fSCedric van Putten await npm.runAsync(['install']); 748d3f3824SCedric van Putten 75*efdcf92fSCedric van Putten expect(spawnAsync).toBeCalledWith( 76*efdcf92fSCedric van Putten expect.anything(), 77*efdcf92fSCedric van Putten expect.anything(), 78*efdcf92fSCedric van Putten expect.objectContaining({ stdio: undefined }) 798d3f3824SCedric van Putten ); 808d3f3824SCedric van Putten }); 818d3f3824SCedric van Putten 828d3f3824SCedric van Putten it('returns spawn promise with child', () => { 838d3f3824SCedric van Putten const npm = new NpmPackageManager({ cwd: projectRoot }); 848d3f3824SCedric van Putten expect(npm.runAsync(['install'])).toHaveProperty( 858d3f3824SCedric van Putten 'child', 868d3f3824SCedric van Putten expect.objectContaining(STUB_SPAWN_CHILD) 878d3f3824SCedric van Putten ); 888d3f3824SCedric van Putten }); 898d3f3824SCedric van Putten 908d3f3824SCedric van Putten it('adds a single package with custom parameters', async () => { 918d3f3824SCedric van Putten const npm = new NpmPackageManager({ cwd: projectRoot }); 928d3f3824SCedric van Putten await npm.runAsync(['install', '--save-peer', '@babel/core']); 938d3f3824SCedric van Putten 948d3f3824SCedric van Putten expect(spawnAsync).toBeCalledWith( 958d3f3824SCedric van Putten 'npm', 968d3f3824SCedric van Putten ['install', '--save-peer', '@babel/core'], 978d3f3824SCedric van Putten expect.objectContaining({ cwd: projectRoot }) 988d3f3824SCedric van Putten ); 998d3f3824SCedric van Putten }); 1008d3f3824SCedric van Putten 1018d3f3824SCedric van Putten it('adds multiple packages with custom parameters', async () => { 1028d3f3824SCedric van Putten const npm = new NpmPackageManager({ cwd: projectRoot }); 1038d3f3824SCedric van Putten await npm.runAsync(['install', '--save-peer', '@babel/core', '@babel/runtime']); 1048d3f3824SCedric van Putten 1058d3f3824SCedric van Putten expect(spawnAsync).toBeCalledWith( 1068d3f3824SCedric van Putten 'npm', 1078d3f3824SCedric van Putten ['install', '--save-peer', '@babel/core', '@babel/runtime'], 1088d3f3824SCedric van Putten expect.objectContaining({ cwd: projectRoot }) 1098d3f3824SCedric van Putten ); 1108d3f3824SCedric van Putten }); 1118d3f3824SCedric van Putten }); 1128d3f3824SCedric van Putten 1138d3f3824SCedric van Putten describe('versionAsync', () => { 1148d3f3824SCedric van Putten it('returns version from npm', async () => { 1158d3f3824SCedric van Putten mockedSpawnAsync.mockImplementation(() => 1168d3f3824SCedric van Putten mockSpawnPromise(Promise.resolve({ stdout: '7.0.0\n' })) 1178d3f3824SCedric van Putten ); 1188d3f3824SCedric van Putten 1198d3f3824SCedric van Putten const npm = new NpmPackageManager({ cwd: projectRoot }); 1208d3f3824SCedric van Putten 1218d3f3824SCedric van Putten expect(await npm.versionAsync()).toBe('7.0.0'); 1228d3f3824SCedric van Putten expect(spawnAsync).toBeCalledWith('npm', ['--version'], expect.anything()); 1238d3f3824SCedric van Putten }); 1248d3f3824SCedric van Putten }); 1258d3f3824SCedric van Putten 1268d3f3824SCedric van Putten describe('getConfigAsync', () => { 1278d3f3824SCedric van Putten it('returns a configuration key from npm', async () => { 1288d3f3824SCedric van Putten mockedSpawnAsync.mockImplementation(() => 1298d3f3824SCedric van Putten mockSpawnPromise(Promise.resolve({ stdout: 'https://custom.registry.org/\n' })) 1308d3f3824SCedric van Putten ); 1318d3f3824SCedric van Putten 1328d3f3824SCedric van Putten const npm = new NpmPackageManager({ cwd: projectRoot }); 1338d3f3824SCedric van Putten 1348d3f3824SCedric van Putten expect(await npm.getConfigAsync('registry')).toBe('https://custom.registry.org/'); 1358d3f3824SCedric van Putten expect(spawnAsync).toBeCalledWith('npm', ['config', 'get', 'registry'], expect.anything()); 1368d3f3824SCedric van Putten }); 1378d3f3824SCedric van Putten }); 1388d3f3824SCedric van Putten 1398d3f3824SCedric van Putten describe('installAsync', () => { 1408d3f3824SCedric van Putten it('runs normal installation', async () => { 1418d3f3824SCedric van Putten const npm = new NpmPackageManager({ cwd: projectRoot }); 1428d3f3824SCedric van Putten await npm.installAsync(); 1438d3f3824SCedric van Putten 1448d3f3824SCedric van Putten expect(spawnAsync).toBeCalledWith( 1458d3f3824SCedric van Putten 'npm', 1468d3f3824SCedric van Putten ['install'], 1478d3f3824SCedric van Putten expect.objectContaining({ cwd: projectRoot }) 1488d3f3824SCedric van Putten ); 1498d3f3824SCedric van Putten }); 1508d3f3824SCedric van Putten 1518d3f3824SCedric van Putten it('runs installation with flags', async () => { 1528d3f3824SCedric van Putten const npm = new NpmPackageManager({ cwd: projectRoot }); 1538d3f3824SCedric van Putten await npm.installAsync(['--ignore-scripts']); 1548d3f3824SCedric van Putten 1558d3f3824SCedric van Putten expect(spawnAsync).toBeCalledWith( 1568d3f3824SCedric van Putten 'npm', 1578d3f3824SCedric van Putten ['install', '--ignore-scripts'], 1588d3f3824SCedric van Putten expect.objectContaining({ cwd: projectRoot }) 1598d3f3824SCedric van Putten ); 1608d3f3824SCedric van Putten }); 1618d3f3824SCedric van Putten }); 1628d3f3824SCedric van Putten 1638d3f3824SCedric van Putten describe('uninstallAsync', () => { 1648d3f3824SCedric van Putten afterEach(() => vol.reset()); 1658d3f3824SCedric van Putten 1668d3f3824SCedric van Putten it('removes node_modules folder relative to cwd', async () => { 1678d3f3824SCedric van Putten vol.fromJSON( 1688d3f3824SCedric van Putten { 1698d3f3824SCedric van Putten 'package.json': '{}', 1708d3f3824SCedric van Putten 'node_modules/expo/package.json': '{}', 1718d3f3824SCedric van Putten }, 1728d3f3824SCedric van Putten projectRoot 1738d3f3824SCedric van Putten ); 1748d3f3824SCedric van Putten 1758d3f3824SCedric van Putten const npm = new NpmPackageManager({ cwd: projectRoot }); 1768d3f3824SCedric van Putten await npm.uninstallAsync(); 1778d3f3824SCedric van Putten 1788d3f3824SCedric van Putten expect(vol.existsSync(path.join(projectRoot, 'node_modules'))).toBe(false); 1798d3f3824SCedric van Putten }); 1808d3f3824SCedric van Putten 1818d3f3824SCedric van Putten it('skips removing non-existing node_modules folder', async () => { 1828d3f3824SCedric van Putten vol.fromJSON({ 'package.json': '{}' }, projectRoot); 1838d3f3824SCedric van Putten 1848d3f3824SCedric van Putten const npm = new NpmPackageManager({ cwd: projectRoot }); 1858d3f3824SCedric van Putten await npm.uninstallAsync(); 1868d3f3824SCedric van Putten 1878d3f3824SCedric van Putten expect(vol.existsSync(path.join(projectRoot, 'node_modules'))).toBe(false); 1888d3f3824SCedric van Putten }); 1898d3f3824SCedric van Putten 1908d3f3824SCedric van Putten it('fails when no cwd is provided', async () => { 1918d3f3824SCedric van Putten const npm = new NpmPackageManager({ cwd: undefined }); 1928d3f3824SCedric van Putten await expect(npm.uninstallAsync()).rejects.toThrow('cwd is required'); 1938d3f3824SCedric van Putten }); 1948d3f3824SCedric van Putten }); 1958d3f3824SCedric van Putten 1968d3f3824SCedric van Putten describe('addAsync', () => { 1978d3f3824SCedric van Putten it('installs project without packages', async () => { 1988d3f3824SCedric van Putten const npm = new NpmPackageManager({ cwd: projectRoot }); 1998d3f3824SCedric van Putten await npm.addAsync(); 2008d3f3824SCedric van Putten 2018d3f3824SCedric van Putten expect(spawnAsync).toBeCalledWith( 2028d3f3824SCedric van Putten 'npm', 2038d3f3824SCedric van Putten ['install'], 2048d3f3824SCedric van Putten expect.objectContaining({ cwd: projectRoot }) 2058d3f3824SCedric van Putten ); 2068d3f3824SCedric van Putten }); 2078d3f3824SCedric van Putten 2088d3f3824SCedric van Putten it('returns pending spawn promise with child', async () => { 2098d3f3824SCedric van Putten const npm = new NpmPackageManager({ cwd: projectRoot }); 2108d3f3824SCedric van Putten const pending = npm.addAsync(['expo']); 2118d3f3824SCedric van Putten 2128d3f3824SCedric van Putten expect(pending).toHaveProperty('child', expect.any(Promise)); 2138d3f3824SCedric van Putten await expect(pending.child).resolves.toMatchObject(STUB_SPAWN_CHILD); 2148d3f3824SCedric van Putten }); 2158d3f3824SCedric van Putten 2168d3f3824SCedric van Putten it('adds a single unversioned package to dependencies', async () => { 2178d3f3824SCedric van Putten const npm = new NpmPackageManager({ cwd: projectRoot }); 2188d3f3824SCedric van Putten await npm.addAsync(['expo']); 2198d3f3824SCedric van Putten 2208d3f3824SCedric van Putten expect(spawnAsync).toBeCalledWith( 2218d3f3824SCedric van Putten 'npm', 2228d3f3824SCedric van Putten ['install', '--save', 'expo'], 2238d3f3824SCedric van Putten expect.objectContaining({ cwd: projectRoot }) 2248d3f3824SCedric van Putten ); 2258d3f3824SCedric van Putten }); 2268d3f3824SCedric van Putten 2278d3f3824SCedric van Putten it('adds a multiple unversioned package to dependencies', async () => { 2288d3f3824SCedric van Putten const npm = new NpmPackageManager({ cwd: projectRoot }); 2298d3f3824SCedric van Putten await npm.addAsync(['expo', 'react-native']); 2308d3f3824SCedric van Putten 2318d3f3824SCedric van Putten expect(spawnAsync).toBeCalledWith( 2328d3f3824SCedric van Putten 'npm', 2338d3f3824SCedric van Putten ['install', '--save', 'expo', 'react-native'], 2348d3f3824SCedric van Putten expect.objectContaining({ cwd: projectRoot }) 2358d3f3824SCedric van Putten ); 2368d3f3824SCedric van Putten }); 2378d3f3824SCedric van Putten 2388d3f3824SCedric van Putten it('installs multiple versioned dependencies by updating package.json', async () => { 2398d3f3824SCedric van Putten vol.fromJSON({ 'package.json': '{}' }, projectRoot); 2408d3f3824SCedric van Putten 2418d3f3824SCedric van Putten const npm = new NpmPackageManager({ cwd: projectRoot }); 2428d3f3824SCedric van Putten await npm.addAsync(['expo@^46', '[email protected]']); 2438d3f3824SCedric van Putten 2448d3f3824SCedric van Putten const packageFile = JSON.parse( 2458d3f3824SCedric van Putten vol.readFileSync(path.join(projectRoot, 'package.json')).toString() 2468d3f3824SCedric van Putten ); 2478d3f3824SCedric van Putten 2488d3f3824SCedric van Putten expect(packageFile).toHaveProperty( 2498d3f3824SCedric van Putten 'dependencies', 2508d3f3824SCedric van Putten expect.objectContaining({ expo: '^46', 'react-native': '0.69.3' }) 2518d3f3824SCedric van Putten ); 2528d3f3824SCedric van Putten expect(spawnAsync).toBeCalledWith( 2538d3f3824SCedric van Putten 'npm', 2548d3f3824SCedric van Putten ['install'], 2558d3f3824SCedric van Putten expect.objectContaining({ cwd: projectRoot }) 2568d3f3824SCedric van Putten ); 2578d3f3824SCedric van Putten }); 2588d3f3824SCedric van Putten 2598d3f3824SCedric van Putten it('installs mixed dependencies with flags by updating package.json', async () => { 2608d3f3824SCedric van Putten vol.fromJSON({ 'package.json': '{}' }, projectRoot); 2618d3f3824SCedric van Putten 2628d3f3824SCedric van Putten const npm = new NpmPackageManager({ cwd: projectRoot }); 2638d3f3824SCedric van Putten await npm.addAsync(['expo@^46', '[email protected]', 'jest', '--ignore-scripts']); 2648d3f3824SCedric van Putten 2658d3f3824SCedric van Putten const packageFile = JSON.parse( 2668d3f3824SCedric van Putten vol.readFileSync(path.join(projectRoot, 'package.json')).toString() 2678d3f3824SCedric van Putten ); 2688d3f3824SCedric van Putten 2698d3f3824SCedric van Putten expect(packageFile).toHaveProperty( 2708d3f3824SCedric van Putten 'dependencies', 2718d3f3824SCedric van Putten expect.objectContaining({ expo: '^46', 'react-native': '0.69.3' }) 2728d3f3824SCedric van Putten ); 2738d3f3824SCedric van Putten expect(spawnAsync).toBeCalledWith( 2748d3f3824SCedric van Putten 'npm', 2758d3f3824SCedric van Putten ['install', '--save', '--ignore-scripts', 'jest'], 2768d3f3824SCedric van Putten expect.objectContaining({ cwd: projectRoot }) 2778d3f3824SCedric van Putten ); 2788d3f3824SCedric van Putten }); 2798d3f3824SCedric van Putten 2808d3f3824SCedric van Putten it('installs dist-tag versions with --save', async () => { 2818d3f3824SCedric van Putten vol.fromJSON({ 'package.json': '{}' }, projectRoot); 2828d3f3824SCedric van Putten 2838d3f3824SCedric van Putten const npm = new NpmPackageManager({ cwd: projectRoot }); 2848d3f3824SCedric van Putten await npm.addAsync(['[email protected]', 'expo@next']); 2858d3f3824SCedric van Putten 2868d3f3824SCedric van Putten const packageFile = JSON.parse( 2878d3f3824SCedric van Putten vol.readFileSync(path.join(projectRoot, 'package.json')).toString() 2888d3f3824SCedric van Putten ); 2898d3f3824SCedric van Putten 2908d3f3824SCedric van Putten expect(packageFile).toHaveProperty( 2918d3f3824SCedric van Putten 'dependencies', 2928d3f3824SCedric van Putten expect.objectContaining({ 'react-native': '0.69.3' }) 2938d3f3824SCedric van Putten ); 2948d3f3824SCedric van Putten expect(spawnAsync).toBeCalledWith( 2958d3f3824SCedric van Putten 'npm', 2968d3f3824SCedric van Putten ['install', '--save', 'expo@next'], 2978d3f3824SCedric van Putten expect.objectContaining({ cwd: projectRoot }) 2988d3f3824SCedric van Putten ); 2998d3f3824SCedric van Putten }); 3008d3f3824SCedric van Putten }); 3018d3f3824SCedric van Putten 3028d3f3824SCedric van Putten describe('addDevAsync', () => { 3038d3f3824SCedric van Putten it('installs project without packages', async () => { 3048d3f3824SCedric van Putten const npm = new NpmPackageManager({ cwd: projectRoot }); 3058d3f3824SCedric van Putten await npm.addDevAsync(); 3068d3f3824SCedric van Putten 3078d3f3824SCedric van Putten expect(spawnAsync).toBeCalledWith( 3088d3f3824SCedric van Putten 'npm', 3098d3f3824SCedric van Putten ['install'], 3108d3f3824SCedric van Putten expect.objectContaining({ cwd: projectRoot }) 3118d3f3824SCedric van Putten ); 3128d3f3824SCedric van Putten }); 3138d3f3824SCedric van Putten 3148d3f3824SCedric van Putten it('returns pending spawn promise with child', async () => { 3158d3f3824SCedric van Putten const npm = new NpmPackageManager({ cwd: projectRoot }); 3168d3f3824SCedric van Putten const pending = npm.addDevAsync(['expo']); 3178d3f3824SCedric van Putten 3188d3f3824SCedric van Putten expect(pending).toHaveProperty('child', expect.any(Promise)); 3198d3f3824SCedric van Putten await expect(pending.child).resolves.toMatchObject(STUB_SPAWN_CHILD); 3208d3f3824SCedric van Putten }); 3218d3f3824SCedric van Putten 3228d3f3824SCedric van Putten it('adds a single unversioned package to dependencies', async () => { 3238d3f3824SCedric van Putten const npm = new NpmPackageManager({ cwd: projectRoot }); 3248d3f3824SCedric van Putten await npm.addDevAsync(['expo']); 3258d3f3824SCedric van Putten 3268d3f3824SCedric van Putten expect(spawnAsync).toBeCalledWith( 3278d3f3824SCedric van Putten 'npm', 3288d3f3824SCedric van Putten ['install', '--save-dev', 'expo'], 3298d3f3824SCedric van Putten expect.objectContaining({ cwd: projectRoot }) 3308d3f3824SCedric van Putten ); 3318d3f3824SCedric van Putten }); 3328d3f3824SCedric van Putten 3338d3f3824SCedric van Putten it('adds a multiple unversioned package to dependencies', async () => { 3348d3f3824SCedric van Putten const npm = new NpmPackageManager({ cwd: projectRoot }); 3358d3f3824SCedric van Putten await npm.addDevAsync(['expo', 'react-native']); 3368d3f3824SCedric van Putten 3378d3f3824SCedric van Putten expect(spawnAsync).toBeCalledWith( 3388d3f3824SCedric van Putten 'npm', 3398d3f3824SCedric van Putten ['install', '--save-dev', 'expo', 'react-native'], 3408d3f3824SCedric van Putten expect.objectContaining({ cwd: projectRoot }) 3418d3f3824SCedric van Putten ); 3428d3f3824SCedric van Putten }); 3438d3f3824SCedric van Putten 3448d3f3824SCedric van Putten it('installs multiple versioned dependencies by updating package.json', async () => { 3458d3f3824SCedric van Putten vol.fromJSON({ 'package.json': '{}' }, projectRoot); 3468d3f3824SCedric van Putten 3478d3f3824SCedric van Putten const npm = new NpmPackageManager({ cwd: projectRoot }); 3488d3f3824SCedric van Putten await npm.addDevAsync(['expo@^46', '[email protected]']); 3498d3f3824SCedric van Putten 3508d3f3824SCedric van Putten const packageFile = JSON.parse( 3518d3f3824SCedric van Putten vol.readFileSync(path.join(projectRoot, 'package.json')).toString() 3528d3f3824SCedric van Putten ); 3538d3f3824SCedric van Putten 3548d3f3824SCedric van Putten expect(packageFile).toHaveProperty( 3558d3f3824SCedric van Putten 'devDependencies', 3568d3f3824SCedric van Putten expect.objectContaining({ expo: '^46', 'react-native': '0.69.3' }) 3578d3f3824SCedric van Putten ); 3588d3f3824SCedric van Putten expect(spawnAsync).toBeCalledWith( 3598d3f3824SCedric van Putten 'npm', 3608d3f3824SCedric van Putten ['install'], 3618d3f3824SCedric van Putten expect.objectContaining({ cwd: projectRoot }) 3628d3f3824SCedric van Putten ); 3638d3f3824SCedric van Putten }); 3648d3f3824SCedric van Putten 3658d3f3824SCedric van Putten it('installs mixed dependencies with flags by updating package.json', async () => { 3668d3f3824SCedric van Putten vol.fromJSON({ 'package.json': '{}' }, projectRoot); 3678d3f3824SCedric van Putten 3688d3f3824SCedric van Putten const npm = new NpmPackageManager({ cwd: projectRoot }); 3698d3f3824SCedric van Putten await npm.addDevAsync(['expo@^46', '[email protected]', 'jest', '--ignore-scripts']); 3708d3f3824SCedric van Putten 3718d3f3824SCedric van Putten const packageFile = JSON.parse( 3728d3f3824SCedric van Putten vol.readFileSync(path.join(projectRoot, 'package.json')).toString() 3738d3f3824SCedric van Putten ); 3748d3f3824SCedric van Putten 3758d3f3824SCedric van Putten expect(packageFile).toHaveProperty( 3768d3f3824SCedric van Putten 'devDependencies', 3778d3f3824SCedric van Putten expect.objectContaining({ expo: '^46', 'react-native': '0.69.3' }) 3788d3f3824SCedric van Putten ); 3798d3f3824SCedric van Putten expect(spawnAsync).toBeCalledWith( 3808d3f3824SCedric van Putten 'npm', 3818d3f3824SCedric van Putten ['install', '--save-dev', '--ignore-scripts', 'jest'], 3828d3f3824SCedric van Putten expect.objectContaining({ cwd: projectRoot }) 3838d3f3824SCedric van Putten ); 3848d3f3824SCedric van Putten }); 3858d3f3824SCedric van Putten 3868d3f3824SCedric van Putten it('installs dist-tag versions with --save', async () => { 3878d3f3824SCedric van Putten vol.fromJSON({ 'package.json': '{}' }, projectRoot); 3888d3f3824SCedric van Putten 3898d3f3824SCedric van Putten const npm = new NpmPackageManager({ cwd: projectRoot }); 3908d3f3824SCedric van Putten await npm.addDevAsync(['[email protected]', 'expo@next']); 3918d3f3824SCedric van Putten 3928d3f3824SCedric van Putten const packageFile = JSON.parse( 3938d3f3824SCedric van Putten vol.readFileSync(path.join(projectRoot, 'package.json')).toString() 3948d3f3824SCedric van Putten ); 3958d3f3824SCedric van Putten 3968d3f3824SCedric van Putten expect(packageFile).toHaveProperty( 3978d3f3824SCedric van Putten 'devDependencies', 3988d3f3824SCedric van Putten expect.objectContaining({ 'react-native': '0.69.3' }) 3998d3f3824SCedric van Putten ); 4008d3f3824SCedric van Putten expect(spawnAsync).toBeCalledWith( 4018d3f3824SCedric van Putten 'npm', 4028d3f3824SCedric van Putten ['install', '--save-dev', 'expo@next'], 4038d3f3824SCedric van Putten expect.objectContaining({ cwd: projectRoot }) 4048d3f3824SCedric van Putten ); 4058d3f3824SCedric van Putten }); 4068d3f3824SCedric van Putten }); 4078d3f3824SCedric van Putten 4088d3f3824SCedric van Putten describe('addGlobalAsync', () => { 4098d3f3824SCedric van Putten it('installs project without packages', async () => { 4108d3f3824SCedric van Putten const npm = new NpmPackageManager({ cwd: projectRoot }); 4118d3f3824SCedric van Putten await npm.addGlobalAsync(); 4128d3f3824SCedric van Putten 4138d3f3824SCedric van Putten expect(spawnAsync).toBeCalledWith( 4148d3f3824SCedric van Putten 'npm', 4158d3f3824SCedric van Putten ['install'], 4168d3f3824SCedric van Putten expect.objectContaining({ cwd: projectRoot }) 4178d3f3824SCedric van Putten ); 4188d3f3824SCedric van Putten }); 4198d3f3824SCedric van Putten 4208d3f3824SCedric van Putten it('adds a single package globally', async () => { 4218d3f3824SCedric van Putten const npm = new NpmPackageManager({ cwd: projectRoot }); 4228d3f3824SCedric van Putten await npm.addGlobalAsync(['expo-cli@^5']); 4238d3f3824SCedric van Putten 4248d3f3824SCedric van Putten expect(spawnAsync).toBeCalledWith( 4258d3f3824SCedric van Putten 'npm', 4268d3f3824SCedric van Putten ['install', '--global', 'expo-cli@^5'], 4278d3f3824SCedric van Putten expect.anything() 4288d3f3824SCedric van Putten ); 4298d3f3824SCedric van Putten }); 4308d3f3824SCedric van Putten 4318d3f3824SCedric van Putten it('adds multiple packages globally', async () => { 4328d3f3824SCedric van Putten const npm = new NpmPackageManager({ cwd: projectRoot }); 4338d3f3824SCedric van Putten await npm.addGlobalAsync(['expo-cli@^5', 'eas-cli']); 4348d3f3824SCedric van Putten 4358d3f3824SCedric van Putten expect(spawnAsync).toBeCalledWith( 4368d3f3824SCedric van Putten 'npm', 4378d3f3824SCedric van Putten ['install', '--global', 'expo-cli@^5', 'eas-cli'], 4388d3f3824SCedric van Putten expect.anything() 4398d3f3824SCedric van Putten ); 4408d3f3824SCedric van Putten }); 4418d3f3824SCedric van Putten }); 4428d3f3824SCedric van Putten 4438d3f3824SCedric van Putten describe('removeAsync', () => { 4448d3f3824SCedric van Putten it('removes a single package', async () => { 4458d3f3824SCedric van Putten const npm = new NpmPackageManager({ cwd: projectRoot }); 4468d3f3824SCedric van Putten await npm.removeAsync(['metro']); 4478d3f3824SCedric van Putten 4488d3f3824SCedric van Putten expect(spawnAsync).toBeCalledWith( 4498d3f3824SCedric van Putten 'npm', 4508d3f3824SCedric van Putten ['uninstall', 'metro'], 4518d3f3824SCedric van Putten expect.objectContaining({ cwd: projectRoot }) 4528d3f3824SCedric van Putten ); 4538d3f3824SCedric van Putten }); 4548d3f3824SCedric van Putten 4558d3f3824SCedric van Putten it('removes multiple packages', async () => { 4568d3f3824SCedric van Putten const npm = new NpmPackageManager({ cwd: projectRoot }); 4578d3f3824SCedric van Putten await npm.removeAsync(['metro', 'jest-haste-map']); 4588d3f3824SCedric van Putten 4598d3f3824SCedric van Putten expect(spawnAsync).toBeCalledWith( 4608d3f3824SCedric van Putten 'npm', 4618d3f3824SCedric van Putten ['uninstall', 'metro', 'jest-haste-map'], 4628d3f3824SCedric van Putten expect.objectContaining({ cwd: projectRoot }) 4638d3f3824SCedric van Putten ); 4648d3f3824SCedric van Putten }); 4658d3f3824SCedric van Putten }); 4668d3f3824SCedric van Putten 4678d3f3824SCedric van Putten describe('removeDevAsync', () => { 4688d3f3824SCedric van Putten it('removes a single package', async () => { 4698d3f3824SCedric van Putten const npm = new NpmPackageManager({ cwd: projectRoot }); 4708d3f3824SCedric van Putten await npm.removeDevAsync(['metro']); 4718d3f3824SCedric van Putten 4728d3f3824SCedric van Putten expect(spawnAsync).toBeCalledWith( 4738d3f3824SCedric van Putten 'npm', 4748d3f3824SCedric van Putten ['uninstall', '--save-dev', 'metro'], 4758d3f3824SCedric van Putten expect.objectContaining({ cwd: projectRoot }) 4768d3f3824SCedric van Putten ); 4778d3f3824SCedric van Putten }); 4788d3f3824SCedric van Putten 4798d3f3824SCedric van Putten it('removes multiple packages', async () => { 4808d3f3824SCedric van Putten const npm = new NpmPackageManager({ cwd: projectRoot }); 4818d3f3824SCedric van Putten await npm.removeDevAsync(['metro', 'jest-haste-map']); 4828d3f3824SCedric van Putten 4838d3f3824SCedric van Putten expect(spawnAsync).toBeCalledWith( 4848d3f3824SCedric van Putten 'npm', 4858d3f3824SCedric van Putten ['uninstall', '--save-dev', 'metro', 'jest-haste-map'], 4868d3f3824SCedric van Putten expect.objectContaining({ cwd: projectRoot }) 4878d3f3824SCedric van Putten ); 4888d3f3824SCedric van Putten }); 4898d3f3824SCedric van Putten }); 4908d3f3824SCedric van Putten 4918d3f3824SCedric van Putten describe('removeGlobalAsync', () => { 4928d3f3824SCedric van Putten it('removes a single package', async () => { 4938d3f3824SCedric van Putten const npm = new NpmPackageManager({ cwd: projectRoot }); 4948d3f3824SCedric van Putten await npm.removeGlobalAsync(['expo-cli']); 4958d3f3824SCedric van Putten 4968d3f3824SCedric van Putten expect(spawnAsync).toBeCalledWith( 4978d3f3824SCedric van Putten 'npm', 4988d3f3824SCedric van Putten ['uninstall', '--global', 'expo-cli'], 4998d3f3824SCedric van Putten expect.objectContaining({ cwd: projectRoot }) 5008d3f3824SCedric van Putten ); 5018d3f3824SCedric van Putten }); 5028d3f3824SCedric van Putten 5038d3f3824SCedric van Putten it('removes multiple packages', async () => { 5048d3f3824SCedric van Putten const npm = new NpmPackageManager({ cwd: projectRoot }); 5058d3f3824SCedric van Putten await npm.removeGlobalAsync(['expo-cli', 'eas-cli']); 5068d3f3824SCedric van Putten 5078d3f3824SCedric van Putten expect(spawnAsync).toBeCalledWith( 5088d3f3824SCedric van Putten 'npm', 5098d3f3824SCedric van Putten ['uninstall', '--global', 'expo-cli', 'eas-cli'], 5108d3f3824SCedric van Putten expect.objectContaining({ cwd: projectRoot }) 5118d3f3824SCedric van Putten ); 5128d3f3824SCedric van Putten }); 5138d3f3824SCedric van Putten }); 5148d3f3824SCedric van Putten 5158d3f3824SCedric van Putten describe('workspaceRoot', () => { 5168d3f3824SCedric van Putten const workspaceRoot = '/monorepo'; 5178d3f3824SCedric van Putten const projectRoot = '/monorepo/packages/test'; 5188d3f3824SCedric van Putten 5198d3f3824SCedric van Putten it('returns null for non-monorepo project', () => { 5208d3f3824SCedric van Putten vol.fromJSON( 5218d3f3824SCedric van Putten { 5228d3f3824SCedric van Putten 'package.json': JSON.stringify({ name: 'project' }), 5238d3f3824SCedric van Putten }, 5248d3f3824SCedric van Putten projectRoot 5258d3f3824SCedric van Putten ); 5268d3f3824SCedric van Putten 5278d3f3824SCedric van Putten const npm = new NpmPackageManager({ cwd: projectRoot }); 5288d3f3824SCedric van Putten expect(npm.workspaceRoot()).toBeNull(); 5298d3f3824SCedric van Putten }); 5308d3f3824SCedric van Putten 5318d3f3824SCedric van Putten it('returns new instance for monorepo project', () => { 5328d3f3824SCedric van Putten vol.fromJSON( 5338d3f3824SCedric van Putten { 5348d3f3824SCedric van Putten 'packages/test/package.json': JSON.stringify({ name: 'project' }), 5358d3f3824SCedric van Putten 'package.json': JSON.stringify({ 5368d3f3824SCedric van Putten name: 'monorepo', 5378d3f3824SCedric van Putten workspaces: ['packages/*'], 5388d3f3824SCedric van Putten }), 5398d3f3824SCedric van Putten }, 5408d3f3824SCedric van Putten workspaceRoot 5418d3f3824SCedric van Putten ); 5428d3f3824SCedric van Putten 5438d3f3824SCedric van Putten const npm = new NpmPackageManager({ cwd: projectRoot }); 5448d3f3824SCedric van Putten const root = npm.workspaceRoot(); 5458d3f3824SCedric van Putten expect(root).toBeInstanceOf(NpmPackageManager); 5468d3f3824SCedric van Putten expect(root).not.toBe(npm); 5478d3f3824SCedric van Putten }); 5488d3f3824SCedric van Putten }); 5498d3f3824SCedric van Putten}); 550