0
0
Fork 0
mirror of https://github.com/renovatebot/renovate.git synced 2025-03-14 16:23:00 +00:00

test: fix coverage ()

This commit is contained in:
Michael Kriese 2019-05-24 15:01:07 +02:00 committed by Rhys Arkins
parent b53c4c09cb
commit 5f213255d0
55 changed files with 941 additions and 109 deletions

View file

@ -27,7 +27,7 @@ module.exports = {
}, },
overrides: [ overrides: [
{ {
files: ['*.spec.ts'], files: ['*.spec.js', '*.spec.ts'],
rules: { rules: {
'global-require': 0, 'global-require': 0,
'prefer-promise-reject-errors': 0, 'prefer-promise-reject-errors': 0,

View file

@ -39,7 +39,6 @@ function getRegistryRepository(lookupName, registryUrls) {
} }
async function getAuthHeaders(registry, repository) { async function getAuthHeaders(registry, repository) {
// istanbul ignore if
try { try {
const apiCheckUrl = `${registry}/v2/`; const apiCheckUrl = `${registry}/v2/`;
const apiCheckResponse = await got(apiCheckUrl, { throwHttpErrors: false }); const apiCheckResponse = await got(apiCheckUrl, { throwHttpErrors: false });
@ -51,8 +50,10 @@ async function getAuthHeaders(registry, repository) {
); );
const { host } = URL.parse(registry); const { host } = URL.parse(registry);
const opts = hostRules.find({ hostType: 'docker', host }) || {}; const opts = {
opts.json = true; ...hostRules.find({ hostType: 'docker', host }),
json: true,
};
if (opts.username && opts.password) { if (opts.username && opts.password) {
const auth = Buffer.from(`${opts.username}:${opts.password}`).toString( const auth = Buffer.from(`${opts.username}:${opts.password}`).toString(
'base64' 'base64'

View file

@ -38,7 +38,7 @@ async function getArtifacts(
if (!config.gitFs) { if (!config.gitFs) {
await fs.outputFile(localLockFileName, existingLockFileContent); await fs.outputFile(localLockFileName, existingLockFileContent);
} }
let authJson = {}; const authJson = {};
let credentials = hostRules.find({ let credentials = hostRules.find({
hostType: 'github', hostType: 'github',
host: 'api.github.com', host: 'api.github.com',
@ -74,7 +74,6 @@ async function getArtifacts(
// istanbul ignore else // istanbul ignore else
if (hostRule.username && hostRule.password) { if (hostRule.username && hostRule.password) {
logger.debug('Setting packagist auth for host ' + host); logger.debug('Setting packagist auth for host ' + host);
authJson = authJson || {};
authJson['http-basic'] = authJson['http-basic'] || {}; authJson['http-basic'] = authJson['http-basic'] || {};
authJson['http-basic'][host] = { authJson['http-basic'][host] = {
username: hostRule.username, username: hostRule.username,

View file

@ -95,11 +95,11 @@ async function getArtifacts(
{ seconds, type: 'go.sum', stdout, stderr }, { seconds, type: 'go.sum', stdout, stderr },
'Generated lockfile' 'Generated lockfile'
); );
// istanbul ignore if
if ( if (
config.postUpdateOptions && config.postUpdateOptions &&
config.postUpdateOptions.includes('gomodTidy') config.postUpdateOptions.includes('gomodTidy')
) { ) {
// istanbul ignore else
if (config.gitFs) { if (config.gitFs) {
args = 'mod tidy'; args = 'mod tidy';
if (cmd.includes('.insteadOf')) { if (cmd.includes('.insteadOf')) {
@ -124,7 +124,6 @@ async function getArtifacts(
} }
} }
const res = []; const res = [];
// istanbul ignore if
if (config.gitFs) { if (config.gitFs) {
const status = await platform.getRepoStatus(); const status = await platform.getRepoStatus();
if (!status.modified.includes(sumFileName)) { if (!status.modified.includes(sumFileName)) {

View file

@ -54,7 +54,6 @@ function detectMonorepos(packageFiles) {
subPackage.lernaClient = lernaClient; subPackage.lernaClient = lernaClient;
subPackage.yarnLock = subPackage.yarnLock || yarnLock; subPackage.yarnLock = subPackage.yarnLock || yarnLock;
subPackage.npmLock = subPackage.npmLock || npmLock; subPackage.npmLock = subPackage.npmLock || npmLock;
// istanbul ignore if
if (subPackage.yarnLock) { if (subPackage.yarnLock) {
subPackage.hasYarnWorkspaces = !!yarnWorkspacesPackages; subPackage.hasYarnWorkspaces = !!yarnWorkspacesPackages;
} }

View file

@ -106,8 +106,12 @@ async function generateLockFile(cwd, env, config = {}, upgrades = []) {
shell: true, shell: true,
env, env,
}); });
stdout += updateRes.stdout ? updateRes.stdout : ''; stdout += updateRes.stdout
stderr += updateRes.stderr ? updateRes.stderr : ''; ? /* istanbul ignore next */ updateRes.stdout
: '';
stderr += updateRes.stderr
? /* istanbul ignore next */ updateRes.stderr
: '';
} }
if ( if (
config.postUpdateOptions && config.postUpdateOptions &&
@ -120,8 +124,12 @@ async function generateLockFile(cwd, env, config = {}, upgrades = []) {
shell: true, shell: true,
env, env,
}); });
stdout += dedupeRes.stdout ? dedupeRes.stdout : ''; stdout += dedupeRes.stdout
stderr += dedupeRes.stderr ? dedupeRes.stderr : ''; ? /* istanbul ignore next */ dedupeRes.stdout
: '';
stderr += dedupeRes.stderr
? /* istanbul ignore next */ dedupeRes.stderr
: '';
} }
if ( if (
config.postUpdateOptions && config.postUpdateOptions &&
@ -134,8 +142,12 @@ async function generateLockFile(cwd, env, config = {}, upgrades = []) {
shell: true, shell: true,
env, env,
}); });
stdout += dedupeRes.stdout ? dedupeRes.stdout : ''; stdout += dedupeRes.stdout
stderr += dedupeRes.stderr ? dedupeRes.stderr : ''; ? /* istanbul ignore next */ dedupeRes.stdout
: '';
stderr += dedupeRes.stderr
? /* istanbul ignore next */ dedupeRes.stderr
: '';
} }
const duration = process.hrtime(startTime); const duration = process.hrtime(startTime);
const seconds = Math.round(duration[0] + duration[1] / 1e9); const seconds = Math.round(duration[0] + duration[1] / 1e9);

View file

@ -28,7 +28,6 @@ async function getPythonAlias() {
try { try {
const { stdout, stderr } = await exec(`${pythonVersion} --version`); const { stdout, stderr } = await exec(`${pythonVersion} --version`);
const version = parsePythonVersion(stdout || stderr); const version = parsePythonVersion(stdout || stderr);
// istanbul ignore if
if (version[0] >= 3 && version[1] >= 7) { if (version[0] >= 3 && version[1] >= 7) {
pythonAlias = pythonVersion; pythonAlias = pythonVersion;
} }
@ -82,7 +81,6 @@ async function extractSetupFile(content, packageFile, config) {
timeout: 5000, timeout: 5000,
})); }));
} catch (err) { } catch (err) {
// istanbul ignore if
if ( if (
err.message && err.message &&
err.message.includes('No such file or directory') && err.message.includes('No such file or directory') &&
@ -94,7 +92,6 @@ async function extractSetupFile(content, packageFile, config) {
} }
throw err; throw err;
} }
// istanbul ignore if
if (stderr) { if (stderr) {
stderr = stderr.replace(/.*\n\s*import imp/, '').trim(); stderr = stderr.replace(/.*\n\s*import imp/, '').trim();
if (stderr.length) { if (stderr.length) {

View file

@ -171,7 +171,6 @@ async function initRepo({
throw new Error('fork'); throw new Error('fork');
} }
} }
// istanbul ignore if
if (res.body.full_name && res.body.full_name !== repository) { if (res.body.full_name && res.body.full_name !== repository) {
logger.info( logger.info(
{ repository, this_repository: res.body.full_name }, { repository, this_repository: res.body.full_name },
@ -1512,7 +1511,7 @@ async function getVulnerabilityAlerts() {
references { url } references { url }
severity severity
} }
securityVulnerability { securityVulnerability {
package { name ecosystem } package { name ecosystem }
firstPatchedVersion { identifier } firstPatchedVersion { identifier }
vulnerableVersionRange vulnerableVersionRange

View file

@ -144,7 +144,7 @@ class Storage {
async function deleteBranch(branchName) { async function deleteBranch(branchName) {
delete branchFiles[branchName]; delete branchFiles[branchName];
const options = config.forkToken const options = config.forkToken
? { token: config.forkToken } ? /* istanbul ignore next */ { token: config.forkToken }
: undefined; : undefined;
try { try {
await get.delete( await get.delete(

View file

@ -40,9 +40,7 @@ async function processBranch(branchConfig, prHourlyLimitReached, packageFiles) {
logger.info('Branch has been checked in master issue: ' + masterIssueCheck); logger.info('Branch has been checked in master issue: ' + masterIssueCheck);
} }
try { try {
logger.debug( logger.debug(`Branch has ${dependencies.length} upgrade(s)`);
`Branch has ${dependencies ? dependencies.length : 0} upgrade(s)`
);
// Check if branch already existed // Check if branch already existed
const existingPr = branchPr ? undefined : await prAlreadyExisted(config); const existingPr = branchPr ? undefined : await prAlreadyExisted(config);
@ -74,7 +72,6 @@ async function processBranch(branchConfig, prHourlyLimitReached, packageFiles) {
content += content +=
'\n\nIf this PR was closed by mistake or you changed your mind, you can simply rename this PR and you will soon get a fresh replacement PR opened.'; '\n\nIf this PR was closed by mistake or you changed your mind, you can simply rename this PR and you will soon get a fresh replacement PR opened.';
if (!config.suppressNotifications.includes('prIgnoreNotification')) { if (!config.suppressNotifications.includes('prIgnoreNotification')) {
// istanbul ignore if
if (config.dryRun) { if (config.dryRun) {
logger.info( logger.info(
'DRY-RUN: Would ensure closed PR comment in PR #' + 'DRY-RUN: Would ensure closed PR comment in PR #' +
@ -85,7 +82,6 @@ async function processBranch(branchConfig, prHourlyLimitReached, packageFiles) {
} }
} }
if (branchExists) { if (branchExists) {
// istanbul ignore if
if (config.dryRun) { if (config.dryRun) {
logger.info('DRY-RUN: Would delete branch ' + config.branchName); logger.info('DRY-RUN: Would delete branch ' + config.branchName);
} else { } else {
@ -138,7 +134,6 @@ async function processBranch(branchConfig, prHourlyLimitReached, packageFiles) {
branchPr.body && branchPr.body &&
branchPr.body.includes(`- [x] <!-- ${appSlug}-rebase -->`); branchPr.body.includes(`- [x] <!-- ${appSlug}-rebase -->`);
if (prRebaseChecked || titleRebase || labelRebase) { if (prRebaseChecked || titleRebase || labelRebase) {
// istanbul ignore if
if (config.dryRun) { if (config.dryRun) {
logger.info( logger.info(
'DRY-RUN: Would ensure PR edited comment removal in PR #' + 'DRY-RUN: Would ensure PR edited comment removal in PR #' +
@ -151,7 +146,6 @@ async function processBranch(branchConfig, prHourlyLimitReached, packageFiles) {
let content = `:construction_worker: This PR has received other commits, so ${appName} will stop updating it to avoid conflicts or other problems.`; let content = `:construction_worker: This PR has received other commits, so ${appName} will stop updating it to avoid conflicts or other problems.`;
content += ` If you wish to abandon your changes and have ${appName} start over you may click the "rebase" checkbox in the PR body/description.`; content += ` If you wish to abandon your changes and have ${appName} start over you may click the "rebase" checkbox in the PR body/description.`;
if (!config.suppressNotifications.includes('prEditNotification')) { if (!config.suppressNotifications.includes('prEditNotification')) {
// istanbul ignore if
if (config.dryRun) { if (config.dryRun) {
logger.info( logger.info(
'DRY-RUN: ensure comment in PR #' + branchPr.number 'DRY-RUN: ensure comment in PR #' + branchPr.number
@ -196,7 +190,7 @@ async function processBranch(branchConfig, prHourlyLimitReached, packageFiles) {
config.unpublishSafe && config.unpublishSafe &&
config.canBeUnpublished && config.canBeUnpublished &&
(config.prCreation === 'not-pending' || (config.prCreation === 'not-pending' ||
config.prCreation === 'status-success') /* istanbul ignore next */ config.prCreation === 'status-success')
) { ) {
logger.info( logger.info(
'Skipping branch creation due to unpublishSafe + status checks' 'Skipping branch creation due to unpublishSafe + status checks'
@ -263,7 +257,6 @@ async function processBranch(branchConfig, prHourlyLimitReached, packageFiles) {
} }
config.committedFiles = await commitFilesToBranch(config); config.committedFiles = await commitFilesToBranch(config);
// istanbul ignore if
if ( if (
config.updateType === 'lockFileMaintenance' && config.updateType === 'lockFileMaintenance' &&
!config.committedFiles && !config.committedFiles &&
@ -273,7 +266,6 @@ async function processBranch(branchConfig, prHourlyLimitReached, packageFiles) {
logger.info( logger.info(
'Deleting lock file maintenance branch as master lock file no longer needs updating' 'Deleting lock file maintenance branch as master lock file no longer needs updating'
); );
// istanbul ignore if
if (config.dryRun) { if (config.dryRun) {
logger.info('DRY-RUN: Would delete lock file maintenance branch'); logger.info('DRY-RUN: Would delete lock file maintenance branch');
} else { } else {
@ -421,7 +413,6 @@ async function processBranch(branchConfig, prHourlyLimitReached, packageFiles) {
config.suppressNotifications.includes('lockFileErrors') config.suppressNotifications.includes('lockFileErrors')
) )
) { ) {
// istanbul ignore if
if (config.dryRun) { if (config.dryRun) {
logger.info( logger.info(
'DRY-RUN: Would ensure lock file error comment in PR #' + 'DRY-RUN: Would ensure lock file error comment in PR #' +
@ -446,7 +437,6 @@ async function processBranch(branchConfig, prHourlyLimitReached, packageFiles) {
// Check if state needs setting // Check if state needs setting
if (existingState !== state) { if (existingState !== state) {
logger.debug(`Updating status check state to failed`); logger.debug(`Updating status check state to failed`);
// istanbul ignore if
if (config.dryRun) { if (config.dryRun) {
logger.info( logger.info(
'DRY-RUN: Would set branch status in ' + config.branchName 'DRY-RUN: Would set branch status in ' + config.branchName

View file

@ -32,7 +32,6 @@ async function start() {
'No repositories found - did you want to run with flag --autodiscover?' 'No repositories found - did you want to run with flag --autodiscover?'
); );
} }
// istanbul ignore if
if ( if (
config.platform === 'github' && config.platform === 'github' &&
config.endpoint && config.endpoint &&
@ -41,7 +40,6 @@ async function start() {
config.prFooter = config.prFooter =
'Available now for Enterprise: [Renovate Pro](https://renovatebot.com/pro) with real-time webhook handling and priority job queue.'; 'Available now for Enterprise: [Renovate Pro](https://renovatebot.com/pro) with real-time webhook handling and priority job queue.';
} }
// istanbul ignore if
if ( if (
config.platform === 'gitlab' && config.platform === 'gitlab' &&
config.endpoint && config.endpoint &&

View file

@ -11,7 +11,7 @@ module.exports = {
async function getTags(endpoint, versionScheme, repository) { async function getTags(endpoint, versionScheme, repository) {
let url = endpoint let url = endpoint
? endpoint.replace(/\/?$/, '/') ? endpoint.replace(/\/?$/, '/')
: 'https://api.github.com/'; : /* istanbul ignore next: not possible to test, maybe never possible? */ 'https://api.github.com/';
url += `repos/${repository}/tags?per_page=100`; url += `repos/${repository}/tags?per_page=100`;
try { try {
const res = await ghGot(url, { const res = await ghGot(url, {

View file

@ -50,7 +50,8 @@ async function validatePrs(config) {
if (parsed) { if (parsed) {
const toValidate = const toValidate =
file === 'package.json' file === 'package.json'
? parsed.renovate || parsed['renovate-config'] ? /* istanbul ignore next */ parsed.renovate ||
parsed['renovate-config']
: parsed; : parsed;
if (toValidate) { if (toValidate) {
logger.debug({ config: toValidate }, 'Validating config'); logger.debug({ config: toValidate }, 'Validating config');

View file

@ -47,7 +47,6 @@ async function lookupUpdates(config) {
res.warnings.push(result); res.warnings.push(result);
return res; return res;
} }
// istanbul ignore if
if (dependency.deprecationMessage) { if (dependency.deprecationMessage) {
logger.info({ dependency: depName }, 'Found deprecationMessage'); logger.info({ dependency: depName }, 'Found deprecationMessage');
res.deprecationMessage = dependency.deprecationMessage; res.deprecationMessage = dependency.deprecationMessage;
@ -56,7 +55,6 @@ async function lookupUpdates(config) {
dependency.sourceUrl && dependency.sourceUrl.length dependency.sourceUrl && dependency.sourceUrl.length
? dependency.sourceUrl ? dependency.sourceUrl
: null; : null;
// istanbul ignore if
if (dependency.sourceDirectory) { if (dependency.sourceDirectory) {
res.sourceDirectory = dependency.sourceDirectory; res.sourceDirectory = dependency.sourceDirectory;
} }

View file

@ -187,7 +187,6 @@ function generateBranchConfig(branchUpgrades) {
config.hasTypes = true; config.hasTypes = true;
} else { } else {
config.upgrades.sort((a, b) => { config.upgrades.sort((a, b) => {
// istanbul ignore if
if (a.fileReplacePosition && b.fileReplacePosition) { if (a.fileReplacePosition && b.fileReplacePosition) {
// This is because we need to replace from the bottom of the file up // This is because we need to replace from the bottom of the file up
return a.fileReplacePosition > b.fileReplacePosition ? -1 : 1; return a.fileReplacePosition > b.fileReplacePosition ? -1 : 1;

View file

@ -698,10 +698,8 @@ exports[`config/presets resolvePreset throws if valid and invalid 3`] = `undefin
exports[`config/presets resolvePreset works with valid 1`] = ` exports[`config/presets resolvePreset works with valid 1`] = `
Object { Object {
"description": Array [
"Use version pinning (maintain a single version only and not semver ranges)",
],
"foo": 1, "foo": 1,
"ignoreDeps": Array [],
"rangeStrategy": "pin", "rangeStrategy": "pin",
} }
`; `;

View file

@ -90,6 +90,7 @@ describe('config/presets', () => {
}); });
it('works with valid', async () => { it('works with valid', async () => {
config.foo = 1; config.foo = 1;
config.ignoreDeps = [];
config.extends = [':pinVersions']; config.extends = [':pinVersions'];
const res = await presets.resolveConfigPresets(config); const res = await presets.resolveConfigPresets(config);
expect(res).toMatchSnapshot(); expect(res).toMatchSnapshot();

View file

@ -342,6 +342,14 @@ Array [
"timeout": 10000, "timeout": 10000,
}, },
], ],
Array [
"https://api.github.com/user/9287/repos?page=3&per_page=100",
Object {
"headers": Object {},
"json": true,
"timeout": 10000,
},
],
Array [ Array [
"https://registry.company.com/v2/", "https://registry.company.com/v2/",
Object { Object {
@ -349,7 +357,7 @@ Array [
}, },
], ],
Array [ Array [
"https://registry.company.com/v2/node/manifests/1.0.0", "https://registry.company.com/v2/node/manifests/latest",
Object { Object {
"headers": Object { "headers": Object {
"accept": "application/vnd.docker.distribution.manifest.v2+json", "accept": "application/vnd.docker.distribution.manifest.v2+json",

View file

@ -44,10 +44,7 @@ describe('api/docker', () => {
got.mockReturnValueOnce({ got.mockReturnValueOnce({
headers: { 'docker-content-digest': 'some-digest' }, headers: { 'docker-content-digest': 'some-digest' },
}); });
const res = await docker.getDigest( const res = await docker.getDigest({ lookupName: 'some-dep' });
{ lookupName: 'some-dep' },
'some-new-value'
);
expect(res).toBe('some-digest'); expect(res).toBe('some-digest');
}); });
it('falls back to body for digest', async () => { it('falls back to body for digest', async () => {
@ -189,7 +186,14 @@ describe('api/docker', () => {
got.mockReturnValueOnce({ got.mockReturnValueOnce({
headers: {}, headers: {},
}); });
got.mockReturnValueOnce({ headers: {}, body: { tags } }); got.mockReturnValueOnce({
headers: {
link:
'<https://api.github.com/user/9287/repos?page=3&per_page=100>; rel="next", ',
},
body: { tags },
});
got.mockReturnValueOnce({ headers: {}, body: { tags: ['latest'] } });
got.mockReturnValueOnce({ got.mockReturnValueOnce({
headers: {}, headers: {},
}); });

View file

@ -87,8 +87,13 @@ describe('datasource/github', () => {
content: Buffer.from('{"foo":"bar"}').toString('base64'), content: Buffer.from('{"foo":"bar"}').toString('base64'),
}, },
})); }));
const content = await github.getPreset('some/repo', 'custom'); try {
expect(content).toEqual({ foo: 'bar' }); global.appMode = true;
const content = await github.getPreset('some/repo', 'custom');
expect(content).toEqual({ foo: 'bar' });
} finally {
delete global.appMode;
}
}); });
}); });
describe('getPkgReleases', () => { describe('getPkgReleases', () => {

View file

@ -45,6 +45,9 @@ describe('api/npm', () => {
}; };
return global.renovateCache.rmAll(); return global.renovateCache.rmAll();
}); });
afterEach(() => {
delete process.env.RENOVATE_CACHE_NPM_MINUTES;
});
it('should return null for no versions', async () => { it('should return null for no versions', async () => {
const missingVersions = { ...npmResponse }; const missingVersions = { ...npmResponse };
missingVersions.versions = {}; missingVersions.versions = {};
@ -387,6 +390,7 @@ describe('api/npm', () => {
.get('/foobar') .get('/foobar')
.reply(200, npmResponse); .reply(200, npmResponse);
process.env.REGISTRY = 'https://registry.from-env.com'; process.env.REGISTRY = 'https://registry.from-env.com';
process.env.RENOVATE_CACHE_NPM_MINUTES = '15';
global.trustLevel = 'high'; global.trustLevel = 'high';
// eslint-disable-next-line no-template-curly-in-string // eslint-disable-next-line no-template-curly-in-string
const npmrc = 'registry=${REGISTRY}'; const npmrc = 'registry=${REGISTRY}';

View file

@ -39,6 +39,16 @@ describe('manager/docker-compose/update', () => {
const res = updateDependency(railsGemfile, upgrade); const res = updateDependency(railsGemfile, upgrade);
expect(res).toBeNull(); expect(res).toBeNull();
}); });
it('uses single quotes', () => {
const upgrade = {
lineNumber: 0,
depName: 'rack-cache',
newValue: '~> 1.3',
};
const gemFile = `gem 'rack-cache', '~> 1.2'`;
const res = updateDependency(gemFile, upgrade);
expect(res).toEqual(`gem 'rack-cache', '~> 1.3'`);
});
it('returns null if error', () => { it('returns null if error', () => {
const res = updateDependency(null, null); const res = updateDependency(null, null);
expect(res).toBeNull(); expect(res).toBeNull();

View file

@ -14,6 +14,9 @@ describe('.getArtifacts()', () => {
beforeEach(() => { beforeEach(() => {
jest.resetAllMocks(); jest.resetAllMocks();
}); });
afterEach(() => {
delete global.trustLevel;
});
it('returns null if no Cargo.lock found', async () => { it('returns null if no Cargo.lock found', async () => {
const updatedDeps = [ const updatedDeps = [
{ {
@ -79,6 +82,7 @@ describe('.getArtifacts()', () => {
currentValue: '1.2.3', currentValue: '1.2.3',
}, },
]; ];
global.trustLevel = 'high';
expect( expect(
await cargo.getArtifacts('Cargo.toml', updatedDeps, '{}', config) await cargo.getArtifacts('Cargo.toml', updatedDeps, '{}', config)
).not.toBeNull(); ).not.toBeNull();

View file

@ -16,6 +16,9 @@ describe('.getArtifacts()', () => {
beforeEach(() => { beforeEach(() => {
jest.resetAllMocks(); jest.resetAllMocks();
}); });
afterEach(() => {
delete global.trustLevel;
});
it('returns if no composer.lock found', async () => { it('returns if no composer.lock found', async () => {
expect( expect(
await composer.getArtifacts('composer.json', [], '{}', config) await composer.getArtifacts('composer.json', [], '{}', config)
@ -62,6 +65,7 @@ describe('.getArtifacts()', () => {
stderror: '', stderror: '',
}); });
fs.readFile = jest.fn(() => 'New composer.lock'); fs.readFile = jest.fn(() => 'New composer.lock');
global.trustLevel = 'high';
expect( expect(
await composer.getArtifacts('composer.json', [], '{}', config) await composer.getArtifacts('composer.json', [], '{}', config)
).not.toBeNull(); ).not.toBeNull();

View file

@ -27,6 +27,10 @@ const config = {
describe('.getArtifacts()', () => { describe('.getArtifacts()', () => {
beforeEach(() => { beforeEach(() => {
jest.resetAllMocks(); jest.resetAllMocks();
exec.mockResolvedValue({
stdout: '',
stderror: '',
});
}); });
it('returns if no go.sum found', async () => { it('returns if no go.sum found', async () => {
expect(await gomod.getArtifacts('go.mod', [], gomod1, config)).toBeNull(); expect(await gomod.getArtifacts('go.mod', [], gomod1, config)).toBeNull();
@ -82,6 +86,29 @@ describe('.getArtifacts()', () => {
}) })
).not.toBeNull(); ).not.toBeNull();
}); });
it('supports docker mode with credentials, appMode and trustLevel=high', async () => {
hostRules.find.mockReturnValue({
token: 'some-token',
});
platform.getFile.mockResolvedValueOnce('Current go.sum');
platform.getRepoStatus.mockResolvedValue({ modified: '' });
fs.readFile.mockResolvedValueOnce('New go.sum');
try {
global.appMode = true;
global.trustLevel = 'high';
expect(
await gomod.getArtifacts('go.mod', [], gomod1, {
...config,
binarySource: 'docker',
postUpdateOptions: ['gomodTidy'],
gitFs: 'https',
})
).toBeNull();
} finally {
delete global.appMode;
delete global.trustLevel;
}
});
it('catches errors', async () => { it('catches errors', async () => {
platform.getFile.mockReturnValueOnce('Current go.sum'); platform.getFile.mockReturnValueOnce('Current go.sum');
fs.outputFile = jest.fn(() => { fs.outputFile = jest.fn(() => {

View file

@ -186,6 +186,7 @@ describe('manager/gradle', () => {
binarySource: 'docker', binarySource: 'docker',
gitFs: true, gitFs: true,
...config, ...config,
gradle: {},
}; };
await manager.extractAllPackageFiles(configWithDocker, ['build.gradle']); await manager.extractAllPackageFiles(configWithDocker, ['build.gradle']);

View file

@ -119,7 +119,7 @@ Object {
"npmLock": undefined, "npmLock": undefined,
"npmrc": undefined, "npmrc": undefined,
"packageJsonName": undefined, "packageJsonName": undefined,
"packageJsonType": "app", "packageJsonType": "library",
"packageJsonVersion": undefined, "packageJsonVersion": undefined,
"pnpmShrinkwrap": undefined, "pnpmShrinkwrap": undefined,
"skipInstalls": false, "skipInstalls": false,

View file

@ -79,3 +79,39 @@ Array [
}, },
] ]
`; `;
exports[`manager/npm/extract .extractPackageFile() uses yarn workspaces package settings 2`] = `
Array [
Object {
"internalPackages": Array [
"@org/a",
"@org/b",
],
"packageFile": "package.json",
"yarnWorkspacesPackages": "packages/*",
},
Object {
"hasYarnWorkspaces": true,
"internalPackages": Array [
"@org/b",
],
"lernaClient": undefined,
"lernaDir": undefined,
"npmLock": undefined,
"packageFile": "packages/a/package.json",
"packageJsonName": "@org/a",
"yarnLock": true,
},
Object {
"internalPackages": Array [
"@org/a",
],
"lernaClient": undefined,
"lernaDir": undefined,
"npmLock": undefined,
"packageFile": "packages/b/package.json",
"packageJsonName": "@org/b",
"yarnLock": undefined,
},
]
`;

View file

@ -166,6 +166,7 @@ describe('manager/npm/extract', () => {
npm: '^8.0.0', npm: '^8.0.0',
yarn: 'disabled', yarn: 'disabled',
}, },
main: 'index.js',
}; };
const pJsonStr = JSON.stringify(pJson); const pJsonStr = JSON.stringify(pJson);
const res = await npmExtract.extractPackageFile( const res = await npmExtract.extractPackageFile(

View file

@ -48,5 +48,25 @@ describe('manager/npm/extract', () => {
expect(packageFiles[1].lernaDir).toEqual('.'); expect(packageFiles[1].lernaDir).toEqual('.');
expect(packageFiles[1].internalPackages).toEqual(['@org/b']); expect(packageFiles[1].internalPackages).toEqual(['@org/b']);
}); });
it('uses yarn workspaces package settings', async () => {
const packageFiles = [
{
packageFile: 'package.json',
yarnWorkspacesPackages: 'packages/*',
},
{
packageFile: 'packages/a/package.json',
packageJsonName: '@org/a',
yarnLock: true,
},
{
packageFile: 'packages/b/package.json',
packageJsonName: '@org/b',
},
];
await detectMonorepos(packageFiles);
expect(packageFiles).toMatchSnapshot();
expect(packageFiles[1].internalPackages).toEqual(['@org/b']);
});
}); });
}); });

View file

@ -67,32 +67,62 @@ Object {
"currentValue": ">=3.2.1,<4.0", "currentValue": ">=3.2.1,<4.0",
"datasource": "pypi", "datasource": "pypi",
"depName": "statsd", "depName": "statsd",
"lineNumber": 63, "lineNumber": 62,
}, },
Object { Object {
"currentValue": ">=2.10.0,<3.0", "currentValue": ">=2.10.0,<3.0",
"datasource": "pypi", "datasource": "pypi",
"depName": "requests", "depName": "requests",
"lineNumber": 64, "lineNumber": 63,
"skipReason": "ignored", "skipReason": "ignored",
}, },
Object { Object {
"currentValue": ">=5.27.1,<7.0", "currentValue": ">=5.27.1,<7.0",
"datasource": "pypi", "datasource": "pypi",
"depName": "raven", "depName": "raven",
"lineNumber": 65, "lineNumber": 64,
}, },
Object { Object {
"currentValue": ">=0.15.2,<0.17", "currentValue": ">=0.15.2,<0.17",
"datasource": "pypi", "datasource": "pypi",
"depName": "future", "depName": "future",
"lineNumber": 66, "lineNumber": 65,
}, },
Object { Object {
"currentValue": ">=1.0.16,<2.0", "currentValue": ">=1.0.16,<2.0",
"datasource": "pypi", "datasource": "pypi",
"depName": "ipaddress", "depName": "ipaddress",
"lineNumber": 67, "lineNumber": 66,
},
],
}
`;
exports[`lib/manager/pip_setup/extract getPythonAlias finds python 1`] = `
[MockFunction] {
"calls": Array [
Array [
"python --version",
],
Array [
"python3 --version",
],
Array [
"python3.7 --version",
],
],
"results": Array [
Object {
"type": "return",
"value": Promise {},
},
Object {
"type": "return",
"value": Promise {},
},
Object {
"type": "return",
"value": Promise {},
}, },
], ],
} }

View file

@ -60,8 +60,7 @@ setup(
include_package_data=True, include_package_data=True,
install_requires=[ install_requires=[
'gunicorn>=19.7.0,<20.0', 'gunicorn>=19.7.0,<20.0',
'Werkzeug>=0.11.5,<0.15', 'Werkzeug>=0.11.5,<0.15', 'statsd>=3.2.1,<4.0',
'statsd>=3.2.1,<4.0',
'requests>=2.10.0,<3.0', # renovate: ignore 'requests>=2.10.0,<3.0', # renovate: ignore
'raven>=5.27.1,<7.0', # pyup: nothing 'raven>=5.27.1,<7.0', # pyup: nothing
'future>=0.15.2,<0.17', 'future>=0.15.2,<0.17',

View file

@ -22,6 +22,9 @@ async function tmpFile() {
} }
describe('lib/manager/pip_setup/extract', () => { describe('lib/manager/pip_setup/extract', () => {
beforeEach(() => {
jest.resetModules();
});
describe('extractPackageFile()', () => { describe('extractPackageFile()', () => {
it('returns found deps', async () => { it('returns found deps', async () => {
expect( expect(
@ -42,6 +45,19 @@ describe('lib/manager/pip_setup/extract', () => {
) )
).toBeNull(); ).toBeNull();
}); });
it('catches error', async () => {
const fExec = jest.fn(() => {
throw new Error('No such file or directory');
});
jest.doMock('child-process-promise', () => {
return {
exec: fExec,
};
});
const m = require('../../../lib/manager/pip_setup/extract');
await m.extractPackageFile(content, packageFile, config);
expect(fExec).toHaveBeenCalledTimes(4);
});
}); });
describe('parsePythonVersion', () => { describe('parsePythonVersion', () => {
@ -53,13 +69,27 @@ describe('lib/manager/pip_setup/extract', () => {
it('returns the python alias to use', async () => { it('returns the python alias to use', async () => {
expect(pythonVersions.includes(await getPythonAlias())).toBe(true); expect(pythonVersions.includes(await getPythonAlias())).toBe(true);
}); });
it('finds python', async () => {
const fExec = jest.fn(() =>
Promise.resolve({ stderr: 'Python 3.7.15rc1' })
);
jest.doMock('child-process-promise', () => {
return {
exec: fExec,
};
});
const m = require('../../../lib/manager/pip_setup/extract');
expect(pythonVersions.includes(await m.getPythonAlias())).toBe(true);
expect(fExec).toMatchSnapshot();
});
}); });
describe('Test for presence of mock lib', () => { describe('Test for presence of mock lib', () => {
it('should test if python mock lib is installed', async () => { it('should test if python mock lib is installed', async () => {
const cp = jest.requireActual('child-process-promise');
let isMockInstalled = true; let isMockInstalled = true;
// when binarysource === docker // when binarysource === docker
try { try {
await exec(`python -c "import mock"`); await cp.exec(`python -c "import mock"`);
} catch (err) { } catch (err) {
isMockInstalled = false; isMockInstalled = false;
} }

View file

@ -15,13 +15,16 @@ describe('.getArtifacts()', () => {
beforeEach(() => { beforeEach(() => {
jest.resetAllMocks(); jest.resetAllMocks();
}); });
afterEach(() => {
delete global.trustLevel;
});
it('returns if no Pipfile.lock found', async () => { it('returns if no Pipfile.lock found', async () => {
expect(await pipenv.getArtifacts('Pipfile', [], '', config)).toBeNull(); expect(await pipenv.getArtifacts('Pipfile', [], '', config)).toBeNull();
}); });
it('returns null if unchanged', async () => { it('returns null if unchanged', async () => {
platform.getFile.mockReturnValueOnce('Current Pipfile.lock'); platform.getFile.mockReturnValueOnce('Current Pipfile.lock');
exec.mockReturnValueOnce({ exec.mockReturnValueOnce({
stdout: '', stdout: 'Locking',
stderror: '', stderror: '',
}); });
fs.readFile = jest.fn(() => 'Current Pipfile.lock'); fs.readFile = jest.fn(() => 'Current Pipfile.lock');
@ -34,6 +37,7 @@ describe('.getArtifacts()', () => {
stderror: '', stderror: '',
}); });
fs.readFile = jest.fn(() => 'New Pipfile.lock'); fs.readFile = jest.fn(() => 'New Pipfile.lock');
global.trustLevel = 'high';
expect( expect(
await pipenv.getArtifacts('Pipfile', [], '{}', config) await pipenv.getArtifacts('Pipfile', [], '{}', config)
).not.toBeNull(); ).not.toBeNull();

View file

@ -13,6 +13,9 @@ describe('.getArtifacts()', () => {
beforeEach(() => { beforeEach(() => {
jest.resetAllMocks(); jest.resetAllMocks();
}); });
afterEach(() => {
delete global.trustLevel;
});
it('returns null if no poetry.lock found', async () => { it('returns null if no poetry.lock found', async () => {
const updatedDeps = [ const updatedDeps = [
{ {
@ -59,6 +62,7 @@ describe('.getArtifacts()', () => {
currentValue: '1.2.3', currentValue: '1.2.3',
}, },
]; ];
global.trustLevel = 'high';
expect( expect(
await poetry.getArtifacts('pyproject.toml', updatedDeps, '{}', config) await poetry.getArtifacts('pyproject.toml', updatedDeps, '{}', config)
).not.toBeNull(); ).not.toBeNull();

View file

@ -2,6 +2,13 @@
exports[`manager/travis/update updateDependency falls back to 2 spaces 1`] = `"hello: world"`; exports[`manager/travis/update updateDependency falls back to 2 spaces 1`] = `"hello: world"`;
exports[`manager/travis/update updateDependency it uses double quotes 1`] = `
"node_js:
- \\"6\\"
- \\"8\\"
"
`;
exports[`manager/travis/update updateDependency updates values 1`] = ` exports[`manager/travis/update updateDependency updates values 1`] = `
"dist: trusty "dist: trusty
language: node_js language: node_js

View file

@ -25,6 +25,14 @@ describe('manager/travis/update', () => {
const res = nodefile.updateDependency('hello: world', upgrade); const res = nodefile.updateDependency('hello: world', upgrade);
expect(res).toMatchSnapshot(); expect(res).toMatchSnapshot();
}); });
it('it uses double quotes', () => {
const upgrade = {
currentValue: ['6'],
newValue: [6, 8],
};
const res = nodefile.updateDependency('node_js:\n - "6"\n', upgrade);
expect(res).toMatchSnapshot();
});
it('returns null if error', () => { it('returns null if error', () => {
const upgrade = { const upgrade = {
currentValue: [8, 6, 4], currentValue: [8, 6, 4],

View file

@ -191,10 +191,35 @@ Array [
"paginate": true, "paginate": true,
}, },
], ],
Array [
"repos/some/repo/pulls/91",
],
Array [
"repos/some/repo/git/refs/heads/master",
],
] ]
`; `;
exports[`platform/github getBranchPr(branchName) should return the PR object 2`] = `null`; exports[`platform/github getBranchPr(branchName) should return the PR object 2`] = `
Object {
"additions": 1,
"base": Object {
"sha": "1234",
},
"branchName": "somebranch",
"canRebase": true,
"commits": 1,
"deletions": 1,
"displayNumber": "Pull Request #91",
"head": Object {
"ref": "somebranch",
},
"isStale": true,
"number": 91,
"sha": undefined,
"state": "open",
}
`;
exports[`platform/github getCommitMessages() returns commits messages 1`] = ` exports[`platform/github getCommitMessages() returns commits messages 1`] = `
Array [ Array [
@ -453,6 +478,35 @@ Array [
] ]
`; `;
exports[`platform/github getPrList() should return PRs 1`] = `
Array [
Object {
"branchName": "somebranch",
"closed_at": undefined,
"createdAt": undefined,
"number": 91,
"sha": undefined,
"sourceRepo": undefined,
"state": "merged",
"title": undefined,
},
]
`;
exports[`platform/github getPrList() should return PRs 2`] = `
Array [
Array [
"repos/some/repo",
],
Array [
"repos/some/repo/pulls?per_page=100&state=all",
Object {
"paginate": true,
},
],
]
`;
exports[`platform/github getRepos should return an array of repos 1`] = ` exports[`platform/github getRepos should return an array of repos 1`] = `
Array [ Array [
Array [ Array [
@ -607,6 +661,17 @@ Array [
] ]
`; `;
exports[`platform/github setBaseBranch(branchName) sets the default base branch 1`] = `
Array [
Array [
"repos/some/repo",
],
Array [
"repos/some/repo/git/trees/master?recursive=true",
],
]
`;
exports[`platform/github updatePr(prNo, title, body) should update the PR 1`] = ` exports[`platform/github updatePr(prNo, title, body) should update the PR 1`] = `
Array [ Array [
Array [ Array [

View file

@ -111,6 +111,7 @@
"title": "feat(azure): abandon pr after delete branch", "title": "feat(azure): abandon pr after delete branch",
"mergeable": "MERGEABLE", "mergeable": "MERGEABLE",
"mergeStateStatus": "BEHIND", "mergeStateStatus": "BEHIND",
"reviews": { "nodes": [ ] },
"commits": { "commits": {
"nodes": [ "nodes": [
{ {

View file

@ -285,7 +285,23 @@ describe('platform/github', () => {
github.initRepo({ github.initRepo({
repository: 'some/repo', repository: 'some/repo',
}) })
).rejects.toThrow(); ).rejects.toThrow('not-found');
});
it('should throw error if renamed', async () => {
get.mockReturnValueOnce({
body: {
fork: true,
full_name: 'some/other',
owner: {},
},
});
await expect(
github.initRepo({
gitFs: 'https',
includeForks: true,
repository: 'some/repo',
})
).rejects.toThrow('renamed');
}); });
}); });
describe('getRepoForceRebase', () => { describe('getRepoForceRebase', () => {
@ -367,6 +383,28 @@ describe('platform/github', () => {
await github.setBaseBranch('some-branch'); await github.setBaseBranch('some-branch');
expect(get.mock.calls).toMatchSnapshot(); expect(get.mock.calls).toMatchSnapshot();
}); });
it('sets the default base branch', async () => {
await initRepo({
repository: 'some/repo',
defaultBranch: 'some-branch',
});
get.mockImplementationOnce(() => ({
body: {
truncated: true,
tree: [],
},
}));
// getBranchCommit
get.mockImplementationOnce(() => ({
body: {
object: {
sha: '1238',
},
},
}));
await github.setBaseBranch();
expect(get.mock.calls).toMatchSnapshot();
});
}); });
describe('getFileList', () => { describe('getFileList', () => {
beforeEach(async () => { beforeEach(async () => {
@ -420,6 +458,15 @@ describe('platform/github', () => {
const files = await github.getFileList('npm-branch'); const files = await github.getFileList('npm-branch');
expect(files).toMatchSnapshot(); expect(files).toMatchSnapshot();
}); });
it('uses default branch', async () => {
get.mockImplementationOnce(() => ({
body: {
truncated: true,
tree: [],
},
}));
expect(await github.getFileList()).toHaveLength(0);
});
}); });
describe('branchExists(branchName)', () => { describe('branchExists(branchName)', () => {
it('should return true if the branch exists (one result)', async () => { it('should return true if the branch exists (one result)', async () => {
@ -523,6 +570,27 @@ describe('platform/github', () => {
expect(await github.isBranchStale('thebranchname')).toBe(true); expect(await github.isBranchStale('thebranchname')).toBe(true);
}); });
}); });
describe('getPrList()', () => {
beforeEach(async () => {
await initRepo({
repository: 'some/repo',
});
});
it('should return PRs', async () => {
get.mockImplementationOnce(() => ({
body: [
{
number: 91,
head: { ref: 'somebranch', repo: {} },
state: 'closed',
merged_at: '12345',
},
],
}));
expect(await github.getPrList()).toMatchSnapshot();
expect(get.mock.calls).toMatchSnapshot();
});
});
describe('getBranchPr(branchName)', () => { describe('getBranchPr(branchName)', () => {
it('should return null if no PR exists', async () => { it('should return null if no PR exists', async () => {
await initRepo({ await initRepo({
@ -539,7 +607,7 @@ describe('platform/github', () => {
repository: 'some/repo', repository: 'some/repo',
}); });
get.mockImplementationOnce(() => ({ get.mockImplementationOnce(() => ({
body: [{ number: 91, head: {} }], body: [{ number: 91, head: { ref: 'somebranch' }, state: 'open' }],
})); }));
get.mockImplementationOnce(() => ({ get.mockImplementationOnce(() => ({
body: { body: {
@ -550,8 +618,11 @@ describe('platform/github', () => {
base: { base: {
sha: '1234', sha: '1234',
}, },
head: { ref: 'somebranch' },
state: 'open',
}, },
})); }));
get.mockResolvedValue({ body: { object: { sha: '12345' } } });
const pr = await github.getBranchPr('somebranch'); const pr = await github.getBranchPr('somebranch');
expect(get.mock.calls).toMatchSnapshot(); expect(get.mock.calls).toMatchSnapshot();
expect(pr).toMatchSnapshot(); expect(pr).toMatchSnapshot();
@ -1320,6 +1391,7 @@ describe('platform/github', () => {
'some-branch', 'some-branch',
'The Title', 'The Title',
'Hello world', 'Hello world',
null,
true true
); );
expect(pr).toMatchSnapshot(); expect(pr).toMatchSnapshot();

View file

@ -0,0 +1,57 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`applyPackageRules() applies 1`] = `
Object {
"currentValue": "1.0.0",
"depName": "a",
"isBump": true,
"packageRules": Array [
Object {
"matchCurrentVersion": "<= 2.0.0",
"packagePatterns": Array [
"*",
],
},
Object {
"matchCurrentVersion": "<= 2.0.0",
"packageNames": Array [
"b",
],
},
Object {
"excludePackagePatterns": Array [
"*",
],
"packageNames": Array [
"b",
],
},
Object {
"updateTypes": Array [
"bump",
],
},
Object {
"excludePackageNames": Array [
"a",
],
"packageNames": Array [
"b",
],
},
Object {
"matchCurrentVersion": "<= 2.0.0",
},
],
"updateTypes": Array [
"bump",
],
}
`;
exports[`applyPackageRules() empty rules 1`] = `
Object {
"foo": "bar",
"packageRules": null,
}
`;

View file

@ -17,6 +17,38 @@ describe('applyPackageRules()', () => {
}, },
], ],
}; };
it('applies', () => {
const config = {
depName: 'a',
isBump: true,
currentValue: '1.0.0',
packageRules: [
{
packagePatterns: ['*'],
matchCurrentVersion: '<= 2.0.0',
},
{
packageNames: ['b'],
matchCurrentVersion: '<= 2.0.0',
},
{
excludePackagePatterns: ['*'],
packageNames: ['b'],
},
{
updateTypes: ['bump'],
},
{
excludePackageNames: ['a'],
packageNames: ['b'],
},
{
matchCurrentVersion: '<= 2.0.0',
},
],
};
expect(applyPackageRules(config)).toMatchSnapshot();
});
it('applies both rules for a', () => { it('applies both rules for a', () => {
const dep = { const dep = {
depName: 'a', depName: 'a',
@ -487,4 +519,9 @@ describe('applyPackageRules()', () => {
}); });
expect(res3.x).toBeDefined(); expect(res3.x).toBeDefined();
}); });
it('empty rules', () => {
expect(
applyPackageRules({ ...config1, packageRules: null })
).toMatchSnapshot();
});
}); });

View file

@ -95,6 +95,14 @@ describe('semver.getNewValue()', () => {
expect(semver.getNewValue('5.0', 'bump', '5.0.0', '5.1.7')).toEqual('5.1'); expect(semver.getNewValue('5.0', 'bump', '5.0.0', '5.1.7')).toEqual('5.1');
expect(semver.getNewValue('5.0', 'bump', '5.0.0', '6.1.7')).toEqual('6.1'); expect(semver.getNewValue('5.0', 'bump', '5.0.0', '6.1.7')).toEqual('6.1');
}); });
it('bumps greater or equals', () => {
expect(semver.getNewValue('>=1.0.0', 'bump', '1.0.0', '1.1.0')).toEqual(
'>=1.1.0'
);
expect(semver.getNewValue('>= 1.0.0', 'bump', '1.0.0', '1.1.0')).toEqual(
'>= 1.1.0'
);
});
it('replaces equals', () => { it('replaces equals', () => {
expect(semver.getNewValue('=1.0.0', 'replace', '1.0.0', '1.1.0')).toEqual( expect(semver.getNewValue('=1.0.0', 'replace', '1.0.0', '1.1.0')).toEqual(
'=1.1.0' '=1.1.0'

View file

@ -10,6 +10,7 @@ const statusChecks = require('../../../lib/workers/branch/status-checks');
const automerge = require('../../../lib/workers/branch/automerge'); const automerge = require('../../../lib/workers/branch/automerge');
const prWorker = require('../../../lib/workers/pr'); const prWorker = require('../../../lib/workers/pr');
const getUpdated = require('../../../lib/workers/branch/get-updated'); const getUpdated = require('../../../lib/workers/branch/get-updated');
const { appSlug } = require('../../../lib/config/app-strings');
jest.mock('../../../lib/workers/branch/get-updated'); jest.mock('../../../lib/workers/branch/get-updated');
jest.mock('../../../lib/workers/branch/schedule'); jest.mock('../../../lib/workers/branch/schedule');
@ -18,6 +19,7 @@ jest.mock('../../../lib/workers/branch/parent');
jest.mock('../../../lib/manager/npm/post-update'); jest.mock('../../../lib/manager/npm/post-update');
jest.mock('../../../lib/workers/branch/status-checks'); jest.mock('../../../lib/workers/branch/status-checks');
jest.mock('../../../lib/workers/branch/automerge'); jest.mock('../../../lib/workers/branch/automerge');
jest.mock('../../../lib/workers/branch/commit');
jest.mock('../../../lib/workers/pr'); jest.mock('../../../lib/workers/pr');
describe('workers/branch', () => { describe('workers/branch', () => {
@ -33,7 +35,7 @@ describe('workers/branch', () => {
upgrades: [{ depName: 'some-dep-name' }], upgrades: [{ depName: 'some-dep-name' }],
}; };
schedule.isScheduledNow.mockReturnValue(true); schedule.isScheduledNow.mockReturnValue(true);
commit.commitFilesToBranch = jest.fn(() => true); commit.commitFilesToBranch.mockReturnValue(true);
}); });
afterEach(() => { afterEach(() => {
platform.ensureComment.mockClear(); platform.ensureComment.mockClear();
@ -168,6 +170,7 @@ describe('workers/branch', () => {
updatedArtifacts: [], updatedArtifacts: [],
}); });
platform.branchExists.mockReturnValueOnce(false); platform.branchExists.mockReturnValueOnce(false);
commit.commitFilesToBranch.mockReturnValueOnce(false);
expect(await branchWorker.processBranch(config)).toEqual('no-work'); expect(await branchWorker.processBranch(config)).toEqual('no-work');
}); });
it('returns if branch automerged', async () => { it('returns if branch automerged', async () => {
@ -325,5 +328,112 @@ describe('workers/branch', () => {
}); });
await branchWorker.processBranch(config); await branchWorker.processBranch(config);
}); });
it('closed pr (dry run)', async () => {
platform.branchExists.mockReturnValueOnce(true);
checkExisting.prAlreadyExisted.mockResolvedValueOnce({ state: 'closed' });
expect(
await branchWorker.processBranch({ ...config, dryRun: true })
).toEqual('already-existed');
});
it('branch pr no rebase (dry run)', async () => {
platform.branchExists.mockReturnValueOnce(true);
platform.getBranchPr.mockResolvedValueOnce({
state: 'open',
canRebase: false,
});
expect(
await branchWorker.processBranch({ ...config, dryRun: true })
).toEqual('pr-edited');
});
it('branch pr no schedule lockfile (dry run)', async () => {
getUpdated.getUpdatedPackageFiles.mockReturnValueOnce({
updatedPackageFiles: [{}],
artifactErrors: [{}],
});
npmPostExtract.getAdditionalFiles.mockReturnValueOnce({
artifactErrors: [],
updatedArtifacts: [{}],
});
platform.branchExists.mockReturnValueOnce(true);
platform.getBranchPr.mockResolvedValueOnce({
title: 'rebase!',
state: 'open',
body: `- [x] <!-- ${appSlug}-rebase -->`,
canRebase: false,
});
schedule.isScheduledNow.mockReturnValueOnce(false);
commit.commitFilesToBranch.mockReturnValueOnce(false);
expect(
await branchWorker.processBranch({
...config,
dryRun: true,
updateType: 'lockFileMaintenance',
parentBranch: undefined,
updatedArtifacts: [{ name: '|delete|', contents: 'dummy' }],
})
).toEqual('done');
});
it('branch pr no schedule (dry run)', async () => {
getUpdated.getUpdatedPackageFiles.mockReturnValueOnce({
updatedPackageFiles: [{}],
artifactErrors: [{}],
});
npmPostExtract.getAdditionalFiles.mockReturnValueOnce({
artifactErrors: [],
updatedArtifacts: [{}],
});
platform.branchExists.mockReturnValueOnce(true);
platform.getBranchPr.mockResolvedValueOnce({
title: 'rebase!',
state: 'open',
body: `- [x] <!-- ${appSlug}-rebase -->`,
canRebase: false,
});
schedule.isScheduledNow.mockReturnValueOnce(false);
prWorker.ensurePr.mockResolvedValueOnce({});
expect(
await branchWorker.processBranch({
...config,
dryRun: true,
artifactErrors: [{}],
})
).toEqual('done');
});
it('branch pr no schedule', async () => {
getUpdated.getUpdatedPackageFiles.mockReturnValueOnce({
updatedPackageFiles: [{}],
artifactErrors: [],
});
npmPostExtract.getAdditionalFiles.mockReturnValueOnce({
artifactErrors: [],
updatedArtifacts: [{}],
});
platform.branchExists.mockReturnValueOnce(true);
platform.getBranchPr.mockResolvedValueOnce({
title: 'rebase!',
state: 'open',
body: `- [x] <!-- ${appSlug}-rebase -->`,
canRebase: false,
});
schedule.isScheduledNow.mockReturnValueOnce(false);
commit.commitFilesToBranch.mockReturnValueOnce(false);
expect(
await branchWorker.processBranch({
...config,
updateType: 'lockFileMaintenance',
parentBranch: undefined,
updatedArtifacts: [{ name: '|delete|', contents: 'dummy' }],
})
).toEqual('done');
});
}); });
}); });

View file

@ -11,20 +11,16 @@ const { exec } = require('child-process-promise');
const yarnHelper = require('../../../../lib/manager/npm/post-update/yarn'); const yarnHelper = require('../../../../lib/manager/npm/post-update/yarn');
describe('generateLockFile', () => { describe('generateLockFile', () => {
beforeEach(() => {
delete process.env.YARN_MUTEX_FILE;
jest.resetAllMocks();
exec.mockResolvedValue({
stdout: '',
stderr: '',
});
});
it('generates lock files', async () => { it('generates lock files', async () => {
getInstalledPath.mockReturnValueOnce('node_modules/yarn'); getInstalledPath.mockReturnValueOnce('node_modules/yarn');
exec.mockReturnValueOnce({
stdout: '',
stderror: '',
});
exec.mockReturnValueOnce({
stdout: '',
stderror: '',
});
exec.mockReturnValueOnce({
stdout: '',
stderror: '',
});
fs.readFile = jest.fn(() => 'package-lock-contents'); fs.readFile = jest.fn(() => 'package-lock-contents');
const env = {}; const env = {};
const config = { const config = {
@ -36,15 +32,9 @@ describe('generateLockFile', () => {
}); });
it('performs lock file updates', async () => { it('performs lock file updates', async () => {
getInstalledPath.mockReturnValueOnce('node_modules/yarn'); getInstalledPath.mockReturnValueOnce('node_modules/yarn');
exec.mockReturnValueOnce({
stdout: '',
stderror: '',
});
exec.mockReturnValueOnce({
stdout: '',
stderror: '',
});
fs.readFile = jest.fn(() => 'package-lock-contents'); fs.readFile = jest.fn(() => 'package-lock-contents');
process.env.YARN_MUTEX_FILE = '/tmp/yarn.mutext';
const res = await yarnHelper.generateLockFile('some-dir', {}, {}, [ const res = await yarnHelper.generateLockFile('some-dir', {}, {}, [
{ depName: 'some-dep', isLockfileUpdate: true }, { depName: 'some-dep', isLockfileUpdate: true },
]); ]);
@ -52,14 +42,6 @@ describe('generateLockFile', () => {
}); });
it('detects yarnIntegrity', async () => { it('detects yarnIntegrity', async () => {
getInstalledPath.mockReturnValueOnce('node_modules/yarn'); getInstalledPath.mockReturnValueOnce('node_modules/yarn');
exec.mockReturnValueOnce({
stdout: '',
stderror: '',
});
exec.mockReturnValueOnce({
stdout: '',
stderror: '',
});
fs.readFile = jest.fn(() => 'package-lock-contents'); fs.readFile = jest.fn(() => 'package-lock-contents');
const config = { const config = {
upgrades: [{ yarnIntegrity: true }], upgrades: [{ yarnIntegrity: true }],
@ -73,7 +55,7 @@ describe('generateLockFile', () => {
getInstalledPath.mockReturnValueOnce('node_modules/yarn'); getInstalledPath.mockReturnValueOnce('node_modules/yarn');
exec.mockReturnValueOnce({ exec.mockReturnValueOnce({
stdout: '', stdout: '',
stderror: 'some-error', stderr: 'some-error',
}); });
fs.readFile = jest.fn(() => { fs.readFile = jest.fn(() => {
throw new Error('not found'); throw new Error('not found');
@ -91,10 +73,6 @@ describe('generateLockFile', () => {
getInstalledPath.mockImplementationOnce( getInstalledPath.mockImplementationOnce(
() => '/node_modules/renovate/node_modules/yarn' () => '/node_modules/renovate/node_modules/yarn'
); );
exec.mockReturnValueOnce({
stdout: '',
stderror: '',
});
fs.readFile = jest.fn(() => 'package-lock-contents'); fs.readFile = jest.fn(() => 'package-lock-contents');
const res = await yarnHelper.generateLockFile('some-dir'); const res = await yarnHelper.generateLockFile('some-dir');
expect(fs.readFile).toHaveBeenCalledTimes(1); expect(fs.readFile).toHaveBeenCalledTimes(1);
@ -109,10 +87,6 @@ describe('generateLockFile', () => {
throw new Error('not found'); throw new Error('not found');
}); });
getInstalledPath.mockImplementationOnce(() => '/node_modules/yarn'); getInstalledPath.mockImplementationOnce(() => '/node_modules/yarn');
exec.mockReturnValueOnce({
stdout: '',
stderror: '',
});
fs.readFile = jest.fn(() => 'package-lock-contents'); fs.readFile = jest.fn(() => 'package-lock-contents');
const res = await yarnHelper.generateLockFile('some-dir'); const res = await yarnHelper.generateLockFile('some-dir');
expect(fs.readFile).toHaveBeenCalledTimes(1); expect(fs.readFile).toHaveBeenCalledTimes(1);
@ -129,10 +103,6 @@ describe('generateLockFile', () => {
getInstalledPath.mockImplementationOnce(() => { getInstalledPath.mockImplementationOnce(() => {
throw new Error('not found'); throw new Error('not found');
}); });
exec.mockReturnValueOnce({
stdout: '',
stderror: '',
});
fs.readFile = jest.fn(() => 'package-lock-contents'); fs.readFile = jest.fn(() => 'package-lock-contents');
const res = await yarnHelper.generateLockFile('some-dir', undefined, { const res = await yarnHelper.generateLockFile('some-dir', undefined, {
binarySource: 'global', binarySource: 'global',

View file

@ -47,4 +47,27 @@ describe('lib/workers/global', () => {
expect(configParser.parseConfigs).toHaveBeenCalledTimes(1); expect(configParser.parseConfigs).toHaveBeenCalledTimes(1);
expect(repositoryWorker.renovateRepository).toHaveBeenCalledTimes(2); expect(repositoryWorker.renovateRepository).toHaveBeenCalledTimes(2);
}); });
describe('processes platforms', () => {
it('github', async () => {
configParser.parseConfigs.mockReturnValueOnce({
repositories: ['a'],
platform: 'github',
endpoint: 'https://github.com/',
});
await globalWorker.start();
expect(configParser.parseConfigs).toHaveBeenCalledTimes(1);
expect(repositoryWorker.renovateRepository).toHaveBeenCalledTimes(1);
});
it('gitlab', async () => {
configParser.parseConfigs.mockReturnValueOnce({
repositories: [{ repository: 'a' }],
platform: 'gitlab',
endpoint: 'https://my.gitlab.com/',
});
await globalWorker.start();
expect(configParser.parseConfigs).toHaveBeenCalledTimes(1);
expect(repositoryWorker.renovateRepository).toHaveBeenCalledTimes(1);
});
});
}); });

View file

@ -18,6 +18,7 @@ With your current configuration, Renovate will create 2 Pull Requests:
<summary>Pin dependencies</summary> <summary>Pin dependencies</summary>
- Branch name: \`renovate/pin-dependencies\` - Branch name: \`renovate/pin-dependencies\`
- Merge into: \`some-other\`
- Pin [a](https://a) to \`1.1.0\` - Pin [a](https://a) to \`1.1.0\`
- Pin b to \`1.5.3\` - Pin b to \`1.5.3\`
@ -28,7 +29,7 @@ With your current configuration, Renovate will create 2 Pull Requests:
<summary>Update a to v2</summary> <summary>Update a to v2</summary>
- Branch name: \`renovate/a-2.x\` - Branch name: \`renovate/a-2.x\`
- Upgrade [a](https://a) to \`2.0.1\` - Upgrade [a](https://a) to \`undefined\`
</details> </details>

View file

@ -63,5 +63,10 @@ describe('workers/repository/onboarding/pr', () => {
expect(platform.createPr).toHaveBeenCalledTimes(0); expect(platform.createPr).toHaveBeenCalledTimes(0);
expect(platform.updatePr).toHaveBeenCalledTimes(1); expect(platform.updatePr).toHaveBeenCalledTimes(1);
}); });
it('creates PR (no require config)', async () => {
config.requireConfig = false;
await ensureOnboardingPr(config, packageFiles, branches);
expect(platform.createPr).toHaveBeenCalledTimes(1);
});
}); });
}); });

View file

@ -38,6 +38,7 @@ describe('workers/repository/onboarding/pr/pr-list', () => {
const branches = [ const branches = [
{ {
prTitle: 'Pin dependencies', prTitle: 'Pin dependencies',
baseBranch: 'some-other',
branchName: 'renovate/pin-dependencies', branchName: 'renovate/pin-dependencies',
upgrades: [ upgrades: [
{ {
@ -64,6 +65,7 @@ describe('workers/repository/onboarding/pr/pr-list', () => {
currentValue: '^1.0.0', currentValue: '^1.0.0',
depType: 'devDependencies', depType: 'devDependencies',
newValue: '2.0.1', newValue: '2.0.1',
isLockfileUpdate: true,
}, },
], ],
}, },

View file

@ -267,6 +267,49 @@ Array [
] ]
`; `;
exports[`workers/repository/process/lookup .lookupUpdates() is deprecated 1`] = `
Object {
"changelogUrl": undefined,
"homepage": undefined,
"releases": Array [
Object {
"canBeUnpublished": false,
"gitRef": "b26cace16f6070e756b6a546cf2693bece03f8f8",
"releaseTimestamp": "2015-04-26T16:42:11.311Z",
"version": "1.3.0",
},
Object {
"canBeUnpublished": false,
"gitRef": "05e20dc704421ca820553721c7178168a8461506",
"releaseTimestamp": "2015-05-09T16:52:40.699Z",
"version": "1.4.0",
},
Object {
"canBeUnpublished": false,
"gitRef": "d373079d3620152e3d60e82f27265a09ee0e81bd",
"releaseTimestamp": "2015-05-17T04:25:07.299Z",
"version": "1.4.1",
},
],
"sourceDirectory": "test",
"sourceUrl": null,
"updates": Array [
Object {
"canBeUnpublished": false,
"fromVersion": "1.3.0",
"isSingleVersion": true,
"newMajor": 1,
"newMinor": 4,
"newValue": "1.4.1",
"releaseTimestamp": "2015-05-17T04:25:07.299Z",
"toVersion": "1.4.1",
"updateType": "minor",
},
],
"warnings": Array [],
}
`;
exports[`workers/repository/process/lookup .lookupUpdates() pins minor ranged versions 1`] = ` exports[`workers/repository/process/lookup .lookupUpdates() pins minor ranged versions 1`] = `
Array [ Array [
Object { Object {

View file

@ -8,6 +8,7 @@ const nextJson = require('../../../../config/npm/_fixtures/next.json');
const vueJson = require('../../../../config/npm/_fixtures/vue.json'); const vueJson = require('../../../../config/npm/_fixtures/vue.json');
const typescriptJson = require('../../../../config/npm/_fixtures/typescript.json'); const typescriptJson = require('../../../../config/npm/_fixtures/typescript.json');
const docker = require('../../../../../lib/datasource/docker'); const docker = require('../../../../../lib/datasource/docker');
const defaults = require('../../../../../lib/config/defaults');
jest.mock('../../../../../lib/datasource/docker'); jest.mock('../../../../../lib/datasource/docker');
@ -17,7 +18,7 @@ let config;
describe('workers/repository/process/lookup', () => { describe('workers/repository/process/lookup', () => {
beforeEach(() => { beforeEach(() => {
config = { ...require('../../../../../lib/config/defaults').getConfig() }; config = { ...defaults.getConfig() };
config.manager = 'npm'; config.manager = 'npm';
config.versionScheme = 'npm'; config.versionScheme = 'npm';
config.rangeStrategy = 'replace'; config.rangeStrategy = 'replace';
@ -1032,6 +1033,25 @@ describe('workers/repository/process/lookup', () => {
expect(res.releases).toHaveLength(2); expect(res.releases).toHaveLength(2);
expect(res.updates[0].toVersion).toEqual('1.4.0'); expect(res.updates[0].toVersion).toEqual('1.4.0');
}); });
it('is deprecated', async () => {
config.currentValue = '1.3.0';
config.depName = 'q3';
config.datasource = 'npm';
const returnJson = {
...JSON.parse(JSON.stringify(qJson)),
name: 'q3',
deprecated: true,
repository: { url: null, directory: 'test' },
};
nock('https://registry.npmjs.org')
.get('/q3')
.reply(200, returnJson);
const res = await lookup.lookupUpdates(config);
expect(res).toMatchSnapshot();
expect(res.releases).toHaveLength(3);
expect(res.updates[0].toVersion).toEqual('1.4.1');
});
it('skips unsupported values', async () => { it('skips unsupported values', async () => {
config.currentValue = 'alpine'; config.currentValue = 'alpine';
config.depName = 'node'; config.depName = 'node';

View file

@ -224,6 +224,116 @@ Array [
"warnings": Array [], "warnings": Array [],
"yarnrc": null, "yarnrc": null,
}, },
Object {
"assignees": Array [],
"automerge": false,
"automergeComment": "automergeComment",
"automergeType": "pr",
"azureAutoComplete": false,
"azureWorkItemId": 0,
"baseDir": null,
"bbUseDefaultReviewers": true,
"binarySource": "bundled",
"branchName": "{{{branchPrefix}}}{{{managerBranchPrefix}}}{{{branchTopic}}}",
"branchPrefix": "renovate/",
"branchTopic": "{{{depNameSanitized}}}-{{{newMajor}}}{{#if isPatch}}.{{{newMinor}}}{{/if}}.x{{#if isLockfileUpdate}}-lockfile{{/if}}",
"bumpVersion": null,
"cacheDir": null,
"commitBody": null,
"commitMessage": "{{{commitMessagePrefix}}} {{{commitMessageAction}}} {{{commitMessageTopic}}} {{{commitMessageExtra}}} {{{commitMessageSuffix}}}",
"commitMessageAction": "Update",
"commitMessageExtra": "to {{#if isMajor}}v{{{newMajor}}}{{else}}{{#if isSingleVersion}}v{{{toVersion}}}{{else}}{{{newValue}}}{{/if}}{{/if}}",
"commitMessagePrefix": null,
"commitMessageSuffix": null,
"commitMessageTopic": "dependency {{depName}}",
"compatibility": Object {},
"depNameSanitized": undefined,
"dryRun": false,
"errors": Array [],
"excludeCommitPaths": Array [],
"gitAuthor": null,
"gitFs": null,
"gitPrivateKey": null,
"group": Object {
"branchTopic": "{{{groupSlug}}}",
"commitMessageTopic": "{{{groupName}}}",
},
"groupName": null,
"groupSlug": null,
"ignoreNpmrcFile": false,
"labels": Array [],
"language": "js",
"lazyGrouping": true,
"manager": "npm",
"managerBranchPrefix": "",
"masterIssue": false,
"masterIssueApproval": false,
"masterIssueAutoclose": false,
"masterIssueTitle": "Update Dependencies (Renovate Bot)",
"newValue": "2.0.0",
"npmToken": null,
"npmrc": null,
"packageFile": "package.json",
"persistRepoData": false,
"platform": "github",
"postUpdateOptions": Array [],
"prBodyColumns": Array [
"Package",
"Type",
"Update",
"Change",
"References",
],
"prBodyDefinitions": Object {
"Change": "[{{#if displayFrom}}\`{{{displayFrom}}}\` -> {{else}}{{#if currentValue}}\`{{{currentValue}}}\` -> {{/if}}{{/if}}{{#if displayTo}}\`{{{displayTo}}}\`{{else}}\`{{{newValue}}}\`{{/if}}](https://diff.intrinsic.com/{{{depName}}}/{{{fromVersion}}}/{{{toVersion}}})",
"Current value": "{{{currentValue}}}",
"New value": "{{{newValue}}}",
"Package": "{{{depName}}}",
"Package file": "{{{packageFile}}}",
"References": "{{{references}}}",
"Type": "{{{depType}}}",
"Update": "{{{updateType}}}",
},
"prBodyNotes": Array [],
"prConcurrentLimit": 0,
"prCreation": "immediate",
"prHourlyLimit": 0,
"prNotPendingHours": 25,
"prTitle": null,
"printConfig": false,
"rangeStrategy": "replace",
"rebaseLabel": "rebase",
"rebaseStalePrs": null,
"recreateClosed": false,
"registryUrls": null,
"requiredStatusChecks": Array [],
"reviewers": Array [],
"rollbackPrs": true,
"schedule": "at any time",
"semanticCommitScope": "deps",
"semanticCommitType": "chore",
"semanticCommits": null,
"separateMajorMinor": true,
"separateMinorPatch": false,
"skipInstalls": null,
"statusCheckVerify": false,
"suppressNotifications": Array [],
"timezone": null,
"unpublishSafe": false,
"updateLockFiles": true,
"updateNotScheduled": true,
"versionScheme": "npm",
"vulnerabilityAlerts": Object {
"commitMessageSuffix": "[SECURITY]",
"enabled": true,
"groupName": null,
"masterIssueApproval": false,
"rangeStrategy": "update-lockfile",
"schedule": Array [],
},
"warnings": Array [],
"yarnrc": null,
},
Object { Object {
"assignees": Array [], "assignees": Array [],
"automerge": false, "automerge": false,

View file

@ -6,4 +6,41 @@ exports[`workers/repository/updates/generate generateBranchConfig() adds commit
[skip-ci]" [skip-ci]"
`; `;
exports[`workers/repository/updates/generate generateBranchConfig() handles @types specially (reversed) 1`] = `
Object {
"automerge": false,
"blockedByPin": false,
"branchName": "some-branch",
"canBeUnpublished": false,
"commitMessage": "",
"depName": "@types/some-dep",
"masterIssueApproval": false,
"newValue": "0.5.7",
"prTitle": "some-title",
"prettyDepType": "dependency",
"releaseTimestamp": undefined,
"reuseLockFiles": true,
"upgrades": Array [
Object {
"branchName": "some-branch",
"commitMessage": "",
"depName": "@types/some-dep",
"newValue": "0.5.7",
"prTitle": "some-title",
"prettyDepType": "dependency",
},
Object {
"branchName": "some-branch",
"commitMessage": "",
"depName": "some-dep",
"newValue": "0.6.0",
"prTitle": "some-title",
"prettyDepType": "dependency",
},
],
}
`;
exports[`workers/repository/updates/generate generateBranchConfig() handles upgrades 1`] = `"some-title ()"`;
exports[`workers/repository/updates/generate generateBranchConfig() supports manual prTitle 1`] = `"upgrade some-dep"`; exports[`workers/repository/updates/generate generateBranchConfig() supports manual prTitle 1`] = `"upgrade some-dep"`;

View file

@ -33,6 +33,10 @@ describe('workers/repository/updates/flatten', () => {
deps: [ deps: [
{ depName: '@org/a', updates: [{ newValue: '1.0.0' }] }, { depName: '@org/a', updates: [{ newValue: '1.0.0' }] },
{ depName: 'foo', updates: [{ newValue: '2.0.0' }] }, { depName: 'foo', updates: [{ newValue: '2.0.0' }] },
{
updateTypes: ['pin'],
updates: [{ newValue: '2.0.0' }],
},
], ],
}, },
{ {
@ -69,7 +73,7 @@ describe('workers/repository/updates/flatten', () => {
}; };
const res = await flattenUpdates(config, packageFiles); const res = await flattenUpdates(config, packageFiles);
expect(res).toMatchSnapshot(); expect(res).toMatchSnapshot();
expect(res).toHaveLength(8); expect(res).toHaveLength(9);
expect( expect(
res.filter(r => r.updateType === 'lockFileMaintenance') res.filter(r => r.updateType === 'lockFileMaintenance')
).toHaveLength(2); ).toHaveLength(2);

View file

@ -461,6 +461,29 @@ describe('workers/repository/updates/generate', () => {
expect(res.recreateClosed).toBe(false); expect(res.recreateClosed).toBe(false);
expect(res.groupName).toBeUndefined(); expect(res.groupName).toBeUndefined();
}); });
it('handles @types specially (reversed)', () => {
const branch = [
{
depName: 'some-dep',
groupName: null,
branchName: 'some-branch',
prTitle: 'some-title',
lazyGrouping: true,
newValue: '0.6.0',
group: {},
},
{
depName: '@types/some-dep',
groupName: null,
branchName: 'some-branch',
prTitle: 'some-title',
lazyGrouping: true,
newValue: '0.5.7',
group: {},
},
];
expect(generateBranchConfig(branch)).toMatchSnapshot();
});
it('overrides schedule for pin PRs', () => { it('overrides schedule for pin PRs', () => {
const branch = [ const branch = [
{ {
@ -473,5 +496,52 @@ describe('workers/repository/updates/generate', () => {
const res = generateBranchConfig(branch); const res = generateBranchConfig(branch);
expect(res.schedule).toEqual([]); expect(res.schedule).toEqual([]);
}); });
it('handles upgrades', () => {
const branch = [
{
depName: 'some-dep',
branchName: 'some-branch',
prTitle: 'some-title',
newValue: '0.6.0',
hasBaseBranches: true,
fileReplacePosition: 5,
},
{
...defaultConfig,
depName: 'some-dep',
branchName: 'some-branch',
prTitle: 'some-title',
newValue: '0.6.0',
isGroup: true,
separateMinorPatch: true,
updateType: 'minor',
fileReplacePosition: 1,
},
{
...defaultConfig,
depName: 'some-dep',
branchName: 'some-branch',
prTitle: 'some-title',
newValue: '0.6.0',
isGroup: true,
separateMajorMinor: true,
updateType: 'major',
fileReplacePosition: 2,
},
{
...defaultConfig,
depName: 'some-dep',
branchName: 'some-branch',
prTitle: 'some-title',
newValue: '0.6.0',
isGroup: true,
separateMajorMinor: true,
updateType: 'patch',
fileReplacePosition: 0,
},
];
const res = generateBranchConfig(branch);
expect(res.prTitle).toMatchSnapshot();
});
}); });
}); });