@@ -18,6 +18,7 @@ var QUnit = {
1818 stats : { all : 0 , bad : 0 } ,
1919 moduleStats : { all : 0 , bad : 0 } ,
2020 started : + new Date ,
21+ updateRate : 1000 ,
2122 blocking : false ,
2223 autorun : false ,
2324 assertions : [ ] ,
@@ -590,8 +591,16 @@ function synchronize( callback ) {
590591}
591592
592593function process ( ) {
594+ var start = ( new Date ( ) ) . getTime ( ) ;
595+
593596 while ( config . queue . length && ! config . blocking ) {
594- config . queue . shift ( ) ( ) ;
597+ if ( config . updateRate <= 0 || ( ( ( new Date ( ) ) . getTime ( ) - start ) < config . updateRate ) ) {
598+ config . queue . shift ( ) ( ) ;
599+
600+ } else {
601+ setTimeout ( process , 13 ) ;
602+ break ;
603+ }
595604 }
596605}
597606
@@ -679,6 +688,7 @@ QUnit.equiv = function () {
679688
680689 var innerEquiv ; // the real equiv function
681690 var callers = [ ] ; // stack to decide between skip/abort functions
691+ var parents = [ ] ; // stack to avoiding loops from circular referencing
682692
683693
684694 // Determine what is o.
@@ -788,28 +798,39 @@ QUnit.equiv = function () {
788798 } ,
789799
790800 "array" : function ( b , a ) {
791- var i ;
801+ var i , j , loop ;
792802 var len ;
793803
794804 // b could be an object literal here
795805 if ( ! ( hoozit ( b ) === "array" ) ) {
796806 return false ;
797- }
798-
807+ }
808+
799809 len = a . length ;
800810 if ( len !== b . length ) { // safe and faster
801811 return false ;
802812 }
813+
814+ //track reference to avoid circular references
815+ parents . push ( a ) ;
803816 for ( i = 0 ; i < len ; i ++ ) {
804- if ( ! innerEquiv ( a [ i ] , b [ i ] ) ) {
817+ loop = false ;
818+ for ( j = 0 ; j < parents . length ; j ++ ) {
819+ if ( parents [ j ] === a [ i ] ) {
820+ loop = true ; //dont rewalk array
821+ }
822+ }
823+ if ( ! loop && ! innerEquiv ( a [ i ] , b [ i ] ) ) {
824+ parents . pop ( ) ;
805825 return false ;
806826 }
807827 }
828+ parents . pop ( ) ;
808829 return true ;
809830 } ,
810831
811832 "object" : function ( b , a ) {
812- var i ;
833+ var i , j , loop ;
813834 var eq = true ; // unless we can proove it
814835 var aProperties = [ ] , bProperties = [ ] ; // collection of strings
815836
@@ -820,18 +841,25 @@ QUnit.equiv = function () {
820841
821842 // stack constructor before traversing properties
822843 callers . push ( a . constructor ) ;
823-
844+ //track reference to avoid circular references
845+ parents . push ( a ) ;
846+
824847 for ( i in a ) { // be strict: don't ensures hasOwnProperty and go deep
825-
848+ loop = false ;
849+ for ( j = 0 ; j < parents . length ; j ++ ) {
850+ if ( parents [ j ] === a [ i ] )
851+ loop = true ; //don't go down the same path twice
852+ }
826853 aProperties . push ( i ) ; // collect a's properties
827854
828- if ( ! innerEquiv ( a [ i ] , b [ i ] ) ) {
855+ if ( ! loop && ! innerEquiv ( a [ i ] , b [ i ] ) ) {
829856 eq = false ;
830857 break ;
831858 }
832859 }
833860
834861 callers . pop ( ) ; // unstack, we are done
862+ parents . pop ( ) ;
835863
836864 for ( i in b ) {
837865 bProperties . push ( i ) ; // collect b's properties
0 commit comments