[OLINGO-413]-split djstest-browser.js
diff --git a/datajs/tests-tmp/common/djstest-browser.js b/datajs/tests-tmp/common/djstest-browser.js
new file mode 100644
index 0000000..366ca33
--- /dev/null
+++ b/datajs/tests-tmp/common/djstest-browser.js
@@ -0,0 +1,150 @@
+/*
+ * 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 java script by the browser
+ * @namespace djstest
+ */
+
+
+var init = function init () {
+
+    var localDjstest = {};
+
+    // Initialize indexedDB if the window object is available
+    localDjstest.indexedDB = window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB || window.indexedDB;
+
+    /** Cleans all the test data saved in the IndexedDb database.
+     * @param {Array} storeNames - Array of store objects with a property that is the name of the store
+     * @param {Function} done - Callback function
+     */
+    localDjstest.cleanStoreOnIndexedDb = function (storeObjects, done) {
+        var IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || {};
+
+        function deleteObjectStores(db) {
+            for ( var i = 0 ; i < db.objectStoreNames.length ; i ++) {
+                db.deleteObjectStore(db.objectStoreNames[i]);
+            }
+        }
+        var job;
+
+        if (localDjstest.indexedDB) {
+            job = new djstest.Job();
+            for ( var i = 0 ; i < storeObjects.length ; i ++) {
+                storeObject = storeObjects[i];
+                job.queue((function (storeObject) {
+                    return function (success, fail) {
+                        var dbname = "_datajs_" + storeObject.name;
+                        var request = localDjstest.indexedDB.open(dbname);
+                        request.onsuccess = function (event) {
+                            var db = request.result;
+
+                            if ("setVersion" in db) {
+                                var versionRequest = db.setVersion("0.1");
+                                versionRequest.onsuccess = function (event) {
+                                    var transaction = versionRequest.transaction;
+                                    transaction.oncomplete = function () {
+                                        db.close();
+                                        success();
+                                    };
+                                    deleteObjectStores(db);
+                                };
+                                versionRequest.onerror = function (e) {
+                                    djstest.fail("Error on cleanup - code: " + e.code + " name: " + e.name + "message: " + message);
+                                    fail();
+                                };
+                                return;
+                            }
+
+                            // new api cleanup
+                            db.close();
+                            var deleteRequest = localDjstest.indexedDB.deleteDatabase(dbname);
+                            deleteRequest.onsuccess = function (event) {
+                                djstest.log("djstest indexeddb cleanup - deleted database " + dbname);
+                                success();
+                            };
+                            deleteRequest.onerror = function (e) {
+                                djstest.fail("djstest indexeddb cleanup - error deleting database " + dbname);
+                                fail();
+                            };
+                            djstest.log("djstest indexeddb cleanup - requested deletion of database " + dbname);
+                        };
+
+                        request.onerror = function (e) {
+                            djstest.fail(e.code + ": " + e.message);
+                        };
+                    };
+                })(storeObject));
+            }
+        }
+
+        if (job) {
+            job.run(function (succeeded) {
+                if (!succeeded) {
+                    djstest.fail("cleanup job failed");
+                }
+                done();
+            });
+        }
+        else {
+            done();
+        }
+    };
+
+
+    // Disable caching to ensure that every test-related AJAX request is actually being sent,
+    // and set up a default error handler
+    if (typeof window !== undefined) {
+        $.ajaxSetup({
+            cache: false,
+            error: function (jqXHR, textStatus, errorThrown) {
+                // Work around bug in IE-Mobile on Windows Phone 7
+                if (jqXHR.status !== 1223) {
+                    var err = {
+                        status: jqXHR.status,
+                        statusText: jqXHR.statusText,
+                        responseText: jqXHR.responseText
+                    };
+                    djstest.fail("AJAX request failed with: " + djstest.toString(err));
+                }
+                djstest.done();
+            }
+        });
+    }
+    return localDjstest;
+};
+
+//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();
+}
+
diff --git a/datajs/tests-tmp/common/djstest.js b/datajs/tests-tmp/common/djstest.js
new file mode 100644
index 0000000..5dda9ff
--- /dev/null
+++ b/datajs/tests-tmp/common/djstest.js
@@ -0,0 +1,419 @@
+/*
+ * 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 java script 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();
+}
+
diff --git a/datajs/tests-tmp/done.txt b/datajs/tests-tmp/done.txt
new file mode 100644
index 0000000..c0e33dc
--- /dev/null
+++ b/datajs/tests-tmp/done.txt
@@ -0,0 +1,18 @@
+This tests-tmp folder will repleace the tests folder.
+The plan is to 
+- select test case per testcase,
+- verify it, and 
+- copy it to the tmp-tests
+- once each tests is checkt and copied the folder tests will be deleted and replaced by tmp-tests
+
+DONE
+
+TestSynchronizerClient.js removed
+  -> Moved from custom c# logging service to jenkins
+
+
+ODataReadOracle.js removed
+  -> TODO check dependencies
+
+rx.js removed
+  -> TODO check dependencies
diff --git a/datajs/tests-tmp/odata-qunit-tests-launcher.htm b/datajs/tests-tmp/odata-qunit-tests-launcher.htm
new file mode 100644
index 0000000..4ec914d
--- /dev/null
+++ b/datajs/tests-tmp/odata-qunit-tests-launcher.htm
@@ -0,0 +1,70 @@
+<!--
+/*
+ * 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.
+ */
+ -->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<html>
+  <head>
+    <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+    <meta http-equiv="cache-control" content="no-cache" />
+    <meta http-equiv="pragma" content="no-cache" />
+    <meta http-equiv="expires" content="-1" />
+
+    <title>OData unit tests</title>
+    <link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-1.10.0.css" type="text/css" />
+
+    <script type="text/javascript" src="http://code.jquery.com/jquery-1.4.4.min.js" ></script>
+    <script type="text/javascript" src="http://code.jquery.com/qunit/qunit-1.10.0.js"></script>
+    <script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/json2/20110223/json2.js"></script>
+
+    
+    <script type="text/javascript" src="../build/datajs-2.0.0.js"></script>
+    <script type="text/javascript" src="./common/common.js"></script>
+
+    <script type="text/javascript" src="./common/mockHttpClient.js"></script>
+    <script type="text/javascript" src="./common/mockXMLHttpRequest.js"></script>
+
+    <script type="text/javascript" src="./common/djstest.js"></script>
+    <script type="text/javascript" src="./common/djstest-browser.js"></script>
+    <script type="text/javascript" src="./common/CacheOracle.js"></script>
+
+<!--bingl: disable the failure test case. Will fix them in the next change set-->
+<!--    <script type="text/javascript" src="odata-tests.js"></script>-->
+    <script type="text/javascript" src="odata-json-tests.js"></script>
+    <script type="text/javascript" src="odata-links-functional-tests.js"></script>
+    <script type="text/javascript" src="odata-metadata-tests.js"></script>
+    <script type="text/javascript" src="odata-xml-tests.js"></script>
+    <script type="text/javascript" src="odata-handler-tests.js"></script>
+    <script type="text/javascript" src="odata-net-tests.js"></script>
+    <script type="text/javascript" src="odata-batch-tests.js"></script>
+    <script type="text/javascript" src="cache-tests.js"></script>
+    <script type="text/javascript" src="store-tests.js"></script>
+    <script type="text/javascript" src="store-indexeddb-tests.js"></script>
+  </head>
+  <body>
+    <h1 id="qunit-header">OData Unit Tests</h1>
+    <h2 id="qunit-banner"></h2>
+    <h2 id="qunit-userAgent"></h2>
+    <ol id="qunit-tests">
+    </ol>
+  </body>
+  <script type="text/javascript">
+    QUnit.config.autostart = false;
+  </script>
+</html>
\ No newline at end of file
diff --git a/datajs/tests/common/djstest-browser.js b/datajs/tests/common/djstest-browser.js
new file mode 100644
index 0000000..366ca33
--- /dev/null
+++ b/datajs/tests/common/djstest-browser.js
@@ -0,0 +1,150 @@
+/*
+ * 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 java script by the browser
+ * @namespace djstest
+ */
+
+
+var init = function init () {
+
+    var localDjstest = {};
+
+    // Initialize indexedDB if the window object is available
+    localDjstest.indexedDB = window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB || window.indexedDB;
+
+    /** Cleans all the test data saved in the IndexedDb database.
+     * @param {Array} storeNames - Array of store objects with a property that is the name of the store
+     * @param {Function} done - Callback function
+     */
+    localDjstest.cleanStoreOnIndexedDb = function (storeObjects, done) {
+        var IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || {};
+
+        function deleteObjectStores(db) {
+            for ( var i = 0 ; i < db.objectStoreNames.length ; i ++) {
+                db.deleteObjectStore(db.objectStoreNames[i]);
+            }
+        }
+        var job;
+
+        if (localDjstest.indexedDB) {
+            job = new djstest.Job();
+            for ( var i = 0 ; i < storeObjects.length ; i ++) {
+                storeObject = storeObjects[i];
+                job.queue((function (storeObject) {
+                    return function (success, fail) {
+                        var dbname = "_datajs_" + storeObject.name;
+                        var request = localDjstest.indexedDB.open(dbname);
+                        request.onsuccess = function (event) {
+                            var db = request.result;
+
+                            if ("setVersion" in db) {
+                                var versionRequest = db.setVersion("0.1");
+                                versionRequest.onsuccess = function (event) {
+                                    var transaction = versionRequest.transaction;
+                                    transaction.oncomplete = function () {
+                                        db.close();
+                                        success();
+                                    };
+                                    deleteObjectStores(db);
+                                };
+                                versionRequest.onerror = function (e) {
+                                    djstest.fail("Error on cleanup - code: " + e.code + " name: " + e.name + "message: " + message);
+                                    fail();
+                                };
+                                return;
+                            }
+
+                            // new api cleanup
+                            db.close();
+                            var deleteRequest = localDjstest.indexedDB.deleteDatabase(dbname);
+                            deleteRequest.onsuccess = function (event) {
+                                djstest.log("djstest indexeddb cleanup - deleted database " + dbname);
+                                success();
+                            };
+                            deleteRequest.onerror = function (e) {
+                                djstest.fail("djstest indexeddb cleanup - error deleting database " + dbname);
+                                fail();
+                            };
+                            djstest.log("djstest indexeddb cleanup - requested deletion of database " + dbname);
+                        };
+
+                        request.onerror = function (e) {
+                            djstest.fail(e.code + ": " + e.message);
+                        };
+                    };
+                })(storeObject));
+            }
+        }
+
+        if (job) {
+            job.run(function (succeeded) {
+                if (!succeeded) {
+                    djstest.fail("cleanup job failed");
+                }
+                done();
+            });
+        }
+        else {
+            done();
+        }
+    };
+
+
+    // Disable caching to ensure that every test-related AJAX request is actually being sent,
+    // and set up a default error handler
+    if (typeof window !== undefined) {
+        $.ajaxSetup({
+            cache: false,
+            error: function (jqXHR, textStatus, errorThrown) {
+                // Work around bug in IE-Mobile on Windows Phone 7
+                if (jqXHR.status !== 1223) {
+                    var err = {
+                        status: jqXHR.status,
+                        statusText: jqXHR.statusText,
+                        responseText: jqXHR.responseText
+                    };
+                    djstest.fail("AJAX request failed with: " + djstest.toString(err));
+                }
+                djstest.done();
+            }
+        });
+    }
+    return localDjstest;
+};
+
+//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();
+}
+
diff --git a/datajs/tests/common/djstest.js b/datajs/tests/common/djstest.js
index 182dd40..5dda9ff 100644
--- a/datajs/tests/common/djstest.js
+++ b/datajs/tests/common/djstest.js
@@ -27,95 +27,8 @@
 
 
 var init = function init () {
-
     var djstest = {};
-    // Initialize indexedDB if the window object is available
-    if (typeof window !== 'undefined') {
-        djstest.indexedDB = window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB || window.indexedDB;
-    }
-
-    // Initialize indexedDB function if the indexedDB is available
-    if (djstest.indexedDB === undefined) {
-        djstest.cleanStoreOnIndexedDb = function (storeObjects, done) {
-            throw "indexedDB not supported in this environment (start test in browser)";
-        };
-    } else {
-        /** Cleans all the test data saved in the IndexedDb database.
-         * @param {Array} storeNames - Array of store objects with a property that is the name of the store
-         * @param {Function} done - Callback function
-         */
-        djstest.cleanStoreOnIndexedDb = function (storeObjects, done) {
-            var IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || {};
-
-            function deleteObjectStores(db) {
-                $.each(db.objectStoreNames, function (_, storeName) {
-                    db.deleteObjectStore(storeName);
-                });
-            }
-            var job;
-
-            if (djstest.indexedDB) {
-                job = new djstest.Job();
-                $.each(storeObjects, function (_, storeObject) {
-                    job.queue((function (storeObject) {
-                        return function (success, fail) {
-                            var dbname = "_datajs_" + storeObject.name;
-                            var request = djstest.indexedDB.open(dbname);
-                            request.onsuccess = function (event) {
-                                var db = request.result;
-
-                                if ("setVersion" in db) {
-                                    var versionRequest = db.setVersion("0.1");
-                                    versionRequest.onsuccess = function (event) {
-                                        var transaction = versionRequest.transaction;
-                                        transaction.oncomplete = function () {
-                                            db.close();
-                                            success();
-                                        };
-                                        deleteObjectStores(db);
-                                    };
-                                    versionRequest.onerror = function (e) {
-                                        djstest.fail("Error on cleanup - code: " + e.code + " name: " + e.name + "message: " + message);
-                                        fail();
-                                    };
-                                    return;
-                                }
-
-                                // new api cleanup
-                                db.close();
-                                var deleteRequest = djstest.indexedDB.deleteDatabase(dbname);
-                                deleteRequest.onsuccess = function (event) {
-                                    djstest.log("djstest indexeddb cleanup - deleted database " + dbname);
-                                    success();
-                                };
-                                deleteRequest.onerror = function (e) {
-                                    djstest.fail("djstest indexeddb cleanup - error deleting database " + dbname);
-                                    fail();
-                                };
-                                djstest.log("djstest indexeddb cleanup - requested deletion of database " + dbname);
-                            };
-
-                            request.onerror = function (e) {
-                                djstest.fail(e.code + ": " + e.message);
-                            };
-                        };
-                    })(storeObject));
-                });
-            }
-
-            if (job) {
-                job.run(function (succeeded) {
-                    if (!succeeded) {
-                        djstest.fail("cleanup job failed");
-                    }
-                    done();
-                });
-            }
-            else {
-                done();
-            }
-        };
-    }
+  
 
     /** Constructs a Job object that allows for enqueuing and synchronizing the execution of functions.
      * @class Job
@@ -351,9 +264,9 @@
         };
 
         if (asyncActions.length > 0) {
-            $.each(asyncActions, function (_, asyncAction) {
-                asyncAction(doneOne);
-            });
+            for ( var i = 0; i < asyncActions.length; i++) {
+                asyncActions[i](doneOne);
+            }
         } else {
             done();
         }
@@ -362,8 +275,22 @@
     /** Makes a deep copy of an object.
      */
     djstest.clone = function (object) {
-        
-        return $.extend(true, {}, 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
@@ -472,25 +399,6 @@
         });
     };
 
