mirror of
https://github.com/renovatebot/renovate.git
synced 2026-11-01 18:19:51 +00:00
05e1271376
Enables the vitest/prefer-expect-resolves oxlint rule and applies its autofix across the spec suite.
1263 lines
38 KiB
TypeScript
1263 lines
38 KiB
TypeScript
import { codeBlock } from 'common-tags';
|
|
import fs from 'fs-extra';
|
|
import { mockDeep } from 'vitest-mock-extended';
|
|
import type { ExecSnapshots } from '~test/exec-util.ts';
|
|
import { envMock, mockExecAll, mockExecSequence } from '~test/exec-util.ts';
|
|
import { Fixtures } from '~test/fixtures.ts';
|
|
import * as util from '~test/util.ts';
|
|
import { GlobalConfig } from '../../../../config/global.ts';
|
|
import * as docker from '../../../../util/exec/docker/index.ts';
|
|
import { getPkgReleases } from '../../../datasource/index.ts';
|
|
import type { PostUpdateConfig } from '../../types.ts';
|
|
import type { NpmManagerData } from '../types.ts';
|
|
import { getNodeToolConstraint } from './node-version.ts';
|
|
import * as yarnHelper from './yarn.ts';
|
|
|
|
vi.mock('fs-extra', async () =>
|
|
(
|
|
await vi.importActual<typeof import('~test/fixtures.ts')>(
|
|
'~test/fixtures.ts',
|
|
)
|
|
).fsExtra(),
|
|
);
|
|
vi.mock('../../../../util/exec/env.ts');
|
|
vi.mock('./node-version.ts');
|
|
vi.mock('../../../datasource/index.ts', () => mockDeep());
|
|
|
|
delete process.env.NPM_CONFIG_CACHE;
|
|
|
|
// TODO: figure out snapshot similarity for each CI platform (#9617)
|
|
function fixSnapshots(snapshots: ExecSnapshots): ExecSnapshots {
|
|
return snapshots.map((snapshot) => ({
|
|
...snapshot,
|
|
cmd: snapshot.cmd.replace(/^.*\/yarn.*?\.js\s+/, '<yarn> '),
|
|
}));
|
|
}
|
|
|
|
const plocktest1PackageJson = Fixtures.get('plocktest1/package.json', '..');
|
|
const plocktest1YarnLockV1 = Fixtures.get('plocktest1/yarn.lock', '..');
|
|
|
|
const yarn1Install =
|
|
'yarn install --ignore-engines --ignore-platform --network-timeout 100000 --ignore-scripts';
|
|
const berryEnv = {
|
|
CI: 'true',
|
|
YARN_ENABLE_GLOBAL_CACHE: '1',
|
|
YARN_ENABLE_IMMUTABLE_INSTALLS: 'false',
|
|
YARN_ENABLE_SCRIPTS: '0',
|
|
YARN_HTTP_TIMEOUT: '100000',
|
|
};
|
|
const berryV3Env = {
|
|
CI: 'true',
|
|
YARN_ENABLE_GLOBAL_CACHE: '1',
|
|
YARN_ENABLE_IMMUTABLE_INSTALLS: 'false',
|
|
YARN_HTTP_TIMEOUT: '100000',
|
|
};
|
|
function expectedExec(
|
|
cmds: string[],
|
|
env: Record<string, string>,
|
|
cwd = 'some-dir',
|
|
): { cmd: string; options: { cwd: string; env: Record<string, string> } }[] {
|
|
return cmds.map((cmd) => ({ cmd, options: { cwd, env } }));
|
|
}
|
|
|
|
describe('modules/manager/npm/post-update/yarn', () => {
|
|
const removeDockerContainer = vi.spyOn(docker, 'removeDockerContainer');
|
|
|
|
beforeEach(() => {
|
|
util.env.getChildProcessEnv.mockReturnValue(envMock.basic);
|
|
vi.stubEnv('BUILDPACK', undefined);
|
|
vi.stubEnv('HTTP_PROXY', undefined);
|
|
vi.stubEnv('HTTPS_PROXY', undefined);
|
|
vi.stubEnv('RENOVATE_X_YARN_PROXY', undefined);
|
|
Fixtures.reset();
|
|
GlobalConfig.set({
|
|
localDir: '.',
|
|
cacheDir: '/tmp/cache',
|
|
binarySource: 'global',
|
|
});
|
|
removeDockerContainer.mockResolvedValue();
|
|
docker.resetPrefetchedImages();
|
|
vi.mocked(getNodeToolConstraint).mockResolvedValueOnce({
|
|
toolName: 'node',
|
|
constraint: '16.16.0',
|
|
});
|
|
});
|
|
|
|
it.each([
|
|
['1.22.0', '^1.10.0', 2],
|
|
['2.1.0', '>= 2.0.0', 1],
|
|
['2.2.0', '2.2.0', 1],
|
|
['3.0.0', '3.0.0', 1],
|
|
])(
|
|
'generates lock files using yarn v%s',
|
|
async (yarnVersion, yarnCompatibility, expectedFsCalls) => {
|
|
Fixtures.mock(
|
|
{
|
|
'.yarnrc': 'yarn-path ./.yarn/cli.js\n',
|
|
'yarn.lock': 'package-lock-contents',
|
|
},
|
|
'/some-dir',
|
|
);
|
|
GlobalConfig.set({
|
|
localDir: '/',
|
|
cacheDir: '/tmp/cache',
|
|
binarySource: 'global',
|
|
});
|
|
const execSnapshots = mockExecAll({
|
|
stdout: yarnVersion,
|
|
stderr: '',
|
|
});
|
|
const config = {
|
|
constraints: {
|
|
yarn: yarnCompatibility,
|
|
},
|
|
postUpdateOptions: ['yarnDedupeFewer', 'yarnDedupeHighest'],
|
|
};
|
|
const res = await yarnHelper.generateLockFile(
|
|
'some-dir',
|
|
{
|
|
YARN_CACHE_FOLDER: '/tmp/renovate/cache/yarn',
|
|
YARN_GLOBAL_FOLDER: '/tmp/renovate/cache/berry',
|
|
},
|
|
config,
|
|
);
|
|
expect(fs.readFile).toHaveBeenCalledTimes(expectedFsCalls);
|
|
expect(fs.remove).toHaveBeenCalledTimes(0);
|
|
expect(res.lockFile).toBe('package-lock-contents');
|
|
const expectedByVersion: Record<
|
|
string,
|
|
{ cmds: string[]; env: Record<string, string> }
|
|
> = {
|
|
'1.22.0': {
|
|
cmds: [
|
|
yarn1Install,
|
|
'npx yarn-deduplicate --strategy fewer',
|
|
yarn1Install,
|
|
'npx yarn-deduplicate --strategy highest',
|
|
yarn1Install,
|
|
],
|
|
env: { CI: 'true', YARN_CACHE_FOLDER: '/tmp/renovate/cache/yarn' },
|
|
},
|
|
'2.1.0': {
|
|
cmds: ['yarn install'],
|
|
env: { ...berryEnv, YARN_GLOBAL_FOLDER: '/tmp/renovate/cache/berry' },
|
|
},
|
|
'2.2.0': {
|
|
cmds: ['yarn install', 'yarn dedupe --strategy highest'],
|
|
env: { ...berryEnv, YARN_GLOBAL_FOLDER: '/tmp/renovate/cache/berry' },
|
|
},
|
|
'3.0.0': {
|
|
cmds: [
|
|
'yarn install --mode=update-lockfile',
|
|
'yarn dedupe --strategy highest --mode=update-lockfile',
|
|
],
|
|
env: {
|
|
...berryV3Env,
|
|
YARN_GLOBAL_FOLDER: '/tmp/renovate/cache/berry',
|
|
},
|
|
},
|
|
};
|
|
const { cmds, env } = expectedByVersion[yarnVersion];
|
|
expect(fixSnapshots(execSnapshots)).toMatchObject(
|
|
expectedExec(cmds, env, '/some-dir'),
|
|
);
|
|
},
|
|
);
|
|
|
|
describe.each([
|
|
['1.22.0', '^1.10.0', 2],
|
|
['2.1.0', '>= 2.0.0', 1],
|
|
['2.2.0', '2.2.0', 1],
|
|
['3.0.0', '3.0.0', 1],
|
|
])(
|
|
'passes NODE_OPTIONS using yarn v%s',
|
|
(yarnVersion, yarnCompatibility, _expectedFsCalls) => {
|
|
it('if nodeMaxMemory set on global config', async () => {
|
|
Fixtures.mock(
|
|
{
|
|
'.yarnrc': 'yarn-path ./.yarn/cli.js\n',
|
|
'yarn.lock': 'package-lock-contents',
|
|
},
|
|
'/some-dir',
|
|
);
|
|
GlobalConfig.set({
|
|
localDir: '/',
|
|
cacheDir: '/tmp/cache',
|
|
toolSettings: {
|
|
nodeMaxMemory: 2345,
|
|
},
|
|
binarySource: 'global',
|
|
});
|
|
const execSnapshots = mockExecAll({
|
|
stdout: yarnVersion,
|
|
stderr: '',
|
|
});
|
|
const config = {
|
|
constraints: {
|
|
yarn: yarnCompatibility,
|
|
},
|
|
postUpdateOptions: ['yarnDedupeFewer', 'yarnDedupeHighest'],
|
|
};
|
|
const res = await yarnHelper.generateLockFile(
|
|
'some-dir',
|
|
{
|
|
YARN_CACHE_FOLDER: '/tmp/renovate/cache/yarn',
|
|
YARN_GLOBAL_FOLDER: '/tmp/renovate/cache/berry',
|
|
},
|
|
config,
|
|
);
|
|
expect(res.error).toBeUndefined();
|
|
|
|
// there may be other command(s), but checking that at least 1 has it is sufficient
|
|
expect(execSnapshots[0].options?.env?.NODE_OPTIONS).toEqual(
|
|
'--max-old-space-size=2345',
|
|
);
|
|
});
|
|
|
|
it('if nodeMaxMemory set on repo config', async () => {
|
|
Fixtures.mock(
|
|
{
|
|
'.yarnrc': 'yarn-path ./.yarn/cli.js\n',
|
|
'yarn.lock': 'package-lock-contents',
|
|
},
|
|
'/some-dir',
|
|
);
|
|
GlobalConfig.set({
|
|
localDir: '/',
|
|
cacheDir: '/tmp/cache',
|
|
binarySource: 'global',
|
|
});
|
|
const execSnapshots = mockExecAll({
|
|
stdout: yarnVersion,
|
|
stderr: '',
|
|
});
|
|
const config = {
|
|
constraints: {
|
|
yarn: yarnCompatibility,
|
|
},
|
|
postUpdateOptions: ['yarnDedupeFewer', 'yarnDedupeHighest'],
|
|
toolSettings: {
|
|
nodeMaxMemory: 2345,
|
|
},
|
|
};
|
|
const res = await yarnHelper.generateLockFile(
|
|
'some-dir',
|
|
{
|
|
YARN_CACHE_FOLDER: '/tmp/renovate/cache/yarn',
|
|
YARN_GLOBAL_FOLDER: '/tmp/renovate/cache/berry',
|
|
},
|
|
config,
|
|
);
|
|
expect(res.error).toBeUndefined();
|
|
|
|
// there may be other command(s), but checking that at least 1 has it is sufficient
|
|
expect(execSnapshots[0].options?.env?.NODE_OPTIONS).toEqual(
|
|
'--max-old-space-size=2345',
|
|
);
|
|
});
|
|
},
|
|
);
|
|
|
|
it('only skips build if skipInstalls is false', async () => {
|
|
Fixtures.mock(
|
|
{
|
|
'yarn.lock': 'package-lock-contents',
|
|
},
|
|
'some-dir',
|
|
);
|
|
const execSnapshots = mockExecAll({
|
|
stdout: '3.0.0',
|
|
stderr: '',
|
|
});
|
|
const config = {
|
|
constraints: {
|
|
yarn: '3.0.0',
|
|
},
|
|
postUpdateOptions: ['yarnDedupeFewer', 'yarnDedupeHighest'],
|
|
skipInstalls: false,
|
|
};
|
|
const res = await yarnHelper.generateLockFile('some-dir', {}, config);
|
|
expect(res.lockFile).toBe('package-lock-contents');
|
|
expect(fixSnapshots(execSnapshots)).toMatchObject(
|
|
expectedExec(
|
|
[
|
|
'yarn install --mode=skip-build',
|
|
'yarn dedupe --strategy highest --mode=skip-build',
|
|
],
|
|
berryV3Env,
|
|
),
|
|
);
|
|
});
|
|
|
|
it('allows and ignore scripts', async () => {
|
|
GlobalConfig.set({
|
|
localDir: '.',
|
|
allowScripts: true,
|
|
cacheDir: '/tmp/cache',
|
|
binarySource: 'global',
|
|
});
|
|
Fixtures.mock(
|
|
{
|
|
'yarn.lock': 'package-lock-contents',
|
|
},
|
|
'some-dir',
|
|
);
|
|
const execSnapshots = mockExecAll({
|
|
stdout: '3.0.0',
|
|
stderr: '',
|
|
});
|
|
const config = {
|
|
constraints: {
|
|
yarn: '3.0.0',
|
|
},
|
|
ignoreScripts: true,
|
|
};
|
|
const res = await yarnHelper.generateLockFile('some-dir', {}, config);
|
|
expect(res.lockFile).toBe('package-lock-contents');
|
|
expect(fixSnapshots(execSnapshots)).toMatchObject(
|
|
expectedExec(['yarn install --mode=update-lockfile'], berryV3Env),
|
|
);
|
|
// scripts must not be explicitly disabled because allowScripts is set
|
|
expect(execSnapshots[0].options?.env?.YARN_ENABLE_SCRIPTS).toBeUndefined();
|
|
});
|
|
|
|
it('sets http proxy', async () => {
|
|
vi.stubEnv('HTTP_PROXY', 'http://proxy');
|
|
vi.stubEnv('HTTPS_PROXY', 'http://proxy');
|
|
vi.stubEnv('RENOVATE_X_YARN_PROXY', 'true');
|
|
GlobalConfig.set({
|
|
localDir: '.',
|
|
allowScripts: true,
|
|
cacheDir: '/tmp/cache',
|
|
binarySource: 'global',
|
|
});
|
|
Fixtures.mock(
|
|
{
|
|
'yarn.lock': 'package-lock-contents',
|
|
},
|
|
'some-dir',
|
|
);
|
|
const execSnapshots = mockExecAll({
|
|
stdout: '3.0.0',
|
|
stderr: '',
|
|
});
|
|
const config = {
|
|
constraints: {
|
|
yarn: '3.0.0',
|
|
},
|
|
};
|
|
const res = await yarnHelper.generateLockFile('some-dir', {}, config);
|
|
expect(res.lockFile).toBe('package-lock-contents');
|
|
expect(fixSnapshots(execSnapshots)).toMatchObject([
|
|
{ cmd: 'yarn config unset --home httpProxy' },
|
|
{ cmd: 'yarn config set --home httpProxy http://proxy' },
|
|
{ cmd: 'yarn config unset --home httpsProxy' },
|
|
{ cmd: 'yarn config set --home httpsProxy http://proxy' },
|
|
{},
|
|
]);
|
|
});
|
|
|
|
it('does not use global cache if zero install is detected', async () => {
|
|
Fixtures.mock(
|
|
{
|
|
'yarn.lock': 'package-lock-contents',
|
|
},
|
|
'some-dir',
|
|
);
|
|
const execSnapshots = mockExecAll({
|
|
stdout: '2.1.0',
|
|
stderr: '',
|
|
});
|
|
const config = {
|
|
constraints: {
|
|
yarn: '>= 2.0.0',
|
|
},
|
|
postUpdateOptions: ['yarnDedupeFewer', 'yarnDedupeHighest'],
|
|
managerData: { yarnZeroInstall: true },
|
|
};
|
|
const res = await yarnHelper.generateLockFile('some-dir', {}, config);
|
|
expect(res.lockFile).toBe('package-lock-contents');
|
|
expect(fixSnapshots(execSnapshots)).toMatchObject(
|
|
expectedExec(['yarn install'], {
|
|
CI: 'true',
|
|
YARN_ENABLE_IMMUTABLE_INSTALLS: 'false',
|
|
YARN_ENABLE_SCRIPTS: '0',
|
|
YARN_HTTP_TIMEOUT: '100000',
|
|
}),
|
|
);
|
|
// the global cache must not be used when zero install is detected
|
|
expect(
|
|
execSnapshots[0].options?.env?.YARN_ENABLE_GLOBAL_CACHE,
|
|
).toBeUndefined();
|
|
});
|
|
|
|
it.each([
|
|
['1.22.0', '^1.10.0'],
|
|
['2.1.0', '>= 2.0.0'],
|
|
['3.0.0', '3.0.0'],
|
|
])(
|
|
'performs lock file updates using yarn v%s',
|
|
async (yarnVersion, yarnCompatibility) => {
|
|
Fixtures.mock(
|
|
{
|
|
'yarn.lock': 'package-lock-contents',
|
|
},
|
|
'some-dir',
|
|
);
|
|
const execSnapshots = mockExecAll({
|
|
stdout: yarnVersion,
|
|
stderr: '',
|
|
});
|
|
const config = {
|
|
constraints: {
|
|
yarn: yarnCompatibility,
|
|
},
|
|
};
|
|
const res = await yarnHelper.generateLockFile('some-dir', {}, config, [
|
|
{
|
|
depName: 'some-dep',
|
|
newValue: '^1.0.0',
|
|
isLockfileUpdate: true,
|
|
},
|
|
{
|
|
depName: 'some-dep',
|
|
newValue: '^1.0.0',
|
|
isLockfileUpdate: true,
|
|
},
|
|
]);
|
|
expect(res.lockFile).toBe('package-lock-contents');
|
|
const expectedByVersion: Record<
|
|
string,
|
|
{ cmds: string[]; env: Record<string, string> }
|
|
> = {
|
|
'1.22.0': {
|
|
cmds: [
|
|
yarn1Install,
|
|
'yarn upgrade some-dep --ignore-engines --ignore-platform --network-timeout 100000 --ignore-scripts',
|
|
],
|
|
env: { CI: 'true' },
|
|
},
|
|
'2.1.0': {
|
|
cmds: ['yarn install', 'yarn up -R some-dep'],
|
|
env: berryEnv,
|
|
},
|
|
'3.0.0': {
|
|
cmds: [
|
|
'yarn install --mode=update-lockfile',
|
|
'yarn up -R some-dep --mode=update-lockfile',
|
|
],
|
|
env: berryV3Env,
|
|
},
|
|
};
|
|
const { cmds, env } = expectedByVersion[yarnVersion];
|
|
expect(fixSnapshots(execSnapshots)).toMatchObject(
|
|
expectedExec(cmds, env),
|
|
);
|
|
},
|
|
);
|
|
|
|
it.each([['1.22.0']])(
|
|
'performs lock file updates and full install using yarn v%s',
|
|
async (yarnVersion) => {
|
|
Fixtures.mock(
|
|
{
|
|
'yarn.lock': 'package-lock-contents',
|
|
},
|
|
'some-dir',
|
|
);
|
|
const execSnapshots = mockExecAll({
|
|
stdout: yarnVersion,
|
|
stderr: '',
|
|
});
|
|
const res = await yarnHelper.generateLockFile('some-dir', {}, {}, [
|
|
{
|
|
depName: 'some-dep',
|
|
isLockfileUpdate: true,
|
|
},
|
|
]);
|
|
expect(res.lockFile).toBe('package-lock-contents');
|
|
expect(fixSnapshots(execSnapshots)).toMatchObject(
|
|
expectedExec(
|
|
[
|
|
yarn1Install,
|
|
'yarn upgrade some-dep --ignore-engines --ignore-platform --network-timeout 100000 --ignore-scripts',
|
|
],
|
|
{ CI: 'true' },
|
|
),
|
|
);
|
|
},
|
|
);
|
|
|
|
it.each([
|
|
['1.22.0', '^1.10.0', 2],
|
|
['2.1.0', '>= 2.0.0', 1],
|
|
['2.2.0', '2.2.0', 1],
|
|
])(
|
|
'performs lock file maintenance using yarn v%s',
|
|
async (yarnVersion, yarnCompatibility, expectedFsCalls) => {
|
|
Fixtures.mock(
|
|
{
|
|
'.yarnrc': null,
|
|
'yarn.lock': 'package-lock-contents',
|
|
},
|
|
'some-dir',
|
|
);
|
|
const execSnapshots = mockExecAll({
|
|
stdout: yarnVersion,
|
|
stderr: '',
|
|
});
|
|
const config = {
|
|
constraints: {
|
|
yarn: yarnCompatibility,
|
|
},
|
|
postUpdateOptions: ['yarnDedupeFewer', 'yarnDedupeHighest'],
|
|
};
|
|
const res = await yarnHelper.generateLockFile('some-dir', {}, config, [
|
|
{ isLockFileMaintenance: true },
|
|
]);
|
|
expect(fs.readFile).toHaveBeenCalledTimes(expectedFsCalls);
|
|
expect(fs.remove).toHaveBeenCalledTimes(0);
|
|
|
|
// expected the lock file not to be deleted.
|
|
expect(res.lockFile).toBe('');
|
|
const expectedByVersion: Record<
|
|
string,
|
|
{ cmds: string[]; env: Record<string, string> }
|
|
> = {
|
|
'1.22.0': {
|
|
cmds: [
|
|
yarn1Install,
|
|
'npx yarn-deduplicate --strategy fewer',
|
|
yarn1Install,
|
|
'npx yarn-deduplicate --strategy highest',
|
|
yarn1Install,
|
|
],
|
|
env: { CI: 'true' },
|
|
},
|
|
'2.1.0': {
|
|
cmds: ['yarn install'],
|
|
env: berryEnv,
|
|
},
|
|
'2.2.0': {
|
|
cmds: ['yarn install', 'yarn dedupe --strategy highest'],
|
|
env: berryEnv,
|
|
},
|
|
};
|
|
const { cmds, env } = expectedByVersion[yarnVersion];
|
|
expect(fixSnapshots(execSnapshots)).toMatchObject(
|
|
expectedExec(cmds, env),
|
|
);
|
|
},
|
|
);
|
|
|
|
it.each([
|
|
['1.22.0', '^1.10.0', 2],
|
|
['2.1.0', '>= 2.0.0', 1],
|
|
['2.2.0', '2.2.0', 1],
|
|
['3.0.0', '3.0.0', 1],
|
|
])(
|
|
'performs lock file maintenance in subdirectory independent workspaces using yarn v%s',
|
|
async (yarnVersion, yarnCompatibility, expectedFsReadCalls) => {
|
|
Fixtures.mock(
|
|
{
|
|
'.yarnrc': null,
|
|
'package.json': JSON.stringify({ name: 'main-workspace' }),
|
|
'yarn.lock': 'main-workspace-lock-contents',
|
|
'sub_workspace/package.json': JSON.stringify({
|
|
name: 'sub-workspace',
|
|
}),
|
|
'sub_workspace/yarn.lock': 'sub-workspace-lock-contents',
|
|
},
|
|
'some-dir',
|
|
);
|
|
const execSnapshots = mockExecAll({
|
|
stdout: yarnVersion,
|
|
stderr: '',
|
|
});
|
|
const config = {
|
|
constraints: {
|
|
yarn: yarnCompatibility,
|
|
},
|
|
postUpdateOptions: ['yarnDedupeFewer', 'yarnDedupeHighest'],
|
|
};
|
|
const res = await yarnHelper.generateLockFile(
|
|
'some-dir/sub_workspace',
|
|
{},
|
|
config,
|
|
[{ isLockFileMaintenance: true }],
|
|
);
|
|
expect(fs.readFile).toHaveBeenCalledTimes(expectedFsReadCalls);
|
|
expect(fs.remove).toHaveBeenCalledTimes(0);
|
|
|
|
// Expect the lock file to be not deleted before `yarn install` is run.
|
|
// The lock file should exist but just be empty. This is necessary for
|
|
// subdirectory isolated workspaces to work with Yarn 2+.
|
|
expect(res.lockFile).toBe('');
|
|
expect(fs.outputFile).toHaveBeenCalledTimes(1);
|
|
expect(vi.mocked(fs.outputFile).mock.calls[0][0]).toEndWith(
|
|
'some-dir/sub_workspace/yarn.lock',
|
|
);
|
|
const expectedByVersion: Record<
|
|
string,
|
|
{ cmds: string[]; env: Record<string, string> }
|
|
> = {
|
|
'1.22.0': {
|
|
cmds: [
|
|
yarn1Install,
|
|
'npx yarn-deduplicate --strategy fewer',
|
|
yarn1Install,
|
|
'npx yarn-deduplicate --strategy highest',
|
|
yarn1Install,
|
|
],
|
|
env: { CI: 'true' },
|
|
},
|
|
'2.1.0': {
|
|
cmds: ['yarn install'],
|
|
env: berryEnv,
|
|
},
|
|
'2.2.0': {
|
|
cmds: ['yarn install', 'yarn dedupe --strategy highest'],
|
|
env: berryEnv,
|
|
},
|
|
'3.0.0': {
|
|
cmds: [
|
|
'yarn install --mode=update-lockfile',
|
|
'yarn dedupe --strategy highest --mode=update-lockfile',
|
|
],
|
|
env: berryV3Env,
|
|
},
|
|
};
|
|
const { cmds, env } = expectedByVersion[yarnVersion];
|
|
expect(fixSnapshots(execSnapshots)).toMatchObject(
|
|
expectedExec(cmds, env, 'some-dir/sub_workspace'),
|
|
);
|
|
},
|
|
);
|
|
|
|
it.each([
|
|
['1.22.0', '^1.10.0'],
|
|
['2.1.0', '>= 2.0.0'],
|
|
])(
|
|
'performs yarn binary update using yarn v%s',
|
|
async (yarnVersion, yarnCompatibility) => {
|
|
Fixtures.mock(
|
|
{
|
|
'yarn.lock': 'package-lock-contents',
|
|
},
|
|
'some-dir',
|
|
);
|
|
const execSnapshots = mockExecAll({
|
|
stdout: yarnVersion,
|
|
stderr: '',
|
|
});
|
|
const config = {
|
|
constraints: {
|
|
yarn: yarnCompatibility,
|
|
},
|
|
};
|
|
const res = await yarnHelper.generateLockFile('some-dir', {}, config, [
|
|
{
|
|
depName: 'yarn',
|
|
depType: 'packageManager',
|
|
newValue: '3.0.1',
|
|
},
|
|
]);
|
|
expect(res.lockFile).toBe('package-lock-contents');
|
|
expect(fixSnapshots(execSnapshots)).toMatchObject(
|
|
expectedExec(
|
|
['yarn set version 3.0.1', 'yarn install --mode=update-lockfile'],
|
|
berryV3Env,
|
|
),
|
|
);
|
|
},
|
|
);
|
|
|
|
it('catches errors', async () => {
|
|
Fixtures.mock({});
|
|
const execSnapshots = mockExecAll(new Error('some-error'));
|
|
const res = await yarnHelper.generateLockFile('some-dir', {});
|
|
expect(fs.readFile).toHaveBeenCalledTimes(3);
|
|
expect(res.error).toBeTrue();
|
|
expect(res.lockFile).toBeUndefined();
|
|
expect(fixSnapshots(execSnapshots)).toMatchObject(
|
|
expectedExec([yarn1Install], { CI: 'true' }),
|
|
);
|
|
});
|
|
|
|
it('supports corepack', async () => {
|
|
vi.stubEnv('CONTAINERBASE', 'true');
|
|
GlobalConfig.set({
|
|
localDir: '.',
|
|
binarySource: 'install',
|
|
cacheDir: '/tmp/cache',
|
|
});
|
|
Fixtures.mock(
|
|
{
|
|
'package.json': '{ "packageManager": "yarn@3.0.0" }',
|
|
'yarn.lock': 'package-lock-contents',
|
|
},
|
|
'some-dir',
|
|
);
|
|
vi.mocked(getPkgReleases).mockResolvedValueOnce({
|
|
releases: [{ version: '0.10.0' }],
|
|
});
|
|
const execSnapshots = mockExecAll({
|
|
stdout: '2.1.0',
|
|
stderr: '',
|
|
});
|
|
const config = util.partial<PostUpdateConfig<NpmManagerData>>({
|
|
managerData: { hasPackageManager: true },
|
|
constraints: {
|
|
yarn: '^3.0.0',
|
|
},
|
|
});
|
|
const res = await yarnHelper.generateLockFile('some-dir', {}, config);
|
|
expect(execSnapshots).toMatchObject([
|
|
{ cmd: 'install-tool node 16.16.0', options: { cwd: 'some-dir' } },
|
|
{ cmd: 'install-tool corepack 0.10.0', options: { cwd: 'some-dir' } },
|
|
{
|
|
cmd: 'yarn install --mode=update-lockfile',
|
|
options: {
|
|
cwd: 'some-dir',
|
|
env: {
|
|
YARN_ENABLE_GLOBAL_CACHE: '1',
|
|
YARN_ENABLE_IMMUTABLE_INSTALLS: 'false',
|
|
YARN_HTTP_TIMEOUT: '100000',
|
|
},
|
|
},
|
|
},
|
|
]);
|
|
expect(res.lockFile).toBe('package-lock-contents');
|
|
});
|
|
|
|
it('supports packageManager url corepack', async () => {
|
|
vi.stubEnv('CONTAINERBASE', 'true');
|
|
GlobalConfig.set({
|
|
localDir: '.',
|
|
binarySource: 'install',
|
|
cacheDir: '/tmp/cache',
|
|
});
|
|
const yarnLockContents = codeBlock`
|
|
__metadata:
|
|
version: 6
|
|
cacheKey: 8
|
|
`;
|
|
Fixtures.mock(
|
|
{
|
|
'package.json':
|
|
'{ "packageManager": "yarn@https://nexus-proxy.repo.local.company.net/nexus/content/groups/npm-all/@yarnpkg/cli-dist/-/cli-dist-3.7.0.tgz#sha224.a06723957ae0292e21f598a453" }',
|
|
'yarn.lock': yarnLockContents,
|
|
},
|
|
'some-dir',
|
|
);
|
|
vi.mocked(getPkgReleases).mockResolvedValueOnce({
|
|
releases: [{ version: '0.10.0' }],
|
|
});
|
|
const execSnapshots = mockExecAll({
|
|
stdout: '2.1.0',
|
|
stderr: '',
|
|
});
|
|
const config = util.partial<PostUpdateConfig<NpmManagerData>>({
|
|
managerData: { hasPackageManager: true },
|
|
});
|
|
const res = await yarnHelper.generateLockFile('some-dir', {}, config);
|
|
expect(execSnapshots).toMatchObject([
|
|
{ cmd: 'install-tool node 16.16.0', options: { cwd: 'some-dir' } },
|
|
{ cmd: 'install-tool corepack 0.10.0', options: { cwd: 'some-dir' } },
|
|
{
|
|
cmd: 'yarn install --mode=update-lockfile',
|
|
options: {
|
|
cwd: 'some-dir',
|
|
env: {
|
|
YARN_ENABLE_GLOBAL_CACHE: '1',
|
|
YARN_ENABLE_IMMUTABLE_INSTALLS: 'false',
|
|
YARN_HTTP_TIMEOUT: '100000',
|
|
},
|
|
},
|
|
},
|
|
]);
|
|
expect(res.lockFile).toBe(yarnLockContents);
|
|
});
|
|
|
|
it('supports corepack on grouping', async () => {
|
|
vi.stubEnv('CONTAINERBASE', 'true');
|
|
GlobalConfig.set({
|
|
localDir: '.',
|
|
binarySource: 'install',
|
|
cacheDir: '/tmp/cache',
|
|
});
|
|
Fixtures.mock(
|
|
{
|
|
'package.json': '{ "packageManager": "yarn@3.0.0" }',
|
|
'yarn.lock': 'package-lock-contents',
|
|
},
|
|
'some-dir',
|
|
);
|
|
vi.mocked(getPkgReleases).mockResolvedValueOnce({
|
|
releases: [{ version: '0.10.0' }],
|
|
});
|
|
const execSnapshots = mockExecAll({
|
|
stdout: '2.1.0',
|
|
stderr: '',
|
|
});
|
|
const config = util.partial<PostUpdateConfig<NpmManagerData>>({
|
|
constraints: {
|
|
yarn: '^3.0.0',
|
|
},
|
|
});
|
|
const res = await yarnHelper.generateLockFile('some-dir', {}, config, [
|
|
{
|
|
managerData: { hasPackageManager: true },
|
|
},
|
|
]);
|
|
expect(execSnapshots).toMatchObject([
|
|
{ cmd: 'install-tool node 16.16.0', options: { cwd: 'some-dir' } },
|
|
{ cmd: 'install-tool corepack 0.10.0', options: { cwd: 'some-dir' } },
|
|
{
|
|
cmd: 'yarn install --mode=update-lockfile',
|
|
options: {
|
|
cwd: 'some-dir',
|
|
env: {
|
|
YARN_ENABLE_GLOBAL_CACHE: '1',
|
|
YARN_ENABLE_IMMUTABLE_INSTALLS: 'false',
|
|
YARN_HTTP_TIMEOUT: '100000',
|
|
},
|
|
},
|
|
},
|
|
]);
|
|
expect(res.lockFile).toBe('package-lock-contents');
|
|
});
|
|
|
|
it('supports customizing corepack version via config constraints', async () => {
|
|
vi.stubEnv('CONTAINERBASE', 'true');
|
|
|
|
GlobalConfig.set({
|
|
localDir: '.',
|
|
binarySource: 'install',
|
|
cacheDir: '/tmp/cache',
|
|
});
|
|
|
|
Fixtures.mock(
|
|
{
|
|
'package.json': '{ "packageManager": "yarn@3.0.0" }',
|
|
'yarn.lock': 'package-lock-contents',
|
|
},
|
|
'some-dir',
|
|
);
|
|
|
|
vi.mocked(getPkgReleases).mockResolvedValueOnce({
|
|
releases: [
|
|
{ version: '0.17.0' },
|
|
{ version: '0.17.1' },
|
|
{ version: '0.18.0' },
|
|
],
|
|
});
|
|
|
|
const execSnapshots = mockExecAll({
|
|
stdout: '2.1.0',
|
|
stderr: '',
|
|
});
|
|
|
|
const config = util.partial<PostUpdateConfig<NpmManagerData>>({
|
|
managerData: { hasPackageManager: true },
|
|
constraints: {
|
|
yarn: '^3.0.0',
|
|
corepack: '^0.17.0',
|
|
},
|
|
});
|
|
|
|
const res = await yarnHelper.generateLockFile('some-dir', {}, config);
|
|
|
|
expect(execSnapshots).toMatchObject([
|
|
{ cmd: 'install-tool node 16.16.0', options: { cwd: 'some-dir' } },
|
|
{ cmd: 'install-tool corepack 0.17.1', options: { cwd: 'some-dir' } },
|
|
{
|
|
cmd: 'yarn install --mode=update-lockfile',
|
|
options: {
|
|
cwd: 'some-dir',
|
|
env: {
|
|
YARN_ENABLE_GLOBAL_CACHE: '1',
|
|
YARN_ENABLE_IMMUTABLE_INSTALLS: 'false',
|
|
YARN_HTTP_TIMEOUT: '100000',
|
|
},
|
|
},
|
|
},
|
|
]);
|
|
|
|
expect(res.lockFile).toBe('package-lock-contents');
|
|
});
|
|
|
|
it('uses slim yarn instead of corepack', async () => {
|
|
// sanity check for later refactorings
|
|
expect(plocktest1YarnLockV1).toBeTruthy();
|
|
vi.stubEnv('CONTAINERBASE', 'true');
|
|
GlobalConfig.set({
|
|
localDir: '.',
|
|
binarySource: 'install',
|
|
cacheDir: '/tmp/cache',
|
|
});
|
|
Fixtures.mock(
|
|
{
|
|
'package.json':
|
|
'{ "packageManager": "yarn@1.22.18", "dependencies": { "chalk": "^2.4.1" } }',
|
|
'yarn.lock': plocktest1YarnLockV1,
|
|
},
|
|
'some-dir',
|
|
);
|
|
vi.mocked(getPkgReleases).mockResolvedValueOnce({
|
|
releases: [{ version: '1.22.18' }, { version: '2.4.3' }],
|
|
});
|
|
const execSnapshots = mockExecAll({
|
|
stdout: '2.1.0',
|
|
stderr: '',
|
|
});
|
|
const config = util.partial<PostUpdateConfig<NpmManagerData>>({
|
|
managerData: { hasPackageManager: true },
|
|
});
|
|
const res = await yarnHelper.generateLockFile('some-dir', {}, config);
|
|
expect(res.lockFile).toBe(plocktest1YarnLockV1);
|
|
expect(execSnapshots).toMatchObject([
|
|
{ cmd: 'install-tool node 16.16.0', options: { cwd: 'some-dir' } },
|
|
{ cmd: 'install-tool yarn-slim 1.22.18', options: { cwd: 'some-dir' } },
|
|
{
|
|
cmd: 'yarn install --ignore-engines --ignore-platform --network-timeout 100000 --ignore-scripts',
|
|
options: { cwd: 'some-dir' },
|
|
},
|
|
]);
|
|
});
|
|
|
|
it('uses devEngine.packageManager(object) instead of corepack', async () => {
|
|
// sanity check for later refactorings
|
|
expect(plocktest1YarnLockV1).toBeTruthy();
|
|
vi.stubEnv('CONTAINERBASE', 'true');
|
|
GlobalConfig.set({
|
|
localDir: '.',
|
|
binarySource: 'install',
|
|
cacheDir: '/tmp/cache',
|
|
});
|
|
Fixtures.mock(
|
|
{
|
|
'package.json':
|
|
'{ "devEngines": {"packageManager": { "name": "yarn", "version": "1.22.19" } }, "packageManager": "yarn@1.22.18", "dependencies": { "chalk": "^2.4.1" } }',
|
|
'yarn.lock': plocktest1YarnLockV1,
|
|
},
|
|
'some-dir',
|
|
);
|
|
vi.mocked(getPkgReleases).mockResolvedValueOnce({
|
|
releases: [{ version: '1.22.19' }, { version: '2.4.3' }],
|
|
});
|
|
const execSnapshots = mockExecAll({
|
|
stdout: '2.1.0',
|
|
stderr: '',
|
|
});
|
|
const config = util.partial<PostUpdateConfig<NpmManagerData>>({
|
|
managerData: { hasPackageManager: true },
|
|
});
|
|
const res = await yarnHelper.generateLockFile('some-dir', {}, config);
|
|
expect(res.lockFile).toBe(plocktest1YarnLockV1);
|
|
expect(execSnapshots).toMatchObject([
|
|
{ cmd: 'install-tool node 16.16.0', options: { cwd: 'some-dir' } },
|
|
{ cmd: 'install-tool yarn-slim 1.22.19', options: { cwd: 'some-dir' } },
|
|
{
|
|
cmd: 'yarn install --ignore-engines --ignore-platform --network-timeout 100000 --ignore-scripts',
|
|
options: { cwd: 'some-dir' },
|
|
},
|
|
]);
|
|
});
|
|
|
|
it('uses devEngine.packageManager(array) instead of corepack', async () => {
|
|
// sanity check for later refactorings
|
|
expect(plocktest1YarnLockV1).toBeTruthy();
|
|
vi.stubEnv('CONTAINERBASE', 'true');
|
|
GlobalConfig.set({
|
|
localDir: '.',
|
|
binarySource: 'install',
|
|
cacheDir: '/tmp/cache',
|
|
});
|
|
Fixtures.mock(
|
|
{
|
|
'package.json':
|
|
'{ "devEngines": {"packageManager": [{ "name": "yarn", "version": "1.22.19" }] }, "packageManager": "yarn@1.22.18", "dependencies": { "chalk": "^2.4.1" } }',
|
|
'yarn.lock': plocktest1YarnLockV1,
|
|
},
|
|
'some-dir',
|
|
);
|
|
vi.mocked(getPkgReleases).mockResolvedValueOnce({
|
|
releases: [{ version: '1.22.19' }, { version: '2.4.3' }],
|
|
});
|
|
const execSnapshots = mockExecAll({
|
|
stdout: '2.1.0',
|
|
stderr: '',
|
|
});
|
|
const config = util.partial<PostUpdateConfig<NpmManagerData>>({
|
|
managerData: { hasPackageManager: true },
|
|
});
|
|
const res = await yarnHelper.generateLockFile('some-dir', {}, config);
|
|
expect(res.lockFile).toBe(plocktest1YarnLockV1);
|
|
expect(execSnapshots).toMatchObject([
|
|
{ cmd: 'install-tool node 16.16.0', options: { cwd: 'some-dir' } },
|
|
{ cmd: 'install-tool yarn-slim 1.22.19', options: { cwd: 'some-dir' } },
|
|
{
|
|
cmd: 'yarn install --ignore-engines --ignore-platform --network-timeout 100000 --ignore-scripts',
|
|
options: { cwd: 'some-dir' },
|
|
},
|
|
]);
|
|
});
|
|
|
|
it('patches local yarn', async () => {
|
|
// sanity check for later refactorings
|
|
expect(plocktest1YarnLockV1).toBeTruthy();
|
|
expect(plocktest1PackageJson).toBeTruthy();
|
|
GlobalConfig.set({
|
|
localDir: '.',
|
|
cacheDir: '/tmp/cache',
|
|
binarySource: 'global',
|
|
});
|
|
Fixtures.mock(
|
|
{
|
|
'package.json': plocktest1PackageJson,
|
|
'.yarn/cli.js': '',
|
|
'yarn.lock': plocktest1YarnLockV1,
|
|
'.yarnrc': 'yarn-path ./.yarn/cli.js\n',
|
|
},
|
|
'some-dir',
|
|
);
|
|
vi.mocked(getPkgReleases).mockResolvedValueOnce({
|
|
releases: [{ version: '1.22.18' }],
|
|
});
|
|
const execSnapshots = mockExecSequence([
|
|
{ stdout: '', stderr: '' },
|
|
{ stdout: '', stderr: '' },
|
|
{ stdout: '', stderr: '' },
|
|
]);
|
|
const config = util.partial<PostUpdateConfig<NpmManagerData>>({});
|
|
const res = await yarnHelper.generateLockFile('some-dir', {}, config);
|
|
expect(res.lockFile).toBe(plocktest1YarnLockV1);
|
|
const options = { cwd: 'some-dir' };
|
|
expect(execSnapshots).toMatchObject([
|
|
{
|
|
cmd: {
|
|
command: [
|
|
'sed',
|
|
'-i',
|
|
`s/ steps,/ steps.slice(0,1),/`,
|
|
'some-dir/.yarn/cli.js',
|
|
],
|
|
ignoreFailure: true,
|
|
},
|
|
options,
|
|
},
|
|
{
|
|
cmd: 'yarn install --ignore-engines --ignore-platform --network-timeout 100000 --ignore-scripts',
|
|
options,
|
|
},
|
|
]);
|
|
});
|
|
|
|
it('patches local yarn (docker)', async () => {
|
|
// sanity check for later refactorings
|
|
expect(plocktest1YarnLockV1).toBeTruthy();
|
|
expect(plocktest1PackageJson).toBeTruthy();
|
|
GlobalConfig.set({
|
|
localDir: '.',
|
|
binarySource: 'docker',
|
|
cacheDir: '/tmp/cache',
|
|
dockerSidecarImage: 'ghcr.io/renovatebot/base-image',
|
|
});
|
|
Fixtures.mock(
|
|
{
|
|
'package.json': plocktest1PackageJson,
|
|
'.yarn/cli.js': '',
|
|
'yarn.lock': plocktest1YarnLockV1,
|
|
'.yarnrc': 'yarn-path ./.yarn/cli.js\n',
|
|
},
|
|
'some-dir',
|
|
);
|
|
vi.mocked(getPkgReleases).mockResolvedValueOnce({
|
|
releases: [{ version: '1.22.18' }],
|
|
});
|
|
const execSnapshots = mockExecAll({ stdout: '', stderr: '' });
|
|
const config = util.partial<PostUpdateConfig<NpmManagerData>>({});
|
|
const res = await yarnHelper.generateLockFile('some-dir', {}, config);
|
|
expect(res.lockFile).toBe(plocktest1YarnLockV1);
|
|
const options = {};
|
|
expect(execSnapshots).toMatchObject([
|
|
{ cmd: 'docker pull ghcr.io/renovatebot/base-image', options },
|
|
{
|
|
cmd:
|
|
`docker run --rm --name=renovate_sidecar --label=renovate_child -v ".":"." -v "/tmp/cache":"/tmp/cache" -e CI -e CONTAINERBASE_CACHE_DIR -w "some-dir" ghcr.io/renovatebot/base-image ` +
|
|
`bash -l -c '` +
|
|
`install-tool node 16.16.0` +
|
|
` && ` +
|
|
`install-tool yarn-slim 1.22.18` +
|
|
` && ` +
|
|
// the preCommand's own single quotes are POSIX-escaped, since the whole
|
|
// command is now the single-quoted argument of `bash -l -c`
|
|
`sed -i '"'"'s/ steps,/ steps.slice(0,1),/'"'"' some-dir/.yarn/cli.js || true` +
|
|
` && ` +
|
|
`yarn install --ignore-engines --ignore-platform --network-timeout 100000 --ignore-scripts` +
|
|
`'`,
|
|
options: { ...options, cwd: 'some-dir' },
|
|
},
|
|
]);
|
|
});
|
|
|
|
describe('checkYarnrc()', () => {
|
|
it('returns offline mirror and yarn path', async () => {
|
|
Fixtures.mock(
|
|
{
|
|
'/tmp/renovate/.yarn/cli.js': '',
|
|
'/tmp/renovate/.yarnrc':
|
|
'yarn-offline-mirror "./packages-cache"\nyarn-path "./.yarn/cli.js"\n',
|
|
},
|
|
'/',
|
|
);
|
|
GlobalConfig.set({
|
|
localDir: '/tmp/renovate',
|
|
cacheDir: '/tmp/cache',
|
|
binarySource: 'global',
|
|
});
|
|
await expect(yarnHelper.checkYarnrc('.')).resolves.toEqual({
|
|
offlineMirror: true,
|
|
yarnPath: '.yarn/cli.js',
|
|
});
|
|
});
|
|
|
|
it('returns yarn path in subdir', async () => {
|
|
Fixtures.mock(
|
|
{
|
|
'.yarn/cli.js': '',
|
|
'.yarnrc': 'yarn-path "./.yarn/cli.js"\n',
|
|
},
|
|
'some-dir',
|
|
);
|
|
await expect(yarnHelper.checkYarnrc('some-dir')).resolves.toEqual({
|
|
offlineMirror: false,
|
|
yarnPath: 'some-dir/.yarn/cli.js',
|
|
});
|
|
});
|
|
|
|
it('returns offline mirror', async () => {
|
|
Fixtures.mock(
|
|
{
|
|
'/tmp/renovate/.yarnrc': 'yarn-offline-mirror "./packages-cache"\n',
|
|
},
|
|
'/',
|
|
);
|
|
GlobalConfig.set({
|
|
localDir: '/tmp/renovate',
|
|
cacheDir: '/tmp/cache',
|
|
binarySource: 'global',
|
|
});
|
|
await expect(yarnHelper.checkYarnrc('.')).resolves.toEqual({
|
|
offlineMirror: true,
|
|
yarnPath: null,
|
|
});
|
|
});
|
|
|
|
it('returns no offline mirror and no absolute yarn path', async () => {
|
|
Fixtures.mock(
|
|
{
|
|
'.yarn/cli.js': '',
|
|
'/tmp/renovate/.yarnrc': 'yarn-path /.yarn/cli.js\n',
|
|
},
|
|
'/',
|
|
);
|
|
GlobalConfig.set({
|
|
localDir: '/tmp',
|
|
cacheDir: '/tmp/cache',
|
|
binarySource: 'global',
|
|
});
|
|
await expect(yarnHelper.checkYarnrc('renovate')).resolves.toEqual({
|
|
offlineMirror: false,
|
|
yarnPath: null,
|
|
});
|
|
});
|
|
|
|
it('returns offline mirror and no yarn path for non-existant yarn-path binary', async () => {
|
|
Fixtures.mock(
|
|
{
|
|
'.yarnrc': 'yarn-path ./.yarn/cli.js\n',
|
|
},
|
|
'/tmp/renovate',
|
|
);
|
|
GlobalConfig.set({
|
|
localDir: '/tmp/renovate',
|
|
cacheDir: '/tmp/cache',
|
|
binarySource: 'global',
|
|
});
|
|
const { offlineMirror, yarnPath } = await yarnHelper.checkYarnrc('.');
|
|
expect(offlineMirror).toBeFalse();
|
|
expect(yarnPath).toBeNull();
|
|
expect(Fixtures.toJSON()['/tmp/renovate/.yarnrc']).toBe('\n');
|
|
});
|
|
|
|
it('removes pure-lockfile and frozen-lockfile from .yarnrc', async () => {
|
|
Fixtures.mock(
|
|
{
|
|
'.yarnrc': `--install.pure-lockfile true\n--install.frozen-lockfile true\n`,
|
|
},
|
|
'/tmp/renovate',
|
|
);
|
|
GlobalConfig.set({
|
|
localDir: '/tmp/renovate',
|
|
cacheDir: '/tmp/cache',
|
|
binarySource: 'global',
|
|
});
|
|
await yarnHelper.checkYarnrc('/tmp/renovate');
|
|
expect(Fixtures.toJSON()['/tmp/renovate/.yarnrc']).toBe('\n\n');
|
|
});
|
|
});
|
|
|
|
describe('fuzzyMatchAdditionalYarnrcYml()', () => {
|
|
it.each`
|
|
additionalRegistry | existingRegistry | expectedRegistry
|
|
${['//my-private-registry']} | ${['//my-private-registry']} | ${['//my-private-registry']}
|
|
${[]} | ${['//my-private-registry']} | ${[]}
|
|
${[]} | ${[]} | ${[]}
|
|
${null} | ${null} | ${[]}
|
|
${['//my-private-registry']} | ${[]} | ${['//my-private-registry']}
|
|
${['//my-private-registry']} | ${['https://my-private-registry']} | ${['https://my-private-registry']}
|
|
${['//my-private-registry']} | ${['http://my-private-registry']} | ${['http://my-private-registry']}
|
|
${['//my-private-registry']} | ${['http://my-private-registry/']} | ${['http://my-private-registry/']}
|
|
${['//my-private-registry']} | ${['https://my-private-registry/']} | ${['https://my-private-registry/']}
|
|
${['//my-private-registry']} | ${['//my-private-registry/']} | ${['//my-private-registry/']}
|
|
${['//my-private-registry/']} | ${['//my-private-registry/']} | ${['//my-private-registry/']}
|
|
${['//my-private-registry/']} | ${['//my-private-registry']} | ${['//my-private-registry']}
|
|
`(
|
|
'should return $expectedRegistry when parsing $additionalRegistry against local $existingRegistry',
|
|
({
|
|
additionalRegistry,
|
|
existingRegistry,
|
|
expectedRegistry,
|
|
}: Record<
|
|
'additionalRegistry' | 'existingRegistry' | 'expectedRegistry',
|
|
string[]
|
|
>) => {
|
|
expect(
|
|
yarnHelper.fuzzyMatchAdditionalYarnrcYml(
|
|
{
|
|
npmRegistries: additionalRegistry?.reduce(
|
|
(acc, cur) => ({
|
|
...acc,
|
|
[cur]: { npmAuthToken: 'xxxxxx' },
|
|
}),
|
|
{},
|
|
),
|
|
},
|
|
{
|
|
npmRegistries: existingRegistry?.reduce(
|
|
(acc, cur) => ({
|
|
...acc,
|
|
[cur]: { npmAuthToken: 'xxxxxx' },
|
|
}),
|
|
{},
|
|
),
|
|
},
|
|
).npmRegistries,
|
|
).toContainAllKeys(expectedRegistry);
|
|
},
|
|
);
|
|
});
|
|
});
|