Changeset 1928


Ignore:
Timestamp:
2011-08-09 15:13:24 (10 months ago)
Author:
mpo
Message:

update to latest qunit

Location:
trunk/modules/kauri-jquery/src/test/qunit
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/modules/kauri-jquery/src/test/qunit/qunit.css

    r1896 r1928  
     1/** 
     2 * QUnit - A JavaScript Unit Testing Framework 
     3 * 
     4 * http://docs.jquery.com/QUnit 
     5 * 
     6 * Copyright (c) 2011 John Resig, Jörn Zaefferer 
     7 * Dual licensed under the MIT (MIT-LICENSE.txt) 
     8 * or GPL (GPL-LICENSE.txt) licenses. 
     9 */ 
     10 
    111/** Font Family and Sizes */ 
    212 
    313#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult { 
    4     font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial; 
     14    font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif; 
    515} 
    616 
     
    2838    line-height: 1em; 
    2939    font-weight: normal; 
    30      
     40 
    3141    border-radius: 15px 15px 0 0; 
    3242    -moz-border-radius: 15px 15px 0 0; 
     
    96106    margin-top: 0.5em; 
    97107    padding: 0.5em; 
    98      
    99     background-color: #fff; 
    100      
     108 
     109    background-color: #fff; 
     110 
    101111    border-radius: 15px; 
    102112    -moz-border-radius: 15px; 
    103113    -webkit-border-radius: 15px; 
    104      
     114 
    105115    box-shadow: inset 0px 2px 13px #999; 
    106116    -moz-box-shadow: inset 0px 2px 13px #999; 
     
    165175#qunit-tests .pass                          { color: #528CE0; background-color: #D2E0E6; } 
    166176#qunit-tests .pass .test-name               { color: #366097; } 
    167   
     177 
    168178#qunit-tests .pass .test-actual, 
    169179#qunit-tests .pass .test-expected           { color: #999999; } 
  • trunk/modules/kauri-jquery/src/test/qunit/qunit.js

    r1896 r1928  
    1 /* 
     1/** 
    22 * QUnit - A JavaScript Unit Testing Framework 
    3  *  
     3 * 
    44 * http://docs.jquery.com/QUnit 
    55 * 
     
    1616        try { 
    1717            return !!sessionStorage.getItem; 
    18         } catch(e){ 
     18        } catch(e) { 
    1919            return false; 
    2020        } 
    21   })() 
     21    })() 
    2222}; 
    2323 
     
    7979        // TODO why?? 
    8080        QUnit.current_testEnvironment = this.testEnvironment; 
    81          
     81 
    8282        try { 
    8383            if ( !config.pollution ) { 
     
    115115    teardown: function() { 
    116116        try { 
     117            this.testEnvironment.teardown.call(this.testEnvironment); 
    117118            checkPollution(); 
    118             this.testEnvironment.teardown.call(this.testEnvironment); 
    119119        } catch(e) { 
    120120            QUnit.ok( false, "Teardown failed on " + this.testName + ": " + e.message ); 
     
    125125            QUnit.ok( false, "Expected " + this.expected + " assertions, but " + this.assertions.length + " were run" ); 
    126126        } 
    127          
     127 
    128128        var good = 0, bad = 0, 
    129129            tests = id("qunit-tests"); 
     
    133133 
    134134        if ( tests ) { 
    135             var ol  = document.createElement("ol"); 
     135            var ol = document.createElement("ol"); 
    136136 
    137137            for ( var i = 0; i < this.assertions.length; i++ ) { 
     
    155155            if ( QUnit.config.reorder && defined.sessionStorage ) { 
    156156                if (bad) { 
    157                     sessionStorage.setItem("qunit-" + this.module + "-" + this.testName, bad) 
     157                    sessionStorage.setItem("qunit-" + this.module + "-" + this.testName, bad); 
    158158                } else { 
    159                     sessionStorage.removeItem("qunit-" + this.testName); 
     159                    sessionStorage.removeItem("qunit-" + this.module + "-" + this.testName); 
    160160                } 
    161161            } 
     
    167167            var b = document.createElement("strong"); 
    168168            b.innerHTML = this.name + " <b class='counts'>(<b class='failed'>" + bad + "</b>, <b class='passed'>" + good + "</b>, " + this.assertions.length + ")</b>"; 
    169              
     169 
    170170            var a = document.createElement("a"); 
    171171            a.innerHTML = "Rerun"; 
    172172            a.href = QUnit.url({ filter: getText([b]).replace(/\([^)]+\)$/, "").replace(/(^\s*|\s*$)/g, "") }); 
    173              
     173 
    174174            addEvent(b, "click", function() { 
    175175                var next = b.nextSibling.nextSibling, 
     
    177177                next.style.display = display === "none" ? "block" : "none"; 
    178178            }); 
    179              
     179 
    180180            addEvent(b, "dblclick", function(e) { 
    181181                var target = e && e.target ? e.target : window.event.srcElement; 
     
    218218        } ); 
    219219    }, 
    220      
     220 
    221221    queue: function() { 
    222222        var test = this; 
     
    247247        }; 
    248248    } 
    249      
     249 
    250250}; 
    251251 
     
    266266        QUnit.test(testName, expected, callback, true); 
    267267    }, 
    268      
     268 
    269269    test: function(testName, expected, callback, async) { 
    270270        var name = '<span class="test-name">' + testName + '</span>', testEnvironmentArg; 
     
    276276        // is 2nd argument a testEnvironment? 
    277277        if ( expected && typeof expected === 'object') { 
    278             testEnvironmentArg =  expected; 
     278            testEnvironmentArg = expected; 
    279279            expected = null; 
    280280        } 
     
    287287            return; 
    288288        } 
    289          
     289 
    290290        var test = new Test(name, testName, expected, testEnvironmentArg, async, callback); 
    291291        test.module = config.currentModule; 
     
    293293        test.queue(); 
    294294    }, 
    295      
     295 
    296296    /** 
    297297     * Specify the number of expected assertions to gurantee that failed test (no assertions are run at all) don't slip through. 
     
    338338        QUnit.push(expected != actual, actual, expected, message); 
    339339    }, 
    340      
     340 
    341341    deepEqual: function(actual, expected, message) { 
    342342        QUnit.push(QUnit.equiv(actual, expected), actual, expected, message); 
     
    357357    raises: function(block, expected, message) { 
    358358        var actual, ok = false; 
    359      
     359 
    360360        if (typeof expected === 'string') { 
    361361            message = expected; 
    362362            expected = null; 
    363363        } 
    364      
     364 
    365365        try { 
    366366            block(); 
     
    368368            actual = e; 
    369369        } 
    370      
     370 
    371371        if (actual) { 
    372372            // we don't want to validate thrown error 
    373373            if (!expected) { 
    374374                ok = true; 
    375             // expected is a regexp  
     375            // expected is a regexp 
    376376            } else if (QUnit.objectType(expected) === "regexp") { 
    377377                ok = expected.test(actual); 
    378             // expected is a constructor     
     378            // expected is a constructor 
    379379            } else if (actual instanceof expected) { 
    380380                ok = true; 
    381             // expected is a validation function which returns true is validation passed     
     381            // expected is a validation function which returns true is validation passed 
    382382            } else if (expected.call({}, actual) === true) { 
    383383                ok = true; 
    384384            } 
    385385        } 
    386              
     386 
    387387        QUnit.ok(ok, message); 
    388388    }, 
     
    401401        if ( defined.setTimeout ) { 
    402402            window.setTimeout(function() { 
     403                if (config.semaphore > 0) { 
     404                    return; 
     405                } 
    403406                if ( config.timeout ) { 
    404407                    clearTimeout(config.timeout); 
     
    413416        } 
    414417    }, 
    415      
     418 
    416419    stop: function(timeout) { 
    417420        config.semaphore++; 
     
    439442    // block until document ready 
    440443    blocking: true, 
    441      
     444 
     445    // when enabled, show only failing tests 
     446    // gets persisted through sessionStorage and can be changed in UI via checkbox 
     447    hidepassed: false, 
     448 
    442449    // by default, run previously failed tests first 
    443450    // very useful in combination with "Hide passed tests" checked 
    444451    reorder: true, 
     452 
     453    // by default, modify document.title when suite is done 
     454    altertitle: true, 
    445455 
    446456    noglobals: false, 
     
    520530            result.parentNode.removeChild( result ); 
    521531        } 
    522          
     532 
    523533        if ( tests ) { 
    524534            result = document.createElement( "p" ); 
     
    529539        } 
    530540    }, 
    531      
     541 
    532542    /** 
    533543     * Resets the test setup. Useful for tests that modify the DOM. 
    534      *  
     544     * 
    535545     * If jQuery is available, uses jQuery's html(), otherwise just innerHTML. 
    536546     */ 
    537547    reset: function() { 
    538548        if ( window.jQuery ) { 
    539             jQuery( "#main, #qunit-fixture" ).html( config.fixture ); 
     549            jQuery( "#qunit-fixture" ).html( config.fixture ); 
    540550        } else { 
    541             var main = id( 'main' ) || id( 'qunit-fixture' ); 
     551            var main = id( 'qunit-fixture' ); 
    542552            if ( main ) { 
    543553                main.innerHTML = config.fixture; 
     
    545555        } 
    546556    }, 
    547      
     557 
    548558    /** 
    549559     * Trigger an event on an element. 
     
    565575        } 
    566576    }, 
    567      
     577 
    568578    // Safe object type checking 
    569579    is: function( type, obj ) { 
    570580        return QUnit.objectType( obj ) == type; 
    571581    }, 
    572      
     582 
    573583    objectType: function( obj ) { 
    574584        if (typeof obj === "undefined") { 
     
    604614        return undefined; 
    605615    }, 
    606      
     616 
    607617    push: function(result, actual, expected, message) { 
    608618        var details = { 
     
    612622            expected: expected 
    613623        }; 
    614          
     624 
    615625        message = escapeHtml(message) || (result ? "okay" : "failed"); 
    616626        message = '<span class="test-message">' + message + "</span>"; 
     
    626636            if (source) { 
    627637                details.source = source; 
    628                 output += '<tr class="test-source"><th>Source: </th><td><pre>' + source +'</pre></td></tr>'; 
     638                output += '<tr class="test-source"><th>Source: </th><td><pre>' + escapeHtml(source) + '</pre></td></tr>'; 
    629639            } 
    630640        } 
    631641        output += "</table>"; 
    632          
     642 
    633643        QUnit.log(details); 
    634          
     644 
    635645        config.current.assertions.push({ 
    636646            result: !!result, 
     
    638648        }); 
    639649    }, 
    640      
     650 
    641651    url: function( params ) { 
    642652        params = extend( extend( {}, QUnit.urlParams ), params ); 
     
    649659        return window.location.pathname + querystring.slice( 0, -1 ); 
    650660    }, 
    651      
     661 
     662    extend: extend, 
     663    id: id, 
     664    addEvent: addEvent, 
     665 
    652666    // Logging callbacks; all receive a single argument with the listed properties 
    653667    // run test/logs.html for any related changes 
     
    671685} 
    672686 
    673 addEvent(window, "load", function() { 
     687QUnit.load = function() { 
    674688    QUnit.begin({}); 
    675      
     689 
    676690    // Initialize the config, saving the execution queue 
    677691    var oldconfig = extend({}, config); 
     
    696710        }); 
    697711    } 
    698      
     712 
    699713    var toolbar = id("qunit-testrunner-toolbar"); 
    700714    if ( toolbar ) { 
     
    712726            if ( defined.sessionStorage ) { 
    713727                if (filter.checked) { 
    714                     sessionStorage.setItem("qunit-filter-passed-tests",  "true"); 
     728                    sessionStorage.setItem("qunit-filter-passed-tests", "true"); 
    715729                } else { 
    716730                    sessionStorage.removeItem("qunit-filter-passed-tests"); 
     
    718732            } 
    719733        }); 
    720         if ( defined.sessionStorage && sessionStorage.getItem("qunit-filter-passed-tests") ) { 
     734        if ( config.hidepassed || defined.sessionStorage && sessionStorage.getItem("qunit-filter-passed-tests") ) { 
    721735            filter.checked = true; 
    722736            var ol = document.getElementById("qunit-tests"); 
     
    731745    } 
    732746 
    733     var main = id('main') || id('qunit-fixture'); 
     747    var main = id('qunit-fixture'); 
    734748    if ( main ) { 
    735749        config.fixture = main.innerHTML; 
     
    739753        QUnit.start(); 
    740754    } 
    741 }); 
     755}; 
     756 
     757addEvent(window, "load", QUnit.load); 
    742758 
    743759function done() { 
     
    775791    } 
    776792 
    777     if ( tests ) {   
     793    if ( tests ) { 
    778794        id( "qunit-testresult" ).innerHTML = html; 
     795    } 
     796 
     797    if ( config.altertitle && typeof document !== "undefined" && document.title ) { 
     798        // show ✖ for good, ✔ for bad suite result in title 
     799        // use escape sequences in case file gets loaded with non-utf-8-charset 
     800        document.title = [ 
     801            (config.stats.bad ? "\u2716" : "\u2714"), 
     802            document.title.replace(/^[\u2714\u2716] /i, "") 
     803        ].join(" "); 
    779804    } 
    780805 
    781806    QUnit.done( { 
    782807        failed: config.stats.bad, 
    783         passed: passed,  
     808        passed: passed, 
    784809        total: config.stats.all, 
    785810        runtime: runtime 
     
    795820    } 
    796821 
    797     not = filter.charAt( 0 ) === "!"; 
     822    var not = filter.charAt( 0 ) === "!"; 
    798823    if ( not ) { 
    799824        filter = filter.slice( 1 ); 
     
    863888        } 
    864889    } 
    865   if (!config.blocking && !config.queue.length) { 
    866     done(); 
    867   } 
     890    if (!config.blocking && !config.queue.length) { 
     891        done(); 
     892    } 
    868893} 
    869894 
    870895function saveGlobal() { 
    871896    config.pollution = []; 
    872      
     897 
    873898    if ( config.noglobals ) { 
    874899        for ( var key in window ) { 
     
    881906    var old = config.pollution; 
    882907    saveGlobal(); 
    883      
     908 
    884909    var newGlobals = diff( config.pollution, old ); 
    885910    if ( newGlobals.length > 0 ) { 
     
    952977QUnit.equiv = function () { 
    953978 
    954     var innerEquiv; // the real equiv function 
    955     var callers = []; // stack to decide between skip/abort functions 
    956     var parents = []; // stack to avoiding loops from circular referencing 
    957  
    958     // Call the o related callback with the given arguments. 
    959     function bindCallbacks(o, callbacks, args) { 
    960         var prop = QUnit.objectType(o); 
    961         if (prop) { 
    962             if (QUnit.objectType(callbacks[prop]) === "function") { 
    963                 return callbacks[prop].apply(callbacks, args); 
    964             } else { 
    965                 return callbacks[prop]; // or undefined 
    966             } 
    967         } 
    968     } 
    969      
    970     var callbacks = function () { 
    971  
    972         // for string, boolean, number and null 
    973         function useStrictEquality(b, a) { 
    974             if (b instanceof a.constructor || a instanceof b.constructor) { 
    975                 // to catch short annotaion VS 'new' annotation of a declaration 
    976                 // e.g. var i = 1; 
    977                 //      var j = new Number(1); 
    978                 return a == b; 
    979             } else { 
    980                 return a === b; 
    981             } 
    982         } 
    983  
    984         return { 
    985             "string": useStrictEquality, 
    986             "boolean": useStrictEquality, 
    987             "number": useStrictEquality, 
    988             "null": useStrictEquality, 
    989             "undefined": useStrictEquality, 
    990  
    991             "nan": function (b) { 
    992                 return isNaN(b); 
    993             }, 
    994  
    995             "date": function (b, a) { 
    996                 return QUnit.objectType(b) === "date" && a.valueOf() === b.valueOf(); 
    997             }, 
    998  
    999             "regexp": function (b, a) { 
    1000                 return QUnit.objectType(b) === "regexp" && 
    1001                     a.source === b.source && // the regex itself 
    1002                     a.global === b.global && // and its modifers (gmi) ... 
    1003                     a.ignoreCase === b.ignoreCase && 
    1004                     a.multiline === b.multiline; 
    1005             }, 
    1006  
    1007             // - skip when the property is a method of an instance (OOP) 
    1008             // - abort otherwise, 
    1009             //   initial === would have catch identical references anyway 
    1010             "function": function () { 
    1011                 var caller = callers[callers.length - 1]; 
    1012                 return caller !== Object && 
    1013                         typeof caller !== "undefined"; 
    1014             }, 
    1015  
    1016             "array": function (b, a) { 
    1017                 var i, j, loop; 
    1018                 var len; 
    1019  
    1020                 // b could be an object literal here 
    1021                 if ( ! (QUnit.objectType(b) === "array")) { 
    1022                     return false; 
    1023                 }    
    1024                  
    1025                 len = a.length; 
    1026                 if (len !== b.length) { // safe and faster 
    1027                     return false; 
    1028                 } 
    1029                  
    1030                 //track reference to avoid circular references 
    1031                 parents.push(a); 
    1032                 for (i = 0; i < len; i++) { 
    1033                     loop = false; 
    1034                     for(j=0;j<parents.length;j++){ 
    1035                         if(parents[j] === a[i]){ 
    1036                             loop = true;//dont rewalk array 
    1037                         } 
    1038                     } 
    1039                     if (!loop && ! innerEquiv(a[i], b[i])) { 
    1040                         parents.pop(); 
    1041                         return false; 
    1042                     } 
    1043                 } 
    1044                 parents.pop(); 
    1045                 return true; 
    1046             }, 
    1047  
    1048             "object": function (b, a) { 
    1049                 var i, j, loop; 
    1050                 var eq = true; // unless we can proove it 
    1051                 var aProperties = [], bProperties = []; // collection of strings 
    1052  
    1053                 // comparing constructors is more strict than using instanceof 
    1054                 if ( a.constructor !== b.constructor) { 
    1055                     return false; 
    1056                 } 
    1057  
    1058                 // stack constructor before traversing properties 
    1059                 callers.push(a.constructor); 
    1060                 //track reference to avoid circular references 
    1061                 parents.push(a); 
    1062                  
    1063                 for (i in a) { // be strict: don't ensures hasOwnProperty and go deep 
    1064                     loop = false; 
    1065                     for(j=0;j<parents.length;j++){ 
    1066                         if(parents[j] === a[i]) 
    1067                             loop = true; //don't go down the same path twice 
    1068                     } 
    1069                     aProperties.push(i); // collect a's properties 
    1070  
    1071                     if (!loop && ! innerEquiv(a[i], b[i])) { 
    1072                         eq = false; 
    1073                         break; 
    1074                     } 
    1075                 } 
    1076  
    1077                 callers.pop(); // unstack, we are done 
    1078                 parents.pop(); 
    1079  
    1080                 for (i in b) { 
    1081                     bProperties.push(i); // collect b's properties 
    1082                 } 
    1083  
    1084                 // Ensures identical properties name 
    1085                 return eq && innerEquiv(aProperties.sort(), bProperties.sort()); 
    1086             } 
    1087         }; 
    1088     }(); 
    1089  
    1090     innerEquiv = function () { // can take multiple arguments 
    1091         var args = Array.prototype.slice.apply(arguments); 
    1092         if (args.length < 2) { 
    1093             return true; // end transition 
    1094         } 
    1095  
    1096         return (function (a, b) { 
    1097             if (a === b) { 
    1098                 return true; // catch the most you can 
    1099             } else if (a === null || b === null || typeof a === "undefined" || typeof b === "undefined" || QUnit.objectType(a) !== QUnit.objectType(b)) { 
    1100                 return false; // don't lose time with error prone cases 
    1101             } else { 
    1102                 return bindCallbacks(a, callbacks, [b, a]); 
    1103             } 
    1104  
    1105         // apply transition with (1..n) arguments 
    1106         })(args[0], args[1]) && arguments.callee.apply(this, args.splice(1, args.length -1)); 
    1107     }; 
    1108  
    1109     return innerEquiv; 
     979    var innerEquiv; // the real equiv function 
     980    var callers = []; // stack to decide between skip/abort functions 
     981    var parents = []; // stack to avoiding loops from circular referencing 
     982 
     983    // Call the o related callback with the given arguments. 
     984    function bindCallbacks(o, callbacks, args) { 
     985        var prop = QUnit.objectType(o); 
     986        if (prop) { 
     987            if (QUnit.objectType(callbacks[prop]) === "function") { 
     988                return callbacks[prop].apply(callbacks, args); 
     989            } else { 
     990                return callbacks[prop]; // or undefined 
     991            } 
     992        } 
     993    } 
     994 
     995    var callbacks = function () { 
     996 
     997        // for string, boolean, number and null 
     998        function useStrictEquality(b, a) { 
     999            if (b instanceof a.constructor || a instanceof b.constructor) { 
     1000                // to catch short annotaion VS 'new' annotation of a 
     1001                // declaration 
     1002                // e.g. var i = 1; 
     1003                // var j = new Number(1); 
     1004                return a == b; 
     1005            } else { 
     1006                return a === b; 
     1007            } 
     1008        } 
     1009 
     1010        return { 
     1011            "string" : useStrictEquality, 
     1012            "boolean" : useStrictEquality, 
     1013            "number" : useStrictEquality, 
     1014            "null" : useStrictEquality, 
     1015            "undefined" : useStrictEquality, 
     1016 
     1017            "nan" : function(b) { 
     1018                return isNaN(b); 
     1019            }, 
     1020 
     1021            "date" : function(b, a) { 
     1022                return QUnit.objectType(b) === "date" 
     1023                        && a.valueOf() === b.valueOf(); 
     1024            }, 
     1025 
     1026            "regexp" : function(b, a) { 
     1027                return QUnit.objectType(b) === "regexp" 
     1028                        && a.source === b.source && // the regex itself 
     1029                        a.global === b.global && // and its modifers 
     1030                                                    // (gmi) ... 
     1031                        a.ignoreCase === b.ignoreCase 
     1032                        && a.multiline === b.multiline; 
     1033            }, 
     1034 
     1035            // - skip when the property is a method of an instance (OOP) 
     1036            // - abort otherwise, 
     1037            // initial === would have catch identical references anyway 
     1038            "function" : function() { 
     1039                var caller = callers[callers.length - 1]; 
     1040                return caller !== Object && typeof caller !== "undefined"; 
     1041            }, 
     1042 
     1043            "array" : function(b, a) { 
     1044                var i, j, loop; 
     1045                var len; 
     1046 
     1047                // b could be an object literal here 
     1048                if (!(QUnit.objectType(b) === "array")) { 
     1049                    return false; 
     1050                } 
     1051 
     1052                len = a.length; 
     1053                if (len !== b.length) { // safe and faster 
     1054                    return false; 
     1055                } 
     1056 
     1057                // track reference to avoid circular references 
     1058                parents.push(a); 
     1059                for (i = 0; i < len; i++) { 
     1060                    loop = false; 
     1061                    for (j = 0; j < parents.length; j++) { 
     1062                        if (parents[j] === a[i]) { 
     1063                            loop = true;// dont rewalk array 
     1064                        } 
     1065                    } 
     1066                    if (!loop && !innerEquiv(a[i], b[i])) { 
     1067                        parents.pop(); 
     1068                        return false; 
     1069                    } 
     1070                } 
     1071                parents.pop(); 
     1072                return true; 
     1073            }, 
     1074 
     1075            "object" : function(b, a) { 
     1076                var i, j, loop; 
     1077                var eq = true; // unless we can proove it 
     1078                var aProperties = [], bProperties = []; // collection of 
     1079                                                        // strings 
     1080 
     1081                // comparing constructors is more strict than using 
     1082                // instanceof 
     1083                if (a.constructor !== b.constructor) { 
     1084                    return false; 
     1085                } 
     1086 
     1087                // stack constructor before traversing properties 
     1088                callers.push(a.constructor); 
     1089                // track reference to avoid circular references 
     1090                parents.push(a); 
     1091 
     1092                for (i in a) { // be strict: don't ensures hasOwnProperty 
     1093                                // and go deep 
     1094                    loop = false; 
     1095                    for (j = 0; j < parents.length; j++) { 
     1096                        if (parents[j] === a[i]) 
     1097                            loop = true; // don't go down the same path 
     1098                                            // twice 
     1099                    } 
     1100                    aProperties.push(i); // collect a's properties 
     1101 
     1102                    if (!loop && !innerEquiv(a[i], b[i])) { 
     1103                        eq = false; 
     1104                        break; 
     1105                    } 
     1106                } 
     1107 
     1108                callers.pop(); // unstack, we are done 
     1109                parents.pop(); 
     1110 
     1111                for (i in b) { 
     1112                    bProperties.push(i); // collect b's properties 
     1113                } 
     1114 
     1115                // Ensures identical properties name 
     1116                return eq 
     1117                        && innerEquiv(aProperties.sort(), bProperties 
     1118                                .sort()); 
     1119            } 
     1120        }; 
     1121    }(); 
     1122 
     1123    innerEquiv = function() { // can take multiple arguments 
     1124        var args = Array.prototype.slice.apply(arguments); 
     1125        if (args.length < 2) { 
     1126            return true; // end transition 
     1127        } 
     1128 
     1129        return (function(a, b) { 
     1130            if (a === b) { 
     1131                return true; // catch the most you can 
     1132            } else if (a === null || b === null || typeof a === "undefined" 
     1133                    || typeof b === "undefined" 
     1134                    || QUnit.objectType(a) !== QUnit.objectType(b)) { 
     1135                return false; // don't lose time with error prone cases 
     1136            } else { 
     1137                return bindCallbacks(a, callbacks, [ b, a ]); 
     1138            } 
     1139 
     1140            // apply transition with (1..n) arguments 
     1141        })(args[0], args[1]) 
     1142                && arguments.callee.apply(this, args.splice(1, 
     1143                        args.length - 1)); 
     1144    }; 
     1145 
     1146    return innerEquiv; 
    11101147 
    11111148}(); 
    11121149 
    11131150/** 
    1114  * jsDump 
    1115  * Copyright (c) 2008 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com 
    1116  * Licensed under BSD (http://www.opensource.org/licenses/bsd-license.php) 
    1117  * Date: 5/15/2008 
     1151 * jsDump Copyright (c) 2008 Ariel Flesler - aflesler(at)gmail(dot)com | 
     1152 * http://flesler.blogspot.com Licensed under BSD 
     1153 * (http://www.opensource.org/licenses/bsd-license.php) Date: 5/15/2008 
     1154 * 
    11181155 * @projectDescription Advanced and extensible data dumping for Javascript. 
    11191156 * @version 1.0.0 
     
    11261163    }; 
    11271164    function literal( o ) { 
    1128         return o + '';   
     1165        return o + ''; 
    11291166    }; 
    11301167    function join( pre, arr, post ) { 
     
    11381175        return [ pre, inner + arr, base + post ].join(s); 
    11391176    }; 
    1140     function array( arr ) { 
    1141         var i = arr.length, ret = Array(i);                  
     1177    function array( arr, stack ) { 
     1178        var i = arr.length, ret = Array(i); 
    11421179        this.up(); 
    11431180        while ( i-- ) 
    1144             ret[i] = this.parse( arr[i] );               
     1181            ret[i] = this.parse( arr[i] , undefined , stack); 
    11451182        this.down(); 
    11461183        return join( '[', ret, ']' ); 
    11471184    }; 
    1148      
     1185 
    11491186    var reName = /^function (\w+)/; 
    1150      
     1187 
    11511188    var jsDump = { 
    1152         parse:function( obj, type ) { //type is used mostly internally, you can fix a (custom)type in advance 
    1153             var parser = this.parsers[ type || this.typeOf(obj) ]; 
    1154             type = typeof parser;            
    1155              
    1156             return type == 'function' ? parser.call( this, obj ) : 
    1157                    type == 'string' ? parser : 
    1158                    this.parsers.error; 
     1189        parse:function( obj, type, stack ) { //type is used mostly internally, you can fix a (custom)type in advance 
     1190            stack = stack || [ ]; 
     1191            var parser = this.parsers[ type || this.typeOf(obj) ]; 
     1192            type = typeof parser; 
     1193            var inStack = inArray(obj, stack); 
     1194            if (inStack != -1) { 
     1195                return 'recursion('+(inStack - stack.length)+')'; 
     1196            } 
     1197            //else 
     1198            if (type == 'function')  { 
     1199                    stack.push(obj); 
     1200                    var res = parser.call( this, obj, stack ); 
     1201                    stack.pop();                     
     1202                    return res; 
     1203            }  
     1204            // else  
     1205            return (type == 'string') ? parser : this.parsers.error; 
    11591206        }, 
    11601207        typeOf:function( obj ) { 
     
    12041251        }, 
    12051252        // The next 3 are exposed so you can use them 
    1206         quote:quote,  
     1253        quote:quote, 
    12071254        literal:literal, 
    12081255        join:join, 
     
    12231270                    ret += ' ' + name; 
    12241271                ret += '('; 
    1225                  
     1272 
    12261273                ret = [ ret, QUnit.jsDump.parse( fn, 'functionArgs' ), '){'].join(''); 
    12271274                return join( ret, QUnit.jsDump.parse(fn,'functionCode'), '}' ); 
     
    12301277            nodelist: array, 
    12311278            arguments: array, 
    1232             object:function( map ) { 
     1279            object:function( map, stack ) { 
    12331280                var ret = [ ]; 
    12341281                QUnit.jsDump.up(); 
    1235                 for ( var key in map ) 
    1236                     ret.push( QUnit.jsDump.parse(key,'key') + ': ' + QUnit.jsDump.parse(map[key]) ); 
     1282                for ( var key in map ) { 
     1283                    var val = map[key]; 
     1284                    ret.push( QUnit.jsDump.parse(key,'key') + ': ' + QUnit.jsDump.parse(val, undefined, stack)); 
     1285                } 
    12371286                QUnit.jsDump.down(); 
    12381287                return join( '{', ret, '}' ); 
     
    12411290                var open = QUnit.jsDump.HTML ? '&lt;' : '<', 
    12421291                    close = QUnit.jsDump.HTML ? '&gt;' : '>'; 
    1243                      
     1292 
    12441293                var tag = node.nodeName.toLowerCase(), 
    12451294                    ret = open + tag; 
    1246                      
     1295 
    12471296                for ( var a in QUnit.jsDump.DOMAttrs ) { 
    12481297                    var val = node[QUnit.jsDump.DOMAttrs[a]]; 
     
    12541303            functionArgs:function( fn ) {//function calls it internally, it's the arguments part of the function 
    12551304                var l = fn.length; 
    1256                 if ( !l ) return '';                 
    1257                  
     1305                if ( !l ) return ''; 
     1306 
    12581307                var args = Array(l); 
    12591308                while ( l-- ) 
     
    13031352}; 
    13041353 
     1354//from jquery.js 
     1355function inArray( elem, array ) { 
     1356    if ( array.indexOf ) { 
     1357        return array.indexOf( elem ); 
     1358    } 
     1359 
     1360    for ( var i = 0, length = array.length; i < length; i++ ) { 
     1361        if ( array[ i ] === elem ) { 
     1362            return i; 
     1363        } 
     1364    } 
     1365 
     1366    return -1; 
     1367} 
     1368 
    13051369/* 
    13061370 * Javascript Diff Algorithm 
     
    13121376 * More Info: 
    13131377 *  http://ejohn.org/projects/javascript-diff-algorithm/ 
    1314  *   
     1378 * 
    13151379 * Usage: QUnit.diff(expected, actual) 
    1316  *  
     1380 * 
    13171381 * 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" 
    13181382 */ 
    13191383QUnit.diff = (function() { 
    1320     function diff(o, n){ 
     1384    function diff(o, n) { 
    13211385        var ns = new Object(); 
    13221386        var os = new Object(); 
    1323          
     1387 
    13241388        for (var i = 0; i < n.length; i++) { 
    1325             if (ns[n[i]] == null)  
     1389            if (ns[n[i]] == null) 
    13261390                ns[n[i]] = { 
    13271391                    rows: new Array(), 
     
    13301394            ns[n[i]].rows.push(i); 
    13311395        } 
    1332          
     1396 
    13331397        for (var i = 0; i < o.length; i++) { 
    1334             if (os[o[i]] == null)  
     1398            if (os[o[i]] == null) 
    13351399                os[o[i]] = { 
    13361400                    rows: new Array(), 
     
    13391403            os[o[i]].rows.push(i); 
    13401404        } 
    1341          
     1405 
    13421406        for (var i in ns) { 
    13431407            if (ns[i].rows.length == 1 && typeof(os[i]) != "undefined" && os[i].rows.length == 1) { 
     
    13521416            } 
    13531417        } 
    1354          
     1418 
    13551419        for (var i = 0; i < n.length - 1; i++) { 
    13561420            if (n[i].text != null && n[i + 1].text == null && n[i].row + 1 < o.length && o[n[i].row + 1].text == null && 
     
    13661430            } 
    13671431        } 
    1368          
     1432 
    13691433        for (var i = n.length - 1; i > 0; i--) { 
    13701434            if (n[i].text != null && n[i - 1].text == null && n[i].row > 0 && o[n[i].row - 1].text == null && 
     
    13801444            } 
    13811445        } 
    1382          
     1446 
    13831447        return { 
    13841448            o: o, 
     
    13861450        }; 
    13871451    } 
    1388      
    1389     return function(o, n){ 
     1452 
     1453    return function(o, n) { 
    13901454        o = o.replace(/\s+$/, ''); 
    13911455        n = n.replace(/\s+$/, ''); 
     
    13931457 
    13941458        var str = ""; 
    1395          
     1459 
    13961460        var oSpace = o.match(/\s+/g); 
    13971461        if (oSpace == null) { 
     
    14081472            nSpace.push(" "); 
    14091473        } 
    1410          
     1474 
    14111475        if (out.n.length == 0) { 
    14121476            for (var i = 0; i < out.o.length; i++) { 
     
    14201484                } 
    14211485            } 
    1422              
     1486 
    14231487            for (var i = 0; i < out.n.length; i++) { 
    14241488                if (out.n[i].text == null) { 
     
    14271491                else { 
    14281492                    var pre = ""; 
    1429                      
     1493 
    14301494                    for (n = out.n[i].row + 1; n < out.o.length && out.o[n].text == null; n++) { 
    14311495                        pre += '<del>' + out.o[n] + oSpace[n] + "</del>"; 
     
    14351499            } 
    14361500        } 
    1437          
     1501 
    14381502        return str; 
    14391503    }; 
Note: See TracChangeset for help on using the changeset viewer.