﻿/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */


// Because this code contains a init function to be useable directly inside the browser as well as in nodejs
// we define the @namespace djstest here instead of the a @module name djstest

/** Create namespace djstest in window.djstest when this file is loaded as JavaScript by the browser
 * @namespace djstest
 */


var init = function init () {
    var djstest = {};
  

    /** Constructs a Job object that allows for enqueuing and synchronizing the execution of functions.
     * @class Job
     * @constructor
     * @returns {Object} Job object
     */
    djstest.Job = function () {
        
        var currentTask = -1;
        var tasks = [];

        var failedTasks = 0;

        /** Adds a function to the job queue regardless if the queue is already executing or not.
         * @method djstest.Job#queue
         * @param {Function} fn - Function to execute.
         */
        this.queue = function (fn) {
            
            tasks.push(fn);
        };

        /** Adds a function to the front of the job queue regardless if the queue is already executing or not.
         * @method djstest.Job#queueNext
         * @param {Function} fn - Function to execute.
         */
        this.queueNext = function (fn) {
        
            if (currentTask < 0) {
                tasks.unshift(fn);
            } else {
                tasks.splice(currentTask + 1, 0, fn);
            }
        };

        /** Starts the execution of this job.
         * @method djstest.Job#run
         * @param {Function} done - Callback invoked when the job has finished executing all of its enqueued tasks.
         */
        this.run = function (done) {
            /// This method does nothing if called on a unit of work that is already executing.
            if (currentTask >= 0) {
                return;
            }

            if (tasks.length === 0) {
                done(true);
                return;
            }

            /**
             * @method djstest.Job~makeTaskDoneCallBack
            */
            function makeTaskDoneCallBack(failed) {
                return function () {
                    // Track the failed task and continue the execution of the job. 
                    if (failed) {
                        failedTasks++;
                    }
                    currentTask++;
                    if (currentTask === tasks.length) {
                        done(failedTasks === 0);
                    } else {
                        runNextTask();
                    }
                };
            }

            /** Executes the next function in the queue.
             * @method djstest.Job~runNextTask
            */
            function runNextTask() {
                defer(function () {
                    try {
                        tasks[currentTask](makeTaskDoneCallBack(false), makeTaskDoneCallBack(true));
                    } catch (e) {
                        makeTaskDoneCallBack(true)();
                    }
                });
            }

            currentTask = 0;
            runNextTask();
        };
    };

    /** Defers the execution of an arbitrary function that takes no parameters.
     * @memberof djstest
     * @inner
     * @param {Function} fn - Function to schedule for later execution.
     */
    function defer(fn) {
        setTimeout(fn, 0);
    }

    /** Exposes date values for Date objects to facilitate debugging
     * @memberof djstest
     * @inner
     * @param {Object} data - The object to operate on
     */
    function exposeDateValues(data) {
     
        if (typeof data === "object") {
            if (data instanceof Date) {
                data.__date__ = data.toUTCString();
            }
            else {
                for (var prop in data) {
                    exposeDateValues(data[prop]);
                }
            }
        }

        return data;
    }

    /** Determines the name of a function.
     * @memberof djstest
     * @inner
     * @param {String} text - Function text.
     * @returns {String} The name of the function from text if found; the original text otherwise.
     */
    function extractFunctionName(text) {

        var index = text.indexOf("function ");
        if (index < 0) {
            return text;
        }

        var nameStart = index + "function ".length;
        var parensIndex = text.indexOf("(", nameStart);
        if (parensIndex < 0) {
            return text;
        }

        var result = text.substr(nameStart, parensIndex - nameStart);
        if (result.indexOf("test") === 0) {
            result = result.substr("test".length);
        }

        return result;
    }

    /** Removes metadata annotations from the specified object.
     * @memberof djstest
     * @inner
     * @param data - Object to remove metadata from; possibly null.
     */
    function removeMetadata(data) {

        if (typeof data === "object" && data !== null) {
            delete data.__metadata;
            for (var prop in data) {
                removeMetadata(data[prop]);
            }
        }
    }

    /** Add the unit test cases
     * @param disable - Indicate whether this test case should be disabled
    */
    djstest.addFullTest = function (disable, fn, name, arg, timeout) {

        if (disable !== true) {
            djstest.addTest(fn, name, arg, timeout);
        }
    };

    /** Add the unit test cases
     * @param disable - Indicate whether this test case should be disabled
    */
    djstest.addTest = function (fn, name, arg, timeout) {
        if (!name) {
            name = extractFunctionName(fn.toString());
        }

        test(name, function () {
            if (!timeout) {
                timeout = 20000;
            }

            QUnit.config.testTimeout = timeout;
            QUnit.stop();
            fn.call(this, arg);
        });
    };

    /** Asserts that a condition is true.
     * @param {Boolean} test - Condition to test.
     * @param {String} message - Text message for condition being tested.
     */
    djstest.assert = function (test, message) {
        
        QUnit.ok(test, message);
    };

    /** Asserts that the values of the expected and actualobjects are equal.
     * @memberof djstest
     * @inner
     */
    djstest.assertAreEqual = function (actual, expected, message) {
        QUnit.equal(actual, expected, message);
    };

    /** Asserts that the actual and expected objects are the same.
     */
    djstest.assertAreEqualDeep = function (actual, expected, message) {
        QUnit.deepEqual(exposeDateValues(actual), exposeDateValues(expected), message);
    };

    /** Asserts that the actual and expected objects are the same but removes the metadata bevore
     */
    djstest.assertWithoutMetadata = function (actual, expected, message) {
        removeMetadata(actual);
        removeMetadata(expected);
        djstest.assertAreEqualDeep(actual, expected, message);
    };

    /** Calls each async action in asyncActions, passing each action a function which keeps a count and
     * calls the passed done function when all async actions complete
     * @param {Array} asyncActions -Array of asynchronous actions to be executed, 
     * each taking a single parameter - the callback function to call when the action is done.</param>
     * @param {Function} done - Function to be executed in the last async action to complete.
     */
    djstest.asyncDo = function (asyncActions, done) {

        var count = 0;
        var doneOne = function () {
            count++;
            if (count >= asyncActions.length) {
                done();
            }
        };

        if (asyncActions.length > 0) {
            for ( var i = 0; i < asyncActions.length; i++) {
                asyncActions[i](doneOne);
            }
        } else {
            done();
        }
    };

    /** Makes a deep copy of an object.
     */
    djstest.clone = function (object) {
        if ( object === undefined ) {
            return undefined;
        } else if (object === null) {
            return null;
        } else if (typeof(object) !== 'object') {
            return object;
        } else {
            var ret = {};
            for(var key in object) {
                if(object.hasOwnProperty(key)) {
                    ret[key] = this.clone(object[key]);
                }
            }
            return ret;
        }
        throw("Error cloning an object");
    };

    /** Destroys the cache and then completes the test
     * @param cache - The cache to destroy
     */
    djstest.destroyCacheAndDone = function (cache) {
     
        cache.clear().then(function () {
            djstest.done();
        }, function (err) {
            djstest.fail("Failed to destroy cache: " + djstest.toString(err));
            djstest.done();
        });
    };

    /** Indicates that the currently running test has finished.
     */
    djstest.done = function () {
      
        QUnit.start();
    };

    /** Test passes if and only if an exception is thrown.
     */
    djstest.expectException = function (testFunction, message) {
     
        try {
            testFunction();
            djstest.fail("Expected exception but function succeeded: " + " " + message);
        }
        catch (e) {
            // Swallow exception.
            djstest.pass("Thrown exception expected");
        }
    };

    /** Indicates the expected number of asserts, fails test if number is not met.
     * @param {Number} asserts - Number of asserts expected in test.
     */
    djstest.assertsExpected = function (asserts) {
        
        expect(asserts);
    };
    /** Marks the current test as failed.
     * @param {String} message - Failure message.
     */
    djstest.fail = function (message) {

        QUnit.ok(false, message);
    };

    /** Returns a function that when invoked will fail this test and be done with it.
     * @param {String} message - Failure message.
     * @param {Function} [cleanupCallback] - 
     * @returns {Function} A new function.
     */
    djstest.failAndDoneCallback = function (message, cleanupCallback) {

        return function (err) {
            message = "" + message + (err) ? JSON.stringify(err) : "";
            djstest.fail(message);
            if (cleanupCallback) {
                try {
                    cleanupCallback();
                } catch (e) {
                    djstest.fail("error during cleanupCallback: " + JSON.stringify(e));
                }
            }

            djstest.done();
        };
    };

    /** Logs a test message.
     * @param {String} message - Test message.
     */
    djstest.log = function (message) {

        var context = { result: true, actual: true, expected: true, message: message };
        QUnit.log(context);
    };

    /** Marks the current test as failed.
     * @param {String} message - Failure message.
     */
    djstest.pass = function (message) {
        QUnit.ok(true, message);
    };

    /** Dumps the object as a string
     * @param {Object} obj - Object to dump
     */
    djstest.toString = function (obj) {

        return QUnit.jsDump.parse(obj);
    };

    /** Executes the function, pausing test execution until the callback is called
     * @param {Function} fn - Function to execute; takes one parameter which is the callback
     * This function is typically used in asynchronous setup/teardown methods</remarks>
     */
    djstest.wait = function (fn) {
        QUnit.stop();
        fn(function () {
            QUnit.start();
        });
    };

    return djstest;
};

//export djstest

if (typeof window !== 'undefined') {
    //expose to browsers window object
    if ( window.djstest === undefined) {
        window.djstest = init();
    } else {
        var tmp = init();
        $.extend( window.djstest,tmp);
    }
} else {
    //expose in commonjs style
    module.exports = init();
}

