diff --git a/source/types/is.mjs b/source/types/is.mjs index 1fc67ae6e577850bb41b222816e26b657a40bc3a..de9754d7ca7b1f616e676548a1a977a68e8b056f 100644 --- a/source/types/is.mjs +++ b/source/types/is.mjs @@ -173,7 +173,15 @@ function isInstance(value, instance) { if (!isObject(value)) return false; if (!isFunction(instance)) return false; if (!instance.hasOwnProperty("prototype")) return false; - return value instanceof instance ? true : false; + if(value instanceof instance) return true; + + let proto = Object.getPrototypeOf(value); + while (proto != null) { + if (proto === instance.prototype) return true; + proto = Object.getPrototypeOf(proto); + } + + return false; } /** diff --git a/test/cases/types/is.mjs b/test/cases/types/is.mjs index 8be3a39ae1eb055baeae0aa01e0ca8fc76812029..852ee31092919c9a661d56598e3424e892d0099d 100644 --- a/test/cases/types/is.mjs +++ b/test/cases/types/is.mjs @@ -238,7 +238,65 @@ describe('Is', function () { }); }); }); - + + describe('.isInstanceExtended()', function () { + class Base {} + class Derived extends Base {} + function AnotherClass() {} + + let baseInstance = new Base(); + let derivedInstance = new Derived(); + + // Test cases + const cases = [ + [() => {}, undefined, false,"function vs undefined"], + [new ID(), ()=>{}, false, "ID instance vs function"], + [new ID(), ID, true, "ID instance vs ID"], + ['test1', undefined, false, "string vs undefined"], + [undefined, undefined, false, "undefined vs undefined"], + [null, undefined, false, "null vs undefined"], + [2, undefined, false, "number vs undefined"], + [false, undefined, false, "false vs undefined"], + [parseInt("a"), undefined, false, "NaN vs undefined"], + [true, undefined, false, "true vs undefined"], + [4.5, undefined, false, "float vs undefined"], + [{}, undefined, false, "object vs undefined"], + [[1, 2, 3], undefined, false, "array vs undefined"], + [Symbol("foo"), undefined, false, "symbol vs undefined"], + [baseInstance, Base, true, "Base instance vs Base"], + [derivedInstance, Base, true, "Derived instance vs Base"], + [derivedInstance, Derived, true, "Derived instance vs Derived"], + [baseInstance, Derived, false, "Base instance vs Derived"], + [baseInstance, AnotherClass, false, "Base instance vs AnotherClass"], + [derivedInstance, ()=>{}, false, "Derived instance vs function"], + [new AnotherClass(), AnotherClass, true, "AnotherClass instance vs AnotherClass"], + ]; + + // Adding prototype modification test + let protoModifiedInstance = new Base(); + Object.setPrototypeOf(protoModifiedInstance, Derived.prototype); + cases.push( + [protoModifiedInstance, Base, true, "Proto modified Base instance vs Base"], + [protoModifiedInstance, Derived, true, "Proto modified Base instance vs Derived"] + ); + + // Running the tests + cases.forEach(function (data) { + const a = data.shift(); + const b = data.shift(); + const c = data.shift(); + const d = data.shift(); + + it('isInstance(' + JSON.stringify(a) + ', [Function]) should return ' + c, function () { + + if (isInstance(a, b)!==c) { + console.log(d) + } + + expect(isInstance(a, b)).to.equal(c); + }); + }); + }); describe('.isObject()', function () {