diff --git a/test/js-native-api/test_general/testInstanceOf.js b/test/js-native-api/test_general/testInstanceOf.js index dedc5a0e6b96f8..0946dda957d48c 100644 --- a/test/js-native-api/test_general/testInstanceOf.js +++ b/test/js-native-api/test_general/testInstanceOf.js @@ -1,58 +1,9 @@ 'use strict'; const common = require('../../common'); -const fs = require('fs'); const assert = require('assert'); // Addon is referenced through the eval expression in testFile const addon = require(`./build/${common.buildType}/test_general`); -const path = require('path'); - -// This test depends on a number of V8 tests. -const v8TestsDir = path.resolve(__dirname, '..', '..', '..', 'deps', 'v8', - 'test', 'mjsunit'); -const v8TestsDirExists = fs.existsSync(v8TestsDir); - -// The following assert functions are referenced by v8's unit tests -// See for instance deps/v8/test/mjsunit/instanceof.js -// eslint-disable-next-line no-unused-vars -function assertTrue(assertion) { - return assert.strictEqual(assertion, true); -} - -// eslint-disable-next-line no-unused-vars -function assertFalse(assertion) { - assert.strictEqual(assertion, false); -} - -// eslint-disable-next-line no-unused-vars -function assertEquals(leftHandSide, rightHandSide) { - assert.strictEqual(leftHandSide, rightHandSide); -} - -// eslint-disable-next-line no-unused-vars -function assertThrows(statement) { - assert.throws(function() { - eval(statement); - }, Error); -} - -function testFile(fileName) { - try { - const contents = fs.readFileSync(fileName, { encoding: 'utf8' }); - eval(contents.replace(/[(]([^\s(]+)\s+instanceof\s+([^)]+)[)]/g, - '(addon.doInstanceOf($1, $2))')); - } catch (err) { - // This test depends on V8 test files, which may not exist in downloaded - // archives. Emit a warning if the tests cannot be found instead of failing. - if (err.code === 'ENOENT' && !v8TestsDirExists) - process.emitWarning(`test file ${fileName} does not exist.`); - else - throw err; - } -} - -testFile(path.join(v8TestsDir, 'instanceof.js')); -testFile(path.join(v8TestsDir, 'instanceof-2.js')); // We can only perform this test if we have a working Symbol.hasInstance if (typeof Symbol !== 'undefined' && 'hasInstance' in Symbol && diff --git a/test/js-native-api/test_general/testV8Instanceof.js b/test/js-native-api/test_general/testV8Instanceof.js new file mode 100644 index 00000000000000..1cb4a71ce2dddd --- /dev/null +++ b/test/js-native-api/test_general/testV8Instanceof.js @@ -0,0 +1,122 @@ +// Copyright 2008 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +'use strict'; + +const common = require('../../common'); +const addon = require(`./build/${common.buildType}/test_general`); +const assert = require('assert'); + +// The following assert functions are referenced by v8's unit tests +// See for instance deps/v8/test/mjsunit/instanceof.js + +function assertTrue(assertion) { + return assert.strictEqual(assertion, true); +} + + +function assertFalse(assertion) { + assert.strictEqual(assertion, false); +} + + +function assertEquals(leftHandSide, rightHandSide) { + assert.strictEqual(leftHandSide, rightHandSide); +} + + +function assertThrows(statement) { + assert.throws(function() { + eval(statement); + }, Error); +} + +assertTrue(addon.doInstanceOf({}, Object)); +assertTrue(addon.doInstanceOf([], Object)); + +assertFalse(addon.doInstanceOf({}, Array)); +assertTrue(addon.doInstanceOf([], Array)); + +function TestChains() { + const A = {}; + const B = {}; + const C = {}; + Object.setPrototypeOf(B, A); + Object.setPrototypeOf(C, B); + + function F() { } + F.prototype = A; + assertTrue(addon.doInstanceOf(C, F)); + assertTrue(addon.doInstanceOf(B, F)); + assertFalse(addon.doInstanceOf(A, F)); + + F.prototype = B; + assertTrue(addon.doInstanceOf(C, F)); + assertFalse(addon.doInstanceOf(B, F)); + assertFalse(addon.doInstanceOf(A, F)); + + F.prototype = C; + assertFalse(addon.doInstanceOf(C, F)); + assertFalse(addon.doInstanceOf(B, F)); + assertFalse(addon.doInstanceOf(A, F)); +} + +TestChains(); + + +function TestExceptions() { + function F() { } + const items = [ 1, new Number(42), + true, + 'string', new String('hest'), + {}, [], + F, new F(), + Object, String ]; + + let exceptions = 0; + let instanceofs = 0; + + for (let i = 0; i < items.length; i++) { + for (let j = 0; j < items.length; j++) { + try { + if (addon.doInstanceOf(items[i], items[j])) instanceofs++; + } catch (e) { + assertTrue(addon.doInstanceOf(e, TypeError)); + exceptions++; + } + } + } + assertEquals(10, instanceofs); + assertEquals(88, exceptions); + + // Make sure to throw an exception if the function prototype + // isn't a proper JavaScript object. + function G() { } + G.prototype = undefined; + assertThrows('addon.doInstanceOf({}, G)'); +} + +TestExceptions(); diff --git a/test/js-native-api/test_general/testV8Instanceof2.js b/test/js-native-api/test_general/testV8Instanceof2.js new file mode 100644 index 00000000000000..24ac4b7e6ba9b3 --- /dev/null +++ b/test/js-native-api/test_general/testV8Instanceof2.js @@ -0,0 +1,343 @@ +// Copyright 2010 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +'use strict'; + +const common = require('../../common'); +const addon = require(`./build/${common.buildType}/test_general`); +const assert = require('assert'); + +function assertTrue(assertion) { + return assert.strictEqual(assertion, true); +} + +function assertEquals(leftHandSide, rightHandSide) { + assert.strictEqual(leftHandSide, rightHandSide); +} + +const except = 'exception'; + +let correct_answer_index = 0; +const correct_answers = [ + false, false, true, true, false, false, true, true, + true, false, false, true, true, false, false, true, + false, true, true, false, false, true, true, false, + true, true, false, false, true, true, false, false, + except, except, true, true, except, except, true, true, + except, except, false, true, except, except, false, true, + except, except, true, false, except, except, true, false, + except, except, false, false, except, except, false, false, + false, false, except, except, false, false, except, except, + true, false, except, except, true, false, except, except, + false, true, except, except, false, true, except, except, + true, true, except, except, true, true, except, except, + except, except, except, except, except, except, except, except, + except, except, except, except, except, except, except, except, + except, except, except, except, except, except, except, except, + except, except, except, except, except, except, except, except, + false, false, true, true, false, false, true, true, + true, false, false, true, false, false, true, true, + false, true, true, false, false, true, true, false, + true, true, false, false, false, true, true, false, + except, except, true, true, except, except, true, true, + except, except, false, true, except, except, true, true, + except, except, true, false, except, except, true, false, + except, except, false, false, except, except, true, false, + false, false, except, except, false, false, except, except, + true, false, except, except, true, false, except, except, + false, true, except, except, false, true, except, except, + true, true, except, except, true, true, except, except, + except, except, except, except, except, except, except, except, + except, except, except, except, except, except, except, except, + except, except, except, except, except, except, except, except, + except, except, except, except, except, except, except, except, + false, false, true, true, false, true, true, false, + true, false, false, true, true, true, false, false, + false, true, true, false, false, true, true, false, + true, true, false, false, true, true, false, false, + except, except, true, true, except, except, true, true, + except, except, false, true, except, except, false, true, + except, except, true, false, except, except, true, false, + except, except, false, false, except, except, false, false, + false, false, except, except, false, true, except, except, + true, false, except, except, true, true, except, except, + false, true, except, except, false, true, except, except, + true, true, except, except, true, true, except, except, + except, except, except, except, except, except, except, except, + except, except, except, except, except, except, except, except, + except, except, except, except, except, except, except, except, + except, except, except, except, except, except, except, except, + false, false, true, true, false, true, true, false, + true, false, false, true, false, true, true, false, + false, true, true, false, false, true, true, false, + true, true, false, false, false, true, true, false, + except, except, true, true, except, except, true, true, + except, except, false, true, except, except, true, true, + except, except, true, false, except, except, true, false, + except, except, false, false, except, except, true, false, + false, false, except, except, false, true, except, except, + true, false, except, except, true, true, except, except, + false, true, except, except, false, true, except, except, + true, true, except, except, true, true, except, except, + except, except, except, except, except, except, except, except, + except, except, except, except, except, except, except, except, + except, except, except, except, except, except, except, except, + except, except, except, except, except, except, except, except, + false, false, true, true, false, false, true, true, + true, false, false, true, false, false, true, true, + false, true, true, false, true, true, false, false, + true, true, false, false, true, true, false, false, + except, except, true, true, except, except, true, true, + except, except, false, true, except, except, true, true, + except, except, true, false, except, except, false, false, + except, except, false, false, except, except, false, false, + false, false, except, except, false, false, except, except, + true, false, except, except, false, false, except, except, + false, true, except, except, true, true, except, except, + true, true, except, except, true, true, except, except, + except, except, except, except, except, except, except, except, + except, except, except, except, except, except, except, except, + except, except, except, except, except, except, except, except, + except, except, except, except, except, except, except, except, + false, false, true, true, false, false, true, true, + true, false, false, true, false, false, true, true, + false, true, true, false, true, true, false, false, + true, true, false, false, true, true, false, false, + except, except, true, true, except, except, true, true, + except, except, false, true, except, except, true, true, + except, except, true, false, except, except, false, false, + except, except, false, false, except, except, false, false, + false, false, except, except, false, false, except, except, + true, false, except, except, false, false, except, except, + false, true, except, except, true, true, except, except, + true, true, except, except, true, true, except, except, + except, except, except, except, except, except, except, except, + except, except, except, except, except, except, except, except, + except, except, except, except, except, except, except, except, + except, except, except, except, except, except, except, except, + false, false, true, true, true, true, false, false, + true, false, false, true, true, true, false, false, + false, true, true, false, true, true, false, false, + true, true, false, false, true, true, false, false, + except, except, true, true, except, except, true, true, + except, except, false, true, except, except, true, true, + except, except, true, false, except, except, false, false, + except, except, false, false, except, except, false, false, + false, false, except, except, true, true, except, except, + true, false, except, except, true, true, except, except, + false, true, except, except, true, true, except, except, + true, true, except, except, true, true, except, except, + except, except, except, except, except, except, except, except, + except, except, except, except, except, except, except, except, + except, except, except, except, except, except, except, except, + except, except, except, except, except, except, except, except, + false, false, true, true, true, true, false, false, + true, false, false, true, true, true, false, false, + false, true, true, false, true, true, false, false, + true, true, false, false, true, true, false, false, + except, except, true, true, except, except, true, true, + except, except, false, true, except, except, true, true, + except, except, true, false, except, except, false, false, + except, except, false, false, except, except, false, false, + false, false, except, except, true, true, except, except, + true, false, except, except, true, true, except, except, + false, true, except, except, true, true, except, except, + true, true, except, except, true, true, except, except, + except, except, except, except, except, except, except, except, + except, except, except, except, except, except, except, except, + except, except, except, except, except, except, except, except, + except, except, except, except, except, except, except, except, + false, false, true, true, false, false, true, true, + true, false, false, true, true, true, false, false, + false, true, true, false, false, false, true, true, + true, true, false, false, true, true, false, false, + except, except, true, true, except, except, true, true, + except, except, false, true, except, except, false, false, + except, except, true, false, except, except, true, true, + except, except, false, false, except, except, false, false, + false, false, except, except, false, false, except, except, + true, false, except, except, true, true, except, except, + false, true, except, except, false, false, except, except, + true, true, except, except, true, true, except, except, + except, except, except, except, except, except, except, except, + except, except, except, except, except, except, except, except, + except, except, except, except, except, except, except, except, + except, except, except, except, except, except, except, except, + false, false, true, true, false, false, true, true, + true, false, false, true, false, false, true, true, + false, true, true, false, false, false, true, true, + true, true, false, false, false, false, true, true, + except, except, true, true, except, except, true, true, + except, except, false, true, except, except, true, true, + except, except, true, false, except, except, true, true, + except, except, false, false, except, except, true, true, + false, false, except, except, false, false, except, except, + true, false, except, except, true, true, except, except, + false, true, except, except, false, false, except, except, + true, true, except, except, true, true, except, except, + except, except, except, except, except, except, except, except, + except, except, except, except, except, except, except, except, + except, except, except, except, except, except, except, except, + except, except, except, except, except, except, except, except, + false, false, true, true, false, false, true, true, + true, false, false, true, true, true, false, false, + false, true, true, false, false, false, true, true, + true, true, false, false, true, true, false, false, + except, except, true, true, except, except, true, true, + except, except, false, true, except, except, false, false, + except, except, true, false, except, except, true, true, + except, except, false, false, except, except, false, false, + false, false, except, except, false, false, except, except, + true, false, except, except, true, true, except, except, + false, true, except, except, false, false, except, except, + true, true, except, except, true, true, except, except, + except, except, except, except, except, except, except, except, + except, except, except, except, except, except, except, except, + except, except, except, except, except, except, except, except, + except, except, except, except, except, except, except, except, + false, false, true, true, false, false, true, true, + true, false, false, true, false, false, true, true, + false, true, true, false, false, false, true, true, + true, true, false, false, false, false, true, true, + except, except, true, true, except, except, true, true, + except, except, false, true, except, except, true, true, + except, except, true, false, except, except, true, true, + except, except, false, false, except, except, true, true, + false, false, except, except, false, false, except, except, + true, false, except, except, true, true, except, except, + false, true, except, except, false, false, except, except, + true, true, except, except, true, true, except, except, + except, except, except, except, except, except, except, except, + except, except, except, except, except, except, except, except, + except, except, except, except, except, except, except, except, + except, except, except, except, except, except, except, except, + false, false, true, true, false, false, true, true, + true, false, false, true, false, false, true, true, + false, true, true, false, true, true, false, false, + true, true, false, false, true, true, false, false, + except, except, true, true, except, except, true, true, + except, except, false, true, except, except, true, true, + except, except, true, false, except, except, false, false, + except, except, false, false, except, except, false, false, + false, false, except, except, false, false, except, except, + true, false, except, except, false, false, except, except, + false, true, except, except, true, true, except, except, + true, true, except, except, true, true, except, except, + except, except, except, except, except, except, except, except, + except, except, except, except, except, except, except, except, + except, except, except, except, except, except, except, except, + except, except, except, except, except, except, except, except, + false, false, true, true, false, false, true, true, + true, false, false, true, false, false, true, true, + false, true, true, false, true, true, false, false, + true, true, false, false, true, true, false, false, + except, except, true, true, except, except, true, true, + except, except, false, true, except, except, true, true, + except, except, true, false, except, except, false, false, + except, except, false, false, except, except, false, false, + false, false, except, except, false, false, except, except, + true, false, except, except, false, false, except, except, + false, true, except, except, true, true, except, except, + true, true, except, except, true, true, except, except, + except, except, except, except, except, except, except, except, + except, except, except, except, except, except, except, except, + except, except, except, except, except, except, except, except, + except, except, except, except, except, except, except, except, + false, false, true, true, true, true, false, false, + true, false, false, true, true, true, false, false, + false, true, true, false, true, true, false, false, + true, true, false, false, true, true, false, false, + except, except, true, true, except, except, true, true, + except, except, false, true, except, except, true, true, + except, except, true, false, except, except, false, false, + except, except, false, false, except, except, false, false, + false, false, except, except, true, true, except, except, + true, false, except, except, true, true, except, except, + false, true, except, except, true, true, except, except, + true, true, except, except, true, true, except, except, + except, except, except, except, except, except, except, except, + except, except, except, except, except, except, except, except, + except, except, except, except, except, except, except, except, + except, except, except, except, except, except, except, except, + false, false, true, true, true, true, false, false, + true, false, false, true, true, true, false, false, + false, true, true, false, true, true, false, false, + true, true, false, false, true, true, false, false, + except, except, true, true, except, except, true, true, + except, except, false, true, except, except, true, true, + except, except, true, false, except, except, false, false, + except, except, false, false, except, except, false, false, + false, false, except, except, true, true, except, except, + true, false, except, except, true, true, except, except, + false, true, except, except, true, true, except, except, + true, true, except, except, true, true, except, except, + except, except, except, except, except, except, except, except, + except, except, except, except, except, except, except, except, + except, except, except, except, except, except, except, except, + except, except, except, except, except, except, except, except]; + +for (let i = 0; i < 256; i++) { + Test(i & 1, i & 2, i & 4, i & 8, i & 0x10, i & 0x20, i & 0x40, i & 0x80); +} + + +function InstanceTest(x, func) { + try { + const answer = addon.doInstanceOf(x, func); + assertEquals(correct_answers[correct_answer_index], answer); + } catch (e) { + assertTrue(/prototype/.test(e)); + assertEquals(correct_answers[correct_answer_index], except); + } + correct_answer_index++; +} + + +function Test(a, b, c, d, e, f, g, h) { + function Foo() { } + + function Bar() { } + + if (c) Foo.prototype = 12; + if (d) Bar.prototype = 13; + const x = a ? new Foo() : new Bar(); + const y = b ? new Foo() : new Bar(); + InstanceTest(x, Foo); + InstanceTest(y, Foo); + InstanceTest(x, Bar); + InstanceTest(y, Bar); + if (e) x.__proto__ = Bar.prototype; // eslint-disable-line no-proto + if (f) y.__proto__ = Foo.prototype; // eslint-disable-line no-proto + if (g) { + Object.setPrototypeOf(x, y); + } else if (h) { + Object.setPrototypeOf(y, x); + } + InstanceTest(x, Foo); + InstanceTest(y, Foo); + InstanceTest(x, Bar); + InstanceTest(y, Bar); +}