1'use strict'; 2const common = require('../../common'); 3const fs = require('fs'); 4const assert = require('assert'); 5 6// Addon is referenced through the eval expression in testFile 7const addon = require(`./build/${common.buildType}/test_general`); 8const path = require('path'); 9 10// This test depends on a number of V8 tests. 11const v8TestsDir = path.resolve(__dirname, '..', '..', '..', 'deps', 'v8', 12 'test', 'mjsunit'); 13const v8TestsDirExists = fs.existsSync(v8TestsDir); 14 15// The following assert functions are referenced by v8's unit tests 16// See for instance deps/v8/test/mjsunit/instanceof.js 17// eslint-disable-next-line no-unused-vars 18function assertTrue(assertion) { 19 return assert.strictEqual(assertion, true); 20} 21 22// eslint-disable-next-line no-unused-vars 23function assertFalse(assertion) { 24 assert.strictEqual(assertion, false); 25} 26 27// eslint-disable-next-line no-unused-vars 28function assertEquals(leftHandSide, rightHandSide) { 29 assert.strictEqual(leftHandSide, rightHandSide); 30} 31 32// eslint-disable-next-line no-unused-vars 33function assertThrows(statement) { 34 assert.throws(function() { 35 eval(statement); 36 }, Error); 37} 38 39function testFile(fileName) { 40 try { 41 const contents = fs.readFileSync(fileName, { encoding: 'utf8' }); 42 eval(contents.replace(/[(]([^\s(]+)\s+instanceof\s+([^)]+)[)]/g, 43 '(addon.doInstanceOf($1, $2))')); 44 } catch (err) { 45 // This test depends on V8 test files, which may not exist in downloaded 46 // archives. Emit a warning if the tests cannot be found instead of failing. 47 if (err.code === 'ENOENT' && !v8TestsDirExists) 48 process.emitWarning(`test file ${fileName} does not exist.`); 49 else 50 throw err; 51 } 52} 53 54testFile(path.join(v8TestsDir, 'instanceof.js')); 55testFile(path.join(v8TestsDir, 'instanceof-2.js')); 56 57// We can only perform this test if we have a working Symbol.hasInstance 58if (typeof Symbol !== 'undefined' && 'hasInstance' in Symbol && 59 typeof Symbol.hasInstance === 'symbol') { 60 61 function compareToNative(theObject, theConstructor) { 62 assert.strictEqual( 63 addon.doInstanceOf(theObject, theConstructor), 64 (theObject instanceof theConstructor) 65 ); 66 } 67 68 function MyClass() {} 69 Object.defineProperty(MyClass, Symbol.hasInstance, { 70 value: function(candidate) { 71 return 'mark' in candidate; 72 } 73 }); 74 75 function MySubClass() {} 76 MySubClass.prototype = new MyClass(); 77 78 let x = new MySubClass(); 79 let y = new MySubClass(); 80 x.mark = true; 81 82 compareToNative(x, MySubClass); 83 compareToNative(y, MySubClass); 84 compareToNative(x, MyClass); 85 compareToNative(y, MyClass); 86 87 x = new MyClass(); 88 y = new MyClass(); 89 x.mark = true; 90 91 compareToNative(x, MySubClass); 92 compareToNative(y, MySubClass); 93 compareToNative(x, MyClass); 94 compareToNative(y, MyClass); 95} 96