You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by ch...@apache.org on 2014/08/28 05:48:22 UTC
[15/51] [partial] rename folder /datajs into /odatajs. no file
modification.
http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/d5ec5557/odatajs/tests-tmp/common/djstest.js
----------------------------------------------------------------------
diff --git a/odatajs/tests-tmp/common/djstest.js b/odatajs/tests-tmp/common/djstest.js
new file mode 100644
index 0000000..104c4cf
--- /dev/null
+++ b/odatajs/tests-tmp/common/djstest.js
@@ -0,0 +1,412 @@
+/*
+ * 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
+ */
+
+if (typeof window !== 'undefined') {
+ //expose to browsers window object
+ window.djstest = window.djstest || {};
+ init(window.djstest);
+} else {
+ //expose in commonjs style
+ module.exports = init();
+}
+
+
+function init (parent) {
+ djstest = parent || {};
+
+ /** 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.ok(true, message);
+
+ };
+
+ /** 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;
+}
+
http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/d5ec5557/odatajs/tests-tmp/common/logging.js
----------------------------------------------------------------------
diff --git a/odatajs/tests-tmp/common/logging.js b/odatajs/tests-tmp/common/logging.js
new file mode 100644
index 0000000..9297527
--- /dev/null
+++ b/odatajs/tests-tmp/common/logging.js
@@ -0,0 +1,5 @@
+QUnit.log( function (context) {
+ if (window.console && window.console.log && context.message) {
+ window.console.log(context.result + ' :: ' + context.message );
+ }
+});
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/d5ec5557/odatajs/tests-tmp/common/mockHttpClient.js
----------------------------------------------------------------------
diff --git a/odatajs/tests-tmp/common/mockHttpClient.js b/odatajs/tests-tmp/common/mockHttpClient.js
new file mode 100644
index 0000000..2ec97e7
--- /dev/null
+++ b/odatajs/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/d5ec5557/odatajs/tests-tmp/common/node-test-setup.js
----------------------------------------------------------------------
diff --git a/odatajs/tests-tmp/common/node-test-setup.js b/odatajs/tests-tmp/common/node-test-setup.js
new file mode 100644
index 0000000..c08c439
--- /dev/null
+++ b/odatajs/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/d5ec5557/odatajs/tests-tmp/common/observableHttpClient.js
----------------------------------------------------------------------
diff --git a/odatajs/tests-tmp/common/observableHttpClient.js b/odatajs/tests-tmp/common/observableHttpClient.js
new file mode 100644
index 0000000..9be75f8
--- /dev/null
+++ b/odatajs/tests-tmp/common/observableHttpClient.js
@@ -0,0 +1,84 @@
+/*
+ * 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.
+ */
+
+// ObservableHttpClient.js
+// This object extends OData's default httpClient by supporting request and response recording sessions, and firing a custom
+// JQuery event for each request/response.
+//
+// The events fired by this object are:
+// request: Before a request is made
+// success: Before the primary success handler is called
+//
+// To bind to an event, JQuery event attachers can be used on the object, e.g.
+// $(observableHttpClient).bind("request", function (request) { ... });
+//
+// To begin a new recording session, use:
+// var session = observableHttpClient.newSession();
+//
+// Requests and responses are then recorded in session.requests and session.responses. Session can be ended by session.end().
+// Multiple simultaneous sessions are supported.
+
+(function (window, undefined) {
+
+ var ObservableHttpClient = function (provider) {
+ this.provider = provider ? provider : window.odatajs.oData.net.defaultHttpClient;
+ };
+
+ ObservableHttpClient.prototype.newSession = function () {
+ return new Session(this);
+ };
+
+ ObservableHttpClient.prototype.request = function (request, success, error) {
+ var that = this;
+
+ $(this).triggerHandler("request", request);
+ return this.provider.request(request, function (response) {
+ $(that).triggerHandler("success", response);
+ success(response);
+ }, error);
+ };
+
+
+ var Session = function (client) {
+ var that = this;
+
+ this.client = client;
+ this.clear();
+
+ this.requestHandler = function (event, request) { that.requests.push(request); };
+ $(client).bind("request", this.requestHandler);
+
+ this.successHandler = function (event, response) { that.responses.push(response); };
+ $(client).bind("success", this.successHandler);
+ };
+
+ Session.prototype.clear = function () {
+ this.requests = [];
+ this.responses = [];
+ }
+
+ Session.prototype.end = function () {
+ $(this.client).unbind("request", this.requestHandler);
+ $(this.client).unbind("success", this.successHandler);
+ };
+
+ window.ObservableHttpClient = ObservableHttpClient;
+ window.Session = Session;
+
+})(this);
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/d5ec5557/odatajs/tests-tmp/common/odataCacheVerifier.js
----------------------------------------------------------------------
diff --git a/odatajs/tests-tmp/common/odataCacheVerifier.js b/odatajs/tests-tmp/common/odataCacheVerifier.js
new file mode 100644
index 0000000..54e4659
--- /dev/null
+++ b/odatajs/tests-tmp/common/odataCacheVerifier.js
@@ -0,0 +1,241 @@
+/*
+ * 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.
+ */
+
+// CacheVerifier.js
+// This object verifies the operation of the cache.
+// Internally it maintains a simple model of the cache implemented using a lookup array of the expected cached pages.
+
+(function (window, undefined) {
+
+ var CacheVerifier = function (baseUri, pageSize, total, cacheSize) {
+ /** Creates a new CacheVerifier
+ * @param {String} baseUri - The base URI of the collection
+ * @param {Integer} pageSize - The page size used in the cache
+ * @param {Integer} total - The total number of items in the collection
+ * @param {Integer} cacheSize - Cache size in bytes
+ */
+ this.baseUri = baseUri;
+ this.pageSize = pageSize;
+ this.total = total;
+ this.cacheSize = (cacheSize !== undefined) ? cacheSize : 1024 * 1024;
+ this.actualSize = 0;
+ this.actualCount = 0;
+ this.cachedPages = [];
+ this.exactPageCount = (total % pageSize === 0);
+ this.maxPage = Math.floor(total / pageSize);
+ this.overflowed = this.cacheSize === 0;
+ };
+
+ CacheVerifier.mechanisms = {
+ memory: "memory",
+ indexeddb: "indexeddb",
+ dom: "dom",
+ best: "best"
+ };
+
+ CacheVerifier.isMechanismAvailable = function (mechanism) {
+ /** Determines if the specified local storage mechanism is available
+ * @param mechanism - The name of the mechanism
+ * @returns Whether the mechanism is available
+ */
+ switch (mechanism) {
+ case CacheVerifier.mechanisms.indexeddb:
+ if (window.msIndexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.indexedDB) {
+ return true;
+ }
+ else {
+ return false;
+ }
+ break;
+ case CacheVerifier.mechanisms.dom:
+ if (window.localStorage) {
+ return true;
+ }
+ else {
+ return false;
+ }
+ break;
+ case CacheVerifier.mechanisms.memory:
+ case CacheVerifier.mechanisms.best:
+ case undefined:
+ return true;
+ default:
+ return false;
+ }
+ };
+
+ CacheVerifier.prototype.clear = function () {
+ /** Clears the cache in the oracle
+ */
+ this.cachedPages = [];
+ this.actualSize = 0;
+ this.actualCount = 0;
+ this.overflowed = this.cacheSize === 0;
+ };
+
+ CacheVerifier.prototype.verifyRequests = function (requests, responses, index, count, description, backwards, isPrefetch) {
+ /** Verifies the HTTP requests for a single data request, and updates the oracle with cached pages
+ * @param {Array} requests - The sequence of request objects (from OData.defaultHttpClient)
+ * @param {Array} responses - The sequence of response objects (from OData.defaultHttpClient)
+ * @param {Integer} index - The starting index of the read
+ * @param {Integer} count - The count of items in the read
+ * @param {String} description - The description of the requests being verified
+ * @param {Boolean} backwards - Whether or not filterBack is being verified
+ * @param {Boolean} isPrefetch - Whether the requests being verified come from the prefetcher
+ */
+ var that = this;
+
+ index = (index < 0 ? 0 : index);
+ var pageIndex = function (index) {
+ /** Returns the page index that the given item index belongs to
+ * @param {Integer} index - The item index
+ * @returns The page index
+ */
+ return Math.floor(index / that.pageSize);
+ };
+
+ var estimateSize = function (obj) {
+ /** Estimates the size of an object in bytes.
+ * @param {Object} obj - Object to determine the size of.
+ * @returns {Number} Estimated size of the object in bytes.
+ */
+
+ var size = 0;
+ var type = typeof obj;
+
+ if (type === "object" && obj) {
+ for (var name in obj) {
+ size += name.length * 2 + estimateSize(obj[name]);
+ }
+ } else if (type === "string") {
+ size = obj.length * 2;
+ } else {
+ size = 8;
+ }
+ return size;
+ };
+
+ var expectedUris = [];
+ var responseIndex = 0;
+ if (count >= 0) {
+ var minPage = pageIndex(index);
+ var maxPage = Math.min(pageIndex(index + count - 1), pageIndex(this.total));
+
+ // In the case that the index is outside the range of the collection the minPage will be greater than the maxPage
+ maxPage = Math.max(minPage, maxPage);
+
+ if (!(isPrefetch && !this.exactPageCount && minPage > this.maxPage)) {
+ for (var page = minPage; page <= maxPage && this.actualCount <= this.total && !(isPrefetch && this.overflowed); page++) {
+ if (!this.cachedPages[page]) {
+
+ expectedUris.push(that.baseUri + "?$skip=" + page * this.pageSize + "&$top=" + (this.pageSize));
+
+ var actualPageSize = 0;
+ var actualPageCount = 0;
+ if (responses[responseIndex] && responses[responseIndex].data) {
+ actualPageSize += estimateSize(responses[responseIndex].data);
+ actualPageCount += responses[responseIndex].data.value.length;
+ // Handle server paging skipToken requests
+ while (responses[responseIndex].data["@odata.nextLink"]) {
+ var nextLink = responses[responseIndex].data["@odata.nextLink"];
+ if (nextLink) {
+ var index = that.baseUri.indexOf(".svc/", 0);
+ if (index != -1) {
+ nextLink = that.baseUri.substring(0, index + 5) + nextLink;
+ }
+ }
+
+ expectedUris.push(nextLink);
+ responseIndex++;
+ actualPageSize += estimateSize(responses[responseIndex].data);
+ actualPageCount += responses[responseIndex].data.value.length;
+ }
+
+ actualPageSize += 24; // 24 byte overhead for the pages (i)ndex, and (c)ount fields
+ }
+
+ responseIndex++;
+
+ this.overflowed = this.cacheSize >= 0 && this.actualSize + actualPageSize > this.cacheSize;
+ if (!this.overflowed) {
+ this.cachedPages[page] = true;
+ this.actualSize += actualPageSize;
+ this.actualCount += actualPageCount;
+ }
+ }
+ }
+ }
+ }
+
+ if (backwards) {
+ expectedUris.reverse();
+ }
+
+ var actualUris = $.map(requests, function (r) { return r.requestUri; });
+ djstest.assertAreEqualDeep(actualUris, expectedUris, description);
+ };
+
+ CacheVerifier.getExpectedFilterResults = function (data, filterIndex, filterCount, predicate, backwards) {
+ /** Verifies the cache filter returns the correct data
+ * @param {Array} collection - Array of items in the collection
+ * @param {Integer} filterIndex - The index value
+ * @param {Integer} filterCount - The count value
+ * @param {Function} predicate - Predicate to be applied in filter, takes an item
+ * @param {Boolean} backwards - Whether or not filterBackwards is being verified
+ */
+ if (!data || !data.value) {
+ return data;
+ }
+
+ var value = [];
+ if (filterCount !== 0) {
+ // Convert [item0, item1, ...] into [{ index: 0, item: item0 }, { index: 1, item: item1 }, ...]
+ var indexedCollection = $.map(data.value, function (item, index) {
+ return { index: index, item: item };
+ });
+
+ var grepPredicate = function (element, index) {
+ return predicate(element.item);
+ };
+
+ var index = filterIndex < 0 ? 0 : filterIndex;
+ var count = filterCount < 0 ? indexedCollection.length : filterCount;
+
+ value = backwards ?
+ // Slice up to 'index', filter, then slice 'count' number of items from the end
+ $.grep(indexedCollection.slice(0, index + 1), grepPredicate).slice(-count) :
+ // Slice from 'index' to the end, filter, then slice 'count' number of items from the beginning
+ $.grep(indexedCollection.slice(index), grepPredicate).slice(0, count);
+ }
+
+ var expectedResults = {};
+ for (var property in data) {
+ if (property == "value") {
+ expectedResults[property] = value;
+ } else {
+ expectedResults[property] = data[property];
+ }
+ }
+
+ return expectedResults;
+ };
+
+ window.CacheVerifier = CacheVerifier;
+
+})(this);
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/d5ec5557/odatajs/tests-tmp/common/odataVerifyReader.js
----------------------------------------------------------------------
diff --git a/odatajs/tests-tmp/common/odataVerifyReader.js b/odatajs/tests-tmp/common/odataVerifyReader.js
new file mode 100644
index 0000000..14bf54e
--- /dev/null
+++ b/odatajs/tests-tmp/common/odataVerifyReader.js
@@ -0,0 +1,203 @@
+/*
+ * 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.
+ */
+
+
+// Client for the odata.read oracle service
+
+(function (window, undefined) {
+ var jsonMime = "application/json";
+ var universalMime = "*/*";
+
+ function readFeed(url, success, mimeType, recognizeDates) {
+ /** Calls the ReadFeed endpoint with the specified URL
+ * @param {String} url - The URL to read the feed from
+ * @param {Function} success - The success callback function
+ * @param {String} mimeType - The MIME media type in the Accept header
+ */
+ var readMethod = getReadMethod(mimeType);
+ oracleRequest("GET", readMethod, typeof url === "string" ? { url: url} : url, mimeType, recognizeDates, function (data) {
+ success(data);
+ });
+ }
+
+ function readEntry(url, success, mimeType, recognizeDates) {
+ /** Calls the ReadEntry endpoint with the specified URL
+ * @param {String} url - The URL to read the entry from
+ * @param {Function} success - The success callback function
+ * @param {String} mimeType - The MIME media type in the Accept header
+ */
+ var readMethod = getReadMethod(mimeType);
+ oracleRequest("GET", readMethod, typeof url === "string" ? { url: url} : url, mimeType, recognizeDates, success);
+ }
+
+ function readLinksEntry(url, success) {
+ /** Calls the ReadMetadata endpoint with the specified URL
+ * @param {String} url - The URL to read the metadata from
+ * @param {Function} success - The success callback function
+ */
+ readJson(
+ url,
+ success
+ );
+ }
+
+ function readLinksFeed(url, success) {
+ /** Calls the ReadMetadata endpoint with the specified URL
+ * @param {String} url - The URL to read the metadata from
+ * @param {Function} success - The success callback function
+ */
+ readJson(
+ url,
+ function (data) {
+ success(data);
+ }
+ );
+ }
+
+ function readMetadata(url, success) {
+ /** Calls the ReadMetadata endpoint with the specified URL
+ * @param {String} url - The URL to read the metadata from
+ * @param {Function} success - The success callback function
+ */
+ oracleRequest("GET", "ReadMetadata", typeof url === "string" ? { url: url} : url, null, null, success);
+ }
+
+ function readServiceDocument (url, success, mimeType) {
+ /** Calls the ReadServiceDocument endpoint with the specified URL
+ * @param {String} url - The URL to the service
+ * @param {Function} success - The success callback function
+ * @param {String} mimeType - The MIME type being tested
+ */
+ var readMethod = getReadMethod(mimeType);
+ oracleRequest("GET", readMethod, typeof url === "string" ? { url: url} : url, mimeType, null, success);
+ }
+
+ function readJson(url, success) {
+ $.ajax({
+ url: url,
+ accepts: null,
+ dataType: "json",
+ beforeSend: function (xhr) {
+ xhr.setRequestHeader("Accept", jsonMime);
+ xhr.setRequestHeader("OData-MaxVersion", "4.0");
+ },
+ success: function (data) {
+ success(data);
+ }
+ });
+ }
+
+ function readJsonAcrossServerPages(url, success) {
+ var data = {};
+ var readPage = function (url) {
+ readJson(url, function (feedData) {
+ var nextLink = feedData["@odata.nextLink"];
+ if (nextLink) {
+ var index = url.indexOf(".svc/", 0);
+ if (index != -1) {
+ nextLink = url.substring(0, index + 5) + nextLink;
+ }
+ }
+
+ if (data.value && feedData.value) {
+ data.value = data.value.concat(feedData.value);
+ }
+ else {
+ for (var property in feedData) {
+ if (property != "@odata.nextLink") {
+ data[property] = feedData[property];
+ }
+ }
+ }
+
+ if (nextLink) {
+ readPage(nextLink);
+ }
+ else {
+ success(data);
+ }
+ });
+ };
+
+ readPage(url);
+ }
+
+ function getReadMethod(mimeType) {
+ switch (mimeType) {
+ case jsonMime:
+ case universalMime:
+ /* falls through */
+ default:
+ return "ReadJson";
+ }
+ return undefined;
+ }
+
+ function oracleRequest(method, endpoint, data, mimeType, recognizeDates, success) {
+ /** Requests a JSON object from the oracle service, removing WCF-specific artifacts
+ * @param {String} method - The HTTP method (GET or POST)
+ * @param {String} endpoint - The oracle endpoint
+ * @param {Object} data - The data to send with the request
+ * @param {Function} reviver - The reviver function to run on each deserialized object
+ * @param {Function} success - Success callback
+ */
+ var url = "./common/ODataVerifiyReader.svc/" + endpoint;
+ if (mimeType) {
+ data.mimeType = mimeType;
+ }
+
+ $.ajax({
+ type: method,
+ url: url,
+ data: data,
+ dataType: "text",
+ success: function (data) {
+ var json = JSON.parse(data);
+ success(json);
+ }
+ });
+ }
+
+ function removeProperty(data, property) {
+ /** Removes the specified property recursively from the given object
+ * @param {Object} data - The object to operate on
+ * @param {String} property - The name of the property to remove
+ */
+ if (typeof data === "object" && data !== null) {
+ if (data[property]) {
+ delete data[property];
+ }
+
+ for (var prop in data) {
+ removeProperty(data[prop], property);
+ }
+ }
+ }
+
+ window.ODataVerifyReader = {
+ readFeed: readFeed,
+ readEntry: readEntry,
+ readLinksEntry: readLinksEntry,
+ readLinksFeed: readLinksFeed,
+ readJson: readJson,
+ readJsonAcrossServerPages: readJsonAcrossServerPages,
+ readMetadata: readMetadata,
+ readServiceDocument: readServiceDocument
+ };
+})(this);
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/d5ec5557/odatajs/tests-tmp/done.txt
----------------------------------------------------------------------
diff --git a/odatajs/tests-tmp/done.txt b/odatajs/tests-tmp/done.txt
new file mode 100644
index 0000000..85ca39b
--- /dev/null
+++ b/odatajs/tests-tmp/done.txt
@@ -0,0 +1,29 @@
+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
+
+odata-json-test.js
+ -> copied and splittet
+
+
+ODataReadOracle.js -> odataVerifyReader.js
+ODataReadOracle.svc -> odataVerifyReader.svc
+
+ODataReadOracle -> odataVerifyReader
http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/d5ec5557/odatajs/tests-tmp/endpoints/BasicAuthDataService.svc
----------------------------------------------------------------------
diff --git a/odatajs/tests-tmp/endpoints/BasicAuthDataService.svc b/odatajs/tests-tmp/endpoints/BasicAuthDataService.svc
new file mode 100644
index 0000000..e059314
--- /dev/null
+++ b/odatajs/tests-tmp/endpoints/BasicAuthDataService.svc
@@ -0,0 +1,124 @@
+<%@ ServiceHost Language="C#" Factory="Microsoft.OData.Service.DataServiceHostFactory, Microsoft.OData.Service, Version=6.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
+ Service="DataJS.Tests.BasicAuthDataService" %>
+/*
+ * 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.
+ */
+namespace DataJS.Tests
+{
+ using System;
+ using System.Collections.Generic;
+ using Microsoft.OData.Service;
+ using System.Linq;
+ using System.ServiceModel;
+ using System.ServiceModel.Web;
+ using System.Text;
+ using System.Web;
+
+ [ServiceBehavior(IncludeExceptionDetailInFaults = true)]
+ public class BasicAuthDataService : DataService<BasicAuthDataSource>
+ {
+ const string Username = "djsUser";
+ const string Password = "djsPassword";
+
+ // This method is called only once to initialize service-wide policies.
+ public static void InitializeService(DataServiceConfiguration config)
+ {
+ config.SetEntitySetAccessRule("*", EntitySetRights.All);
+ config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);
+ config.DataServiceBehavior.MaxProtocolVersion = Microsoft.OData.Client.ODataProtocolVersion.V4;
+ config.UseVerboseErrors = true;
+ }
+
+ public BasicAuthDataService()
+ : base()
+ {
+ this.ProcessingPipeline.ProcessingRequest += OnRequest;
+ }
+
+ [WebInvoke]
+ public void ResetData()
+ {
+ this.CurrentDataSource.ResetData();
+ }
+
+ private static void UnauthorizedRequest(DataServiceOperationContext context)
+ {
+ context.ResponseHeaders["WWW-Authenticate"] = "Basic realm=\"DataJS.Tests\"";
+ throw new DataServiceException(401, "401 Unauthorized");
+ }
+
+ private void OnRequest(object sender, DataServiceProcessingPipelineEventArgs e)
+ {
+ string authHeader = e.OperationContext.RequestHeaders["Authorization"];
+
+ // Validate the Authorization header
+ if (authHeader == null || !authHeader.StartsWith("Basic"))
+ {
+ UnauthorizedRequest(e.OperationContext);
+ }
+
+ // Decode the username and password from the header
+ string base64Credentials = authHeader.Substring(6);
+ string[] credentials = Encoding.ASCII.GetString(Convert.FromBase64String(base64Credentials)).Split(':');
+ if (credentials.Length != 2 || !(credentials[0].Equals(Username) && credentials[1].Equals(Password)))
+ {
+ UnauthorizedRequest(e.OperationContext);
+ }
+ }
+ }
+
+ public class BasicAuthDataSource : ReflectionDataContext, IUpdatable
+ {
+ private static bool dataInitialized;
+
+ public IQueryable<Customer> Customers
+ {
+ get { return this.GetResourceSetEntities<Customer>("Customers").AsQueryable(); }
+ }
+
+ public void ResetData()
+ {
+ this.ClearData();
+
+ IList<Customer> customers = this.GetResourceSetEntities<Customer>("Customers");
+ foreach (int i in Enumerable.Range(1, 16))
+ {
+ customers.Add(new Customer()
+ {
+ ID = i,
+ Name = "Customer " + i
+ });
+ }
+ }
+
+ protected override void EnsureDataIsInitialized()
+ {
+ if (!dataInitialized)
+ {
+ this.ResetData();
+ dataInitialized = true;
+ }
+ }
+ }
+
+ public class Customer
+ {
+ public int ID { get; set; }
+ public string Name { get; set; }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/d5ec5557/odatajs/tests-tmp/endpoints/CustomAnnotations.xml
----------------------------------------------------------------------
diff --git a/odatajs/tests-tmp/endpoints/CustomAnnotations.xml b/odatajs/tests-tmp/endpoints/CustomAnnotations.xml
new file mode 100644
index 0000000..ebf4e26
--- /dev/null
+++ b/odatajs/tests-tmp/endpoints/CustomAnnotations.xml
@@ -0,0 +1,121 @@
+<!--/*
+ * 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.
+*/
+-->
+<?xml version="1.0" encoding="utf-8"?>
+<edmx:Edmx xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx" Version="1.0">
+ <edmx:DataServices m:DataServiceVersion="2.0" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
+ <Schema xmlns="http://schemas.microsoft.com/ado/2007/05/edm" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:mcns="http://MyCustomNamespace.com"
+ Namespace="DataJS.Tests">
+ <EntityType Name="MappedEntry" mcns:MyCustomAnnotation="My custom attribute.">
+ <Key mcns:MyCustomAnnotation="//">
+ <PropertyRef Name="ID" mcns:MyCustomAnnotation=" "/>
+ </Key>
+ <Property Name="ID" Nullable="false" Type="Edm.Int32"/>
+ <Property Name="UnmappedField" Nullable="true" Type="Edm.String"/>
+ <Property Name="Author" Nullable="false" Type="DataJS.Tests.Author" m:FC_KeepInContent_5="false" m:FC_SourcePath_5="Contributor/Name" m:FC_ContentKind_5="text" m:FC_TargetPath_5="SyndicationContributorName" m:FC_KeepInContent_4="false" m:FC_SourcePath_4="Contributor/Email" m:FC_ContentKind_4="text" m:FC_TargetPath_4="SyndicationContributorEmail" m:FC_KeepInContent_3="false" m:FC_SourcePath_3="Uri" m:FC_ContentKind_3="text" m:FC_TargetPath_3="SyndicationAuthorUri" m:FC_KeepInContent_2="false" m:FC_SourcePath_2="Name" m:FC_ContentKind_2="text" m:FC_TargetPath_2="SyndicationAuthorName" m:FC_KeepInContent_1="false" m:FC_SourcePath_1="Email" m:FC_ContentKind_1="text" m:FC_TargetPath_1="SyndicationAuthorEmail" m:FC_KeepInContent="false" m:FC_SourcePath="Contributor/Uri" m:FC_ContentKind="text" m:FC_TargetPath="SyndicationContributorUri"/>
+ <Property Name="Published" Nullable="true" Type="Edm.String" m:FC_KeepInContent="false" m:FC_ContentKind="text" m:FC_TargetPath="SyndicationPublished"/>
+ <Property Name="Rights" Nullable="true" Type="Edm.String" m:FC_KeepInContent="false" m:FC_ContentKind="text" m:FC_TargetPath="SyndicationRights"/>
+ <Property Name="Summary" Nullable="true" Type="Edm.String" m:FC_KeepInContent="false" m:FC_ContentKind="xhtml" m:FC_TargetPath="SyndicationSummary"/>
+ <Property Name="Title" Nullable="true" Type="Edm.String" m:FC_KeepInContent="false" m:FC_ContentKind="html" m:FC_TargetPath="SyndicationTitle"/>
+ <Property Name="Updated" Nullable="true" Type="Edm.String" m:FC_KeepInContent="false" m:FC_ContentKind="text" m:FC_TargetPath="SyndicationUpdated"/>
+ <Property Name="CustomElement" Nullable="true" Type="Edm.String" m:FC_KeepInContent="false" m:FC_TargetPath="customElement" m:FC_NsPrefix="pr" m:FC_NsUri="http://www.example.org/dummy"/>
+ <Property Name="CustomAttribute" Nullable="true" Type="Edm.String" m:FC_KeepInContent="false" m:FC_TargetPath="customElement/@customAttribute" m:FC_NsPrefix="pr" m:FC_NsUri="http://www.example.org/dummy"/>
+ <Property Name="NestedElement1" Nullable="true" Type="Edm.String" m:FC_KeepInContent="false" m:FC_TargetPath="commonElement/nestedElement1" m:FC_NsPrefix="pr" m:FC_NsUri="http://www.example.com/dummy"/>
+ <Property Name="NestedElement2" Nullable="true" Type="Edm.String" m:FC_KeepInContent="false" m:FC_TargetPath="commonElement/nestedElement2" m:FC_NsPrefix="pr" m:FC_NsUri="http://www.example.com/dummy"/>
+ <Property Name="CommonAttribute1" Nullable="true" Type="Edm.String" m:FC_KeepInContent="false" m:FC_TargetPath="commonElement/@commonAttribute1" m:FC_NsPrefix="pr" m:FC_NsUri="http://www.example.com/dummy"/>
+ <Property Name="CommonAttribute2" Nullable="true" Type="Edm.String" m:FC_KeepInContent="false" m:FC_TargetPath="commonElement/@commonAttribute2" m:FC_NsPrefix="pr" m:FC_NsUri="http://www.example.com/dummy"/>
+ <Property Name="Location" Nullable="false" Type="DataJS.Tests.Location" m:FC_KeepInContent_1="false" m:FC_SourcePath_1="Long" m:FC_TargetPath_1="long" m:FC_KeepInContent="false" m:FC_SourcePath="Lat" m:FC_TargetPath="lat" m:FC_NsPrefix="geo" m:FC_NsUri="http://www.georss.org/georss" m:FC_NsPrefix_1="geo" m:FC_NsUri_1="http://www.georss.org/georss"/>
+ </EntityType>
+ <ComplexType Name="Author" mcns:MyCustomAnnotation="">
+ <Property Name="Email" Nullable="true" Type="Edm.String" mcns:MyCustomAnnotation=""/>
+ <Property Name="Name" Nullable="true" Type="Edm.String"/>
+ <Property Name="Uri" Nullable="true" Type="Edm.String"/>
+ <Property Name="Contributor" Nullable="false" Type="DataJS.Tests.Contributor"/>
+ </ComplexType>
+ <ComplexType Name="Contributor">
+ <Property Name="Email" Nullable="true" Type="Edm.String" mcns:MyCustomAnnotation=" "/>
+ <Property Name="Name" Nullable="true" Type="Edm.String"/>
+ <Property Name="Uri" Nullable="true" Type="Edm.String" mcns:MyCustomAnnotation="true"/>
+ </ComplexType>
+ <ComplexType Name="Location">
+ <Property Name="Lat" Nullable="false" Type="Edm.Single" mcns:MyCustomAnnotation="27"/>
+ <Property Name="Long" Nullable="false" Type="Edm.Single"/>
+ </ComplexType>
+ <EntityType Name="ReplicatedEntry">
+ <Key>
+ <PropertyRef Name="ID"/>
+ </Key>
+ <Property Name="ID" Nullable="false" Type="Edm.Int32"/>
+ <Property Name="UnmappedField" Nullable="true" Type="Edm.String"/>
+ <Property Name="Author" Nullable="false" Type="DataJS.Tests.Author2" m:FC_KeepInContent_5="true" m:FC_SourcePath_5="Contributor/Uri" m:FC_ContentKind_5="text" m:FC_TargetPath_5="SyndicationContributorUri" m:FC_KeepInContent_4="true" m:FC_SourcePath_4="Contributor/Name" m:FC_ContentKind_4="text" m:FC_TargetPath_4="SyndicationContributorName" m:FC_KeepInContent_3="true" m:FC_SourcePath_3="Contributor/Email" m:FC_ContentKind_3="text" m:FC_TargetPath_3="SyndicationContributorEmail" m:FC_KeepInContent_2="true" m:FC_SourcePath_2="Uri" m:FC_ContentKind_2="text" m:FC_TargetPath_2="SyndicationAuthorUri" m:FC_KeepInContent_1="true" m:FC_SourcePath_1="Name" m:FC_ContentKind_1="text" m:FC_TargetPath_1="SyndicationAuthorName" m:FC_KeepInContent="true" m:FC_SourcePath="Email" m:FC_ContentKind="text" m:FC_TargetPath="SyndicationAuthorEmail" mcns:MyCustomAnnotation="b>100/b>"/>
+ <Property Name="Published" Nullable="true" Type="Edm.String" m:FC_KeepInContent="true" m:FC_ContentKind="text" m:FC_TargetPath="SyndicationPublished" mcns:MyCustomAnnotation=" . "/>
+ <Property Name="Rights" Nullable="true" Type="Edm.String" m:FC_KeepInContent="true" m:FC_ContentKind="text" m:FC_TargetPath="SyndicationRights"/>
+ <Property Name="Summary" Nullable="true" Type="Edm.String" m:FC_KeepInContent="true" m:FC_ContentKind="xhtml" m:FC_TargetPath="SyndicationSummary" mcns:MyCustomAnnotation="/Property"/>
+ <Property Name="Title" Nullable="true" Type="Edm.String" m:FC_KeepInContent="true" m:FC_ContentKind="html" m:FC_TargetPath="SyndicationTitle"/>
+ <Property Name="Updated" Nullable="true" Type="Edm.String" m:FC_KeepInContent="true" m:FC_ContentKind="text" m:FC_TargetPath="SyndicationUpdated"/>
+ <Property Name="CustomElement" Nullable="true" Type="Edm.String" m:FC_KeepInContent="true" m:FC_TargetPath="customElement" m:FC_NsPrefix="pr" m:FC_NsUri="http://www.example.org/dummy"/>
+ <Property Name="CustomAttribute" Nullable="true" Type="Edm.String" m:FC_KeepInContent="true" m:FC_TargetPath="customElement/@customAttribute" m:FC_NsPrefix="pr" m:FC_NsUri="http://www.example.org/dummy"/>
+ <Property Name="NestedElement1" Nullable="true" Type="Edm.String" m:FC_KeepInContent="true" m:FC_TargetPath="commonElement/nestedElement1" m:FC_NsPrefix="pr" m:FC_NsUri="http://www.example.com/dummy"/>
+ <Property Name="NestedElement2" Nullable="true" Type="Edm.String" m:FC_KeepInContent="true" m:FC_TargetPath="commonElement/nestedElement2" m:FC_NsPrefix="pr" m:FC_NsUri="http://www.example.com/dummy"/>
+ <Property Name="CommonAttribute1" Nullable="true" Type="Edm.String" m:FC_KeepInContent="true" m:FC_TargetPath="commonElement/@commonAttribute1" m:FC_NsPrefix="pr" m:FC_NsUri="http://www.example.com/dummy"/>
+ <Property Name="CommonAttribute2" Nullable="true" Type="Edm.String" m:FC_KeepInContent="true" m:FC_TargetPath="commonElement/@commonAttribute2" m:FC_NsPrefix="pr" m:FC_NsUri="http://www.example.com/dummy"/>
+ <Property Name="Location" Nullable="false" Type="DataJS.Tests.Location2" m:FC_KeepInContent_1="true" m:FC_SourcePath_1="Long" m:FC_TargetPath_1="long" m:FC_KeepInContent="true" m:FC_SourcePath="Lat" m:FC_TargetPath="lat" m:FC_NsPrefix="geo" m:FC_NsUri="http://www.georss.org/georss" m:FC_NsPrefix_1="geo" m:FC_NsUri_1="http://www.georss.org/georss"/>
+ </EntityType>
+ <ComplexType Name="Author2">
+ <Property Name="Email" Nullable="true" Type="Edm.String"/>
+ <Property Name="Name" Nullable="true" Type="Edm.String"/>
+ <Property Name="Uri" Nullable="true" Type="Edm.String"/>
+ <Property Name="Contributor" Nullable="false" Type="DataJS.Tests.Contributor2"/>
+ </ComplexType>
+ <ComplexType Name="Contributor2">
+ <Property Name="Email" Nullable="true" Type="Edm.String"/>
+ <Property Name="Name" Nullable="true" Type="Edm.String"/>
+ <Property Name="Uri" Nullable="true" Type="Edm.String"/>
+ </ComplexType>
+ <ComplexType Name="Location2">
+ <Property Name="Lat" Nullable="false" Type="Edm.Single"/>
+ <Property Name="Long" Nullable="false" Type="Edm.Single"/>
+ </ComplexType>
+ <EntityType Name="DerivedEntry" m:FC_KeepInContent="false" m:FC_SourcePath="MappedInDerivedField" m:FC_TargetPath="mappedField/@mappedInDerived" m:FC_NsPrefix="pre" m:FC_NsUri="http://www.example.com/dummy" BaseType="DataJS.Tests.BaseEntry">
+ <Property Name="UnmappedConcreteField" Nullable="true" Type="Edm.String"/>
+ <Property Name="MappedConcreteField" Nullable="true" Type="Edm.String" m:FC_KeepInContent="false" m:FC_TargetPath="mappedField/@mappedConcrete" m:FC_NsPrefix="pre" m:FC_NsUri="http://www.example.com/dummy"/>
+ </EntityType>
+ <EntityType Name="BaseEntry">
+ <Key>
+ <PropertyRef Name="ID"/>
+ </Key>
+ <Property Name="ID" Nullable="false" Type="Edm.Int32"/>
+ <Property Name="UnmappedField" Nullable="true" Type="Edm.String"/>
+ <Property Name="MappedInDerivedField" Nullable="true" Type="Edm.String" mcns:MyCustomAnnotation="false"/>
+ <Property Name="MappedField" Nullable="true" Type="Edm.String" m:FC_KeepInContent="false" m:FC_TargetPath="mappedField" m:FC_NsPrefix="pre" m:FC_NsUri="http://www.example.com/dummy"/>
+ </EntityType>
+ <EntityContainer Name="EpmDataSource" m:IsDefaultEntityContainer="true" mcns:MyCustomAnnotation="0">
+ <EntitySet Name="MappedEntries" EntityType="DataJS.Tests.MappedEntry"/>
+ <EntitySet Name="ReplicatedEntries" EntityType="DataJS.Tests.ReplicatedEntry"/>
+ <EntitySet Name="HierarchicalEntries" EntityType="DataJS.Tests.BaseEntry"/>
+ <FunctionImport Name="ResetData" m:HttpMethod="POST" mcns:MyCustomAnnotation="null"/>
+ </EntityContainer>
+ <mcns:EmptyElement></mcns:EmptyElement>
+ <mcns:ParentCustomElement mcns:MyCustomAnnotation="annotation" mcns:MySecondCustomAnnotation="annotation 2">
+ <mcns:CustomChildElement1>Custom metadata 1.</mcns:CustomChildElement1>
+ <mcns:CustomChildElement2>Custom metadata 2.</mcns:CustomChildElement2>
+ </mcns:ParentCustomElement>
+ </Schema>
+ </edmx:DataServices>
+</edmx:Edmx>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/d5ec5557/odatajs/tests-tmp/endpoints/CustomDataService.svc
----------------------------------------------------------------------
diff --git a/odatajs/tests-tmp/endpoints/CustomDataService.svc b/odatajs/tests-tmp/endpoints/CustomDataService.svc
new file mode 100644
index 0000000..67fcfd0
--- /dev/null
+++ b/odatajs/tests-tmp/endpoints/CustomDataService.svc
@@ -0,0 +1,85 @@
+<!--
+/*
+ * 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.
+ */
+-->
+
+<%@ ServiceHost Language="C#" Debug="true" Factory="System.ServiceModel.Activation.WebServiceHostFactory"
+ Service="DataJS.Tests.CustomDataService" %>
+
+
+using System.Collections;
+using System.IO;
+
+namespace DataJS.Tests
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.ServiceModel;
+ using System.ServiceModel.Activation;
+ using System.ServiceModel.Web;
+
+ /// <summary>
+ /// Custom data service that does not use OData
+ /// </summary>
+ [ServiceContract]
+ [ServiceBehavior(IncludeExceptionDetailInFaults = true)]
+ [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
+ public class CustomDataService
+ {
+ static readonly Item[] data = Enumerable.Range(0, 16).Select(i => new Item
+ {
+ ID = i,
+ Name = "Item " + i
+ }).ToArray();
+
+ // This uses the same URI template as OData so that the CacheOracle can be reused
+ [OperationContract]
+ [WebGet(UriTemplate = "ReadRange?$skip={skip}&$top={top}")]
+ public Stream ReadRange(int skip, int top)
+ {
+ IEnumerable selectData = data.Skip(skip).Take(top);
+ Dictionary<string, object> result = new Dictionary<string, object>();
+ List<Dictionary<string, string>> value = new List<Dictionary<string, string>>();
+ foreach (Item d in selectData)
+ {
+ Dictionary<string, string> item = new Dictionary<string, string>();
+ item.Add("ID", d.ID.ToString());
+ item.Add("Name", d.Name);
+ value.Add(item);
+ }
+
+ result.Add("value", value);
+ return ReaderUtils.ConvertDictionarytoJsonlightStream(result);
+ }
+
+ [OperationContract]
+ [WebGet(ResponseFormat = WebMessageFormat.Json)]
+ public int Count()
+ {
+ return data.Count();
+ }
+ }
+
+ public class Item
+ {
+ public int ID { get; set; }
+ public string Name { get; set; }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/d5ec5557/odatajs/tests-tmp/endpoints/EpmDataService.svc
----------------------------------------------------------------------
diff --git a/odatajs/tests-tmp/endpoints/EpmDataService.svc b/odatajs/tests-tmp/endpoints/EpmDataService.svc
new file mode 100644
index 0000000..316c9ae
--- /dev/null
+++ b/odatajs/tests-tmp/endpoints/EpmDataService.svc
@@ -0,0 +1,336 @@
+<!--
+/*
+ * 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.
+ */
+-->
+
+<%@ ServiceHost Language="C#" Factory="Microsoft.OData.Service.DataServiceHostFactory, Microsoft.OData.Service, Version=6.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
+ Service="DataJS.Tests.EpmDataService" %>
+
+
+namespace DataJS.Tests
+{
+ using System;
+ using System.Collections.Generic;
+ using Microsoft.OData.Service;
+ using System.Linq;
+ using System.ServiceModel.Web;
+
+ /// <summary>
+ /// A data service that uses EPM
+ /// </summary>
+ [System.ServiceModel.ServiceBehavior(IncludeExceptionDetailInFaults = true)]
+ public class EpmDataService : DataService<EpmDataSource>
+ {
+ // This method is called only once to initialize service-wide policies.
+ public static void InitializeService(DataServiceConfiguration config)
+ {
+ config.SetEntitySetAccessRule("*", EntitySetRights.All);
+ config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);
+ config.DataServiceBehavior.MaxProtocolVersion = Microsoft.OData.Client.ODataProtocolVersion.V4;
+ config.UseVerboseErrors = true;
+
+ }
+
+ [WebInvoke]
+ public void ResetData()
+ {
+ this.CurrentDataSource.ResetData();
+ }
+ }
+
+ public class EpmDataSource : ReflectionDataContext, IUpdatable
+ {
+ private static bool dataInitialized;
+
+ public IQueryable<MappedEntry> MappedEntries
+ {
+ get { return this.GetResourceSetEntities<MappedEntry>("MappedEntries").AsQueryable(); }
+ }
+
+ public IQueryable<ReplicatedEntry> ReplicatedEntries
+ {
+ get { return this.GetResourceSetEntities<ReplicatedEntry>("ReplicatedEntries").AsQueryable(); }
+ }
+
+ public IQueryable<BaseEntry> HierarchicalEntries
+ {
+ get { return this.GetResourceSetEntities<BaseEntry>("HierarchicalEntries").AsQueryable(); }
+ }
+
+ public void ResetData()
+ {
+ this.ClearData();
+
+ MappedEntry[] mappedEntries = new MappedEntry[]
+ {
+ new MappedEntry
+ {
+ ID = 0,
+ UnmappedField = "Unmapped0",
+ Author = new Author
+ {
+ Email = "AuthorEmail0",
+ Name = "AuthorName0",
+ Uri = "http://www.example.com/AuthorUri",
+ Contributor = new Contributor
+ {
+ Email = "ContributorEmail0",
+ Name = "ContributorName0",
+ Uri = "http://www.example.com/ContributorUri",
+ },
+ },
+ Published = "2000-01-01T00:00:00-08:00",
+ Rights = "Rights0",
+ Summary = "<xmlElement xmlns=\"http://www.example.org/dummy\" attr=\"value0\">Summary0</xmlElement>",
+ Title = "Title<b>0</b>",
+ Updated = "2000-01-01T00:00:00-08:00",
+ CustomElement = "CustomElement0",
+ CustomAttribute = "CustomAttribute0",
+ NestedElement1 = "NestedElement1_0",
+ NestedElement2 = "NestedElement2_0",
+ CommonAttribute1 = "CommonAttribute1_0",
+ CommonAttribute2 = "CommonAttribute2_0",
+ Location = new Location
+ {
+ Lat = 3.14f,
+ Long = 2.72f
+ }
+ },
+
+ new MappedEntry
+ {
+ ID = 1,
+ UnmappedField = null,
+ Author = new Author
+ {
+ Email = null,
+ Name = string.Empty,
+ Uri = "http://www.example.com/AuthorUri1",
+ Contributor = new Contributor
+ {
+ Email = null,
+ Name = string.Empty,
+ Uri = "http://www.example.com/ContributorUri1",
+ },
+ },
+ Published = "2000-01-01T00:00:00-08:00",
+ Rights = null,
+ Summary = "",
+ Title = "Title<i>1</i>",
+ Updated = "2111-01-01T00:00:00-08:00",
+ CustomElement = null,
+ NestedElement1 = string.Empty,
+ NestedElement2 = "NestedElement2_1",
+ CustomAttribute = null,
+ CommonAttribute1 = string.Empty,
+ CommonAttribute2 = "CommonAttribute2_1",
+ Location = new Location
+ {
+ Lat = float.MaxValue,
+ Long = float.MinValue
+ }
+ },
+
+ new MappedEntry
+ {
+ ID = 2,
+ UnmappedField = "Unmapped2",
+ Author = new Author
+ {
+ Email = "AuthorEmail2",
+ Name = "AuthorName2",
+ Uri = "http://www.example.com/AuthorUri2",
+ Contributor = null
+ },
+ Published = "2000-01-01T00:00:00-08:00",
+ Rights = "Rights2",
+ Summary = "Summary2",
+ Title = "Title2",
+ Updated = "2000-01-01T00:00:00-08:00",
+ CustomElement = "CustomElement2",
+ CustomAttribute = "CustomAttribute2",
+ NestedElement1 = "NestedElement1_2",
+ NestedElement2 = "NestedElement2_2",
+ CommonAttribute1 = "CommonAttribute1_2",
+ CommonAttribute2 = "CommonAttribute2_2",
+ Location = null
+ },
+ };
+ Array.ForEach(mappedEntries, (item) => this.GetResourceSetEntities<MappedEntry>("MappedEntries").Add(item));
+
+ Array.ForEach(mappedEntries, (item) => this.GetResourceSetEntities<ReplicatedEntry>("ReplicatedEntries").Add(new ReplicatedEntry
+ {
+ ID = item.ID,
+ UnmappedField = item.UnmappedField,
+ Author = item.Author == null ? null : new Author2
+ {
+ Email = item.Author.Email,
+ Name = item.Author.Name,
+ Uri = item.Author.Uri,
+ Contributor = item.Author.Contributor == null ? null : new Contributor2
+ {
+ Name = item.Author.Contributor.Name,
+ Email = item.Author.Contributor.Email,
+ Uri = item.Author.Contributor.Uri
+ },
+ },
+ Published = item.Published,
+ Rights = item.Rights,
+ Summary = item.Summary,
+ Title = item.Title,
+ Updated = item.Updated,
+ CustomElement = item.CustomElement,
+ CustomAttribute = item.CustomAttribute,
+ NestedElement1 = item.NestedElement1,
+ NestedElement2 = item.NestedElement2,
+ CommonAttribute1 = item.CommonAttribute1,
+ CommonAttribute2 = item.CommonAttribute2,
+ Location = item.Location == null ? null : new Location2
+ {
+ Lat = item.Location.Lat,
+ Long = item.Location.Long
+ }
+ }));
+
+ BaseEntry[] hierarchicalEntries = new BaseEntry[]
+ {
+ new BaseEntry
+ {
+ ID = 0,
+ MappedField = "MappedField0",
+ MappedInDerivedField = "MappedInDerivedField0",
+ UnmappedField = "UnmappedField0"
+ },
+ new DerivedEntry
+ {
+ ID = 1,
+ MappedField = "MappedField1",
+ MappedInDerivedField = "MappedInDerivedField1",
+ UnmappedField = "UnmappedField1",
+ MappedConcreteField = "MappedConcreteField1",
+ UnmappedConcreteField = "UnmappedConcreteField1"
+ },
+ };
+ Array.ForEach(hierarchicalEntries, (item) => this.GetResourceSetEntities<BaseEntry>("HierarchicalEntries").Add(item));
+ }
+
+ protected override void EnsureDataIsInitialized()
+ {
+ if (!dataInitialized)
+ {
+ this.ResetData();
+ dataInitialized = true;
+ }
+ }
+ }
+
+ public class Author
+ {
+ public string Email { get; set; }
+ public string Name { get; set; }
+ public string Uri { get; set; }
+ public Contributor Contributor { get; set; }
+ }
+
+ public class Contributor
+ {
+ public string Email { get; set; }
+ public string Name { get; set; }
+ public string Uri { get; set; }
+ }
+
+ public class Location
+ {
+ public float Lat { get; set; }
+ public float Long { get; set; }
+ }
+
+ public class Author2
+ {
+ public string Email { get; set; }
+ public string Name { get; set; }
+ public string Uri { get; set; }
+ public Contributor2 Contributor { get; set; }
+ }
+
+ public class Contributor2
+ {
+ public string Email { get; set; }
+ public string Name { get; set; }
+ public string Uri { get; set; }
+ }
+
+ public class Location2
+ {
+ public float Lat { get; set; }
+ public float Long { get; set; }
+ }
+
+ public class MappedEntry
+ {
+ public int ID { get; set; }
+ public string UnmappedField { get; set; }
+ public Author Author { get; set; }
+ public string Published { get; set; }
+ public string Rights { get; set; }
+ public string Summary { get; set; }
+ public string Title { get; set; }
+ public string Updated { get; set; }
+ public string CustomElement { get; set; }
+ public string CustomAttribute { get; set; }
+ public string NestedElement1 { get; set; }
+ public string NestedElement2 { get; set; }
+ public string CommonAttribute1 { get; set; }
+ public string CommonAttribute2 { get; set; }
+ public Location Location { get; set; }
+ }
+
+ public class ReplicatedEntry
+ {
+ public int ID { get; set; }
+ public string UnmappedField { get; set; }
+ public Author2 Author { get; set; }
+ public string Published { get; set; }
+ public string Rights { get; set; }
+ public string Summary { get; set; }
+ public string Title { get; set; }
+ public string Updated { get; set; }
+ public string CustomElement { get; set; }
+ public string CustomAttribute { get; set; }
+ public string NestedElement1 { get; set; }
+ public string NestedElement2 { get; set; }
+ public string CommonAttribute1 { get; set; }
+ public string CommonAttribute2 { get; set; }
+ public Location2 Location { get; set; }
+ }
+
+ public class BaseEntry
+ {
+ public int ID { get; set; }
+ public string UnmappedField { get; set; }
+ public string MappedInDerivedField { get; set; }
+ public string MappedField { get; set; }
+ }
+
+ public class DerivedEntry : BaseEntry
+ {
+ public string UnmappedConcreteField { get; set; }
+ public string MappedConcreteField { get; set; }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/d5ec5557/odatajs/tests-tmp/endpoints/ErrorDataService.svc
----------------------------------------------------------------------
diff --git a/odatajs/tests-tmp/endpoints/ErrorDataService.svc b/odatajs/tests-tmp/endpoints/ErrorDataService.svc
new file mode 100644
index 0000000..052a2df
--- /dev/null
+++ b/odatajs/tests-tmp/endpoints/ErrorDataService.svc
@@ -0,0 +1,78 @@
+<!--
+/*
+ * 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.
+ */
+-->
+
+<%@ ServiceHost Language="C#" Factory="Microsoft.OData.Service.DataServiceHostFactory, Microsoft.OData.Service, Version=6.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
+ Service="DataJS.Tests.ErrorDataService" %>
+
+
+
+namespace DataJS.Tests
+{
+ using System;
+ using System.Collections.Generic;
+ using Microsoft.OData.Service;
+ using System.Linq;
+
+ /// <summary>
+ /// A data service that contains in-stream errors
+ /// </summary>
+ public class ErrorDataService : DataService<ErrorDataSource>
+ {
+ // This method is called only once to initialize service-wide policies.
+ public static void InitializeService(DataServiceConfiguration config)
+ {
+ config.SetEntitySetAccessRule("*", EntitySetRights.All);
+ config.DataServiceBehavior.MaxProtocolVersion = Microsoft.OData.Client.ODataProtocolVersion.V4;
+ }
+ }
+
+ public class ErrorDataSource
+ {
+ public IQueryable<ErrorType> Entities
+ {
+ get
+ {
+ ErrorType[] entities = new ErrorType[]
+ {
+ new ErrorType(() => 0),
+ new ErrorType(() => { throw new ApplicationException(); })
+ };
+
+ return entities.AsQueryable();
+ }
+ }
+ }
+
+ public class ErrorType
+ {
+ Func<int> generateID;
+
+ public ErrorType(Func<int> generateID)
+ {
+ this.generateID = generateID;
+ }
+
+ public int ID
+ {
+ get { return this.generateID(); }
+ }
+ }
+}
\ No newline at end of file