2020-01-02 15:30:40 +00:00
|
|
|
import { exec as _exec } from 'child_process';
|
2020-03-05 20:57:24 +00:00
|
|
|
import { ExecSnapshots, envMock, mockExecAll } from '../../../../test/execUtil';
|
2020-08-21 13:01:26 +00:00
|
|
|
import { fs, getName, mocked } from '../../../../test/util';
|
2020-05-01 16:03:48 +00:00
|
|
|
import * as _env from '../../../util/exec/env';
|
2020-05-29 06:43:09 +00:00
|
|
|
import * as _yarnHelper from './yarn';
|
2017-02-14 07:08:40 +00:00
|
|
|
|
2020-01-02 15:30:40 +00:00
|
|
|
jest.mock('child_process');
|
2020-03-05 20:57:24 +00:00
|
|
|
jest.mock('../../../util/exec/env');
|
2020-08-21 13:01:26 +00:00
|
|
|
jest.mock('../../../util/fs');
|
2020-06-02 08:46:02 +00:00
|
|
|
jest.mock('./node-version');
|
2017-04-20 10:15:46 +00:00
|
|
|
|
2020-01-02 15:30:40 +00:00
|
|
|
const exec: jest.Mock<typeof _exec> = _exec as any;
|
2020-01-10 14:18:41 +00:00
|
|
|
const env = mocked(_env);
|
2019-12-09 11:42:55 +00:00
|
|
|
const yarnHelper = mocked(_yarnHelper);
|
2017-04-20 10:15:46 +00:00
|
|
|
|
2020-05-29 06:43:09 +00:00
|
|
|
delete process.env.NPM_CONFIG_CACHE;
|
|
|
|
|
2020-01-02 15:30:40 +00:00
|
|
|
// TODO: figure out snapshot similarity for each CI platform
|
|
|
|
const fixSnapshots = (snapshots: ExecSnapshots): ExecSnapshots =>
|
2020-04-12 16:09:36 +00:00
|
|
|
snapshots.map((snapshot) => ({
|
2020-01-02 15:30:40 +00:00
|
|
|
...snapshot,
|
2020-01-16 21:05:50 +00:00
|
|
|
cmd: snapshot.cmd.replace(/^.*\/yarn.*?\.js\s+/, '<yarn> '),
|
2020-01-02 15:30:40 +00:00
|
|
|
}));
|
|
|
|
|
2020-04-13 09:23:47 +00:00
|
|
|
describe(getName(__filename), () => {
|
2019-05-24 13:01:07 +00:00
|
|
|
beforeEach(() => {
|
|
|
|
jest.resetAllMocks();
|
2020-08-21 13:01:26 +00:00
|
|
|
jest.resetModules();
|
2020-01-10 14:18:41 +00:00
|
|
|
env.getChildProcessEnv.mockReturnValue(envMock.basic);
|
2019-05-24 13:01:07 +00:00
|
|
|
});
|
2020-08-21 13:01:26 +00:00
|
|
|
it.each([
|
2020-09-08 11:21:26 +00:00
|
|
|
['1.22.0', '^1.10.0', 2],
|
|
|
|
['2.1.0', '>= 2.0.0', 1],
|
|
|
|
['2.2.0', '2.2.0', 1],
|
2020-08-21 13:01:26 +00:00
|
|
|
])(
|
2020-04-13 09:23:47 +00:00
|
|
|
'generates lock files using yarn v%s',
|
2020-09-08 11:21:26 +00:00
|
|
|
async (yarnVersion, yarnCompatibility, expectedFsCalls) => {
|
2020-04-13 09:23:47 +00:00
|
|
|
const execSnapshots = mockExecAll(exec, {
|
|
|
|
stdout: yarnVersion,
|
|
|
|
stderr: '',
|
|
|
|
});
|
2020-08-21 13:01:26 +00:00
|
|
|
fs.readFile.mockImplementation((filename, encoding) => {
|
|
|
|
if (filename.endsWith('.yarnrc')) {
|
|
|
|
return new Promise<string>((resolve) => resolve(null));
|
|
|
|
}
|
|
|
|
return new Promise<string>((resolve) =>
|
|
|
|
resolve('package-lock-contents')
|
|
|
|
);
|
|
|
|
});
|
2020-04-13 09:23:47 +00:00
|
|
|
const config = {
|
2020-05-29 06:43:09 +00:00
|
|
|
dockerMapDotfiles: true,
|
2020-06-03 05:24:53 +00:00
|
|
|
compatibility: {
|
2020-09-08 11:21:26 +00:00
|
|
|
yarn: yarnCompatibility,
|
2020-06-03 05:24:53 +00:00
|
|
|
},
|
2020-04-13 09:23:47 +00:00
|
|
|
postUpdateOptions: ['yarnDedupeFewer', 'yarnDedupeHighest'],
|
|
|
|
};
|
|
|
|
const res = await yarnHelper.generateLockFile('some-dir', {}, config);
|
2020-08-21 13:01:26 +00:00
|
|
|
expect(fs.readFile).toHaveBeenCalledTimes(expectedFsCalls);
|
2020-06-03 10:28:37 +00:00
|
|
|
expect(fs.remove).toHaveBeenCalledTimes(0);
|
2020-04-13 09:23:47 +00:00
|
|
|
expect(res.lockFile).toEqual('package-lock-contents');
|
|
|
|
expect(fixSnapshots(execSnapshots)).toMatchSnapshot();
|
|
|
|
}
|
|
|
|
);
|
2020-09-09 06:42:40 +00:00
|
|
|
it.each([['1.22.0'], ['2.1.0']])(
|
2020-04-13 09:23:47 +00:00
|
|
|
'performs lock file updates using yarn v%s',
|
|
|
|
async (yarnVersion) => {
|
|
|
|
const execSnapshots = mockExecAll(exec, {
|
|
|
|
stdout: yarnVersion,
|
|
|
|
stderr: '',
|
|
|
|
});
|
2020-09-09 06:42:40 +00:00
|
|
|
fs.readFile.mockImplementation((filename, encoding) => {
|
|
|
|
if (filename.endsWith('.yarnrc')) {
|
|
|
|
return new Promise<string>((resolve) => resolve(null));
|
|
|
|
}
|
|
|
|
return new Promise<string>((resolve) =>
|
|
|
|
resolve('package-lock-contents')
|
|
|
|
);
|
|
|
|
});
|
|
|
|
const config = {
|
|
|
|
compatibility: {
|
|
|
|
yarn: yarnVersion === '1.22.0' ? '^1.10.0' : '>= 2.0.0',
|
|
|
|
},
|
|
|
|
};
|
|
|
|
const res = await yarnHelper.generateLockFile('some-dir', {}, config, [
|
2020-05-30 08:57:07 +00:00
|
|
|
{
|
|
|
|
depName: 'some-dep',
|
2020-09-10 05:00:21 +00:00
|
|
|
newValue: '^1.0.0',
|
2020-05-30 08:57:07 +00:00
|
|
|
isLockfileUpdate: true,
|
|
|
|
},
|
|
|
|
]);
|
|
|
|
expect(res.lockFile).toEqual('package-lock-contents');
|
|
|
|
expect(fixSnapshots(execSnapshots)).toMatchSnapshot();
|
|
|
|
}
|
|
|
|
);
|
|
|
|
it.each([['1.22.0']])(
|
|
|
|
'performs lock file updates and full install using yarn v%s',
|
|
|
|
async (yarnVersion) => {
|
|
|
|
const execSnapshots = mockExecAll(exec, {
|
|
|
|
stdout: yarnVersion,
|
|
|
|
stderr: '',
|
|
|
|
});
|
2020-08-21 13:01:26 +00:00
|
|
|
fs.readFile
|
|
|
|
.mockResolvedValueOnce(
|
|
|
|
'yarn-offline-mirror ./npm-packages-offline-cache'
|
|
|
|
)
|
|
|
|
.mockResolvedValueOnce('package-lock-contents');
|
2020-04-13 09:23:47 +00:00
|
|
|
const res = await yarnHelper.generateLockFile('some-dir', {}, {}, [
|
2020-05-29 06:43:09 +00:00
|
|
|
{
|
|
|
|
depName: 'some-dep',
|
|
|
|
isLockfileUpdate: true,
|
|
|
|
},
|
2020-04-13 09:23:47 +00:00
|
|
|
]);
|
|
|
|
expect(res.lockFile).toEqual('package-lock-contents');
|
|
|
|
expect(fixSnapshots(execSnapshots)).toMatchSnapshot();
|
|
|
|
}
|
|
|
|
);
|
2020-08-21 13:01:26 +00:00
|
|
|
it.each([
|
2020-09-08 11:21:26 +00:00
|
|
|
['1.22.0', '^1.10.0', 2],
|
|
|
|
['2.1.0', '>= 2.0.0', 1],
|
|
|
|
['2.2.0', '2.2.0', 1],
|
2020-08-21 13:01:26 +00:00
|
|
|
])(
|
2020-06-03 10:28:37 +00:00
|
|
|
'performs lock file maintenance using yarn v%s',
|
2020-09-08 11:21:26 +00:00
|
|
|
async (yarnVersion, yarnCompatibility, expectedFsCalls) => {
|
2020-06-03 10:28:37 +00:00
|
|
|
const execSnapshots = mockExecAll(exec, {
|
|
|
|
stdout: yarnVersion,
|
|
|
|
stderr: '',
|
|
|
|
});
|
2020-08-21 13:01:26 +00:00
|
|
|
fs.readFile.mockImplementation((filename, encoding) => {
|
|
|
|
if (filename.endsWith('.yarnrc')) {
|
|
|
|
return new Promise<string>((resolve) => resolve(null));
|
|
|
|
}
|
|
|
|
return new Promise<string>((resolve) =>
|
|
|
|
resolve('package-lock-contents')
|
|
|
|
);
|
|
|
|
});
|
2020-06-03 10:28:37 +00:00
|
|
|
const config = {
|
|
|
|
dockerMapDotfiles: true,
|
|
|
|
compatibility: {
|
2020-09-08 11:21:26 +00:00
|
|
|
yarn: yarnCompatibility,
|
2020-06-03 10:28:37 +00:00
|
|
|
},
|
|
|
|
postUpdateOptions: ['yarnDedupeFewer', 'yarnDedupeHighest'],
|
|
|
|
};
|
|
|
|
const res = await yarnHelper.generateLockFile('some-dir', {}, config, [
|
|
|
|
{ isLockFileMaintenance: true },
|
|
|
|
]);
|
2020-08-21 13:01:26 +00:00
|
|
|
expect(fs.readFile).toHaveBeenCalledTimes(expectedFsCalls);
|
2020-06-03 10:28:37 +00:00
|
|
|
expect(fs.remove).toHaveBeenCalledTimes(1);
|
|
|
|
expect(res.lockFile).toEqual('package-lock-contents');
|
|
|
|
expect(fixSnapshots(execSnapshots)).toMatchSnapshot();
|
|
|
|
}
|
|
|
|
);
|
2017-09-20 20:56:57 +00:00
|
|
|
it('catches errors', async () => {
|
2020-01-02 15:30:40 +00:00
|
|
|
const execSnapshots = mockExecAll(exec, {
|
2020-04-13 09:23:47 +00:00
|
|
|
stdout: '1.9.4',
|
2019-05-24 13:01:07 +00:00
|
|
|
stderr: 'some-error',
|
2017-09-20 20:56:57 +00:00
|
|
|
});
|
2020-08-21 13:01:26 +00:00
|
|
|
fs.readFile.mockResolvedValueOnce(null).mockRejectedValueOnce(() => {
|
2020-05-30 08:57:07 +00:00
|
|
|
throw new Error('not-found');
|
|
|
|
});
|
2020-05-30 17:59:31 +00:00
|
|
|
const res = await yarnHelper.generateLockFile('some-dir', {});
|
2020-08-21 04:43:58 +00:00
|
|
|
expect(fs.readFile).toHaveBeenCalledTimes(2);
|
2017-10-19 12:05:10 +00:00
|
|
|
expect(res.error).toBe(true);
|
|
|
|
expect(res.lockFile).not.toBeDefined();
|
2020-01-02 15:30:40 +00:00
|
|
|
expect(fixSnapshots(execSnapshots)).toMatchSnapshot();
|
2017-04-20 10:15:46 +00:00
|
|
|
});
|
2017-02-14 07:08:40 +00:00
|
|
|
});
|