-    // Disable caching to ensure that every test-related AJAX request is actually being sent,
-    // and set up a default error handler
-    if (typeof window !== undefined) {
-        $.ajaxSetup({
-            cache: false,
-            error: function (jqXHR, textStatus, errorThrown) {
-                // Work around bug in IE-Mobile on Windows Phone 7
-                if (jqXHR.status !== 1223) {
-                    var err = {
-                        status: jqXHR.status,
-                        statusText: jqXHR.statusText,
-                        responseText: jqXHR.responseText
-                    };
-                    djstest.fail("AJAX request failed with: " + djstest.toString(err));
-                }
-                djstest.done();
-            }
-        });
-    }
     return djstest;
 };
 
@@ -498,11 +406,14 @@
 
 if (typeof window !== 'undefined') {
     //expose to browsers window object
-    window.djstest = init();
-    init();
+    if ( window.djstest === undefined) {
+        window.djstest = init();
+    } else {
+        var tmp = init();
+        $.extend( window.djstest,tmp);
+    }
 } else {
     //expose in commonjs style
-    //var $ = {};
     module.exports = init();
 }
 
diff --git a/datajs/tests/node-test-setup.js b/datajs/tests/node-test-setup.js
index 68c03b9..50fcac2 100644
--- a/datajs/tests/node-test-setup.js
+++ b/datajs/tests/node-test-setup.js
@@ -19,7 +19,7 @@
 //Creates the global objects
 
 //tools
