docs(changelog test): i test how to automate ChangeLog
This commit is contained in:
594
node_modules/cz-conventional-changelog/engine.test.js
generated
vendored
Normal file
594
node_modules/cz-conventional-changelog/engine.test.js
generated
vendored
Normal file
@@ -0,0 +1,594 @@
|
||||
var chai = require('chai');
|
||||
var chalk = require('chalk');
|
||||
var engine = require('./engine');
|
||||
var mock = require('mock-require');
|
||||
var semver = require('semver');
|
||||
|
||||
var types = require('conventional-commit-types').types;
|
||||
|
||||
var expect = chai.expect;
|
||||
chai.should();
|
||||
|
||||
var defaultOptions = {
|
||||
types,
|
||||
maxLineWidth: 100,
|
||||
maxHeaderWidth: 100
|
||||
};
|
||||
|
||||
var type = 'func';
|
||||
var scope = 'everything';
|
||||
var subject = 'testing123';
|
||||
var longBody =
|
||||
'a a aa a aa a aa a aa a aa a aa a aa a aa a aa a aa a aa a aa a aa a aa a' +
|
||||
'a a aa a aa a aa a aa a aa a aa a aa a aa a aa a aa a aa a aa a aa a aa a aa a aa a aa a aa a' +
|
||||
'a a aa a aa a aa a aa a aa a aa a aa a aa a aa a aa a aa a aa a aa a aa a aa a aa a aa a aa a';
|
||||
var longBodySplit =
|
||||
longBody.slice(0, defaultOptions.maxLineWidth).trim() +
|
||||
'\n' +
|
||||
longBody
|
||||
.slice(defaultOptions.maxLineWidth, 2 * defaultOptions.maxLineWidth)
|
||||
.trim() +
|
||||
'\n' +
|
||||
longBody.slice(defaultOptions.maxLineWidth * 2, longBody.length).trim();
|
||||
var body = 'A quick brown fox jumps over the dog';
|
||||
var issues = 'a issues is not a person that kicks things';
|
||||
var longIssues =
|
||||
'b b bb b bb b bb b bb b bb b bb b bb b bb b bb b bb b bb b bb b bb b bb b' +
|
||||
'b b bb b bb b bb b bb b bb b bb b bb b bb b bb b bb b bb b bb b bb b bb b bb b bb b bb b bb b' +
|
||||
'b b bb b bb b bb b bb b bb b bb b bb b bb b bb b bb b bb b bb b bb b bb b bb b bb b bb b bb b';
|
||||
var breakingChange = 'BREAKING CHANGE: ';
|
||||
var breaking = 'asdhdfkjhbakjdhjkashd adhfajkhs asdhkjdsh ahshd';
|
||||
var longIssuesSplit =
|
||||
longIssues.slice(0, defaultOptions.maxLineWidth).trim() +
|
||||
'\n' +
|
||||
longIssues
|
||||
.slice(defaultOptions.maxLineWidth, defaultOptions.maxLineWidth * 2)
|
||||
.trim() +
|
||||
'\n' +
|
||||
longIssues.slice(defaultOptions.maxLineWidth * 2, longIssues.length).trim();
|
||||
|
||||
describe('commit message', function() {
|
||||
it('only header w/ out scope', function() {
|
||||
expect(
|
||||
commitMessage({
|
||||
type,
|
||||
subject
|
||||
})
|
||||
).to.equal(`${type}: ${subject}`);
|
||||
});
|
||||
it('only header w/ scope', function() {
|
||||
expect(
|
||||
commitMessage({
|
||||
type,
|
||||
scope,
|
||||
subject
|
||||
})
|
||||
).to.equal(`${type}(${scope}): ${subject}`);
|
||||
});
|
||||
it('header and body w/ out scope', function() {
|
||||
expect(
|
||||
commitMessage({
|
||||
type,
|
||||
subject,
|
||||
body
|
||||
})
|
||||
).to.equal(`${type}: ${subject}\n\n${body}`);
|
||||
});
|
||||
it('header and body w/ scope', function() {
|
||||
expect(
|
||||
commitMessage({
|
||||
type,
|
||||
scope,
|
||||
subject,
|
||||
body
|
||||
})
|
||||
).to.equal(`${type}(${scope}): ${subject}\n\n${body}`);
|
||||
});
|
||||
it('header and body w/ uppercase scope', function() {
|
||||
var upperCaseScope = scope.toLocaleUpperCase();
|
||||
expect(
|
||||
commitMessage(
|
||||
{
|
||||
type,
|
||||
scope: upperCaseScope,
|
||||
subject,
|
||||
body
|
||||
},
|
||||
{
|
||||
...defaultOptions,
|
||||
disableScopeLowerCase: true
|
||||
}
|
||||
)
|
||||
).to.equal(`${type}(${upperCaseScope}): ${subject}\n\n${body}`);
|
||||
});
|
||||
it('header and body w/ uppercase subject', function() {
|
||||
var upperCaseSubject = subject.toLocaleUpperCase();
|
||||
expect(
|
||||
commitMessage(
|
||||
{
|
||||
type,
|
||||
scope,
|
||||
subject: upperCaseSubject,
|
||||
body
|
||||
},
|
||||
{
|
||||
...defaultOptions,
|
||||
disableSubjectLowerCase: true
|
||||
}
|
||||
)
|
||||
).to.equal(`${type}(${scope}): ${upperCaseSubject}\n\n${body}`);
|
||||
});
|
||||
it('header, body and issues w/ out scope', function() {
|
||||
expect(
|
||||
commitMessage({
|
||||
type,
|
||||
subject,
|
||||
body,
|
||||
issues
|
||||
})
|
||||
).to.equal(`${type}: ${subject}\n\n${body}\n\n${issues}`);
|
||||
});
|
||||
it('header, body and issues w/ scope', function() {
|
||||
expect(
|
||||
commitMessage({
|
||||
type,
|
||||
scope,
|
||||
subject,
|
||||
body,
|
||||
issues
|
||||
})
|
||||
).to.equal(`${type}(${scope}): ${subject}\n\n${body}\n\n${issues}`);
|
||||
});
|
||||
it('header, body and long issues w/ out scope', function() {
|
||||
expect(
|
||||
commitMessage({
|
||||
type,
|
||||
subject,
|
||||
body,
|
||||
issues: longIssues
|
||||
})
|
||||
).to.equal(`${type}: ${subject}\n\n${body}\n\n${longIssuesSplit}`);
|
||||
});
|
||||
it('header, body and long issues w/ scope', function() {
|
||||
expect(
|
||||
commitMessage({
|
||||
type,
|
||||
scope,
|
||||
subject,
|
||||
body,
|
||||
issues: longIssues
|
||||
})
|
||||
).to.equal(
|
||||
`${type}(${scope}): ${subject}\n\n${body}\n\n${longIssuesSplit}`
|
||||
);
|
||||
});
|
||||
it('header and long body w/ out scope', function() {
|
||||
expect(
|
||||
commitMessage({
|
||||
type,
|
||||
subject,
|
||||
body: longBody
|
||||
})
|
||||
).to.equal(`${type}: ${subject}\n\n${longBodySplit}`);
|
||||
});
|
||||
it('header and long body w/ scope', function() {
|
||||
expect(
|
||||
commitMessage({
|
||||
type,
|
||||
scope,
|
||||
subject,
|
||||
body: longBody
|
||||
})
|
||||
).to.equal(`${type}(${scope}): ${subject}\n\n${longBodySplit}`);
|
||||
});
|
||||
it('header, long body and issues w/ out scope', function() {
|
||||
expect(
|
||||
commitMessage({
|
||||
type,
|
||||
subject,
|
||||
body: longBody,
|
||||
issues
|
||||
})
|
||||
).to.equal(`${type}: ${subject}\n\n${longBodySplit}\n\n${issues}`);
|
||||
});
|
||||
it('header, long body and issues w/ scope', function() {
|
||||
expect(
|
||||
commitMessage({
|
||||
type,
|
||||
scope,
|
||||
subject,
|
||||
body: longBody,
|
||||
issues
|
||||
})
|
||||
).to.equal(
|
||||
`${type}(${scope}): ${subject}\n\n${longBodySplit}\n\n${issues}`
|
||||
);
|
||||
});
|
||||
it('header, long body and long issues w/ out scope', function() {
|
||||
expect(
|
||||
commitMessage({
|
||||
type,
|
||||
subject,
|
||||
body: longBody,
|
||||
issues: longIssues
|
||||
})
|
||||
).to.equal(`${type}: ${subject}\n\n${longBodySplit}\n\n${longIssuesSplit}`);
|
||||
});
|
||||
it('header, long body and long issues w/ scope', function() {
|
||||
expect(
|
||||
commitMessage({
|
||||
type,
|
||||
scope,
|
||||
subject,
|
||||
body: longBody,
|
||||
issues: longIssues
|
||||
})
|
||||
).to.equal(
|
||||
`${type}(${scope}): ${subject}\n\n${longBodySplit}\n\n${longIssuesSplit}`
|
||||
);
|
||||
});
|
||||
it('header, long body, breaking change, and long issues w/ scope', function() {
|
||||
expect(
|
||||
commitMessage({
|
||||
type,
|
||||
scope,
|
||||
subject,
|
||||
body: longBody,
|
||||
breaking,
|
||||
issues: longIssues
|
||||
})
|
||||
).to.equal(
|
||||
`${type}(${scope}): ${subject}\n\n${longBodySplit}\n\n${breakingChange}${breaking}\n\n${longIssuesSplit}`
|
||||
);
|
||||
});
|
||||
it('header, long body, breaking change (with prefix entered), and long issues w/ scope', function() {
|
||||
expect(
|
||||
commitMessage({
|
||||
type,
|
||||
scope,
|
||||
subject,
|
||||
body: longBody,
|
||||
breaking: `${breakingChange}${breaking}`,
|
||||
issues: longIssues
|
||||
})
|
||||
).to.equal(
|
||||
`${type}(${scope}): ${subject}\n\n${longBodySplit}\n\n${breakingChange}${breaking}\n\n${longIssuesSplit}`
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('validation', function() {
|
||||
it('subject exceeds max length', function() {
|
||||
expect(() =>
|
||||
commitMessage({
|
||||
type,
|
||||
scope,
|
||||
subject: longBody
|
||||
})
|
||||
).to.throw(
|
||||
'length must be less than or equal to ' +
|
||||
`${defaultOptions.maxLineWidth - type.length - scope.length - 4}`
|
||||
);
|
||||
});
|
||||
it('empty subject', function() {
|
||||
expect(() =>
|
||||
commitMessage({
|
||||
type,
|
||||
scope,
|
||||
subject: ''
|
||||
})
|
||||
).to.throw('subject is required');
|
||||
});
|
||||
});
|
||||
|
||||
describe('defaults', function() {
|
||||
it('defaultType default', function() {
|
||||
expect(questionDefault('type')).to.be.undefined;
|
||||
});
|
||||
it('defaultType options', function() {
|
||||
expect(
|
||||
questionDefault('type', customOptions({ defaultType: type }))
|
||||
).to.equal(type);
|
||||
});
|
||||
it('defaultScope default', function() {
|
||||
expect(questionDefault('scope')).to.be.undefined;
|
||||
});
|
||||
it('defaultScope options', () =>
|
||||
expect(
|
||||
questionDefault('scope', customOptions({ defaultScope: scope }))
|
||||
).to.equal(scope));
|
||||
|
||||
it('defaultSubject default', () =>
|
||||
expect(questionDefault('subject')).to.be.undefined);
|
||||
it('defaultSubject options', function() {
|
||||
expect(
|
||||
questionDefault(
|
||||
'subject',
|
||||
customOptions({
|
||||
defaultSubject: subject
|
||||
})
|
||||
)
|
||||
).to.equal(subject);
|
||||
});
|
||||
it('defaultBody default', function() {
|
||||
expect(questionDefault('body')).to.be.undefined;
|
||||
});
|
||||
it('defaultBody options', function() {
|
||||
expect(
|
||||
questionDefault('body', customOptions({ defaultBody: body }))
|
||||
).to.equal(body);
|
||||
});
|
||||
it('defaultIssues default', function() {
|
||||
expect(questionDefault('issues')).to.be.undefined;
|
||||
});
|
||||
it('defaultIssues options', function() {
|
||||
expect(
|
||||
questionDefault(
|
||||
'issues',
|
||||
customOptions({
|
||||
defaultIssues: issues
|
||||
})
|
||||
)
|
||||
).to.equal(issues);
|
||||
});
|
||||
it('disableScopeLowerCase default', function() {
|
||||
expect(questionDefault('disableScopeLowerCase')).to.be.undefined;
|
||||
});
|
||||
it('disableSubjectLowerCase default', function() {
|
||||
expect(questionDefault('disableSubjectLowerCase')).to.be.undefined;
|
||||
});
|
||||
});
|
||||
|
||||
describe('prompts', function() {
|
||||
it('commit subject prompt for commit w/ out scope', function() {
|
||||
expect(questionPrompt('subject', { type })).to.contain(
|
||||
`(max ${defaultOptions.maxHeaderWidth - type.length - 2} chars)`
|
||||
);
|
||||
});
|
||||
it('commit subject prompt for commit w/ scope', function() {
|
||||
expect(questionPrompt('subject', { type, scope })).to.contain(
|
||||
`(max ${defaultOptions.maxHeaderWidth -
|
||||
type.length -
|
||||
scope.length -
|
||||
4} chars)`
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('transformation', function() {
|
||||
it('subject w/ character count', () =>
|
||||
expect(
|
||||
questionTransformation('subject', {
|
||||
type,
|
||||
subject
|
||||
})
|
||||
).to.equal(chalk.green(`(${subject.length}) ${subject}`)));
|
||||
it('long subject w/ character count', () =>
|
||||
expect(
|
||||
questionTransformation('subject', {
|
||||
type,
|
||||
subject: longBody
|
||||
})
|
||||
).to.equal(chalk.red(`(${longBody.length}) ${longBody}`)));
|
||||
});
|
||||
|
||||
describe('filter', function() {
|
||||
it('lowercase scope', () =>
|
||||
expect(questionFilter('scope', 'HelloMatt')).to.equal('hellomatt'));
|
||||
it('lowerfirst subject trimmed and trailing dots striped', () =>
|
||||
expect(questionFilter('subject', ' A subject... ')).to.equal(
|
||||
'a subject'
|
||||
));
|
||||
});
|
||||
|
||||
describe('when', function() {
|
||||
it('breaking by default', () =>
|
||||
expect(questionWhen('breaking', {})).to.be.undefined);
|
||||
it('breaking when isBreaking', () =>
|
||||
expect(
|
||||
questionWhen('breaking', {
|
||||
isBreaking: true
|
||||
})
|
||||
).to.be.true);
|
||||
it('issues by default', () =>
|
||||
expect(questionWhen('issues', {})).to.be.undefined);
|
||||
it('issues when isIssueAffected', () =>
|
||||
expect(
|
||||
questionWhen('issues', {
|
||||
isIssueAffected: true
|
||||
})
|
||||
).to.be.true);
|
||||
});
|
||||
|
||||
describe('commitlint config header-max-length', function() {
|
||||
//commitlint config parser only supports Node 6.0.0 and higher
|
||||
if (semver.gte(process.version, '6.0.0')) {
|
||||
function mockOptions(headerMaxLength) {
|
||||
var options = undefined;
|
||||
mock('./engine', function(opts) {
|
||||
options = opts;
|
||||
});
|
||||
if (headerMaxLength) {
|
||||
mock('cosmiconfig', function() {
|
||||
return {
|
||||
load: function(cwd) {
|
||||
return {
|
||||
filepath: cwd + '/.commitlintrc.js',
|
||||
config: {
|
||||
rules: {
|
||||
'header-max-length': [2, 'always', headerMaxLength]
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
mock.reRequire('./index');
|
||||
try {
|
||||
return mock
|
||||
.reRequire('@commitlint/load')()
|
||||
.then(function() {
|
||||
return options;
|
||||
});
|
||||
} catch (err) {
|
||||
return Promise.resolve(options);
|
||||
}
|
||||
}
|
||||
|
||||
afterEach(function() {
|
||||
delete require.cache[require.resolve('./index')];
|
||||
delete require.cache[require.resolve('@commitlint/load')];
|
||||
delete process.env.CZ_MAX_HEADER_WIDTH;
|
||||
mock.stopAll();
|
||||
});
|
||||
|
||||
it('with no environment or commitizen config override', function() {
|
||||
return mockOptions(72).then(function(options) {
|
||||
expect(options).to.have.property('maxHeaderWidth', 72);
|
||||
});
|
||||
});
|
||||
|
||||
it('with environment variable override', function() {
|
||||
process.env.CZ_MAX_HEADER_WIDTH = '105';
|
||||
return mockOptions(72).then(function(options) {
|
||||
expect(options).to.have.property('maxHeaderWidth', 105);
|
||||
});
|
||||
});
|
||||
|
||||
it('with commitizen config override', function() {
|
||||
mock('commitizen', {
|
||||
configLoader: {
|
||||
load: function() {
|
||||
return {
|
||||
maxHeaderWidth: 103
|
||||
};
|
||||
}
|
||||
}
|
||||
});
|
||||
return mockOptions(72).then(function(options) {
|
||||
expect(options).to.have.property('maxHeaderWidth', 103);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
//Node 4 doesn't support commitlint so the config value should remain the same
|
||||
it('default value for Node 4', function() {
|
||||
return mockOptions(72).then(function(options) {
|
||||
expect(options).to.have.property('maxHeaderWidth', 100);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
function commitMessage(answers, options) {
|
||||
options = options || defaultOptions;
|
||||
var result = null;
|
||||
engine(options).prompter(
|
||||
{
|
||||
prompt: function(questions) {
|
||||
return {
|
||||
then: function(finalizer) {
|
||||
processQuestions(questions, answers, options);
|
||||
finalizer(answers);
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
function(message) {
|
||||
result = message;
|
||||
}
|
||||
);
|
||||
return result;
|
||||
}
|
||||
|
||||
function processQuestions(questions, answers, options) {
|
||||
for (var i in questions) {
|
||||
var question = questions[i];
|
||||
var answer = answers[question.name];
|
||||
var validation =
|
||||
answer === undefined || !question.validate
|
||||
? true
|
||||
: question.validate(answer, answers);
|
||||
if (validation !== true) {
|
||||
throw new Error(
|
||||
validation ||
|
||||
`Answer '${answer}' to question '${question.name}' was invalid`
|
||||
);
|
||||
}
|
||||
if (question.filter && answer) {
|
||||
answers[question.name] = question.filter(answer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getQuestions(options) {
|
||||
options = options || defaultOptions;
|
||||
var result = null;
|
||||
engine(options).prompter({
|
||||
prompt: function(questions) {
|
||||
result = questions;
|
||||
return {
|
||||
then: function() {}
|
||||
};
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
function getQuestion(name, options) {
|
||||
options = options || defaultOptions;
|
||||
var questions = getQuestions(options);
|
||||
for (var i in questions) {
|
||||
if (questions[i].name === name) {
|
||||
return questions[i];
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function questionPrompt(name, answers, options) {
|
||||
options = options || defaultOptions;
|
||||
var question = getQuestion(name, options);
|
||||
return question.message && typeof question.message === 'string'
|
||||
? question.message
|
||||
: question.message(answers);
|
||||
}
|
||||
|
||||
function questionTransformation(name, answers, options) {
|
||||
options = options || defaultOptions;
|
||||
var question = getQuestion(name, options);
|
||||
return (
|
||||
question.transformer &&
|
||||
question.transformer(answers[name], answers, options)
|
||||
);
|
||||
}
|
||||
|
||||
function questionFilter(name, answer, options) {
|
||||
options = options || defaultOptions;
|
||||
var question = getQuestion(name, options);
|
||||
return (
|
||||
question.filter &&
|
||||
question.filter(typeof answer === 'string' ? answer : answer[name])
|
||||
);
|
||||
}
|
||||
|
||||
function questionDefault(name, options) {
|
||||
options = options || defaultOptions;
|
||||
var question = getQuestion(name, options);
|
||||
return question.default;
|
||||
}
|
||||
|
||||
function questionWhen(name, answers, options) {
|
||||
options = options || defaultOptions;
|
||||
var question = getQuestion(name, options);
|
||||
return question.when(answers);
|
||||
}
|
||||
|
||||
function customOptions(options) {
|
||||
Object.keys(defaultOptions).forEach(key => {
|
||||
if (options[key] === undefined) {
|
||||
options[key] = defaultOptions[key];
|
||||
}
|
||||
});
|
||||
return options;
|
||||
}
|
||||
Reference in New Issue
Block a user