olingo-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kobl...@apache.org
Subject [2/2] git commit: [OLINGO-413] create tests-tmp for refactoring the tests
Date Fri, 22 Aug 2014 12:16:14 GMT
[OLINGO-413] create tests-tmp for refactoring the tests


Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/commit/a0d10179
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/tree/a0d10179
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/diff/a0d10179

Branch: refs/heads/master
Commit: a0d101793a48812135ba346be48bde4251760fc8
Parents: 249678c
Author: Sven Kobler <sven.kobler-morris@sap.com>
Authored: Fri Aug 22 14:14:34 2014 +0200
Committer: Sven Kobler <sven.kobler-morris@sap.com>
Committed: Fri Aug 22 14:15:42 2014 +0200

----------------------------------------------------------------------
 datajs/Gruntfile.js                             |   4 +-
 datajs/demo/tester.html                         |   4 +-
 datajs/package.json                             |   1 +
 datajs/src/index.js                             |  32 +-
 datajs/src/lib/cache.js                         |  10 +-
 datajs/src/lib/datajs/utils.js                  |   4 +
 datajs/src/lib/store/indexeddb.js               |  10 +-
 datajs/tests-tmp/common/djstest-browser.js      |  43 +-
 datajs/tests-tmp/common/djstest.js              |  31 +-
 datajs/tests-tmp/common/mockHttpClient.js       | 138 +++
 datajs/tests-tmp/common/node-test-setup.js      |  30 +
 datajs/tests-tmp/done.txt                       |   3 +-
 .../tests-tmp/odata-json-tests-todo-analyse.js  | 830 +++++++++++++++++++
 datajs/tests-tmp/odata-json-tests.js            | 211 +++++
 datajs/tests-tmp/odata-qunit-tests-launcher.htm |  25 +-
 datajs/tests/common/mockHttpClient.js           |   4 +-
 16 files changed, 1280 insertions(+), 100 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/a0d10179/datajs/Gruntfile.js
----------------------------------------------------------------------
diff --git a/datajs/Gruntfile.js b/datajs/Gruntfile.js
index 7d967e5..5e892c7 100644
--- a/datajs/Gruntfile.js
+++ b/datajs/Gruntfile.js
@@ -114,8 +114,8 @@ module.exports = function(grunt) {
           namespace: null
         },
         deps: '',
