From 7abd5308dc7b92915b6a48ae57fc4f86bbb1aeed Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Mon, 2 Dec 2019 13:27:54 -0800 Subject: [PATCH] [Tests] add passing tests from node core See https://github.com/nodejs/node/pull/30764 --- package.json | 3 ++ test/cmp.js | 127 +++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 122 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index 2619c86..55ca6bc 100644 --- a/package.json +++ b/package.json @@ -47,8 +47,11 @@ "auto-changelog": "^1.16.2", "eslint": "^6.7.2", "has-symbols": "^1.0.1", + "has-typed-arrays": "^1.0.0", "object.assign": "^4.1.0", + "object.getownpropertydescriptors": "^2.0.3", "safe-publish-latest": "^1.1.4", + "semver": "^6.3.0", "tape": "^4.11.0" }, "repository": { diff --git a/test/cmp.js b/test/cmp.js index a792018..26a736c 100644 --- a/test/cmp.js +++ b/test/cmp.js @@ -1,7 +1,14 @@ var test = require('tape'); require('./_tape'); var assign = require('object.assign'); +var gOPDs = require('object.getownpropertydescriptors'); var hasSymbols = require('has-symbols')(); +var hasTypedArrays = require('has-typed-arrays')(); +var semver = require('semver'); + +var safeBuffer = typeof Buffer === 'function' ? Buffer.from && Buffer.from.length > 1 ? Buffer.from : Buffer : null; + +var isNode = typeof process === 'object' && typeof process.version === 'string'; function tag(obj, value) { if (hasSymbols && Symbol.toStringTags && Object.defineProperty) { @@ -220,11 +227,28 @@ test('Dates', function (t) { st.end(); }); + t.test('fake Date', { skip: !hasDunderProto }, function (st) { + var a = new Date(2000); + var b = tag(Object.create( + a.__proto__, // eslint-disable-line no-proto + gOPDs(a) + ), 'Date'); + + st.deepEqualTest( + a, + b, + 'Date, and fake Date', + false, + false + ); + + st.end(); + }); + t.end(); }); test('buffers', { skip: typeof Buffer !== 'function' }, function (t) { - var safeBuffer = Buffer.from && Buffer.from.length > 1 ? Buffer.from : Buffer; /* eslint no-buffer-constructor: 1, new-cap: 1 */ t.deepEqualTest( safeBuffer('xyz'), @@ -473,6 +497,18 @@ test('regexen', function (t) { t.deepEqualTest(/abc/, /abc/, 'two abc regexes', true, true, false); t.deepEqualTest(/xyz/, /xyz/, 'two xyz regexes', true, true, false); + t.test('fake RegExp', { skip: !hasDunderProto }, function (st) { + var a = /abc/g; + var b = tag(Object.create( + a.__proto__, // eslint-disable-line no-proto + gOPDs(a) + ), 'RegExp'); + + st.deepEqualTest(a, b, 'regex and fake regex', false, false); + + st.end(); + }); + t.end(); }); @@ -506,6 +542,23 @@ test('Errors', function (t) { false ); + t.test('fake error', { skip: !hasDunderProto }, function (st) { + var a = tag({ + __proto__: null + }, 'Error'); + var b = new RangeError('abc'); + b.__proto__ = null; // eslint-disable-line no-proto + + st.deepEqualTest( + a, + b, + 'null object faking as an Error, RangeError with null proto', + false, + false + ); + st.end(); + }); + t.end(); }); @@ -525,22 +578,23 @@ test('error = Object', function (t) { t.end(); }); -test('[[Prototypes]]', { skip: !Object.getPrototypeOf }, function (t) { +test('[[Prototypes]]', function (t) { function C() {} var instance = new C(); delete instance.constructor; t.deepEqualTest({}, instance, 'two identical objects with different [[Prototypes]]', true, false); - t.test('Dates with different prototypes', { skip: !Object.setPrototypeOf }, function (st) { + t.test('Dates with different prototypes', { skip: !hasDunderProto }, function (st) { var d1 = new Date(0); var d2 = new Date(0); t.deepEqualTest(d1, d2, 'two dates with the same timestamp', true, true); - var newProto = {}; - Object.setPrototypeOf(newProto, Date.prototype); - Object.setPrototypeOf(d2, newProto); + var newProto = { + __proto__: Date.prototype + }; + d2.__proto__ = newProto; // eslint-disable-line no-proto st.ok(d2 instanceof Date, 'd2 is still a Date instance after tweaking [[Prototype]]'); t.deepEqualTest(d1, d2, 'two dates with the same timestamp and different [[Prototype]]', true, false); @@ -613,8 +667,8 @@ test('getters', { skip: !Object.defineProperty }, function (t) { t.end(); }); -var isAssertAndNode1321 = process.env.ASSERT && process.version.replace(/^v/g, '').replace(/[^.]+(?:.)?/g, function (x, i) { return x * Math.pow(10, i); }) <= '1320000'; -test('fake arrays: extra keys will be tested', { skip: !hasDunderProto || isAssertAndNode1321 }, function (t) { +var isAssertAndNode1321 = isNode && process.env.ASSERT && semver.satisfies(process.version, '>= 13.2.0'); +test('fake arrays: extra keys will be tested', { skip: !hasDunderProto || !isAssertAndNode1321 }, function (t) { var a = tag({ __proto__: Array.prototype, 0: 1, @@ -629,6 +683,17 @@ test('fake arrays: extra keys will be tested', { skip: !hasDunderProto || isAsse } t.deepEqualTest(a, [1, 1], 'fake and real array with same contents and [[Prototype]]', false, false); + + var b = tag(/abc/, 'Array'); + b.__proto__ = Array.prototype; // eslint-disable-line no-proto + b.length = 3; + if (Object.defineProperty) { + Object.defineProperty(b, 'length', { + enumerable: false + }); + } + t.deepEqualTest(b, ['a', 'b', 'c'], 'regex faking as array, and array', false, false); + t.end(); }); @@ -665,3 +730,49 @@ test('circular references', function (t) { t.end(); }); + +var isNode0x = isNode && semver.satisfies(process.version, '< 1'); + +test('TypedArrays', { skip: !hasTypedArrays }, function (t) { + t.test('Buffer faked as Uint8Array', { skip: typeof Buffer !== 'function' || !Object.create || !hasDunderProto }, function (st) { + var a = safeBuffer('test'); + var b = tag(Object.create( + a.__proto__, // eslint-disable-line no-proto + assign(gOPDs(a), { + length: { + enumerable: false, + value: 4 + } + }) + ), 'Uint8Array'); + + st.deepEqualTest( + a, + b, + 'Buffer and Uint8Array', + isNode0x, + isNode0x + ); + + st.end(); + }); + + t.test('one TypedArray faking as another', { skip: !hasDunderProto }, function (st) { + /* globals Uint8Array, Int8Array */ + var a = new Uint8Array(10); + var b = tag(new Int8Array(10), 'Uint8Array'); + b.__proto__ = Uint8Array.prototype; // eslint-disable-line no-proto + + st.deepEqualTest( + a, + b, + 'Uint8Array, and Int8Array pretending to be a Uint8Array', + false, + false + ); + + st.end(); + }); + + t.end(); +});