renovate/lib/config/validation.spec.ts
2020-03-07 11:27:10 +01:00

310 lines
8.6 KiB
TypeScript

import * as configValidation from './validation';
import { RenovateConfig } from '.';
describe('config/validation', () => {
describe('validateConfig(config)', () => {
it('returns deprecation warnings', async () => {
const config = {
prTitle: 'something',
};
const { warnings } = await configValidation.validateConfig(config);
expect(warnings).toHaveLength(1);
expect(warnings).toMatchSnapshot();
});
it('catches invalid handlebars templates', async () => {
const config = {
commitMessage: '{{{something}}',
};
const { errors } = await configValidation.validateConfig(config);
expect(errors).toHaveLength(1);
expect(errors).toMatchSnapshot();
});
it('returns nested errors', async () => {
const config: RenovateConfig = {
foo: 1,
schedule: ['after 5pm'],
timezone: 'Asia/Singapore',
packageRules: [
{
packagePatterns: ['*'],
excludePackagePatterns: ['abc ([a-z]+) ([a-z]+))'],
},
],
lockFileMaintenance: {
bar: 2,
},
major: null,
};
const { warnings, errors } = await configValidation.validateConfig(
config
);
expect(warnings).toHaveLength(0);
expect(errors).toHaveLength(3);
expect(errors).toMatchSnapshot();
});
it('included unsupported manager', async () => {
const config = {
packageRules: [
{
managers: ['foo'],
},
],
};
const { warnings, errors } = await configValidation.validateConfig(
config
);
expect(warnings).toHaveLength(0);
expect(errors).toHaveLength(1);
expect(errors[0].message.includes('ansible')).toBe(true);
});
it('included managers of the wrong type', async () => {
const config = {
packageRules: [
{
managers: 'string not an array',
},
],
};
const { warnings, errors } = await configValidation.validateConfig(
config
);
expect(warnings).toHaveLength(0);
expect(errors).toHaveLength(2);
expect(errors).toMatchSnapshot();
});
it('errors for all types', async () => {
const config: RenovateConfig = {
allowedVersions: 'foo',
enabled: 1 as any,
schedule: ['every 15 mins every weekday'],
timezone: 'Asia',
labels: 5 as any,
semanticCommitType: 7 as any,
lockFileMaintenance: false as any,
extends: [':timezone(Europe/Brussel)'],
packageRules: [
{
excludePackageNames: ['foo'],
enabled: true,
},
{
foo: 1,
},
'what?' as any,
{
packagePatterns: 'abc ([a-z]+) ([a-z]+))',
excludePackagePatterns: ['abc ([a-z]+) ([a-z]+))'],
enabled: false,
},
],
major: null,
};
const { warnings, errors } = await configValidation.validateConfig(
config
);
expect(warnings).toHaveLength(0);
expect(errors).toMatchSnapshot();
expect(errors).toHaveLength(12);
});
it('selectors outside packageRules array trigger errors', async () => {
const config = {
packageNames: ['angular'],
meteor: {
packageRules: [
{
packageNames: ['meteor'],
},
],
},
docker: {
minor: {
packageNames: ['testPackage'],
},
},
};
const { warnings, errors } = await configValidation.validateConfig(
config
);
expect(warnings).toHaveLength(0);
expect(errors).toMatchSnapshot();
expect(errors).toHaveLength(2);
});
it('ignore packageRule nesting validation for presets', async () => {
const config = {
description: ['All angular.js packages'],
packageNames: [
'angular',
'angular-animate',
'angular-scroll',
'angular-sanitize',
],
};
const { warnings, errors } = await configValidation.validateConfig(
config,
true
);
expect(warnings).toHaveLength(0);
expect(errors).toMatchSnapshot();
expect(errors).toHaveLength(0);
});
it('errors for unsafe fileMatches', async () => {
const config = {
npm: {
fileMatch: ['abc ([a-z]+) ([a-z]+))'],
},
docker: {
fileMatch: ['x?+'],
},
};
const { warnings, errors } = await configValidation.validateConfig(
config
);
expect(warnings).toHaveLength(0);
expect(errors).toHaveLength(2);
expect(errors).toMatchSnapshot();
});
it('validates regEx for each fileMatch', async () => {
const config = {
fileMatch: ['js', '***$}{]]['],
};
const { warnings, errors } = await configValidation.validateConfig(
config,
true
);
expect(warnings).toHaveLength(0);
expect(errors).toHaveLength(1);
});
it('errors if no regexManager matchStrings', async () => {
const config = {
regexManagers: [
{
matchStrings: [],
},
],
};
const { warnings, errors } = await configValidation.validateConfig(
config,
true
);
expect(warnings).toHaveLength(0);
expect(errors).toHaveLength(1);
});
it('validates regEx for each matchStrings', async () => {
const config = {
regexManagers: [
{
matchStrings: ['***$}{]]['],
},
],
};
const { warnings, errors } = await configValidation.validateConfig(
config,
true
);
expect(warnings).toHaveLength(0);
expect(errors).toHaveLength(1);
});
it('passes if regexManager fields are present', async () => {
const config = {
regexManagers: [
{
matchStrings: ['ENV (?<currentValue>.*?)\\s'],
depNameTemplate: 'foo',
datasourceTemplate: 'bar',
},
],
};
const { warnings, errors } = await configValidation.validateConfig(
config,
true
);
expect(warnings).toHaveLength(0);
expect(errors).toHaveLength(0);
});
it('errors if extra regexManager fields are present', async () => {
const config = {
regexManagers: [
{
matchStrings: ['ENV (?<currentValue>.*?)\\s'],
depNameTemplate: 'foo',
datasourceTemplate: 'bar',
automerge: true,
},
],
};
const { warnings, errors } = await configValidation.validateConfig(
config,
true
);
expect(warnings).toHaveLength(0);
expect(errors).toHaveLength(1);
});
it('errors if regexManager fields are missing', async () => {
const config = {
regexManagers: [
{
matchStrings: ['ENV (.*?)\\s'],
depNameTemplate: 'foo',
datasourceTemplate: 'bar',
},
],
};
const { warnings, errors } = await configValidation.validateConfig(
config,
true
);
expect(warnings).toHaveLength(0);
expect(errors).toMatchSnapshot();
expect(errors).toHaveLength(1);
});
it('ignore keys', async () => {
const config = {
$schema: 'renovate.json',
};
const { warnings, errors } = await configValidation.validateConfig(
config,
true
);
expect(warnings).toHaveLength(0);
expect(errors).toHaveLength(0);
});
it('validates timezone preset', async () => {
const config = {
extends: [':timezone', ':timezone(Europe/Berlin)'],
};
const { warnings, errors } = await configValidation.validateConfig(
config,
true
);
expect(warnings).toHaveLength(0);
expect(errors).toHaveLength(0);
});
it('does not validate compatibility children', async () => {
const config = {
compatibility: { packageRules: [{}] },
};
const { warnings, errors } = await configValidation.validateConfig(
config,
true
);
expect(warnings).toHaveLength(0);
expect(errors).toHaveLength(0);
});
it('validates object with ignored children', async () => {
const config = {
prBodyDefinitions: {},
};
const { warnings, errors } = await configValidation.validateConfig(
config,
true
);
expect(warnings).toHaveLength(0);
expect(errors).toHaveLength(0);
});
});
});