├── .gitignore ├── DEPENDENCIES ├── Gruntfile.js ├── JSLib.csproj ├── JSLib.sln ├── LICENSE ├── NOTICE ├── README.md ├── Web.config ├── demo ├── scripts │ ├── datajs_demo.js │ └── tools.js └── tester.html ├── grunt-config ├── banner.txt ├── custom-tasks │ ├── rat.js │ ├── rat │ │ ├── .gitignore │ │ ├── package.json │ │ ├── readme.md │ │ └── tasks │ │ │ └── rat.js │ ├── sign.js │ ├── toBrowser.js │ └── toBrowser │ │ ├── toBrowser.js │ │ └── wrapper-tpl.js ├── nugetpack.nuspec ├── rat-config.js ├── release-config.js └── sign-config.js ├── index-browser.js ├── index.js ├── lib ├── cache.js ├── cache │ └── source.js ├── deferred.js ├── odata.js ├── odata │ ├── batch.js │ ├── handler.js │ ├── json.js │ ├── metadata.js │ ├── net-browser.js │ ├── net.js │ └── odatautils.js ├── store.js ├── store │ ├── dom.js │ ├── indexeddb.js │ └── memory.js ├── utils.js └── xml.js ├── package.json ├── packages.config ├── test ├── mocha.opts ├── test-demo-scenario.js ├── test-odata-json.js └── test-utils.js └── tests ├── cache-tests.js ├── code ├── ReflectionDataContext.cs ├── csdlreader.cs ├── jsdate.cs ├── jsonobject.cs └── readerutils.cs ├── common ├── CacheVerifier.js ├── Instrument.js ├── Instrument.svc ├── ODataVerifyReader.svc ├── ObservableHttpClient.js ├── TestLogger.svc ├── TestSynchronizerClient.js ├── common.js ├── djstest-browser-ext.js ├── djstest.js ├── mockHttpClient.js ├── mockXMLHttpRequest.js ├── odataVerifyReader.js └── rx.js ├── e2etest └── Test.html ├── endpoints ├── BasicAuthDataService.svc ├── CustomAnnotations.xml ├── CustomDataService.svc ├── EpmDataService.svc ├── ErrorDataService.svc ├── FoodStoreDataServiceV4.svc ├── LargeCollectionService.svc └── web.config ├── info.txt ├── node-test-setup.js ├── odata-batch-functional-tests.html ├── odata-batch-functional-tests.js ├── odata-batch-tests.js ├── odata-cache-filter-functional-tests.html ├── odata-cache-filter-functional-tests.js ├── odata-cache-fperf-tests.html ├── odata-cache-fperf-tests.js ├── odata-cache-functional-tests.html ├── odata-cache-functional-tests.js ├── odata-cache-rx-functional-tests.html ├── odata-cache-rx-functional-tests.js ├── odata-fuzz.html ├── odata-handler-tests.js ├── odata-json-light-tests.js ├── odata-json-parse-tests.html ├── odata-json-parse-tests.js ├── odata-json-tests.js ├── odata-links-functional-tests.html ├── odata-links-functional-tests.js ├── odata-metadata-awareness-functional-tests.html ├── odata-metadata-awareness-functional-tests.js ├── odata-metadata-tests.js ├── odata-net-tests.js ├── odata-perf-tests.html ├── odata-perf-tests.js ├── odata-qunit-tests.htm ├── odata-read-crossdomain-functional-tests.html ├── odata-read-crossdomain-functional-tests.js ├── odata-read-functional-tests.html ├── odata-read-functional-tests.js ├── odata-request-functional-tests.html ├── odata-request-functional-tests.js ├── odata-roundtrip-functional-tests.js ├── odata-tests.js ├── odata-xml-tests.js ├── odatajs-cache-large-collection-functional-tests.html ├── odatajs-cache-large-collection-functional-tests.js ├── odatajs-cache-long-haul-tests.html ├── odatajs-startup-perf-test.html ├── run-tests.wsf ├── store-indexeddb-tests.js ├── store-tests.js ├── test-list.js └── test-manager.html /.gitignore: -------------------------------------------------------------------------------- 1 | # ignore local stuff starting with an underscore 2 | _* 3 | 4 | # ignore IDE settings 5 | .idea 6 | olingo-odata4-js.iml 7 | 8 | # ignore local config 9 | localgrunt.config 10 | 11 | # testing copies 12 | ../demo/scripts/odatajs-4.0.0-* 13 | 14 | # build artefacts 15 | #build/ 16 | 17 | # nodejs temporary objects 18 | node_modules/ 19 | 20 | # C.net server temporary objects 21 | bin/ 22 | obj/ 23 | packages/ 24 | JSLib.suo 25 | JSLib.csproj.user 26 | -------------------------------------------------------------------------------- /DEPENDENCIES: -------------------------------------------------------------------------------- 1 | // ------------------------------------------------------------------ 2 | // Transitive dependencies of this project determined from the 3 | // maven pom organized by organization. 4 | // ------------------------------------------------------------------ 5 | 6 | Apache Olingo -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | /* 3 | * Licensed to the Apache Software Foundation (ASF) under one 4 | * or more contributor license agreements. See the NOTICE file 5 | * distributed with this work for additional information 6 | * regarding copyright ownership. The ASF licenses this file 7 | * to you under the Apache License, Version 2.0 (the 8 | * "License"); you may not use this file except in compliance 9 | * with the License. You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, 14 | * software distributed under the License is distributed on an 15 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | * KIND, either express or implied. See the License for the 17 | * specific language governing permissions and limitations 18 | * under the License. 19 | */ 20 | module.exports = function(grunt) { 21 | 'use strict'; 22 | var intUse = '-internal use only-'; 23 | var pkg = grunt.file.readJSON('package.json'); 24 | 25 | // Build artifact base name 26 | //<%= pkg.name %>-<%= pkg.version %>-<%= pkg.postfix %>-<%= pkg.releaseCandidate %>' 27 | var artifactname = pkg.name + '-' + pkg.version + 28 | (pkg.postfix.length > 0 ? "-" : "") + pkg.postfix + 29 | (pkg.releaseCandidate.length > 0 ? "-" : "") + pkg.releaseCandidate; 30 | 31 | //options 32 | var init = { 33 | pkg: pkg, 34 | banner: grunt.file.read('grunt-config/banner.txt'), 35 | artifactname : artifactname, 36 | 37 | "toBrowser" : { 38 | "release" : { 39 | options: { index : "index-browser.js" }, 40 | src: ["lib/**/*.js", '!**/*-node.*'], 41 | dest: "_build/lib/<%= artifactname %>.js" 42 | } 43 | }, 44 | "uglify": { // uglify and minify the lib 45 | options: { 46 | sourceMap : true, 47 | sourceMapName : "_build/lib/<%= artifactname %>.map", 48 | sourceMapIncludeSources : true, 49 | banner : "<%= banner %>" 50 | }, 51 | "browser": { 52 | src: "_build/lib/<%= artifactname %>.js", 53 | dest: "_build/lib/<%= artifactname %>.min.js" 54 | } 55 | }, 56 | "jsdoc" : { 57 | "src" : { 58 | src: ["index.js","lib/**/*.js"], 59 | options: { destination: "_build/doc-src", verbose : true, debug : true, pedantic : true } 60 | } 61 | }, 62 | "nugetpack" : { // create nuget pagckage 63 | "dist": { 64 | src: 'grunt-config/nugetpack.nuspec', 65 | dest: '_build/' 66 | } 67 | }, 68 | "copy" : { 69 | "to-latest" : { 70 | src :"_build/lib/<%= artifactname %>.js", 71 | dest: "_build/lib/odatajs-latest.js" 72 | } 73 | }, 74 | "priv-clean": { 75 | options: {force: true}, 76 | "build": { 77 | src: [ "_build/*"] 78 | } 79 | } 80 | }; 81 | 82 | // Join local configuration for proxies and local test servers 83 | if (grunt.file.exists('localgrunt.config')) { 84 | console.log("merge localgrunt.config"); 85 | var localGrundConfig = grunt.file.read('localgrunt.config'); 86 | init.connect['test-browser'].proxies = init.connect['test-browser'].proxies.concat(JSON.parse(localGrundConfig).proxies); 87 | } 88 | 89 | // Init config 90 | grunt.initConfig(init); 91 | 92 | // Load tasks from npm modules ***/ 93 | grunt.loadNpmTasks('grunt-contrib-uglify'); 94 | grunt.loadNpmTasks("grunt-contrib-copy"); 95 | grunt.loadNpmTasks('grunt-contrib-compress'); 96 | grunt.loadNpmTasks('grunt-curl'); 97 | grunt.loadNpmTasks("grunt-jsdoc"); 98 | grunt.loadNpmTasks("grunt-nuget"); 99 | 100 | // Load the custom-* tasks from the grunt-config/custom-tasks directory 101 | grunt.loadTasks('grunt-config/custom-tasks'); //currently rat.js/sign.js/toBrowser.js 102 | 103 | // Load the custom-* config from the grunt-config directory 104 | grunt.loadTasks('grunt-config'); //rat.js/sign.js/toBrowser.js 105 | 106 | // Rename some tasks to avoid name clashes with the user tasks 107 | grunt.renameTask('clean','priv-clean'); //rat-config.js/sign-config.js/release-config.js 108 | 109 | // Avoid problems with apache-rat tool 110 | grunt.registerTask('clearEnv', intUse, function() { 111 | process.env['JAVA_TOOL_OPTIONS'] = ''; 112 | }); 113 | 114 | 115 | // E N D U S E R T A S K S 116 | 117 | grunt.registerTask('default' , 'Show help', function() { grunt.log.write('Use grunt --help to get a list of tasks')}); 118 | 119 | grunt.registerTask('clean', 'Clean the temporary build directories', ['priv-clean:build']); 120 | 121 | // BUILD the odatajs library 122 | grunt.registerTask('build', 'Build the odatajs library', ['clean:build','toBrowser:release', 'uglify:browser', 'copy:to-latest', 'nugetpack']); 123 | 124 | // Create DOCumentation in /_build/doc 125 | grunt.registerTask('doc', 'Create documentation in folder ./_build/doc-src',['clearEnv', 'jsdoc:src']); 126 | 127 | // R E L E A S E T A S K S ( tasts defined in release-config.js) 128 | grunt.registerTask('release','Build the odatajs library, run checks and package it in folder ./_dist',[ 129 | 'priv-clean:release-dist', 130 | 'build', 131 | 'doc', 132 | 'copy:release-lib','copy:release-doc','copy:release-sources', 133 | 'rat:dist', // check the license headers 134 | 'compress:release-lib','compress:release-doc','compress:release-sources' 135 | ]); 136 | 137 | 138 | grunt.registerTask('release-sign','Sign the files which are released (run "grunt release" before"',[ 139 | 'sign:release','sign:asc','sign:asc-verify' 140 | ]); 141 | 142 | // Runs the license header check to verify the any source file contains a license header 143 | grunt.registerTask('license-check','Check files for the existence of the license header', ['rat:manual','rat:dist']); 144 | }; 145 | 146 | -------------------------------------------------------------------------------- /JSLib.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 11.00 2 | # Visual Studio 2010 3 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JSLib", "JSLib.csproj", "{73ADF1A7-613B-4679-885B-2AE4AFAA9A6A}" 4 | EndProject 5 | Global 6 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 7 | Debug|Any CPU = Debug|Any CPU 8 | Release|Any CPU = Release|Any CPU 9 | EndGlobalSection 10 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 11 | {73ADF1A7-613B-4679-885B-2AE4AFAA9A6A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 12 | {73ADF1A7-613B-4679-885B-2AE4AFAA9A6A}.Debug|Any CPU.Build.0 = Debug|Any CPU 13 | {73ADF1A7-613B-4679-885B-2AE4AFAA9A6A}.Release|Any CPU.ActiveCfg = Release|Any CPU 14 | {73ADF1A7-613B-4679-885B-2AE4AFAA9A6A}.Release|Any CPU.Build.0 = Release|Any CPU 15 | EndGlobalSection 16 | GlobalSection(SolutionProperties) = preSolution 17 | HideSolutionNode = FALSE 18 | EndGlobalSection 19 | EndGlobal 20 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | 2 | Apache Olingo 3 | Copyright 2013-2014 The Apache Software Foundation 4 | 5 | This product includes software developed at 6 | The Apache Software Foundation (http://www.apache.org/). 7 | 8 | 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Licensed to the Apache Software Foundation (ASF) under one 2 | or more contributor license agreements. See the NOTICE file 3 | distributed with this work for additional information 4 | regarding copyright ownership. The ASF licenses this file 5 | to you under the Apache License, Version 2.0 (the 6 | "License"); you may not use this file except in compliance 7 | with the License. You may obtain a copy of the License at 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, 12 | software distributed under the License is distributed on an 13 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | KIND, either express or implied. See the License for the 15 | specific language governing permissions and limitations 16 | under the License. 17 | 18 | ------------------------- 19 | ## Olingo OData Client for JavaScript 20 | The Olingo OData Client for JavaScript (odatajs) is a library written in JavaScript that enables browser based frontend applications to easily use the OData protocol for communication with application servers. 21 | 22 | This library "odatajs-4.0.0.min.js" supports only the OData V4 protocol. 23 | 24 | For using the OData protocols V1-V3 please refer to the [datajs library](http://datajs.codeplex.com/) 25 | 26 | The odatajs library can be included in any html page with the script tag (for example) 27 | ``` 28 | 29 | ``` 30 | and its features can be used through the `odatajs` namespace (or `window.odatajs`). The odatajs library can be used together with the datajs library which uses the `window.OData` namespace. 31 | 32 | For API documentation please see [ODatajs API documentation](http://olingo.apache.org/doc/javascript/apidoc/) 33 | 34 | You may also use the documentation and the samples from the [datajs library](http://datajs.codeplex.com/documentation) because the features and API are similar. 35 | 36 | ## Contribute to Olingo OData Client for JavaScript 37 | If you are interested to contribute to this library please have a look into [Project setup](http://olingo.apache.org/doc/javascript/project-setup.html) and [Build instructions](http://olingo.apache.org/doc/javascript/project-build.html) where you find a manual how you can download the source code and build the odatajs library. 38 | 39 | If you intend so please also join the [Olingo developers group](http://olingo.apache.org/support.html) for discussion. 40 | -------------------------------------------------------------------------------- /Web.config: -------------------------------------------------------------------------------- 1 |  2 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /demo/scripts/datajs_demo.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | var run = function() { 20 | //testJQueryReadMetadata(); 21 | runSimpleReadRequest(); 22 | runSimpleReadRequestWithMetadata(); 23 | // readWithJsonP(); 24 | //alert(OData.odataRelatedLinksPrefix); 25 | //OData.odataRelatedLinksPrefix = "dasfs"; 26 | //alert(OData.odataRelatedLinksPrefix); 27 | //var time = new Date("1992-08-06T00:00:00+01:00"); 28 | //var jsonTime = {value : time}; 29 | //var jsonstring = window.JSON.stringify(jsonTime); 30 | //alert(jsonstring); 31 | 32 | //time.offset = 100; 33 | //alert(time.offset); 34 | //var offsite = time.getTimezoneOffset(); 35 | //alert(offsite); 36 | }; 37 | 38 | var runSimpleReadRequest = function() { 39 | var oHeaders = { 40 | 'Accept': 'application/json', 41 | "Odata-Version": "4.0", 42 | "OData-MaxVersion": "4.0" 43 | }; 44 | 45 | var request = 46 | { 47 | headers: oHeaders, 48 | // requestUri: "http://services.odata.org/OData/OData.svc/Categories", 49 | requestUri: "http://odatasampleservices.azurewebsites.net/V4/OData/OData.svc/Categories", 50 | data: null, 51 | }; 52 | var successFunction = function (data) { 53 | document.getElementById("simpleRead").innerHTML = JSON.stringify(data, undefined, 2); 54 | }; 55 | var failFunction = function (err) { 56 | alert("err"); 57 | alert(JSON.stringify(err)); 58 | }; 59 | odatajs.oData.read(request, successFunction, failFunction); 60 | }; 61 | 62 | var runSimpleReadRequestWithMetadata = function () { 63 | var oHeaders = { 64 | 'Accept': 'text/html,application/xhtml+xml,application/xml,application/json;odata.metadata=minimal', 65 | "Odata-Version": "4.0", 66 | "OData-MaxVersion": "4.0", 67 | "Prefer": "odata.allow-entityreferences" 68 | }; 69 | 70 | var readMetadataSuccess = function (metadata) { 71 | document.getElementById("metadata").innerHTML = JSON.stringify(metadata, undefined, 2); 72 | var request = 73 | { 74 | headers: oHeaders, 75 | // requestUri: "http://services.odata.org/OData/OData.svc/Categories", 76 | requestUri: "http://odatasampleservices.azurewebsites.net/V4/OData/OData.svc/Products", 77 | data: null, 78 | }; 79 | var successFunction = function(data) { 80 | document.getElementById("simpleReadWithMetadata").innerHTML = JSON.stringify(data, undefined, 2); 81 | }; 82 | var failFunction = function(err) { 83 | alert("err"); 84 | alert(JSON.stringify(err)); 85 | }; 86 | odatajs.oData.read(request, successFunction, failFunction, null, null, metadata); 87 | }; 88 | 89 | var readMetadataFail = function (err) { 90 | alert("err"); 91 | alert(JSON.stringify(err)); 92 | }; 93 | 94 | var metadataRequest = 95 | { 96 | headers: oHeaders, 97 | // requestUri: "http://services.odata.org/OData/OData.svc/$metadata", 98 | requestUri: "http://odatasampleservices.azurewebsites.net/V4/OData/OData.svc/$metadata", 99 | // "http://localhost:6630/PrimitiveKeys.svc/$metadata", 100 | data: null, 101 | }; 102 | 103 | odatajs.oData.read(metadataRequest, readMetadataSuccess, readMetadataFail, odatajs.V4.oData.metadataHandler); 104 | }; 105 | 106 | var readWithJsonP = function() { 107 | var sUrl2 = "http://odatasampleservices.azurewebsites.net/V4/OData/OData.svc?$expand=Category"; 108 | 109 | var oRequest = { 110 | requestUri: sUrl2, 111 | enableJsonpCallback: true, 112 | }; 113 | 114 | odatajs.oData.read(oRequest, function (data) { 115 | document.getElementById("simpleReadWithJSONP").innerHTML = JSON.stringify(data, undefined, 2); 116 | }, 117 | function (oError) { 118 | alert(oError.message); 119 | }); 120 | }; 121 | 122 | var testJQueryReadMetadata = function () { 123 | $.ajax({ 124 | url: "http://odatasampleservices.azurewebsites.net/V4/OData/OData.svc/$metadata", 125 | headers: { 126 | 'Accept': 'text/html,application/xhtml+xml,application/xml,application/json;odata.metadata=full', 127 | "Odata-Version": "4.0", 128 | "OData-MaxVersion": "4.0", 129 | "Prefer": "odata.allow-entityreferences" 130 | }, 131 | type: "GET", 132 | converters: { "text xml": OData.metadataParser }, 133 | dataType: "xml", 134 | success: function (xml, textStatus, jqXHR) { 135 | var data = OData.metadataParser2(xml) || undefined; 136 | document.getElementById("simpleReadWithMetadata").innerHTML = JSON.stringify(data, undefined, 2); 137 | }, 138 | error: function (jqXHR, textStatus, errorThrown) { 139 | alert("err"); 140 | } 141 | }); 142 | }; 143 | -------------------------------------------------------------------------------- /grunt-config/banner.txt: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | -------------------------------------------------------------------------------- /grunt-config/custom-tasks/rat.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | //rat is written as like a npm module so include the /rat/tasks folder 21 | module.exports = function(grunt) { 22 | require('./rat/tasks/rat.js')(grunt); 23 | }; 24 | -------------------------------------------------------------------------------- /grunt-config/custom-tasks/rat/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | -------------------------------------------------------------------------------- /grunt-config/custom-tasks/rat/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "grunt-rat", 3 | "version": "0.0.1", 4 | "description": "Run Apache Rat(release audit tool)", 5 | "license": "Apache", 6 | "author": { 7 | "name": "Sven Kobler-Morris", 8 | "email": "koblers@apache.org" 9 | }, 10 | "files": [ 11 | "tasks" 12 | ], 13 | "dependencies": { 14 | "chalk": "~0.4.0" 15 | }, 16 | "devDependencies": { 17 | "async": "0.9.0", 18 | "grunt": "0.4.0", 19 | "xml2js": "0.4.4" 20 | }, 21 | "engines": { 22 | "node": ">=0.8.0" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /grunt-config/custom-tasks/rat/readme.md: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | Download "apache-rat-0.11-bin.zip" from http://creadur.apache.org/rat/download_rat.cgi and unpack it to 20 | "_extern-tools/apache-rat-0.11" 21 | 22 | "apache-rat-0.11.jar" must be located in ./_extern-tools/apache-rat-0.11/apache-rat-0.11.jar 23 | ( full path from git root /odatajs/grunt-config/custom-tasks/rat/_extern-tools/apache-rat-0.11/apache-rat-0.11.jar) -------------------------------------------------------------------------------- /grunt-config/custom-tasks/rat/tasks/rat.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | module.exports = function (grunt) { 21 | grunt.registerMultiTask('rat', 'Run Apache Rat', function () { 22 | var async = require("async"); 23 | var chalk = require('chalk'); 24 | var childProcess = require('child_process'); 25 | var path = require('path'); 26 | var fs = require('fs'); 27 | var xml2js = require('xml2js'); 28 | 29 | var globalCB = this.async(); 30 | 31 | var ratJarFile = path.resolve(__dirname,'./../_extern-tools/apache-rat-0.11/apache-rat-0.11.jar'); 32 | var options = this.options({ xml : true, dest : './_dist/tmp'}); 33 | 34 | //check output directory 35 | if(!fs.existsSync(options.dest)){ 36 | grunt.file.mkdir(options.dest,0766); 37 | } 38 | 39 | //collect directories which should be checked 40 | var checkDirs = []; 41 | for(var i = 0; i < this.files.length; i++) { 42 | for(var ii = 0; ii < this.files[i].src.length; ii++) { 43 | var checkDir = { 44 | dir : this.files[i].src[ii], 45 | options : { 46 | xml : options.xml, 47 | dest : options.dest, 48 | tag : this.files[i].options.tag, 49 | exclude : options.exclude || this.files[i].options.exclude 50 | } 51 | }; 52 | checkDirs.push(checkDir); 53 | } 54 | } 55 | 56 | var processDirectory = function processDirectory(data,cb) { 57 | var checkDir = data.dir; 58 | var options = data.options; 59 | var outPutFile = options.dest + '/'+ 'rat_' + (options.tag ? options.tag:'') + (options.xml ? '.xml' : '.txt'); 60 | 61 | //sample command java -jar apache-rat-0.10.jar -x -d ./src > ./_dist/tmp/rat.txt 62 | var cmd = 'java -jar ' + ratJarFile+ ' '; 63 | cmd += options.xml ? ' -x' : ''; 64 | cmd += ' --force -d ' + checkDir; 65 | //cmd += ' -E ./grunt-config/custom-tasks/rat/.rat-excludes' 66 | if (options.exclude) { 67 | for (var i = 0; i< options.exclude.length; i ++) { 68 | cmd += ' -e '+ options.exclude[i]; 69 | } 70 | } 71 | cmd += ' > ' + outPutFile; 72 | 73 | grunt.verbose.writeln('Command:', chalk.yellow(cmd)); 74 | var cp = childProcess.exec(cmd, options.execOptions, function (error, stdout, stderr) { 75 | if (error) { 76 | grunt.fail.warn('rat --> ' + error, 1); //exit grunt with error code 1 77 | } 78 | checkOutFile(outPutFile,data,cb); 79 | }); 80 | }; 81 | 82 | var checkOutFile = function(outFile,data,cb) { 83 | //check out files 84 | if (path.extname(outFile) !== '.xml') { 85 | //grunt.log.writeln(chalk.yellow('\nrat --> ' + 'No XML output: ('+outFile+') skipped!\n')); 86 | cb(); 87 | return; 88 | } 89 | 90 | var xml = grunt.file.read(outFile); 91 | var parser = new xml2js.Parser(); 92 | 93 | parser.parseString(xml, function (err, result) { 94 | if (err) { 95 | grunt.fail.warn('rat --> XML parse error: ' + err, 1); 96 | } 97 | 98 | if (checkRatLogFile(result)) { 99 | grunt.fail.warn('rat --> check license error: ' + 'Missing or Invalied license header detected ( see "'+outFile+'")', 1); 100 | } 101 | 102 | grunt.log.ok('rat --> check on ' + data.dir + ' ok -> see' + outFile); 103 | }); 104 | cb(); 105 | }; 106 | 107 | var checkRatLogFile = function(result) { 108 | var list = result['rat-report']['resource']; 109 | for (var i = 0; i < list.length; i++ ){ 110 | var item = list[i]; 111 | 112 | var headerType = list[i]['header-type']; 113 | var attr = headerType[0]['$']; 114 | if (attr.name.trim() !== 'AL') { 115 | return true; 116 | } 117 | } 118 | return false; 119 | }; 120 | 121 | var captureOutput = function (child, output) { 122 | if (grunt.option('color') === false) { 123 | child.on('data', function (data) { 124 | output.write(chalk.stripColor(data)); 125 | }); 126 | } else { 127 | child.pipe(output); 128 | } 129 | }; 130 | 131 | //files 132 | async.each(checkDirs, 133 | function (checkDir,cb) { 134 | processDirectory(checkDir,cb); 135 | }, 136 | function(err) { 137 | grunt.log.ok('rat --> finished'); 138 | globalCB(); 139 | } 140 | ); 141 | 142 | 143 | /* 144 | captureOutput(cp.stdout, process.stdout); 145 | captureOutput(cp.stderr, process.stderr); 146 | 147 | if (options.stdin) { 148 | process.stdin.resume(); 149 | process.stdin.setEncoding('utf8'); 150 | process.stdin.pipe(cp.stdin); 151 | }*/ 152 | }); 153 | }; 154 | 155 | -------------------------------------------------------------------------------- /grunt-config/custom-tasks/sign.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | module.exports = function(grunt) { 21 | 22 | grunt.registerMultiTask('sign', function() { 23 | var self = this; 24 | 25 | var path = require('path'); 26 | var fs = require( 'fs' ); 27 | var chalk = require('./rat/node_modules/chalk'); 28 | 29 | var globalDone = this.async(); 30 | 31 | var options = this.options({ types : [] }); 32 | var workLoad = []; 33 | var writeToLogOk = function(data) { grunt.log.ok(data.toString()); }; 34 | //console.log("this.files" +JSON.stringify(this.files)); 35 | // fill workLoad 36 | for(var i = 0; i < this.files.length; i++) { 37 | for(var ii = 0; ii < this.files[i].src.length; ii++) { 38 | for (var iii = 0; iii < options.types.length; iii++) { 39 | workLoad.push({ 40 | src :this.files[i].src[ii], 41 | type: options.types[iii] 42 | }); 43 | } 44 | } 45 | } 46 | 47 | function process() { 48 | if(workLoad.length <= 0) { 49 | globalDone(); 50 | return; 51 | } 52 | 53 | var workItem = workLoad.pop(); 54 | // make source file releative to cwd, since cwd is used as workdir from spawn 55 | var fileName = path.relative(self.data.cwd,workItem.src); 56 | var taskOptions,pipeTo,pipeSrc = 'out'; 57 | console.log (fileName); 58 | if ( workItem.type === 'md5' ) { 59 | pipeTo = workItem.src+'.md5'; 60 | 61 | grunt.log.writeln(chalk.yellow('Signing ('+workItem.type+') ' + fileName + " ...")); 62 | //openssl dgst -md5 odatajs.4.0.0.nupkg 63 | taskOptions = { 64 | cmd : 'openssl', 65 | args: ['dgst','-md5',fileName], 66 | opts : { cwd :self.data.cwd } 67 | }; 68 | } else if ( workItem.type === 'sha' ) { 69 | pipeTo = workItem.src+'.sha'; 70 | 71 | grunt.log.writeln(chalk.yellow('Signing ('+workItem.type+') ' + fileName + " ...")); 72 | 73 | //gpg --print-md SHA512 odatajs-4.0.0-doc.zip 74 | taskOptions = { 75 | cmd : 'gpg', 76 | args: ['--print-md','SHA512',fileName], 77 | opts : { cwd :self.data.cwd } 78 | }; 79 | } else if ( workItem.type === 'asc' ) { 80 | pipeTo = undefined; // done by gpg 81 | 82 | grunt.log.writeln(chalk.yellow('Signing ('+workItem.type+') ' + fileName + " ...")); 83 | 84 | //gpg --armor --detach-sign odatajs-4.0.0-sources.zip 85 | taskOptions = { 86 | cmd : 'gpg', 87 | args: ['--armor','--detach-sign',fileName], 88 | opts : { cwd :self.data.cwd } 89 | }; 90 | } else if ( workItem.type === 'asc-verify' ) { 91 | pipeTo = 'console'; 92 | pipeSrc = 'err'; 93 | 94 | grunt.log.writeln(chalk.yellow('Verify ('+workItem.type+') ' +fileName+ '.asc' + " ...")); 95 | 96 | //gpg --verify --detach-sign odatajs-4.0.0-sources.zip.asc 97 | taskOptions = { 98 | cmd : 'gpg', 99 | args: ['--verify', fileName+'.asc'], 100 | opts : { cwd :self.data.cwd } 101 | }; 102 | } else { 103 | grunt.fail.warn('Unknown sign type: "'+ workItem.type + '"', 1); 104 | } 105 | 106 | //console.log(taskOptions); 107 | 108 | var task = grunt.util.spawn(taskOptions, function done(err,result) { 109 | if (err) { 110 | grunt.fail.warn('Sign: '+err); 111 | } 112 | }); 113 | 114 | 115 | 116 | if (pipeTo) { 117 | if (pipeTo === 'console') { 118 | if (pipeSrc ==='err') { 119 | task.stderr.on('data', writeToLogOk ); 120 | } else { 121 | task.stdout.on('data', writeToLogOk); 122 | } 123 | } else { 124 | var outStream = fs.createWriteStream(pipeTo/* ,{flags: 'w'}*/); 125 | var src = (pipeSrc ==='err') ? task.stderr : task.stdout; 126 | src.pipe(outStream, { end: false }); 127 | } 128 | } 129 | 130 | task.on('close', function (code) { 131 | grunt.log.ok('Processed ('+workItem.type+') :' + workItem.src); 132 | grunt.log.ok('with code ' + code); 133 | process(); 134 | }); 135 | 136 | } 137 | 138 | process(); 139 | }); 140 | }; 141 | 142 | -------------------------------------------------------------------------------- /grunt-config/custom-tasks/toBrowser.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | 21 | module.exports = function(grunt) { 22 | require('./toBrowser/toBrowser.js')(grunt); 23 | }; 24 | -------------------------------------------------------------------------------- /grunt-config/custom-tasks/toBrowser/toBrowser.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | module.exports = function(grunt) { 21 | 22 | var stripHeader = function(input) { 23 | return input.replace(/(\/\*(.|\n|\r)*?\*\/)/i,""); 24 | }; 25 | 26 | grunt.registerMultiTask('toBrowser', function() { 27 | var self = this; 28 | 29 | var path = require('path'); 30 | var fs = require( 'fs' ); 31 | 32 | var globalDone = this.async(); 33 | 34 | var options = this.options({ }); 35 | 36 | var workLoad = []; 37 | var writeToLogOk = function(data) { grunt.log.ok(data.toString()); }; 38 | 39 | 40 | // fill workLoad 41 | for(var i = 0; i < this.files.length; i++) { 42 | for(var ii = 0; ii < this.files[i].src.length; ii++) { 43 | 44 | 45 | var srcFile = this.files[i].src[ii]; 46 | 47 | var srcPath = srcFile.substring(0,srcFile.lastIndexOf('/')+1); 48 | var srcName = srcFile.substring(srcFile.lastIndexOf('/')+1,srcFile.length-3); 49 | 50 | //console.log('exists :'+srcPath+srcName+'-browser.js' ); 51 | tarName = srcName; 52 | if (srcName.indexOf('-browser') > 0) { 53 | tarName = tarName.substring(0,srcName.indexOf('-browser')); 54 | //console.log('new srcName :'+srcName ); 55 | } else if (grunt.file.exists(srcPath+srcName+'-browser.js')) { 56 | //console.log('exists :yes'); 57 | continue; //skip that file 58 | } 59 | 60 | 61 | workLoad.push({ 62 | srcPath : srcPath, 63 | srcName : srcName, 64 | tarName : tarName 65 | }); 66 | 67 | } 68 | 69 | var concat = '{'; 70 | for(var x = 0; x < workLoad.length; x++) { 71 | console.log('workLoad :'+JSON.stringify(workLoad[x] )); 72 | var src = grunt.file.read(workLoad[x].srcPath+workLoad[x].srcName+'.js'); 73 | // remove the first comment 74 | src = stripHeader(src); 75 | 76 | if (x > 0) { 77 | concat+= ', '; 78 | } 79 | 80 | concat+= '"' + workLoad[x].tarName + '" : '; 81 | concat+= 'function(exports, module, require) {'; 82 | concat+= src +'}'; 83 | } 84 | concat+= '}'; 85 | 86 | var tpl = grunt.file.read('./grunt-config/custom-tasks/toBrowser/wrapper-tpl.js'); 87 | var init = stripHeader(grunt.file.read(options.index)); 88 | 89 | tpl = tpl.replace('\'<% initFunction %>\'',init); 90 | tpl = tpl.replace('\'<% filesAsFunctionList %>\'',concat); 91 | 92 | grunt.file.write(this.files[i].dest, tpl); 93 | } 94 | 95 | globalDone(); 96 | }); 97 | }; 98 | 99 | -------------------------------------------------------------------------------- /grunt-config/custom-tasks/toBrowser/wrapper-tpl.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | var init = function(exports, module, require) { 20 | '<% initFunction %>' 21 | }; 22 | 23 | var datas = '<% filesAsFunctionList %>'; 24 | 25 | var modules = {}; 26 | 27 | var require = function(path) { 28 | var name = path.substring(path.lastIndexOf('/')+1,path.length-3); 29 | if (modules[name]) { return modules[name].exports; } 30 | 31 | modules[name] = { exports : {}}; 32 | datas[name].call(this,modules[name].exports,modules[name],require); 33 | return modules[name].exports; 34 | }; 35 | 36 | window.odatajs = {}; 37 | init.call(this,window.odatajs,window.odatajs,require); 38 | 39 | 40 | -------------------------------------------------------------------------------- /grunt-config/nugetpack.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Olingo OData Client for JavaScript 5 | odatajs 6 | restful api open protocol odata client javascript 7 | 4.0.0 8 | Apache Olingo (Challen He, Kobler-Morris Sven) 9 | Apache Olingo 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | Copyright 2014 The Apache Software Foundation 12 | http://olingo.apache.org/ 13 | http://olingo.apache.org/img/OlingoOrangeTM.png 14 | true 15 | JavaScript library to easily interact with OData V4 service. 16 | Olingo OData Client for JavaScript (odatajs) is a lightweight cross-browser JavaScript library that enables web browser to consume and interact with OData V4 service. 17 | 18 | This odatajs library for OData V4 is a new version based on datajs(http://datajs.codeplex.com/) which is for OData V3. 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /grunt-config/rat-config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | module.exports = function(grunt) { 21 | 22 | 23 | grunt.config('rat', { 24 | dist: { 25 | options: { 26 | dest : './_build/tmp', 27 | exclude: [ 28 | "node_modules","_extern-tools",".gitignore","package.json","JSLib", 29 | "DEPENDENCIES","LICENSE","NOTICE", 30 | "JSLib.sln","package.json", "mocha.opts","info.txt","olingo-odata4-js.iml" 31 | ] }, 32 | files: [ 33 | /*{ src: ['./../_dist/<%= artifactname %>/doc'], options:{ tag:"dist-doc"}},generated*/ 34 | { src: ['./lib'], options:{ tag:"lib"}}, 35 | { src: ['./tests'], options:{ tag:"tests"}}, 36 | { src: ['./demo'], options:{ tag:"demo"}}, 37 | { src: ['./grunt-config'], options:{ tag:"grunt-config" }}, 38 | { src: ['./_dist/<%= artifactname %>/lib'], options:{ tag:"dist-lib"}}, 39 | { src: ['./_dist/<%= artifactname %>/sources'], options:{ tag:"dist-src"}} 40 | ] 41 | }, 42 | manual: { // with txt output 43 | options: { xml:false, 44 | dest : './_build/tmp', 45 | exclude: [ 46 | "node_modules","_extern-tools",".gitignore","package.json","JSLib", 47 | "DEPENDENCIES","LICENSE","NOTICE", 48 | "JSLib.sln","package.json", "mocha.opts","info.txt","olingo-odata4-js.iml" 49 | ] }, 50 | files: [ 51 | { src: ['./lib'], options:{ tag:"lib"}}, 52 | { src: ['./tests'], options:{ tag:"tests"}}, 53 | { src: ['./demo'], options:{ tag:"demo"}}, 54 | { src: ['./grunt-config'], options:{ tag:"grunt-config" }}, 55 | { src: ['./_dist/<%= artifactname %>/lib'], options:{ tag:"dist-lib"}}, 56 | { src: ['./_dist/<%= artifactname %>/sources'], options:{ tag:"dist-src"}} 57 | ] 58 | } 59 | }); 60 | 61 | 62 | }; -------------------------------------------------------------------------------- /grunt-config/release-config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | module.exports = function(grunt) { 20 | 21 | function endsWith(hay, needle) { 22 | return hay.indexOf(needle, hay.length - needle.length) !== -1; 23 | } 24 | 25 | function startsWith(hay, needle) { 26 | return hay.indexOf(needle) === 0; 27 | } 28 | 29 | function contains(hay, needle) { 30 | return hay.indexOf(needle) > -1; 31 | } 32 | 33 | 34 | 35 | // clean 36 | grunt.config.merge( { 37 | 'priv-clean': { 38 | 'release-dist': { 39 | options: { force: true }, 40 | src: [ "./_dist/<%= artifactname %>*"] 41 | } 42 | } 43 | }); 44 | 45 | grunt.loadNpmTasks("grunt-contrib-clean"); 46 | 47 | // doc 48 | grunt.config.merge( { 49 | 'jsdoc' : { // generate documentation 50 | "release-doc-src" : { 51 | src: ['**/*.js'], 52 | options: { 53 | destination: './_dist/<%= artifactname %>/doc', 54 | verbose : false 55 | } 56 | } 57 | } 58 | }); 59 | 60 | // copy 61 | grunt.config.merge( { 62 | "copy" : { 63 | "release-lib" : { 64 | files: [ 65 | { expand: true, cwd: '_build/lib', src: ['<%= artifactname %>*.*'], dest: './_dist/<%= artifactname %>/lib/lib', filter: 'isFile'}, 66 | { expand: true, src :'LICENSE',dest: './_dist/<%= artifactname %>/lib', filter: 'isFile' }, 67 | { expand: true, src :'NOTICE',dest: './_dist/<%= artifactname %>/lib', filter: 'isFile' }, 68 | { expand: true, src :'DEPENDENCIES',dest: './_dist/<%= artifactname %>/lib', filter: 'isFile' }, 69 | { expand: true, src :'README.md',dest: './_dist/<%= artifactname %>/lib', filter: 'isFile' } 70 | ] 71 | }, 72 | "release-nuget": { 73 | files: [ 74 | { expand: true, cwd: '_build', src: ['odatajs.4.0.0.nupkg'], dest: './_dist/<%= artifactname %>', filter: 'isFile' }, 75 | ] 76 | }, 77 | "release-doc" : { 78 | files: [ 79 | { expand: true, cwd: '_build/doc-src', src: ['**'], dest: './_dist/<%= artifactname %>/doc/doc', filter: 'isFile'}, 80 | { expand: true, src :'LICENSE',dest: './_dist/<%= artifactname %>/doc', filter: 'isFile' }, 81 | { expand: true, src :'NOTICE',dest: './_dist/<%= artifactname %>/doc', filter: 'isFile' }, 82 | { expand: true, src :'DEPENDENCIES',dest: './_dist/<%= artifactname %>/doc', filter: 'isFile' }, 83 | { expand: true, src :'README.md',dest: './_dist/<%= artifactname %>/doc', filter: 'isFile' } 84 | ] 85 | }, 86 | "release-sources" : { 87 | files: [ 88 | { expand: true, src :'LICENSE',dest: './_dist/<%= artifactname %>/sources', filter: 'isFile' }, 89 | { expand: true, src :'NOTICE',dest: './_dist/<%= artifactname %>/sources', filter: 'isFile' }, 90 | { expand: true, src :'DEPENDENCIES',dest: './_dist/<%= artifactname %>/sources', filter: 'isFile' }, 91 | { dot: true, expand: true, cwd: './', src: ['**'], dest: './_dist/<%= artifactname %>/sources/odatajs', 92 | filter: function(srcPath) { 93 | // no node_modules 94 | if (srcPath === 'node_modules' || contains(srcPath, 'node_modules')) { 95 | return false; 96 | } 97 | if (srcPath === '_extern-tools' || contains(srcPath, '_extern-tools')) { 98 | return false; 99 | } 100 | 101 | if (contains(srcPath, 'demo\\scripts\\datajs-') || 102 | contains(srcPath, 'demo/scripts/datajs-')) { 103 | return false; 104 | } 105 | if (contains(srcPath, 'demo\\scripts\\odatajs-') || 106 | contains(srcPath, 'demo/scripts/odatajs-')) { 107 | return false; 108 | } 109 | 110 | // no c# files 111 | if (srcPath === 'obj' || contains(srcPath, 'obj')|| contains(srcPath, 'obj')) { 112 | return false; 113 | } 114 | 115 | if (srcPath === 'bin' || contains(srcPath, 'bin')|| contains(srcPath, 'bin')) { 116 | return false; 117 | } 118 | 119 | if (srcPath === 'packages' || contains(srcPath, 'packages')|| contains(srcPath, 'packages')) { 120 | return false; 121 | } 122 | 123 | // no IDE stuff 124 | if (srcPath === '.idea' || contains(srcPath, '.idea')|| contains(srcPath, '.idea')) { 125 | return false; 126 | } 127 | 128 | // no build results 129 | if (srcPath === '_build' || contains(srcPath, '_build')|| contains(srcPath, '_build')) { 130 | return false; 131 | } 132 | if (srcPath === '_dist' || contains(srcPath, '_dist')|| contains(srcPath, '_dist')) { 133 | return false; 134 | } 135 | 136 | if (srcPath === '.git' || contains(srcPath, '.git')|| contains(srcPath, '.git')) { 137 | return false; 138 | } 139 | 140 | if (endsWith(srcPath, '.gitignore')) { 141 | return false; 142 | } 143 | if (endsWith(srcPath, 'localgrunt.config')) { 144 | return false; 145 | } 146 | if (endsWith(srcPath, 'JSLib.suo')) { 147 | return false; 148 | } 149 | if (endsWith(srcPath, 'JSLib.csproj.user')) { 150 | return false; 151 | } 152 | 153 | console.log(' + ' + srcPath); 154 | return true; 155 | }}, 156 | ] 157 | } 158 | } 159 | }); 160 | 161 | grunt.loadNpmTasks("grunt-contrib-copy"); 162 | 163 | 164 | 165 | 166 | // zip 167 | grunt.config.merge( { 168 | compress: { // build the zip files for the release 169 | 'release-lib': { // just the lib 170 | options: {archive: './_dist/<%= artifactname %>/<%= artifactname %>-lib.zip'}, 171 | files: [{expand: true, cwd: './_dist/<%= artifactname %>/lib', src: ['**'], dest: '/'}] 172 | }, 173 | 'release-doc': { // just the documentation 174 | options: {archive: './_dist/<%= artifactname %>/<%= artifactname %>-doc.zip'}, 175 | files: [{expand: true, cwd: './_dist/<%= artifactname %>/doc', src: ['**'], dest: '/'}] 176 | }, 177 | 'release-sources' : { // the full repository with out the git stuff 178 | options: { archive: './_dist/<%= artifactname %>/<%= artifactname %>-sources.zip'}, 179 | files: [ 180 | {expand: true, cwd: './_dist/<%= artifactname %>/sources', src: ['**'], dest: '/'}, 181 | ] 182 | } 183 | } 184 | }); 185 | 186 | 187 | grunt.loadNpmTasks('grunt-contrib-compress'); 188 | 189 | }; 190 | 191 | -------------------------------------------------------------------------------- /grunt-config/sign-config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | module.exports = function(grunt) { 20 | 21 | 22 | //sign 23 | grunt.config.merge( { 24 | 'sign' : { 25 | 'release' : { 26 | options: { types : ['md5', 'sha']}, 27 | expand : true, 28 | cwd : './_dist/<%= artifactname %>/', 29 | src : [ 30 | '<%= artifactname %>-lib.zip', 31 | 'odatajs.4.0.0.nupkg', 32 | '<%= artifactname %>-doc.zip', 33 | '<%= artifactname %>-sources.zip' 34 | ] 35 | }, 36 | 'asc' : { 37 | options: { types : ['asc']}, 38 | expand : true, 39 | cwd : './_dist/<%= artifactname %>/', 40 | src : [ 41 | '<%= artifactname %>-lib.zip', 42 | 'odatajs.4.0.0.nupkg', 43 | '<%= artifactname %>-doc.zip', 44 | '<%= artifactname %>-sources.zip' 45 | ] 46 | }, 47 | 'asc-verify' : { 48 | options: { types : ['asc-verify']}, 49 | expand : true, 50 | cwd : './_dist/<%= artifactname %>/', 51 | src : [ 52 | '<%= artifactname %>-lib.zip', 53 | 'odatajs.4.0.0.nupkg', 54 | '<%= artifactname %>-doc.zip', 55 | '<%= artifactname %>-sources.zip' 56 | ] 57 | } 58 | }, 59 | }); 60 | }; 61 | 62 | -------------------------------------------------------------------------------- /index-browser.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | // version information 21 | exports.version = { major: 4, minor: 0, build: 0 }; 22 | 23 | // core stuff, always needed 24 | exports.deferred = require('./lib/deferred.js'); 25 | exports.utils = require('./lib/utils.js'); 26 | 27 | // only needed for xml metadata 28 | exports.xml = require('./lib/xml.js'); 29 | 30 | // only need in browser case 31 | exports.oData = require('./lib/odata.js'); 32 | exports.store = require('./lib/store.js'); 33 | exports.cache = require('./lib/cache.js'); 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | var odatajs = {}; 21 | 22 | odatajs.version = { 23 | major: 4, 24 | minor: 0, 25 | build: 0 26 | }; 27 | 28 | // core stuff, alway needed 29 | odatajs.deferred = require('./lib/deferred.js'); 30 | odatajs.utils = require('./lib/utils.js'); 31 | 32 | // only neede for xml metadata 33 | odatajs.xml = require('./lib/xml.js'); 34 | 35 | // only need in browser case 36 | odatajs.oData = require('./lib/odata.js'); 37 | odatajs.store = require('./lib/store.js'); 38 | odatajs.cache = require('./lib/cache.js'); 39 | 40 | if (typeof window !== 'undefined') { 41 | //expose to browsers window object 42 | window.odatajs = odatajs; 43 | } else { 44 | //expose in commonjs style 45 | odatajs.node = "node"; 46 | module.exports = odatajs; 47 | } 48 | -------------------------------------------------------------------------------- /lib/cache/source.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 'use strict'; 20 | 21 | /** @module cache/source */ 22 | 23 | var utils = require("./../utils.js"); 24 | var odataRequest = require("./../odata.js"); 25 | 26 | var parseInt10 = utils.parseInt10; 27 | var normalizeURICase = utils.normalizeURICase; 28 | 29 | 30 | 31 | 32 | /** Appends the specified escaped query option to the specified URI. 33 | * @param {String} uri - URI to append option to. 34 | * @param {String} queryOption - Escaped query option to append. 35 | */ 36 | function appendQueryOption(uri, queryOption) { 37 | var separator = (uri.indexOf("?") >= 0) ? "&" : "?"; 38 | return uri + separator + queryOption; 39 | } 40 | 41 | /** Appends the specified segment to the given URI. 42 | * @param {String} uri - URI to append a segment to. 43 | * @param {String} segment - Segment to append. 44 | * @returns {String} The original URI with a new segment appended. 45 | */ 46 | function appendSegment(uri, segment) { 47 | var index = uri.indexOf("?"); 48 | var queryPortion = ""; 49 | if (index >= 0) { 50 | queryPortion = uri.substr(index); 51 | uri = uri.substr(0, index); 52 | } 53 | 54 | if (uri[uri.length - 1] !== "/") { 55 | uri += "/"; 56 | } 57 | return uri + segment + queryPortion; 58 | } 59 | 60 | /** Builds a request object to GET the specified URI. 61 | * @param {String} uri - URI for request. 62 | * @param {Object} options - Additional options. 63 | */ 64 | function buildODataRequest(uri, options) { 65 | return { 66 | method: "GET", 67 | requestUri: uri, 68 | user: options.user, 69 | password: options.password, 70 | enableJsonpCallback: options.enableJsonpCallback, 71 | callbackParameterName: options.callbackParameterName, 72 | formatQueryString: options.formatQueryString 73 | }; 74 | } 75 | 76 | /** Finds the index where the value of a query option starts. 77 | * @param {String} uri - URI to search in. 78 | * @param {String} name - Name to look for. 79 | * @returns {Number} The index where the query option starts. 80 | */ 81 | function findQueryOptionStart(uri, name) { 82 | var result = -1; 83 | var queryIndex = uri.indexOf("?"); 84 | if (queryIndex !== -1) { 85 | var start = uri.indexOf("?" + name + "=", queryIndex); 86 | if (start === -1) { 87 | start = uri.indexOf("&" + name + "=", queryIndex); 88 | } 89 | if (start !== -1) { 90 | result = start + name.length + 2; 91 | } 92 | } 93 | return result; 94 | } 95 | 96 | /** Gets data from an OData service. 97 | * @param {String} uri - URI to the OData service. 98 | * @param {Object} options - Object with additional well-known request options. 99 | * @param {Function} success - Success callback. 100 | * @param {Function} error - Error callback. 101 | * @returns {Object} Object with an abort method. 102 | */ 103 | function queryForData (uri, options, success, error) { 104 | return queryForDataInternal(uri, options, {}, success, error); 105 | } 106 | 107 | /** Gets data from an OData service taking into consideration server side paging. 108 | * @param {String} uri - URI to the OData service. 109 | * @param {Object} options - Object with additional well-known request options. 110 | * @param {Array} data - Array that stores the data provided by the OData service. 111 | * @param {Function} success - Success callback. 112 | * @param {Function} error - Error callback. 113 | * @returns {Object} Object with an abort method. 114 | */ 115 | function queryForDataInternal(uri, options, data, success, error) { 116 | 117 | var request = buildODataRequest(uri, options); 118 | var currentRequest = odataRequest.request(request, function (newData) { 119 | var nextLink = newData["@odata.nextLink"]; 120 | if (nextLink) { 121 | var index = uri.indexOf(".svc/", 0); 122 | if (index != -1) { 123 | nextLink = uri.substring(0, index + 5) + nextLink; 124 | } 125 | } 126 | 127 | if (data.value && newData.value) { 128 | data.value = data.value.concat(newData.value); 129 | } 130 | else { 131 | for (var property in newData) { 132 | if (property != "@odata.nextLink") { 133 | data[property] = newData[property]; 134 | } 135 | } 136 | } 137 | 138 | if (nextLink) { 139 | currentRequest = queryForDataInternal(nextLink, options, data, success, error); 140 | } 141 | else { 142 | success(data); 143 | } 144 | }, error, undefined, options.httpClient, options.metadata); 145 | 146 | return { 147 | abort: function () { 148 | currentRequest.abort(); 149 | } 150 | }; 151 | } 152 | 153 | /** Creates a data cache source object for requesting data from an OData service. 154 | * @class ODataCacheSource 155 | * @param options - Options for the cache data source. 156 | * @returns {ODataCacheSource} A new data cache source instance. 157 | */ 158 | function ODataCacheSource (options) { 159 | var that = this; 160 | var uri = options.source; 161 | 162 | that.identifier = normalizeURICase(encodeURI(decodeURI(uri))); 163 | that.options = options; 164 | 165 | /** Gets the number of items in the collection. 166 | * @method ODataCacheSource#count 167 | * @param {Function} success - Success callback with the item count. 168 | * @param {Function} error - Error callback. 169 | * @returns {Object} Request object with an abort method. 170 | */ 171 | that.count = function (success, error) { 172 | var options = that.options; 173 | return odataRequest.request( 174 | buildODataRequest(appendSegment(uri, "$count"), options), 175 | function (data) { 176 | var count = parseInt10(data.toString()); 177 | if (isNaN(count)) { 178 | error({ message: "Count is NaN", count: count }); 179 | } else { 180 | success(count); 181 | } 182 | }, error, undefined, options.httpClient, options.metadata 183 | ); 184 | }; 185 | 186 | /** Gets a number of consecutive items from the collection. 187 | * @method ODataCacheSource#read 188 | * @param {Number} index - Zero-based index of the items to retrieve. 189 | * @param {Number} count - Number of items to retrieve. 190 | * @param {Function} success - Success callback with the requested items. 191 | * @param {Function} error - Error callback. 192 | * @returns {Object} Request object with an abort method. 193 | */ 194 | that.read = function (index, count, success, error) { 195 | 196 | var queryOptions = "$skip=" + index + "&$top=" + count; 197 | return queryForData(appendQueryOption(uri, queryOptions), that.options, success, error); 198 | }; 199 | 200 | return that; 201 | } 202 | 203 | 204 | 205 | /** ODataCacheSource (see {@link ODataCacheSource}) */ 206 | exports.ODataCacheSource = ODataCacheSource; -------------------------------------------------------------------------------- /lib/deferred.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 'use strict'; 20 | 21 | /** @module odatajs/deferred */ 22 | 23 | 24 | 25 | /** Creates a new function to forward a call. 26 | * @param {Object} thisValue - Value to use as the 'this' object. 27 | * @param {String} name - Name of function to forward to. 28 | * @param {Object} returnValue - Return value for the forward call (helps keep identity when chaining calls). 29 | * @returns {Function} A new function that will forward a call. 30 | */ 31 | function forwardCall(thisValue, name, returnValue) { 32 | return function () { 33 | thisValue[name].apply(thisValue, arguments); 34 | return returnValue; 35 | }; 36 | } 37 | 38 | /** Initializes a new DjsDeferred object. 39 | * 61 | * @class DjsDeferred 62 | */ 63 | function DjsDeferred() { 64 | this._arguments = undefined; 65 | this._done = undefined; 66 | this._fail = undefined; 67 | this._resolved = false; 68 | this._rejected = false; 69 | } 70 | 71 | 72 | DjsDeferred.prototype = { 73 | 74 | /** Adds success and error callbacks for this deferred object. 75 | * See Compatibility Note A. 76 | * @method DjsDeferred#then 77 | * @param {function} [fulfilledHandler] - Success callback ( may be null) 78 | * @param {function} [errorHandler] - Error callback ( may be null) 79 | */ 80 | then: function (fulfilledHandler, errorHandler) { 81 | 82 | if (fulfilledHandler) { 83 | if (!this._done) { 84 | this._done = [fulfilledHandler]; 85 | } else { 86 | this._done.push(fulfilledHandler); 87 | } 88 | } 89 | 90 | if (errorHandler) { 91 | if (!this._fail) { 92 | this._fail = [errorHandler]; 93 | } else { 94 | this._fail.push(errorHandler); 95 | } 96 | } 97 | 98 | //// See Compatibility Note A in the DjsDeferred constructor. 99 | //// if (!this._next) { 100 | //// this._next = createDeferred(); 101 | //// } 102 | //// return this._next.promise(); 103 | 104 | if (this._resolved) { 105 | this.resolve.apply(this, this._arguments); 106 | } else if (this._rejected) { 107 | this.reject.apply(this, this._arguments); 108 | } 109 | 110 | return this; 111 | }, 112 | 113 | /** Invokes success callbacks for this deferred object. 114 | * All arguments are forwarded to success callbacks. 115 | * @method DjsDeferred#resolve 116 | */ 117 | resolve: function (/* args */) { 118 | if (this._done) { 119 | var i, len; 120 | for (i = 0, len = this._done.length; i < len; i++) { 121 | //// See Compability Note B - Fulfillment value. 122 | //// var nextValue = 123 | this._done[i].apply(null, arguments); 124 | } 125 | 126 | //// See Compatibility Note A in the DjsDeferred constructor. 127 | //// this._next.resolve(nextValue); 128 | //// delete this._next; 129 | 130 | this._done = undefined; 131 | this._resolved = false; 132 | this._arguments = undefined; 133 | } else { 134 | this._resolved = true; 135 | this._arguments = arguments; 136 | } 137 | }, 138 | 139 | /** Invokes error callbacks for this deferred object. 140 | * All arguments are forwarded to error callbacks. 141 | * @method DjsDeferred#reject 142 | */ 143 | reject: function (/* args */) { 144 | 145 | if (this._fail) { 146 | var i, len; 147 | for (i = 0, len = this._fail.length; i < len; i++) { 148 | this._fail[i].apply(null, arguments); 149 | } 150 | 151 | this._fail = undefined; 152 | this._rejected = false; 153 | this._arguments = undefined; 154 | } else { 155 | this._rejected = true; 156 | this._arguments = arguments; 157 | } 158 | }, 159 | 160 | /** Returns a version of this object that has only the read-only methods available. 161 | * @method DjsDeferred#promise 162 | * @returns An object with only the promise object. 163 | */ 164 | 165 | promise: function () { 166 | var result = {}; 167 | result.then = forwardCall(this, "then", result); 168 | return result; 169 | } 170 | }; 171 | 172 | /** Creates a deferred object. 173 | * @returns {DjsDeferred} A new deferred object. If jQuery is installed, then a jQueryDeferred object is returned, which provides a superset of features. 174 | */ 175 | function createDeferred() { 176 | if (window.jQuery && window.jQuery.Deferred) { 177 | return new window.jQuery.Deferred(); 178 | } else { 179 | return new DjsDeferred(); 180 | } 181 | } 182 | 183 | 184 | 185 | 186 | /** createDeferred (see {@link module:datajs/deferred~createDeferred}) */ 187 | exports.createDeferred = createDeferred; 188 | 189 | /** DjsDeferred (see {@link DjsDeferred}) */ 190 | exports.DjsDeferred = DjsDeferred; -------------------------------------------------------------------------------- /lib/odata.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 'use strict'; 20 | 21 | /** @module odata */ 22 | 23 | // Imports 24 | var odataUtils = exports.utils = require('./odata/odatautils.js'); 25 | var odataHandler = exports.handler = require('./odata/handler.js'); 26 | var odataMetadata = exports.metadata = require('./odata/metadata.js'); 27 | var odataNet = exports.net = require('./odata/net.js'); 28 | var odataJson = exports.json = require('./odata/json.js'); 29 | exports.batch = require('./odata/batch.js'); 30 | 31 | 32 | 33 | var utils = require('./utils.js'); 34 | var assigned = utils.assigned; 35 | 36 | var defined = utils.defined; 37 | var throwErrorCallback = utils.throwErrorCallback; 38 | 39 | var invokeRequest = odataUtils.invokeRequest; 40 | var MAX_DATA_SERVICE_VERSION = odataHandler.MAX_DATA_SERVICE_VERSION; 41 | var prepareRequest = odataUtils.prepareRequest; 42 | var metadataParser = odataMetadata.metadataParser; 43 | 44 | // CONTENT START 45 | 46 | var handlers = [odataJson.jsonHandler, odataHandler.textHandler]; 47 | 48 | /** Dispatches an operation to handlers. 49 | * @param {String} handlerMethod - Name of handler method to invoke. 50 | * @param {Object} requestOrResponse - request/response argument for delegated call. 51 | * @param {Object} context - context argument for delegated call. 52 | */ 53 | function dispatchHandler(handlerMethod, requestOrResponse, context) { 54 | 55 | var i, len; 56 | for (i = 0, len = handlers.length; i < len && !handlers[i][handlerMethod](requestOrResponse, context); i++) { 57 | } 58 | 59 | if (i === len) { 60 | throw { message: "no handler for data" }; 61 | } 62 | } 63 | 64 | /** Default success handler for OData. 65 | * @param data - Data to process. 66 | */ 67 | exports.defaultSuccess = function (data) { 68 | 69 | window.alert(window.JSON.stringify(data)); 70 | }; 71 | 72 | exports.defaultError = throwErrorCallback; 73 | 74 | exports.defaultHandler = { 75 | 76 | /** Reads the body of the specified response by delegating to JSON handlers. 77 | * @param response - Response object. 78 | * @param context - Operation context. 79 | */ 80 | read: function (response, context) { 81 | 82 | if (response && assigned(response.body) && response.headers["Content-Type"]) { 83 | dispatchHandler("read", response, context); 84 | } 85 | }, 86 | 87 | /** Write the body of the specified request by delegating to JSON handlers. 88 | * @param request - Reques tobject. 89 | * @param context - Operation context. 90 | */ 91 | write: function (request, context) { 92 | 93 | dispatchHandler("write", request, context); 94 | }, 95 | 96 | maxDataServiceVersion: MAX_DATA_SERVICE_VERSION, 97 | accept: "application/json;q=0.9, */*;q=0.1" 98 | }; 99 | 100 | exports.defaultMetadata = []; //TODO check why is the defaultMetadata an Array? and not an Object. 101 | 102 | /** Reads data from the specified URL. 103 | * @param urlOrRequest - URL to read data from. 104 | * @param {Function} [success] - 105 | * @param {Function} [error] - 106 | * @param {Object} [handler] - 107 | * @param {Object} [httpClient] - 108 | * @param {Object} [metadata] - 109 | */ 110 | exports.read = function (urlOrRequest, success, error, handler, httpClient, metadata) { 111 | 112 | var request; 113 | if (urlOrRequest instanceof String || typeof urlOrRequest === "string") { 114 | request = { requestUri: urlOrRequest }; 115 | } else { 116 | request = urlOrRequest; 117 | } 118 | 119 | return exports.request(request, success, error, handler, httpClient, metadata); 120 | }; 121 | 122 | /** Sends a request containing OData payload to a server. 123 | * @param {Object} request - Object that represents the request to be sent. 124 | * @param {Function} [success] - 125 | * @param {Function} [error] - 126 | * @param {Object} [handler] - 127 | * @param {Object} [httpClient] - 128 | * @param {Object} [metadata] - 129 | */ 130 | exports.request = function (request, success, error, handler, httpClient, metadata) { 131 | 132 | success = success || exports.defaultSuccess; 133 | error = error || exports.defaultError; 134 | handler = handler || exports.defaultHandler; 135 | httpClient = httpClient || odataNet.defaultHttpClient; 136 | metadata = metadata || exports.defaultMetadata; 137 | 138 | // Augment the request with additional defaults. 139 | request.recognizeDates = utils.defined(request.recognizeDates, odataJson.jsonHandler.recognizeDates); 140 | request.callbackParameterName = utils.defined(request.callbackParameterName, odataNet.defaultHttpClient.callbackParameterName); 141 | request.formatQueryString = utils.defined(request.formatQueryString, odataNet.defaultHttpClient.formatQueryString); 142 | request.enableJsonpCallback = utils.defined(request.enableJsonpCallback, odataNet.defaultHttpClient.enableJsonpCallback); 143 | 144 | // Create the base context for read/write operations, also specifying complete settings. 145 | var context = { 146 | metadata: metadata, 147 | recognizeDates: request.recognizeDates, 148 | callbackParameterName: request.callbackParameterName, 149 | formatQueryString: request.formatQueryString, 150 | enableJsonpCallback: request.enableJsonpCallback 151 | }; 152 | 153 | try { 154 | odataUtils.prepareRequest(request, handler, context); 155 | return odataUtils.invokeRequest(request, success, error, handler, httpClient, context); 156 | } catch (err) { 157 | // errors in success handler for sync requests are catched here and result in error handler calls. 158 | // So here we fix this and throw that error further. 159 | if (err.bIsSuccessHandlerError) { 160 | throw err; 161 | } else { 162 | error(err); 163 | } 164 | } 165 | 166 | }; 167 | 168 | /** Parses the csdl metadata to ODataJS metatdata format. This method can be used when the metadata is retrieved using something other than odatajs 169 | * @param {string} csdlMetadataDocument - A string that represents the entire csdl metadata. 170 | * @returns {Object} An object that has the representation of the metadata in odatajs format. 171 | */ 172 | exports.parseMetadata = function (csdlMetadataDocument) { 173 | 174 | return metadataParser(null, csdlMetadataDocument); 175 | }; 176 | 177 | // Configure the batch handler to use the default handler for the batch parts. 178 | exports.batch.batchHandler.partHandler = exports.defaultHandler; 179 | exports.metadataHandler = odataMetadata.metadataHandler; 180 | exports.jsonHandler = odataJson.jsonHandler; 181 | -------------------------------------------------------------------------------- /lib/odata/net.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 'use strict'; 20 | /** @module odata/net */ 21 | 22 | 23 | var http = require('http'); 24 | var utils = require('./../utils.js'); 25 | var url = require("url"); 26 | 27 | 28 | var defined = utils.defined; 29 | var delay = utils.delay; 30 | 31 | var ticks = 0; 32 | 33 | /* Checks whether the specified request can be satisfied with a JSONP request. 34 | * @param request - Request object to check. 35 | * @returns {Boolean} true if the request can be satisfied; false otherwise. 36 | 37 | * Requests that 'degrade' without changing their meaning by going through JSONP 38 | * are considered usable. 39 | * 40 | * We allow data to come in a different format, as the servers SHOULD honor the Accept 41 | * request but may in practice return content with a different MIME type. 42 | */ 43 | function canUseJSONP(request) { 44 | return false; 45 | } 46 | 47 | 48 | 49 | /** Checks whether the specified URL is an absolute URL. 50 | * @param {String} url - URL to check. 51 | * @returns {Boolean} true if the url is an absolute URL; false otherwise. 52 | */ 53 | function isAbsoluteUrl(url) { 54 | return url.indexOf("http://") === 0 || 55 | url.indexOf("https://") === 0 || 56 | url.indexOf("file://") === 0; 57 | } 58 | 59 | /** Checks whether the specified URL is local to the current context. 60 | * @param {String} url - URL to check. 61 | * @returns {Boolean} true if the url is a local URL; false otherwise. 62 | */ 63 | function isLocalUrl(url) { 64 | 65 | if (!isAbsoluteUrl(url)) { 66 | return true; 67 | } 68 | 69 | // URL-embedded username and password will not be recognized as same-origin URLs. 70 | var location = window.location; 71 | var locationDomain = location.protocol + "//" + location.host + "/"; 72 | return (url.indexOf(locationDomain) === 0); 73 | } 74 | 75 | 76 | /** Reads response headers into array. 77 | * @param {Object} inHeader 78 | * @param {Array} outHeader 79 | */ 80 | function readResponseHeaders(inHeader, outHeader) { 81 | for (var property in inHeader) { 82 | 83 | if (inHeader.hasOwnProperty(property)) { 84 | outHeader[property] = inHeader[property]; 85 | } 86 | } 87 | } 88 | 89 | 90 | 91 | 92 | 93 | exports.defaultHttpClient = { 94 | formatQueryString: "$format=json", 95 | 96 | 97 | /** Performs a network request. 98 | * @param {Object} request - Request description 99 | * @param {Function} success - Success callback with the response object. 100 | * @param {Function} error - Error callback with an error object. 101 | * @returns {Object} Object with an 'abort' method for the operation. 102 | */ 103 | request: function (request, success, error) { 104 | 105 | var result = {}; 106 | var done = false; 107 | 108 | var options = url.parse(request.requestUri); 109 | options.method = request.method || "GET"; 110 | options.headers = {}; 111 | //options.auth = request.user + ':' + request.password; 112 | //add headers 113 | var name; 114 | if (request.headers) { 115 | for (name in request.headers) { 116 | options.headers[name] = request.headers[name]; 117 | } 118 | } 119 | 120 | 121 | var xhr = http.request(options); 122 | 123 | result.abort = function () { 124 | if (done) { 125 | return; 126 | } 127 | 128 | done = true; 129 | if (xhr) { 130 | xhr.abort(); 131 | xhr = null; 132 | } 133 | 134 | error({ message: "Request aborted" }); 135 | }; 136 | 137 | // Set the timeout if available. 138 | if (request.timeoutMS) { 139 | xhr.setTimeout(request.timeoutMS,function () { 140 | if (!done) { 141 | done = true; 142 | xhr = null; 143 | error({ message: "Request timed out" }); 144 | } 145 | }); 146 | } 147 | 148 | xhr.on('error', function(e) { 149 | var response = { requestUri: url, statusCode: 400, statusText: e.message }; 150 | error({ message: "HTTP request failed", request: request, response: response }); 151 | }); 152 | 153 | 154 | xhr.on('response', function (resp) { 155 | if (done || xhr === null) { 156 | return; 157 | } 158 | 159 | var headers = []; 160 | readResponseHeaders(resp.headers, headers); 161 | 162 | var body = ''; 163 | 164 | resp.on('data', function(chunk) { 165 | body+=chunk; 166 | }); 167 | resp.on('end', function() { 168 | // do what you do 169 | var response = { requestUri: url, statusCode: resp.statusCode, statusText: '', headers: headers, body: body }; 170 | 171 | done = true; 172 | xhr = null; 173 | if (resp.statusCode >= 200 && resp.statusCode <= 299) { 174 | success(response); 175 | } else { 176 | error({ message: "HTTP request failed", request: request, response: response }); 177 | } 178 | }); 179 | }); 180 | 181 | //xhr.open(request.method || "GET", url, true,); 182 | if (request.body) { 183 | xhr.write(request.body); 184 | } 185 | xhr.end(); 186 | 187 | return result; 188 | } 189 | }; 190 | 191 | 192 | 193 | exports.canUseJSONP = canUseJSONP; 194 | exports.isAbsoluteUrl = isAbsoluteUrl; 195 | exports.isLocalUrl = isLocalUrl; -------------------------------------------------------------------------------- /lib/store.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | //'use strict'; 20 | 21 | /** @module store */ 22 | 23 | 24 | 25 | 26 | 27 | exports.defaultStoreMechanism = "best"; 28 | 29 | /** Creates a new store object. 30 | * @param {String} name - Store name. 31 | * @param {String} [mechanism] - 32 | * @returns {Object} Store object. 33 | */ 34 | exports.createStore = function (name, mechanism) { 35 | 36 | 37 | if (!mechanism) { 38 | mechanism = exports.defaultStoreMechanism; 39 | } 40 | 41 | if (mechanism === "best") { 42 | mechanism = (DomStore.isSupported()) ? "dom" : "memory"; 43 | } 44 | 45 | var factory = mechanisms[mechanism]; 46 | if (factory) { 47 | return factory.create(name); 48 | } 49 | 50 | throw { message: "Failed to create store", name: name, mechanism: mechanism }; 51 | }; 52 | 53 | exports.DomStore = DomStore = require('./store/dom.js'); 54 | exports.IndexedDBStore = IndexedDBStore = require('./store/indexeddb.js'); 55 | exports.MemoryStore = MemoryStore = require('./store/memory.js'); 56 | 57 | var mechanisms = { 58 | indexeddb: IndexedDBStore, 59 | dom: DomStore, 60 | memory: MemoryStore 61 | }; 62 | 63 | exports.mechanisms = mechanisms; 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "odatajs", 3 | "version": "4.0.1", 4 | "postfix": "", 5 | "releaseCandidate": "", 6 | "title": "Olingo OData Client for JavaScript", 7 | "description": "the Olingo OData Client for JavaScript library 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.", 8 | "homepage": "http://olingo.apache.org", 9 | "main": "index-node.js", 10 | "main-browser": "index.js", 11 | "repository": { 12 | "type": "git", 13 | "url": "http://git-wip-us.apache.org/repos/asf/olingo-odata4-js.git" 14 | }, 15 | "engines": { 16 | "node": ">= 0.12.0" 17 | }, 18 | "contributors": [ 19 | { 20 | "name": "Bing Li", 21 | "email": "bingl@apache.org" 22 | }, 23 | { 24 | "name": "Sven Kobler-Morris", 25 | "email": "koblers@apache.org" 26 | }, 27 | { 28 | "name": "Challen He", 29 | "email": "challenh@apache.org" 30 | } 31 | ], 32 | "scripts": { 33 | "preinstall": "npm --prefix ./grunt-config/custom-tasks/rat install" 34 | }, 35 | "devDependencies": { 36 | "chai": "2.0.0", 37 | "grunt": "0.4.5", 38 | "grunt-connect-proxy": "0.1.10", 39 | "grunt-contrib-clean": "0.6.0", 40 | "grunt-contrib-compress": "0.10.0", 41 | "grunt-contrib-copy": "0.5.0", 42 | "grunt-contrib-uglify": "0.4.0", 43 | "grunt-curl": "2.0.2", 44 | "grunt-jsdoc": "0.5.6", 45 | "grunt-nuget": "0.1.3", 46 | "mocha": "2.1.0", 47 | "xmldom": "0.1.19" 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /test/mocha.opts: -------------------------------------------------------------------------------- 1 | --reporter spec 2 | --ui bdd 3 | --timeout 5000 -------------------------------------------------------------------------------- /test/test-utils.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 'use strict'; 20 | 21 | var odatajs = require('./../index.js'); 22 | var chai = require('chai'); 23 | var assert = chai.assert; 24 | 25 | describe('TEST utils.js', function () { 26 | it('utils.isArray', function () { 27 | assert.isTrue(odatajs.utils.isArray([])); 28 | assert.isTrue(odatajs.utils.isArray([1, 2])); 29 | assert.isTrue(!odatajs.utils.isArray({})); 30 | assert.isTrue(!odatajs.utils.isArray("1,2,3,4")); 31 | assert.isTrue(!odatajs.utils.isArray()); 32 | assert.isTrue(!odatajs.utils.isArray(null)); 33 | }); 34 | }); 35 | -------------------------------------------------------------------------------- /tests/code/jsdate.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | /// 21 | /// The verifiers's representation of a Javascript date object as deserialized by the library 22 | /// 23 | 24 | namespace DataJS.Tests 25 | { 26 | using System; 27 | using System.Collections.Generic; 28 | using System.IO; 29 | using System.Linq; 30 | using System.Net; 31 | using System.Runtime.Serialization; 32 | using System.ServiceModel; 33 | using System.ServiceModel.Activation; 34 | using System.ServiceModel.Syndication; 35 | using System.ServiceModel.Web; 36 | using System.Xml; 37 | using System.Xml.Linq; 38 | using Microsoft.Spatial; 39 | using Microsoft.OData.Core; 40 | 41 | [Serializable] 42 | public class JsDate : JsonObject 43 | { 44 | private static readonly DateTime JsEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); 45 | 46 | public JsDate(DateTime dateTime) 47 | : base() 48 | { 49 | this["milliseconds"] = dateTime.Subtract(JsEpoch).TotalMilliseconds; 50 | } 51 | 52 | public JsDate(DateTimeOffset dateTimeOffset) 53 | : this(dateTimeOffset.UtcDateTime) 54 | { 55 | this["__edmType"] = "Edm.DateTimeOffset"; 56 | this["__offset"] = (dateTimeOffset.Offset < TimeSpan.Zero ? "-" : "+") + dateTimeOffset.Offset.ToString("hh':'mm"); 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /tests/code/jsonobject.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | /// 21 | /// A weakly typed representation of a JSON object using a dictionary implementation 22 | /// 23 | /// The CLR type of the values of the properties 24 | 25 | namespace DataJS.Tests 26 | { 27 | using System; 28 | using System.Collections; 29 | using System.Collections.Generic; 30 | using System.Linq; 31 | using System.Runtime.Serialization; 32 | 33 | [Serializable] 34 | [KnownType(typeof(JsonObject))] 35 | [KnownType(typeof(JsonObject[]))] 36 | [KnownType(typeof(JsDate))] 37 | [KnownType(typeof(List))] 38 | public class JsonObject : ISerializable, IEnumerable> 39 | { 40 | Dictionary dictionary = new Dictionary(); 41 | 42 | public void Remove(string key) 43 | { 44 | dictionary.Remove(key); 45 | } 46 | 47 | public object this[string key] 48 | { 49 | get 50 | { 51 | return this.dictionary[key]; 52 | } 53 | set 54 | { 55 | this.dictionary[key] = value; 56 | } 57 | } 58 | 59 | public bool ContainsKey(string key) 60 | { 61 | return this.dictionary.ContainsKey(key); 62 | } 63 | 64 | public static JsonObject Merge(JsonObject first, JsonObject second) 65 | { 66 | if (first == null) 67 | { 68 | return second; 69 | } 70 | 71 | if (second != null) 72 | { 73 | JsonObject merged = new JsonObject(); 74 | merged.dictionary = new Dictionary(first.dictionary); 75 | foreach (var pair in second.dictionary) 76 | { 77 | merged.dictionary[pair.Key] = pair.Value; 78 | } 79 | return merged; 80 | } 81 | return first; 82 | } 83 | 84 | public void GetObjectData(SerializationInfo info, StreamingContext context) 85 | { 86 | this.dictionary.ToList().ForEach(pair => info.AddValue(pair.Key, pair.Value)); 87 | } 88 | 89 | public IEnumerator> GetEnumerator() 90 | { 91 | return this.dictionary.GetEnumerator(); 92 | } 93 | 94 | IEnumerator IEnumerable.GetEnumerator() 95 | { 96 | return this.dictionary.GetEnumerator(); 97 | } 98 | } 99 | } -------------------------------------------------------------------------------- /tests/code/readerutils.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | using System.Collections.Generic; 21 | using System.IO; 22 | using System.Net; 23 | using System.Web.Script.Serialization; 24 | 25 | namespace DataJS.Tests 26 | { 27 | public static class ReaderUtils 28 | { 29 | public static JsonObject CreateEntryPropertyMetadata(string type) 30 | { 31 | return CreateEntryPropertyMetadata(type, true); 32 | } 33 | 34 | public static JsonObject CreateEntryPropertyMetadata(string type, bool withExtensions) 35 | { 36 | JsonObject json = new JsonObject(); 37 | json["type"] = type; 38 | 39 | 40 | // TODO: add proper support for property extensions 41 | if (withExtensions) 42 | { 43 | json["extensions"] = new JsonObject[] { }; 44 | } 45 | 46 | return json; 47 | } 48 | 49 | public static JsonObject CreateExtension(string name, string nameSpace, string value) 50 | { 51 | JsonObject json = new JsonObject(); 52 | json["name"] = name; 53 | json["namespaceURI"] = nameSpace; 54 | json["value"] = value; 55 | return json; 56 | } 57 | 58 | public static WebRequest CreateRequest(string url, string user = null, string password = null) 59 | { 60 | WebRequest request = WebRequest.Create(url); 61 | if (user != null || password != null) 62 | { 63 | request.Credentials = new NetworkCredential(user, password); 64 | request.PreAuthenticate = true; 65 | } 66 | 67 | return request; 68 | } 69 | 70 | public static Stream ConvertDictionarytoJsonlightStream(Dictionary dict) 71 | { 72 | MemoryStream stream = new MemoryStream(); 73 | if (dict == null) 74 | { 75 | return stream; 76 | } 77 | 78 | string jsonString = new JavaScriptSerializer().Serialize(dict); 79 | StreamWriter writer = new StreamWriter(stream); 80 | writer.Write(jsonString); 81 | writer.Flush(); 82 | stream.Position = 0; 83 | return stream; 84 | } 85 | 86 | } 87 | } -------------------------------------------------------------------------------- /tests/common/Instrument.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | // Instrument.js 21 | // Instrumentation utilities 22 | 23 | (function (window, undefined) { 24 | 25 | var warmedUp = false; 26 | var getBrowserMemorySize = function (success) { 27 | /** Gets the memory size (in bytes) of the browser process 28 | * @param {Function} success - The success callback 29 | */ 30 | var makeRequest = function (success) { 31 | $.get("./common/Instrument.svc/GetBrowserMemorySize", function (data) { 32 | success(parseInt(data)); 33 | }, "text"); 34 | }; 35 | 36 | if (window.CollectGarbage) { 37 | window.CollectGarbage(); 38 | } 39 | 40 | if (!warmedUp) { 41 | // Make a dummy request to warm it up 42 | makeRequest(function () { 43 | warmedUp = true; 44 | makeRequest(success); 45 | }); 46 | } else { 47 | makeRequest(success); 48 | } 49 | }; 50 | 51 | window.Instrument = { 52 | getBrowserMemorySize: getBrowserMemorySize 53 | }; 54 | 55 | })(this); -------------------------------------------------------------------------------- /tests/common/Instrument.svc: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | <%@ ServiceHost Language="C#" Debug="true" Factory="System.ServiceModel.Activation.WebScriptServiceHostFactory" 21 | Service="DataJS.Tests.Instrument" %> 22 | 23 | namespace DataJS.Tests 24 | { 25 | using System; 26 | using System.Collections.Generic; 27 | using System.Diagnostics; 28 | using System.IO; 29 | using System.Linq; 30 | using System.Runtime.Serialization; 31 | using System.ServiceModel; 32 | using System.ServiceModel.Activation; 33 | using System.ServiceModel.Syndication; 34 | using System.ServiceModel.Web; 35 | using System.Text; 36 | 37 | /// 38 | /// Instrumentation utilities 39 | /// 40 | [ServiceContract] 41 | [ServiceBehavior(IncludeExceptionDetailInFaults = true)] 42 | [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] 43 | public class Instrument 44 | { 45 | static readonly Dictionary userAgents = new Dictionary 46 | { 47 | { "MSIE", "iexplore" }, 48 | { "Firefox", "firefox" }, 49 | { "Chrome", "chrome" }, 50 | { "Safari", "safari" } 51 | }; 52 | 53 | /// 54 | /// Gets the memory size used by the browser 55 | /// 56 | /// The memory size used by the browser (in bytes), or zero if browser is not supported 57 | [OperationContract] 58 | [WebGet] 59 | public Stream GetBrowserMemorySize() 60 | { 61 | string userAgentString = WebOperationContext.Current.IncomingRequest.UserAgent; 62 | string userAgentKey = Instrument.userAgents.Keys.FirstOrDefault(ua => userAgentString.Contains(ua)); 63 | 64 | if (userAgentKey != null) 65 | { 66 | string processName = userAgents[userAgentKey]; 67 | long totalMemory = Process.GetProcessesByName(processName).Select(p => p.WorkingSet64).Sum(); 68 | 69 | return new MemoryStream(Encoding.UTF8.GetBytes(totalMemory.ToString())); 70 | } 71 | else 72 | { 73 | return new MemoryStream(Encoding.UTF8.GetBytes("0")); 74 | } 75 | } 76 | } 77 | } -------------------------------------------------------------------------------- /tests/common/ODataVerifyReader.svc: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | <%@ ServiceHost Language="C#" Debug="true" Factory="System.ServiceModel.Activation.WebScriptServiceHostFactory" 21 | Service="DataJS.Tests.ODataVerifyReader" %> 22 | 23 | //uncomment this line to debug JSON serialization. 24 | //#define DEBUG_SERIALIZATION 25 | 26 | namespace DataJS.Tests 27 | { 28 | using System; 29 | using System.Collections.Generic; 30 | using System.IO; 31 | using System.Linq; 32 | using System.Net; 33 | using System.Runtime.Serialization; 34 | using System.ServiceModel; 35 | using System.ServiceModel.Activation; 36 | using System.ServiceModel.Syndication; 37 | using System.ServiceModel.Web; 38 | using System.Xml; 39 | using System.Xml.Linq; 40 | using Microsoft.Spatial; 41 | using Microsoft.OData.Core; 42 | using System.Web.Script.Serialization; 43 | 44 | /// 45 | /// Verifier for the OData.read library function 46 | /// 47 | [ServiceContract] 48 | [ServiceBehavior(IncludeExceptionDetailInFaults = true)] 49 | [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] 50 | public class ODataVerifyReader 51 | { 52 | const string jsonlightMediaType = "application/json"; 53 | 54 | /// 55 | /// Reads a URI that will return a metadata object 56 | /// 57 | /// The URL to send the request to 58 | /// Stream of metadata in json light format 59 | [OperationContract] 60 | [WebGet] 61 | public Stream ReadMetadata(string url) 62 | { 63 | WebResponse response = WebRequest.Create(ResolveUri(url, UriKind.Absolute)).GetResponse(); 64 | Dictionary jsonObject = CsdlReader.ReadCsdl(new StreamReader(response.GetResponseStream())); 65 | return ReaderUtils.ConvertDictionarytoJsonlightStream(jsonObject); 66 | } 67 | 68 | /// 69 | /// Reads a URI that will get the Json response and return the stream 70 | /// 71 | /// URL of the entry 72 | /// The username for basic authentication 73 | /// The password for basic authentication 74 | /// Stream of the Json response expected to be returned by OData.read 75 | [OperationContract] 76 | [WebGet(ResponseFormat = WebMessageFormat.Json)] 77 | public Stream ReadJson(string url, string mimeType, string user, string password) 78 | { 79 | if (mimeType == null) 80 | { 81 | mimeType = jsonlightMediaType + ";odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8"; 82 | } 83 | 84 | HttpWebRequest request = (HttpWebRequest)ReaderUtils.CreateRequest(ResolveUri(url, UriKind.Absolute), user, password); 85 | request.Accept = mimeType; 86 | WebResponse response = request.GetResponse(); 87 | 88 | return response.GetResponseStream(); 89 | } 90 | 91 | /// 92 | /// Resolves the given url string to a URI 93 | /// 94 | /// The given URL string 95 | /// URI kind to resolve to 96 | /// The resolved URI 97 | private static string ResolveUri(string url, UriKind uriKind) 98 | { 99 | Uri resolvedUri = new Uri(url, UriKind.RelativeOrAbsolute); 100 | if (!resolvedUri.IsAbsoluteUri) 101 | { 102 | // If the given URI is relative, then base it on the Referer URI 103 | Uri baseUri = new Uri(WebOperationContext.Current.IncomingRequest.Headers["Referer"]); 104 | resolvedUri = new Uri(baseUri, resolvedUri); 105 | if (uriKind == UriKind.Relative) 106 | { 107 | resolvedUri = baseUri.MakeRelativeUri(resolvedUri); 108 | } 109 | } 110 | 111 | return resolvedUri.ToString(); 112 | } 113 | } 114 | } -------------------------------------------------------------------------------- /tests/common/ObservableHttpClient.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | // ObservableHttpClient.js 21 | // This object extends OData's default httpClient by supporting request and response recording sessions, and firing a custom 22 | // JQuery event for each request/response. 23 | // 24 | // The events fired by this object are: 25 | // request: Before a request is made 26 | // success: Before the primary success handler is called 27 | // 28 | // To bind to an event, JQuery event attachers can be used on the object, e.g. 29 | // $(observableHttpClient).bind("request", function (request) { ... }); 30 | // 31 | // To begin a new recording session, use: 32 | // var session = observableHttpClient.newSession(); 33 | // 34 | // Requests and responses are then recorded in session.requests and session.responses. Session can be ended by session.end(). 35 | // Multiple simultaneous sessions are supported. 36 | 37 | (function (window, undefined) { 38 | 39 | var ObservableHttpClient = function (provider) { 40 | this.provider = provider ? provider : window.odatajs.oData.net.defaultHttpClient; 41 | }; 42 | 43 | ObservableHttpClient.prototype.newSession = function () { 44 | return new Session(this); 45 | }; 46 | 47 | ObservableHttpClient.prototype.request = function (request, success, error) { 48 | var that = this; 49 | 50 | $(this).triggerHandler("request", request); 51 | return this.provider.request(request, function (response) { 52 | $(that).triggerHandler("success", response); 53 | success(response); 54 | }, error); 55 | }; 56 | 57 | 58 | var Session = function (client) { 59 | var that = this; 60 | 61 | this.client = client; 62 | this.clear(); 63 | 64 | this.requestHandler = function (event, request) { that.requests.push(request); }; 65 | $(client).bind("request", this.requestHandler); 66 | 67 | this.successHandler = function (event, response) { that.responses.push(response); }; 68 | $(client).bind("success", this.successHandler); 69 | }; 70 | 71 | Session.prototype.clear = function () { 72 | this.requests = []; 73 | this.responses = []; 74 | }; 75 | 76 | Session.prototype.end = function () { 77 | $(this.client).unbind("request", this.requestHandler); 78 | $(this.client).unbind("success", this.successHandler); 79 | }; 80 | 81 | window.ObservableHttpClient = ObservableHttpClient; 82 | window.Session = Session; 83 | 84 | })(this); -------------------------------------------------------------------------------- /tests/common/common.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | (function (window, undefined) { 20 | window.temp = window.odatajs; 21 | window.temp.store = window.odatajs.store; 22 | window.temp.cache = window.odatajs.cache; 23 | window.odatajs = window.temp; 24 | delete window.temp; 25 | })(this); -------------------------------------------------------------------------------- /tests/common/djstest-browser-ext.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | 21 | // Because this code contains a init function to be useable directly inside the browser as well as in nodejs 22 | // we define the @namespace djstest here instead of the a @module name djstest 23 | 24 | /** Create namespace djstest in window.djstest when this file is loaded as JavaScript by the browser 25 | * @namespace djstest 26 | */ 27 | 28 | 29 | var init = function init () { 30 | 31 | var localDjstest = {}; 32 | 33 | // Initialize indexedDB if the window object is available 34 | localDjstest.indexedDB = window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB || window.indexedDB; 35 | 36 | /** Cleans all the test data saved in the IndexedDb database. 37 | * @param {Array} storeObjects - Array of store objects with a property that is the name of the store 38 | * @param {Function} done - Callback function 39 | */ 40 | localDjstest.cleanStoreOnIndexedDb = function (storeObjects, done) { 41 | var IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || {}; 42 | 43 | function deleteObjectStores(db) { 44 | for ( var i = 0 ; i < db.objectStoreNames.length ; i ++) { 45 | db.deleteObjectStore(db.objectStoreNames[i]); 46 | } 47 | } 48 | var job; 49 | 50 | if (localDjstest.indexedDB) { 51 | job = new djstest.Job(); 52 | for ( var i = 0 ; i < storeObjects.length ; i ++) { 53 | var storeObject = storeObjects[i]; 54 | job.queue((function (storeObject) { 55 | return function (success, fail) { 56 | var dbname = "_datajs_" + storeObject.name; 57 | var request = localDjstest.indexedDB.open(dbname); 58 | request.onsuccess = function (event) { 59 | var db = request.result; 60 | 61 | if ("setVersion" in db) { 62 | var versionRequest = db.setVersion("0.1"); 63 | versionRequest.onsuccess = function (event) { 64 | var transaction = versionRequest.transaction; 65 | transaction.oncomplete = function () { 66 | db.close(); 67 | success(); 68 | }; 69 | deleteObjectStores(db); 70 | }; 71 | versionRequest.onerror = function (e) { 72 | djstest.fail("Error on cleanup - code: " + e.code + " name: " + e.name + "message: " + message); 73 | fail(); 74 | }; 75 | return; 76 | } 77 | 78 | // new api cleanup 79 | db.close(); 80 | var deleteRequest = localDjstest.indexedDB.deleteDatabase(dbname); 81 | deleteRequest.onsuccess = function (event) { 82 | djstest.log("djstest indexeddb cleanup - deleted database " + dbname); 83 | success(); 84 | }; 85 | deleteRequest.onerror = function (e) { 86 | djstest.fail("djstest indexeddb cleanup - error deleting database " + dbname); 87 | fail(); 88 | }; 89 | djstest.log("djstest indexeddb cleanup - requested deletion of database " + dbname); 90 | }; 91 | 92 | request.onerror = function (e) { 93 | djstest.fail(e.code + ": " + e.message); 94 | }; 95 | }; 96 | })(storeObject)); 97 | } 98 | } 99 | 100 | if (job) { 101 | job.run(function (succeeded) { 102 | if (!succeeded) { 103 | djstest.fail("cleanup job failed"); 104 | } 105 | done(); 106 | }); 107 | } 108 | else { 109 | done(); 110 | } 111 | }; 112 | 113 | 114 | // Disable caching to ensure that every test-related AJAX request is actually being sent, 115 | // and set up a default error handler 116 | if (typeof window !== undefined) { 117 | $.ajaxSetup({ 118 | cache: false, 119 | error: function (jqXHR, textStatus, errorThrown) { 120 | // Work around bug in IE-Mobile on Windows Phone 7 121 | if (jqXHR.status !== 1223) { 122 | var err = { 123 | status: jqXHR.status, 124 | statusText: jqXHR.statusText, 125 | responseText: jqXHR.responseText 126 | }; 127 | djstest.fail("AJAX request failed with: " + djstest.toString(err)); 128 | } 129 | djstest.done(); 130 | } 131 | }); 132 | } 133 | return localDjstest; 134 | }; 135 | 136 | //export djstest 137 | 138 | if (typeof window !== 'undefined') { 139 | //expose to browsers window object 140 | if ( window.djstest === undefined) { 141 | window.djstest = init(); 142 | } else { 143 | var tmp = init(); 144 | $.extend( window.djstest,tmp); 145 | } 146 | } else { 147 | //expose in commonjs style 148 | module.exports = init(); 149 | } 150 | 151 | -------------------------------------------------------------------------------- /tests/common/mockHttpClient.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | //mockHttpClient.js 21 | //this object allows for associating a uri with a requestVerfier and mock responses that will be sent back to the client of the httpStack. 22 | //It can be used to replace OData's httpClient for testing purposes. 23 | // 24 | //RequestVerifiers 25 | // 26 | // 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. 27 | // the callback receives as its only parameter the request object passed to the mockHttpClient. 28 | // 29 | // To register a request verifier, simply do 30 | // 31 | // MockHttpClient.addRequestVerifier("http://someUri", function(request) { 32 | // djstest.assertAreEqual(request.requestUri,"http://someUri"); 33 | // } 34 | // 35 | //Responses 36 | // 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, 37 | // depending on the response status code invoke either the success or the error callbacks. 38 | // 39 | // To register a response, 40 | // 41 | // MockHttpClient.addResponse("http://someUri", {status: 200, body:"some body"}); 42 | // 43 | //Exceptions 44 | // 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. 45 | // 46 | 47 | function init(window, undefined) { 48 | 49 | var httpClient = {}; 50 | 51 | var responses = {}; 52 | var requestVerifiers = {}; 53 | 54 | httpClient.addRequestVerifier = function (uri, verifier) { 55 | requestVerifiers[uri] = verifier; 56 | return this; 57 | }; 58 | 59 | httpClient.addResponse = function (uri, response) { 60 | responses[uri] = response; 61 | return this; 62 | }; 63 | 64 | httpClient.async = false; 65 | 66 | httpClient.clear = function () { 67 | /** Clears all registered responses and verifiers. 68 | * @returns this client 69 | */ 70 | responses = {}; 71 | requestVerifiers = {}; 72 | this.async = false; 73 | return this; 74 | }; 75 | 76 | httpClient.request = function (request, success, error) { 77 | var uri = request.requestUri; 78 | var verifier = requestVerifiers[uri]; 79 | var response = responses[uri]; 80 | 81 | if (verifier === undefined) { 82 | verifier = requestVerifiers["*"]; 83 | } 84 | 85 | if (response === undefined) { 86 | response = responses["*"]; 87 | } 88 | 89 | if (!verifier && !response) { 90 | throw { message: "neither verifier or response defined for uri: " + uri }; 91 | } 92 | 93 | if (verifier) { 94 | verifier(request); 95 | } 96 | 97 | if (response) { 98 | response.requestUri = uri; 99 | if (response.statusCode >= 200 && response.statusCode <= 299) { 100 | if (this.async) { 101 | setTimeout(function () { 102 | success(response); 103 | }); 104 | } else { 105 | success(response); 106 | } 107 | } else { 108 | if (this.async) { 109 | setTimeout(function () { 110 | error({ message: "failed test response", request: request, response: response }); 111 | }); 112 | } 113 | else { 114 | error({ message: "failed test response", request: request, response: response }); 115 | } 116 | } 117 | } 118 | }; 119 | 120 | httpClient.setAsync = function (value) { 121 | this.async = value; 122 | return this; 123 | }; 124 | 125 | return httpClient; 126 | } 127 | 128 | 129 | 130 | if (typeof window !== 'undefined') { 131 | //in browser call init() directly window as context 132 | window.MockHttpClient = init(window); 133 | } else { 134 | //expose function init to be called with a custom context 135 | module.exports.init = init; 136 | } 137 | 138 | -------------------------------------------------------------------------------- /tests/common/mockXMLHttpRequest.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | // mockXMLHttpRequest.js 21 | // 22 | // This file provides a window.MockXMLHttpRequest object that can be used 23 | // to replace or wrap the browser's XMLHttpRequest object for testing. 24 | // 25 | // Typically the object is installed, a test run, and then the original 26 | // object restored. The addResponse and addRequest verifier can be 27 | // used to set up callbacks; reset is used to clear those values. 28 | // 29 | // For a sample demonstrating how to use this functionality, see 30 | // the httpClientSendRequestTest test in odata-net-tests.js. 31 | 32 | (function (window, undefined) { 33 | 34 | if (!window.MockXMLHttpRequest) { 35 | window.MockXMLHttpRequest = {}; 36 | } 37 | 38 | var mockXMLHttpRequest = window.MockXMLHttpRequest; 39 | 40 | var responses = {}; 41 | var verifiers = {}; 42 | 43 | mockXMLHttpRequest.addResponse = function (uri, response) { 44 | /** Adds a new response to be returned for the specified uri (* for 'anything'). 45 | * @param {String} uri - URI to match (* to match anything not otherwise specified). 46 | * @param {Object} response - Response object. 47 | */ 48 | responses = responses || {}; 49 | responses[uri] = response; 50 | 51 | return this; 52 | }; 53 | 54 | mockXMLHttpRequest.addRequestVerifier = function (uri, verifier) { 55 | /** Adds a new request verifier to be invoked for the specified uri (* for 'anything'). 56 | * @param {String} uri - URI to match (* to match anything not otherwise specified). 57 | * @param {Function} response - Verifier callback that takes the request. 58 | */ 59 | verifiers = verifiers || {}; 60 | verifiers[uri] = verifier; 61 | 62 | return this; 63 | }; 64 | 65 | mockXMLHttpRequest.reset = function () { 66 | /** Resets all configuration from the mock XHR object. 67 | */ 68 | 69 | responses = {}; 70 | verifiers = {}; 71 | 72 | mockXMLHttpRequest.onCreate = undefined; 73 | mockXMLHttpRequest.onAfterSend = undefined; 74 | 75 | return this; 76 | }; 77 | 78 | var xmlHttpRequest = function () { 79 | //properties 80 | this.readyState = 0; 81 | this.responseXML = undefined; 82 | 83 | //events 84 | this.ontimeout = undefined; 85 | this.onreadystatechange = undefined; 86 | 87 | if (mockXMLHttpRequest.onCreate) { 88 | mockXMLHttpRequest.onCreate(this); 89 | } 90 | }; 91 | 92 | xmlHttpRequest.prototype.open = function (method, url, async, user, password) { 93 | if (!method) { 94 | throw { method: "method parameter is not defined, empty, or null " }; 95 | } 96 | if (!url) { 97 | throw { message: "url parameter is not defined, empty, or null " }; 98 | } 99 | 100 | this._request = { 101 | headers: {}, 102 | url: url, 103 | method: method, 104 | async: async, 105 | user: user, 106 | password: password 107 | }; 108 | }; 109 | 110 | xmlHttpRequest.prototype.getAllResponseHeaders = function () { 111 | if (!this._response) { 112 | throw { message: "_response property is undefined, did you forget to call send() or map the request url to a response?" }; 113 | } 114 | 115 | var result = ""; 116 | var header; 117 | for (header in this._response.headers) { 118 | result = result + header + ": " + this._response.headers[header] + "\n\r"; 119 | } 120 | //remove trailing LFCR 121 | return result.substring(0, result.length - 2); 122 | }; 123 | 124 | xmlHttpRequest.prototype.getResponseHeader = function (header) { 125 | if (!this._response) { 126 | throw { message: "_response property is undefined, did you forget to call send() or map the request url to a response?" }; 127 | } 128 | return this._response.headers[header]; 129 | }; 130 | 131 | xmlHttpRequest.prototype.abort = function () { 132 | //do nothing for now. 133 | }; 134 | 135 | xmlHttpRequest.prototype.setRequestHeader = function (header, value) { 136 | if (!this._request) { 137 | throw { message: "_request property is undefined, did you forget to call open() first?" }; 138 | } 139 | this._request.headers[header] = value; 140 | }; 141 | 142 | xmlHttpRequest.prototype.send = function (data) { 143 | if (!this._request) { 144 | throw { message: "_request property is undefined, did you forget to call open() first?" }; 145 | } 146 | 147 | if (this._request.headers["MockNoOp"]) { 148 | return; 149 | } 150 | 151 | if (this._request.headers["MockTimeOut"]) { 152 | if (!this.timeout) { 153 | throw { message: "timeout property is not set" }; 154 | } 155 | 156 | if (this.ontimeout) { 157 | (function (xhr) { 158 | setTimeout(function () { 159 | xhr.ontimeout(); 160 | }, xhr.timeout); 161 | })(this); 162 | } 163 | return; 164 | } 165 | 166 | var url = this._request.url; 167 | var verifier = verifiers[url]; 168 | var response = responses[url]; 169 | 170 | if (!verifier) { 171 | verifier = verifiers["*"]; 172 | } 173 | 174 | if (!response) { 175 | response = responses["*"]; 176 | } 177 | 178 | if (!verifier && !response) { 179 | throw { message: "neither verifier or response defined for url: " + url }; 180 | } 181 | 182 | this._request.body = data; 183 | 184 | if (verifier) { 185 | verifier(this._request); 186 | } 187 | 188 | if (response) { 189 | // Execute the respone after a 30ms delay. 190 | this._response = response; 191 | sendResponseDelay(this, response, 60); 192 | } 193 | }; 194 | 195 | var sendResponseDelay = function (xhr, response, delay) { 196 | setTimeout(function () { 197 | xhr.status = response.status; 198 | xhr.responseText = response.body; 199 | xhr.responseBody = response.body; 200 | 201 | xhr.readyState = 4; 202 | if (xhr.onreadystatechange) { 203 | xhr.onreadystatechange(); 204 | if (mockXMLHttpRequest.onAfterSend) { 205 | mockXMLHttpRequest.onAfterSend(); 206 | } 207 | } 208 | }, delay); 209 | }; 210 | 211 | mockXMLHttpRequest.XMLHttpRequest = xmlHttpRequest; 212 | 213 | })(this); 214 | -------------------------------------------------------------------------------- /tests/e2etest/Test.html: -------------------------------------------------------------------------------- 1 |  21 | 22 | 23 | 24 | odatajs side-by-side test (V3 & V4) 25 | 26 | 27 | 28 | https://datajs.codeplex.com/downloads/get/784666 29 | 30 | 31 |

