11var test = require ( 'tape' ) ;
22require ( './_tape' ) ;
33var assign = require ( 'object.assign' ) ;
4+ var gOPDs = require ( 'object.getownpropertydescriptors' ) ;
45var hasSymbols = require ( 'has-symbols' ) ( ) ;
6+ var hasTypedArrays = require ( 'has-typed-arrays' ) ( ) ;
7+ var semver = require ( 'semver' ) ;
8+
9+ var safeBuffer = typeof Buffer === 'function' ? Buffer . from && Buffer . from . length > 1 ? Buffer . from : Buffer : null ;
10+
11+ var isNode = typeof process === 'object' && typeof process . version === 'string' ;
512
613function tag ( obj , value ) {
714 if ( hasSymbols && Symbol . toStringTags && Object . defineProperty ) {
@@ -220,11 +227,28 @@ test('Dates', function (t) {
220227 st . end ( ) ;
221228 } ) ;
222229
230+ t . test ( 'fake Date' , { skip : ! hasDunderProto } , function ( st ) {
231+ var a = new Date ( 2000 ) ;
232+ var b = tag ( Object . create (
233+ a . __proto__ , // eslint-disable-line no-proto
234+ gOPDs ( a )
235+ ) , 'Date' ) ;
236+
237+ st . deepEqualTest (
238+ a ,
239+ b ,
240+ 'Date, and fake Date' ,
241+ false ,
242+ false
243+ ) ;
244+
245+ st . end ( ) ;
246+ } ) ;
247+
223248 t . end ( ) ;
224249} ) ;
225250
226251test ( 'buffers' , { skip : typeof Buffer !== 'function' } , function ( t ) {
227- var safeBuffer = Buffer . from && Buffer . from . length > 1 ? Buffer . from : Buffer ;
228252 /* eslint no-buffer-constructor: 1, new-cap: 1 */
229253 t . deepEqualTest (
230254 safeBuffer ( 'xyz' ) ,
@@ -473,6 +497,18 @@ test('regexen', function (t) {
473497 t . deepEqualTest ( / a b c / , / a b c / , 'two abc regexes' , true , true , false ) ;
474498 t . deepEqualTest ( / x y z / , / x y z / , 'two xyz regexes' , true , true , false ) ;
475499
500+ t . test ( 'fake RegExp' , { skip : ! hasDunderProto } , function ( st ) {
501+ var a = / a b c / g;
502+ var b = tag ( Object . create (
503+ a . __proto__ , // eslint-disable-line no-proto
504+ gOPDs ( a )
505+ ) , 'RegExp' ) ;
506+
507+ st . deepEqualTest ( a , b , 'regex and fake regex' , false , false ) ;
508+
509+ st . end ( ) ;
510+ } ) ;
511+
476512 t . end ( ) ;
477513} ) ;
478514
@@ -506,6 +542,23 @@ test('Errors', function (t) {
506542 false
507543 ) ;
508544
545+ t . test ( 'fake error' , { skip : ! hasDunderProto } , function ( st ) {
546+ var a = tag ( {
547+ __proto__ : null
548+ } , 'Error' ) ;
549+ var b = new RangeError ( 'abc' ) ;
550+ b . __proto__ = null ; // eslint-disable-line no-proto
551+
552+ st . deepEqualTest (
553+ a ,
554+ b ,
555+ 'null object faking as an Error, RangeError with null proto' ,
556+ false ,
557+ false
558+ ) ;
559+ st . end ( ) ;
560+ } ) ;
561+
509562 t . end ( ) ;
510563} ) ;
511564
@@ -525,22 +578,23 @@ test('error = Object', function (t) {
525578 t . end ( ) ;
526579} ) ;
527580
528- test ( '[[Prototypes]]' , { skip : ! Object . getPrototypeOf } , function ( t ) {
581+ test ( '[[Prototypes]]' , function ( t ) {
529582 function C ( ) { }
530583 var instance = new C ( ) ;
531584 delete instance . constructor ;
532585
533586 t . deepEqualTest ( { } , instance , 'two identical objects with different [[Prototypes]]' , true , false ) ;
534587
535- t . test ( 'Dates with different prototypes' , { skip : ! Object . setPrototypeOf } , function ( st ) {
588+ t . test ( 'Dates with different prototypes' , { skip : ! hasDunderProto } , function ( st ) {
536589 var d1 = new Date ( 0 ) ;
537590 var d2 = new Date ( 0 ) ;
538591
539592 t . deepEqualTest ( d1 , d2 , 'two dates with the same timestamp' , true , true ) ;
540593
541- var newProto = { } ;
542- Object . setPrototypeOf ( newProto , Date . prototype ) ;
543- Object . setPrototypeOf ( d2 , newProto ) ;
594+ var newProto = {
595+ __proto__ : Date . prototype
596+ } ;
597+ d2 . __proto__ = newProto ; // eslint-disable-line no-proto
544598 st . ok ( d2 instanceof Date , 'd2 is still a Date instance after tweaking [[Prototype]]' ) ;
545599
546600 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) {
613667 t . end ( ) ;
614668} ) ;
615669
616- var isAssertAndNode1321 = process . env . ASSERT && process . version . replace ( / ^ v / g , '' ) . replace ( / [ ^ . ] + (?: . ) ? / g , function ( x , i ) { return x * Math . pow ( 10 , i ) ; } ) <= '1320000' ;
617- test ( 'fake arrays: extra keys will be tested' , { skip : ! hasDunderProto || isAssertAndNode1321 } , function ( t ) {
670+ var isAssertAndNode1321 = isNode && process . env . ASSERT && semver . satisfies ( process . version , '>= 13.2.0' ) ;
671+ test ( 'fake arrays: extra keys will be tested' , { skip : ! hasDunderProto || ! isAssertAndNode1321 } , function ( t ) {
618672 var a = tag ( {
619673 __proto__ : Array . prototype ,
620674 0 : 1 ,
@@ -629,6 +683,17 @@ test('fake arrays: extra keys will be tested', { skip: !hasDunderProto || isAsse
629683 }
630684
631685 t . deepEqualTest ( a , [ 1 , 1 ] , 'fake and real array with same contents and [[Prototype]]' , false , false ) ;
686+
687+ var b = tag ( / a b c / , 'Array' ) ;
688+ b . __proto__ = Array . prototype ; // eslint-disable-line no-proto
689+ b . length = 3 ;
690+ if ( Object . defineProperty ) {
691+ Object . defineProperty ( b , 'length' , {
692+ enumerable : false
693+ } ) ;
694+ }
695+ t . deepEqualTest ( b , [ 'a' , 'b' , 'c' ] , 'regex faking as array, and array' , false , false ) ;
696+
632697 t . end ( ) ;
633698} ) ;
634699
@@ -665,3 +730,50 @@ test('circular references', function (t) {
665730
666731 t . end ( ) ;
667732} ) ;
733+
734+ // io.js v2 is the only version where `console.log(b)` below is catchable
735+ var isNodeWhereBufferBreaks = isNode && semver . satisfies ( process . version , '< 3' ) ;
736+
737+ test ( 'TypedArrays' , { skip : ! hasTypedArrays } , function ( t ) {
738+ t . test ( 'Buffer faked as Uint8Array' , { skip : typeof Buffer !== 'function' || ! Object . create || ! hasDunderProto } , function ( st ) {
739+ var a = safeBuffer ( 'test' ) ;
740+ var b = tag ( Object . create (
741+ a . __proto__ , // eslint-disable-line no-proto
742+ assign ( gOPDs ( a ) , {
743+ length : {
744+ enumerable : false ,
745+ value : 4
746+ }
747+ } )
748+ ) , 'Uint8Array' ) ;
749+
750+ st . deepEqualTest (
751+ a ,
752+ b ,
753+ 'Buffer and Uint8Array' ,
754+ isNode0x ,
755+ isNode0x
756+ ) ;
757+
758+ st . end ( ) ;
759+ } ) ;
760+
761+ t . test ( 'one TypedArray faking as another' , { skip : ! hasDunderProto } , function ( st ) {
762+ /* globals Uint8Array, Int8Array */
763+ var a = new Uint8Array ( 10 ) ;
764+ var b = tag ( new Int8Array ( 10 ) , 'Uint8Array' ) ;
765+ b . __proto__ = Uint8Array . prototype ; // eslint-disable-line no-proto
766+
767+ st . deepEqualTest (
768+ a ,
769+ b ,
770+ 'Uint8Array, and Int8Array pretending to be a Uint8Array' ,
771+ false ,
772+ false
773+ ) ;
774+
775+ st . end ( ) ;
776+ } ) ;
777+
778+ t . end ( ) ;
779+ } ) ;
0 commit comments