Skip to content

Commit

Permalink
Fix issue #1919 by adding a new util function to prevent duplicate co…
Browse files Browse the repository at this point in the history
…de (#1942)

* Issue #1919 Refactor to reduce duplicate code and add tests

* undo changes to package-lock.json
  • Loading branch information
khamiltonuk authored and mroderick committed Oct 29, 2018
1 parent 07e4994 commit 96f8e40
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 34 deletions.
23 changes: 5 additions & 18 deletions lib/sinon/behavior.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ var extend = require("./util/core/extend");
var functionName = require("@sinonjs/commons").functionName;
var nextTick = require("./util/core/next-tick");
var valueToString = require("@sinonjs/commons").valueToString;
var exportAsyncBehaviors = require("./util/core/export-async-behaviors");

var concat = arrayProto.concat;
var forEach = arrayProto.forEach;
var join = arrayProto.join;
var reverse = arrayProto.reverse;
var slice = arrayProto.slice;
Expand Down Expand Up @@ -205,22 +205,6 @@ var proto = {
}
};

function createAsyncVersion(syncFnName) {
return function() {
var result = this[syncFnName].apply(this, arguments);
this.callbackAsync = true;
return result;
};
}

// create asynchronous versions of callsArg* and yields* methods
forEach(Object.keys(proto), function(method) {
// need to avoid creating anotherasync versions of the newly added async methods
if (method.match(/^(callsArg|yields)/) && !method.match(/Async/)) {
proto[method + "Async"] = createAsyncVersion(method);
}
});

function createBehavior(behaviorMethod) {
return function() {
this.defaultBehavior = this.defaultBehavior || proto.create(this);
Expand All @@ -240,4 +224,7 @@ function addBehavior(stub, name, fn) {

proto.addBehavior = addBehavior;
proto.createBehavior = createBehavior;
module.exports = proto;

var asyncBehaviors = exportAsyncBehaviors(proto);

module.exports = extend({}, proto, asyncBehaviors);
21 changes: 5 additions & 16 deletions lib/sinon/default-behaviors.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

var arrayProto = require("@sinonjs/commons").prototypes.array;
var isPropertyConfigurable = require("./util/core/is-property-configurable");
var exportAsyncBehaviors = require("./util/core/export-async-behaviors");
var extend = require("./util/core/extend");

var forEach = arrayProto.forEach;
var slice = arrayProto.slice;

var useLeftMostCallback = -1;
Expand All @@ -27,7 +28,7 @@ function throwsException(fake, error, message) {
}
}

module.exports = {
var defaultBehaviors = {
callsFake: function callsFake(fake, fn) {
fake.fakeFn = fn;
},
Expand Down Expand Up @@ -260,18 +261,6 @@ module.exports = {
}
};

function createAsyncVersion(syncFnName) {
return function() {
var result = module.exports[syncFnName].apply(this, arguments);
this.callbackAsync = true;
return result;
};
}
var asyncBehaviors = exportAsyncBehaviors(defaultBehaviors);

// create asynchronous versions of callsArg* and yields* methods
forEach(Object.keys(module.exports), function(method) {
// need to avoid creating anotherasync versions of the newly added async methods
if (method.match(/^(callsArg|yields)/) && !method.match(/Async/)) {
module.exports[method + "Async"] = createAsyncVersion(method);
}
});
module.exports = extend({}, defaultBehaviors, asyncBehaviors);
22 changes: 22 additions & 0 deletions lib/sinon/util/core/export-async-behaviors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
"use strict";

var arrayProto = require("@sinonjs/commons").prototypes.array;
var reduce = arrayProto.reduce;

module.exports = function exportAsyncBehaviors(behaviorMethods) {
return reduce(
Object.keys(behaviorMethods),
function(acc, method) {
// need to avoid creating another async versions of the newly added async methods
if (method.match(/^(callsArg|yields)/) && !method.match(/Async/)) {
acc[method + "Async"] = function() {
var result = behaviorMethods[method].apply(this, arguments);
this.callbackAsync = true;
return result;
};
}
return acc;
},
{}
);
};
35 changes: 35 additions & 0 deletions test/util/core/export-async-behaviors-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
"use strict";

var referee = require("@sinonjs/referee");
var assert = referee.assert;
var exportAsyncBehaviors = require("../../../lib/sinon/util/core/export-async-behaviors");

describe("util/core/exportAsyncBehaviors", function() {
describe("for methods with names starting with 'callsArg' or 'yields'", function() {
it("should create an async version", function() {
var methods = {
yieldsOn: function yieldsOn() {
return "2";
},
callsArg: function callsArg() {
return "3";
}
};
assert.equals(Object.keys(exportAsyncBehaviors(methods)), ["yieldsOnAsync", "callsArgAsync"]);
});
});

describe("for methods with names not starting with 'callsArg' or 'yields'", function() {
it("should not add any new methods", function() {
var methods = {
callsFake: function callsFake() {
return "1";
},
resolvesThisAsync: function resolvesThisAsync() {
return "4";
}
};
assert.equals(Object.keys(exportAsyncBehaviors(methods)), []);
});
});
});

0 comments on commit 96f8e40

Please sign in to comment.