32 | Test V3 and V4 running side by side...

33 |
34 |
35 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /tests/endpoints/BasicAuthDataService.svc: -------------------------------------------------------------------------------- 1 | <%@ ServiceHost Language="C#" Factory="Microsoft.OData.Service.DataServiceHostFactory, Microsoft.OData.Service, Version=6.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" 2 | Service="DataJS.Tests.BasicAuthDataService" %> 3 | /* 4 | * Licensed to the Apache Software Foundation (ASF) under one 5 | * or more contributor license agreements. See the NOTICE file 6 | * distributed with this work for additional information 7 | * regarding copyright ownership. The ASF licenses this file 8 | * to you under the Apache License, Version 2.0 (the 9 | * "License"); you may not use this file except in compliance 10 | * with the License. You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, 15 | * software distributed under the License is distributed on an 16 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 | * KIND, either express or implied. See the License for the 18 | * specific language governing permissions and limitations 19 | * under the License. 20 | */ 21 | namespace DataJS.Tests 22 | { 23 | using System; 24 | using System.Collections.Generic; 25 | using Microsoft.OData.Service; 26 | using System.Linq; 27 | using System.ServiceModel; 28 | using System.ServiceModel.Web; 29 | using System.Text; 30 | using System.Web; 31 | 32 | [ServiceBehavior(IncludeExceptionDetailInFaults = true)] 33 | public class BasicAuthDataService : DataService 34 | { 35 | const string Username = "djsUser"; 36 | const string Password = "djsPassword"; 37 | 38 | // This method is called only once to initialize service-wide policies. 39 | public static void InitializeService(DataServiceConfiguration config) 40 | { 41 | config.SetEntitySetAccessRule("*", EntitySetRights.All); 42 | config.SetServiceOperationAccessRule("*", ServiceOperationRights.All); 43 | config.DataServiceBehavior.MaxProtocolVersion = Microsoft.OData.Client.ODataProtocolVersion.V4; 44 | config.UseVerboseErrors = true; 45 | } 46 | 47 | public BasicAuthDataService() 48 | : base() 49 | { 50 | this.ProcessingPipeline.ProcessingRequest += OnRequest; 51 | } 52 | 53 | [WebInvoke] 54 | public void ResetData() 55 | { 56 | this.CurrentDataSource.ResetData(); 57 | } 58 | 59 | private static void UnauthorizedRequest(DataServiceOperationContext context) 60 | { 61 | context.ResponseHeaders["WWW-Authenticate"] = "Basic realm=\"DataJS.Tests\""; 62 | throw new DataServiceException(401, "401 Unauthorized"); 63 | } 64 | 65 | private void OnRequest(object sender, DataServiceProcessingPipelineEventArgs e) 66 | { 67 | string authHeader = e.OperationContext.RequestHeaders["Authorization"]; 68 | 69 | // Validate the Authorization header 70 | if (authHeader == null || !authHeader.StartsWith("Basic")) 71 | { 72 | UnauthorizedRequest(e.OperationContext); 73 | } 74 | 75 | // Decode the username and password from the header 76 | string base64Credentials = authHeader.Substring(6); 77 | string[] credentials = Encoding.ASCII.GetString(Convert.FromBase64String(base64Credentials)).Split(':'); 78 | if (credentials.Length != 2 || !(credentials[0].Equals(Username) && credentials[1].Equals(Password))) 79 | { 80 | UnauthorizedRequest(e.OperationContext); 81 | } 82 | } 83 | } 84 | 85 | public class BasicAuthDataSource : ReflectionDataContext, IUpdatable 86 | { 87 | private static bool dataInitialized; 88 | 89 | public IQueryable Customers 90 | { 91 | get { return this.GetResourceSetEntities("Customers").AsQueryable(); } 92 | } 93 | 94 | public void ResetData() 95 | { 96 | this.ClearData(); 97 | 98 | IList customers = this.GetResourceSetEntities("Customers"); 99 | foreach (int i in Enumerable.Range(1, 16)) 100 | { 101 | customers.Add(new Customer() 102 | { 103 | ID = i, 104 | Name = "Customer " + i 105 | }); 106 | } 107 | } 108 | 109 | protected override void EnsureDataIsInitialized() 110 | { 111 | if (!dataInitialized) 112 | { 113 | this.ResetData(); 114 | dataInitialized = true; 115 | } 116 | } 117 | } 118 | 119 | public class Customer 120 | { 121 | public int ID { get; set; } 122 | public string Name { get; set; } 123 | } 124 | } -------------------------------------------------------------------------------- /tests/endpoints/CustomDataService.svc: -------------------------------------------------------------------------------- 1 |  21 | 22 | <%@ ServiceHost Language="C#" Debug="true" Factory="System.ServiceModel.Activation.WebServiceHostFactory" 23 | Service="DataJS.Tests.CustomDataService" %> 24 | 25 | 26 | using System.Collections; 27 | using System.IO; 28 | 29 | namespace DataJS.Tests 30 | { 31 | using System; 32 | using System.Collections.Generic; 33 | using System.Linq; 34 | using System.ServiceModel; 35 | using System.ServiceModel.Activation; 36 | using System.ServiceModel.Web; 37 | 38 | /// 39 | /// Custom data service that does not use OData 40 | /// 41 | [ServiceContract] 42 | [ServiceBehavior(IncludeExceptionDetailInFaults = true)] 43 | [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] 44 | public class CustomDataService 45 | { 46 | static readonly Item[] data = Enumerable.Range(0, 16).Select(i => new Item 47 | { 48 | ID = i, 49 | Name = "Item " + i 50 | }).ToArray(); 51 | 52 | // This uses the same URI template as OData so that the CacheVerifier can be reused 53 | [OperationContract] 54 | [WebGet(UriTemplate = "ReadRange?$skip={skip}&$top={top}")] 55 | public Stream ReadRange(int skip, int top) 56 | { 57 | IEnumerable selectData = data.Skip(skip).Take(top); 58 | Dictionary result = new Dictionary(); 59 | List> value = new List>(); 60 | foreach (Item d in selectData) 61 | { 62 | Dictionary item = new Dictionary(); 63 | item.Add("ID", d.ID.ToString()); 64 | item.Add("Name", d.Name); 65 | value.Add(item); 66 | } 67 | 68 | result.Add("value", value); 69 | return ReaderUtils.ConvertDictionarytoJsonlightStream(result); 70 | } 71 | 72 | [OperationContract] 73 | [WebGet(ResponseFormat = WebMessageFormat.Json)] 74 | public int Count() 75 | { 76 | return data.Count(); 77 | } 78 | } 79 | 80 | public class Item 81 | { 82 | public int ID { get; set; } 83 | public string Name { get; set; } 84 | } 85 | } -------------------------------------------------------------------------------- /tests/endpoints/ErrorDataService.svc: -------------------------------------------------------------------------------- 1 | 21 | 22 | <%@ ServiceHost Language="C#" Factory="Microsoft.OData.Service.DataServiceHostFactory, Microsoft.OData.Service, Version=6.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" 23 | Service="DataJS.Tests.ErrorDataService" %> 24 | 25 | 26 | 27 | namespace DataJS.Tests 28 | { 29 | using System; 30 | using System.Collections.Generic; 31 | using Microsoft.OData.Service; 32 | using System.Linq; 33 | 34 | /// 35 | /// A data service that contains in-stream errors 36 | /// 37 | public class ErrorDataService : DataService 38 | { 39 | // This method is called only once to initialize service-wide policies. 40 | public static void InitializeService(DataServiceConfiguration config) 41 | { 42 | config.SetEntitySetAccessRule("*", EntitySetRights.All); 43 | config.DataServiceBehavior.MaxProtocolVersion = Microsoft.OData.Client.ODataProtocolVersion.V4; 44 | } 45 | } 46 | 47 | public class ErrorDataSource 48 | { 49 | public IQueryable Entities 50 | { 51 | get 52 | { 53 | ErrorType[] entities = new ErrorType[] 54 | { 55 | new ErrorType(() => 0), 56 | new ErrorType(() => { throw new ApplicationException(); }) 57 | }; 58 | 59 | return entities.AsQueryable(); 60 | } 61 | } 62 | } 63 | 64 | public class ErrorType 65 | { 66 | Func generateID; 67 | 68 | public ErrorType(Func generateID) 69 | { 70 | this.generateID = generateID; 71 | } 72 | 73 | public int ID 74 | { 75 | get { return this.generateID(); } 76 | } 77 | } 78 | } -------------------------------------------------------------------------------- /tests/endpoints/LargeCollectionService.svc: -------------------------------------------------------------------------------- 1 | 21 | 22 | <%@ ServiceHost Language="C#" Factory="Microsoft.OData.Service.DataServiceHostFactory, Microsoft.OData.Service, Version=6.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" 23 | Service="DataJS.Tests.LargeCollectionService" %> 24 | 25 | namespace DataJS.Tests 26 | { 27 | using System; 28 | using System.Collections.Generic; 29 | using Microsoft.OData.Service; 30 | using System.Linq; 31 | using System.ServiceModel; 32 | using System.ServiceModel.Web; 33 | using System.Web; 34 | 35 | [ServiceBehavior(IncludeExceptionDetailInFaults = true)] 36 | public class LargeCollectionService : DataService 37 | { 38 | // This method is called only once to initialize service-wide policies. 39 | public static void InitializeService(DataServiceConfiguration config) 40 | { 41 | config.SetEntitySetAccessRule("*", EntitySetRights.All); 42 | config.SetServiceOperationAccessRule("*", ServiceOperationRights.All); 43 | config.UseVerboseErrors = true; 44 | } 45 | 46 | [WebInvoke] 47 | public void ResetData() 48 | { 49 | this.CurrentDataSource.ResetData(); 50 | } 51 | } 52 | 53 | public class LargeCollection : ReflectionDataContext, IUpdatable 54 | { 55 | private static bool dataInitialized; 56 | 57 | public IQueryable Customers 58 | { 59 | get { return this.GetResourceSetEntities("Customers").AsQueryable(); } 60 | } 61 | 62 | public IQueryable Suppliers 63 | { 64 | get { return this.GetResourceSetEntities("Suppliers").AsQueryable(); } 65 | } 66 | 67 | public void ResetData() 68 | { 69 | this.ClearData(); 70 | 71 | IList customers = this.GetResourceSetEntities("Customers"); 72 | foreach (int i in Enumerable.Range(1, 2 * 1024 * 1024)) 73 | { 74 | customers.Add(new Customer() 75 | { 76 | ID = i, 77 | Name = "Customer " + i 78 | }); 79 | } 80 | 81 | IList suppliers = this.GetResourceSetEntities("Suppliers"); 82 | foreach (int i in Enumerable.Range(1, 5000)) 83 | { 84 | suppliers.Add(new Supplier() 85 | { 86 | ID = i, 87 | Name = "Supplier " + i 88 | }); 89 | } 90 | } 91 | 92 | protected override void EnsureDataIsInitialized() 93 | { 94 | if (!dataInitialized) 95 | { 96 | this.ResetData(); 97 | dataInitialized = true; 98 | } 99 | } 100 | } 101 | 102 | public class Customer 103 | { 104 | public int ID { get; set; } 105 | public string Name { get; set; } 106 | } 107 | 108 | public class Supplier 109 | { 110 | public int ID { get; set; } 111 | public string Name { get; set; } 112 | } 113 | } -------------------------------------------------------------------------------- /tests/endpoints/web.config: -------------------------------------------------------------------------------- 1 | 2 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /tests/info.txt: -------------------------------------------------------------------------------- 1 | Chrome 41 and Firefox 35 2 | *OK 115 / 125 odata-batch-functional-tests.html 3 | *OK 904 / 904 odata-cache-filter-functional-tests.html 4 | *OK 12 / 12 odata-cache-fperf-tests.html 5 | *OK 1062 / 1062 odata-cache-functional-tests.html 6 | *OK 42 / 42 odata-cache-rx-functional-tests.html 7 | *OK odata-fuzz.html 8 | *OK 27 / 27 odata-json-parse-tests.html 9 | *OK 16 / 16 odata-links-functional-tests.html 10 | FAIL 23 / 52 odata-metadata-awareness-functional-tests.html ----> Tests 1-6 OK; Accepted: Tests 7-27 are using old __metadata 11 | *OK 36 / 36 odata-perf-tests.html 12 | *OK 975 / 975 odata-qunit-tests.htm 13 | FAIL 0 / 31 odata-read-crossdomain-functional-tests.html ----> Accepted: calls to odatasampleservices.azurewebsites.net fail 14 | *OK 124/124 odata-read-functional-tests.html 15 | *OK 52/ 52 odata-request-functional-tests.html 16 | *OK 41/ 42 odatajs-cache-large-collection-functional-tests.html ------> Accepted: one timeout on server side, no bug on client side 17 | FAIL odatajs-cache-long-haul-tests.html -------> Accepted: uses netflix 18 | *OK 2/ 2 odatajs-startup-perf-test.html 19 | ?? test-manager.html 20 | 21 | 22 | Test results by IE on win8.1: 23 | *OK 115 / 115 passed, 0 failed. odata-batch-functional-tests.html 24 | *OK 904 / 904 passed, 0 failed. odata-cache-filter-functional-tests.html 25 | *OK 12 / 12 passed, 0 failed. odata-cache-fperf-tests.html 26 | *OK 1062 / 1062 passed, 0 failed. odata-cache-functional-tests.html 27 | *OK 42 / 42 passed, 0 failed. odata-cache-rx-functional-tests.html 28 | *OK odata-fuzz.html 29 | *OK 27 / 27 passed, 0 failed. odata-json-parse-tests.html 30 | *OK 16 / 16 passed, 0 failed. odata-links-functional-tests.html 31 | *OK 23 / 52 passed, 29 failed. odata-metadata-awareness-functional-tests.html ---> Test 1-6 OK. 32 | *OK 36 / 36 passed, 0 failed. odata-perf-tests.html 33 | *OK 975 / 975 passed, 0 failed. odata-qunit-tests.htm 34 | 15 / 44 passed, 29 failed. odata-read-crossdomain-functional-tests.html ---> 35 | *OK 124 / 124 passed, 0 failed. odata-read-functional-tests.html 36 | *OK 52 / 52 passed, 0 failed. odata-request-functional-tests.html 37 | *OK 41 / 42 passed, 1 failed. odatajs-cache-large-collection-functional-tests.html ---> 1 case timeout 38 | *OK 2 / 2 passed, 0 failed. odatajs-startup-perf-test.html 39 | -------------------------------------------------------------------------------- /tests/node-test-setup.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | //Creates the global objects 20 | 21 | //tools 22 | djstest = require("./common/djstest.js"); 23 | MockHttpClient = require("./common/mockHttpClient.js").init({}); 24 | 25 | //lib 26 | datajs = require('././lib/datajs.js'); 27 | OData = require('././odata.js'); 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /tests/odata-batch-functional-tests.html: -------------------------------------------------------------------------------- 1 |  21 | 22 | 23 | 24 | batch tests 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 |

batch tests

46 |

47 |

48 |
    49 | 50 | -------------------------------------------------------------------------------- /tests/odata-cache-filter-functional-tests.html: -------------------------------------------------------------------------------- 1 |  21 | 22 | 23 | 24 | datajs.cache filter functional tests 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 |

    datajs.cache filter functional tests

    49 |

    50 |

    51 |
      52 | 53 | -------------------------------------------------------------------------------- /tests/odata-cache-fperf-tests.html: -------------------------------------------------------------------------------- 1 |  21 | 22 | 23 | 24 | datajs.cache functional perf tests 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 |

      datajs.cache functional perf tests

      47 |

      48 |

      49 |
        50 | 51 | -------------------------------------------------------------------------------- /tests/odata-cache-fperf-tests.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | (function (window, undefined) { 21 | 22 | var slowHttpClient = { 23 | latency: 750, 24 | provider: window.odatajs.oData.net.defaultHttpClient, 25 | request: function (request, success, error) { 26 | setTimeout(function () { 27 | slowHttpClient.provider.request(request, success, error); 28 | }, slowHttpClient.latency); 29 | } 30 | }; 31 | 32 | var feeds = [ 33 | { uri: "./endpoints/FoodStoreDataServiceV4.svc/Foods" } 34 | ]; 35 | 36 | module("Functional", { 37 | setup: function () { 38 | window.odatajs.oData.net.defaultHttpClient = slowHttpClient; 39 | }, 40 | teardown: function () { 41 | window.odatajs.oData.net.defaultHttpClient = slowHttpClient.provider; 42 | } 43 | }); 44 | 45 | var cacheReadRangeWallClockTest = function (totalReads, interval, mechanism, source, pageSize, prefetchSize, generateRange, threshold) { 46 | /** Cache readRange wall-clock test 47 | * The average time computed by the wall-clock test does *not* include the initial readRange 48 | * @param totalReads - Number of reads to collect data from 49 | * @param interval - Interval (milliseconds) between reads 50 | * @param mechanism - The cache store mechanism 51 | * @param source - The feed source 52 | * @param pageSize - The page size 53 | * @param prefetchSize - The prefetch size 54 | * @param generateRange - The range generator function: given the read index, returns the readRange index and count 55 | * @param threshold - The average read time threshold for test to pass; if not specified, defaults to the slowHttpClient latency 56 | * @returns The test function 57 | */ 58 | return function () { 59 | var cache = odatajs.cache.createDataCache({ name: "cache" + new Date().valueOf(), source: source, pageSize: pageSize, prefetchSize: prefetchSize }); 60 | var totalTime = 0; 61 | var readCount = 0; 62 | 63 | var callReadRange = function () { 64 | var range = generateRange(readCount); 65 | var startTime = new Date().valueOf(); 66 | cache.readRange(range.index, range.count).then(function (data) { 67 | var duration = (new Date().valueOf()) - startTime; 68 | djstest.log("readRange " + readCount + " [" + range.index + ", " + range.count + "]: " + duration + "ms"); 69 | 70 | // The first readRange is not counted 71 | totalTime += (readCount > 0) ? duration : 0; 72 | readCount += 1; 73 | 74 | if (readCount < totalReads) { 75 | setTimeout(callReadRange, interval); 76 | } else { 77 | // The first readRange is not counted 78 | var averageTime = totalTime / (totalReads - 1); 79 | var actualThreshold = threshold === undefined ? slowHttpClient.latency : threshold; 80 | djstest.assert(averageTime < actualThreshold, "Average: " + averageTime + "ms, Threshold: " + actualThreshold + "ms"); 81 | djstest.destroyCacheAndDone(cache); 82 | } 83 | }, function (err) { 84 | djstest.fail("Unexpected call to error handler with error: " + djstest.toString(err)); 85 | djstest.destroyCacheAndDone(cache); 86 | }); 87 | }; 88 | 89 | callReadRange(); 90 | }; 91 | }; 92 | 93 | $.each(CacheVerifier.mechanisms, function (_, mechanism) { 94 | if (mechanism !== "best" && CacheVerifier.isMechanismAvailable(mechanism)) { 95 | $.each(feeds, function (_, feed) { 96 | djstest.addTest(cacheReadRangeWallClockTest(2, 1000, mechanism, feed.uri, 5, 0, function () { 97 | return { index: 0, count: 5 }; 98 | }), "Cache small single-page wall-clock test with " + mechanism + " on " + feed.uri); 99 | 100 | djstest.addTest(cacheReadRangeWallClockTest(5, 1000, mechanism, feed.uri, 3, -1, function (readCount) { 101 | return { index: readCount * 3, count: 3 }; 102 | }), "Cache page-by-page wall-clock test with " + mechanism + " on " + feed.uri); 103 | 104 | djstest.addTest(cacheReadRangeWallClockTest(5, 1000, mechanism, feed.uri, 3, -1, function (readCount) { 105 | return { index: readCount, count: 3 }; 106 | }), "Cache line-by-line wall-clock test with " + mechanism + " on " + feed.uri); 107 | }); 108 | 109 | var largeFeedUri = "./endpoints/LargeCollectionService.svc/Customers"; 110 | djstest.addTest(cacheReadRangeWallClockTest(2, 1000, mechanism, largeFeedUri, 100, 0, function () { 111 | return { index: 0, count: 500 }; 112 | }), "Cache large single-page wall-clock test with " + mechanism + " on " + largeFeedUri, undefined, 60000); 113 | } 114 | }); 115 | })(this); -------------------------------------------------------------------------------- /tests/odata-cache-functional-tests.html: -------------------------------------------------------------------------------- 1 |  21 | 22 | 23 | 24 | OData tests against local service 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 |

        datajs.cache tests against local in-memory service

        49 |

        50 |

        51 |
          52 | 53 | 54 | -------------------------------------------------------------------------------- /tests/odata-cache-rx-functional-tests.html: -------------------------------------------------------------------------------- 1 |  21 | 22 | 23 | 24 | >datajs.cache toObservable() tests 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 |

          datajs.cache toObservable() tests

          48 |

          49 |

          50 |
            51 | 52 | 53 | -------------------------------------------------------------------------------- /tests/odata-cache-rx-functional-tests.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | (function (window, undefined) { 21 | odatajs.oData.defaultHandler.accept = "application/json;q=0.9, */*;q=0.1"; 22 | var feeds = [ 23 | { uri: "./endpoints/FoodStoreDataServiceV4.svc/Foods" } 24 | ]; 25 | 26 | var itemsInCollection = 16; 27 | var pageSizes = [ 28 | 1, 29 | 4, // factor of total, <= server page size 30 | 5, // non-factor of total, <= server page size 31 | 6, // non-factor of total, > server page size 32 | 8, // factor of total, > server page size 33 | itemsInCollection, 34 | itemsInCollection + 1 35 | ]; 36 | 37 | var operatorTests = [ 38 | function (observable) { 39 | return observable.take(0); 40 | }, 41 | function (observable) { 42 | return observable.take(1); 43 | }, 44 | function (observable) { 45 | return observable.skip(1); 46 | }, 47 | function (observable) { 48 | return observable.skip(2).take(4); 49 | }, 50 | function (observable) { 51 | return observable.select(function (item) { return item.Name; }); 52 | }, 53 | function (observable) { 54 | return observable.where(function (item) { return item.FoodID % 2 === 1; }); 55 | } 56 | ]; 57 | 58 | /** Asserts two finite observables generate the same sequence 59 | * @param {Object} actual - The actual observable 60 | * @param {Object} expected - The expected observable 61 | * @param {Function} done - The callback function when asserts are done 62 | */ 63 | var assertObservables = function (actual, expected, done) { 64 | 65 | var toArray = function (observable, callback) { 66 | var arr = []; 67 | observable.subscribe( 68 | function (item) { arr.push(item); }, 69 | function (err) { arr.push({ "__error__": err }); }, 70 | function () { callback(arr); }); 71 | }; 72 | 73 | toArray(actual, function (actualSequence) { 74 | toArray(expected, function (expectedSequence) { 75 | djstest.assertAreEqualDeep(actualSequence, expectedSequence, "Verify observable sequence"); 76 | done(); 77 | }); 78 | }); 79 | }; 80 | 81 | module("Functional"); 82 | $.each(feeds, function (_, feed) { 83 | $.each(pageSizes, function (_, pageSize) { 84 | $.each(operatorTests, function (_, operator) { 85 | var params = { feedUri: feed.uri, pageSize: pageSize, operator: operator }; 86 | djstest.addTest(function (params) { 87 | djstest.assertsExpected(1); 88 | var options = { name: "cache" + new Date().valueOf(), source: params.feedUri, pageSize: params.pageSize, prefetchSize: 0 }; 89 | var cache = odatajs.cache.createDataCache(options); 90 | 91 | ODataVerifyReader.readJsonAcrossServerPages(params.feedUri, function (collection) { 92 | assertObservables(params.operator(cache.toObservable()), params.operator(window.Rx.Observable.fromArray(collection.value)), function () { 93 | djstest.destroyCacheAndDone(cache); 94 | }); 95 | }); 96 | }, "feed: " + params.feedUri + ", pageSize: " + params.pageSize + ", operator: " + params.operator.toString(), params); 97 | }); 98 | }); 99 | }); 100 | })(this); 101 | -------------------------------------------------------------------------------- /tests/odata-json-parse-tests.html: -------------------------------------------------------------------------------- 1 | 21 | 22 | 23 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | OData unit tests 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 |

            OData Unit Tests

            63 |

            64 |

            65 |
              66 |
            67 | 68 | -------------------------------------------------------------------------------- /tests/odata-json-parse-tests.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | // odata-tests.js 21 | (function (window, undefined) { 22 | function errorFunc() { 23 | djstest.fail('Errror'); 24 | } 25 | 26 | function runWithMetadata(metaDatasuccess) { 27 | var oHeaders = { 28 | 'Accept': 'text/html,application/xhtml+xml,application/xml,application/json;odata.metadata=full', 29 | "Odata-Version": "4.0", 30 | "OData-MaxVersion": "4.0", 31 | "Prefer": "odata.allow-entityreferences" 32 | }; 33 | var metadataRequest = 34 | { 35 | headers: oHeaders, 36 | //requestUri: "http://services.odata.org/OData/OData.svc/$metadata", 37 | requestUri: "http://localhost:4002/tests/endpoints/FoodStoreDataServiceV4.svc/$metadata", //"http://localhost:6630/PrimitiveKeys.svc/$metadata", 38 | data: null 39 | }; 40 | odatajs.oData.read(metadataRequest, metaDatasuccess, errorFunc,odatajs.oData.metadataHandler); 41 | } 42 | 43 | djstest.addTest(function test1() { 44 | var checkAll = function (metadata, input, expected) { 45 | var info = window.odatajs.oData.json.createPayloadInfo({ "@odata.context" : input}, metadata); 46 | djstest.assertAreEqual(info,expected, "Test context fragment: "+ input); 47 | }; 48 | 49 | var checkLastTypeName = function (metadata, input, expectedKind, expectedLastTypeName) { 50 | var info = window.odatajs.oData.json.createPayloadInfo({ "@odata.context" : input}, metadata); 51 | djstest.assertAreEqual(info.detectedPayloadKind,expectedKind, "Test context fragment: "+ input); 52 | djstest.assertAreEqual(info.typeName,expectedLastTypeName, "Test context fragment: "+ input); 53 | }; 54 | 55 | var checkProjection = function (metadata, input, expectedKind, expectedLastTypeName, projection) { 56 | var info = window.odatajs.oData.json.createPayloadInfo({ "@odata.context" : input}, metadata); 57 | djstest.assertAreEqual(info.detectedPayloadKind,expectedKind, "Test context fragment: "+ input); 58 | djstest.assertAreEqual(info.typeName,expectedLastTypeName, "Test context fragment: "+ input); 59 | djstest.assertAreEqual(info.projection,projection, "Test context fragment: "+ input); 60 | }; 61 | 62 | var checkKind = function (metadata, input, expected) { 63 | var info = window.odatajs.oData.json.createPayloadInfo({ "@odata.context" : input}, metadata); 64 | djstest.assertAreEqual(info.detectedPayloadKind,expected, "Test context fragment: "+ input); 65 | }; 66 | 67 | var success = function(metadata){ 68 | //Chapter 10.1 69 | checkKind(metadata, '#', 's'); 70 | //Chapter 10.2 71 | checkLastTypeName(metadata, '#Foods', 'f', 'DataJS.Tests.V4.Food'); 72 | //Chapter 10.3 73 | checkLastTypeName(metadata, '#Foods/$entity', 'e', 'DataJS.Tests.V4.Food'); 74 | //Chapter 10.4 75 | //checkKind(metadata, '#Singleton', ''); 76 | //Chapter 10.5 77 | checkLastTypeName(metadata, '#Foods/DataJS.Tests.V4.Food', 'f', 'DataJS.Tests.V4.Food'); 78 | //Chapter 10.6 79 | checkLastTypeName(metadata, '#Foods/DataJS.Tests.V4.Food/$entity', 'e', 'DataJS.Tests.V4.Food'); 80 | //Chapter 10.7 81 | checkProjection(metadata, '#Foods(FoodID,Name)', 'f', 'DataJS.Tests.V4.Food','FoodID,Name'); 82 | //Chapter 10.8 83 | checkProjection(metadata, '#Foods(FoodID,Name)/$entity', 'e', 'DataJS.Tests.V4.Food','FoodID,Name'); 84 | //Chapter 10.9 85 | checkProjection(metadata, '#Foods(FoodID,Name,Category,Category+(CategoryID,Name))', 'f', 86 | 'DataJS.Tests.V4.Food','FoodID,Name,Category,Category+(CategoryID,Name)'); 87 | //Chapter 10.10 88 | checkProjection(metadata, '#Foods(FoodID,Name,Category,Category+(CategoryID,Name))/$entity', 'e', 89 | 'DataJS.Tests.V4.Food','FoodID,Name,Category,Category+(CategoryID,Name)'); 90 | //Chapter 10.11 91 | checkKind(metadata, '#Collection($ref)', 'erls'); 92 | //Chapter 10.12 93 | checkKind(metadata, '#$ref', 'erl'); 94 | //Chapter 10.13 95 | checkKind(metadata, '#Foods(0)/Packaging', 'p', 'DataJS.Tests.V4.Package'); 96 | //Chapter 10.14 97 | checkKind(metadata, '#Collection(Edm.String)', 'c', 'Edm.String'); 98 | //Chapter 10.15 99 | checkKind(metadata, '#Edm.String', 'v'); 100 | 101 | checkKind(metadata, '#Edm.Null', 'v'); 102 | //TODO add tests for delta tokens 103 | djstest.done(); 104 | }; 105 | 106 | runWithMetadata(success); 107 | },'test createPayloadInfo'); 108 | 109 | 110 | })(this); 111 | -------------------------------------------------------------------------------- /tests/odata-links-functional-tests.html: -------------------------------------------------------------------------------- 1 |  21 | 22 | 23 | 24 | OData tests against local service 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 |

            OData.Read tests against local in-memory service

            46 |

            47 |

            48 |
              49 | 50 | 51 | -------------------------------------------------------------------------------- /tests/odata-metadata-awareness-functional-tests.html: -------------------------------------------------------------------------------- 1 |  21 | 22 | 23 | 24 | metadata awareness tests 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 |

              metadata awareness tests

              45 |

              46 |

              47 |
                48 | 49 | -------------------------------------------------------------------------------- /tests/odata-perf-tests.html: -------------------------------------------------------------------------------- 1 |  21 | 22 | 23 | 24 | OData perf tests 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 |

                OData perf tests

                47 |

                48 |

                49 |
                  50 | 51 | -------------------------------------------------------------------------------- /tests/odata-qunit-tests.htm: -------------------------------------------------------------------------------- 1 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | OData unit tests 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 |

                  OData Unit Tests

                  71 |

                  72 |

                  73 |
                    74 |
                  75 | 76 | -------------------------------------------------------------------------------- /tests/odata-read-crossdomain-functional-tests.html: -------------------------------------------------------------------------------- 1 |  21 | 22 | 23 | 24 | OData tests against local service 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 |

                  OData.Read tests against cross domain endpoints

                  46 |

                  47 |

                  48 |
                    49 | 50 | -------------------------------------------------------------------------------- /tests/odata-read-functional-tests.html: -------------------------------------------------------------------------------- 1 |  21 | 22 | 23 | 24 | OData tests against local service 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 |

                    OData.Read tests against local in-memory service

                    46 |

                    47 |

                    48 |
                      49 | 50 | 51 | -------------------------------------------------------------------------------- /tests/odata-request-functional-tests.html: -------------------------------------------------------------------------------- 1 |  21 | 22 | 23 | 24 | odata.request tests 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 |

                      odata.request tests

                      46 |

                      47 |

                      48 |
                        49 | 50 | -------------------------------------------------------------------------------- /tests/odatajs-cache-large-collection-functional-tests.html: -------------------------------------------------------------------------------- 1 |  21 | 22 | 23 | odatajs.cache and odatajs.store full local store tests 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 |

                        odatajs.cache and odatajs.store full local store tests

                        49 |

                        50 |

                        51 |
                          52 | 53 | -------------------------------------------------------------------------------- /tests/odatajs-startup-perf-test.html: -------------------------------------------------------------------------------- 1 | 21 | 22 | 23 | 37 | 38 | 39 | datajs startup perf test 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 51 | 52 | 53 | 54 | 55 | 56 | 102 | 103 | 104 |

                          datajs startup perf test

                          105 |

                          106 |

                          107 |
                            108 |
                          109 | 110 | -------------------------------------------------------------------------------- /tests/test-list.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | // Test list for datajs tests 21 | 22 | function getAllTestFiles() { 23 | return [ 24 | "odata-qunit-tests.htm" 25 | ]; 26 | } -------------------------------------------------------------------------------- /tests/test-manager.html: -------------------------------------------------------------------------------- 1 |  21 | 22 | 23 | 24 | datajs test manager 25 | 26 | 27 | 83 | 84 | 85 |

                          datajs test manager

                          86 |
                          87 |

                          1. Create Test Run

                          88 |
                          89 |
                          Pages
                          90 |
                          91 |
                          92 |
                          Browser:
                          93 |
                          94 | 95 |
                          96 | 97 |

                          2. Run Tests

                          98 | Test Run ID: 99 | 100 |

                          3. View Results

                          101 | Test Run ID: 102 | 103 |
                          104 |

                          Active Runs

                          105 |
                          106 |
                          107 | 108 | --------------------------------------------------------------------------------