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 { YarnPackageManager } from '../YarnPackageManager';
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('YarnPackageManager', () => {
178d3f3824SCedric van Putten  const projectRoot = '/project/with-yarn';
188d3f3824SCedric van Putten
198d3f3824SCedric van Putten  it('name is set to yarn', () => {
208d3f3824SCedric van Putten    const yarn = new YarnPackageManager({ cwd: projectRoot });
218d3f3824SCedric van Putten    expect(yarn.name).toBe('yarn');
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 yarn = new YarnPackageManager({ cwd: projectRoot });
278d3f3824SCedric van Putten      await yarn.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 yarn = new YarnPackageManager({ cwd: projectRoot, env: { ADBLOCK: '0' } });
408d3f3824SCedric van Putten      await yarn.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 yarn = new YarnPackageManager({ cwd: projectRoot, log });
568d3f3824SCedric van Putten      await yarn.runAsync(['install', '--some-flag']);
578d3f3824SCedric van Putten      expect(log).toHaveBeenCalledWith('> yarn install --some-flag');
588d3f3824SCedric van Putten    });
598d3f3824SCedric van Putten
60*efdcf92fSCedric van Putten    it('inherits stdio output without silent', async () => {
618d3f3824SCedric van Putten      const yarn = new YarnPackageManager({ cwd: projectRoot });
62*efdcf92fSCedric van Putten      await yarn.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 yarn = new YarnPackageManager({ cwd: projectRoot, silent: true });
73*efdcf92fSCedric van Putten      await yarn.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('adds a single package with custom parameters', async () => {
838d3f3824SCedric van Putten      const yarn = new YarnPackageManager({ cwd: projectRoot });
848d3f3824SCedric van Putten      await yarn.runAsync(['add', '--peer', '@babel/core']);
858d3f3824SCedric van Putten
868d3f3824SCedric van Putten      expect(spawnAsync).toBeCalledWith(
878d3f3824SCedric van Putten        'yarnpkg',
888d3f3824SCedric van Putten        ['add', '--peer', '@babel/core'],
898d3f3824SCedric van Putten        expect.objectContaining({ cwd: projectRoot })
908d3f3824SCedric van Putten      );
918d3f3824SCedric van Putten    });
928d3f3824SCedric van Putten
938d3f3824SCedric van Putten    it('adds multiple packages with custom parameters', async () => {
948d3f3824SCedric van Putten      const yarn = new YarnPackageManager({ cwd: projectRoot });
958d3f3824SCedric van Putten      await yarn.runAsync(['add', '--peer', '@babel/core', '@babel/runtime']);
968d3f3824SCedric van Putten
978d3f3824SCedric van Putten      expect(spawnAsync).toBeCalledWith(
988d3f3824SCedric van Putten        'yarnpkg',
998d3f3824SCedric van Putten        ['add', '--peer', '@babel/core', '@babel/runtime'],
1008d3f3824SCedric van Putten        expect.objectContaining({ cwd: projectRoot })
1018d3f3824SCedric van Putten      );
1028d3f3824SCedric van Putten    });
1038d3f3824SCedric van Putten  });
1048d3f3824SCedric van Putten
1058d3f3824SCedric van Putten  describe('versionAsync', () => {
1068d3f3824SCedric van Putten    it('returns version from yarn', async () => {
1078d3f3824SCedric van Putten      mockedSpawnAsync.mockImplementation(() =>
1088d3f3824SCedric van Putten        mockSpawnPromise(Promise.resolve({ stdout: '4.2.0\n' }))
1098d3f3824SCedric van Putten      );
1108d3f3824SCedric van Putten
1118d3f3824SCedric van Putten      const yarn = new YarnPackageManager({ cwd: projectRoot });
1128d3f3824SCedric van Putten
1138d3f3824SCedric van Putten      expect(await yarn.versionAsync()).toBe('4.2.0');
1148d3f3824SCedric van Putten      expect(spawnAsync).toBeCalledWith('yarnpkg', ['--version'], expect.anything());
1158d3f3824SCedric van Putten    });
1168d3f3824SCedric van Putten  });
1178d3f3824SCedric van Putten
1188d3f3824SCedric van Putten  describe('getConfigAsync', () => {
1198d3f3824SCedric van Putten    it('returns a configuration key from yarn', async () => {
1208d3f3824SCedric van Putten      mockedSpawnAsync.mockImplementation(() =>
1218d3f3824SCedric van Putten        mockSpawnPromise(Promise.resolve({ stdout: 'https://custom.registry.org/\n' }))
1228d3f3824SCedric van Putten      );
1238d3f3824SCedric van Putten
1248d3f3824SCedric van Putten      const yarn = new YarnPackageManager({ cwd: projectRoot });
1258d3f3824SCedric van Putten
1268d3f3824SCedric van Putten      expect(await yarn.getConfigAsync('registry')).toBe('https://custom.registry.org/');
1278d3f3824SCedric van Putten      expect(spawnAsync).toBeCalledWith(
1288d3f3824SCedric van Putten        'yarnpkg',
1298d3f3824SCedric van Putten        ['config', 'get', 'registry'],
1308d3f3824SCedric van Putten        expect.anything()
1318d3f3824SCedric van Putten      );
1328d3f3824SCedric van Putten    });
1338d3f3824SCedric van Putten  });
1348d3f3824SCedric van Putten
1358d3f3824SCedric van Putten  describe('installAsync', () => {
1368d3f3824SCedric van Putten    it('runs normal installation', async () => {
1378d3f3824SCedric van Putten      const yarn = new YarnPackageManager({ cwd: projectRoot });
1388d3f3824SCedric van Putten      await yarn.installAsync();
1398d3f3824SCedric van Putten
1408d3f3824SCedric van Putten      expect(spawnAsync).toBeCalledWith(
1418d3f3824SCedric van Putten        'yarnpkg',
1428d3f3824SCedric van Putten        ['install'],
1438d3f3824SCedric van Putten        expect.objectContaining({ cwd: projectRoot })
1448d3f3824SCedric van Putten      );
1458d3f3824SCedric van Putten    });
1468d3f3824SCedric van Putten
1478d3f3824SCedric van Putten    it('runs installation with flags', async () => {
1488d3f3824SCedric van Putten      const yarn = new YarnPackageManager({ cwd: projectRoot });
1498d3f3824SCedric van Putten      await yarn.installAsync(['--ignore-scripts']);
1508d3f3824SCedric van Putten
1518d3f3824SCedric van Putten      expect(spawnAsync).toBeCalledWith(
1528d3f3824SCedric van Putten        'yarnpkg',
1538d3f3824SCedric van Putten        ['install', '--ignore-scripts'],
1548d3f3824SCedric van Putten        expect.objectContaining({ cwd: projectRoot })
1558d3f3824SCedric van Putten      );
1568d3f3824SCedric van Putten    });
1578d3f3824SCedric van Putten  });
1588d3f3824SCedric van Putten
1598d3f3824SCedric van Putten  describe('uninstallAsync', () => {
1608d3f3824SCedric van Putten    afterEach(() => vol.reset());
1618d3f3824SCedric van Putten
1628d3f3824SCedric van Putten    it('removes node_modules folder relative to cwd', async () => {
1638d3f3824SCedric van Putten      vol.fromJSON(
1648d3f3824SCedric van Putten        {
1658d3f3824SCedric van Putten          'package.json': '{}',
1668d3f3824SCedric van Putten          'node_modules/expo/package.json': '{}',
1678d3f3824SCedric van Putten        },
1688d3f3824SCedric van Putten        projectRoot
1698d3f3824SCedric van Putten      );
1708d3f3824SCedric van Putten
1718d3f3824SCedric van Putten      const yarn = new YarnPackageManager({ cwd: projectRoot });
1728d3f3824SCedric van Putten      await yarn.uninstallAsync();
1738d3f3824SCedric van Putten
1748d3f3824SCedric van Putten      expect(vol.existsSync(path.join(projectRoot, 'node_modules'))).toBe(false);
1758d3f3824SCedric van Putten    });
1768d3f3824SCedric van Putten
1778d3f3824SCedric van Putten    it('skips removing non-existing node_modules folder', async () => {
1788d3f3824SCedric van Putten      vol.fromJSON({ 'package.json': '{}' }, projectRoot);
1798d3f3824SCedric van Putten
1808d3f3824SCedric van Putten      const yarn = new YarnPackageManager({ cwd: projectRoot });
1818d3f3824SCedric van Putten      await yarn.uninstallAsync();
1828d3f3824SCedric van Putten
1838d3f3824SCedric van Putten      expect(vol.existsSync(path.join(projectRoot, 'node_modules'))).toBe(false);
1848d3f3824SCedric van Putten    });
1858d3f3824SCedric van Putten
1868d3f3824SCedric van Putten    it('fails when no cwd is provided', async () => {
1878d3f3824SCedric van Putten      const yarn = new YarnPackageManager({ cwd: undefined });
1888d3f3824SCedric van Putten      await expect(yarn.uninstallAsync()).rejects.toThrow('cwd is required');
1898d3f3824SCedric van Putten    });
1908d3f3824SCedric van Putten  });
1918d3f3824SCedric van Putten
1928d3f3824SCedric van Putten  describe('addAsync', () => {
1938d3f3824SCedric van Putten    it('installs project without packages', async () => {
1948d3f3824SCedric van Putten      const yarn = new YarnPackageManager({ cwd: projectRoot });
1958d3f3824SCedric van Putten      await yarn.addAsync();
1968d3f3824SCedric van Putten
1978d3f3824SCedric van Putten      expect(spawnAsync).toBeCalledWith(
1988d3f3824SCedric van Putten        'yarnpkg',
1998d3f3824SCedric van Putten        ['install'],
2008d3f3824SCedric van Putten        expect.objectContaining({ cwd: projectRoot })
2018d3f3824SCedric van Putten      );
2028d3f3824SCedric van Putten    });
2038d3f3824SCedric van Putten
2048d3f3824SCedric van Putten    it('returns pending spawn promise with child', async () => {
2058d3f3824SCedric van Putten      const yarn = new YarnPackageManager({ cwd: projectRoot });
2068d3f3824SCedric van Putten      const pending = yarn.addAsync(['expo']);
2078d3f3824SCedric van Putten
2088d3f3824SCedric van Putten      expect(pending).toHaveProperty('child', expect.any(Promise));
2098d3f3824SCedric van Putten      await expect(pending.child).resolves.toMatchObject(STUB_SPAWN_CHILD);
2108d3f3824SCedric van Putten    });
2118d3f3824SCedric van Putten
2128d3f3824SCedric van Putten    it('adds a single package to dependencies', async () => {
2138d3f3824SCedric van Putten      const yarn = new YarnPackageManager({ cwd: projectRoot });
2148d3f3824SCedric van Putten      await yarn.addAsync(['@react-navigation/native']);
2158d3f3824SCedric van Putten
2168d3f3824SCedric van Putten      expect(spawnAsync).toBeCalledWith(
2178d3f3824SCedric van Putten        'yarnpkg',
2188d3f3824SCedric van Putten        ['add', '@react-navigation/native'],
2198d3f3824SCedric van Putten        expect.objectContaining({ cwd: projectRoot })
2208d3f3824SCedric van Putten      );
2218d3f3824SCedric van Putten    });
2228d3f3824SCedric van Putten
2238d3f3824SCedric van Putten    it('adds multiple packages to dependencies', async () => {
2248d3f3824SCedric van Putten      const yarn = new YarnPackageManager({ cwd: projectRoot });
2258d3f3824SCedric van Putten      await yarn.addAsync(['@react-navigation/native', '@react-navigation/drawer']);
2268d3f3824SCedric van Putten
2278d3f3824SCedric van Putten      expect(spawnAsync).toBeCalledWith(
2288d3f3824SCedric van Putten        'yarnpkg',
2298d3f3824SCedric van Putten        ['add', '@react-navigation/native', '@react-navigation/drawer'],
2308d3f3824SCedric van Putten        expect.objectContaining({ cwd: projectRoot })
2318d3f3824SCedric van Putten      );
2328d3f3824SCedric van Putten    });
2338d3f3824SCedric van Putten  });
2348d3f3824SCedric van Putten
2358d3f3824SCedric van Putten  describe('addDevAsync', () => {
2368d3f3824SCedric van Putten    it('installs project without packages', async () => {
2378d3f3824SCedric van Putten      const yarn = new YarnPackageManager({ cwd: projectRoot });
2388d3f3824SCedric van Putten      await yarn.addDevAsync();
2398d3f3824SCedric van Putten
2408d3f3824SCedric van Putten      expect(spawnAsync).toBeCalledWith(
2418d3f3824SCedric van Putten        'yarnpkg',
2428d3f3824SCedric van Putten        ['install'],
2438d3f3824SCedric van Putten        expect.objectContaining({ cwd: projectRoot })
2448d3f3824SCedric van Putten      );
2458d3f3824SCedric van Putten    });
2468d3f3824SCedric van Putten
2478d3f3824SCedric van Putten    it('returns pending spawn promise with child', async () => {
2488d3f3824SCedric van Putten      const yarn = new YarnPackageManager({ cwd: projectRoot });
2498d3f3824SCedric van Putten      const pending = yarn.addDevAsync(['expo']);
2508d3f3824SCedric van Putten
2518d3f3824SCedric van Putten      expect(pending).toHaveProperty('child', expect.any(Promise));
2528d3f3824SCedric van Putten      await expect(pending.child).resolves.toMatchObject(STUB_SPAWN_CHILD);
2538d3f3824SCedric van Putten    });
2548d3f3824SCedric van Putten
2558d3f3824SCedric van Putten    it('adds a single package to dev dependencies', async () => {
2568d3f3824SCedric van Putten      const yarn = new YarnPackageManager({ cwd: projectRoot });
2578d3f3824SCedric van Putten      await yarn.addDevAsync(['eslint']);
2588d3f3824SCedric van Putten
2598d3f3824SCedric van Putten      expect(spawnAsync).toBeCalledWith(
2608d3f3824SCedric van Putten        'yarnpkg',
2618d3f3824SCedric van Putten        ['add', '--dev', 'eslint'],
2628d3f3824SCedric van Putten        expect.objectContaining({ cwd: projectRoot })
2638d3f3824SCedric van Putten      );
2648d3f3824SCedric van Putten    });
2658d3f3824SCedric van Putten
2668d3f3824SCedric van Putten    it('adds multiple packages to dev dependencies', async () => {
2678d3f3824SCedric van Putten      const yarn = new YarnPackageManager({ cwd: projectRoot });
2688d3f3824SCedric van Putten      await yarn.addDevAsync(['eslint', 'prettier']);
2698d3f3824SCedric van Putten
2708d3f3824SCedric van Putten      expect(spawnAsync).toBeCalledWith(
2718d3f3824SCedric van Putten        'yarnpkg',
2728d3f3824SCedric van Putten        ['add', '--dev', 'eslint', 'prettier'],
2738d3f3824SCedric van Putten        expect.objectContaining({ cwd: projectRoot })
2748d3f3824SCedric van Putten      );
2758d3f3824SCedric van Putten    });
2768d3f3824SCedric van Putten  });
2778d3f3824SCedric van Putten
2788d3f3824SCedric van Putten  describe('addGlobalAsync', () => {
2798d3f3824SCedric van Putten    it('installs project without packages', async () => {
2808d3f3824SCedric van Putten      const yarn = new YarnPackageManager({ cwd: projectRoot });
2818d3f3824SCedric van Putten      await yarn.addGlobalAsync();
2828d3f3824SCedric van Putten
2838d3f3824SCedric van Putten      expect(spawnAsync).toBeCalledWith(
2848d3f3824SCedric van Putten        'yarnpkg',
2858d3f3824SCedric van Putten        ['install'],
2868d3f3824SCedric van Putten        expect.objectContaining({ cwd: projectRoot })
2878d3f3824SCedric van Putten      );
2888d3f3824SCedric van Putten    });
2898d3f3824SCedric van Putten
2908d3f3824SCedric van Putten    it('returns pending spawn promise with child', async () => {
2918d3f3824SCedric van Putten      const yarn = new YarnPackageManager({ cwd: projectRoot });
2928d3f3824SCedric van Putten      const pending = yarn.addGlobalAsync(['expo']);
2938d3f3824SCedric van Putten
2948d3f3824SCedric van Putten      expect(pending).toHaveProperty('child', expect.any(Promise));
2958d3f3824SCedric van Putten      await expect(pending.child).resolves.toMatchObject(STUB_SPAWN_CHILD);
2968d3f3824SCedric van Putten    });
2978d3f3824SCedric van Putten
2988d3f3824SCedric van Putten    it('adds a single package globally', async () => {
2998d3f3824SCedric van Putten      const yarn = new YarnPackageManager({ cwd: projectRoot });
3008d3f3824SCedric van Putten      await yarn.addGlobalAsync(['expo-cli@^5']);
3018d3f3824SCedric van Putten
3028d3f3824SCedric van Putten      expect(spawnAsync).toBeCalledWith(
3038d3f3824SCedric van Putten        'yarnpkg',
3048d3f3824SCedric van Putten        ['global', 'add', 'expo-cli@^5'],
3058d3f3824SCedric van Putten        expect.anything()
3068d3f3824SCedric van Putten      );
3078d3f3824SCedric van Putten    });
3088d3f3824SCedric van Putten
3098d3f3824SCedric van Putten    it('adds multiple packages globally', async () => {
3108d3f3824SCedric van Putten      const yarn = new YarnPackageManager({ cwd: projectRoot });
3118d3f3824SCedric van Putten      await yarn.addGlobalAsync(['expo-cli@^5', 'eas-cli']);
3128d3f3824SCedric van Putten
3138d3f3824SCedric van Putten      expect(spawnAsync).toBeCalledWith(
3148d3f3824SCedric van Putten        'yarnpkg',
3158d3f3824SCedric van Putten        ['global', 'add', 'expo-cli@^5', 'eas-cli'],
3168d3f3824SCedric van Putten        expect.anything()
3178d3f3824SCedric van Putten      );
3188d3f3824SCedric van Putten    });
3198d3f3824SCedric van Putten  });
3208d3f3824SCedric van Putten
3218d3f3824SCedric van Putten  describe('removeAsync', () => {
3228d3f3824SCedric van Putten    it('removes a single package', async () => {
3238d3f3824SCedric van Putten      const yarn = new YarnPackageManager({ cwd: projectRoot });
3248d3f3824SCedric van Putten      await yarn.removeAsync(['metro']);
3258d3f3824SCedric van Putten
3268d3f3824SCedric van Putten      expect(spawnAsync).toBeCalledWith(
3278d3f3824SCedric van Putten        'yarnpkg',
3288d3f3824SCedric van Putten        ['remove', 'metro'],
3298d3f3824SCedric van Putten        expect.objectContaining({ cwd: projectRoot })
3308d3f3824SCedric van Putten      );
3318d3f3824SCedric van Putten    });
3328d3f3824SCedric van Putten
3338d3f3824SCedric van Putten    it('removes multiple packages', async () => {
3348d3f3824SCedric van Putten      const yarn = new YarnPackageManager({ cwd: projectRoot });
3358d3f3824SCedric van Putten      await yarn.removeAsync(['metro', 'jest-haste-map']);
3368d3f3824SCedric van Putten
3378d3f3824SCedric van Putten      expect(spawnAsync).toBeCalledWith(
3388d3f3824SCedric van Putten        'yarnpkg',
3398d3f3824SCedric van Putten        ['remove', 'metro', 'jest-haste-map'],
3408d3f3824SCedric van Putten        expect.objectContaining({ cwd: projectRoot })
3418d3f3824SCedric van Putten      );
3428d3f3824SCedric van Putten    });
3438d3f3824SCedric van Putten  });
3448d3f3824SCedric van Putten
3458d3f3824SCedric van Putten  describe('removeDevAsync', () => {
3468d3f3824SCedric van Putten    it('removes a single package', async () => {
3478d3f3824SCedric van Putten      const yarn = new YarnPackageManager({ cwd: projectRoot });
3488d3f3824SCedric van Putten      await yarn.removeDevAsync(['metro']);
3498d3f3824SCedric van Putten
3508d3f3824SCedric van Putten      expect(spawnAsync).toBeCalledWith(
3518d3f3824SCedric van Putten        'yarnpkg',
3528d3f3824SCedric van Putten        ['remove', 'metro'],
3538d3f3824SCedric van Putten        expect.objectContaining({ cwd: projectRoot })
3548d3f3824SCedric van Putten      );
3558d3f3824SCedric van Putten    });
3568d3f3824SCedric van Putten
3578d3f3824SCedric van Putten    it('removes multiple packages', async () => {
3588d3f3824SCedric van Putten      const yarn = new YarnPackageManager({ cwd: projectRoot });
3598d3f3824SCedric van Putten      await yarn.removeDevAsync(['metro', 'jest-haste-map']);
3608d3f3824SCedric van Putten
3618d3f3824SCedric van Putten      expect(spawnAsync).toBeCalledWith(
3628d3f3824SCedric van Putten        'yarnpkg',
3638d3f3824SCedric van Putten        ['remove', 'metro', 'jest-haste-map'],
3648d3f3824SCedric van Putten        expect.objectContaining({ cwd: projectRoot })
3658d3f3824SCedric van Putten      );
3668d3f3824SCedric van Putten    });
3678d3f3824SCedric van Putten  });
3688d3f3824SCedric van Putten
3698d3f3824SCedric van Putten  describe('removeGlobalAsync', () => {
3708d3f3824SCedric van Putten    it('removes a single package', async () => {
3718d3f3824SCedric van Putten      const yarn = new YarnPackageManager({ cwd: projectRoot });
3728d3f3824SCedric van Putten      await yarn.removeGlobalAsync(['expo-cli']);
3738d3f3824SCedric van Putten
3748d3f3824SCedric van Putten      expect(spawnAsync).toBeCalledWith(
3758d3f3824SCedric van Putten        'yarnpkg',
3768d3f3824SCedric van Putten        ['global', 'remove', 'expo-cli'],
3778d3f3824SCedric van Putten        expect.objectContaining({ cwd: projectRoot })
3788d3f3824SCedric van Putten      );
3798d3f3824SCedric van Putten    });
3808d3f3824SCedric van Putten
3818d3f3824SCedric van Putten    it('removes multiple packages', async () => {
3828d3f3824SCedric van Putten      const yarn = new YarnPackageManager({ cwd: projectRoot });
3838d3f3824SCedric van Putten      await yarn.removeGlobalAsync(['expo-cli', 'eas-cli']);
3848d3f3824SCedric van Putten
3858d3f3824SCedric van Putten      expect(spawnAsync).toBeCalledWith(
3868d3f3824SCedric van Putten        'yarnpkg',
3878d3f3824SCedric van Putten        ['global', 'remove', 'expo-cli', 'eas-cli'],
3888d3f3824SCedric van Putten        expect.objectContaining({ cwd: projectRoot })
3898d3f3824SCedric van Putten      );
3908d3f3824SCedric van Putten    });
3918d3f3824SCedric van Putten  });
3928d3f3824SCedric van Putten
3938d3f3824SCedric van Putten  describe('workspaceRoot', () => {
3948d3f3824SCedric van Putten    const workspaceRoot = '/monorepo';
3958d3f3824SCedric van Putten    const projectRoot = '/monorepo/packages/test';
3968d3f3824SCedric van Putten
3978d3f3824SCedric van Putten    it('returns null for non-monorepo project', () => {
3988d3f3824SCedric van Putten      vol.fromJSON(
3998d3f3824SCedric van Putten        {
4008d3f3824SCedric van Putten          'package.json': JSON.stringify({ name: 'project' }),
4018d3f3824SCedric van Putten        },
4028d3f3824SCedric van Putten        projectRoot
4038d3f3824SCedric van Putten      );
4048d3f3824SCedric van Putten
4058d3f3824SCedric van Putten      const yarn = new YarnPackageManager({ cwd: projectRoot });
4068d3f3824SCedric van Putten      expect(yarn.workspaceRoot()).toBeNull();
4078d3f3824SCedric van Putten    });
4088d3f3824SCedric van Putten
4098d3f3824SCedric van Putten    it('returns new instance for monorepo project', () => {
4108d3f3824SCedric van Putten      vol.fromJSON(
4118d3f3824SCedric van Putten        {
4128d3f3824SCedric van Putten          'packages/test/package.json': JSON.stringify({ name: 'project' }),
4138d3f3824SCedric van Putten          'package.json': JSON.stringify({
4148d3f3824SCedric van Putten            name: 'monorepo',
4158d3f3824SCedric van Putten            workspaces: ['packages/*'],
4168d3f3824SCedric van Putten          }),
4178d3f3824SCedric van Putten        },
4188d3f3824SCedric van Putten        workspaceRoot
4198d3f3824SCedric van Putten      );
4208d3f3824SCedric van Putten
4218d3f3824SCedric van Putten      const yarn = new YarnPackageManager({ cwd: projectRoot });
4228d3f3824SCedric van Putten      const root = yarn.workspaceRoot();
4238d3f3824SCedric van Putten      expect(root).toBeInstanceOf(YarnPackageManager);
4248d3f3824SCedric van Putten      expect(root).not.toBe(yarn);
4258d3f3824SCedric van Putten    });
4268d3f3824SCedric van Putten  });
4278d3f3824SCedric van Putten
4288d3f3824SCedric van Putten  // describe('offline support', () => {
4298d3f3824SCedric van Putten  //   // TODO
4308d3f3824SCedric van Putten  // });
4318d3f3824SCedric van Putten});
432