* QUnit.diff("the quick brown fox jumped over", "the quick fox jumps over") == "the quick <del>brown </del> fox <del>jumped </del><ins>jumps </ins> over"
equals(QUnit.equiv(a1,a2),true,"Same property, same constructor");
// b1.fn and b2.fn are functions but they are different references
// But we decided to skip function for instances.
equals(QUnit.equiv(b1,b2),true,"Same property, same constructor");
equals(QUnit.equiv(a1,b1),false,"Same properties but different constructor");// failed
functionCar(year){
varprivateVar=0;
this.year=year;
this.isOld=function(){
returnyear>10;
};
}
functionHuman(year){
varprivateVar=1;
this.year=year;
this.isOld=function(){
returnyear>80;
};
}
varcar=newCar(30);
varcarSame=newCar(30);
varcarDiff=newCar(10);
varhuman=newHuman(30);
vardiff={
year:30
};
varsame={
year:30,
isOld:function(){}
};
equals(QUnit.equiv(car,car),true);
equals(QUnit.equiv(car,carDiff),false);
equals(QUnit.equiv(car,carSame),true);
equals(QUnit.equiv(car,human),false);
});
test("Complex Instances Nesting (with function value in literals and/or in nested instances)",function(){
functionA(fn){
this.a={};
this.fn=fn;
this.b={a:[]};
this.o={};
this.fn1=fn;
}
functionB(fn){
this.fn=fn;
this.fn1=function(){};
this.a=newA(function(){});
}
functionfnOutside(){
}
functionC(fn){
functionfnInside(){
}
this.x=10;
this.fn=fn;
this.fn1=function(){};
this.fn2=fnInside;
this.fn3={
a:true,
b:fnOutside// ok make reference to a function in all instances scope
};
this.o1={};
// This function will be ignored.
// Even if it is not visible for all instances (e.g. locked in a closures),
// it is from a property that makes part of an instance (e.g. from the C constructor)
this.b1=newB(function(){});
this.b2=newB({
x:{
b2:newB(function(){})
}
});
}
functionD(fn){
functionfnInside(){
}
this.x=10;
this.fn=fn;
this.fn1=function(){};
this.fn2=fnInside;
this.fn3={
a:true,
b:fnOutside,// ok make reference to a function in all instances scope
// This function won't be ingored.
// It isn't visible for all C insances
// and it is not in a property of an instance. (in an Object instances e.g. the object literal)
c:fnInside
};
this.o1={};
// This function will be ignored.
// Even if it is not visible for all instances (e.g. locked in a closures),
// it is from a property that makes part of an instance (e.g. from the C constructor)
this.b1=newB(function(){});
this.b2=newB({
x:{
b2:newB(function(){})
}
});
}
functionE(fn){
functionfnInside(){
}
this.x=10;
this.fn=fn;
this.fn1=function(){};
this.fn2=fnInside;
this.fn3={
a:true,
b:fnOutside// ok make reference to a function in all instances scope
};
this.o1={};
// This function will be ignored.
// Even if it is not visible for all instances (e.g. locked in a closures),
// it is from a property that makes part of an instance (e.g. from the C constructor)
this.b1=newB(function(){});
this.b2=newB({
x:{
b1:newB({a:function(){}}),
b2:newB(function(){})
}
});
}
vara1=newA(function(){});
vara2=newA(function(){});
equals(QUnit.equiv(a1,a2),true);
equals(QUnit.equiv(a1,a2),true);// different instances
varb1=newB(function(){});
varb2=newB(function(){});
equals(QUnit.equiv(b1,b2),true);
varc1=newC(function(){});
varc2=newC(function(){});
equals(QUnit.equiv(c1,c2),true);
vard1=newD(function(){});
vard2=newD(function(){});
equals(QUnit.equiv(d1,d2),false);
vare1=newE(function(){});
vare2=newE(function(){});
equals(QUnit.equiv(e1,e2),false);
});
test('object with references to self wont loop',function(){
varcircularA={
abc:null
},circularB={
abc:null
};
circularA.abc=circularA;
circularB.abc=circularB;
equals(QUnit.equiv(circularA,circularB),true,"Should not repeat test on object (ambigous test)");
circularA.def=1;
circularB.def=1;
equals(QUnit.equiv(circularA,circularB),true,"Should not repeat test on object (ambigous test)");
circularA.def=1;
circularB.def=0;
equals(QUnit.equiv(circularA,circularB),false,"Should not repeat test on object (unambigous test)");
});
test('array with references to self wont loop',function(){
varcircularA=[],
circularB=[];
circularA.push(circularA);
circularB.push(circularB);
equals(QUnit.equiv(circularA,circularB),true,"Should not repeat test on array (ambigous test)");
circularA.push('abc');
circularB.push('abc');
equals(QUnit.equiv(circularA,circularB),true,"Should not repeat test on array (ambigous test)");
circularA.push('hello');
circularB.push('goodbye');
equals(QUnit.equiv(circularA,circularB),false,"Should not repeat test on array (unambigous test)");
});
test('mixed object/array with references to self wont loop',function(){
varcircularA=[{abc:null}],
circularB=[{abc:null}];
circularA[0].abc=circularA;
circularB[0].abc=circularB;
circularA.push(circularA);
circularB.push(circularB);
equals(QUnit.equiv(circularA,circularB),true,"Should not repeat test on object/array (ambigous test)");
circularA[0].def=1;
circularB[0].def=1;
equals(QUnit.equiv(circularA,circularB),true,"Should not repeat test on object/array (ambigous test)");
circularA[0].def=1;
circularB[0].def=0;
equals(QUnit.equiv(circularA,circularB),false,"Should not repeat test on object/array (unambigous test)");
});
test("Test that must be done at the end because they extend some primitive's prototype",function(){
// Try that a function looks like our regular expression.
// This tests if we check that a and b are really both instance of RegExp
Function.prototype.global=true;
Function.prototype.multiline=true;
Function.prototype.ignoreCase=false;
Function.prototype.source="my regex";
varre=/my regex/gm;
equals(QUnit.equiv(re,function(){}),false,"A function that looks that a regex isn't a regex");
// This test will ensures it works in both ways, and ALSO especially that we can make differences
// between RegExp and Function constructor because typeof on a RegExpt instance is "function"
equals(QUnit.equiv(function(){},re),false,"Same conversely, but ensures that function and regexp are distinct because their constructor are different");