Skip to content

Commit

Permalink
Refactor tests + more integrated tests
Browse files Browse the repository at this point in the history
  • Loading branch information
webpro committed Aug 11, 2021
1 parent f97297e commit 80b99dc
Show file tree
Hide file tree
Showing 2 changed files with 141 additions and 78 deletions.
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -5,7 +5,7 @@
"type": "module",
"exports": "./index.js",
"scripts": {
"test": "bron test.js",
"test": "bron test.js --serial",
"release": "release-it"
},
"keywords": [
Expand Down
217 changes: 140 additions & 77 deletions test.js
@@ -1,156 +1,219 @@
const test = require('bron');
const assert = require('assert');
const { EOL } = require('os');
const sinon = require('sinon');
const proxyquire = require('proxyquire');
const stream = require('stream');
const fs = require('fs');
const { factory, runTasks } = require('release-it/test/util');

const conventionalRecommendedBump = sinon.stub().callsFake((options, cb) => {
if (options.preset === 'angular') return cb(null, { releaseType: 'minor' });
cb(new Error('Something went wrong'));
});

const conventionalChangelog = sinon.stub().callsFake(options => {
const readableStream = new stream.Readable();
readableStream._read = () => {};
process.nextTick(() => {
readableStream.emit('data', 'The changelog');
if (options.releaseCount < 0) readableStream.emit('error', new Error('Something went wrong'));
readableStream.emit('end');
});
return readableStream;
});

const Plugin = proxyquire('.', {
'conventional-recommended-bump': conventionalRecommendedBump,
'conventional-changelog': conventionalChangelog
});
import test from 'bron';
import { strict as assert } from 'assert';
import fs from 'fs';
import path from 'path';
import sinon from 'sinon';
import sh from 'shelljs';
import tmp from 'tmp';
import { factory, runTasks } from 'release-it/test/util';
import Plugin from './index.js';

sh.config.silent = true;

const mkTmpDir = () => {
const dir = tmp.dirSync({ prefix: 'conventional-changelog-' });
return dir.name;
};

const namespace = 'conventional-changelog';
const preset = 'angular';
const infile = 'CHANGES.md';
const git = { tagName: '${version}' };

test('should not throw', async t => {
const options = { [namespace]: { preset }, git, tagTemplate: '${version}' };
const add = (type, file) => {
sh.ShellString(file).toEnd(file);
sh.exec(`git add ${file}`);
sh.exec(`git commit -m "${type}(${file}): ${type} ${file}"`);
};

const setup = () => {
const dir = mkTmpDir();
sh.pushd(dir);
sh.exec(`git init .`);
add('fix', 'foo');
return { dir };
};

test('should not throw', async () => {
const options = { [namespace]: { preset }, git };
const plugin = factory(Plugin, { namespace, options });
await assert.doesNotReject(runTasks(plugin));
});

test('should set changelog', async t => {
const options = { [namespace]: { preset }, git, tagTemplate: '${version}' };
test('should set changelog using recommended bump (minor)', async () => {
setup();

sh.exec(`git tag 1.0.0`);
add('fix', 'bar');
add('feat', 'baz');

const options = { [namespace]: { preset }, git };
const plugin = factory(Plugin, { namespace, options });
await runTasks(plugin);
const { changelog } = plugin.config.getContext();
assert.strictEqual(changelog, 'The changelog');
assert.match(
changelog,
/# \[1\.1\.0\]\(\/compare\/1\.0\.0\.\.\.1\.1\.0\) \([0-9]{4}-[0-9]{2}-[0-9]{2}\)\s*### Bug Fixes\n\n\* \*\*bar:\*\* fix bar [0-9a-f]{7}\n\n\n### Features\n\n\* \*\*baz:\*\* feat baz [0-9a-f]{7}/
);
sh.popd();
});

test('should use recommended bump', async t => {
const options = { [namespace]: { preset }, git, tagTemplate: '${version}' };
test('should set changelog using recommended bump (patch)', async () => {
setup();

sh.exec(`git tag 1.0.0`);
add('fix', 'bar');
add('fix', 'baz');

const options = { [namespace]: { preset }, git };
const plugin = factory(Plugin, { namespace, options });
await runTasks(plugin);
const { version } = plugin.config.getContext();
assert.strictEqual(version, '1.1.0');
const { changelog } = plugin.config.getContext();
assert.match(
changelog,
/# \[1\.0\.1\]\(\/compare\/1\.0\.0\.\.\.1\.0\.1\) \([0-9]{4}-[0-9]{2}-[0-9]{2}\)\s*### Bug Fixes\n\n\* \*\*bar:\*\* fix bar [0-9a-f]{7}\n\* \*\*baz:\*\* fix baz [0-9a-f]{7}/
);
sh.popd();
});

test('should ignore recommended bump (option)', async t => {
const options = { [namespace]: { preset, ignoreRecommendedBump: true }, git, tagTemplate: '${version}' };
test('should ignore recommended bump (option)', async () => {
setup();
add('feat', 'baz');

const options = { [namespace]: { preset, ignoreRecommendedBump: true }, git };
const plugin = factory(Plugin, { namespace, options });
const spy = sinon.spy(plugin, 'generateChangelog');
await runTasks(plugin);
const { version } = plugin.config.getContext();
assert.strictEqual(spy.callCount, 2);
assert.strictEqual(version, '1.0.1');
assert.equal(spy.callCount, 2);
assert.equal(version, '1.0.1');
spy.restore();
});

test('should ignore recommended bump (prelease)', async t => {
const options = { preRelease: 'alpha', [namespace]: { preset }, git, tagTemplate: '${version}' };
test('should ignore recommended bump (prelease)', async () => {
setup();

const options = { preRelease: 'alpha', [namespace]: { preset }, git };
const plugin = factory(Plugin, { namespace, options });
await runTasks(plugin);
const { version } = plugin.config.getContext();
assert.strictEqual(version, '1.0.1-alpha.0');
assert.equal(version, '1.0.1-alpha.0');
});

test('should ignore recommended bump (prelease continuation)', async t => {
const options = { preRelease: 'alpha', [namespace]: { preset }, git, tagTemplate: '${version}' };
test('should ignore recommended bump (prelease continuation)', async () => {
setup();

const options = { preRelease: 'alpha', [namespace]: { preset }, git };
const plugin = factory(Plugin, { namespace, options });
const stub = sinon.stub(plugin, 'getLatestVersion').returns('1.0.1-alpha.0');
await runTasks(plugin);
const { version } = plugin.config.getContext();
assert.strictEqual(version, '1.0.1-alpha.1');
assert.equal(version, '1.0.1-alpha.1');
stub.restore();
});

test('should ignore recommended bump (next prelease)', async t => {
const options = { preRelease: 'beta', [namespace]: { preset }, git, tagTemplate: '${version}' };
test('should ignore recommended bump (next prelease)', async () => {
setup();

const options = { preRelease: 'beta', [namespace]: { preset }, git };
const plugin = factory(Plugin, { namespace, options });
const stub = sinon.stub(plugin, 'getLatestVersion').returns('1.0.1-alpha.1');
await runTasks(plugin);
const { version } = plugin.config.getContext();
assert.strictEqual(version, '1.0.1-beta.0');
assert.equal(version, '1.0.1-beta.0');
stub.restore();
});

test('should use recommended bump (from prelease)', async t => {
const options = { [namespace]: { preset }, git, tagTemplate: '${version}' };
test('should use recommended bump (from prelease)', async () => {
setup();

const options = { [namespace]: { preset }, git };
const plugin = factory(Plugin, { namespace, options });
const stub = sinon.stub(plugin, 'getLatestVersion').returns('1.0.1-beta.0');
await runTasks(plugin);
const { version } = plugin.config.getContext();
assert.strictEqual(version, '1.1.0');
assert.equal(version, '1.0.1');
stub.restore();
});

test('should use provided increment', async t => {
const options = { increment: 'major', [namespace]: { preset }, git, tagTemplate: '${version}' };
test('should use provided increment', async () => {
setup();

const options = { increment: 'major', [namespace]: { preset }, git };
const plugin = factory(Plugin, { namespace, options });
await runTasks(plugin);
const { version } = plugin.config.getContext();
assert.strictEqual(version, '2.0.0');
assert.equal(version, '2.0.0');
});

test('should use provided version', async t => {
const options = { increment: '1.2.3', [namespace]: { preset }, git, tagTemplate: '${version}' };
test('should use provided version', async () => {
setup();

const options = { increment: '1.2.3', [namespace]: { preset }, git };
const plugin = factory(Plugin, { namespace, options });
await runTasks(plugin);
const { version } = plugin.config.getContext();
assert.strictEqual(version, '1.2.3');
assert.equal(version, '1.2.3');
});

test(`should write and update infile (${infile})`, async t => {
const options = { [namespace]: { preset, infile }, git, tagTemplate: '${version}' };
test(`should write and update infile (${infile})`, async () => {
const { dir } = setup();
add('feat', 'bar');

const f = path.join(dir, infile);
const options = { [namespace]: { preset, infile: f }, git };
const plugin = factory(Plugin, { namespace, options });
await runTasks(plugin);
const changelog = fs.readFileSync(infile);
assert.strictEqual(changelog.toString().trim(), 'The changelog');
const changelog = fs.readFileSync(f);
assert.match(
changelog.toString(),
/# \[1\.1\.0\]\(\/compare\/1\.0\.0\.\.\.1\.1\.0\) \([0-9]{4}-[0-9]{2}-[0-9]{2}\)\s*### Bug Fixes\n\n\* \*\*foo:\*\* fix foo [0-9a-f]{7}\n\n\n### Features\n\n\* \*\*bar:\*\* feat bar [0-9a-f]{7}/
);
{
const options = { [namespace]: { preset, infile: f }, git };
const plugin = factory(Plugin, { namespace, options });
sh.exec(`git tag 1.1.0`);
const stub = sinon.stub(plugin, 'getLatestVersion').returns('1.1.0');

add('fix', 'bar');
add('fix', 'baz');

await runTasks(plugin);
const changelog = fs.readFileSync(infile);
assert.strictEqual(changelog.toString().trim(), `The changelog${EOL}${EOL}The changelog`);
const changelog = fs.readFileSync(f);

assert.match(
changelog.toString(),
/## \[1\.1\.1\]\(\/compare\/1\.1\.0\.\.\.1\.1\.1\) \([0-9]{4}-[0-9]{2}-[0-9]{2}\)\s*### Bug Fixes\n\n\* \*\*bar:\*\* fix bar [0-9a-f]{7}\n\* \*\*baz:\*\* fix baz [0-9a-f]{7}\n\n# \[1\.1\.0\]\(\/compare\/1\.0\.0\.\.\.1\.1\.0\) \([0-9]{4}-[0-9]{2}-[0-9]{2}\)\s*### Bug Fixes\n\n\* \*\*foo:\*\* fix foo [0-9a-f]{7}\n\n\n### Features\n\n\* \*\*bar:\*\* feat bar [0-9a-f]{7}/
);

stub.restore();
}
fs.unlinkSync(infile);
});

test('should reject if conventional bump passes error', async t => {
const options = { [namespace]: { preset: 'what?' }, git, tagTemplate: '${version}' };
test('should reject if conventional bump passes error', async () => {
setup();

const options = { [namespace]: { preset: 'what?' }, git };
const plugin = factory(Plugin, { namespace, options });
await assert.rejects(runTasks(plugin), /Something went wrong/);
await assert.rejects(
runTasks(plugin),
'Error: Unable to load the "what?" preset package. Please make sure it\'s installed.'
);
});

test('should reject if conventional changelog has error', async t => {
const options = { [namespace]: { preset, releaseCount: -1 }, git, tagTemplate: '${version}' };
test('should reject if conventional changelog has error', async () => {
const options = { [namespace]: { preset: () => {} }, git };
const plugin = factory(Plugin, { namespace, options });
await assert.rejects(runTasks(plugin), /Something went wrong/);
await assert.rejects(runTasks(plugin), /preset must be string or object with key name/);
});

test('should not write infile in dry run', async t => {
const infile = 'DRYRUN.md';
const options = { 'dry-run': true, [namespace]: { preset, infile }, git, tagTemplate: '${version}' };
test('should not write infile in dry run', async () => {
const { dir } = setup();
const infile = path.join(dir, 'DRYRUN.md');
const options = { 'dry-run': true, [namespace]: { preset, infile }, git };
const plugin = factory(Plugin, { namespace, options });
const spy = sinon.spy(plugin, 'writeChangelog');
await runTasks(plugin);
assert.strictEqual(spy.callCount, 0);
assert.equal(spy.callCount, 0);
assert.throws(() => fs.readFileSync(infile), /no such file/);
});

0 comments on commit 80b99dc

Please sign in to comment.