• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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