semantic-release/test/pre.test.js
Pierre-Denis Vanduynslager abf92ad03d refactor: Use ES6, Test with AVA
- Use async/await instead of callbacks
- Use execa to run command line
- Use AVA for tests
- Add several assertions in the unit tests
- Add documentation (comments) in the tests
- Run tests with a real git repo instead of mocking child_process and add test helpers to create repos, commits and checkout
- Simplify test directory structure
- Simplify code readability (mostly with async/await)
- Use eslint for for linting, prettier for formatting
2017-09-30 13:30:41 -04:00

164 lines
6.8 KiB
JavaScript

import {callbackify} from 'util';
import test from 'ava';
import {gitRepo, gitCommits} from './helpers/git-utils';
import proxyquire from 'proxyquire';
import {stub} from 'sinon';
// Stub to capture the log messages
const errorLog = stub();
// Module to test
const pre = proxyquire('../src/pre', {
'./lib/get-commits': proxyquire('../src/lib/get-commits', {npmlog: {error: errorLog}}),
});
test.beforeEach(t => {
// Save the current working diretory
t.context.cwd = process.cwd();
// Reset the stub call history
errorLog.resetHistory();
});
test.afterEach.always(t => {
// Restore the current working directory
process.chdir(t.context.cwd);
});
test.serial('Increase version', async t => {
// Create a git repository, set the current working directory at the root of the repo
await gitRepo();
// Add commits to the master branch
const cmts = await gitCommits(['fix: First fix', 'feat: Second feature']);
const options = {branch: 'master'};
const pkg = {name: 'available'};
const lastRelease = {version: '1.0.0', gitHead: cmts[cmts.length - 1].hash};
// Stub the getLastRelease, analyzeCommits and verifyRelease plugins
const getLastRelease = stub().resolves(lastRelease);
const analyzeCommits = stub().resolves('major');
const verifyRelease = stub().resolves();
// Call the pre module
const nextRelease = await pre({
options,
pkg,
plugins: {
getLastRelease: callbackify(getLastRelease),
analyzeCommits: callbackify(analyzeCommits),
verifyRelease: callbackify(verifyRelease),
},
});
// Verify the pre module returns the 'type' returned by analyzeCommits and the 'version' returned by getLastRelease increamented with the 'type' (current version 1.0.0 => major release = version 2.0.0)
t.deepEqual(nextRelease, {type: 'major', version: '2.0.0'});
// Verify the getLastRelease plugin has been called with 'options' and 'pkg'
t.true(getLastRelease.calledOnce);
t.deepEqual(getLastRelease.firstCall.args[0].options, options);
t.deepEqual(getLastRelease.firstCall.args[0].pkg, pkg);
// Verify the analyzeCommits plugin has been called with the repo 'commits' since lastVersion githead
t.true(analyzeCommits.calledOnce);
t.is(analyzeCommits.firstCall.args[0].commits.length, 1);
t.is(analyzeCommits.firstCall.args[0].commits[0].hash.substring(0, 7), cmts[0].hash);
t.is(analyzeCommits.firstCall.args[0].commits[0].message, cmts[0].message);
// Verify the verifyRelease plugin has been called with 'lastRelease' and 'nextRelease'
t.true(verifyRelease.calledOnce);
t.deepEqual(verifyRelease.firstCall.args[0].lastRelease, lastRelease);
t.deepEqual(verifyRelease.firstCall.args[0].nextRelease, nextRelease);
});
test.serial('Initial version', async t => {
// Create a git repository, set the current working directory at the root of the repo
await gitRepo();
// Add commits to the master branch
const cmts = await gitCommits(['fix(scope1): First fix', 'feat(scope2): Second feature']);
const options = {branch: 'master'};
const pkg = {name: 'available'};
const lastRelease = {version: null, gitHead: undefined};
// Stub the getLastRelease, analyzeCommits and verifyRelease plugins
const getLastRelease = stub().resolves({version: null, gitHead: undefined});
const analyzeCommits = stub().resolves('major');
const verifyRelease = stub().resolves();
// Call the pre module
const nextRelease = await pre({
options,
pkg,
plugins: {
getLastRelease: callbackify(getLastRelease),
analyzeCommits: callbackify(analyzeCommits),
verifyRelease: callbackify(verifyRelease),
},
});
// Verify the pre module returns the 'type' returned by analyzeCommits and the 'version' returned by getLastRelease increamented with the 'type' (no current version => initial release = version 1.0.0)
t.deepEqual(nextRelease, {type: 'initial', version: '1.0.0'});
// Verify the getLastRelease plugin has been called with 'options' and 'pkg'
t.true(getLastRelease.calledOnce);
t.deepEqual(getLastRelease.firstCall.args[0].options, options);
t.deepEqual(getLastRelease.firstCall.args[0].pkg, pkg);
// Verify the analyzeCommits plugin has been called with all the repo 'commits'
t.true(analyzeCommits.calledOnce);
t.is(analyzeCommits.firstCall.args[0].commits.length, 2);
t.is(analyzeCommits.firstCall.args[0].commits[0].hash.substring(0, 7), cmts[0].hash);
t.is(analyzeCommits.firstCall.args[0].commits[0].message, cmts[0].message);
t.is(analyzeCommits.firstCall.args[0].commits[1].hash.substring(0, 7), cmts[1].hash);
t.is(analyzeCommits.firstCall.args[0].commits[1].message, cmts[1].message);
// Verify the verifyRelease plugin has been called with 'lastRelease' and 'nextRelease'
t.true(verifyRelease.calledOnce);
t.deepEqual(verifyRelease.firstCall.args[0].lastRelease, lastRelease);
t.deepEqual(verifyRelease.firstCall.args[0].nextRelease, nextRelease);
});
test.serial('Throws error if verifyRelease fails', async t => {
// Create a git repository, set the current working directory at the root of the repo
await gitRepo();
// Add commits to the master branch
const cmts = await gitCommits(['fix: First fix', 'feat: Second feature']);
const options = {branch: 'master'};
const pkg = {name: 'available'};
const lastRelease = {version: '1.0.0', gitHead: cmts[cmts.length - 1].hash};
// Stub the getLastRelease, analyzeCommits and verifyRelease plugins
const getLastRelease = stub().resolves(lastRelease);
const analyzeCommits = stub().resolves('major');
const verifyRelease = stub().rejects(new Error('verifyRelease failed'));
// Call the pre module and verify it returns the Error returned by verifyRelease
const error = await t.throws(
pre({
options,
pkg,
plugins: {
getLastRelease: callbackify(getLastRelease),
analyzeCommits: callbackify(analyzeCommits),
verifyRelease: callbackify(verifyRelease),
},
})
);
// Verify the error message is the one returned by verifyRelease
t.is(error.message, 'verifyRelease failed');
// Verify the getLastRelease plugin has been called with 'options' and 'pkg'
t.true(getLastRelease.calledOnce);
t.deepEqual(getLastRelease.firstCall.args[0].options, options);
t.deepEqual(getLastRelease.firstCall.args[0].pkg, pkg);
// Verify the analyzeCommits plugin has been called with all the repo 'commits'
t.true(analyzeCommits.calledOnce);
t.is(analyzeCommits.firstCall.args[0].commits.length, 1);
t.is(analyzeCommits.firstCall.args[0].commits[0].hash.substring(0, 7), cmts[0].hash);
t.is(analyzeCommits.firstCall.args[0].commits[0].message, cmts[0].message);
// Verify the verifyRelease plugin has been called with 'lastRelease' and 'nextRelease'
t.true(verifyRelease.calledOnce);
t.deepEqual(verifyRelease.firstCall.args[0].lastRelease, lastRelease);
t.deepEqual(verifyRelease.firstCall.args[0].nextRelease, {type: 'major', version: '2.0.0'});
});