-djstest = require("./common/djstest.js").init({});
+djstest = require("./common/djstest.js");
 MockHttpClient = require("./common/MockHttpClient.js").init({});
 
 //lib
diff --git a/datajs/tests/odata-json-tests.js b/datajs/tests/odata-json-tests.js
index 93a468e..7d30a7c 100644
--- a/datajs/tests/odata-json-tests.js
+++ b/datajs/tests/odata-json-tests.js
@@ -23,6 +23,7 @@
    
     
     djstest.addTest(function isArrayTest() {
+        console.log("hier-----------------------");
         djstest.assert(odatajs.utils.isArray([]));
         djstest.assert(odatajs.utils.isArray([1, 2]));
         djstest.assert(!odatajs.utils.isArray({}));
@@ -867,7 +868,7 @@
                 type: "Point",
                 coordinates: [1.0, 2.0],
                 crs: {
-                    type: name,
+                    type: "Point",
                     properties: {
                         name: "EPSG:4326"
                     }
@@ -878,7 +879,7 @@
                 "type": "LineString",
                 "coordinates": [ [100.0, 0.0], [101.0, 1.0] ],
                 crs: {
-                    type: name,
+                    type: "LineString",
                     properties: {
                         name: "EPSG:4326"
                     }
@@ -892,7 +893,7 @@
                   [ [100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2] ]
                   ],
                 crs: {
-                    type: name,
+                    type: "Polygon",
                     properties: {
                         name: "EPSG:4326"
                     }
@@ -903,7 +904,7 @@
                 "type": "MultiPoint",
                 "coordinates": [ [100.0, 0.0], [101.0, 1.0] ],
                 crs: {
-                    type: name,
+                    type: "MultiPoint",
                     properties: {
                         name: "EPSG:4326"
                     }
@@ -917,7 +918,7 @@
                       [ [102.0, 2.0], [103.0, 3.0] ]
                     ],
                 crs: {
-                    type: name,
+                    type: "MultiLineString",
                     properties: {
                         name: "EPSG:4326"
                     }
@@ -931,7 +932,7 @@
                      [[100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2]]]
                     ],
                 crs: {
-                    type: name,
+                    type: "MultiPolygon",
                     properties: {
                         name: "EPSG:4326"
                     }
diff --git a/datajs/tests/odata-qunit-tests.htm b/datajs/tests/odata-qunit-tests.htm
index 7934ae6..7832559 100644
--- a/datajs/tests/odata-qunit-tests.htm
+++ b/datajs/tests/odata-qunit-tests.htm
@@ -50,6 +50,7 @@
     <script type="text/javascript" src="./common/mockXMLHttpRequest.js"></script>
 
     <script type="text/javascript" src="./common/djstest.js"></script>
+    <script type="text/javascript" src="./common/djstest-browser.js"></script>
     <script type="text/javascript" src="./common/CacheOracle.js"></script>
 
 <!--bingl: disable the failure test case. Will fix them in the next change set-->