diff --git a/lib/sinon/match.js b/lib/sinon/match.js index 59c485b2d..48eda0ba3 100644 --- a/lib/sinon/match.js +++ b/lib/sinon/match.js @@ -17,6 +17,12 @@ function assertType(value, type, name) { } } +function assertMethodExists(value, method, name, methodPath) { + if (value[method] == null) { + throw new TypeError("Expected " + name + " to have method " + methodPath); + } +} + var matcher = { toString: function () { return this.message; @@ -179,10 +185,14 @@ match.typeOf = function (type) { }; match.instanceOf = function (type) { - assertType(type, "function", "type"); + if (typeof Symbol === "undefined" || typeof Symbol.hasInstance === "undefined") { + assertType(type, "function", "type"); + } else { + assertMethodExists(type, Symbol.hasInstance, "type", "[Symbol.hasInstance]"); + } return match(function (actual) { return actual instanceof type; - }, "instanceOf(" + functionName(type) + ")"); + }, "instanceOf(" + (functionName(type) || Object.prototype.toString.call(type)) + ")"); }; function createPropertyMatcher(propertyTest, messagePrefix) { diff --git a/test/match-test.js b/test/match-test.js index 6e810f51a..142f47c81 100644 --- a/test/match-test.js +++ b/test/match-test.js @@ -493,6 +493,14 @@ describe("sinonMatch", function () { }, "TypeError"); }); + if (typeof Symbol !== "undefined" && typeof Symbol.hasInstance !== "undefined") { + it("does not throw if given argument defines Symbol.hasInstance", function () { + var objectWithCustomTypeChecks = {}; + objectWithCustomTypeChecks[Symbol.hasInstance] = function () {}; + sinonMatch.instanceOf(objectWithCustomTypeChecks); + }); + } + it("returns matcher", function () { var instanceOf = sinonMatch.instanceOf(function () {});