CLICK HERE TO BUY IT TODAY! OR GET IT FREE VIA TRIALPAY  

PHP Demo Application - Source Code

/Framework/Model/Vendor/jquery-ui/development-bundle/external/qunit.js



/*
 * QUnit - A JavaScript Unit Testing Framework
 * 
 * http://docs.jquery.com/QUnit
 *
 * Copyright (c) 2009 John Resig, Jörn Zaefferer
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 */
(function(window) {
	var QUnit = {
		    // call on start of module test to prepend name to all tests
		    module: function(nametestEnvironment) {
			        config.currentModule name;
			        synchronize(function() {
				            if ( config.currentModule ) {
					                QUnit.moduleDoneconfig.currentModuleconfig.moduleStats.badconfig.moduleStats.all );
					            }
				            config.currentModule name;
				            config.moduleTestEnvironment testEnvironment;
				            config.moduleStats = { all0bad0
					};
				            QUnit.moduleStartnametestEnvironment );
				        });
			    },
		    asyncTest: function(testNameexpectedcallback) {
			        if ( arguments.length === ) {
				            callback expected;
				            expected 0;
				        }
			        QUnit.test(testNameexpectedcallbacktrue);
			    },
		    test: function(testNameexpectedcallbackasync) {
			        var name '<span class="test-name">' testName '</span>'testEnvironmenttestEnvironmentArg;
			        if ( arguments.length === ) {
				            callback expected;
				            expected null;
				        }
			        // is 2nd argument a testEnvironment?
			        if ( expected && typeof expected === 'object') {
				            testEnvironmentArg =  expected;
				            expected null;
				        }
			        if ( config.currentModule ) {
				            name '<span class="module-name">' config.currentModule "</span>: " name;
				        }
			        if ( !validTest(config.currentModule ": " testName) ) {
				            return;
				        }
			        synchronize(function() {
				            testEnvironment extend({
					                setup: function() {},
					                teardown: function() {}
					            }, config.moduleTestEnvironment);
				            if (testEnvironmentArg) {
					                extend(testEnvironment,testEnvironmentArg);
					            }
				            QUnit.testStarttestNametestEnvironment );
				            // allow utility functions to access the current test environment
				            QUnit.current_testEnvironment testEnvironment;
				            config.assertions [];
				            config.expected expected;
				            var tests id("qunit-tests");
				            if (tests) {
					                var document.createElement("strong");
					                    b.innerHTML "Running " name;
					                var li document.createElement("li");
					                    li.appendChild);
					                    li.id "current-test-output";
					                tests.appendChildli )
					            }
				            try {
					                if ( !config.pollution ) {
						                    saveGlobal();
						                }
					                testEnvironment.setup.call(testEnvironment);
					            } catch(e) {
					                QUnit.okfalse"Setup failed on " name ": " e.message );
					            }
				});
			        synchronize(function() {
				            if ( async ) {
					                QUnit.stop();
					            }
				            try {
					                callback.call(testEnvironment);
					            } catch(e) {
					                fail("Test " name " died, exception and test follows"ecallback);
					                QUnit.okfalse"Died on test #" + (config.assertions.length 1) + ": " e.message );
					                // else next test will carry the responsibility
					                saveGlobal();
					                // Restart the tests if they're blocking
					                if ( config.blocking ) {
						                    start();
						                }
					            }
				        });
			        synchronize(function() {
				            try {
					                checkPollution();
					                testEnvironment.teardown.call(testEnvironment);
					            } catch(e) {
					                QUnit.okfalse"Teardown failed on " name ": " e.message );
					            }
				});
			        synchronize(function() {
				            try {
					                QUnit.reset();
					            } catch(e) {
					                fail("reset() failed, following Test " name ", exception and reset fn follows"ereset);
					            }
				            if ( config.expected && config.expected != config.assertions.length ) {
					                QUnit.okfalse"Expected " config.expected " assertions, but " config.assertions.length " were run" );
					            }
				            var good 0bad 0,
				                tests id("qunit-tests");
				            config.stats.all += config.assertions.length;
				            config.moduleStats.all += config.assertions.length;
				            if ( tests ) {
					                var ol  document.createElement("ol");
					                for ( var 0;
					 config.assertions.length;
					 i++ ) {
						                    var assertion config.assertions[i];
						                    var li document.createElement("li");
						                    li.className assertion.result "pass" "fail";
						                    li.innerHTML assertion.message || "(no message)";
						                    ol.appendChildli );
						                    if ( assertion.result ) {
							                        good++;
							                    } else {
							                        bad++;
							                        config.stats.bad++;
							                        config.moduleStats.bad++;
							                    }
						                }
					                if (bad == 0) {
						                    ol.style.display "none";
						                }
					                var document.createElement("strong");
					                b.innerHTML name " <b style='color:black;
					'>(<b class='fail'>" bad "</b>, <b class='pass'>" good "</b>, " config.assertions.length ")</b>";
					                addEvent(b"click", function() {
						                    var next b.nextSiblingdisplay next.style.display;
						                    next.style.display display === "none" "block" "none";
						                });
					                addEvent(b"dblclick", function(e) {
						                    var target && e.target e.target window.event.srcElement;
						                    if ( target.nodeName.toLowerCase() == "span" || target.nodeName.toLowerCase() == "b" ) {
							                        target target.parentNode;
							                    }
						                    if ( window.location && target.nodeName.toLowerCase() === "strong" ) {
							                        window.location.search "?" encodeURIComponent(getText([target]).replace(/\(.+\)$/, "").replace(/(^\s*|\s*$)/g""));
							                    }
						                });
					                var li id("current-test-output");
					                li.id "";
					                li.className bad "fail" "pass";
					                li.removeChildli.firstChild );
					                li.appendChild);
					                li.appendChildol );
					                if ( bad ) {
						                    var toolbar id("qunit-testrunner-toolbar");
						                    if ( toolbar ) {
							                        toolbar.style.display "block";
							                        id("qunit-filter-pass").disabled null;
							                        id("qunit-filter-missing").disabled null;
							                    }
						                }
					            } else {
					                for ( var 0;
					 config.assertions.length;
					 i++ ) {
						                    if ( !config.assertions[i].result ) {
							                        bad++;
							                        config.stats.bad++;
							                        config.moduleStats.bad++;
							                    }
						                }
					            }
				            QUnit.testDonetestNamebadconfig.assertions.length );
				            if ( !window.setTimeout && !config.queue.length ) {
					                done();
					            }
				        });
			        if ( window.setTimeout && !config.doneTimer ) {
				            config.doneTimer window.setTimeout(function(){
					                if ( !config.queue.length ) {
						                    done();
						                } else {
						                    synchronizedone );
						                }
					            }, 13);
				        }
			    },
		    /**
		     * Specify the number of expected assertions to gurantee that failed test (no assertions are run at all) don't slip through.
		     */
		    expect: function(asserts) {
			        config.expected asserts;
			    },
		    /**
		     * Asserts true.
		     * @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" );
		     */
		    ok: function(amsg) {
			        msg escapeHtml(msg);
			        QUnit.log(amsg);
			        config.assertions.push({
				            result: !!a,
				            messagemsg
				        });
			    },
		    /**
		     * Checks that the first two arguments are equal, with an optional message.
		     * Prints out both actual and expected values.
		     *
		     * Prefered to ok( actual == expected, message )
		     *
		     * @example equal( format("Received {0} bytes.", 2), "Received 2 bytes." );
		     *
		     * @param Object actual
		     * @param Object expected
		     * @param String message (optional)
		     */
		    equal: function(actualexpectedmessage) {
			        push(expected == actualactualexpectedmessage);
			    },
		    notEqual: function(actualexpectedmessage) {
			        push(expected != actualactualexpectedmessage);
			    },
		    deepEqual: function(actualexpectedmessage) {
			        push(QUnit.equiv(actualexpected), actualexpectedmessage);
			    },
		    notDeepEqual: function(actualexpectedmessage) {
			        push(!QUnit.equiv(actualexpected), actualexpectedmessage);
			    },
		    strictEqual: function(actualexpectedmessage) {
			        push(expected === actualactualexpectedmessage);
			    },
		    notStrictEqual: function(actualexpectedmessage) {
			        push(expected !== actualactualexpectedmessage);
			    },
		    raises: function(fn,  message) {
			        try {
				            fn();
				            okfalsemessage );
				        }
			        catch (e) {
				            oktruemessage );
				        }
			    },
		    start: function() {
			        // A slight delay, to avoid any current callbacks
			        if ( window.setTimeout ) {
				            window.setTimeout(function() {
					                if ( config.timeout ) {
						                    clearTimeout(config.timeout);
						                }
					                config.blocking false;
					                process();
					            }, 13);
				        } else {
				            config.blocking false;
				            process();
				        }
			    },
		    stop: function(timeout) {
			        config.blocking true;
			        if ( timeout && window.setTimeout ) {
				            config.timeout window.setTimeout(function() {
					                QUnit.okfalse"Test timed out" );
					                QUnit.start();
					            }, timeout);
				        }
			    }
		};
	// Backwards compatibility, deprecated
	QUnit.equals QUnit.equal;
	QUnit.same QUnit.deepEqual;
	// Maintain internal state
	var config = {
		    // The queue of tests to run
		    queue[],
		    // block until document ready
		    blockingtrue
		};
	// Load paramaters
	(function() {
		    var location window.location || { search""protocol"file:"
			},
		        GETParams location.search.slice(1).split('&');
		    for ( var 0;
		 GETParams.length;
		 i++ ) {
			        GETParams[i] = decodeURIComponentGETParams[i] );
			        if ( GETParams[i] === "noglobals" ) {
				            GETParams.splicei);
				            i--;
				            config.noglobals true;
				        } else if ( GETParams[i].search('=') > -) {
				            GETParams.splicei);
				            i--;
				        }
			    }
		    // restrict modules/tests by get parameters
		    config.filters GETParams;
		    // Figure out if we're running the tests from a server or not
		    QUnit.isLocal = !!(location.protocol === 'file:');
		})();
	// Expose the API as global variables, unless an 'exports'
	// object exists, in that case we assume we're in CommonJS
	if ( typeof exports === "undefined" || typeof require === "undefined" ) {
		    extend(windowQUnit);
		    window.QUnit QUnit;
		} else {
		    extend(exportsQUnit);
		    exports.QUnit QUnit;
		}
	// define these after exposing globals to keep them in these QUnit namespace only
	extend(QUnit, {
		    configconfig,
		    // Initialize the configuration options
		    init: function() {
			        extend(config, {
				            stats: { all0bad0
					},
				            moduleStats: { all0bad0
					},
				            started: +new Date,
				            updateRate1000,
				            blockingfalse,
				            autostarttrue,
				            autorunfalse,
				            assertions[],
				            filters[],
				            queue[]
				        });
			        var tests id("qunit-tests"),
			            banner id("qunit-banner"),
			            result id("qunit-testresult");
			        if ( tests ) {
				            tests.innerHTML "";
				        }
			        if ( banner ) {
				            banner.className "";
				        }
			        if ( result ) {
				            result.parentNode.removeChildresult );
				        }
			    },
		    /**
		     * Resets the test setup. Useful for tests that modify the DOM.
		     */
		    reset: function() {
			        if ( window.jQuery ) {
				            jQuery("#main, #qunit-fixture").htmlconfig.fixture );
				        }
			    },
		    /**
		     * Trigger an event on an element.
		     *
		     * @example triggerEvent( document.body, "click" );
		     *
		     * @param DOMElement elem
		     * @param String type
		     */
		    triggerEvent: function( elemtypeevent ) {
			        if ( document.createEvent ) {
				            event document.createEvent("MouseEvents");
				            event.initMouseEvent(typetruetrueelem.ownerDocument.defaultView,
				                00000falsefalsefalsefalse0null);
				            elem.dispatchEventevent );
				        } else if ( elem.fireEvent ) {
				            elem.fireEvent("on"+type);
				        }
			    },
		    // Safe object type checking
		    is: function( typeobj ) {
			        return QUnit.objectTypeobj ) == type;
			    },
		    objectType: function( obj ) {
			        if (typeof obj === "undefined") {
				                return "undefined";
				        // consider: typeof null === object
				        }
			        if (obj === null) {
				                return "null";
				        }
			        var type Object.prototype.toString.callobj )
			            .match(/^\[object\s(.*)\]$/)[1] || '';
			        switch (type) {
				                case 'Number':
				                        if (isNaN(obj)) {
					                                return "nan";
					                        } else {
					                                return "number";
					                        }
				                case 'String':
				                case 'Boolean':
				                case 'Array':
				                case 'Date':
				                case 'RegExp':
				                case 'Function':
				                        return type.toLowerCase();
				        }
			        if (typeof obj === "object") {
				                return "object";
				        }
			        return undefined;
			    },
		    // Logging callbacks
		    begin: function() {},
		    done: function(failurestotal{},
		    log: function(resultmessage{},
		    testStart: function(nametestEnvironment{},
		    testDone: function(namefailurestotal{},
		    moduleStart: function(nametestEnvironment{},
		    moduleDone: function(namefailurestotal{}
		});
	if ( typeof document === "undefined" || document.readyState === "complete" ) {
		    config.autorun true;
		}
	addEvent(window"load", function() {
		    QUnit.begin();
		    // Initialize the config, saving the execution queue
		    var oldconfig extend({}config);
		    QUnit.init();
		    extend(configoldconfig);
		    config.blocking false;
		    var userAgent id("qunit-userAgent");
		    if ( userAgent ) {
			        userAgent.innerHTML navigator.userAgent;
			    }
		    var toolbar id("qunit-testrunner-toolbar");
		    if ( toolbar ) {
			        toolbar.style.display "none";
			        var filter document.createElement("input");
			        filter.type "checkbox";
			        filter.id "qunit-filter-pass";
			        filter.disabled true;
			        addEventfilter"click", function() {
				            var li document.getElementsByTagName("li");
				            for ( var 0;
				 li.length;
				 i++ ) {
					                if ( li[i].className.indexOf("pass") > -) {
						                    li[i].style.display filter.checked "none" "";
						                }
					            }
				        });
			        toolbar.appendChildfilter );
			        var label document.createElement("label");
			        label.setAttribute("for""qunit-filter-pass");
			        label.innerHTML "Hide passed tests";
			        toolbar.appendChildlabel );
			        var missing document.createElement("input");
			        missing.type "checkbox";
			        missing.id "qunit-filter-missing";
			        missing.disabled true;
			        addEventmissing"click", function() {
				            var li document.getElementsByTagName("li");
				            for ( var 0;
				 li.length;
				 i++ ) {
					                if ( li[i].className.indexOf("fail") > -&& li[i].innerHTML.indexOf('missing test - untested code is broken code') > - ) {
						                    li[i].parentNode.parentNode.style.display missing.checked "none" "block";
						                }
					            }
				        });
			        toolbar.appendChildmissing );
			        label document.createElement("label");
			        label.setAttribute("for""qunit-filter-missing");
			        label.innerHTML "Hide missing tests (untested code is broken code)";
			        toolbar.appendChildlabel );
			    }
		    var main id('main') || id('qunit-fixture');
		    if ( main ) {
			        config.fixture main.innerHTML;
			    }
		    if (config.autostart) {
			        QUnit.start();
			    }
		});
	function done() {
		    if ( config.doneTimer && window.clearTimeout ) {
			        window.clearTimeoutconfig.doneTimer );
			        config.doneTimer null;
			    }
		    if ( config.queue.length ) {
			        config.doneTimer window.setTimeout(function(){
				            if ( !config.queue.length ) {
					                done();
					            } else {
					                synchronizedone );
					            }
				        }, 13);
			        return;
			    }
		    config.autorun true;
		    // Log the last module results
		    if ( config.currentModule ) {
			        QUnit.moduleDoneconfig.currentModuleconfig.moduleStats.badconfig.moduleStats.all );
			    }
		    var banner id("qunit-banner"),
		        tests id("qunit-tests"),
		        html = ['Tests completed in ',
		        +new Date config.started' milliseconds.<br/>',
		        '<span class="passed">'config.stats.all config.stats.bad'</span> tests of <span class="total">'config.stats.all'</span> passed, <span class="failed">'config.stats.bad,'</span> failed.'].join('');
		    if ( banner ) {
			        banner.className = (config.stats.bad "qunit-fail" "qunit-pass");
			    }
		    if ( tests ) {    
			        var result id("qunit-testresult");
			        if ( !result ) {
				            result document.createElement("p");
				            result.id "qunit-testresult";
				            result.className "result";
				            tests.parentNode.insertBeforeresulttests.nextSibling );
				        }
			        result.innerHTML html;
			    }
		    QUnit.doneconfig.stats.badconfig.stats.all );
		}
	function validTestname ) {
		    var config.filters.length,
		        run false;
		    if ( !) {
			        return true;
			    }
		    while ( i-- ) {
			        var filter config.filters[i],
			            not filter.charAt(0) == '!';
			        if ( not ) {
				            filter filter.slice(1);
				        }
			        if ( name.indexOf(filter) !== -) {
				            return !not;
				        }
			        if ( not ) {
				            run true;
				        }
			    }
		    return run;
		}
	function escapeHtml(s) {
		    === null "" "";
		    return s.replace(/[\&"<>\\]/g, function(s) {
			        switch(s) {
				            case "&": return "&amp;
				";
				            case "\\": return "\\\\";
				            case '"': return '\"';
				            case "<": return "&lt;
				";
				            case ">": return "&gt;
				";
				            default: return s;
				        }
			    });
		}
	function push(result, actual, expected, message) {
		    message = escapeHtml(message) || (result ? "okay" : "failed");
		    message = '<span class="test-message">' + message + "</span>";
		    expected = escapeHtml(QUnit.jsDump.parse(expected));
		    actual = escapeHtml(QUnit.jsDump.parse(actual));
		    var output = message + ', expected: <span class="test-expected">' + expected + '</span>';
		    if (actual != expected) {
			        output += ' result: <span class="test-actual">' + actual + '</span>, diff: ' + QUnit.diff(expected, actual);
			    }
		    // can't use ok, as that would double-escape messages
		    QUnit.log(result, output);
		    config.assertions.push({
			        result: !!result,
			        message: output
			    });
		}
	function synchronize( callback ) {
		    config.queue.push( callback );
		    if ( config.autorun && !config.blocking ) {
			        process();
			    }
		}
	function process() {
		    var start = (new Date()).getTime();
		    while ( config.queue.length && !config.blocking ) {
			        if ( config.updateRate <= 0 || (((new Date()).getTime() - start) < config.updateRate) ) {
				            config.queue.shift()();
				        } else {
				            setTimeout( process, 13 );
				            break;
				        }
			    }
		}
	function saveGlobal() {
		    config.pollution = [];
		    if ( config.noglobals ) {
			        for ( var key in window ) {
				            config.pollution.push( key );
				        }
			    }
		}
	function checkPollution( name ) {
		    var old = config.pollution;
		    saveGlobal();
		    var newGlobals = diff( old, config.pollution );
		    if ( newGlobals.length > 0 ) {
			        ok( false, "Introduced global variable(s): " + newGlobals.join("") );
			        config.expected++;
			    }
		    var deletedGlobals = diff( config.pollution, old );
		    if ( deletedGlobals.length > 0 ) {
			        ok( false, "Deleted global variable(s): " + deletedGlobals.join("") );
			        config.expected++;
			    }
		}
	// returns a new Array with the elements that are in a but not in b
	function diff( a, b ) {
		    var result = a.slice();
		    for ( var i = 0;
		 i < result.length;
		 i++ ) {
			        for ( var j = 0;
			 j < b.length;
			 j++ ) {
				            if ( result[i] === b[j] ) {
					                result.splice(i, 1);
					                i--;
					                break;
					            }
				        }
			    }
		    return result;
		}
	function fail(message, exception, callback) {
		    if ( typeof console !== "undefined" && console.error && console.warn ) {
			        console.error(message);
			        console.error(exception);
			        console.warn(callback.toString());
			    } else if ( window.opera && opera.postError ) {
			        opera.postError(message, exception, callback.toString);
			    }
		}
	function extend(a, b) {
		    for ( var prop in b ) {
			        a[prop] = b[prop];
			    }
		    return a;
		}
	function addEvent(elem, type, fn) {
		    if ( elem.addEventListener ) {
			        elem.addEventListener( type, fn, false );
			    } else if ( elem.attachEvent ) {
			        elem.attachEvent( "on" + type, fn );
			    } else {
			        fn();
			    }
		}
	function id(name) {
		    return !!(typeof document !== "undefined" && document && document.getElementById) &&
		        document.getElementById( name );
		}
	// Test for equality any JavaScript type.
	// Discussions and reference: http://philrathe.com/articles/equiv
	// Test suites: http://philrathe.com/tests/equiv
	// Author: Philippe Rathé <prathe@gmail.com>
	QUnit.equiv = function () {
		    var innerEquiv;
		 // the real equiv function
		    var callers = [];
		 // stack to decide between skip/abort functions
		    var parents = [];
		 // stack to avoiding loops from circular referencing
		    // Call the o related callback with the given arguments.
		    function bindCallbacks(o, callbacks, args) {
			        var prop = QUnit.objectType(o);
			        if (prop) {
				            if (QUnit.objectType(callbacks[prop]) === "function") {
					                return callbacks[prop].apply(callbacks, args);
					} else {
					                return callbacks[prop];
					 // or undefined
					}
				}
			}
		    var callbacks = function () {
			        // for string, boolean, number and null
			        function useStrictEquality(b, a) {
				            if (b instanceof a.constructor || a instanceof b.constructor) {
					                // to catch short annotaion VS 'new' annotation of a declaration
					                // e.g. var i = 1;
					                //      var j = new Number(1);
					                return a == b;
					} else {
					                return a === b;
					}
				}
			        return {
				            "string": useStrictEquality,
				            "boolean": useStrictEquality,
				            "number": useStrictEquality,
				            "null": useStrictEquality,
				            "undefined": useStrictEquality,
				            "nan": function (b) {
					                return isNaN(b);
					},
				            "date": function (b, a) {
					                return QUnit.objectType(b) === "date" && a.valueOf() === b.valueOf();
					},
				            "regexp": function (b, a) {
					                return QUnit.objectType(b) === "regexp" &&
					                    a.source === b.source && // the regex itself
					                    a.global === b.global && // and its modifers (gmi) ...
					                    a.ignoreCase === b.ignoreCase &&
					                    a.multiline === b.multiline;
					},
				            // - skip when the property is a method of an instance (OOP)
				            // - abort otherwise,
				            //   initial === would have catch identical references anyway
				            "function": function () {
					                var caller = callers[callers.length - 1];
					                return caller !== Object &&
					                        typeof caller !== "undefined";
					},
				            "array": function (b, a) {
					                var i, j, loop;
					                var len;
					                // b could be an object literal here
					                if ( ! (QUnit.objectType(b) === "array")) {
						                    return false;
						}   
					                len = a.length;
					                if (len !== b.length) {
						// safe and faster
						                    return false;
						}
					                //track reference to avoid circular references
					                parents.push(a);
					                for (i = 0;
					 i < len;
					 i++) {
						                    loop = false;
						                    for(j=0;
						j<parents.length;
						j++){
							                        if(parents[j] === a[i]){
								                            loop = true;
								//dont rewalk array
								}
							}
						                    if (!loop && ! innerEquiv(a[i], b[i])) {
							                        parents.pop();
							                        return false;
							}
						}
					                parents.pop();
					                return true;
					},
				            "object": function (b, a) {
					                var i, j, loop;
					                var eq = true;
					 // unless we can proove it
					                var aProperties = [], bProperties = [];
					 // collection of strings
					                // comparing constructors is more strict than using instanceof
					                if ( a.constructor !== b.constructor) {
						                    return false;
						}
					                // stack constructor before traversing properties
					                callers.push(a.constructor);
					                //track reference to avoid circular references
					                parents.push(a);
					                for (i in a) {
						// be strict: don't ensures hasOwnProperty and go deep
						                    loop = false;
						                    for(j=0;
						j<parents.length;
						j++){
							                        if(parents[j] === a[i])
							                            loop = true;
							 //don't go down the same path twice
							}
						                    aProperties.push(i);
						 // collect a's properties
						                    if (!loop && ! innerEquiv(a[i], b[i])) {
							                        eq = false;
							                        break;
							}
						}
					                callers.pop();
					 // unstack, we are done
					                parents.pop();
					                for (i in b) {
						                    bProperties.push(i);
						 // collect b's properties
						}
					                // Ensures identical properties name
					                return eq && innerEquiv(aProperties.sort(), bProperties.sort());
					}
				};
			}();
		    innerEquiv = function () {
			// can take multiple arguments
			        var args = Array.prototype.slice.apply(arguments);
			        if (args.length < 2) {
				            return true;
				 // end transition
				}
			        return (function (a, b) {
				            if (a === b) {
					                return true;
					 // catch the most you can
					} else if (a === null || b === null || typeof a === "undefined" || typeof b === "undefined" || QUnit.objectType(a) !== QUnit.objectType(b)) {
					                return false;
					 // don't lose time with error prone cases
					} else {
					                return bindCallbacks(a, callbacks, [b, a]);
					}
				        // apply transition with (1..n) arguments
				})(args[0], args[1]) && arguments.callee.apply(this, args.splice(1, args.length -1));
			};
		    return innerEquiv;
		}();
	/**
	 * jsDump
	 * Copyright (c) 2008 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com
	 * Licensed under BSD (http://www.opensource.org/licenses/bsd-license.php)
	 * Date: 5/15/2008
	 * @projectDescription Advanced and extensible data dumping for Javascript.
	 * @version 1.0.0
	 * @author Ariel Flesler
	 * @link {http://flesler.blogspot.com/2008/05/jsdump-pretty-dump-of-any-javascript.html}
	 */
	QUnit.jsDump = (function() {
		    function quote( str ) {
			        return '"' + str.toString().replace(/"/g, '\\"') + '"';
			    };
		    function literal( o ) {
			        return o + '';
			    };
		    function join( pre, arr, post ) {
			        var s = jsDump.separator(),
			            base = jsDump.indent(),
			            inner = jsDump.indent(1);
			        if ( arr.join )
			            arr = arr.join( ',' + s + inner );
			        if ( !arr )
			            return pre + post;
			        return [ pre, inner + arr, base + post ].join(s);
			    };
		    function array( arr ) {
			        var i = arr.length,    ret = Array(i);
			        this.up();
			        while ( i-- )
			            ret[i] = this.parse( arr[i] );
			        this.down();
			        return join( '[', ret, ']' );
			    };
		    var reName = /^function (\w+)/;
		    var jsDump = {
			        parse:function( obj, type ) {
				//type is used mostly internally, you can fix a (custom)type in advance
				            var    parser = this.parsers[ type || this.typeOf(obj) ];
				            type = typeof parser;
				            return type == 'function' ? parser.call( this, obj ) :
				                   type == 'string' ? parser :
				                   this.parsers.error;
				        },
			        typeOf:function( obj ) {
				            var type;
				            if ( obj === null ) {
					                type = "null";
					            } else if (typeof obj === "undefined") {
					                type = "undefined";
					            } else if (QUnit.is("RegExp", obj)) {
					                type = "regexp";
					            } else if (QUnit.is("Date", obj)) {
					                type = "date";
					            } else if (QUnit.is("Function", obj)) {
					                type = "function";
					            } else if (obj.setInterval && obj.document && !obj.nodeType) {
					                type = "window";
					            } else if (obj.nodeType === 9) {
					                type = "document";
					            } else if (obj.nodeType) {
					                type = "node";
					            } else if (typeof obj === "object" && typeof obj.length === "number" && obj.length >= 0) {
					                type = "array";
					            } else {
					                type = typeof obj;
					            }
				            return type;
				        },
			        separator:function() {
				            return this.multiline ?    this.HTML ? '<br />' : '\n' : this.HTML ? '&nbsp;
				' : ' ';
				        },
			        indent:function( extra ) {// extra can be a number, shortcut for increasing-calling-decreasing
				            if ( !this.multiline )
				                return '';
				            var chr = this.indentChar;
				            if ( this.HTML )
				                chr = chr.replace(/\t/g,'   ').replace(/ /g,'&nbsp;
				');
				            return Array( this._depth_ + (extra||0) ).join(chr);
				        },
			        up:function( a ) {
				            this._depth_ += a || 1;
				        },
			        down:function( a ) {
				            this._depth_ -= a || 1;
				        },
			        setParser:function( name, parser ) {
				            this.parsers[name] = parser;
				        },
			        // The next 3 are exposed so you can use them
			        quote:quote, 
			        literal:literal,
			        join:join,
			        //
			        _depth_: 1,
			        // This is the list of parsers, to modify them, use jsDump.setParser
			        parsers:{
				            window: '[Window]',
				            document: '[Document]',
				            error:'[ERROR]', //when no parser is found, shouldn't happen
				            unknown'[Unknown]',
				            'null':'null',
				            undefined:'undefined',
				            'function':function( fn ) {
					                var ret 'function',
					                    name 'name' in fn fn.name : (reName.exec(fn)||[])[1];
					//functions never have name in IE
					                if ( name )
					                    ret += ' ' name;
					                ret += '(';
					                ret = [ retthis.parsefn'functionArgs' ), '){'].join('');
						                return joinretthis.parse(fn,'functionCode'), '}' );
					            },
				            array: array,
				            nodelist: array,
				            arguments: array,
				            object:function( map ) {
					                var ret = [ ];
					                this.up();
					                for ( var key in map )
					                    ret.pushthis.parse(key,'key') + ': ' this.parse(map[key]) );
					                this.down();
					                return join'{'ret'}' );
					            },
				            node:function( node ) {
					                var open this.HTML '&lt;
					' '<',
					                    close this.HTML '&gt;
					' '>';
					                var tag node.nodeName.toLowerCase(),
					                    ret open tag;
					                for ( var a in this.DOMAttrs ) {
						                    var val node[this.DOMAttrs[a]];
						                    if ( val )
						                        ret += ' ' '=' this.parseval'attribute' );
						                }
					                return ret close open '/' tag close;
					            },
				            functionArgs:function( fn ) {//function calls it internally, it's the arguments part of the function
					                var fn.length;
					                if ( !) return '';
					                var args = Array(l);
					                while ( l-- )
					                    args[l] = String.fromCharCode(97+l);
					//97 is 'a'
					                return ' ' args.join(', ') + ' ';
					            },
				            key:quote//object calls it internally, the key part of an item in a map
				            functionCode:'[code]'//function calls it internally, it's the content of the function
				            attribute:quote//node calls it internally, it's an html attribute value
				            string:quote,
				            date:quote,
				            regexp:literal//regex
				            number:literal,
				            'boolean':literal
				        },
			        DOMAttrs:{//attributes to dump from nodes, name=>realName
				            id:'id',
				            name:'name',
				            'class':'className'
				        },
			        HTML:false,//if true, entities are escaped ( <, >, \t, space and \n )
			        indentChar:'   ',//indentation unit
			        multiline:false //if true, items in a collection, are separated by a \n, else just a space.
			    };
		    return jsDump;
		})();
	// from Sizzle.js
	function getTextelems ) {
		    var ret ""elem;
		    for ( var 0;
		 elems[i];
		 i++ ) {
			        elem elems[i];
			        // Get the text from text nodes and CDATA nodes
			        if ( elem.nodeType === || elem.nodeType === ) {
				            ret += elem.nodeValue;
				        // Traverse everything else, except comment nodes
				        } else if ( elem.nodeType !== ) {
				            ret += getTextelem.childNodes );
				        }
			    }
		    return ret;
		};
	/*
	 * Javascript Diff Algorithm
	 *  By John Resig (http://ejohn.org/)
	 *  Modified by Chu Alan "sprite"
	 *
	 * Released under the MIT license.
	 *
	 * More Info:
	 *  http://ejohn.org/projects/javascript-diff-algorithm/
	 *  
	 * Usage: QUnit.diff(expected, actual)
	 * 
	 * 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"
	 */
	QUnit.diff = (function() {
		    function diff(on){
			        var ns = new Object();
			        var os = new Object();
			        for (var 0;
			 n.length;
			 i++) {
				            if (ns[n[i]] == null) 
				                ns[n[i]] = {
					                    rows: new Array(),
					                    onull
					                };
				            ns[n[i]].rows.push(i);
				        }
			        for (var 0;
			 o.length;
			 i++) {
				            if (os[o[i]] == null) 
				                os[o[i]] = {
					                    rows: new Array(),
					                    nnull
					                };
				            os[o[i]].rows.push(i);
				        }
			        for (var i in ns) {
				            if (ns[i].rows.length == && typeof(os[i]) != "undefined" && os[i].rows.length == 1) {
					                n[ns[i].rows[0]] = {
						                    textn[ns[i].rows[0]],
						                    rowos[i].rows[0]
						                };
					                o[os[i].rows[0]] = {
						                    texto[os[i].rows[0]],
						                    rowns[i].rows[0]
						                };
					            }
				        }
			        for (var 0;
			 n.length 1;
			 i++) {
				            if (n[i].text != null && n[1].text == null && n[i].row o.length && o[n[i].row 1].text == null &&
				            n[1] == o[n[i].row 1]) {
					                n[1] = {
						                    textn[1],
						                    rown[i].row 1
						                };
					                o[n[i].row 1] = {
						                    texto[n[i].row 1],
						                    row1
						                };
					            }
				        }
			        for (var n.length 1;
			 0;
			 i--) {
				            if (n[i].text != null && n[1].text == null && n[i].row && o[n[i].row 1].text == null &&
				            n[1] == o[n[i].row 1]) {
					                n[1] = {
						                    textn[1],
						                    rown[i].row 1
						                };
					                o[n[i].row 1] = {
						                    texto[n[i].row 1],
						                    row1
						                };
					            }
				        }
			        return {
				            oo,
				            nn
				        };
			    }
		    return function(on){
			        o.replace(/\s+$/, '');
			        n.replace(/\s+$/, '');
			        var out diff(== "" [] : o.split(/\s+/), == "" [] : n.split(/\s+/));
			        var str "";
			        var oSpace o.match(/\s+/g);
			        if (oSpace == null) {
				            oSpace = [" "];
				        }
			        else {
				            oSpace.push(" ");
				        }
			        var nSpace n.match(/\s+/g);
			        if (nSpace == null) {
				            nSpace = [" "];
				        }
			        else {
				            nSpace.push(" ");
				        }
			        if (out.n.length == 0) {
				            for (var 0;
				 out.o.length;
				 i++) {
					                str += '<del>' out.o[i] + oSpace[i] + "</del>";
					            }
				        }
			        else {
				            if (out.n[0].text == null) {
					                for (0;
					 out.o.length && out.o[n].text == null;
					 n++) {
						                    str += '<del>' out.o[n] + oSpace[n] + "</del>";
						                }
					            }
				            for (var 0;
				 out.n.length;
				 i++) {
					                if (out.n[i].text == null) {
						                    str += '<ins>' out.n[i] + nSpace[i] + "</ins>";
						                }
					                else {
						                    var pre "";
						                    for (out.n[i].row 1;
						 out.o.length && out.o[n].text == null;
						 n++) {
							                        pre += '<del>' out.o[n] + oSpace[n] + "</del>";
							                    }
						                    str += " " out.n[i].text nSpace[i] + pre;
						                }
					            }
				        }
			        return str;
			    }
		})();
	})(this);





PHP Demo Source Code Index