fix(deps): bump @semantic-release/npm to ^10.0.0-beta.1 (#2670)
This commit is contained in:
+117
-102
@@ -1,7 +1,7 @@
|
||||
import test from 'ava';
|
||||
import {noop} from 'lodash-es';
|
||||
import {stub} from 'sinon';
|
||||
import normalize from '../../lib/plugins/normalize.js';
|
||||
import test from "ava";
|
||||
import { noop } from "lodash-es";
|
||||
import { stub } from "sinon";
|
||||
import normalize from "../../lib/plugins/normalize.js";
|
||||
|
||||
const cwd = process.cwd();
|
||||
|
||||
@@ -10,7 +10,7 @@ test.beforeEach((t) => {
|
||||
t.context.log = stub();
|
||||
t.context.error = stub();
|
||||
t.context.success = stub();
|
||||
t.context.stderr = {write: stub()};
|
||||
t.context.stderr = { write: stub() };
|
||||
t.context.logger = {
|
||||
log: t.context.log,
|
||||
error: t.context.error,
|
||||
@@ -19,98 +19,108 @@ test.beforeEach((t) => {
|
||||
};
|
||||
});
|
||||
|
||||
test('Normalize and load plugin from string', async (t) => {
|
||||
test("Normalize and load plugin from string", async (t) => {
|
||||
const plugin = await normalize(
|
||||
{cwd, options: {}, logger: t.context.logger},
|
||||
'verifyConditions',
|
||||
'./test/fixtures/plugin-noop.cjs',
|
||||
{ cwd, options: {}, logger: t.context.logger },
|
||||
"verifyConditions",
|
||||
"./test/fixtures/plugin-noop.cjs",
|
||||
{}
|
||||
);
|
||||
|
||||
t.is(plugin.pluginName, './test/fixtures/plugin-noop.cjs');
|
||||
t.is(typeof plugin, 'function');
|
||||
t.is(plugin.pluginName, "./test/fixtures/plugin-noop.cjs");
|
||||
t.is(typeof plugin, "function");
|
||||
t.deepEqual(t.context.success.args[0], ['Loaded plugin "verifyConditions" from "./test/fixtures/plugin-noop.cjs"']);
|
||||
});
|
||||
|
||||
test('Normalize and load plugin from object', async (t) => {
|
||||
test("Normalize and load plugin from object", async (t) => {
|
||||
const plugin = await normalize(
|
||||
{cwd, options: {}, logger: t.context.logger},
|
||||
'publish',
|
||||
{path: './test/fixtures/plugin-noop.cjs'},
|
||||
{ cwd, options: {}, logger: t.context.logger },
|
||||
"publish",
|
||||
{ path: "./test/fixtures/plugin-noop.cjs" },
|
||||
{}
|
||||
);
|
||||
|
||||
t.is(plugin.pluginName, './test/fixtures/plugin-noop.cjs');
|
||||
t.is(typeof plugin, 'function');
|
||||
t.is(plugin.pluginName, "./test/fixtures/plugin-noop.cjs");
|
||||
t.is(typeof plugin, "function");
|
||||
t.deepEqual(t.context.success.args[0], ['Loaded plugin "publish" from "./test/fixtures/plugin-noop.cjs"']);
|
||||
});
|
||||
|
||||
test('Normalize and load plugin from a base file path', async (t) => {
|
||||
const plugin = await normalize({cwd, options: {}, logger: t.context.logger}, 'verifyConditions', './plugin-noop.cjs', {
|
||||
'./plugin-noop.cjs': './test/fixtures',
|
||||
});
|
||||
test("Normalize and load plugin from a base file path", async (t) => {
|
||||
const plugin = await normalize(
|
||||
{ cwd, options: {}, logger: t.context.logger },
|
||||
"verifyConditions",
|
||||
"./plugin-noop.cjs",
|
||||
{
|
||||
"./plugin-noop.cjs": "./test/fixtures",
|
||||
}
|
||||
);
|
||||
|
||||
t.is(plugin.pluginName, './plugin-noop.cjs');
|
||||
t.is(typeof plugin, 'function');
|
||||
t.is(plugin.pluginName, "./plugin-noop.cjs");
|
||||
t.is(typeof plugin, "function");
|
||||
t.deepEqual(t.context.success.args[0], [
|
||||
'Loaded plugin "verifyConditions" from "./plugin-noop.cjs" in shareable config "./test/fixtures"',
|
||||
]);
|
||||
});
|
||||
|
||||
test('Wrap plugin in a function that add the "pluginName" to the error"', async (t) => {
|
||||
const plugin = await normalize({cwd, options: {}, logger: t.context.logger}, 'verifyConditions', './plugin-error', {
|
||||
'./plugin-error': './test/fixtures',
|
||||
const plugin = await normalize({ cwd, options: {}, logger: t.context.logger }, "verifyConditions", "./plugin-error", {
|
||||
"./plugin-error": "./test/fixtures",
|
||||
});
|
||||
|
||||
const error = await t.throwsAsync(plugin({options: {}}));
|
||||
const error = await t.throwsAsync(plugin({ options: {} }));
|
||||
|
||||
t.is(error.pluginName, './plugin-error');
|
||||
t.is(error.pluginName, "./plugin-error");
|
||||
});
|
||||
|
||||
test('Wrap plugin in a function that add the "pluginName" to multiple errors"', async (t) => {
|
||||
const plugin = await normalize({cwd, options: {}, logger: t.context.logger}, 'verifyConditions', './plugin-errors', {
|
||||
'./plugin-errors': './test/fixtures',
|
||||
});
|
||||
const plugin = await normalize(
|
||||
{ cwd, options: {}, logger: t.context.logger },
|
||||
"verifyConditions",
|
||||
"./plugin-errors",
|
||||
{
|
||||
"./plugin-errors": "./test/fixtures",
|
||||
}
|
||||
);
|
||||
|
||||
const errors = [...(await t.throwsAsync(plugin({options: {}}))).errors];
|
||||
const errors = [...(await t.throwsAsync(plugin({ options: {} }))).errors];
|
||||
for (const error of errors) {
|
||||
t.is(error.pluginName, './plugin-errors');
|
||||
t.is(error.pluginName, "./plugin-errors");
|
||||
}
|
||||
});
|
||||
|
||||
test('Normalize and load plugin from function', async (t) => {
|
||||
test("Normalize and load plugin from function", async (t) => {
|
||||
const pluginFunction = () => {};
|
||||
const plugin = await normalize({cwd, options: {}, logger: t.context.logger}, '', pluginFunction, {});
|
||||
const plugin = await normalize({ cwd, options: {}, logger: t.context.logger }, "", pluginFunction, {});
|
||||
|
||||
t.is(plugin.pluginName, '[Function: pluginFunction]');
|
||||
t.is(typeof plugin, 'function');
|
||||
t.is(plugin.pluginName, "[Function: pluginFunction]");
|
||||
t.is(typeof plugin, "function");
|
||||
});
|
||||
|
||||
test('Normalize and load plugin that retuns multiple functions', async (t) => {
|
||||
test("Normalize and load plugin that retuns multiple functions", async (t) => {
|
||||
const plugin = await normalize(
|
||||
{cwd, options: {}, logger: t.context.logger},
|
||||
'verifyConditions',
|
||||
'./test/fixtures/multi-plugin.cjs',
|
||||
{ cwd, options: {}, logger: t.context.logger },
|
||||
"verifyConditions",
|
||||
"./test/fixtures/multi-plugin.cjs",
|
||||
{}
|
||||
);
|
||||
|
||||
t.is(typeof plugin, 'function');
|
||||
t.is(typeof plugin, "function");
|
||||
t.deepEqual(t.context.success.args[0], ['Loaded plugin "verifyConditions" from "./test/fixtures/multi-plugin.cjs"']);
|
||||
});
|
||||
|
||||
test('Wrap "analyzeCommits" plugin in a function that validate the output of the plugin', async (t) => {
|
||||
const analyzeCommits = stub().resolves(2);
|
||||
const plugin = await normalize(
|
||||
{cwd, options: {}, stderr: t.context.stderr, logger: t.context.logger},
|
||||
'analyzeCommits',
|
||||
{ cwd, options: {}, stderr: t.context.stderr, logger: t.context.logger },
|
||||
"analyzeCommits",
|
||||
analyzeCommits,
|
||||
{}
|
||||
);
|
||||
|
||||
const error = await t.throwsAsync(plugin({options: {}}));
|
||||
const error = await t.throwsAsync(plugin({ options: {} }));
|
||||
|
||||
t.is(error.code, 'EANALYZECOMMITSOUTPUT');
|
||||
t.is(error.name, 'SemanticReleaseError');
|
||||
t.is(error.code, "EANALYZECOMMITSOUTPUT");
|
||||
t.is(error.name, "SemanticReleaseError");
|
||||
t.truthy(error.message);
|
||||
t.truthy(error.details);
|
||||
t.regex(error.details, /2/);
|
||||
@@ -119,16 +129,16 @@ test('Wrap "analyzeCommits" plugin in a function that validate the output of the
|
||||
test('Wrap "generateNotes" plugin in a function that validate the output of the plugin', async (t) => {
|
||||
const generateNotes = stub().resolves(2);
|
||||
const plugin = await normalize(
|
||||
{cwd, options: {}, stderr: t.context.stderr, logger: t.context.logger},
|
||||
'generateNotes',
|
||||
{ cwd, options: {}, stderr: t.context.stderr, logger: t.context.logger },
|
||||
"generateNotes",
|
||||
generateNotes,
|
||||
{}
|
||||
);
|
||||
|
||||
const error = await t.throwsAsync(plugin({options: {}}));
|
||||
const error = await t.throwsAsync(plugin({ options: {} }));
|
||||
|
||||
t.is(error.code, 'EGENERATENOTESOUTPUT');
|
||||
t.is(error.name, 'SemanticReleaseError');
|
||||
t.is(error.code, "EGENERATENOTESOUTPUT");
|
||||
t.is(error.name, "SemanticReleaseError");
|
||||
t.truthy(error.message);
|
||||
t.truthy(error.details);
|
||||
t.regex(error.details, /2/);
|
||||
@@ -137,16 +147,16 @@ test('Wrap "generateNotes" plugin in a function that validate the output of the
|
||||
test('Wrap "publish" plugin in a function that validate the output of the plugin', async (t) => {
|
||||
const publish = stub().resolves(2);
|
||||
const plugin = await normalize(
|
||||
{cwd, options: {}, stderr: t.context.stderr, logger: t.context.logger},
|
||||
'publish',
|
||||
{ cwd, options: {}, stderr: t.context.stderr, logger: t.context.logger },
|
||||
"publish",
|
||||
publish,
|
||||
{}
|
||||
);
|
||||
|
||||
const error = await t.throwsAsync(plugin({options: {}}));
|
||||
const error = await t.throwsAsync(plugin({ options: {} }));
|
||||
|
||||
t.is(error.code, 'EPUBLISHOUTPUT');
|
||||
t.is(error.name, 'SemanticReleaseError');
|
||||
t.is(error.code, "EPUBLISHOUTPUT");
|
||||
t.is(error.name, "SemanticReleaseError");
|
||||
t.truthy(error.message);
|
||||
t.truthy(error.details);
|
||||
t.regex(error.details, /2/);
|
||||
@@ -155,16 +165,16 @@ test('Wrap "publish" plugin in a function that validate the output of the plugin
|
||||
test('Wrap "addChannel" plugin in a function that validate the output of the plugin', async (t) => {
|
||||
const addChannel = stub().resolves(2);
|
||||
const plugin = await normalize(
|
||||
{cwd, options: {}, stderr: t.context.stderr, logger: t.context.logger},
|
||||
'addChannel',
|
||||
{ cwd, options: {}, stderr: t.context.stderr, logger: t.context.logger },
|
||||
"addChannel",
|
||||
addChannel,
|
||||
{}
|
||||
);
|
||||
|
||||
const error = await t.throwsAsync(plugin({options: {}}));
|
||||
const error = await t.throwsAsync(plugin({ options: {} }));
|
||||
|
||||
t.is(error.code, 'EADDCHANNELOUTPUT');
|
||||
t.is(error.name, 'SemanticReleaseError');
|
||||
t.is(error.code, "EADDCHANNELOUTPUT");
|
||||
t.is(error.name, "SemanticReleaseError");
|
||||
t.truthy(error.message);
|
||||
t.truthy(error.details);
|
||||
t.regex(error.details, /2/);
|
||||
@@ -172,60 +182,60 @@ test('Wrap "addChannel" plugin in a function that validate the output of the plu
|
||||
|
||||
test('Plugin is called with "pluginConfig" (with object definition) and input', async (t) => {
|
||||
const pluginFunction = stub().resolves();
|
||||
const pluginConf = {path: pluginFunction, conf: 'confValue'};
|
||||
const options = {global: 'globalValue'};
|
||||
const plugin = await normalize({cwd, options, logger: t.context.logger}, '', pluginConf, {});
|
||||
await plugin({options: {}, param: 'param'});
|
||||
const pluginConf = { path: pluginFunction, conf: "confValue" };
|
||||
const options = { global: "globalValue" };
|
||||
const plugin = await normalize({ cwd, options, logger: t.context.logger }, "", pluginConf, {});
|
||||
await plugin({ options: {}, param: "param" });
|
||||
|
||||
t.true(
|
||||
pluginFunction.calledWithMatch(
|
||||
{conf: 'confValue', global: 'globalValue'},
|
||||
{param: 'param', logger: t.context.logger}
|
||||
{ conf: "confValue", global: "globalValue" },
|
||||
{ param: "param", logger: t.context.logger }
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
test('Plugin is called with "pluginConfig" (with array definition) and input', async (t) => {
|
||||
const pluginFunction = stub().resolves();
|
||||
const pluginConf = [pluginFunction, {conf: 'confValue'}];
|
||||
const options = {global: 'globalValue'};
|
||||
const plugin = await normalize({cwd, options, logger: t.context.logger}, '', pluginConf, {});
|
||||
await plugin({options: {}, param: 'param'});
|
||||
const pluginConf = [pluginFunction, { conf: "confValue" }];
|
||||
const options = { global: "globalValue" };
|
||||
const plugin = await normalize({ cwd, options, logger: t.context.logger }, "", pluginConf, {});
|
||||
await plugin({ options: {}, param: "param" });
|
||||
|
||||
t.true(
|
||||
pluginFunction.calledWithMatch(
|
||||
{conf: 'confValue', global: 'globalValue'},
|
||||
{param: 'param', logger: t.context.logger}
|
||||
{ conf: "confValue", global: "globalValue" },
|
||||
{ param: "param", logger: t.context.logger }
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
test('Prevent plugins to modify "pluginConfig"', async (t) => {
|
||||
const pluginFunction = stub().callsFake((pluginConfig) => {
|
||||
pluginConfig.conf.subConf = 'otherConf';
|
||||
pluginConfig.conf.subConf = "otherConf";
|
||||
});
|
||||
const pluginConf = {path: pluginFunction, conf: {subConf: 'originalConf'}};
|
||||
const options = {globalConf: {globalSubConf: 'originalGlobalConf'}};
|
||||
const plugin = await normalize({cwd, options, logger: t.context.logger}, '', pluginConf, {});
|
||||
await plugin({options: {}});
|
||||
const pluginConf = { path: pluginFunction, conf: { subConf: "originalConf" } };
|
||||
const options = { globalConf: { globalSubConf: "originalGlobalConf" } };
|
||||
const plugin = await normalize({ cwd, options, logger: t.context.logger }, "", pluginConf, {});
|
||||
await plugin({ options: {} });
|
||||
|
||||
t.is(pluginConf.conf.subConf, 'originalConf');
|
||||
t.is(options.globalConf.globalSubConf, 'originalGlobalConf');
|
||||
t.is(pluginConf.conf.subConf, "originalConf");
|
||||
t.is(options.globalConf.globalSubConf, "originalGlobalConf");
|
||||
});
|
||||
|
||||
test('Prevent plugins to modify its input', async (t) => {
|
||||
test("Prevent plugins to modify its input", async (t) => {
|
||||
const pluginFunction = stub().callsFake((pluginConfig, options) => {
|
||||
options.param.subParam = 'otherParam';
|
||||
options.param.subParam = "otherParam";
|
||||
});
|
||||
const input = {param: {subParam: 'originalSubParam'}, options: {}};
|
||||
const plugin = await normalize({cwd, options: {}, logger: t.context.logger}, '', pluginFunction, {});
|
||||
const input = { param: { subParam: "originalSubParam" }, options: {} };
|
||||
const plugin = await normalize({ cwd, options: {}, logger: t.context.logger }, "", pluginFunction, {});
|
||||
await plugin(input);
|
||||
|
||||
t.is(input.param.subParam, 'originalSubParam');
|
||||
t.is(input.param.subParam, "originalSubParam");
|
||||
});
|
||||
|
||||
test('Return noop if the plugin is not defined', async (t) => {
|
||||
const plugin = await normalize({cwd, options: {}, logger: t.context.logger});
|
||||
test("Return noop if the plugin is not defined", async (t) => {
|
||||
const plugin = await normalize({ cwd, options: {}, logger: t.context.logger });
|
||||
|
||||
t.is(plugin, noop);
|
||||
});
|
||||
@@ -233,12 +243,12 @@ test('Return noop if the plugin is not defined', async (t) => {
|
||||
test('Always pass a defined "pluginConfig" for plugin defined with string', async (t) => {
|
||||
// Call the normalize function with the path of a plugin that returns its config
|
||||
const plugin = await normalize(
|
||||
{cwd, options: {}, logger: t.context.logger},
|
||||
'',
|
||||
'./test/fixtures/plugin-result-config',
|
||||
{ cwd, options: {}, logger: t.context.logger },
|
||||
"",
|
||||
"./test/fixtures/plugin-result-config",
|
||||
{}
|
||||
);
|
||||
const pluginResult = await plugin({options: {}});
|
||||
const pluginResult = await plugin({ options: {} });
|
||||
|
||||
t.deepEqual(pluginResult.pluginConfig, {});
|
||||
});
|
||||
@@ -246,33 +256,38 @@ test('Always pass a defined "pluginConfig" for plugin defined with string', asyn
|
||||
test('Always pass a defined "pluginConfig" for plugin defined with path', async (t) => {
|
||||
// Call the normalize function with the path of a plugin that returns its config
|
||||
const plugin = await normalize(
|
||||
{cwd, options: {}, logger: t.context.logger},
|
||||
'',
|
||||
{path: './test/fixtures/plugin-result-config'},
|
||||
{ cwd, options: {}, logger: t.context.logger },
|
||||
"",
|
||||
{ path: "./test/fixtures/plugin-result-config" },
|
||||
{}
|
||||
);
|
||||
const pluginResult = await plugin({options: {}});
|
||||
const pluginResult = await plugin({ options: {} });
|
||||
|
||||
t.deepEqual(pluginResult.pluginConfig, {});
|
||||
});
|
||||
|
||||
test('Throws an error if the plugin return an object without the expected plugin function', async (t) => {
|
||||
test("Throws an error if the plugin return an object without the expected plugin function", async (t) => {
|
||||
const error = await t.throwsAsync(() =>
|
||||
normalize({cwd, options: {}, logger: t.context.logger}, 'nonExistentPlugin', './test/fixtures/multi-plugin.cjs', {})
|
||||
normalize(
|
||||
{ cwd, options: {}, logger: t.context.logger },
|
||||
"nonExistentPlugin",
|
||||
"./test/fixtures/multi-plugin.cjs",
|
||||
{}
|
||||
)
|
||||
);
|
||||
|
||||
t.is(error.code, 'EPLUGIN');
|
||||
t.is(error.name, 'SemanticReleaseError');
|
||||
t.is(error.code, "EPLUGIN");
|
||||
t.is(error.name, "SemanticReleaseError");
|
||||
t.truthy(error.message);
|
||||
t.truthy(error.details);
|
||||
});
|
||||
|
||||
test('Throws an error if the plugin is not found', async (t) => {
|
||||
test("Throws an error if the plugin is not found", async (t) => {
|
||||
await t.throwsAsync(
|
||||
() => normalize({cwd, options: {}, logger: t.context.logger}, 'nonExistentPlugin', 'non-existing-path', {}),
|
||||
() => normalize({ cwd, options: {}, logger: t.context.logger }, "nonExistentPlugin", "non-existing-path", {}),
|
||||
{
|
||||
message: /Cannot find module 'non-existing-path'/,
|
||||
code: 'MODULE_NOT_FOUND',
|
||||
code: "MODULE_NOT_FOUND",
|
||||
instanceOf: Error,
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import test from 'ava';
|
||||
import {stub} from 'sinon';
|
||||
import AggregateError from 'aggregate-error';
|
||||
import pipeline from '../../lib/plugins/pipeline.js';
|
||||
import test from "ava";
|
||||
import { stub } from "sinon";
|
||||
import AggregateError from "aggregate-error";
|
||||
import pipeline from "../../lib/plugins/pipeline.js";
|
||||
|
||||
test('Execute each function in series passing the same input', async (t) => {
|
||||
test("Execute each function in series passing the same input", async (t) => {
|
||||
const step1 = stub().resolves(1);
|
||||
const step2 = stub().resolves(2);
|
||||
const step3 = stub().resolves(3);
|
||||
@@ -25,7 +25,7 @@ test('Execute each function in series passing a transformed input from "getNextI
|
||||
const step4 = stub().resolves(4);
|
||||
const getNextInput = (lastResult, result) => lastResult + result;
|
||||
|
||||
const result = await pipeline([step1, step2, step3, step4], {settleAll: false, getNextInput})(0);
|
||||
const result = await pipeline([step1, step2, step3, step4], { settleAll: false, getNextInput })(0);
|
||||
|
||||
t.deepEqual(result, [1, 2, 3, 4]);
|
||||
t.true(step1.calledWith(0));
|
||||
@@ -44,7 +44,7 @@ test('Execute each function in series passing the "lastResult" and "result" to "
|
||||
const step4 = stub().resolves(4);
|
||||
const getNextInput = stub().returnsArg(0);
|
||||
|
||||
const result = await pipeline([step1, step2, step3, step4], {settleAll: false, getNextInput})(5);
|
||||
const result = await pipeline([step1, step2, step3, step4], { settleAll: false, getNextInput })(5);
|
||||
|
||||
t.deepEqual(result, [1, 2, 3, 4]);
|
||||
t.deepEqual(getNextInput.args, [
|
||||
@@ -63,7 +63,7 @@ test('Execute each function in series calling "transform" to modify the results'
|
||||
const getNextInput = stub().returnsArg(0);
|
||||
const transform = stub().callsFake((result) => result + 1);
|
||||
|
||||
const result = await pipeline([step1, step2, step3, step4], {getNextInput, transform})(5);
|
||||
const result = await pipeline([step1, step2, step3, step4], { getNextInput, transform })(5);
|
||||
|
||||
t.deepEqual(result, [1 + 1, 2 + 1, 3 + 1, 4 + 1]);
|
||||
t.deepEqual(getNextInput.args, [
|
||||
@@ -82,7 +82,7 @@ test('Execute each function in series calling "transform" to modify the results
|
||||
const getNextInput = stub().returnsArg(0);
|
||||
const transform = stub().callsFake((result) => result + 1);
|
||||
|
||||
const result = await pipeline([step1, step2, step3, step4], {settleAll: true, getNextInput, transform})(5);
|
||||
const result = await pipeline([step1, step2, step3, step4], { settleAll: true, getNextInput, transform })(5);
|
||||
|
||||
t.deepEqual(result, [1 + 1, 2 + 1, 3 + 1, 4 + 1]);
|
||||
t.deepEqual(getNextInput.args, [
|
||||
@@ -93,24 +93,24 @@ test('Execute each function in series calling "transform" to modify the results
|
||||
]);
|
||||
});
|
||||
|
||||
test('Stop execution and throw error if a step rejects', async (t) => {
|
||||
test("Stop execution and throw error if a step rejects", async (t) => {
|
||||
const step1 = stub().resolves(1);
|
||||
const step2 = stub().rejects(new Error('test error'));
|
||||
const step2 = stub().rejects(new Error("test error"));
|
||||
const step3 = stub().resolves(3);
|
||||
|
||||
const error = await t.throwsAsync(pipeline([step1, step2, step3])(0), {
|
||||
instanceOf: Error,
|
||||
message: 'test error',
|
||||
message: "test error",
|
||||
});
|
||||
t.is(error.message, 'test error');
|
||||
t.is(error.message, "test error");
|
||||
t.true(step1.calledWith(0));
|
||||
t.true(step2.calledWith(0));
|
||||
t.true(step3.notCalled);
|
||||
});
|
||||
|
||||
test('Throw all errors from the first step throwing an AggregateError', async (t) => {
|
||||
const error1 = new Error('test error 1');
|
||||
const error2 = new Error('test error 2');
|
||||
test("Throw all errors from the first step throwing an AggregateError", async (t) => {
|
||||
const error1 = new Error("test error 1");
|
||||
const error2 = new Error("test error 2");
|
||||
|
||||
const step1 = stub().resolves(1);
|
||||
const step2 = stub().rejects(new AggregateError([error1, error2]));
|
||||
@@ -124,14 +124,14 @@ test('Throw all errors from the first step throwing an AggregateError', async (t
|
||||
t.true(step3.notCalled);
|
||||
});
|
||||
|
||||
test('Execute all even if a Promise rejects', async (t) => {
|
||||
const error1 = new Error('test error 1');
|
||||
const error2 = new Error('test error 2');
|
||||
test("Execute all even if a Promise rejects", async (t) => {
|
||||
const error1 = new Error("test error 1");
|
||||
const error2 = new Error("test error 2");
|
||||
const step1 = stub().resolves(1);
|
||||
const step2 = stub().rejects(error1);
|
||||
const step3 = stub().rejects(error2);
|
||||
|
||||
const error = await t.throwsAsync(pipeline([step1, step2, step3], {settleAll: true})(0));
|
||||
const error = await t.throwsAsync(pipeline([step1, step2, step3], { settleAll: true })(0));
|
||||
|
||||
t.deepEqual([...error.errors], [error1, error2]);
|
||||
t.true(step1.calledWith(0));
|
||||
@@ -139,31 +139,31 @@ test('Execute all even if a Promise rejects', async (t) => {
|
||||
t.true(step3.calledWith(0));
|
||||
});
|
||||
|
||||
test('Throw all errors from all steps throwing an AggregateError', async (t) => {
|
||||
const error1 = new Error('test error 1');
|
||||
const error2 = new Error('test error 2');
|
||||
const error3 = new Error('test error 3');
|
||||
const error4 = new Error('test error 4');
|
||||
test("Throw all errors from all steps throwing an AggregateError", async (t) => {
|
||||
const error1 = new Error("test error 1");
|
||||
const error2 = new Error("test error 2");
|
||||
const error3 = new Error("test error 3");
|
||||
const error4 = new Error("test error 4");
|
||||
const step1 = stub().rejects(new AggregateError([error1, error2]));
|
||||
const step2 = stub().rejects(new AggregateError([error3, error4]));
|
||||
|
||||
const error = await t.throwsAsync(pipeline([step1, step2], {settleAll: true})(0));
|
||||
const error = await t.throwsAsync(pipeline([step1, step2], { settleAll: true })(0));
|
||||
|
||||
t.deepEqual([...error.errors], [error1, error2, error3, error4]);
|
||||
t.true(step1.calledWith(0));
|
||||
t.true(step2.calledWith(0));
|
||||
});
|
||||
|
||||
test('Execute each function in series passing a transformed input even if a step rejects', async (t) => {
|
||||
const error2 = new Error('test error 2');
|
||||
const error3 = new Error('test error 3');
|
||||
test("Execute each function in series passing a transformed input even if a step rejects", async (t) => {
|
||||
const error2 = new Error("test error 2");
|
||||
const error3 = new Error("test error 3");
|
||||
const step1 = stub().resolves(1);
|
||||
const step2 = stub().rejects(error2);
|
||||
const step3 = stub().rejects(error3);
|
||||
const step4 = stub().resolves(4);
|
||||
const getNextInput = (previousResult, result) => previousResult + result;
|
||||
|
||||
const error = await t.throwsAsync(pipeline([step1, step2, step3, step4], {settleAll: true, getNextInput})(0));
|
||||
const error = await t.throwsAsync(pipeline([step1, step2, step3, step4], { settleAll: true, getNextInput })(0));
|
||||
|
||||
t.deepEqual([...error.errors], [error2, error3]);
|
||||
t.true(step1.calledWith(0));
|
||||
|
||||
+163
-157
@@ -1,9 +1,9 @@
|
||||
import path from 'path';
|
||||
import test from 'ava';
|
||||
import {copy, outputFile} from 'fs-extra';
|
||||
import {stub} from 'sinon';
|
||||
import {temporaryDirectory} from 'tempy';
|
||||
import getPlugins from '../../lib/plugins/index.js';
|
||||
import path from "path";
|
||||
import test from "ava";
|
||||
import { copy, outputFile } from "fs-extra";
|
||||
import { stub } from "sinon";
|
||||
import { temporaryDirectory } from "tempy";
|
||||
import getPlugins from "../../lib/plugins/index.js";
|
||||
|
||||
// Save the current working directory
|
||||
const cwd = process.cwd();
|
||||
@@ -12,32 +12,32 @@ test.beforeEach((t) => {
|
||||
// Stub the logger functions
|
||||
t.context.log = stub();
|
||||
t.context.success = stub();
|
||||
t.context.logger = {log: t.context.log, success: t.context.success, scope: () => t.context.logger};
|
||||
t.context.logger = { log: t.context.log, success: t.context.success, scope: () => t.context.logger };
|
||||
});
|
||||
|
||||
test('Export default plugins', async (t) => {
|
||||
const plugins = await getPlugins({cwd, options: {}, logger: t.context.logger}, {});
|
||||
test("Export default plugins", async (t) => {
|
||||
const plugins = await getPlugins({ cwd, options: {}, logger: t.context.logger }, {});
|
||||
|
||||
// Verify the module returns a function for each plugin
|
||||
t.is(typeof plugins.verifyConditions, 'function');
|
||||
t.is(typeof plugins.analyzeCommits, 'function');
|
||||
t.is(typeof plugins.verifyRelease, 'function');
|
||||
t.is(typeof plugins.generateNotes, 'function');
|
||||
t.is(typeof plugins.prepare, 'function');
|
||||
t.is(typeof plugins.publish, 'function');
|
||||
t.is(typeof plugins.success, 'function');
|
||||
t.is(typeof plugins.fail, 'function');
|
||||
t.is(typeof plugins.verifyConditions, "function");
|
||||
t.is(typeof plugins.analyzeCommits, "function");
|
||||
t.is(typeof plugins.verifyRelease, "function");
|
||||
t.is(typeof plugins.generateNotes, "function");
|
||||
t.is(typeof plugins.prepare, "function");
|
||||
t.is(typeof plugins.publish, "function");
|
||||
t.is(typeof plugins.success, "function");
|
||||
t.is(typeof plugins.fail, "function");
|
||||
});
|
||||
|
||||
test('Export plugins based on steps config', async (t) => {
|
||||
test("Export plugins based on steps config", async (t) => {
|
||||
const plugins = await getPlugins(
|
||||
{
|
||||
cwd,
|
||||
logger: t.context.logger,
|
||||
options: {
|
||||
verifyConditions: ['./test/fixtures/plugin-noop.cjs', {path: './test/fixtures/plugin-noop.cjs'}],
|
||||
generateNotes: './test/fixtures/plugin-noop.cjs',
|
||||
analyzeCommits: {path: './test/fixtures/plugin-noop.cjs'},
|
||||
verifyConditions: ["./test/fixtures/plugin-noop.cjs", { path: "./test/fixtures/plugin-noop.cjs" }],
|
||||
generateNotes: "./test/fixtures/plugin-noop.cjs",
|
||||
analyzeCommits: { path: "./test/fixtures/plugin-noop.cjs" },
|
||||
verifyRelease: () => {},
|
||||
},
|
||||
},
|
||||
@@ -45,161 +45,161 @@ test('Export plugins based on steps config', async (t) => {
|
||||
);
|
||||
|
||||
// Verify the module returns a function for each plugin
|
||||
t.is(typeof plugins.verifyConditions, 'function');
|
||||
t.is(typeof plugins.analyzeCommits, 'function');
|
||||
t.is(typeof plugins.verifyRelease, 'function');
|
||||
t.is(typeof plugins.generateNotes, 'function');
|
||||
t.is(typeof plugins.prepare, 'function');
|
||||
t.is(typeof plugins.publish, 'function');
|
||||
t.is(typeof plugins.success, 'function');
|
||||
t.is(typeof plugins.fail, 'function');
|
||||
t.is(typeof plugins.verifyConditions, "function");
|
||||
t.is(typeof plugins.analyzeCommits, "function");
|
||||
t.is(typeof plugins.verifyRelease, "function");
|
||||
t.is(typeof plugins.generateNotes, "function");
|
||||
t.is(typeof plugins.prepare, "function");
|
||||
t.is(typeof plugins.publish, "function");
|
||||
t.is(typeof plugins.success, "function");
|
||||
t.is(typeof plugins.fail, "function");
|
||||
});
|
||||
|
||||
test('Export plugins based on "plugins" config (array)', async (t) => {
|
||||
const plugin1 = {verifyConditions: stub(), publish: stub()};
|
||||
const plugin2 = {verifyConditions: stub(), verifyRelease: stub()};
|
||||
const plugin1 = { verifyConditions: stub(), publish: stub() };
|
||||
const plugin2 = { verifyConditions: stub(), verifyRelease: stub() };
|
||||
const plugins = await getPlugins(
|
||||
{cwd, logger: t.context.logger, options: {plugins: [plugin1, [plugin2, {}]], verifyRelease: () => {}}},
|
||||
{ cwd, logger: t.context.logger, options: { plugins: [plugin1, [plugin2, {}]], verifyRelease: () => {} } },
|
||||
{}
|
||||
);
|
||||
await plugins.verifyConditions({options: {}});
|
||||
await plugins.verifyConditions({ options: {} });
|
||||
t.true(plugin1.verifyConditions.calledOnce);
|
||||
t.true(plugin2.verifyConditions.calledOnce);
|
||||
|
||||
await plugins.publish({options: {}});
|
||||
await plugins.publish({ options: {} });
|
||||
t.true(plugin1.publish.calledOnce);
|
||||
|
||||
await plugins.verifyRelease({options: {}});
|
||||
await plugins.verifyRelease({ options: {} });
|
||||
t.true(plugin2.verifyRelease.notCalled);
|
||||
|
||||
// Verify the module returns a function for each plugin
|
||||
t.is(typeof plugins.verifyConditions, 'function');
|
||||
t.is(typeof plugins.analyzeCommits, 'function');
|
||||
t.is(typeof plugins.verifyRelease, 'function');
|
||||
t.is(typeof plugins.generateNotes, 'function');
|
||||
t.is(typeof plugins.prepare, 'function');
|
||||
t.is(typeof plugins.publish, 'function');
|
||||
t.is(typeof plugins.success, 'function');
|
||||
t.is(typeof plugins.fail, 'function');
|
||||
t.is(typeof plugins.verifyConditions, "function");
|
||||
t.is(typeof plugins.analyzeCommits, "function");
|
||||
t.is(typeof plugins.verifyRelease, "function");
|
||||
t.is(typeof plugins.generateNotes, "function");
|
||||
t.is(typeof plugins.prepare, "function");
|
||||
t.is(typeof plugins.publish, "function");
|
||||
t.is(typeof plugins.success, "function");
|
||||
t.is(typeof plugins.fail, "function");
|
||||
});
|
||||
|
||||
test('Export plugins based on "plugins" config (single definition)', async (t) => {
|
||||
const plugin1 = {verifyConditions: stub(), publish: stub()};
|
||||
const plugins = await getPlugins({cwd, logger: t.context.logger, options: {plugins: plugin1}}, {});
|
||||
const plugin1 = { verifyConditions: stub(), publish: stub() };
|
||||
const plugins = await getPlugins({ cwd, logger: t.context.logger, options: { plugins: plugin1 } }, {});
|
||||
|
||||
await plugins.verifyConditions({options: {}});
|
||||
await plugins.verifyConditions({ options: {} });
|
||||
t.true(plugin1.verifyConditions.calledOnce);
|
||||
|
||||
await plugins.publish({options: {}});
|
||||
await plugins.publish({ options: {} });
|
||||
t.true(plugin1.publish.calledOnce);
|
||||
|
||||
// Verify the module returns a function for each plugin
|
||||
t.is(typeof plugins.verifyConditions, 'function');
|
||||
t.is(typeof plugins.analyzeCommits, 'function');
|
||||
t.is(typeof plugins.verifyRelease, 'function');
|
||||
t.is(typeof plugins.generateNotes, 'function');
|
||||
t.is(typeof plugins.prepare, 'function');
|
||||
t.is(typeof plugins.publish, 'function');
|
||||
t.is(typeof plugins.success, 'function');
|
||||
t.is(typeof plugins.fail, 'function');
|
||||
t.is(typeof plugins.verifyConditions, "function");
|
||||
t.is(typeof plugins.analyzeCommits, "function");
|
||||
t.is(typeof plugins.verifyRelease, "function");
|
||||
t.is(typeof plugins.generateNotes, "function");
|
||||
t.is(typeof plugins.prepare, "function");
|
||||
t.is(typeof plugins.publish, "function");
|
||||
t.is(typeof plugins.success, "function");
|
||||
t.is(typeof plugins.fail, "function");
|
||||
});
|
||||
|
||||
test('Merge global options, "plugins" options and step options', async (t) => {
|
||||
const plugin1 = [{verifyConditions: stub(), publish: stub()}, {pluginOpt1: 'plugin1'}];
|
||||
const plugin2 = [{verifyConditions: stub()}, {pluginOpt2: 'plugin2'}];
|
||||
const plugin3 = [stub(), {pluginOpt3: 'plugin3'}];
|
||||
const plugin1 = [{ verifyConditions: stub(), publish: stub() }, { pluginOpt1: "plugin1" }];
|
||||
const plugin2 = [{ verifyConditions: stub() }, { pluginOpt2: "plugin2" }];
|
||||
const plugin3 = [stub(), { pluginOpt3: "plugin3" }];
|
||||
const plugins = await getPlugins(
|
||||
{
|
||||
cwd,
|
||||
logger: t.context.logger,
|
||||
options: {globalOpt: 'global', plugins: [plugin1, plugin2], verifyRelease: [plugin3]},
|
||||
options: { globalOpt: "global", plugins: [plugin1, plugin2], verifyRelease: [plugin3] },
|
||||
},
|
||||
{}
|
||||
);
|
||||
|
||||
await plugins.verifyConditions({options: {}});
|
||||
t.deepEqual(plugin1[0].verifyConditions.args[0][0], {globalOpt: 'global', pluginOpt1: 'plugin1'});
|
||||
t.deepEqual(plugin2[0].verifyConditions.args[0][0], {globalOpt: 'global', pluginOpt2: 'plugin2'});
|
||||
await plugins.verifyConditions({ options: {} });
|
||||
t.deepEqual(plugin1[0].verifyConditions.args[0][0], { globalOpt: "global", pluginOpt1: "plugin1" });
|
||||
t.deepEqual(plugin2[0].verifyConditions.args[0][0], { globalOpt: "global", pluginOpt2: "plugin2" });
|
||||
|
||||
await plugins.publish({options: {}});
|
||||
t.deepEqual(plugin1[0].publish.args[0][0], {globalOpt: 'global', pluginOpt1: 'plugin1'});
|
||||
await plugins.publish({ options: {} });
|
||||
t.deepEqual(plugin1[0].publish.args[0][0], { globalOpt: "global", pluginOpt1: "plugin1" });
|
||||
|
||||
await plugins.verifyRelease({options: {}});
|
||||
t.deepEqual(plugin3[0].args[0][0], {globalOpt: 'global', pluginOpt3: 'plugin3'});
|
||||
await plugins.verifyRelease({ options: {} });
|
||||
t.deepEqual(plugin3[0].args[0][0], { globalOpt: "global", pluginOpt3: "plugin3" });
|
||||
});
|
||||
|
||||
test('Unknown steps of plugins configured in "plugins" are ignored', async (t) => {
|
||||
const plugin1 = {verifyConditions: () => {}, unknown: () => {}};
|
||||
const plugins = await getPlugins({cwd, logger: t.context.logger, options: {plugins: [plugin1]}}, {});
|
||||
const plugin1 = { verifyConditions: () => {}, unknown: () => {} };
|
||||
const plugins = await getPlugins({ cwd, logger: t.context.logger, options: { plugins: [plugin1] } }, {});
|
||||
|
||||
t.is(typeof plugins.verifyConditions, 'function');
|
||||
t.is(typeof plugins.verifyConditions, "function");
|
||||
t.is(plugins.unknown, undefined);
|
||||
});
|
||||
|
||||
test('Export plugins loaded from the dependency of a shareable config module', async (t) => {
|
||||
test("Export plugins loaded from the dependency of a shareable config module", async (t) => {
|
||||
const cwd = temporaryDirectory();
|
||||
await copy(
|
||||
'./test/fixtures/plugin-noop.cjs',
|
||||
path.resolve(cwd, 'node_modules/shareable-config/node_modules/custom-plugin/index.js')
|
||||
"./test/fixtures/plugin-noop.cjs",
|
||||
path.resolve(cwd, "node_modules/shareable-config/node_modules/custom-plugin/index.js")
|
||||
);
|
||||
await outputFile(path.resolve(cwd, 'node_modules/shareable-config/index.js'), '');
|
||||
await outputFile(path.resolve(cwd, "node_modules/shareable-config/index.js"), "");
|
||||
|
||||
const plugins = await getPlugins(
|
||||
{
|
||||
cwd,
|
||||
logger: t.context.logger,
|
||||
options: {
|
||||
verifyConditions: ['custom-plugin', {path: 'custom-plugin'}],
|
||||
generateNotes: 'custom-plugin',
|
||||
analyzeCommits: {path: 'custom-plugin'},
|
||||
verifyConditions: ["custom-plugin", { path: "custom-plugin" }],
|
||||
generateNotes: "custom-plugin",
|
||||
analyzeCommits: { path: "custom-plugin" },
|
||||
verifyRelease: () => {},
|
||||
},
|
||||
},
|
||||
{'custom-plugin': 'shareable-config'}
|
||||
{ "custom-plugin": "shareable-config" }
|
||||
);
|
||||
|
||||
// Verify the module returns a function for each plugin
|
||||
t.is(typeof plugins.verifyConditions, 'function');
|
||||
t.is(typeof plugins.analyzeCommits, 'function');
|
||||
t.is(typeof plugins.verifyRelease, 'function');
|
||||
t.is(typeof plugins.generateNotes, 'function');
|
||||
t.is(typeof plugins.prepare, 'function');
|
||||
t.is(typeof plugins.publish, 'function');
|
||||
t.is(typeof plugins.success, 'function');
|
||||
t.is(typeof plugins.fail, 'function');
|
||||
t.is(typeof plugins.verifyConditions, "function");
|
||||
t.is(typeof plugins.analyzeCommits, "function");
|
||||
t.is(typeof plugins.verifyRelease, "function");
|
||||
t.is(typeof plugins.generateNotes, "function");
|
||||
t.is(typeof plugins.prepare, "function");
|
||||
t.is(typeof plugins.publish, "function");
|
||||
t.is(typeof plugins.success, "function");
|
||||
t.is(typeof plugins.fail, "function");
|
||||
});
|
||||
|
||||
test('Export plugins loaded from the dependency of a shareable config file', async (t) => {
|
||||
test("Export plugins loaded from the dependency of a shareable config file", async (t) => {
|
||||
const cwd = temporaryDirectory();
|
||||
await copy('./test/fixtures/plugin-noop.cjs', path.resolve(cwd, 'plugin/plugin-noop.cjs'));
|
||||
await outputFile(path.resolve(cwd, 'shareable-config.js'), '');
|
||||
await copy("./test/fixtures/plugin-noop.cjs", path.resolve(cwd, "plugin/plugin-noop.cjs"));
|
||||
await outputFile(path.resolve(cwd, "shareable-config.js"), "");
|
||||
|
||||
const plugins = await getPlugins(
|
||||
{
|
||||
cwd,
|
||||
logger: t.context.logger,
|
||||
options: {
|
||||
verifyConditions: ['./plugin/plugin-noop.cjs', {path: './plugin/plugin-noop.cjs'}],
|
||||
generateNotes: './plugin/plugin-noop.cjs',
|
||||
analyzeCommits: {path: './plugin/plugin-noop.cjs'},
|
||||
verifyConditions: ["./plugin/plugin-noop.cjs", { path: "./plugin/plugin-noop.cjs" }],
|
||||
generateNotes: "./plugin/plugin-noop.cjs",
|
||||
analyzeCommits: { path: "./plugin/plugin-noop.cjs" },
|
||||
verifyRelease: () => {},
|
||||
},
|
||||
},
|
||||
{'./plugin/plugin-noop': './shareable-config.js'}
|
||||
{ "./plugin/plugin-noop": "./shareable-config.js" }
|
||||
);
|
||||
|
||||
// Verify the module returns a function for each plugin
|
||||
t.is(typeof plugins.verifyConditions, 'function');
|
||||
t.is(typeof plugins.analyzeCommits, 'function');
|
||||
t.is(typeof plugins.verifyRelease, 'function');
|
||||
t.is(typeof plugins.generateNotes, 'function');
|
||||
t.is(typeof plugins.prepare, 'function');
|
||||
t.is(typeof plugins.publish, 'function');
|
||||
t.is(typeof plugins.success, 'function');
|
||||
t.is(typeof plugins.fail, 'function');
|
||||
t.is(typeof plugins.verifyConditions, "function");
|
||||
t.is(typeof plugins.analyzeCommits, "function");
|
||||
t.is(typeof plugins.verifyRelease, "function");
|
||||
t.is(typeof plugins.generateNotes, "function");
|
||||
t.is(typeof plugins.prepare, "function");
|
||||
t.is(typeof plugins.publish, "function");
|
||||
t.is(typeof plugins.success, "function");
|
||||
t.is(typeof plugins.fail, "function");
|
||||
});
|
||||
|
||||
test('Use default when only options are passed for a single plugin', async (t) => {
|
||||
test("Use default when only options are passed for a single plugin", async (t) => {
|
||||
const analyzeCommits = {};
|
||||
const generateNotes = {};
|
||||
const publish = {};
|
||||
@@ -211,7 +211,7 @@ test('Use default when only options are passed for a single plugin', async (t) =
|
||||
cwd,
|
||||
logger: t.context.logger,
|
||||
options: {
|
||||
plugins: ['@semantic-release/commit-analyzer', '@semantic-release/release-notes-generator'],
|
||||
plugins: ["@semantic-release/commit-analyzer", "@semantic-release/release-notes-generator"],
|
||||
analyzeCommits,
|
||||
generateNotes,
|
||||
publish,
|
||||
@@ -223,96 +223,102 @@ test('Use default when only options are passed for a single plugin', async (t) =
|
||||
);
|
||||
|
||||
// Verify the module returns a function for each plugin
|
||||
t.is(typeof plugins.analyzeCommits, 'function');
|
||||
t.is(typeof plugins.generateNotes, 'function');
|
||||
t.is(typeof plugins.success, 'function');
|
||||
t.is(typeof plugins.fail, 'function');
|
||||
t.is(typeof plugins.analyzeCommits, "function");
|
||||
t.is(typeof plugins.generateNotes, "function");
|
||||
t.is(typeof plugins.success, "function");
|
||||
t.is(typeof plugins.fail, "function");
|
||||
|
||||
// Verify only the plugins defined as an object with no `path` are set to the default value
|
||||
t.falsy(success.path);
|
||||
t.falsy(fail.path);
|
||||
});
|
||||
|
||||
test('Merge global options with plugin options', async (t) => {
|
||||
test("Merge global options with plugin options", async (t) => {
|
||||
const plugins = await getPlugins(
|
||||
{
|
||||
cwd,
|
||||
logger: t.context.logger,
|
||||
options: {
|
||||
globalOpt: 'global',
|
||||
otherOpt: 'globally-defined',
|
||||
verifyRelease: {path: './test/fixtures/plugin-result-config', localOpt: 'local', otherOpt: 'locally-defined'},
|
||||
globalOpt: "global",
|
||||
otherOpt: "globally-defined",
|
||||
verifyRelease: { path: "./test/fixtures/plugin-result-config", localOpt: "local", otherOpt: "locally-defined" },
|
||||
},
|
||||
},
|
||||
{}
|
||||
);
|
||||
|
||||
const [result] = await plugins.verifyRelease({options: {}});
|
||||
const [result] = await plugins.verifyRelease({ options: {} });
|
||||
|
||||
t.deepEqual(result.pluginConfig, {localOpt: 'local', globalOpt: 'global', otherOpt: 'locally-defined'});
|
||||
t.deepEqual(result.pluginConfig, { localOpt: "local", globalOpt: "global", otherOpt: "locally-defined" });
|
||||
});
|
||||
|
||||
test('Throw an error for each invalid plugin configuration', async (t) => {
|
||||
test("Throw an error for each invalid plugin configuration", async (t) => {
|
||||
const errors = [
|
||||
...(await t.throwsAsync(() =>
|
||||
getPlugins(
|
||||
{
|
||||
cwd,
|
||||
logger: t.context.logger,
|
||||
options: {
|
||||
plugins: ['@semantic-release/commit-analyzer', '@semantic-release/release-notes-generator'],
|
||||
verifyConditions: 1,
|
||||
analyzeCommits: [],
|
||||
verifyRelease: [{}],
|
||||
generateNotes: [{path: null}],
|
||||
...(
|
||||
await t.throwsAsync(() =>
|
||||
getPlugins(
|
||||
{
|
||||
cwd,
|
||||
logger: t.context.logger,
|
||||
options: {
|
||||
plugins: ["@semantic-release/commit-analyzer", "@semantic-release/release-notes-generator"],
|
||||
verifyConditions: 1,
|
||||
analyzeCommits: [],
|
||||
verifyRelease: [{}],
|
||||
generateNotes: [{ path: null }],
|
||||
},
|
||||
},
|
||||
},
|
||||
{}
|
||||
{}
|
||||
)
|
||||
)
|
||||
)).errors,
|
||||
).errors,
|
||||
];
|
||||
|
||||
t.is(errors[0].name, 'SemanticReleaseError');
|
||||
t.is(errors[0].code, 'EPLUGINCONF');
|
||||
t.is(errors[1].name, 'SemanticReleaseError');
|
||||
t.is(errors[1].code, 'EPLUGINCONF');
|
||||
t.is(errors[2].name, 'SemanticReleaseError');
|
||||
t.is(errors[2].code, 'EPLUGINCONF');
|
||||
t.is(errors[3].name, 'SemanticReleaseError');
|
||||
t.is(errors[3].code, 'EPLUGINCONF');
|
||||
t.is(errors[0].name, "SemanticReleaseError");
|
||||
t.is(errors[0].code, "EPLUGINCONF");
|
||||
t.is(errors[1].name, "SemanticReleaseError");
|
||||
t.is(errors[1].code, "EPLUGINCONF");
|
||||
t.is(errors[2].name, "SemanticReleaseError");
|
||||
t.is(errors[2].code, "EPLUGINCONF");
|
||||
t.is(errors[3].name, "SemanticReleaseError");
|
||||
t.is(errors[3].code, "EPLUGINCONF");
|
||||
});
|
||||
|
||||
test('Throw EPLUGINSCONF error if the "plugins" option contains an old plugin definition (returns a function)', async (t) => {
|
||||
const errors = [
|
||||
...(await t.throwsAsync(() =>
|
||||
getPlugins(
|
||||
{
|
||||
cwd,
|
||||
logger: t.context.logger,
|
||||
options: {plugins: ['./test/fixtures/multi-plugin.cjs', './test/fixtures/plugin-noop.cjs', () => {}]},
|
||||
},
|
||||
{}
|
||||
...(
|
||||
await t.throwsAsync(() =>
|
||||
getPlugins(
|
||||
{
|
||||
cwd,
|
||||
logger: t.context.logger,
|
||||
options: { plugins: ["./test/fixtures/multi-plugin.cjs", "./test/fixtures/plugin-noop.cjs", () => {}] },
|
||||
},
|
||||
{}
|
||||
)
|
||||
)
|
||||
)).errors,
|
||||
).errors,
|
||||
];
|
||||
|
||||
t.is(errors[0].name, 'SemanticReleaseError');
|
||||
t.is(errors[0].code, 'EPLUGINSCONF');
|
||||
t.is(errors[1].name, 'SemanticReleaseError');
|
||||
t.is(errors[1].code, 'EPLUGINSCONF');
|
||||
t.is(errors[0].name, "SemanticReleaseError");
|
||||
t.is(errors[0].code, "EPLUGINSCONF");
|
||||
t.is(errors[1].name, "SemanticReleaseError");
|
||||
t.is(errors[1].code, "EPLUGINSCONF");
|
||||
});
|
||||
|
||||
test('Throw EPLUGINSCONF error for each invalid definition if the "plugins" option', async (t) => {
|
||||
const errors = [
|
||||
...(await t.throwsAsync(() =>
|
||||
getPlugins({cwd, logger: t.context.logger, options: {plugins: [1, {path: 1}, [() => {}, {}, {}]]}}, {})
|
||||
)).errors,
|
||||
...(
|
||||
await t.throwsAsync(() =>
|
||||
getPlugins({ cwd, logger: t.context.logger, options: { plugins: [1, { path: 1 }, [() => {}, {}, {}]] } }, {})
|
||||
)
|
||||
).errors,
|
||||
];
|
||||
|
||||
t.is(errors[0].name, 'SemanticReleaseError');
|
||||
t.is(errors[0].code, 'EPLUGINSCONF');
|
||||
t.is(errors[1].name, 'SemanticReleaseError');
|
||||
t.is(errors[1].code, 'EPLUGINSCONF');
|
||||
t.is(errors[2].name, 'SemanticReleaseError');
|
||||
t.is(errors[2].code, 'EPLUGINSCONF');
|
||||
t.is(errors[0].name, "SemanticReleaseError");
|
||||
t.is(errors[0].code, "EPLUGINSCONF");
|
||||
t.is(errors[1].name, "SemanticReleaseError");
|
||||
t.is(errors[1].code, "EPLUGINSCONF");
|
||||
t.is(errors[2].name, "SemanticReleaseError");
|
||||
t.is(errors[2].code, "EPLUGINSCONF");
|
||||
});
|
||||
|
||||
+128
-118
@@ -1,214 +1,224 @@
|
||||
import test from 'ava';
|
||||
import {loadPlugin, parseConfig, validatePlugin, validateStep} from '../../lib/plugins/utils.js';
|
||||
import test from "ava";
|
||||
import { loadPlugin, parseConfig, validatePlugin, validateStep } from "../../lib/plugins/utils.js";
|
||||
|
||||
test('validatePlugin', (t) => {
|
||||
const path = 'plugin-module';
|
||||
const options = {option1: 'value1', option2: 'value2'};
|
||||
test("validatePlugin", (t) => {
|
||||
const path = "plugin-module";
|
||||
const options = { option1: "value1", option2: "value2" };
|
||||
|
||||
t.true(validatePlugin(path), 'String definition');
|
||||
t.true(validatePlugin({publish: () => {}}), 'Object definition');
|
||||
t.true(validatePlugin([path]), 'Array definition');
|
||||
t.true(validatePlugin([path, options]), 'Array definition with options');
|
||||
t.true(validatePlugin([{publish: () => {}}, options]), 'Array definition with options and path as object');
|
||||
t.true(validatePlugin({path}), 'Object with path definition');
|
||||
t.true(validatePlugin({path, ...options}), 'Object with path definition with options');
|
||||
t.true(validatePlugin(path), "String definition");
|
||||
t.true(validatePlugin({ publish: () => {} }), "Object definition");
|
||||
t.true(validatePlugin([path]), "Array definition");
|
||||
t.true(validatePlugin([path, options]), "Array definition with options");
|
||||
t.true(validatePlugin([{ publish: () => {} }, options]), "Array definition with options and path as object");
|
||||
t.true(validatePlugin({ path }), "Object with path definition");
|
||||
t.true(validatePlugin({ path, ...options }), "Object with path definition with options");
|
||||
t.true(
|
||||
validatePlugin({path: {publish: () => {}}, ...options}),
|
||||
'Object with path definition with options and path as object'
|
||||
validatePlugin({ path: { publish: () => {} }, ...options }),
|
||||
"Object with path definition with options and path as object"
|
||||
);
|
||||
|
||||
t.false(validatePlugin(1), 'String definition, wrong path');
|
||||
t.false(validatePlugin([]), 'Array definition, missing path');
|
||||
t.false(validatePlugin([path, options, {}]), 'Array definition, additional parameter');
|
||||
t.false(validatePlugin([1]), 'Array definition, wrong path');
|
||||
t.false(validatePlugin([path, 1]), 'Array definition, wrong options');
|
||||
t.false(validatePlugin({path: 1}), 'Object definition, wrong path');
|
||||
t.false(validatePlugin(1), "String definition, wrong path");
|
||||
t.false(validatePlugin([]), "Array definition, missing path");
|
||||
t.false(validatePlugin([path, options, {}]), "Array definition, additional parameter");
|
||||
t.false(validatePlugin([1]), "Array definition, wrong path");
|
||||
t.false(validatePlugin([path, 1]), "Array definition, wrong options");
|
||||
t.false(validatePlugin({ path: 1 }), "Object definition, wrong path");
|
||||
});
|
||||
|
||||
test('validateStep: optional plugin configuration', (t) => {
|
||||
const type = {multiple: true, required: false};
|
||||
test("validateStep: optional plugin configuration", (t) => {
|
||||
const type = { multiple: true, required: false };
|
||||
|
||||
// Empty config
|
||||
t.true(validateStep(type));
|
||||
t.true(validateStep(type, []));
|
||||
|
||||
// Single value definition
|
||||
t.true(validateStep(type, 'plugin-path.js'));
|
||||
t.true(validateStep(type, "plugin-path.js"));
|
||||
t.true(validateStep(type, () => {}));
|
||||
t.true(validateStep(type, ['plugin-path.js']));
|
||||
t.true(validateStep(type, ["plugin-path.js"]));
|
||||
t.true(validateStep(type, [() => {}]));
|
||||
t.false(validateStep(type, {}));
|
||||
t.false(validateStep(type, [{}]));
|
||||
|
||||
// Array type definition
|
||||
t.true(validateStep(type, [['plugin-path.js']]));
|
||||
t.true(validateStep(type, [['plugin-path.js', {options: 'value'}]]));
|
||||
t.true(validateStep(type, [[() => {}, {options: 'value'}]]));
|
||||
t.false(validateStep(type, [['plugin-path.js', 1]]));
|
||||
t.true(validateStep(type, [["plugin-path.js"]]));
|
||||
t.true(validateStep(type, [["plugin-path.js", { options: "value" }]]));
|
||||
t.true(validateStep(type, [[() => {}, { options: "value" }]]));
|
||||
t.false(validateStep(type, [["plugin-path.js", 1]]));
|
||||
|
||||
// Object type definition
|
||||
t.true(validateStep(type, {path: 'plugin-path.js'}));
|
||||
t.true(validateStep(type, {path: 'plugin-path.js', options: 'value'}));
|
||||
t.true(validateStep(type, {path: () => {}, options: 'value'}));
|
||||
t.false(validateStep(type, {path: null}));
|
||||
t.true(validateStep(type, { path: "plugin-path.js" }));
|
||||
t.true(validateStep(type, { path: "plugin-path.js", options: "value" }));
|
||||
t.true(validateStep(type, { path: () => {}, options: "value" }));
|
||||
t.false(validateStep(type, { path: null }));
|
||||
|
||||
// Considered as an Array of 2 definitions and not as one Array definition in case of a muliple plugin type
|
||||
t.false(validateStep(type, [() => {}, {options: 'value'}]));
|
||||
t.false(validateStep(type, ['plugin-path.js', {options: 'value'}]));
|
||||
t.false(validateStep(type, [() => {}, { options: "value" }]));
|
||||
t.false(validateStep(type, ["plugin-path.js", { options: "value" }]));
|
||||
|
||||
// Multiple definitions
|
||||
t.true(
|
||||
validateStep(type, [
|
||||
'plugin-path.js',
|
||||
"plugin-path.js",
|
||||
() => {},
|
||||
['plugin-path.js'],
|
||||
['plugin-path.js', {options: 'value'}],
|
||||
[() => {}, {options: 'value'}],
|
||||
{path: 'plugin-path.js'},
|
||||
{path: 'plugin-path.js', options: 'value'},
|
||||
{path: () => {}, options: 'value'},
|
||||
["plugin-path.js"],
|
||||
["plugin-path.js", { options: "value" }],
|
||||
[() => {}, { options: "value" }],
|
||||
{ path: "plugin-path.js" },
|
||||
{ path: "plugin-path.js", options: "value" },
|
||||
{ path: () => {}, options: "value" },
|
||||
])
|
||||
);
|
||||
t.false(
|
||||
validateStep(type, [
|
||||
'plugin-path.js',
|
||||
"plugin-path.js",
|
||||
() => {},
|
||||
['plugin-path.js'],
|
||||
['plugin-path.js', 1],
|
||||
[() => {}, {options: 'value'}],
|
||||
{path: 'plugin-path.js'},
|
||||
{path: 'plugin-path.js', options: 'value'},
|
||||
{path: () => {}, options: 'value'},
|
||||
["plugin-path.js"],
|
||||
["plugin-path.js", 1],
|
||||
[() => {}, { options: "value" }],
|
||||
{ path: "plugin-path.js" },
|
||||
{ path: "plugin-path.js", options: "value" },
|
||||
{ path: () => {}, options: "value" },
|
||||
])
|
||||
);
|
||||
t.false(
|
||||
validateStep(type, [
|
||||
'plugin-path.js',
|
||||
"plugin-path.js",
|
||||
{},
|
||||
['plugin-path.js'],
|
||||
['plugin-path.js', {options: 'value'}],
|
||||
[() => {}, {options: 'value'}],
|
||||
{path: 'plugin-path.js'},
|
||||
{path: 'plugin-path.js', options: 'value'},
|
||||
{path: () => {}, options: 'value'},
|
||||
["plugin-path.js"],
|
||||
["plugin-path.js", { options: "value" }],
|
||||
[() => {}, { options: "value" }],
|
||||
{ path: "plugin-path.js" },
|
||||
{ path: "plugin-path.js", options: "value" },
|
||||
{ path: () => {}, options: "value" },
|
||||
])
|
||||
);
|
||||
t.false(
|
||||
validateStep(type, [
|
||||
'plugin-path.js',
|
||||
"plugin-path.js",
|
||||
() => {},
|
||||
['plugin-path.js'],
|
||||
['plugin-path.js', {options: 'value'}],
|
||||
[() => {}, {options: 'value'}],
|
||||
{path: null},
|
||||
{path: 'plugin-path.js', options: 'value'},
|
||||
{path: () => {}, options: 'value'},
|
||||
["plugin-path.js"],
|
||||
["plugin-path.js", { options: "value" }],
|
||||
[() => {}, { options: "value" }],
|
||||
{ path: null },
|
||||
{ path: "plugin-path.js", options: "value" },
|
||||
{ path: () => {}, options: "value" },
|
||||
])
|
||||
);
|
||||
});
|
||||
|
||||
test('validateStep: required plugin configuration', (t) => {
|
||||
const type = {required: true};
|
||||
test("validateStep: required plugin configuration", (t) => {
|
||||
const type = { required: true };
|
||||
|
||||
// Empty config
|
||||
t.false(validateStep(type));
|
||||
t.false(validateStep(type, []));
|
||||
|
||||
// Single value definition
|
||||
t.true(validateStep(type, 'plugin-path.js'));
|
||||
t.true(validateStep(type, "plugin-path.js"));
|
||||
t.true(validateStep(type, () => {}));
|
||||
t.true(validateStep(type, ['plugin-path.js']));
|
||||
t.true(validateStep(type, ["plugin-path.js"]));
|
||||
t.true(validateStep(type, [() => {}]));
|
||||
t.false(validateStep(type, {}));
|
||||
t.false(validateStep(type, [{}]));
|
||||
|
||||
// Array type definition
|
||||
t.true(validateStep(type, [['plugin-path.js']]));
|
||||
t.true(validateStep(type, [['plugin-path.js', {options: 'value'}]]));
|
||||
t.true(validateStep(type, [[() => {}, {options: 'value'}]]));
|
||||
t.false(validateStep(type, [['plugin-path.js', 1]]));
|
||||
t.true(validateStep(type, [["plugin-path.js"]]));
|
||||
t.true(validateStep(type, [["plugin-path.js", { options: "value" }]]));
|
||||
t.true(validateStep(type, [[() => {}, { options: "value" }]]));
|
||||
t.false(validateStep(type, [["plugin-path.js", 1]]));
|
||||
|
||||
// Object type definition
|
||||
t.true(validateStep(type, {path: 'plugin-path.js'}));
|
||||
t.true(validateStep(type, {path: 'plugin-path.js', options: 'value'}));
|
||||
t.true(validateStep(type, {path: () => {}, options: 'value'}));
|
||||
t.false(validateStep(type, {path: null}));
|
||||
t.true(validateStep(type, { path: "plugin-path.js" }));
|
||||
t.true(validateStep(type, { path: "plugin-path.js", options: "value" }));
|
||||
t.true(validateStep(type, { path: () => {}, options: "value" }));
|
||||
t.false(validateStep(type, { path: null }));
|
||||
|
||||
// Considered as an Array of 2 definitions and not as one Array definition in the case of a muliple plugin type
|
||||
t.false(validateStep(type, [() => {}, {options: 'value'}]));
|
||||
t.false(validateStep(type, ['plugin-path.js', {options: 'value'}]));
|
||||
t.false(validateStep(type, [() => {}, { options: "value" }]));
|
||||
t.false(validateStep(type, ["plugin-path.js", { options: "value" }]));
|
||||
|
||||
// Multiple definitions
|
||||
t.true(
|
||||
validateStep(type, [
|
||||
'plugin-path.js',
|
||||
"plugin-path.js",
|
||||
() => {},
|
||||
['plugin-path.js'],
|
||||
['plugin-path.js', {options: 'value'}],
|
||||
[() => {}, {options: 'value'}],
|
||||
{path: 'plugin-path.js'},
|
||||
{path: 'plugin-path.js', options: 'value'},
|
||||
{path: () => {}, options: 'value'},
|
||||
["plugin-path.js"],
|
||||
["plugin-path.js", { options: "value" }],
|
||||
[() => {}, { options: "value" }],
|
||||
{ path: "plugin-path.js" },
|
||||
{ path: "plugin-path.js", options: "value" },
|
||||
{ path: () => {}, options: "value" },
|
||||
])
|
||||
);
|
||||
t.false(
|
||||
validateStep(type, [
|
||||
'plugin-path.js',
|
||||
"plugin-path.js",
|
||||
() => {},
|
||||
['plugin-path.js'],
|
||||
['plugin-path.js', 1],
|
||||
[() => {}, {options: 'value'}],
|
||||
{path: 'plugin-path.js'},
|
||||
{path: 'plugin-path.js', options: 'value'},
|
||||
{path: () => {}, options: 'value'},
|
||||
["plugin-path.js"],
|
||||
["plugin-path.js", 1],
|
||||
[() => {}, { options: "value" }],
|
||||
{ path: "plugin-path.js" },
|
||||
{ path: "plugin-path.js", options: "value" },
|
||||
{ path: () => {}, options: "value" },
|
||||
])
|
||||
);
|
||||
t.false(
|
||||
validateStep(type, [
|
||||
'plugin-path.js',
|
||||
"plugin-path.js",
|
||||
{},
|
||||
['plugin-path.js'],
|
||||
['plugin-path.js', {options: 'value'}],
|
||||
[() => {}, {options: 'value'}],
|
||||
{path: 'plugin-path.js'},
|
||||
{path: 'plugin-path.js', options: 'value'},
|
||||
{path: () => {}, options: 'value'},
|
||||
["plugin-path.js"],
|
||||
["plugin-path.js", { options: "value" }],
|
||||
[() => {}, { options: "value" }],
|
||||
{ path: "plugin-path.js" },
|
||||
{ path: "plugin-path.js", options: "value" },
|
||||
{ path: () => {}, options: "value" },
|
||||
])
|
||||
);
|
||||
t.false(
|
||||
validateStep(type, [
|
||||
'plugin-path.js',
|
||||
"plugin-path.js",
|
||||
() => {},
|
||||
['plugin-path.js'],
|
||||
['plugin-path.js', {options: 'value'}],
|
||||
[() => {}, {options: 'value'}],
|
||||
{path: null},
|
||||
{path: 'plugin-path.js', options: 'value'},
|
||||
{path: () => {}, options: 'value'},
|
||||
["plugin-path.js"],
|
||||
["plugin-path.js", { options: "value" }],
|
||||
[() => {}, { options: "value" }],
|
||||
{ path: null },
|
||||
{ path: "plugin-path.js", options: "value" },
|
||||
{ path: () => {}, options: "value" },
|
||||
])
|
||||
);
|
||||
});
|
||||
|
||||
test('loadPlugin', async (t) => {
|
||||
test("loadPlugin", async (t) => {
|
||||
const cwd = process.cwd();
|
||||
const func = () => {};
|
||||
|
||||
t.is((await import('../fixtures/plugin-noop.cjs')).default, await loadPlugin({cwd: './test/fixtures'}, './plugin-noop.cjs', {}), 'From cwd');
|
||||
t.is(
|
||||
(await import('../fixtures/plugin-noop.cjs')).default,
|
||||
await loadPlugin({cwd}, './plugin-noop.cjs', {'./plugin-noop.cjs': './test/fixtures'}),
|
||||
'From a shareable config context'
|
||||
(await import("../fixtures/plugin-noop.cjs")).default,
|
||||
await loadPlugin({ cwd: "./test/fixtures" }, "./plugin-noop.cjs", {}),
|
||||
"From cwd"
|
||||
);
|
||||
t.is(func, await loadPlugin({cwd}, func, {}), 'Defined as a function');
|
||||
t.is(
|
||||
(await import("../fixtures/plugin-noop.cjs")).default,
|
||||
await loadPlugin({ cwd }, "./plugin-noop.cjs", { "./plugin-noop.cjs": "./test/fixtures" }),
|
||||
"From a shareable config context"
|
||||
);
|
||||
const { ...namedExports } = await import("../fixtures/plugin-esm-named-exports.js");
|
||||
const plugin = await loadPlugin({ cwd }, "./plugin-esm-named-exports.js", {
|
||||
"./plugin-esm-named-exports.js": "./test/fixtures",
|
||||
});
|
||||
|
||||
t.deepEqual(namedExports, plugin, "ESM with named exports");
|
||||
t.is(func, await loadPlugin({ cwd }, func, {}), "Defined as a function");
|
||||
});
|
||||
|
||||
test('parseConfig', (t) => {
|
||||
const path = 'plugin-module';
|
||||
const options = {option1: 'value1', option2: 'value2'};
|
||||
test("parseConfig", (t) => {
|
||||
const path = "plugin-module";
|
||||
const options = { option1: "value1", option2: "value2" };
|
||||
|
||||
t.deepEqual(parseConfig(path), [path, {}], 'String definition');
|
||||
t.deepEqual(parseConfig({path}), [path, {}], 'Object definition');
|
||||
t.deepEqual(parseConfig({path, ...options}), [path, options], 'Object definition with options');
|
||||
t.deepEqual(parseConfig([path]), [path, {}], 'Array definition');
|
||||
t.deepEqual(parseConfig([path, options]), [path, options], 'Array definition with options');
|
||||
t.deepEqual(parseConfig(path), [path, {}], "String definition");
|
||||
t.deepEqual(parseConfig({ path }), [path, {}], "Object definition");
|
||||
t.deepEqual(parseConfig({ path, ...options }), [path, options], "Object definition with options");
|
||||
t.deepEqual(parseConfig([path]), [path, {}], "Array definition");
|
||||
t.deepEqual(parseConfig([path, options]), [path, options], "Array definition with options");
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user