Skip to content

Commit

Permalink
Re-add assert.callOrder
Browse files Browse the repository at this point in the history
Lifted some private code from Sinon, as `calledInOrder` and
`orderByFirstCall were made private in Sinon in
sinonjs/sinon#1506
  • Loading branch information
mroderick committed Mar 2, 2018
1 parent 5b71a0c commit 19af146
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 1 deletion.
2 changes: 1 addition & 1 deletion .eslintrc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ rules:
ie11/no-loop-func: warn
ie11/no-weak-collections: error

max-len: [error, {code: 120, ignoreStrings: true}]
max-len: [error, {code: 120, ignoreComments: true, ignoreStrings: true}]

overrides:
files: '*.test.*'
Expand Down
70 changes: 70 additions & 0 deletions lib/referee-sinon.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,59 @@
}(typeof self !== "undefined" ? self : this, function () {
"use strict";

// lifted from https://github.com/sinonjs/sinon/blob/f89392c419dd3825d7af7fa0d58cc6ddeabfa3a6/lib/sinon/util/core/order-by-first-call.js
// FIXME: figure out how to share this code from Sinon
// * separate repository for this function?
// * Mono repo? https://lernajs.io
function orderByFirstCall(spies) {
return spies.sort(function (a, b) {
// uuid, won't ever be equal
var aCall = a.getCall(0);
var bCall = b.getCall(0);
var aId = aCall && aCall.callId || -1;
var bId = bCall && bCall.callId || -1;

return aId < bId ? -1 : 1;
});
}

// lifted from https://github.com/sinonjs/sinon/blob/f89392c419dd3825d7af7fa0d58cc6ddeabfa3a6/lib/sinon/util/core/called-in-order.js
// FIXME: figure out how to share this code from Sinon
// * separate repository for this function?
// * Mono repo? https://lernajs.io
var every = Array.prototype.every;

function calledInOrder(spies) {
var callMap = {};

function hasCallsLeft(spy) {
if (callMap[spy.id] === undefined) {
callMap[spy.id] = 0;
}

return callMap[spy.id] < spy.callCount;
}

if (arguments.length > 1) {
spies = arguments;
}

return every.call(spies, function checkAdjacentCalls(spy, i) {
var calledBeforeNext = true;

if (i !== spies.length - 1) {
calledBeforeNext = spy.calledBefore(spies[i + 1]);
}

if (hasCallsLeft(spy) && calledBeforeNext) {
callMap[spy.id] += 1;
return true;
}

return false;
});
}

return function (referee, sinon) {
sinon.expectation.pass = function (assertion) {
referee.emit("pass", assertion);
Expand Down Expand Up @@ -80,6 +133,23 @@
return [].slice.call(arr, from);
}

referee.add("callOrder", {
assert: function (spy) {
var type = Object.prototype.toString.call(spy);
var isArray = type === "[object Array]";
var args = isArray ? spy : arguments;
verifyFakes.apply(this, args);
if (calledInOrder(args)) { return true; }

this.expected = [].join.call(args, ", ");
this.actual = orderByFirstCall(slice(args)).join(", ");
return false;
},

assertMessage: "Expected ${expected} to be called in order but were called as ${actual}",
refuteMessage: "Expected ${expected} not to be called in order"
});

function addCallCountAssertion(count) {
referee.add("called" + count, {
assert: function (spy) {
Expand Down
35 changes: 35 additions & 0 deletions lib/referee-sinon.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,41 @@ describe("referee-sinon", function () {
});
});

describe("callOrder", function () {
it("fails when not called with function", requiresFunction("callOrder"));
it("fails when not called with spy", requiresSpy("callOrder"));

it("passes when called in order", function () {
var spies = [sinon.spy(), sinon.spy()];
spies[0]();
spies[1]();

assert.callOrder(spies[0], spies[1]);
});

it("passes when called in order using an array", function () {
var spies = [sinon.spy(), sinon.spy()];
spies[0]();
spies[1]();

assert.callOrder(spies);
});

it("formats message", function () {
var spies = [sinon.spy(), sinon.spy()];
spies[1]();
spies[0]();

try {
assert.callOrder(spies[0], spies[1]);
} catch (e) {
var message = "[assert.callOrder] Expected 0, 1 to be " +
"called in order but were called as 1, 0";
assert.equals(e.message, message);
}
});
});

describe("calledOn", function () {
it("fails when not called with function", requiresFunction("calledOn", {}));
it("fails when not called with spy", requiresSpy("calledOn", {}));
Expand Down

0 comments on commit 19af146

Please sign in to comment.