Home page Forum Wiki Mail Jabber Devel NIX-FILES

AltLUG Git

Git-repositories of Altai Linux User Group

Moved the QUnit test directory into the QUnit directory.
authorJohn Resig <jeresig@gmail.com>
Tue, 29 Sep 2009 22:19:04 +0000 (22:19 +0000)
committerJohn Resig <jeresig@gmail.com>
Tue, 29 Sep 2009 22:19:04 +0000 (22:19 +0000)
test/index.html [new file with mode: 0644]
test/same.js [new file with mode: 0644]
test/test.js [new file with mode: 0644]

diff --git a/test/index.html b/test/index.html
new file mode 100644 (file)
index 0000000..e1a0f85
--- /dev/null
@@ -0,0 +1,243 @@
+<!DOCTYPE html>
+<html lang="en" class="qunit">
+<head>
+       <title>QUnit Test Suite</title>
+       <link rel="stylesheet" href="../testsuite.css" type="text/css" media="screen">
+
+       <script type="text/javascript" src="../testrunner.js"></script>
+       <script type="text/javascript" src="test.js"></script>
+       <script type="text/javascript" src="same.js"></script>
+</head>
+<body class="flora">
+       <h1>QUnit Test Suite</h1>
+       <h2 id="qunit-banner"></h2>
+       <div id="qunit-testrunner-toolbar"></div>
+       <h2 id="qunit-userAgent"></h2>
+
+       <!-- Test HTML -->
+       <div id="other" style="display:none;">
+               <input type="password" name="pw1" id="pw1" value="engfeh" />
+               <input type="password" name="pw2" id="pw2" value="" />
+       </div>
+       <div id="main" style="display:none;">
+               <p id="firstp">See <a id="simon1" href="http://simon.incutio.com/archive/2003/03/25/#getElementsBySelector" rel="bookmark">this blog entry</a> for more information.</p>
+               <p id="ap">
+                       Here are some links in a normal paragraph: <a id="google" href="http://www.google.com/" title="Google!">Google</a>, 
+                       <a id="groups" href="http://groups.google.com/">Google Groups</a>. 
+                       This link has <code><a href="#" id="anchor1">class="blog"</a></code>: 
+                       <a href="http://diveintomark.org/" class="blog" hreflang="en" id="mark">diveintomark</a>
+
+               </p>
+               <div id="foo">
+                       <p id="sndp">Everything inside the red border is inside a div with <code>id="foo"</code>.</p>
+                       <p lang="en" id="en">This is a normal link: <a id="yahoo" href="http://www.yahoo.com/" class="blogTest">Yahoo</a></p>
+                       <p id="sap">This link has <code><a href="#2" id="anchor2">class="blog"</a></code>: <a href="http://simon.incutio.com/" class="blog link" id="simon">Simon Willison's Weblog</a></p>
+
+               </div>
+               <p id="first">Try them out:</p>
+               <ul id="firstUL"></ul>
+               <ol id="empty"></ol>
+               
+               <form id="testForm1">
+                       <input class="{required:true,minlength:2}" title="buga" name="firstname" id="firstname" />
+                       <label id="errorFirstname" for="firstname" class="error">error for firstname</label>
+                       <input class="{required:true}" title="buga" name="lastname" id="lastname" />
+                       <input class="{required:true}" title="something" name="something" id="something" value="something" />
+               </form>
+               
+               <form id="testForm1clean">
+                       <input title="buga" name="firstname" id="firstnamec" />
+                       <label id="errorFirstname" for="firstname" class="error">error for firstname</label>
+                       <input title="buga" name="lastname" id="lastnamec" />
+               </form>
+               
+               <form id="userForm">
+                       <input class="{required:true}" name="username" id="username" />
+               </form>
+               
+               <form method="post" id="signupForm" action="../demo/form.php">
+                       <input id="user" name="user" title="Please enter your username (at least 3 characters)" class="{required:true,minlength:3}" />
+                       <input type="password" name="password" id="password" class="{required:true,minlength:5}" />
+               </form>
+               
+               <form id="testForm2">
+                       <input class="{required:true}" type="radio" name="agree" id="agb" />
+                       <label for="agree" id="agreeLabel" class="xerror">error for agb</label>
+               </form>
+               
+               <form id="testForm3">
+                       <select class="{required:true}" name="meal" id="meal" >
+                               <option value="">Please select...</option>
+                               <option value="1">Food</option>
+                               <option value="2">Milk</option>
+                       </select>
+               </form>
+               <div class="error" id="errorContainer">
+                       <ul>
+                               <li class="error" id="errorWrapper">
+                                       <label for="meal" id="mealLabel" class="error">error for meal</label>
+                               </li>
+                       </ul>
+               </div>
+               
+               <form id="testForm4">
+                       <input class="{foo:true}" name="f1" id="f1" />
+                       <input class="{bar:true}" name="f2" id="f2" />
+               </form>
+               
+               <form id="testForm5">
+                       <input class="{equalTo:'#x2'}" value="x" name="x1" id="x1" />
+                       <input class="{equalTo:'#x1'}" value="y" name="x2" id="x2" />
+               </form>
+               
+               <form id="testForm6">
+                       <input class="{required:true,minlength:2}" type="checkbox" name="check" id="form6check1" />
+                       <input type="checkbox" name="check" id="form6check2" />
+               </form>
+               
+               <form id="testForm7">
+                       <select class="{required:true,minlength:2}" name="select5" id="select5" multiple="multiple">
+                               <option id="optionxa" value="0">0</option>
+                               <option id="optionxb" value="1">1</option>
+                               <option id="optionxc" value="2">2</option>
+                               <option id="optionxd" value="3">3</option>
+                       </select>
+               </form>
+               
+               <form id="dateRangeForm">
+                       <input id="fromDate" name="fromDate" class="requiredDateRange" value="x" />
+                       <input id="toDate" name="toDate" class="requiredDateRange" value="y" />
+                       <span class="errorContainer"></span>
+               </form>
+               
+               <form id="testForm8">
+                       <input id="form8input" class="{required:true,number:true,rangelength:[2,8]}" name="abc" />
+                       <input type="radio" name="radio1"/>
+               </form>
+               
+               <form id="testForm9">
+                       <input id="testEmail9" class="{required:true,email:true,messages:{required:'required',email:'email'}}" />
+               </form>
+               
+               <div id="simplecontainer">
+                       <h3></h3>
+               </div>
+
+               <div id="container"></div>
+               
+               <ol id="labelcontainer"></ol>
+               
+               <form id="elementsOrder">
+                       <select class="required" name="order1" id="order1"><option value="">none</option></select>
+                       <input class="required" name="order2" id="order2"/>
+                       <input class="required" name="order3" type="checkbox" id="order3"/>
+                       <input class="required" name="order4" id="order4"/>
+                       <input class="required" name="order5" type="radio" id="order5"/>
+                       <input class="required" name="order6" id="order6"/>
+                       <ul id="orderContainer">
+                       </ul>
+               </form> 
+               
+               <form id="form" action="formaction">
+                       <input type="text" name="action" value="Test" id="text1"/>
+                       <input type="text" name="text2" value="T" id="text2"/>
+                       <input type="text" name="text2" value="TestTestTest" id="text3"/>
+                       
+                       <input type="text" name="action" value="0" id="value1"/>
+                       <input type="text" name="text2" value="10" id="value2"/>
+                       <input type="text" name="text2" value="1000" id="value3"/>
+                       
+                       <input type="radio" name="radio1" id="radio1"/>
+                       <input type="radio" name="radio1" id="radio1a"/>
+                       <input type="radio" name="radio2" id="radio2" checked="checked"/>
+                       <input type="radio" name="radio" id="radio3"/>
+                       <input type="radio" name="radio" id="radio4" checked="checked"/>
+                       
+                       <input type="checkbox" name="check" id="check1" checked="checked"/>
+                       <input type="checkbox" name="check" id="check1b" />
+                       
+                       <input type="checkbox" name="check2" id="check2"/>
+                       
+                       <input type="checkbox" name="check3" id="check3" checked="checked"/>
+                       <input type="checkbox" name="check3" checked="checked"/>
+                       <input type="checkbox" name="check3" checked="checked"/>
+                       <input type="checkbox" name="check3" checked="checked"/>
+                       <input type="checkbox" name="check3" checked="checked"/>
+                       
+                       <input type="hidden" name="hidden" id="hidden1"/>
+                       <input type="text" style="display:none;" name="foo[bar]" id="hidden2"/>
+                       
+                       <input type="text" readonly="readonly" id="name" name="name" value="name" />
+                       
+                       <button name="button">Button</button>
+                       
+                       <textarea id="area1" name="area1"">foobar</textarea>
+                       
+                       
+                       <textarea id="area2" name="area2"></textarea>
+                       
+                       <select name="select1" id="select1">
+                               <option id="option1a" value="">Nothing</option>
+                               <option id="option1b" value="1">1</option>
+                               <option id="option1c" value="2">2</option>
+                               <option id="option1d" value="3">3</option>
+                       </select>
+                       <select name="select2" id="select2">
+                               <option id="option2a" value="">Nothing</option>
+                               <option id="option2b" value="1">1</option>
+                               <option id="option2c" value="2">2</option>
+                               <option id="option2d" selected="selected" value="3">3</option>
+                       </select>
+                       <select name="select3" id="select3" multiple="multiple">
+                               <option id="option3a" value="">Nothing</option>
+                               <option id="option3b" selected="selected" value="1">1</option>
+                               <option id="option3c" selected="selected" value="2">2</option>
+                               <option id="option3d" value="3">3</option>
+                       </select>
+                       <select name="select4" id="select4" multiple="multiple">
+                               <option id="option3b" selected="selected" value="1">1</option>
+                               <option id="option3c" selected="selected" value="2">2</option>
+                               <option id="option3d" selected="selected" value="3">3</option>
+                               <option id="option3e" selected="selected" value="4">4</option>
+                               <option id="option3f" selected="selected" value="5">5</option>
+                       </select>
+                       <select name="select5" id="select5" multiple="multiple">
+                               <option id="option3a" value="0">0</option>
+                               <option id="option3b" value="1">1</option>
+                               <option id="option3c" value="2">2</option>
+                               <option id="option3d" value="3">3</option>
+                       </select>
+               </form>
+               
+               <form id="v2">
+                       <input id="v2-i1" name="v2-i1" class="required" />
+                       <input id="v2-i2" name="v2-i2" class="required email" />
+                       <input id="v2-i3" name="v2-i3" class="url" />
+                       <input id="v2-i4" name="v2-i4" class="required" minlength="2" />
+                       <input id="v2-i5" name="v2-i5" class="required" minlength="2" maxlength="5" customMethod1="123" />
+                       <input id="v2-i6" name="v2-i6" class="required customMethod2 {maxlength: 5}" minlength="2" />
+                       <input id="v2-i7" name="v2-i7" />
+               </form>
+               
+               <form id="checkables">
+                       <input type="checkbox" id="checkable1" name="checkablesgroup" class="required" />
+                       <input type="checkbox" id="checkable2" name="checkablesgroup" />
+                       <input type="checkbox" id="checkable3" name="checkablesgroup" />
+               </form>
+               
+               
+               <form id="subformRequired">
+                       <div class="billingAddressControl">
+               <input type="checkbox" id="bill_to_co" name="bill_to_co" class="toggleCheck" checked="checked" style="width: auto;" tabindex="1" />
+               <label for="bill_to_co" style="cursor:pointer">Same as Company Address</label>
+               </div>
+                       <div id="subform">
+                               <input  maxlength="40" class="billingRequired" name="bill_first_name" size="20" type="text" tabindex="2" value="" />
+                       </div>
+                       <input id="co_name" class="required" maxlength="40" name="co_name" size="20" type="text" tabindex="1" value="" />
+               </form>
+       </div>
+
+       <ol id="qunit-tests"></ol>
+       </body>
+</html>
diff --git a/test/same.js b/test/same.js
new file mode 100644 (file)
index 0000000..d87a726
--- /dev/null
@@ -0,0 +1,1368 @@
+module("equiv");
+
+
+test("Primitive types and constants", function () {
+    equals(QUnit.equiv(null, null), true, "null");
+    equals(QUnit.equiv(null, {}), false, "null");
+    equals(QUnit.equiv(null, undefined), false, "null");
+    equals(QUnit.equiv(null, 0), false, "null");
+    equals(QUnit.equiv(null, false), false, "null");
+    equals(QUnit.equiv(null, ''), false, "null");
+    equals(QUnit.equiv(null, []), false, "null");
+
+    equals(QUnit.equiv(undefined, undefined), true, "undefined");
+    equals(QUnit.equiv(undefined, null), false, "undefined");
+    equals(QUnit.equiv(undefined, 0), false, "undefined");
+    equals(QUnit.equiv(undefined, false), false, "undefined");
+    equals(QUnit.equiv(undefined, {}), false, "undefined");
+    equals(QUnit.equiv(undefined, []), false, "undefined");
+    equals(QUnit.equiv(undefined, ""), false, "undefined");
+
+    // Nan usually doest not equal to Nan using the '==' operator.
+    // Only isNaN() is able to do it.
+    equals(QUnit.equiv(0/0, 0/0), true, "NaN"); // NaN VS NaN
+    equals(QUnit.equiv(1/0, 2/0), true, "Infinity"); // Infinity VS Infinity
+    equals(QUnit.equiv(-1/0, 2/0), false, "-Infinity, Infinity"); // -Infinity VS Infinity
+    equals(QUnit.equiv(-1/0, -2/0), true, "-Infinity, -Infinity"); // -Infinity VS -Infinity
+    equals(QUnit.equiv(0/0, 1/0), false, "NaN, Infinity"); // Nan VS Infinity
+    equals(QUnit.equiv(1/0, 0/0), false, "NaN, Infinity"); // Nan VS Infinity
+    equals(QUnit.equiv(0/0, null), false, "NaN");
+    equals(QUnit.equiv(0/0, undefined), false, "NaN");
+    equals(QUnit.equiv(0/0, 0), false, "NaN");
+    equals(QUnit.equiv(0/0, false), false, "NaN");
+    equals(QUnit.equiv(0/0, function () {}), false, "NaN");
+    equals(QUnit.equiv(1/0, null), false, "NaN, Infinity");
+    equals(QUnit.equiv(1/0, undefined), false, "NaN, Infinity");
+    equals(QUnit.equiv(1/0, 0), false, "NaN, Infinity");
+    equals(QUnit.equiv(1/0, 1), false, "NaN, Infinity");
+    equals(QUnit.equiv(1/0, false), false, "NaN, Infinity");
+    equals(QUnit.equiv(1/0, true), false, "NaN, Infinity");
+    equals(QUnit.equiv(1/0, function () {}), false, "NaN, Infinity");
+
+    equals(QUnit.equiv(0, 0), true, "number");
+    equals(QUnit.equiv(0, 1), false, "number");
+    equals(QUnit.equiv(1, 0), false, "number");
+    equals(QUnit.equiv(1, 1), true, "number");
+    equals(QUnit.equiv(1.1, 1.1), true, "number");
+    equals(QUnit.equiv(0.0000005, 0.0000005), true, "number");
+    equals(QUnit.equiv(0, ''), false, "number");
+    equals(QUnit.equiv(0, '0'), false, "number");
+    equals(QUnit.equiv(1, '1'), false, "number");
+    equals(QUnit.equiv(0, false), false, "number");
+    equals(QUnit.equiv(1, true), false, "number");
+
+    equals(QUnit.equiv(true, true), true, "boolean");
+    equals(QUnit.equiv(true, false), false, "boolean");
+    equals(QUnit.equiv(false, true), false, "boolean");
+    equals(QUnit.equiv(false, 0), false, "boolean");
+    equals(QUnit.equiv(false, null), false, "boolean");
+    equals(QUnit.equiv(false, undefined), false, "boolean");
+    equals(QUnit.equiv(true, 1), false, "boolean");
+    equals(QUnit.equiv(true, null), false, "boolean");
+    equals(QUnit.equiv(true, undefined), false, "boolean");
+
+    equals(QUnit.equiv('', ''), true, "string");
+    equals(QUnit.equiv('a', 'a'), true, "string");
+    equals(QUnit.equiv("foobar", "foobar"), true, "string");
+    equals(QUnit.equiv("foobar", "foo"), false, "string");
+    equals(QUnit.equiv('', 0), false, "string");
+    equals(QUnit.equiv('', false), false, "string");
+    equals(QUnit.equiv('', null), false, "string");
+    equals(QUnit.equiv('', undefined), false, "string");
+    
+    // Short annotation VS new annotation
+    equals(QUnit.equiv(0, new Number()), true, "short annotation VS new annotation");
+    equals(QUnit.equiv(new Number(), 0), true, "short annotation VS new annotation");
+    equals(QUnit.equiv(1, new Number(1)), true, "short annotation VS new annotation");
+    equals(QUnit.equiv(new Number(1), 1), true, "short annotation VS new annotation");
+    equals(QUnit.equiv(new Number(0), 1), false, "short annotation VS new annotation");
+    equals(QUnit.equiv(0, new Number(1)), false, "short annotation VS new annotation");
+
+    equals(QUnit.equiv(new String(), ""), true, "short annotation VS new annotation");
+    equals(QUnit.equiv("", new String()), true, "short annotation VS new annotation");
+    equals(QUnit.equiv(new String("My String"), "My String"), true, "short annotation VS new annotation");
+    equals(QUnit.equiv("My String", new String("My String")), true, "short annotation VS new annotation");
+    equals(QUnit.equiv("Bad String", new String("My String")), false, "short annotation VS new annotation");
+    equals(QUnit.equiv(new String("Bad String"), "My String"), false, "short annotation VS new annotation");
+
+    equals(QUnit.equiv(false, new Boolean()), true, "short annotation VS new annotation");
+    equals(QUnit.equiv(new Boolean(), false), true, "short annotation VS new annotation");
+    equals(QUnit.equiv(true, new Boolean(true)), true, "short annotation VS new annotation");
+    equals(QUnit.equiv(new Boolean(true), true), true, "short annotation VS new annotation");
+    equals(QUnit.equiv(true, new Boolean(1)), true, "short annotation VS new annotation");
+    equals(QUnit.equiv(false, new Boolean(false)), true, "short annotation VS new annotation");
+    equals(QUnit.equiv(new Boolean(false), false), true, "short annotation VS new annotation");
+    equals(QUnit.equiv(false, new Boolean(0)), true, "short annotation VS new annotation");
+    equals(QUnit.equiv(true, new Boolean(false)), false, "short annotation VS new annotation");
+    equals(QUnit.equiv(new Boolean(false), true), false, "short annotation VS new annotation");
+
+    equals(QUnit.equiv(new Object(), {}), true, "short annotation VS new annotation");
+    equals(QUnit.equiv({}, new Object()), true, "short annotation VS new annotation");
+    equals(QUnit.equiv(new Object(), {a:1}), false, "short annotation VS new annotation");
+    equals(QUnit.equiv({a:1}, new Object()), false, "short annotation VS new annotation");
+    equals(QUnit.equiv({a:undefined}, new Object()), false, "short annotation VS new annotation");
+    equals(QUnit.equiv(new Object(), {a:undefined}), false, "short annotation VS new annotation");
+});
+
+test("Objects Basics.", function() {
+    equals(QUnit.equiv({}, {}), true);
+    equals(QUnit.equiv({}, null), false);
+    equals(QUnit.equiv({}, undefined), false);
+    equals(QUnit.equiv({}, 0), false);
+    equals(QUnit.equiv({}, false), false);
+
+    // This test is a hard one, it is very important
+    // REASONS:
+    //      1) They are of the same type "object"
+    //      2) [] instanceof Object is true
+    //      3) Their properties are the same (doesn't exists)
+    equals(QUnit.equiv({}, []), false);
+
+    equals(QUnit.equiv({a:1}, {a:1}), true);
+    equals(QUnit.equiv({a:1}, {a:"1"}), false);
+    equals(QUnit.equiv({a:[]}, {a:[]}), true);
+    equals(QUnit.equiv({a:{}}, {a:null}), false);
+    equals(QUnit.equiv({a:1}, {}), false);
+    equals(QUnit.equiv({}, {a:1}), false);
+
+    // Hard ones
+    equals(QUnit.equiv({a:undefined}, {}), false);
+    equals(QUnit.equiv({}, {a:undefined}), false);
+    equals(QUnit.equiv(
+        {
+            a: [{ bar: undefined }]
+        },
+        {
+            a: [{ bat: undefined }]
+        }
+    ), false);
+});
+
+
+test("Arrays Basics.", function() {
+
+    equals(QUnit.equiv([], []), true);
+
+    // May be a hard one, can invoke a crash at execution.
+    // because their types are both "object" but null isn't
+    // like a true object, it doesn't have any property at all.
+    equals(QUnit.equiv([], null), false);
+
+    equals(QUnit.equiv([], undefined), false);
+    equals(QUnit.equiv([], false), false);
+    equals(QUnit.equiv([], 0), false);
+    equals(QUnit.equiv([], ""), false);
+
+    // May be a hard one, but less hard
+    // than {} with [] (note the order)
+    equals(QUnit.equiv([], {}), false);
+
+    equals(QUnit.equiv([null],[]), false);
+    equals(QUnit.equiv([undefined],[]), false);
+    equals(QUnit.equiv([],[null]), false);
+    equals(QUnit.equiv([],[undefined]), false);
+    equals(QUnit.equiv([null],[undefined]), false);
+    equals(QUnit.equiv([[]],[[]]), true);
+    equals(QUnit.equiv([[],[],[]],[[],[],[]]), true);
+    equals(QUnit.equiv(
+                            [[],[],[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]],
+                            [[],[],[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]),
+                            true);
+    equals(QUnit.equiv(
+                            [[],[],[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]],
+                            [[],[],[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]), // shorter
+                            false);
+    equals(QUnit.equiv(
+                            [[],[],[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[{}]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]],
+                            [[],[],[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]), // deepest element not an array
+                            false);
+
+    // same multidimensional
+    equals(QUnit.equiv(
+                            [1,2,3,4,5,6,7,8,9, [
+                                1,2,3,4,5,6,7,8,9, [
+                                    1,2,3,4,5,[
+                                        [6,7,8,9, [
+                                            [
+                                                1,2,3,4,[
+                                                    2,3,4,[
+                                                        1,2,[
+                                                            1,2,3,4,[
+                                                                1,2,3,4,5,6,7,8,9,[
+                                                                    0
+                                                                ],1,2,3,4,5,6,7,8,9
+                                                            ],5,6,7,8,9
+                                                        ],4,5,6,7,8,9
+                                                    ],5,6,7,8,9
+                                                ],5,6,7
+                                            ]
+                                        ]
+                                    ]
+                                ]
+                            ]]],
+                            [1,2,3,4,5,6,7,8,9, [
+                                1,2,3,4,5,6,7,8,9, [
+                                    1,2,3,4,5,[
+                                        [6,7,8,9, [
+                                            [
+                                                1,2,3,4,[
+                                                    2,3,4,[
+                                                        1,2,[
+                                                            1,2,3,4,[
+                                                                1,2,3,4,5,6,7,8,9,[
+                                                                    0
+                                                                ],1,2,3,4,5,6,7,8,9
+                                                            ],5,6,7,8,9
+                                                        ],4,5,6,7,8,9
+                                                    ],5,6,7,8,9
+                                                ],5,6,7
+                                            ]
+                                        ]
+                                    ]
+                                ]
+                            ]]]),
+                            true, "Multidimensional");
+
+    // different multidimensional
+    equals(QUnit.equiv(
+                            [1,2,3,4,5,6,7,8,9, [
+                                1,2,3,4,5,6,7,8,9, [
+                                    1,2,3,4,5,[
+                                        [6,7,8,9, [
+                                            [
+                                                1,2,3,4,[
+                                                    2,3,4,[
+                                                        1,2,[
+                                                            1,2,3,4,[
+                                                                1,2,3,4,5,6,7,8,9,[
+                                                                    0
+                                                                ],1,2,3,4,5,6,7,8,9
+                                                            ],5,6,7,8,9
+                                                        ],4,5,6,7,8,9
+                                                    ],5,6,7,8,9
+                                                ],5,6,7
+                                            ]
+                                        ]
+                                    ]
+                                ]
+                            ]]],
+                            [1,2,3,4,5,6,7,8,9, [
+                                1,2,3,4,5,6,7,8,9, [
+                                    1,2,3,4,5,[
+                                        [6,7,8,9, [
+                                            [
+                                                1,2,3,4,[
+                                                    2,3,4,[
+                                                        1,2,[
+                                                            '1',2,3,4,[                 // string instead of number
+                                                                1,2,3,4,5,6,7,8,9,[
+                                                                    0
+                                                                ],1,2,3,4,5,6,7,8,9
+                                                            ],5,6,7,8,9
+                                                        ],4,5,6,7,8,9
+                                                    ],5,6,7,8,9
+                                                ],5,6,7
+                                            ]
+                                        ]
+                                    ]
+                                ]
+                            ]]]),
+                            false, "Multidimensional");
+
+    // different multidimensional
+    equals(QUnit.equiv(
+                            [1,2,3,4,5,6,7,8,9, [
+                                1,2,3,4,5,6,7,8,9, [
+                                    1,2,3,4,5,[
+                                        [6,7,8,9, [
+                                            [
+                                                1,2,3,4,[
+                                                    2,3,4,[
+                                                        1,2,[
+                                                            1,2,3,4,[
+                                                                1,2,3,4,5,6,7,8,9,[
+                                                                    0
+                                                                ],1,2,3,4,5,6,7,8,9
+                                                            ],5,6,7,8,9
+                                                        ],4,5,6,7,8,9
+                                                    ],5,6,7,8,9
+                                                ],5,6,7
+                                            ]
+                                        ]
+                                    ]
+                                ]
+                            ]]],
+                            [1,2,3,4,5,6,7,8,9, [
+                                1,2,3,4,5,6,7,8,9, [
+                                    1,2,3,4,5,[
+                                        [6,7,8,9, [
+                                            [
+                                                1,2,3,4,[
+                                                    2,3,[                   // missing an element (4)
+                                                        1,2,[
+                                                            1,2,3,4,[
+                                                                1,2,3,4,5,6,7,8,9,[
+                                                                    0
+                                                                ],1,2,3,4,5,6,7,8,9
+                                                            ],5,6,7,8,9
+                                                        ],4,5,6,7,8,9
+                                                    ],5,6,7,8,9
+                                                ],5,6,7
+                                            ]
+                                        ]
+                                    ]
+                                ]
+                            ]]]),
+                            false, "Multidimensional");
+});
+
+test("Functions.", function() {
+    var f0 = function () {};
+    var f1 = function () {};
+
+    // f2 and f3 have the same code, formatted differently
+    var f2 = function () {var i = 0;};
+    var f3 = function () {
+        var i = 0 // this comment and no semicoma as difference
+    };
+
+    equals(QUnit.equiv(function() {}, function() {}), false, "Anonymous functions"); // exact source code
+    equals(QUnit.equiv(function() {}, function() {return true;}), false, "Anonymous functions");
+
+    equals(QUnit.equiv(f0, f0), true, "Function references"); // same references
+    equals(QUnit.equiv(f0, f1), false, "Function references"); // exact source code, different references
+    equals(QUnit.equiv(f2, f3), false, "Function references"); // equivalent source code, different references
+    equals(QUnit.equiv(f1, f2), false, "Function references"); // different source code, different references
+    equals(QUnit.equiv(function() {}, true), false);
+    equals(QUnit.equiv(function() {}, undefined), false);
+    equals(QUnit.equiv(function() {}, null), false);
+    equals(QUnit.equiv(function() {}, {}), false);
+});
+
+
+test("Date instances.", function() {
+    // Date, we don't need to test Date.parse() because it returns a number.
+    // Only test the Date instances by setting them a fix date.
+    // The date use is midnight January 1, 1970
+    
+    var d1 = new Date();
+    d1.setTime(0); // fix the date
+
+    var d2 = new Date();
+    d2.setTime(0); // fix the date
+
+    var d3 = new Date(); // The very now
+
+    // Anyway their types differs, just in case the code fails in the order in which it deals with date
+    equals(QUnit.equiv(d1, 0), false); // d1.valueOf() returns 0, but d1 and 0 are different
+    // test same values date and different instances equality
+    equals(QUnit.equiv(d1, d2), true);
+    // test different date and different instances difference
+    equals(QUnit.equiv(d1, d3), false);
+});
+
+
+test("RegExp.", function() {
+    // Must test cases that imply those traps:
+    // var a = /./;
+    // a instanceof Object;        // Oops
+    // a instanceof RegExp;        // Oops
+    // typeof a === "function";    // Oops, false in IE and Opera, true in FF and Safari ("object")
+
+    // Tests same regex with same modifiers in different order
+    var r = /foo/;
+    var r5 = /foo/gim;
+    var r6 = /foo/gmi;
+    var r7 = /foo/igm;
+    var r8 = /foo/img;
+    var r9 = /foo/mig;
+    var r10 = /foo/mgi;
+    var ri1 = /foo/i;
+    var ri2 = /foo/i;
+    var rm1 = /foo/m;
+    var rm2 = /foo/m;
+    var rg1 = /foo/g;
+    var rg2 = /foo/g;
+
+    equals(QUnit.equiv(r5, r6), true, "Modifier order");
+    equals(QUnit.equiv(r5, r7), true, "Modifier order");
+    equals(QUnit.equiv(r5, r8), true, "Modifier order");
+    equals(QUnit.equiv(r5, r9), true, "Modifier order");
+    equals(QUnit.equiv(r5, r10), true, "Modifier order");
+    equals(QUnit.equiv(r, r5), false, "Modifier");
+
+    equals(QUnit.equiv(ri1, ri2), true, "Modifier");
+    equals(QUnit.equiv(r, ri1), false, "Modifier");
+    equals(QUnit.equiv(ri1, rm1), false, "Modifier");
+    equals(QUnit.equiv(r, rm1), false, "Modifier");
+    equals(QUnit.equiv(rm1, ri1), false, "Modifier");
+    equals(QUnit.equiv(rm1, rm2), true, "Modifier");
+    equals(QUnit.equiv(rg1, rm1), false, "Modifier");
+    equals(QUnit.equiv(rm1, rg1), false, "Modifier");
+    equals(QUnit.equiv(rg1, rg2), true, "Modifier");
+
+    // Different regex, same modifiers
+    var r11 = /[a-z]/gi;
+    var r13 = /[0-9]/gi; // oops! different
+    equals(QUnit.equiv(r11, r13), false, "Regex pattern");
+
+    var r14 = /0/ig;
+    var r15 = /"0"/ig; // oops! different
+    equals(QUnit.equiv(r14, r15), false, "Regex pattern");
+
+    var r1 = /[\n\r\u2028\u2029]/g;
+    var r2 = /[\n\r\u2028\u2029]/g;
+    var r3 = /[\n\r\u2028\u2028]/g; // differs from r1
+    var r4 = /[\n\r\u2028\u2029]/;  // differs from r1
+
+    equals(QUnit.equiv(r1, r2), true, "Regex pattern");
+    equals(QUnit.equiv(r1, r3), false, "Regex pattern");
+    equals(QUnit.equiv(r1, r4), false, "Regex pattern");
+
+    // More complex regex
+    var regex1 = "^[-_.a-z0-9]+@([-_a-z0-9]+\\.)+([A-Za-z][A-Za-z]|[A-Za-z][A-Za-z][A-Za-z])|(([0-9][0-9]?|[0-1][0-9][0-9]|[2][0-4][0-9]|[2][5][0-5]))$";
+    var regex2 = "^[-_.a-z0-9]+@([-_a-z0-9]+\\.)+([A-Za-z][A-Za-z]|[A-Za-z][A-Za-z][A-Za-z])|(([0-9][0-9]?|[0-1][0-9][0-9]|[2][0-4][0-9]|[2][5][0-5]))$";
+    // regex 3 is different: '.' not escaped
+    var regex3 = "^[-_.a-z0-9]+@([-_a-z0-9]+.)+([A-Za-z][A-Za-z]|[A-Za-z][A-Za-z][A-Za-z])|(([0-9][0-9]?|[0-1][0-9][0-9]|[2][0-4][0-9]|[2][5][0-5]))$";
+
+    var r21 = new RegExp(regex1);
+    var r22 = new RegExp(regex2);
+    var r23 = new RegExp(regex3); // diff from r21, not same pattern
+    var r23a = new RegExp(regex3, "gi"); // diff from r23, not same modifier
+    var r24a = new RegExp(regex3, "ig"); // same as r23a
+
+    equals(QUnit.equiv(r21, r22), true, "Complex Regex");
+    equals(QUnit.equiv(r21, r23), false, "Complex Regex");
+    equals(QUnit.equiv(r23, r23a), false, "Complex Regex");
+    equals(QUnit.equiv(r23a, r24a), true, "Complex Regex");
+
+    // typeof r1 is "function" in some browsers and "object" in others so we must cover this test
+    var re = / /;
+    equals(QUnit.equiv(re, function () {}), false, "Regex internal");
+    equals(QUnit.equiv(re, {}), false, "Regex internal");
+});
+
+
+test("Complex Objects.", function() {
+
+    function fn1() {
+        return "fn1";
+    }
+    function fn2() {
+        return "fn2";
+    }
+    
+    // Try to invert the order of some properties to make sure it is covered.
+    // It can failed when properties are compared between unsorted arrays.
+    equals(QUnit.equiv(
+        {
+            a: 1,
+            b: null,
+            c: [{}],
+            d: {
+                a: 3.14159,
+                b: false,
+                c: {
+                    e: fn1,
+                    f: [[[]]],
+                    g: {
+                        j: {
+                            k: {
+                                n: {
+                                    r: "r",
+                                    s: [1,2,3],
+                                    t: undefined,
+                                    u: 0,
+                                    v: {
+                                        w: {
+                                            x: {
+                                                y: "Yahoo!",
+                                                z: null
+                                            }
+                                        }
+                                    }
+                                },
+                                q: [],
+                                p: 1/0,
+                                o: 99
+                            },
+                            l: undefined,
+                            m: null
+                        }
+                    },
+                    d: 0,
+                    i: true,
+                    h: "false"
+                }
+            },
+            e: undefined,
+            g: "",
+            h: "h",
+            f: {},
+            i: []
+        },
+        {
+            a: 1,
+            b: null,
+            c: [{}],
+            d: {
+                b: false,
+                a: 3.14159,
+                c: {
+                    d: 0,
+                    e: fn1,
+                    f: [[[]]],
+                    g: {
+                        j: {
+                            k: {
+                                n: {
+                                    r: "r",
+                                    t: undefined,
+                                    u: 0,
+                                    s: [1,2,3],
+                                    v: {
+                                        w: {
+                                            x: {
+                                                z: null,
+                                                y: "Yahoo!"
+                                            }
+                                        }
+                                    }
+                                },
+                                o: 99,
+                                p: 1/0,
+                                q: []
+                            },
+                            l: undefined,
+                            m: null
+                        }
+                    },
+                    i: true,
+                    h: "false"
+                }
+            },
+            e: undefined,
+            g: "",
+            f: {},
+            h: "h",
+            i: []
+        }
+    ), true);
+
+    equals(QUnit.equiv(
+        {
+            a: 1,
+            b: null,
+            c: [{}],
+            d: {
+                a: 3.14159,
+                b: false,
+                c: {
+                    d: 0,
+                    e: fn1,
+                    f: [[[]]],
+                    g: {
+                        j: {
+                            k: {
+                                n: {
+                                    //r: "r",   // different: missing a property
+                                    s: [1,2,3],
+                                    t: undefined,
+                                    u: 0,
+                                    v: {
+                                        w: {
+                                            x: {
+                                                y: "Yahoo!",
+                                                z: null
+                                            }
+                                        }
+                                    }
+                                },
+                                o: 99,
+                                p: 1/0,
+                                q: []
+                            },
+                            l: undefined,
+                            m: null
+                        }
+                    },
+                    h: "false",
+                    i: true
+                }
+            },
+            e: undefined,
+            f: {},
+            g: "",
+            h: "h",
+            i: []
+        },
+        {
+            a: 1,
+            b: null,
+            c: [{}],
+            d: {
+                a: 3.14159,
+                b: false,
+                c: {
+                    d: 0,
+                    e: fn1,
+                    f: [[[]]],
+                    g: {
+                        j: {
+                            k: {
+                                n: {
+                                    r: "r",
+                                    s: [1,2,3],
+                                    t: undefined,
+                                    u: 0,
+                                    v: {
+                                        w: {
+                                            x: {
+                                                y: "Yahoo!",
+                                                z: null
+                                            }
+                                        }
+                                    }
+                                },
+                                o: 99,
+                                p: 1/0,
+                                q: []
+                            },
+                            l: undefined,
+                            m: null
+                        }
+                    },
+                    h: "false",
+                    i: true
+                }
+            },
+            e: undefined,
+            f: {},
+            g: "",
+            h: "h",
+            i: []
+        }
+    ), false);
+
+    equals(QUnit.equiv(
+        {
+            a: 1,
+            b: null,
+            c: [{}],
+            d: {
+                a: 3.14159,
+                b: false,
+                c: {
+                    d: 0,
+                    e: fn1,
+                    f: [[[]]],
+                    g: {
+                        j: {
+                            k: {
+                                n: {
+                                    r: "r",
+                                    s: [1,2,3],
+                                    t: undefined,
+                                    u: 0,
+                                    v: {
+                                        w: {
+                                            x: {
+                                                y: "Yahoo!",
+                                                z: null
+                                            }
+                                        }
+                                    }
+                                },
+                                o: 99,
+                                p: 1/0,
+                                q: []
+                            },
+                            l: undefined,
+                            m: null
+                        }
+                    },
+                    h: "false",
+                    i: true
+                }
+            },
+            e: undefined,
+            f: {},
+            g: "",
+            h: "h",
+            i: []
+        },
+        {
+            a: 1,
+            b: null,
+            c: [{}],
+            d: {
+                a: 3.14159,
+                b: false,
+                c: {
+                    d: 0,
+                    e: fn1,
+                    f: [[[]]],
+                    g: {
+                        j: {
+                            k: {
+                                n: {
+                                    r: "r",
+                                    s: [1,2,3],
+                                    //t: undefined,                 // different: missing a property with an undefined value
+                                    u: 0,
+                                    v: {
+                                        w: {
+                                            x: {
+                                                y: "Yahoo!",
+                                                z: null
+                                            }
+                                        }
+                                    }
+                                },
+                                o: 99,
+                                p: 1/0,
+                                q: []
+                            },
+                            l: undefined,
+                            m: null
+                        }
+                    },
+                    h: "false",
+                    i: true
+                }
+            },
+            e: undefined,
+            f: {},
+            g: "",
+            h: "h",
+            i: []
+        }
+    ), false);
+
+    equals(QUnit.equiv(
+        {
+            a: 1,
+            b: null,
+            c: [{}],
+            d: {
+                a: 3.14159,
+                b: false,
+                c: {
+                    d: 0,
+                    e: fn1,
+                    f: [[[]]],
+                    g: {
+                        j: {
+                            k: {
+                                n: {
+                                    r: "r",
+                                    s: [1,2,3],
+                                    t: undefined,
+                                    u: 0,
+                                    v: {
+                                        w: {
+                                            x: {
+                                                y: "Yahoo!",
+                                                z: null
+                                            }
+                                        }
+                                    }
+                                },
+                                o: 99,
+                                p: 1/0,
+                                q: []
+                            },
+                            l: undefined,
+                            m: null
+                        }
+                    },
+                    h: "false",
+                    i: true
+                }
+            },
+            e: undefined,
+            f: {},
+            g: "",
+            h: "h",
+            i: []
+        },
+        {
+            a: 1,
+            b: null,
+            c: [{}],
+            d: {
+                a: 3.14159,
+                b: false,
+                c: {
+                    d: 0,
+                    e: fn1,
+                    f: [[[]]],
+                    g: {
+                        j: {
+                            k: {
+                                n: {
+                                    r: "r",
+                                    s: [1,2,3],
+                                    t: undefined,
+                                    u: 0,
+                                    v: {
+                                        w: {
+                                            x: {
+                                                y: "Yahoo!",
+                                                z: null
+                                            }
+                                        }
+                                    }
+                                },
+                                o: 99,
+                                p: 1/0,
+                                q: {}           // different was []
+                            },
+                            l: undefined,
+                            m: null
+                        }
+                    },
+                    h: "false",
+                    i: true
+                }
+            },
+            e: undefined,
+            f: {},
+            g: "",
+            h: "h",
+            i: []
+        }
+    ), false);
+
+    var same1 = {
+        a: [
+            "string", null, 0, "1", 1, {
+                prop: null,
+                foo: [1,2,null,{}, [], [1,2,3]],
+                bar: undefined
+            }, 3, "Hey!", "Κάνε πάντα γνωρίζουμε ας των, μηχανής επιδιόρθωσης επιδιορθώσεις ώς μια. Κλπ ας"
+        ],
+        unicode: "老 汉语中存在 港澳和海外的华人圈中 贵州 我去了书店 现在尚有争",
+        b: "b",
+        c: fn1
+    };
+
+    var same2 = {
+        a: [
+            "string", null, 0, "1", 1, {
+                prop: null,
+                foo: [1,2,null,{}, [], [1,2,3]],
+                bar: undefined
+            }, 3, "Hey!", "Κάνε πάντα γνωρίζουμε ας των, μηχανής επιδιόρθωσης επιδιορθώσεις ώς μια. Κλπ ας"
+        ],
+        unicode: "老 汉语中存在 港澳和海外的华人圈中 贵州 我去了书店 现在尚有争",
+        b: "b",
+        c: fn1
+    };
+
+    var diff1 = {
+        a: [
+            "string", null, 0, "1", 1, {
+                prop: null,
+                foo: [1,2,null,{}, [], [1,2,3,4]], // different: 4 was add to the array
+                bar: undefined
+            }, 3, "Hey!", "Κάνε πάντα γνωρίζουμε ας των, μηχανής επιδιόρθωσης επιδιορθώσεις ώς μια. Κλπ ας"
+        ],
+        unicode: "老 汉语中存在 港澳和海外的华人圈中 贵州 我去了书店 现在尚有争",
+        b: "b",
+        c: fn1
+    };
+
+    var diff2 = {
+        a: [
+            "string", null, 0, "1", 1, {
+                prop: null,
+                foo: [1,2,null,{}, [], [1,2,3]],
+                newprop: undefined, // different: newprop was added
+                bar: undefined
+            }, 3, "Hey!", "Κάνε πάντα γνωρίζουμε ας των, μηχανής επιδιόρθωσης επιδιορθώσεις ώς μια. Κλπ ας"
+        ],
+        unicode: "老 汉语中存在 港澳和海外的华人圈中 贵州 我去了书店 现在尚有争",
+        b: "b",
+        c: fn1
+    };
+
+    var diff3 = {
+        a: [
+            "string", null, 0, "1", 1, {
+                prop: null,
+                foo: [1,2,null,{}, [], [1,2,3]],
+                bar: undefined
+            }, 3, "Hey!", "Κάνε πάντα γνωρίζουμε ας των, μηχανής επιδιόρθωσης επιδιορθώσεις ώς μια. Κλπ α" // different: missing last char
+        ],
+        unicode: "老 汉语中存在 港澳和海外的华人圈中 贵州 我去了书店 现在尚有争",
+        b: "b",
+        c: fn1
+    };
+
+    var diff4 = {
+        a: [
+            "string", null, 0, "1", 1, {
+                prop: null,
+                foo: [1,2,undefined,{}, [], [1,2,3]], // different: undefined instead of null
+                bar: undefined
+            }, 3, "Hey!", "Κάνε πάντα γνωρίζουμε ας των, μηχανής επιδιόρθωσης επιδιορθώσεις ώς μια. Κλπ ας"
+        ],
+        unicode: "老 汉语中存在 港澳和海外的华人圈中 贵州 我去了书店 现在尚有争",
+        b: "b",
+        c: fn1
+    };
+
+    var diff5 = {
+        a: [
+            "string", null, 0, "1", 1, {
+                prop: null,
+                foo: [1,2,null,{}, [], [1,2,3]],
+                bat: undefined // different: property name not "bar"
+            }, 3, "Hey!", "Κάνε πάντα γνωρίζουμε ας των, μηχανής επιδιόρθωσης επιδιορθώσεις ώς μια. Κλπ ας"
+        ],
+        unicode: "老 汉语中存在 港澳和海外的华人圈中 贵州 我去了书店 现在尚有争",
+        b: "b",
+        c: fn1
+    };
+
+    equals(QUnit.equiv(same1, same2), true);
+    equals(QUnit.equiv(same2, same1), true);
+    equals(QUnit.equiv(same2, diff1), false);
+    equals(QUnit.equiv(diff1, same2), false);
+
+    equals(QUnit.equiv(same1, diff1), false);
+    equals(QUnit.equiv(same1, diff2), false);
+    equals(QUnit.equiv(same1, diff3), false);
+    equals(QUnit.equiv(same1, diff3), false);
+    equals(QUnit.equiv(same1, diff4), false);
+    equals(QUnit.equiv(same1, diff5), false);
+    equals(QUnit.equiv(diff5, diff1), false);
+});
+
+
+test("Complex Arrays.", function() {
+
+    function fn() {
+    }
+
+    equals(QUnit.equiv(
+                [1, 2, 3, true, {}, null, [
+                    {
+                        a: ["", '1', 0]
+                    },
+                    5, 6, 7
+                ], "foo"],
+                [1, 2, 3, true, {}, null, [
+                    {
+                        a: ["", '1', 0]
+                    },
+                    5, 6, 7
+                ], "foo"]),
+            true);
+
+    equals(QUnit.equiv(
+                [1, 2, 3, true, {}, null, [
+                    {
+                        a: ["", '1', 0]
+                    },
+                    5, 6, 7
+                ], "foo"],
+                [1, 2, 3, true, {}, null, [
+                    {
+                        b: ["", '1', 0]         // not same property name
+                    },
+                    5, 6, 7
+                ], "foo"]),
+            false);
+
+    var a = [{
+        b: fn,
+        c: false,
+        "do": "reserved word",
+        "for": {
+            ar: [3,5,9,"hey!", [], {
+                ar: [1,[
+                    3,4,6,9, null, [], []
+                ]],
+                e: fn,
+                f: undefined
+            }]
+        },
+        e: 0.43445
+    }, 5, "string", 0, fn, false, null, undefined, 0, [
+        4,5,6,7,8,9,11,22,33,44,55,"66", null, [], [[[[[3]]]], "3"], {}, 1/0
+    ], [], [[[], "foo", null, {
+        n: 1/0,
+        z: {
+            a: [3,4,5,6,"yep!", undefined, undefined],
+            b: {}
+        }
+    }, {}]]];
+
+    equals(QUnit.equiv(a,
+            [{
+                b: fn,
+                c: false,
+                "do": "reserved word",
+                "for": {
+                    ar: [3,5,9,"hey!", [], {
+                        ar: [1,[
+                            3,4,6,9, null, [], []
+                        ]],
+                        e: fn,
+                        f: undefined
+                    }]
+                },
+                e: 0.43445
+            }, 5, "string", 0, fn, false, null, undefined, 0, [
+                4,5,6,7,8,9,11,22,33,44,55,"66", null, [], [[[[[3]]]], "3"], {}, 1/0
+            ], [], [[[], "foo", null, {
+                n: 1/0,
+                z: {
+                    a: [3,4,5,6,"yep!", undefined, undefined],
+                    b: {}
+                }
+            }, {}]]]), true);
+
+    equals(QUnit.equiv(a,
+            [{
+                b: fn,
+                c: false,
+                "do": "reserved word",
+                "for": {
+                    ar: [3,5,9,"hey!", [], {
+                        ar: [1,[
+                            3,4,6,9, null, [], []
+                        ]],
+                        e: fn,
+                        f: undefined
+                    }]
+                },
+                e: 0.43445
+            }, 5, "string", 0, fn, false, null, undefined, 0, [
+                4,5,6,7,8,9,11,22,33,44,55,"66", null, [], [[[[[2]]]], "3"], {}, 1/0    // different: [[[[[2]]]]] instead of [[[[[3]]]]]
+            ], [], [[[], "foo", null, {
+                n: 1/0,
+                z: {
+                    a: [3,4,5,6,"yep!", undefined, undefined],
+                    b: {}
+                }
+            }, {}]]]), false);
+
+    equals(QUnit.equiv(a,
+            [{
+                b: fn,
+                c: false,
+                "do": "reserved word",
+                "for": {
+                    ar: [3,5,9,"hey!", [], {
+                        ar: [1,[
+                            3,4,6,9, null, [], []
+                        ]],
+                        e: fn,
+                        f: undefined
+                    }]
+                },
+                e: 0.43445
+            }, 5, "string", 0, fn, false, null, undefined, 0, [
+                4,5,6,7,8,9,11,22,33,44,55,"66", null, [], [[[[[3]]]], "3"], {}, 1/0
+            ], [], [[[], "foo", null, {
+                n: -1/0,                                                                // different, -Infinity instead of Infinity
+                z: {
+                    a: [3,4,5,6,"yep!", undefined, undefined],
+                    b: {}
+                }
+            }, {}]]]), false);
+
+    equals(QUnit.equiv(a,
+            [{
+                b: fn,
+                c: false,
+                "do": "reserved word",
+                "for": {
+                    ar: [3,5,9,"hey!", [], {
+                        ar: [1,[
+                            3,4,6,9, null, [], []
+                        ]],
+                        e: fn,
+                        f: undefined
+                    }]
+                },
+                e: 0.43445
+            }, 5, "string", 0, fn, false, null, undefined, 0, [
+                4,5,6,7,8,9,11,22,33,44,55,"66", null, [], [[[[[3]]]], "3"], {}, 1/0
+            ], [], [[[], "foo", {                                                       // different: null is missing
+                n: 1/0,
+                z: {
+                    a: [3,4,5,6,"yep!", undefined, undefined],
+                    b: {}
+                }
+            }, {}]]]), false);
+
+    equals(QUnit.equiv(a,
+            [{
+                b: fn,
+                c: false,
+                "do": "reserved word",
+                "for": {
+                    ar: [3,5,9,"hey!", [], {
+                        ar: [1,[
+                            3,4,6,9, null, [], []
+                        ]],
+                        e: fn
+                                                                                // different: missing property f: undefined
+                    }]
+                },
+                e: 0.43445
+            }, 5, "string", 0, fn, false, null, undefined, 0, [
+                4,5,6,7,8,9,11,22,33,44,55,"66", null, [], [[[[[3]]]], "3"], {}, 1/0
+            ], [], [[[], "foo", null, {
+                n: 1/0,
+                z: {
+                    a: [3,4,5,6,"yep!", undefined, undefined],
+                    b: {}
+                }
+            }, {}]]]), false);
+});
+
+
+test("Prototypal inheritance", function() {
+    function Gizmo(id) {
+        this.id = id;
+    }
+
+    function Hoozit(id) {
+        this.id = id;
+    }
+    Hoozit.prototype = new Gizmo();
+
+    var gizmo = new Gizmo("ok");
+    var hoozit = new Hoozit("ok");
+
+    // Try this test many times after test on instances that hold function
+    // to make sure that our code does not mess with last object constructor memoization.
+    equals(QUnit.equiv(function () {}, function () {}), false);
+
+    // Hoozit inherit from Gizmo
+    // hoozit instanceof Hoozit; // true
+    // hoozit instanceof Gizmo; // true
+    equals(QUnit.equiv(hoozit, gizmo), true);
+
+    Gizmo.prototype.bar = true; // not a function just in case we skip them
+
+    // Hoozit inherit from Gizmo
+    // They are equivalent
+    equals(QUnit.equiv(hoozit, gizmo), true);
+
+    // Make sure this is still true !important
+    // The reason for this is that I forgot to reset the last
+    // caller to where it were called from.
+    equals(QUnit.equiv(function () {}, function () {}), false);
+
+    // Make sure this is still true !important
+    equals(QUnit.equiv(hoozit, gizmo), true);
+
+    Hoozit.prototype.foo = true; // not a function just in case we skip them
+
+    // Gizmo does not inherit from Hoozit
+    // gizmo instanceof Gizmo; // true
+    // gizmo instanceof Hoozit; // false
+    // They are not equivalent
+    equals(QUnit.equiv(hoozit, gizmo), false);
+
+    // Make sure this is still true !important
+    equals(QUnit.equiv(function () {}, function () {}), false);
+});
+
+
+test("Instances", function() {
+    function A() {} 
+    var a1 = new A(); 
+    var a2 = new A(); 
+
+    function B() {
+        this.fn = function () {};
+    } 
+    var b1 = new B(); 
+    var b2 = new B(); 
+
+    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
+
+    function Car(year) {
+        var privateVar = 0;
+        this.year = year;
+        this.isOld = function() {
+            return year > 10;
+        };
+    }
+
+    function Human(year) {
+        var privateVar = 1;
+        this.year = year;
+        this.isOld = function() {
+            return year > 80;
+        };
+    }
+
+    var car = new Car(30);
+    var carSame = new Car(30);
+    var carDiff = new Car(10);
+    var human = new Human(30);
+
+    var diff = {
+        year: 30
+    };
+
+    var same = {
+        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() {
+    function A(fn) {
+        this.a = {};
+        this.fn = fn;
+        this.b = {a: []};
+        this.o = {};
+        this.fn1 = fn;
+    }
+    function B(fn) {
+        this.fn = fn;
+        this.fn1 = function () {};
+        this.a = new A(function () {});
+    }
+
+    function fnOutside() {
+    }
+
+    function C(fn) {
+        function fnInside() {
+        }
+        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 = new B(function () {});
+        this.b2 = new B({
+            x: {
+                b2: new B(function() {})
+            }
+        });
+    }
+
+    function D(fn) {
+        function fnInside() {
+        }
+        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 = new B(function () {});
+        this.b2 = new B({
+            x: {
+                b2: new B(function() {})
+            }
+        });
+    }
+
+    function E(fn) {
+        function fnInside() {
+        }
+        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 = new B(function () {});
+        this.b2 = new B({
+            x: {
+                b1: new B({a: function() {}}),
+                b2: new B(function() {})
+            }
+        });
+    }
+
+
+    var a1 = new A(function () {});
+    var a2 = new A(function () {});
+    equals(QUnit.equiv(a1, a2), true);
+
+    equals(QUnit.equiv(a1, a2), true); // different instances
+
+    var b1 = new B(function () {});
+    var b2 = new B(function () {});
+    equals(QUnit.equiv(a1, a2), true);
+
+    var c1 = new C(function () {});
+    var c2 = new C(function () {});
+    equals(QUnit.equiv(c1, c2), true);
+
+    var d1 = new D(function () {});
+    var d2 = new D(function () {});
+    equals(QUnit.equiv(d1, d2), false);
+
+    var e1 = new E(function () {});
+    var e2 = new E(function () {});
+    equals(QUnit.equiv(e1, e2), false);
+
+});
+
+
+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";
+    var re = /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");
+});
+
diff --git a/test/test.js b/test/test.js
new file mode 100644 (file)
index 0000000..e81afa6
--- /dev/null
@@ -0,0 +1,69 @@
+test("module without setup/teardown (default)", function() {
+       expect(1);
+       ok(true);
+});
+
+module("setup test", {
+       setup: function() {
+               ok(true);
+       }
+});
+
+test("module with setup", function() {
+       expect(2);
+       ok(true);
+})
+
+module("setup/teardown test", {
+       setup: function() {
+               window.fail = true;
+               ok(true);
+       },
+       teardown: function() {
+               delete window.fail;
+               ok(true);
+       }
+});
+
+test("module with setup/teardown", function() {
+       expect(3);
+       ok(true);
+})
+
+module("setup/teardown test 2");
+
+test("module without setup/teardown", function() {
+       expect(1);
+       ok(true);
+});
+
+var state;
+
+module("teardown and stop", {
+       teardown: function() {
+               ok(state == "done");
+       }
+});
+
+test("teardown must be called after test ended", function() {
+       
+       expect(1);
+       stop();
+       setTimeout(function() {
+               state = "done";
+               start();
+       }, 0);
+});
+
+module("save scope", {
+       setup: function() {
+               this.foo = "bar";
+       },
+       teardown: function() {
+               same(this.foo, "bar");
+       }
+});
+test("scope check", function() {
+       expect(2);
+       same(this.foo, "bar");
+});

Hosting is provided AltSPAHow to use Git
Please direct any questions on jabber alex.wolf@jabber.ru

Valid HTML 4.0 Transitional Valid CSS!

Designer Alexander Wolf