-        code: './tests/node-test-setup.js',
-        tests: ['./tests/odata-json-tests.js'],
+        code: './tests-tmp/common/node-test-setup.js',
+        tests: ['./tests-tmp/odata-json-tests.js'],
         done: function(err, res){
             !err && publishResults("node", res, this.async());
         }

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/a0d10179/datajs/demo/tester.html
----------------------------------------------------------------------
diff --git a/datajs/demo/tester.html b/datajs/demo/tester.html
index 929c6fd..4893414 100644
--- a/datajs/demo/tester.html
+++ b/datajs/demo/tester.html
@@ -97,8 +97,8 @@
             // Testing 
             function buttonClick(configNr) {
                 var metadata = $("input[name*='inMetadata']:checked").val();
-                var recognizeDates  = ($("#inRecognizeDates:checked").val() ==='on') ? true : false;
-                var inMinimalToFull = ($("#inMinimalToFull:checked").val() ==='on') ? true : false;
+                var recognizeDates  = ($("#inRecognizeDates").val() ==='on') ? true : false;
+                var inMinimalToFull = ($("#inMinimalToFull").val() ==='on') ? true : false;
 
                 var requestUri = {
                     requestUri : config[configNr].url

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/a0d10179/datajs/package.json
----------------------------------------------------------------------
diff --git a/datajs/package.json b/datajs/package.json
index 1e939a6..1bd9d75 100644
--- a/datajs/package.json
+++ b/datajs/package.json
@@ -4,6 +4,7 @@
   "version": "2.0.0",
   "description": "datajs is a new cross-browser JavaScript library that enables data-centric web applications by leveraging modern protocols such as JSON and OData and HTML5-enabled browser features. It's designed to be small, fast and easy to use.",
   "homepage": "http://olingo.apache.org",
+  "main":"index.js",
   "repository": {
     "type": "git",
     "url": "http://git-wip-us.apache.org/repos/asf/olingo-odata4-js.git"

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/a0d10179/datajs/src/index.js
----------------------------------------------------------------------
diff --git a/datajs/src/index.js b/datajs/src/index.js
index e2fd697..fa4203d 100644
--- a/datajs/src/index.js
+++ b/datajs/src/index.js
@@ -17,25 +17,17 @@
  * under the License.
  */
 
-if ( window.odatajs===undefined) {
-    window.odatajs = {};
-}
-
-window.odatajs = require('./lib/datajs.js');
-
-window.odatajs.oData = require('./lib/odata.js');
-window.odatajs.store = require('./lib/store.js');
-window.odatajs.cache = require('./lib/cache.js');
-
-/*
-function extend(target) {
-    var sources = [].slice.call(arguments, 1);
-    sources.forEach(function (source) {
-        for (var prop in source) {
-            target[prop] = source[prop];
-        }
-    });
-    return target;
-}*/
+var odatajs = require('./lib/datajs.js');
 
+odatajs.oData = require('./lib/odata.js');
+odatajs.store = require('./lib/store.js');
+odatajs.cache = require('./lib/cache.js');
 
+if (typeof window !== 'undefined') {
+    //expose to browsers window object
+    window.odatajs = odatajs;
+} else {
+    //expose in commonjs style
+    odatajs.node = "node";
+    module.exports = odatajs;
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/a0d10179/datajs/src/lib/cache.js
----------------------------------------------------------------------
diff --git a/datajs/src/lib/cache.js b/datajs/src/lib/cache.js
index 1a7e3c2..56eb5f1 100644
--- a/datajs/src/lib/cache.js
+++ b/datajs/src/lib/cache.js
@@ -19,7 +19,7 @@
 
  /** @module cache */
 
-var datajs = require('./datajs.js');
+var odatajs = require('./datajs.js');
 var utils = odatajs.utils;
 var deferred = odatajs.deferred;
 var storeReq = odatajs.store;
@@ -587,6 +587,10 @@ function DataCache(options) {
      * @returns A new Observable object that enumerates all the cache contents.
      */
     that.ToObservable = that.toObservable = function () {
+        if ( !utils.inBrowser()) {
+            throw { message: "Only in broser supported" };
+        }
+
         if (!window.Rx || !window.Rx.Observable) {
             throw { message: "Rx library not available - include rx.js" };
         }
@@ -1016,7 +1020,7 @@ function DataCache(options) {
         
 
         return function (/*error*/) {
-            // var console = window.console;
+            // var console = windo1w.console;
             // if (console && console.log) {
             //    console.log(message);
             //    console.dir(error);
@@ -1433,7 +1437,7 @@ function createDataCache (options) {
     }
 
     return new DataCache(options);
-};
+}
 
 
 /** estimateSize (see {@link estimateSize}) */

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/a0d10179/datajs/src/lib/datajs/utils.js
----------------------------------------------------------------------
diff --git a/datajs/src/lib/datajs/utils.js b/datajs/src/lib/datajs/utils.js
index 5d33207..27af705 100644
--- a/datajs/src/lib/datajs/utils.js
+++ b/datajs/src/lib/datajs/utils.js
@@ -20,6 +20,9 @@
 /** @module datajs/utils */
 
 
+function inBrowser() {
+    return typeof window !== 'undefined';
+}
 
 /** Creates a new ActiveXObject from the given progId.
  * @param {String} progId - ProgId string of the desired ActiveXObject.
@@ -549,6 +552,7 @@ function getFormatKind(format, defaultFormatKind) {
 
     
     
+exports.inBrowser = inBrowser;
 exports.activeXObject = activeXObject;
 exports.assigned = assigned;
 exports.contains = contains;

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/a0d10179/datajs/src/lib/store/indexeddb.js
----------------------------------------------------------------------
diff --git a/datajs/src/lib/store/indexeddb.js b/datajs/src/lib/store/indexeddb.js
index 1dc4047..397354a 100644
--- a/datajs/src/lib/store/indexeddb.js
+++ b/datajs/src/lib/store/indexeddb.js
@@ -18,18 +18,16 @@
  */
 
 /** @module store/indexeddb */
-
-
-
 var utils = require('./../datajs.js').utils;
 
 // Imports.
 var throwErrorCallback = utils.throwErrorCallback;
 var delay = utils.delay;
 
-var indexedDB = window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB || window.indexedDB;
-var IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange;
-var IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || {};
+
+var indexedDB = utils.inBrowser() ? window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB || window.indexedDB : undefined;
+var IDBKeyRange = utils.inBrowser() ? window.IDBKeyRange || window.webkitIDBKeyRange : undefined;
+var IDBTransaction = utils.inBrowser() ? window.IDBTransaction || window.webkitIDBTransaction || {} : {} ;
 
 var IDBT_READ_ONLY = IDBTransaction.READ_ONLY || "readonly";
 var IDBT_READ_WRITE = IDBTransaction.READ_WRITE || "readwrite";

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/a0d10179/datajs/tests-tmp/common/djstest-browser.js
----------------------------------------------------------------------
diff --git a/datajs/tests-tmp/common/djstest-browser.js b/datajs/tests-tmp/common/djstest-browser.js
index 366ca33..9bd0f45 100644
--- a/datajs/tests-tmp/common/djstest-browser.js
+++ b/datajs/tests-tmp/common/djstest-browser.js
@@ -25,19 +25,30 @@
  * @namespace djstest
  */
 
+if (typeof window !== 'undefined') {
+    //expose to browsers window object
+    window.djstest = window.djstest || {};
+    init(window.djstest);
+} else {
+    //expose in commonjs style
+    module.exports = init();
+}
 
-var init = function init () {
 
-    var localDjstest = {};
+function init (window) {
+    var djstest = window.djstest;
+    if (!djstest) { 
+        djstest = window.djstest = {};
+    }
 
     // Initialize indexedDB if the window object is available
-    localDjstest.indexedDB = window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB || window.indexedDB;
+    djstest.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) {
+    djstest.cleanStoreOnIndexedDb = function (storeObjects, done) {
         var IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || {};
 
         function deleteObjectStores(db) {
@@ -47,14 +58,14 @@ var init = function init () {
         }
         var job;
 
-        if (localDjstest.indexedDB) {
+        if (djstest.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);
+                        var request = djstest.indexedDB.open(dbname);
                         request.onsuccess = function (event) {
                             var db = request.result;
 
@@ -77,7 +88,7 @@ var init = function init () {
 
                             // new api cleanup
                             db.close();
-                            var deleteRequest = localDjstest.indexedDB.deleteDatabase(dbname);
+                            var deleteRequest = djstest.indexedDB.deleteDatabase(dbname);
                             deleteRequest.onsuccess = function (event) {
                                 djstest.log("djstest indexeddb cleanup - deleted database " + dbname);
                                 success();
@@ -130,21 +141,5 @@ var init = function init () {
             }
         });
     }
-    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();
+    return djstest;
 }
-

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/a0d10179/datajs/tests-tmp/common/djstest.js
----------------------------------------------------------------------
diff --git a/datajs/tests-tmp/common/djstest.js b/datajs/tests-tmp/common/djstest.js
index 5dda9ff..f8180d1 100644
--- a/datajs/tests-tmp/common/djstest.js
+++ b/datajs/tests-tmp/common/djstest.js
@@ -1,4 +1,4 @@
-/*
+/*
  * 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
@@ -25,10 +25,18 @@
  * @namespace djstest
  */
 
+if (typeof window !== 'undefined') {
+    //expose to browsers window object
+    window.djstest = window.djstest || {};
+    init(window.djstest);
+} else {
+    //expose in commonjs style
+    module.exports = init();
+}
 
-var init = function init () {
-    var djstest = {};
-  
+
+function init (parent) {
+    djstest = parent || {};
 
     /** Constructs a Job object that allows for enqueuing and synchronizing the execution of functions.
      * @class Job
@@ -400,20 +408,5 @@ var init = function init () {
     };
 
     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();
 }
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/a0d10179/datajs/tests-tmp/common/mockHttpClient.js
----------------------------------------------------------------------
diff --git a/datajs/tests-tmp/common/mockHttpClient.js b/datajs/tests-tmp/common/mockHttpClient.js
new file mode 100644
index 0000000..2ec97e7
--- /dev/null
+++ b/datajs/tests-tmp/common/mockHttpClient.js
@@ -0,0 +1,138 @@
+/*
+ * 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.
+ */
+ 
+//mockHttpClient.js
+//this object allows for associating a uri with a requestVerfier and mock responses that will be sent back to the client of the httpStack.  
+//It can be used to replace OData's httpClient for testing purposes.
+//
+//RequestVerifiers
+//
+//    A request verifier is a function associated to a particular URI that will be executed by the mockHttpClient when it receives a request with the matching URI.
+//    the callback receives as its only parameter the request object passed to the mockHttpClient.
+//
+//    To register a request verifier, simply do 
+//        
+//            MockHttpClient.addRequestVerifier("http://someUri", function(request) {
+//                djstest.assertAreEqual(request.requestUri,"http://someUri");
+//            }
+//
+//Responses
+//    Mock responses can be associated with a particular URI.  When the MockHttpClient receives a request with a URI mapped to a response, then it will, 
+//    depending on the response status code invoke either the success or the error callbacks. 
+//
+//    To register a response,
+//       
+//           MockHttpClient.addResponse("http://someUri", {status: 200, body:"some body"});
+//
+//Exceptions
+//    MockHttpClient will throw an exception if it receives a request to a URI that is not mapped to either a request verifier or a response.
+//
+
+
+if (typeof window !== 'undefined') {
+    //in browser call init() directly window as context
+    window.MockHttpClient = window.MockHttpClient || {};
+    init(window.MockHttpClient);
+} else {
+    //expose function init to be called with a custom context
+    module.exports = init();
+}
+
+
+function init(parent, undefined) {
+    httpClient = parent || {};
+
+    var responses = {};
+    var requestVerifiers = {};
+
+    httpClient.addRequestVerifier = function (uri, verifier) {
+        requestVerifiers[uri] = verifier;
+        return this;
+    };
+
+    httpClient.addResponse = function (uri, response) {
+        responses[uri] = response;
+        return this;
+    };
+
+    httpClient.async = false;
+
+    httpClient.clear = function () {
+        /** Clears all registered responses and verifiers.
+         * @returns this client
+         */
+        responses = {};
+        requestVerifiers = {};
+        this.async = false;
+        return this;
+    };
+
+    httpClient.request = function (request, success, error) {
+        var uri = request.requestUri;
+        var verifier = requestVerifiers[uri];
+        var response = responses[uri];
+
+        if (verifier === undefined) {
+            verifier = requestVerifiers["*"];
+        }
+
+        if (response === undefined) {
+            response = responses["*"];
+        }
+
+        if (!verifier && !response) {
+            throw { message: "neither verifier or response defined for uri: " + uri };
+        }
+
+        if (verifier) {
+            verifier(request);
+        }
+
+        if (response) {
+            response.requestUri = uri;
+            if (response.statusCode >= 200 && response.statusCode <= 299) {
+                if (this.async) {
+                    setTimeout(function () {
+                        success(response);
+                    });
+                } else {
+                    success(response);
+                }
+            } else {
+                if (this.async) {
+                    setTimeout(function () {
+                        error({ message: "failed test response", request: request, response: response });
+                    });
+                }
+                else {
+                    error({ message: "failed test response", request: request, response: response });
+                }
+            }
+        }
+    };
+
+    httpClient.setAsync = function (value) {
+        this.async = value;
+        return this;
+    };
+
+    return httpClient;
+}
+
+

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/a0d10179/datajs/tests-tmp/common/node-test-setup.js
----------------------------------------------------------------------
diff --git a/datajs/tests-tmp/common/node-test-setup.js b/datajs/tests-tmp/common/node-test-setup.js
new file mode 100644
index 0000000..c08c439
--- /dev/null
+++ b/datajs/tests-tmp/common/node-test-setup.js
@@ -0,0 +1,30 @@
+/*
+ * 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.
+*/
+//Creates the global objects
+
+//tools
+
+var window = {};
+window.djstest = require("./djstest.js");
+window.mockHttpClient = require("./mockHttpClient.js");
+window.odatajs  = require('./../../src/index.js');
+
+global.window = window;
+console.log(global.window.odatajs.node+'asdfasdfasdfasdf');
+

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/a0d10179/datajs/tests-tmp/done.txt
----------------------------------------------------------------------
diff --git a/datajs/tests-tmp/done.txt b/datajs/tests-tmp/done.txt
index c0e33dc..b313ca7 100644
--- a/datajs/tests-tmp/done.txt
+++ b/datajs/tests-tmp/done.txt
@@ -10,9 +10,10 @@ DONE
 TestSynchronizerClient.js removed
   -> Moved from custom c# logging service to jenkins
 
-
 ODataReadOracle.js removed
   -> TODO check dependencies
 
 rx.js removed
   -> TODO check dependencies
+
+odata-json-test.js copied and splittet 
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/a0d10179/datajs/tests-tmp/odata-json-tests-todo-analyse.js
----------------------------------------------------------------------
diff --git a/datajs/tests-tmp/odata-json-tests-todo-analyse.js b/datajs/tests-tmp/odata-json-tests-todo-analyse.js
new file mode 100644
index 0000000..d608673
--- /dev/null
+++ b/datajs/tests-tmp/odata-json-tests-todo-analyse.js
@@ -0,0 +1,830 @@
+/*
+ * 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.
+ */
+
+// odata-tests.js
+
+(function (window, undefined) {
+   
+    
+    djstest.addTest(function jsonParserTest() {
+        var tests = [
+            { context: { response: { requestUri: "http://base.org" }, dataServiceVersion: "4.0" }, expected: {} },
+            { context: { response: { requestUri: "http://base.org" }, dataServiceVersion: "4.0" },
+                expected: {
+                    "@odata.context": "http://foo/OData.svc/$metadata",
+                    value: [
+                      {
+                          name: "Products",
+                          kind: "EntitySet",
+                          url: "Products"
+                      },
+                      {
+                          name: "ProductDetails",
+                          kind: "EntitySet",
+                          url: "ProductDetails"
+                      }
+                  ]
+                }
+            },
+            { context: { response: { requestUri: "http://base.org" }, dataServiceVersion: "4.0" },
+                expected: {
+                    value: [
+                      {
+                          name: "Products",
+                          kind: "EntitySet",
+                          url: "http://foo/OData.svc/Products"
+                      },
+                      {
+                          name: "ProductDetails",
+                          kind: "EntitySet",
+                          url: "http://foo/OData.svc/ProductDetails"
+                      }
+                  ]
+                }
+            },
+            { context: { response: { requestUri: "http://base.org" }, dataServiceVersion: "4.0" }, expected: { "@odata.context": "http://foo/OData.svc/$metadata#Products(0)/Name", value: "Bread"} },
+            { context: { response: { requestUri: "http://base.org" }, dataServiceVersion: "4.0" },
+                expected: {
+                    "@odata.context": "http://foo/OData.svc/$metadata#Products",
+                    value: [
+                      {
+                          "@odata.type": "#ODataDemo.Product",
+                          "@odata.id": "http://foo/OData.svc/Products(0)",
+                          "@odata.editLink": "Products(0)",
+                          "Categories@odata.navigationLink": "Products(0)/Categories",
+                          "Categories@odata.associationLink": "Products(0)/Categories/$ref",
+                          "Supplier@odata.navigationLink": "Products(0)/Supplier",
+                          "Supplier@odata.associationLink": "Products(0)/Supplier/$ref",
+                          "ProductDetail@odata.navigationLink": "Products(0)/ProductDetail",
+                          "ProductDetail@odata.associationLink": "Products(0)/ProductDetail/$ref",
+                          ID: 0,
+                          Name: "Bread",
+                          Description: "Whole grain bread",
+                          "ReleaseDate@odata.type": "#DateTimeOffset",
+                          ReleaseDate: "1992-01-01T00:00:00Z",
+                          DiscontinuedDate: null,
+                          "Rating@odata.type": "#Int16",
+                          Rating: 4,
+                          Price: 2.5
+                      }]
+                }
+            },
+            { context: { response: { requestUri: "http://base.org" }, dataServiceVersion: "4.0" },
+                expected: {
+                    "@odata.context": "http://foo/OData.svc/$metadata#Products",
+                    value: [
+                      {
+                          ID: 0,
+                          Name: "Bread",
+                          Description: "Whole grain bread",
+                          ReleaseDate: "1992-01-01T00:00:00Z",
+                          DiscontinuedDate: null,
+                          Rating: 4,
+                          Price: 2.5
+                      }]
+                }
+            },
+             { context: { response: { requestUri: "http://base.org" }, dataServiceVersion: "4.0" },
+                 expected: {
+                     value: [
+                      {
+                          ID: 0,
+                          Name: "Bread",
+                          Description: "Whole grain bread",
+                          ReleaseDate: "1992-01-01T00:00:00Z",
+                          DiscontinuedDate: null,
+                          Rating: 4,
+                          Price: 2.5
+                      }]
+                 }
+             },
+              { context: { response: { requestUri: "http://base.org" }, dataServiceVersion: "4.0" },
+                  expected: {
+                      "@odata.context": "http://foo/OData.svc/$metadata#Products/$entry",
+                      "@odata.type": "#ODataDemo.Product",
+                      "@odata.id": "http://foo/OData.svc/Products(0)",
+                      "@odata.editLink": "Products(0)",
+                      "Categories@odata.navigationLink": "Products(0)/Categories",
+                      "Categories@odata.associationLink": "Products(0)/Categories/$ref",
+                      "Supplier@odata.navigationLink": "Products(0)/Supplier",
+                      "Supplier@odata.associationLink": "Products(0)/Supplier/$ref",
+                      "ProductDetail@odata.navigationLink": "Products(0)/ProductDetail",
+                      "ProductDetail@odata.associationLink": "Products(0)/ProductDetail/$ref",
+                      ID: 0,
+                      Name: "Bread",
+                      Description: "Whole grain bread",
+                      "ReleaseDate@odata.type": "#DateTimeOffset",
+                      ReleaseDate: "1992-01-01T00:00:00Z",
+                      DiscontinuedDate: null,
+                      "Rating@odata.type": "#Int16",
+                      Rating: 4,
+                      Price: 2.5
+                  }
+              },
+              { context: { response: { requestUri: "http://base.org" }, dataServiceVersion: "4.0" },
+                  expected: {
+                      "@odata.context": "http://foo/OData.svc/$metadata#Products/$entry",
+                      ID: 0,
+                      Name: "Bread",
+                      Description: "Whole grain bread",
+                      ReleaseDate: "1992-01-01T00:00:00Z",
+                      DiscontinuedDate: null,
+                      Rating: 4,
+                      Price: 2.5
+                  }
+              },
+              { context: { response: { requestUri: "http://base.org" }, dataServiceVersion: "4.0" },
+                  expected: {
+                      ID: 0,
+                      Name: "Bread",
+                      Description: "Whole grain bread",
+                      ReleaseDate: "1992-01-01T00:00:00Z",
+                      DiscontinuedDate: null,
+                      Rating: 4,
+                      Price: 2.5
+                  }
+              },
+              { context: { response: { requestUri: "http://base.org" }, dataServiceVersion: "4.0" },
+                  expected: {
+                      "@odata.context": "http://foo/$metadata#Customer(-10)/PrimaryContactInfo/AlternativeNames",
+                      "@odata.type": "#Collection(String)",
+                      value: [
+                      "グぁマせぺネソぁぼソひバたぴソ歹九ネボボяポソ畚クяせべ歹珱Я欲タハバミ裹ぼボをヲ歹んひ九ひ匚ぁa",
+                      "qckrnuruxcbhjfimnsykgfquffobcadpsaocixoeljhspxrhebkudppgndgcrlyvynqhbujrnvyxyymhnroemigogsqulvgallta",
+                      "btsnhqrjqryqzgxducl",
+                      "qbtlssjhunufmzdv",
+                      "ボんЯぜチべゼボボほa匚ミぼ九ぁひチ珱黑ミんぁタび暦クソソボゾんんあゼぞひタボタぜん弌ひべ匚",
+                      "vicqasfdkxsuyuzspjqunxpyfuhlxfhgfqnlcpdfivqnxqoothnfsbuykfguftgulgldnkkzufssbae",
+                      "九ソミせボぜゾボёaをぜЯまゾタぜタひ縷ダんaバたゼソ",
+                      "ぽマタぁぁ黑ソゼミゼ匚zソダマぁァゾぽミaタゾ弌ミゼタそzぺポせ裹バポハハヲぺチあマ匚ミ",
+                      "hssiißuamtctgqhglmusexyikhcsqctusonubxorssyizhyqpbtbdßjnelxqttkhdalabibuqhiubtßsptrmzelud",
+                      "gbjssllxzzxkmßppyyrhgmoeßizlcmsuqqnvjßudszevtfunflqzqcuubukypßqjcix"
+                     ]
+                  }
+              }
+        ];
+
+        var i, len;
+        for (i = 0, len = tests.length; i < len; i++) {
+            var data = JSON.stringify(tests[i].expected);
+            var actual = window.odatajs.oData.json.jsonParser(window.odatajs.oData.json.jsonHandler, data, tests[i].context);
+            djstest.assertAreEqualDeep(actual, tests[i].expected, "test " + i + "didn't return the expected data");
+        }
+
+        djstest.done();
+    });
+
+    djstest.addTest(function jsonSerializerTest() {
+        var tests = [
+            { context: { response: { requestUri: "http://base.org" }, dataServiceVersion: "4.0" }, expected: { value: ""} },
+            { context: { response: { requestUri: "http://base.org" }, dataServiceVersion: "4.0" }, expected: { value: []} },
+            { context: { response: { requestUri: "http://base.org" }, dataServiceVersion: "4.0" },
+                expected: {
+                    ID: 0,
+                    Name: "Bread",
+                    Description: "Whole grain bread",
+                    ReleaseDate: "1992-01-01T00:00:00Z",
+                    DiscontinuedDate: null,
+                    Rating: 4,
+                    Price: 2.5
+                }
+            },
+           { context: { response: { requestUri: "http://base.org" }, dataServiceVersion: "4.0" },
+               expected: {
+                   value: [
+                      "グぁマせぺネソぁぼソひバたぴソ歹九ネボボяポソ畚クяせべ歹珱Я欲タハバミ裹ぼボをヲ歹んひ九ひ匚ぁa",
+                      "qckrnuruxcbhjfimnsykgfquffobcadpsaocixoeljhspxrhebkudppgndgcrlyvynqhbujrnvyxyymhnroemigogsqulvgallta",
+                      "btsnhqrjqryqzgxducl",
+                      "qbtlssjhunufmzdv",
+                      "ボんЯぜチべゼボボほa匚ミぼ九ぁひチ珱黑ミんぁタび暦クソソボゾんんあゼぞひタボタぜん弌ひべ匚",
+                      "vicqasfdkxsuyuzspjqunxpyfuhlxfhgfqnlcpdfivqnxqoothnfsbuykfguftgulgldnkkzufssbae",
+                      "九ソミせボぜゾボёaをぜЯまゾタぜタひ縷ダんaバたゼソ",
+                      "ぽマタぁぁ黑ソゼミゼ匚zソダマぁァゾぽミaタゾ弌ミゼタそzぺポせ裹バポハハヲぺチあマ匚ミ",
+                      "hssiißuamtctgqhglmusexyikhcsqctusonubxorssyizhyqpbtbdßjnelxqttkhdalabibuqhiubtßsptrmzelud",
+                      "gbjssllxzzxkmßppyyrhgmoeßizlcmsuqqnvjßudszevtfunflqzqcuubukypßqjcix"
+                     ]
+               }
+           },
+           { context: { response: { requestUri: "http://base.org" }, dataServiceVersion: "4.0" },
+               expected: {
+                   "@odata.id": "Foods(4)",
+                   "@odata.type": "#DataJS.Tests.V4.Food",
+                   ID: 0,
+                   Name: "Bread",
+                   Description: "Whole grain bread",
+                   ReleaseDate: "1992-01-01T00:00:00Z",
+                   DiscontinuedDate: null,
+                   Rating: 4,
+                   Price: 2.5
+               },
+               data: {
+                   "@odata.context": "http://base.org/$metadata#Foods/$entity",
+                   "@odata.id": "Foods(4)",
+                   "@odata.etag": "W/MjAxMy0wNS0yN1QxMTo1OFo=",
+                   "@odata.editLink": "Foods(0)",
+                   "@odata.type": "#DataJS.Tests.V4.Food",
+                   "@odata.mediaEditLink": "http://base.org/$metadata#Foods/mediaEditLink",
+                   "@odata.mediaReadLink": "http://base.org/$metadata#Foods/mediaReadLink",
+                   "@odata.mediaContentType": "http://base.org/$metadata#Foods/mediaContentType",
+                   "@odata.mediaEtag": "http://base.org/$metadata#Foods/mediaEtag",
+                   ID: 0,
+                   Name: "Bread",
+                   Description: "Whole grain bread",
+                   ReleaseDate: "1992-01-01T00:00:00Z",
+                   DiscontinuedDate: null,
+                   Rating: 4,
+                   Price: 2.5
+               }
+           },
+           { context: { response: { requestUri: "http://base.org" }, dataServiceVersion: "4.0" },
+               expected: {
+                   "@odata.id": "Foods(4)",
+                   value : [{
+                       "@odata.id": "Foods(4)",
+                       "@odata.type": "#DataJS.Tests.V4.Food",
+                       ID: 0,
+                       ComplexInLayerOne:
+                       {
+                           "@odata.id": "Foods(4)",
+                           "@odata.type": "#DataJS.Tests.V4.Food",
+                           ID: 1,
+                           ComplexInLayerTwo:
+                           {
+                               "@odata.id": "Foods(4)",
+                               "@odata.type": "#DataJS.Tests.V4.Food",
+                               ID: 2,
+                               ComplexInLayerThreeList: [
+                               {
+                                   "@odata.id": "Foods(4)",
+                                   "@odata.type": "#DataJS.Tests.V4.Food",
+                                   ID: 3,
+                                   Name: "BreadInLayer3",
+                                   Description: "Whole grain bread inLayer3",
+                                   ReleaseDate: "1992-01-01T00:00:00Z",
+                                   DiscontinuedDate: null,
+                                   Rating: 7,
+                                   Price: 5.5
+                               },
+                               {
+                                   "@odata.id": "Foods(4)",
+                                   "@odata.type": "#DataJS.Tests.V4.Food",
+                                   ID: 3,
+                                   Name: "BreadInLayer3",
+                                   Description: "Whole grain bread inLayer3",
+                                   ReleaseDate: "1992-01-01T00:00:00Z",
+                                   DiscontinuedDate: null,
+                                   Rating: 7,
+                                   Price: 5.5
+                               }],
+                               Name: "BreadInLayer2",
+                               Description: "Whole grain bread inLayer2",
+                               ReleaseDate: "1992-01-01T00:00:00Z",
+                               DiscontinuedDate: null,
+                               Rating: 6,
+                               Price: 4.5
+                           },
+                           Name: ["BreadInLayer1", "BreadInLayer12", "BreadInLayer13"],
+                           Description: "Whole grain bread inLayer1",
+                           ReleaseDate: "1992-01-01T00:00:00Z",
+                           DiscontinuedDate: null,
+                           Rating: 5,
+                           Price: 3.5
+                       },
+                       Name: "Bread",
+                       Description: "Whole grain bread",
+                       ReleaseDate: "1992-01-01T00:00:00Z",
+                       DiscontinuedDate: null,
+                       Rating: 4,
+                       Price: 2.5
+                   },
+                   {
+                       "@odata.id": "Foods(4)",
+                       "@odata.type": "#DataJS.Tests.V4.Food",
+                       ID: 0,
+                       ComplexInLayerOne:
+                       {
+                           "@odata.id": "Foods(4)",
+                           "@odata.type": "#DataJS.Tests.V4.Food",
+                           ID: 1,
+                           ComplexInLayerTwo:
+                           {
+                               "@odata.id": "Foods(4)",
+                               "@odata.type": "#DataJS.Tests.V4.Food",
+                               ID: 2,
+                               ComplexInLayerThreeList: [
+                               {
+                                   "@odata.id": "Foods(4)",
+                                   "@odata.type": "#DataJS.Tests.V4.Food",
+                                   ID: 3,
+                                   Name: "BreadInLayer3",
+                                   Description: "Whole grain bread inLayer3",
+                                   ReleaseDate: "1992-01-01T00:00:00Z",
+                                   DiscontinuedDate: null,
+                                   Rating: 7,
+                                   Price: 5.5
+                               },
+                               {
+                                   "@odata.id": "Foods(4)",
+                                   "@odata.type": "#DataJS.Tests.V4.Food",
+                                   ID: 3,
+                                   Name: "BreadInLayer3",
+                                   Description: "Whole grain bread inLayer3",
+                                   ReleaseDate: "1992-01-01T00:00:00Z",
+                                   DiscontinuedDate: null,
+                                   Rating: 7,
+                                   Price: 5.5
+                               }],
+                               Name: "BreadInLayer2",
+                               Description: "Whole grain bread inLayer2",
+                               ReleaseDate: "1992-01-01T00:00:00Z",
+                               DiscontinuedDate: null,
+                               Rating: 6,
+                               Price: 4.5
+                           },
+                           Name: ["BreadInLayer1", "BreadInLayer12", "BreadInLayer13"],
+                           Description: "Whole grain bread inLayer1",
+                           ReleaseDate: "1992-01-01T00:00:00Z",
+                           DiscontinuedDate: null,
+                           Rating: 5,
+                           Price: 3.5
+                       },
+                       Name: "Bread",
+                       Description: "Whole grain bread",
+                       ReleaseDate: "1992-01-01T00:00:00Z",
+                       DiscontinuedDate: null,
+                       Rating: 4,
+                       Price: 2.5
+                   }]
+               },
+               data: {
+                   "@odata.context": "http://base.org/$metadata#Foods/$entity",
+                   "@odata.id": "Foods(4)",
+                   "@odata.editLink": "Foods(0)",
+                   value : [{
+                       "@odata.context": "http://base.org/$metadata#Foods/$entity",
+                       "@odata.id": "Foods(4)",
+                       "@odata.etag": "W/MjAxMy0wNS0yN1QxMTo1OFo=",
+                       "@odata.editLink": "Foods(0)",
+                       "@odata.type": "#DataJS.Tests.V4.Food",
+                       "@odata.mediaEditLink": "http://base.org/$metadata#Foods/mediaEditLink",
+                       "@odata.mediaReadLink": "http://base.org/$metadata#Foods/mediaReadLink",
+                       "@odata.mediaContentType": "http://base.org/$metadata#Foods/mediaContentType",
+                       "@odata.mediaEtag": "http://base.org/$metadata#Foods/mediaEtag",
+                       ID: 0,
+                       ComplexInLayerOne:
+                       {
+                           "@odata.context": "http://base.org/$metadata#Foods/$entity",
+                           "@odata.id": "Foods(4)",
+                           "@odata.etag": "W/MjAxMy0wNS0yN1QxMTo1OFo=",
+                           "@odata.editLink": "Foods(0)",
+                           "@odata.type": "#DataJS.Tests.V4.Food",
+                           "@odata.mediaEditLink": "http://base.org/$metadata#Foods/mediaEditLink/layer1",
+                           "@odata.mediaReadLink": "http://base.org/$metadata#Foods/mediaReadLink/layer1",
+                           "@odata.mediaContentType": "http://base.org/$metadata#Foods/mediaContentType/layer1",
+                           "@odata.mediaEtag": "http://base.org/$metadata#Foods/mediaEtag/layer1",
+                           ID: 1,
+                           ComplexInLayerTwo:
+                           {
+                               "@odata.context": "http://base.org/$metadata#Foods/$entity",
+                               "@odata.id": "Foods(4)",
+                               "@odata.etag": "W/MjAxMy0wNS0yN1QxMTo1OFo=",
+                               "@odata.editLink": "Foods(0)",
+                               "@odata.type": "#DataJS.Tests.V4.Food",
+                               "@odata.mediaEditLink": "http://base.org/$metadata#Foods/mediaEditLink/layer2",
+                               "@odata.mediaReadLink": "http://base.org/$metadata#Foods/mediaReadLink/layer2",
+                               "@odata.mediaContentType": "http://base.org/$metadata#Foods/mediaContentType/layer2",
+                               "@odata.mediaEtag": "http://base.org/$metadata#Foods/mediaEtag/layer2",
+                               ID: 2,
+                               ComplexInLayerThreeList: [
+                               {
+                                   "@odata.context": "http://base.org/$metadata#Foods/$entity",
+                                   "@odata.id": "Foods(4)",
+                                   "@odata.etag": "W/MjAxMy0wNS0yN1QxMTo1OFo=",
+                                   "@odata.editLink": "Foods(0)",
+                                   "@odata.type": "#DataJS.Tests.V4.Food",
+                                   "@odata.mediaEditLink": "http://base.org/$metadata#Foods/mediaEditLink/layer3",
+                                   "@odata.mediaReadLink": "http://base.org/$metadata#Foods/mediaReadLink/layer3",
+                                   "@odata.mediaContentType": "http://base.org/$metadata#Foods/mediaContentType/layer3",
+                                   "@odata.mediaEtag": "http://base.org/$metadata#Foods/mediaEtag/layer3",
+                                   ID: 3,
+                                   Name: "BreadInLayer3",
+                                   Description: "Whole grain bread inLayer3",
+                                   ReleaseDate: "1992-01-01T00:00:00Z",
+                                   DiscontinuedDate: null,
+                                   Rating: 7,
+                                   Price: 5.5
+                               },
+                               {
+                                   "@odata.context": "http://base.org/$metadata#Foods/$entity",
+                                   "@odata.id": "Foods(4)",
+                                   "@odata.etag": "W/MjAxMy0wNS0yN1QxMTo1OFo=",
+                                   "@odata.editLink": "Foods(0)",
+                                   "@odata.type": "#DataJS.Tests.V4.Food",
+                                   "@odata.mediaEditLink": "http://base.org/$metadata#Foods/mediaEditLink/layer3",
+                                   "@odata.mediaReadLink": "http://base.org/$metadata#Foods/mediaReadLink/layer3",
+                                   "@odata.mediaContentType": "http://base.org/$metadata#Foods/mediaContentType/layer3",
+                                   "@odata.mediaEtag": "http://base.org/$metadata#Foods/mediaEtag/layer3",
+                                   ID: 3,
+                                   Name: "BreadInLayer3",
+                                   Description: "Whole grain bread inLayer3",
+                                   ReleaseDate: "1992-01-01T00:00:00Z",
+                                   DiscontinuedDate: null,
+                                   Rating: 7,
+                                   Price: 5.5
+                               }],
+                               Name: "BreadInLayer2",
+                               Description: "Whole grain bread inLayer2",
+                               ReleaseDate: "1992-01-01T00:00:00Z",
+                               DiscontinuedDate: null,
+                               Rating: 6,
+                               Price: 4.5
+                           },
+                           Name: ["BreadInLayer1", "BreadInLayer12", "BreadInLayer13"],
+                           Description: "Whole grain bread inLayer1",
+                           ReleaseDate: "1992-01-01T00:00:00Z",
+                           DiscontinuedDate: null,
+                           Rating: 5,
+                           Price: 3.5
+                       },
+                       Name: "Bread",
+                       Description: "Whole grain bread",
+                       ReleaseDate: "1992-01-01T00:00:00Z",
+                       DiscontinuedDate: null,
+                       Rating: 4,
+                       Price: 2.5
+                   },
+                   {
+                       "@odata.context": "http://base.org/$metadata#Foods/$entity",
+                       "@odata.id": "Foods(4)",
+                       "@odata.etag": "W/MjAxMy0wNS0yN1QxMTo1OFo=",
+                       "@odata.editLink": "Foods(0)",
+                       "@odata.type": "#DataJS.Tests.V4.Food",
+                       "@odata.mediaEditLink": "http://base.org/$metadata#Foods/mediaEditLink",
+                       "@odata.mediaReadLink": "http://base.org/$metadata#Foods/mediaReadLink",
+                       "@odata.mediaContentType": "http://base.org/$metadata#Foods/mediaContentType",
+                       "@odata.mediaEtag": "http://base.org/$metadata#Foods/mediaEtag",
+                       ID: 0,
+                       ComplexInLayerOne:
+                       {
+                           "@odata.context": "http://base.org/$metadata#Foods/$entity",
+                           "@odata.id": "Foods(4)",
+                           "@odata.etag": "W/MjAxMy0wNS0yN1QxMTo1OFo=",
+                           "@odata.editLink": "Foods(0)",
+                           "@odata.type": "#DataJS.Tests.V4.Food",
+                           "@odata.mediaEditLink": "http://base.org/$metadata#Foods/mediaEditLink/layer1",
+                           "@odata.mediaReadLink": "http://base.org/$metadata#Foods/mediaReadLink/layer1",
+                           "@odata.mediaContentType": "http://base.org/$metadata#Foods/mediaContentType/layer1",
+                           "@odata.mediaEtag": "http://base.org/$metadata#Foods/mediaEtag/layer1",
+                           ID: 1,
+                           ComplexInLayerTwo:
+                           {
+                               "@odata.context": "http://base.org/$metadata#Foods/$entity",
+                               "@odata.id": "Foods(4)",
+                               "@odata.etag": "W/MjAxMy0wNS0yN1QxMTo1OFo=",
+                               "@odata.editLink": "Foods(0)",
+                               "@odata.type": "#DataJS.Tests.V4.Food",
+                               "@odata.mediaEditLink": "http://base.org/$metadata#Foods/mediaEditLink/layer2",
+                               "@odata.mediaReadLink": "http://base.org/$metadata#Foods/mediaReadLink/layer2",
+                               "@odata.mediaContentType": "http://base.org/$metadata#Foods/mediaContentType/layer2",
+                               "@odata.mediaEtag": "http://base.org/$metadata#Foods/mediaEtag/layer2",
+                               ID: 2,
+                               ComplexInLayerThreeList: [
+                               {
+                                   "@odata.context": "http://base.org/$metadata#Foods/$entity",
+                                   "@odata.id": "Foods(4)",
+                                   "@odata.etag": "W/MjAxMy0wNS0yN1QxMTo1OFo=",
+                                   "@odata.editLink": "Foods(0)",
+                                   "@odata.type": "#DataJS.Tests.V4.Food",
+                                   "@odata.mediaEditLink": "http://base.org/$metadata#Foods/mediaEditLink/layer3",
+                                   "@odata.mediaReadLink": "http://base.org/$metadata#Foods/mediaReadLink/layer3",
+                                   "@odata.mediaContentType": "http://base.org/$metadata#Foods/mediaContentType/layer3",
+                                   "@odata.mediaEtag": "http://base.org/$metadata#Foods/mediaEtag/layer3",
+                                   ID: 3,
+                                   Name: "BreadInLayer3",
+                                   Description: "Whole grain bread inLayer3",
+                                   ReleaseDate: "1992-01-01T00:00:00Z",
+                                   DiscontinuedDate: null,
+                                   Rating: 7,
+                                   Price: 5.5
+                               },
+                               {
+                                   "@odata.context": "http://base.org/$metadata#Foods/$entity",
+                                   "@odata.id": "Foods(4)",
+                                   "@odata.etag": "W/MjAxMy0wNS0yN1QxMTo1OFo=",
+                                   "@odata.editLink": "Foods(0)",
+                                   "@odata.type": "#DataJS.Tests.V4.Food",
+                                   "@odata.mediaEditLink": "http://base.org/$metadata#Foods/mediaEditLink/layer3",
+                                   "@odata.mediaReadLink": "http://base.org/$metadata#Foods/mediaReadLink/layer3",
+                                   "@odata.mediaContentType": "http://base.org/$metadata#Foods/mediaContentType/layer3",
+                                   "@odata.mediaEtag": "http://base.org/$metadata#Foods/mediaEtag/layer3",
+                                   ID: 3,
+                                   Name: "BreadInLayer3",
+                                   Description: "Whole grain bread inLayer3",
+                                   ReleaseDate: "1992-01-01T00:00:00Z",
+                                   DiscontinuedDate: null,
+                                   Rating: 7,
+                                   Price: 5.5
+                               }],
+                               Name: "BreadInLayer2",
+                               Description: "Whole grain bread inLayer2",
+                               ReleaseDate: "1992-01-01T00:00:00Z",
+                               DiscontinuedDate: null,
+                               Rating: 6,
+                               Price: 4.5
+                           },
+                           Name: ["BreadInLayer1", "BreadInLayer12", "BreadInLayer13"],
+                           Description: "Whole grain bread inLayer1",
+                           ReleaseDate: "1992-01-01T00:00:00Z",
+                           DiscontinuedDate: null,
+                           Rating: 5,
+                           Price: 3.5
+                       },
+                       Name: "Bread",
+                       Description: "Whole grain bread",
+                       ReleaseDate: "1992-01-01T00:00:00Z",
+                       DiscontinuedDate: null,
+                       Rating: 4,
+                       Price: 2.5
+                   }]
+               }
+           },
+           { context: { response: { requestUri: "http://base.org" }, dataServiceVersion: "4.0" },
+               expected: {
+                   "@odata.id": "Foods(4)",
+                   "@odata.type": "#DataJS.Tests.V4.Food",
+                   ID: 0,
+                   ComplexInLayerOne:
+                   {
+                       "@odata.id": "Foods(4)",
+                       "@odata.type": "#DataJS.Tests.V4.Food",
+                       ID: 1,
+                       ComplexInLayerTwo:
+                       {
+                           "@odata.id": "Foods(4)",
+                           "@odata.type": "#DataJS.Tests.V4.Food",
+                           ID: 2,
+                           ComplexInLayerThree:
+                           {
+                               "@odata.id": "Foods(4)",
+                               "@odata.type": "#DataJS.Tests.V4.Food",
+                               ID: 3,
+                               Name: "BreadInLayer3",
+                               Description: "Whole grain bread inLayer3",
+                               ReleaseDate: "1992-01-01T00:00:00Z",
+                               DiscontinuedDate: null,
+                               Rating: 7,
+                               Price: 5.5
+                           },
+                           Name: "BreadInLayer2",
+                           Description: "Whole grain bread inLayer2",
+                           ReleaseDate: "1992-01-01T00:00:00Z",
+                           DiscontinuedDate: null,
+                           Rating: 6,
+                           Price: 4.5
+                       },
+                       Name: "BreadInLayer1",
+                       Description: "Whole grain bread inLayer1",
+                       ReleaseDate: "1992-01-01T00:00:00Z",
+                       DiscontinuedDate: null,
+                       Rating: 5,
+                       Price: 3.5
+                   },
+                   Name: "Bread",
+                   Description: "Whole grain bread",
+                   ReleaseDate: "1992-01-01T00:00:00Z",
+                   DiscontinuedDate: null,
+                   Rating: 4,
+                   Price: 2.5
+               },
+               data: {
+                   "@odata.context": "http://base.org/$metadata#Foods/$entity",
+                   "@odata.id": "Foods(4)",
+                   "@odata.etag": "W/MjAxMy0wNS0yN1QxMTo1OFo=",
+                   "@odata.editLink": "Foods(0)",
+                   "@odata.type": "#DataJS.Tests.V4.Food",
+                   "@odata.mediaEditLink": "http://base.org/$metadata#Foods/mediaEditLink",
+                   "@odata.mediaReadLink": "http://base.org/$metadata#Foods/mediaReadLink",
+                   "@odata.mediaContentType": "http://base.org/$metadata#Foods/mediaContentType",
+                   "@odata.mediaEtag": "http://base.org/$metadata#Foods/mediaEtag",
+                   ID: 0,
+                   ComplexInLayerOne:
+                   {
+                       "@odata.context": "http://base.org/$metadata#Foods/$entity",
+                       "@odata.id": "Foods(4)",
+                       "@odata.etag": "W/MjAxMy0wNS0yN1QxMTo1OFo=",
+                       "@odata.editLink": "Foods(0)",
+                       "@odata.type": "#DataJS.Tests.V4.Food",
+                       "@odata.mediaEditLink": "http://base.org/$metadata#Foods/mediaEditLink/layer1",
+                       "@odata.mediaReadLink": "http://base.org/$metadata#Foods/mediaReadLink/layer1",
+                       "@odata.mediaContentType": "http://base.org/$metadata#Foods/mediaContentType/layer1",
+                       "@odata.mediaEtag": "http://base.org/$metadata#Foods/mediaEtag/layer1",
+                       ID: 1,
+                       ComplexInLayerTwo:
+                       {
+                           "@odata.context": "http://base.org/$metadata#Foods/$entity",
+                           "@odata.id": "Foods(4)",
+                           "@odata.etag": "W/MjAxMy0wNS0yN1QxMTo1OFo=",
+                           "@odata.editLink": "Foods(0)",
+                           "@odata.type": "#DataJS.Tests.V4.Food",
+                           "@odata.mediaEditLink": "http://base.org/$metadata#Foods/mediaEditLink/layer2",
+                           "@odata.mediaReadLink": "http://base.org/$metadata#Foods/mediaReadLink/layer2",
+                           "@odata.mediaContentType": "http://base.org/$metadata#Foods/mediaContentType/layer2",
+                           "@odata.mediaEtag": "http://base.org/$metadata#Foods/mediaEtag/layer2",
+                           ID: 2,
+                           ComplexInLayerThree:
+                           {
+                               "@odata.context": "http://base.org/$metadata#Foods/$entity",
+                               "@odata.id": "Foods(4)",
+                               "@odata.etag": "W/MjAxMy0wNS0yN1QxMTo1OFo=",
+                               "@odata.editLink": "Foods(0)",
+                               "@odata.type": "#DataJS.Tests.V4.Food",
+                               "@odata.mediaEditLink": "http://base.org/$metadata#Foods/mediaEditLink/layer3",
+                               "@odata.mediaReadLink": "http://base.org/$metadata#Foods/mediaReadLink/layer3",
+                               "@odata.mediaContentType": "http://base.org/$metadata#Foods/mediaContentType/layer3",
+                               "@odata.mediaEtag": "http://base.org/$metadata#Foods/mediaEtag/layer3",
+                               ID: 3,
+                               Name: "BreadInLayer3",
+                               Description: "Whole grain bread inLayer3",
+                               ReleaseDate: "1992-01-01T00:00:00Z",
+                               DiscontinuedDate: null,
+                               Rating: 7,
+                               Price: 5.5
+                           },
+                           Name: "BreadInLayer2",
+                           Description: "Whole grain bread inLayer2",
+                           ReleaseDate: "1992-01-01T00:00:00Z",
+                           DiscontinuedDate: null,
+                           Rating: 6,
+                           Price: 4.5
+                       },
+                       Name: "BreadInLayer1",
+                       Description: "Whole grain bread inLayer1",
+                       ReleaseDate: "1992-01-01T00:00:00Z",
+                       DiscontinuedDate: null,
+                       Rating: 5,
+                       Price: 3.5
+                   },
+                   Name: "Bread",
+                   Description: "Whole grain bread",
+                   ReleaseDate: "1992-01-01T00:00:00Z",
+                   DiscontinuedDate: null,
+                   Rating: 4,
+                   Price: 2.5
+               }
+           },
+           { context: { response: { requestUri: "http://base.org" }, dataServiceVersion: "4.0" },
+               expected: {
+                   value: [{
+                       "@odata.id": "Foods(4)",
+                       "@odata.type": "#DataJS.Tests.V4.Food",
+                       ID: 0,
+                       Name: "Bread",
+                       Description: "Whole grain bread",
+                       ReleaseDate: "1992-01-01T00:00:00Z",
+                       DiscontinuedDate: null,
+                       Rating: 4,
+                       Price: 2.5
+                   },
+                   {
+                       "@odata.id": "Foods(2)",
+                       "@odata.type": "#DataJS.Tests.V4.Food",
+                       ID: 1,
+                       Name: "Bread",
+                       Description: "Whole grain bread",
+                       ReleaseDate: "1999-01-01T00:00:00Z",
+                       DiscontinuedDate: null,
+                       Rating: 6,
+                       Price: 3.5
+                   }]
+               },
+               data: {
+                   value: [{
+                       "@odata.context": "http://base.org/$metadata#Foods/$entity",
+                       "@odata.id": "Foods(4)",
+                       "@odata.etag": "W/MjAxMy0wNS0yN1QxMTo1OFo=",
+                       "@odata.editLink": "Foods(0)",
+                       "@odata.type": "#DataJS.Tests.V4.Food",
+                       "@odata.mediaEditLink": "http://base.org/$metadata#Foods/mediaEditLink",
+                       "@odata.mediaReadLink": "http://base.org/$metadata#Foods/mediaReadLink",
+                       "@odata.mediaContentType": "http://base.org/$metadata#Foods/mediaContentType",
+                       "@odata.mediaEtag": "http://base.org/$metadata#Foods/mediaEtag",
+                       ID: 0,
+                       Name: "Bread",
+                       Description: "Whole grain bread",
+                       ReleaseDate: "1992-01-01T00:00:00Z",
+                       DiscontinuedDate: null,
+                       Rating: 4,
+                       Price: 2.5
+                   },
+                   {
+                       "@odata.context": "http://base.org/$metadata#Foods/$entity",
+                       "@odata.id": "Foods(2)",
+                       "@odata.etag": "W/MjAxMy0wNS0yN1QxMTo1OFo=",
+                       "@odata.editLink": "Foods(2)",
+                       "@odata.type": "#DataJS.Tests.V4.Food",
+                       "@odata.mediaEditLink": "http://base.org/$metadata#Foods/mediaEditLink2",
+                       "@odata.mediaReadLink": "http://base.org/$metadata#Foods/mediaReadLink2",
+                       "@odata.mediaContentType": "http://base.org/$metadata#Foods/mediaContentType2",
+                       "@odata.mediaEtag": "http://base.org/$metadata#Foods/mediaEtag2",
+                       ID: 1,
+                       Name: "Bread",
+                       Description: "Whole grain bread",
+                       ReleaseDate: "1999-01-01T00:00:00Z",
+                       DiscontinuedDate: null,
+                       Rating: 6,
+                       Price: 3.5
+                   }]
+               }
+           }
+          ];
+        var i, len;
+        for (i = 0, len = tests.length; i < len; i++) {
+            var data = tests[i].data ? tests[i].data : tests[i].expected;
+            var actual = window.odatajs.oData.json.jsonSerializer(window.odatajs.oData.json.jsonHandler, data, tests[i].context);
+            var expected = JSON.stringify(tests[i].expected);
+            djstest.assertAreEqualDeep(actual, expected, "test " + i + "didn't return the expected data");
+        }
+        djstest.done();
+    });
+
+    djstest.addTest(function normalizeHeadersReadTest() {
+        // Verifies that headers are normalized for reading.
+        // See issue at http://datajs.codeplex.com/workitem/148
+        MockHttpClient.clear();
+
+        MockHttpClient.clear().addResponse("/foo", {
+            statusCode: 200,
+            body: { "@odata.context": "http://foo", value: [] },
+            headers: { "unknown": "u", "Content-Encoding": "compress, gzip", "Content-Length": "8042",
+                "Content-Type": "application/json", "OData-Version": "4.0", "Etag": "Vetag", "Location": "foo", "OData-EntityId": "entityId",
+                "Preference-Applied": "prefered", "Retry-After": "retry"
+            }
+        });
+
+        odatajs.oData.read("/foo", function (data, response) {
+            // djstest.assertAreEqual(data.results.length, 2, "data.results.length has two entries");
+            djstest.assertAreEqual(response.headers.unknown, "u", "u unmodified");
+            djstest.assertAreEqual(response.headers["Content-Encoding"], "compress, gzip", "Content-Encoding available");
+            djstest.assertAreEqual(response.headers["Content-Length"], "8042", "Content-Length available");
+            djstest.assertAreEqual(response.headers["Content-Type"], "application/json", "Content-Type available");
+            djstest.assertAreEqual(response.headers["ETag"], "Vetag", "Content-Type available");
+            djstest.assertAreEqual(response.headers["Location"], "foo", "Content-Type available");
+            djstest.assertAreEqual(response.headers["OData-EntityId"], "entityId", "OData-EntityId available");
+            djstest.assertAreEqual(response.headers["Preference-Applied"], "prefered", "Preference-Applied available");
+            djstest.assertAreEqual(response.headers["Retry-After"], "retry", "Retry available");
+            djstest.assertAreEqual(response.headers["OData-Version"], "4.0", "OData-Version available");
+            djstest.done();
+        }, undefined, undefined, MockHttpClient);
+    });
+
+    djstest.addTest(function normalizeHeadersWriteTest() {
+
+        // Verifies that headers are normalized for writing.
+        // See issue at http://datajs.codeplex.com/workitem/148
+
+        MockHttpClient.clear().addRequestVerifier("/foo", function (request) {
+            djstest.assertAreEqual(request.headers.Accept, "application/json", "Accept available");
+            djstest.assertAreEqual(request.headers["Content-Type"], "application/json", "json found");
+            djstest.assertAreEqual(request.headers["Content-Encoding"], "compress, gzip", "Content-Encoding available");
+            djstest.assertAreEqual(request.headers["Content-Length"], "8042", "Content-Length available");
+            djstest.assertAreEqual(request.headers["OData-Version"], "4.0", "OData-Version available");
+            djstest.assertAreEqual(request.headers["Accept-Charset"], "Accept-Charset", "Accept-Charset available");
+            djstest.assertAreEqual(request.headers["If-Match"], "true", "If-Match available");
+            djstest.assertAreEqual(request.headers["If-None-Match"], "false", "If-None-Match available");
+            djstest.assertAreEqual(request.headers["OData-Isolation"], "isolation", "OData-Isolation available");
+            djstest.assertAreEqual(request.headers["OData-MaxVersion"], "4.0", "OData-MaxVersion available");
+            djstest.assertAreEqual(request.headers["Prefer"], "prefer", "prefer available");
+            djstest.done();
+        });
+
+        var request = {
+            method: "POST",
+            requestUri: "/foo",
+            data: { value: 123 },
+            headers: { "Accept": "application/json", "Content-Encoding": "compress, gzip", "Content-Length": "8042", "content-type": "application/json", "OData-Version": "4.0",
+                "accept-charset": "Accept-Charset", "if-match": "true", "if-none-match": "false", "odata-isolation": "isolation",
+                "odata-maxversion": "4.0", "prefer": "prefer"
+            }
+        };
+        odatajs.oData.request(request, function (data) { }, undefined, undefined, MockHttpClient);
+
+    });
+
+
+})(this);

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/a0d10179/datajs/tests-tmp/odata-json-tests.js
----------------------------------------------------------------------
diff --git a/datajs/tests-tmp/odata-json-tests.js b/datajs/tests-tmp/odata-json-tests.js
new file mode 100644
index 0000000..3e306a5
--- /dev/null
+++ b/datajs/tests-tmp/odata-json-tests.js
@@ -0,0 +1,211 @@
+/*
+ * 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.
+ */
+
+// odata-tests.js
+
+(function (window, undefined) {
+    QUnit.module("odata-json-tests.js");
+
+    djstest.addTest(function isArrayTest() {
+        djstest.assert(window.odatajs.utils.isArray([]));
+        djstest.assert(window.odatajs.utils.isArray([1, 2]));
+        djstest.assert(!window.odatajs.utils.isArray({}));
+        djstest.assert(!window.odatajs.utils.isArray("1,2,3,4"));
+        djstest.assert(!window.odatajs.utils.isArray());
+        djstest.assert(!window.odatajs.utils.isArray(null));
+        djstest.done();
+    });
+
+    var verifyReadJsonLightDataMetadataFull = function (input, expected, message, model) {
+        var response = { 
+          headers: { 
+            "Content-Type": "application/json;odata.metadata=full",
+             DataServiceVersion: "4.0"
+          },
+          body: JSON.stringify(input) 
+        };
+
+        window.odatajs.oData.json.jsonHandler.read(response, { metadata: model });
+        djstest.assertAreEqualDeep(response.data, expected, message);
+    };
+
+
+    var verifyReadJsonLightDataMetadataMinimal= function (input, expected, message, model) {
+        var response = { 
+          headers: { 
+            "Content-Type": "application/json;odata.metadata=minimal",
+             DataServiceVersion: "4.0"
+          },
+          body: JSON.stringify(input) 
+        };
+
+        window.odatajs.oData.json.jsonHandler.read(response, { metadata: model });
+        djstest.assertAreEqualDeep(response.data, expected, message);
+    };
+
+
+    function createPointValue(geoKind) { 
+      return { 
+        edmType : geoKind+'Point', value : {
+          type: "Point",
+          coordinates: [1.0, 2.0],
+          crs: {
+              type: "Point",
+              properties: {
+                  name: "EPSG:4326"
+              }
+          }
+        }
+      };
+    }
+
+    function createLineStringValue(geoKind) { 
+      return  { 
+        edmType : geoKind+'LineString', value : {
+          "type": "LineString",
+          "coordinates": [ [100.0, 0.0], [101.0, 1.0] ],
+          crs: {
+              type: "LineString",
+              properties: {
+                  name: "EPSG:4326"
+              }
+          }
+        }
+      };
+    }
+
+    function createPolygonValue(geoKind) { 
+      return  {
+        edmType : geoKind+'Polygon', value : {
+          "type": "Polygon",
+          "coordinates": [
+            [ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ],
+            [ [100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2] ]
+            ],
+          crs: {
+              type: "Polygon",
+              properties: {
+                  name: "EPSG:4326"
+              }
+          }
+        }
+      };
+    }
+
+    function createMultiPointValue(geoKind) { 
+      return  { 
+        edmType : geoKind+'MultiPoint', value : {
+          "type": "MultiPoint",
+          "coordinates": [ [100.0, 0.0], [101.0, 1.0] ],
+          crs: {
+              type: "MultiPoint",
+              properties: {
+                  name: "EPSG:4326"
+              }
+          }
+        }
+      };
+    }
+
+    function createMultiLineStringValue(geoKind) { 
+      return  { 
+        edmType : geoKind+'MultiLineString', value : {
+          "type": "MultiLineString",
+          "coordinates": [
+              [ [100.0, 0.0], [101.0, 1.0] ],
+              [ [102.0, 2.0], [103.0, 3.0] ]
+            ],
+          crs: {
+              type: "MultiLineString",
+              properties: {
+                  name: "EPSG:4326"
+              }
+          }
+        }
+      };
+    }
+    function createMultiPolygonStringValue(geoKind) { 
+      return  { 
+        edmType : geoKind+'MultiPolygon', value : {
+                "type": "MultiPolygon",
+                "coordinates": [
+                  [[[102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0]]],
+                  [[[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]],
+                   [[100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2]]]
+                  ],
+              crs: {
+                  type: "MultiPolygon",
+                  properties: {
+                      name: "EPSG:4326"
+                  }
+              }
+            }
+          };
+        }
+
+    function createWorkload(geoKind) { 
+      return [
+        createPointValue(geoKind),
+        createLineStringValue(geoKind), 
+        createPolygonValue(geoKind),
+        createMultiPointValue(geoKind),
+        createMultiLineStringValue(geoKind),
+        createMultiPolygonStringValue(geoKind) 
+      ];
+    }
+
+    function checkGeoKind(geoKind, full) {
+      var workload = createWorkload(geoKind);
+      for ( var i = 0; i < workload.length; i++) {
+        var item = workload[i]; 
+        var input = {
+          "@odata.context": "http://someUri#Edm."+item.edmType,
+          "value@odata.type" : item.edmType,
+          value: item.value
+        }; 
+
+        var expected = {
+          "@odata.context": "http://someUri#Edm."+item.edmType,
+          "value@odata.type" : item.edmType,
+          value: item.value
+        };
+        if (full) {
+          verifyReadJsonLightDataMetadataFull(input, expected, item.edmType + " was read properly.", {});
+        } else {
+          verifyReadJsonLightDataMetadataMinimal(input, expected, item.edmType + " was read properly.", {});
+        }
+      }
+      
+      djstest.done();
+    }
+
+    djstest.addTest(function jsonReadGeometryFull() {
+      checkGeoKind('Geometry',true);
+    });
+    djstest.addTest(function jsonReadGeometryMinimal() {
+      checkGeoKind('Geometry',false);
+    });
+    djstest.addTest(function jsonReadGeographyFull() {
+      checkGeoKind('Geography',true);
+    });
+    djstest.addTest(function jsonReadGeographyMinimal() {
+      checkGeoKind('Geography',false);
+    });
+
+})(window);

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/a0d10179/datajs/tests-tmp/odata-qunit-tests-launcher.htm
----------------------------------------------------------------------
diff --git a/datajs/tests-tmp/odata-qunit-tests-launcher.htm b/datajs/tests-tmp/odata-qunit-tests-launcher.htm
index 4ec914d..ff49b50 100644
--- a/datajs/tests-tmp/odata-qunit-tests-launcher.htm
+++ b/datajs/tests-tmp/odata-qunit-tests-launcher.htm
@@ -44,27 +44,10 @@
     <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>
+    <script type="text/javascript" src="./odata-json-tests.js"></script>
+    <script type="text/javascript" src="./odata-json-tests-todo-analyse.js"></script>
   <body>
-    <h1 id="qunit-header">OData Unit Tests</h1>
-    <h2 id="qunit-banner"></h2>
-    <h2 id="qunit-userAgent"></h2>
-    <ol id="qunit-tests">
-    </ol>
+    <div id="qunit"></div>
   </body>
-  <script type="text/javascript">
-    QUnit.config.autostart = false;
-  </script>
+  
 </html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/a0d10179/datajs/tests/common/mockHttpClient.js
----------------------------------------------------------------------
diff --git a/datajs/tests/common/mockHttpClient.js b/datajs/tests/common/mockHttpClient.js
index 20396e4..f5b2bd0 100644
--- a/datajs/tests/common/mockHttpClient.js
+++ b/datajs/tests/common/mockHttpClient.js
@@ -44,7 +44,7 @@
 //    MockHttpClient will throw an exception if it receives a request to a URI that is not mapped to either a request verifier or a response.
 //
 
-var init = function (window, undefined) {
+function init(window, undefined) {
 
     var httpClient = {};
 
@@ -123,7 +123,7 @@ var init = function (window, undefined) {
     };
 
     return httpClient;
-};
+}
 
 
 


Mime
View raw message