11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ciconst common = require('../../common');
31cb0ef41Sopenharmony_ciconst fs = require('fs');
41cb0ef41Sopenharmony_ciconst assert = require('assert');
51cb0ef41Sopenharmony_ci
61cb0ef41Sopenharmony_ci// Addon is referenced through the eval expression in testFile
71cb0ef41Sopenharmony_ciconst addon = require(`./build/${common.buildType}/test_general`);
81cb0ef41Sopenharmony_ciconst path = require('path');
91cb0ef41Sopenharmony_ci
101cb0ef41Sopenharmony_ci// This test depends on a number of V8 tests.
111cb0ef41Sopenharmony_ciconst v8TestsDir = path.resolve(__dirname, '..', '..', '..', 'deps', 'v8',
121cb0ef41Sopenharmony_ci                                'test', 'mjsunit');
131cb0ef41Sopenharmony_ciconst v8TestsDirExists = fs.existsSync(v8TestsDir);
141cb0ef41Sopenharmony_ci
151cb0ef41Sopenharmony_ci// The following assert functions are referenced by v8's unit tests
161cb0ef41Sopenharmony_ci// See for instance deps/v8/test/mjsunit/instanceof.js
171cb0ef41Sopenharmony_ci// eslint-disable-next-line no-unused-vars
181cb0ef41Sopenharmony_cifunction assertTrue(assertion) {
191cb0ef41Sopenharmony_ci  return assert.strictEqual(assertion, true);
201cb0ef41Sopenharmony_ci}
211cb0ef41Sopenharmony_ci
221cb0ef41Sopenharmony_ci// eslint-disable-next-line no-unused-vars
231cb0ef41Sopenharmony_cifunction assertFalse(assertion) {
241cb0ef41Sopenharmony_ci  assert.strictEqual(assertion, false);
251cb0ef41Sopenharmony_ci}
261cb0ef41Sopenharmony_ci
271cb0ef41Sopenharmony_ci// eslint-disable-next-line no-unused-vars
281cb0ef41Sopenharmony_cifunction assertEquals(leftHandSide, rightHandSide) {
291cb0ef41Sopenharmony_ci  assert.strictEqual(leftHandSide, rightHandSide);
301cb0ef41Sopenharmony_ci}
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_ci// eslint-disable-next-line no-unused-vars
331cb0ef41Sopenharmony_cifunction assertThrows(statement) {
341cb0ef41Sopenharmony_ci  assert.throws(function() {
351cb0ef41Sopenharmony_ci    eval(statement);
361cb0ef41Sopenharmony_ci  }, Error);
371cb0ef41Sopenharmony_ci}
381cb0ef41Sopenharmony_ci
391cb0ef41Sopenharmony_cifunction testFile(fileName) {
401cb0ef41Sopenharmony_ci  try {
411cb0ef41Sopenharmony_ci    const contents = fs.readFileSync(fileName, { encoding: 'utf8' });
421cb0ef41Sopenharmony_ci    eval(contents.replace(/[(]([^\s(]+)\s+instanceof\s+([^)]+)[)]/g,
431cb0ef41Sopenharmony_ci                          '(addon.doInstanceOf($1, $2))'));
441cb0ef41Sopenharmony_ci  } catch (err) {
451cb0ef41Sopenharmony_ci    // This test depends on V8 test files, which may not exist in downloaded
461cb0ef41Sopenharmony_ci    // archives. Emit a warning if the tests cannot be found instead of failing.
471cb0ef41Sopenharmony_ci    if (err.code === 'ENOENT' && !v8TestsDirExists)
481cb0ef41Sopenharmony_ci      process.emitWarning(`test file ${fileName} does not exist.`);
491cb0ef41Sopenharmony_ci    else
501cb0ef41Sopenharmony_ci      throw err;
511cb0ef41Sopenharmony_ci  }
521cb0ef41Sopenharmony_ci}
531cb0ef41Sopenharmony_ci
541cb0ef41Sopenharmony_citestFile(path.join(v8TestsDir, 'instanceof.js'));
551cb0ef41Sopenharmony_citestFile(path.join(v8TestsDir, 'instanceof-2.js'));
561cb0ef41Sopenharmony_ci
571cb0ef41Sopenharmony_ci// We can only perform this test if we have a working Symbol.hasInstance
581cb0ef41Sopenharmony_ciif (typeof Symbol !== 'undefined' && 'hasInstance' in Symbol &&
591cb0ef41Sopenharmony_ci    typeof Symbol.hasInstance === 'symbol') {
601cb0ef41Sopenharmony_ci
611cb0ef41Sopenharmony_ci  function compareToNative(theObject, theConstructor) {
621cb0ef41Sopenharmony_ci    assert.strictEqual(
631cb0ef41Sopenharmony_ci      addon.doInstanceOf(theObject, theConstructor),
641cb0ef41Sopenharmony_ci      (theObject instanceof theConstructor),
651cb0ef41Sopenharmony_ci    );
661cb0ef41Sopenharmony_ci  }
671cb0ef41Sopenharmony_ci
681cb0ef41Sopenharmony_ci  function MyClass() {}
691cb0ef41Sopenharmony_ci  Object.defineProperty(MyClass, Symbol.hasInstance, {
701cb0ef41Sopenharmony_ci    value: function(candidate) {
711cb0ef41Sopenharmony_ci      return 'mark' in candidate;
721cb0ef41Sopenharmony_ci    },
731cb0ef41Sopenharmony_ci  });
741cb0ef41Sopenharmony_ci
751cb0ef41Sopenharmony_ci  function MySubClass() {}
761cb0ef41Sopenharmony_ci  MySubClass.prototype = new MyClass();
771cb0ef41Sopenharmony_ci
781cb0ef41Sopenharmony_ci  let x = new MySubClass();
791cb0ef41Sopenharmony_ci  let y = new MySubClass();
801cb0ef41Sopenharmony_ci  x.mark = true;
811cb0ef41Sopenharmony_ci
821cb0ef41Sopenharmony_ci  compareToNative(x, MySubClass);
831cb0ef41Sopenharmony_ci  compareToNative(y, MySubClass);
841cb0ef41Sopenharmony_ci  compareToNative(x, MyClass);
851cb0ef41Sopenharmony_ci  compareToNative(y, MyClass);
861cb0ef41Sopenharmony_ci
871cb0ef41Sopenharmony_ci  x = new MyClass();
881cb0ef41Sopenharmony_ci  y = new MyClass();
891cb0ef41Sopenharmony_ci  x.mark = true;
901cb0ef41Sopenharmony_ci
911cb0ef41Sopenharmony_ci  compareToNative(x, MySubClass);
921cb0ef41Sopenharmony_ci  compareToNative(y, MySubClass);
931cb0ef41Sopenharmony_ci  compareToNative(x, MyClass);
941cb0ef41Sopenharmony_ci  compareToNative(y, MyClass);
951cb0ef41Sopenharmony_ci}
96