run-pace
Version:
Calculate running pace
179 lines (146 loc) • 7.17 kB
JavaScript
;
const chai = require("chai");
const chaiSpies = require("chai-spies");
const expect = chai.expect;
const proxyquire = require("proxyquire");
const mockRunPace = {};
const cli = proxyquire("../bin/cli.js", { "../lib/run-pace.js": mockRunPace });
const baseArgs = [ "/path/to/node", "/path/to/script.js" ];
let fakeProcess;
chai.use(chaiSpies);
const params = [
[ "--length", "10km" ],
[ "--time", "45m" ],
[ "--pace", "4:30/km" ],
];
describe("cli test", () => {
beforeEach(() => {
mockRunPace.calculateLength = chai.spy();
mockRunPace.calculatePace = chai.spy();
mockRunPace.calculateTime = chai.spy();
mockRunPace.paceToSpeed = chai.spy();
fakeProcess = {
stdout: { write: chai.spy() },
stderr: { write: chai.spy() },
};
});
it("no parameters", () => {
cli(baseArgs, fakeProcess);
expect(mockRunPace.calculateLength).to.not.have.been.called;
expect(mockRunPace.calculatePace).to.not.have.been.called;
expect(mockRunPace.calculateTime).to.not.have.been.called;
expect(mockRunPace.paceToSpeed).to.not.have.been.called;
expect(fakeProcess.stdout.write).to.have.been.called.once;
expect(fakeProcess.stderr.write).to.have.been.called.once.with("Two of \"time\", \"length\" and \"pace\" must be provided.\n" +
"\"speed\" is only valid when (only) pace is given or calculated.\n");
});
params.forEach((param) => {
it(`one parameter: "${param.join(" ")}"`, () => {
cli(baseArgs.concat(param), fakeProcess);
expect(mockRunPace.calculateLength).to.not.have.been.called;
expect(mockRunPace.calculatePace).to.not.have.been.called;
expect(mockRunPace.calculateTime).to.not.have.been.called;
expect(mockRunPace.paceToSpeed).to.not.have.been.called;
expect(fakeProcess.stdout.write).to.have.been.called.once;
expect(fakeProcess.stderr.write).to.have.been.called.once.with("Two of \"time\", \"length\" and \"pace\" must be provided.\n" +
"\"speed\" is only valid when (only) pace is given or calculated.\n");
});
});
params.forEach((_, index) => {
const callParams = cloneArray(params);
const skippedParam = removeElement(callParams, index);
const calledMethod = getMethodName(skippedParam);
const paramsString = callParams.map((p) => p.join(" ")).join(" ");
it(`two parameters: "${paramsString}" calls "${calledMethod}"`, () => {
cli(baseArgs.concat(...callParams), fakeProcess);
const calledArgs = {};
callParams.forEach(([ key, value ]) => {
calledArgs[key.slice(2)] = value;
expect(mockRunPace[getMethodName(key)]).to.not.have.been.called;
});
expect(mockRunPace.paceToSpeed).to.not.have.been.called;
expect(mockRunPace[calledMethod]).to.have.been.called.once.with(calledArgs);
});
});
it("three parameters", () => {
cli(baseArgs.concat(...params), fakeProcess);
expect(mockRunPace.calculateLength).to.not.have.been.called;
expect(mockRunPace.calculatePace).to.not.have.been.called;
expect(mockRunPace.calculateTime).to.not.have.been.called;
expect(mockRunPace.paceToSpeed).to.not.have.been.called;
expect(fakeProcess.stdout.write).to.have.been.called.once;
expect(fakeProcess.stderr.write).to.have.been.called.once.with("Too many arguments. Only two of \"time\", \"length\" and \"pace\" may be provided at any time\n");
});
[ "metric", "imperial" ].forEach((flag) => {
const callParams = params.slice(1);
const calledArgs = callParams.reduce((acc, [ key, value ]) => {
acc[key.slice(2)] = value;
return acc;
}, {});
calledArgs[flag] = true;
it(`${flag} flag`, () => {
cli(baseArgs.concat(...callParams, `--${flag}`), fakeProcess);
expect(mockRunPace.calculateLength).to.have.been.called.once.with(calledArgs);
expect(mockRunPace.calculatePace).to.not.have.been.called;
expect(mockRunPace.calculateTime).to.not.have.been.called;
expect(mockRunPace.paceToSpeed).to.not.have.been.called;
expect(fakeProcess.stdout.write).to.have.been.called.once;
expect(fakeProcess.stderr.write).to.not.have.been.called;
});
});
it("both \"metric\" and \"imperial\" flag", () => {
cli(baseArgs.concat(...params.slice(1), "-m", "-i"), fakeProcess);
expect(mockRunPace.calculateLength).to.not.have.been.called;
expect(mockRunPace.calculatePace).to.not.have.been.called;
expect(mockRunPace.calculateTime).to.not.have.been.called;
expect(mockRunPace.paceToSpeed).to.not.have.been.called;
expect(fakeProcess.stdout.write).to.have.been.called.once;
expect(fakeProcess.stderr.write).to.have.been.called.once.with("Conflicting parameters: \"metric\" and \"imperial\" cannot be provided at the same time\n");
});
it("speed from pace", () => {
cli(baseArgs.concat(...params.slice(-1), "-s"), fakeProcess);
expect(mockRunPace.calculateLength).to.not.have.been.called;
expect(mockRunPace.calculatePace).to.not.have.been.called;
expect(mockRunPace.calculateTime).to.not.have.been.called;
expect(mockRunPace.paceToSpeed).to.have.been.called.once;
expect(fakeProcess.stdout.write).to.have.been.called.once;
expect(fakeProcess.stderr.write).to.not.have.been.called;
});
it("speed from length and time", () => {
cli(baseArgs.concat(...params.slice(0, -1), "-s"), fakeProcess);
expect(mockRunPace.calculateLength).to.not.have.been.called;
expect(mockRunPace.calculatePace).to.have.been.called;
expect(mockRunPace.calculateTime).to.not.have.been.called;
expect(mockRunPace.paceToSpeed).to.have.been.called;
expect(fakeProcess.stdout.write).to.have.been.called.once;
expect(fakeProcess.stderr.write).to.not.have.been.called;
});
it("speed is not valid with length and pace", () => {
cli(baseArgs.concat(params[0], params[2], "-s"), fakeProcess);
expect(mockRunPace.calculateLength).to.not.have.been.called;
expect(mockRunPace.calculatePace).to.have.been.called;
expect(mockRunPace.calculateTime).to.not.have.been.called;
expect(mockRunPace.paceToSpeed).to.not.have.been.called;
expect(fakeProcess.stdout.write).to.have.been.called.once;
expect(fakeProcess.stderr.write).to.have.been.called.with("\"speed\" is only valid when (only) pace is given or calculated.\n");
});
it("speed is not valid with time and pace", () => {
cli(baseArgs.concat(...params.slice(1), "-s"), fakeProcess);
expect(mockRunPace.calculateLength).to.not.have.been.called;
expect(mockRunPace.calculatePace).to.have.been.called;
expect(mockRunPace.calculateTime).to.not.have.been.called;
expect(mockRunPace.paceToSpeed).to.not.have.been.called;
expect(fakeProcess.stdout.write).to.have.been.called.once;
expect(fakeProcess.stderr.write).to.have.been.called.with("\"speed\" is only valid when (only) pace is given or calculated.\n");
});
});
function cloneArray(arr) {
return arr.slice();
}
function removeElement(arr, index) {
const [ [ removedElement ] ] = arr.splice(index, 1);
return removedElement;
}
function getMethodName(flag) {
return `calculate${flag[2].toUpperCase()}${flag.slice(3)}`;
}