From f217e8103621cabbacf79fc8dcf9f51721377266 Mon Sep 17 00:00:00 2001 From: Andrey Shvydky Date: Tue, 29 Nov 2016 11:53:32 +0200 Subject: [PATCH 1/2] closed #95 ODataValue is extended with additional parameter isCustomType that allows to send type name and data value AS IS without any conversion in form "type'value'" --- .grunt/grunt-contrib-jasmine/boot.js | 2 +- .grunt/grunt-contrib-jasmine/jasmine-html.js | 22 +- .grunt/grunt-contrib-jasmine/jasmine.js | 369 ++++++-- _SpecRunner.html | 4 +- build/odataresources.js | 901 ++++++++++--------- build/odataresources.min.js | 4 +- src/odatavalue.js | 7 +- 7 files changed, 763 insertions(+), 546 deletions(-) diff --git a/.grunt/grunt-contrib-jasmine/boot.js b/.grunt/grunt-contrib-jasmine/boot.js index a1002de..2f39ce1 100644 --- a/.grunt/grunt-contrib-jasmine/boot.js +++ b/.grunt/grunt-contrib-jasmine/boot.js @@ -1,5 +1,5 @@ /* -Copyright (c) 2008-2015 Pivotal Labs +Copyright (c) 2008-2016 Pivotal Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/.grunt/grunt-contrib-jasmine/jasmine-html.js b/.grunt/grunt-contrib-jasmine/jasmine-html.js index da23532..233c982 100644 --- a/.grunt/grunt-contrib-jasmine/jasmine-html.js +++ b/.grunt/grunt-contrib-jasmine/jasmine-html.js @@ -1,5 +1,5 @@ /* -Copyright (c) 2008-2015 Pivotal Labs +Copyright (c) 2008-2016 Pivotal Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the @@ -209,9 +209,10 @@ jasmineRequire.HtmlReporter = function(j$) { if (specsExecuted < totalSpecsDefined) { var skippedMessage = 'Ran ' + specsExecuted + ' of ' + totalSpecsDefined + ' specs - run all'; + var skippedLink = order && order.random ? '?random=true' : '?'; alert.appendChild( createDom('span', {className: 'jasmine-bar jasmine-skipped'}, - createDom('a', {href: '?', title: 'Run all specs'}, skippedMessage) + createDom('a', {href: skippedLink, title: 'Run all specs'}, skippedMessage) ) ); } @@ -237,15 +238,22 @@ jasmineRequire.HtmlReporter = function(j$) { alert.appendChild(createDom('span', {className: statusBarClassName}, statusBarMessage, seedBar)); - for(i = 0; i < failedSuites.length; i++) { + var errorBarClassName = 'jasmine-bar jasmine-errored'; + var errorBarMessagePrefix = 'AfterAll '; + + for(var i = 0; i < failedSuites.length; i++) { var failedSuite = failedSuites[i]; for(var j = 0; j < failedSuite.failedExpectations.length; j++) { - var errorBarMessage = 'AfterAll ' + failedSuite.failedExpectations[j].message; - var errorBarClassName = 'jasmine-bar jasmine-errored'; - alert.appendChild(createDom('span', {className: errorBarClassName}, errorBarMessage)); + alert.appendChild(createDom('span', {className: errorBarClassName}, errorBarMessagePrefix + failedSuite.failedExpectations[j].message)); } } + var globalFailures = (doneResult && doneResult.failedExpectations) || []; + for(i = 0; i < globalFailures.length; i++) { + var failure = globalFailures[i]; + alert.appendChild(createDom('span', {className: errorBarClassName}, errorBarMessagePrefix + failure.message)); + } + var results = find('.jasmine-results'); results.appendChild(summary); @@ -309,7 +317,7 @@ jasmineRequire.HtmlReporter = function(j$) { setMenuModeTo('jasmine-failure-list'); var failureNode = find('.jasmine-failures'); - for (var i = 0; i < failures.length; i++) { + for (i = 0; i < failures.length; i++) { failureNode.appendChild(failures[i]); } } diff --git a/.grunt/grunt-contrib-jasmine/jasmine.js b/.grunt/grunt-contrib-jasmine/jasmine.js index bea469d..7cab7e0 100644 --- a/.grunt/grunt-contrib-jasmine/jasmine.js +++ b/.grunt/grunt-contrib-jasmine/jasmine.js @@ -1,5 +1,5 @@ /* -Copyright (c) 2008-2015 Pivotal Labs +Copyright (c) 2008-2016 Pivotal Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the @@ -23,7 +23,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. var getJasmineRequireObj = (function (jasmineGlobal) { var jasmineRequire; - if (typeof module !== 'undefined' && module.exports) { + if (typeof module !== 'undefined' && module.exports && typeof exports !== 'undefined') { if (typeof global !== 'undefined') { jasmineGlobal = global; } else { @@ -47,9 +47,10 @@ var getJasmineRequireObj = (function (jasmineGlobal) { jRequire.base(j$, jasmineGlobal); j$.util = jRequire.util(); j$.errors = jRequire.errors(); + j$.formatErrorMsg = jRequire.formatErrorMsg(); j$.Any = jRequire.Any(j$); j$.Anything = jRequire.Anything(j$); - j$.CallTracker = jRequire.CallTracker(); + j$.CallTracker = jRequire.CallTracker(j$); j$.MockDate = jRequire.MockDate(); j$.Clock = jRequire.Clock(); j$.DelayedFunctionScheduler = jRequire.DelayedFunctionScheduler(); @@ -66,7 +67,7 @@ var getJasmineRequireObj = (function (jasmineGlobal) { j$.ReportDispatcher = jRequire.ReportDispatcher(); j$.Spec = jRequire.Spec(j$); j$.SpyRegistry = jRequire.SpyRegistry(j$); - j$.SpyStrategy = jRequire.SpyStrategy(); + j$.SpyStrategy = jRequire.SpyStrategy(j$); j$.StringMatching = jRequire.StringMatching(j$); j$.Suite = jRequire.Suite(j$); j$.Timer = jRequire.Timer(); @@ -89,6 +90,8 @@ getJasmineRequireObj().requireMatchers = function(jRequire, j$) { 'toBeDefined', 'toBeFalsy', 'toBeGreaterThan', + 'toBeGreaterThanOrEqual', + 'toBeLessThanOrEqual', 'toBeLessThan', 'toBeNaN', 'toBeNull', @@ -144,6 +147,10 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) { return j$.isA_('Number', value); }; + j$.isFunction_ = function(value) { + return j$.isA_('Function', value); + }; + j$.isA_ = function(typeName, value) { return Object.prototype.toString.apply(value) === '[object ' + typeName + ']'; }; @@ -153,7 +160,12 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) { }; j$.fnNameFor = function(func) { - return func.name || func.toString().match(/^\s*function\s*(\w*)\s*\(/)[1]; + if (func.name) { + return func.name; + } + + var matches = func.toString().match(/^\s*function\s*(\w*)\s*\(/); + return matches ? matches[1] : ''; }; j$.any = function(clazz) { @@ -515,7 +527,6 @@ getJasmineRequireObj().Env = function(j$) { var realClearTimeout = j$.getGlobal().clearTimeout; this.clock = new j$.Clock(global, function () { return new j$.DelayedFunctionScheduler(); }, new j$.MockDate(global)); - var runnableLookupTable = {}; var runnableResources = {}; var currentSpec = null; @@ -625,7 +636,13 @@ getJasmineRequireObj().Env = function(j$) { }; var getSpecName = function(spec, suite) { - return suite.getFullName() + ' ' + spec.description; + var fullName = [spec.description], + suiteFullName = suite.getFullName(); + + if (suiteFullName !== '') { + fullName.unshift(suiteFullName); + } + return fullName.join(' '); }; // TODO: we may just be able to pass in the fn instead of wrapping here @@ -701,9 +718,9 @@ getJasmineRequireObj().Env = function(j$) { env: this, id: getNextSuiteId(), description: 'Jasmine__TopLevel__Suite', - queueRunner: queueRunnerFactory + expectationFactory: expectationFactory, + expectationResultFactory: expectationResultFactory }); - runnableLookupTable[topSuite.id] = topSuite; defaultResourcesForRunnable(topSuite.id); currentDeclarationSuite = topSuite; @@ -754,9 +771,15 @@ getJasmineRequireObj().Env = function(j$) { totalSpecsDefined: totalSpecsDefined }); + currentlyExecutingSuites.push(topSuite); + processor.execute(function() { + clearResourcesForRunnable(topSuite.id); + currentlyExecutingSuites.pop(); + reporter.jasmineDone({ - order: order + order: order, + failedExpectations: topSuite.result.failedExpectations }); }); }; @@ -765,6 +788,14 @@ getJasmineRequireObj().Env = function(j$) { reporter.addReporter(reporterToAdd); }; + this.provideFallbackReporter = function(reporterToAdd) { + reporter.provideFallbackReporter(reporterToAdd); + }; + + this.clearReporters = function() { + reporter.clearReporters(); + }; + var spyRegistry = new j$.SpyRegistry({currentSpies: function() { if(!currentRunnable()) { throw new Error('Spies must be created in a before function or a spec'); @@ -772,6 +803,10 @@ getJasmineRequireObj().Env = function(j$) { return runnableResources[currentRunnable().id].spies; }}); + this.allowRespy = function(allow){ + spyRegistry.allowRespy(allow); + }; + this.spyOn = function() { return spyRegistry.spyOn.apply(spyRegistry, arguments); }; @@ -787,14 +822,13 @@ getJasmineRequireObj().Env = function(j$) { throwOnExpectationFailure: throwOnExpectationFailure }); - runnableLookupTable[suite.id] = suite; return suite; }; this.describe = function(description, specDefinitions) { var suite = suiteFactory(description); if (specDefinitions.length > 0) { - throw new Error('describe does not expect a done parameter'); + throw new Error('describe does not expect any arguments'); } if (currentDeclarationSuite.markedPending) { suite.pend(); @@ -889,8 +923,6 @@ getJasmineRequireObj().Env = function(j$) { throwOnExpectationFailure: throwOnExpectationFailure }); - runnableLookupTable[spec.id] = spec; - if (!self.specFilter(spec)) { spec.disable(); } @@ -1079,12 +1111,29 @@ getJasmineRequireObj().JsApiReporter = function() { return JsApiReporter; }; -getJasmineRequireObj().CallTracker = function() { +getJasmineRequireObj().CallTracker = function(j$) { function CallTracker() { var calls = []; + var opts = {}; + + function argCloner(context) { + var clonedArgs = []; + var argsAsArray = j$.util.argsToArray(context.args); + for(var i = 0; i < argsAsArray.length; i++) { + if(Object.prototype.toString.apply(argsAsArray[i]).match(/^\[object/)) { + clonedArgs.push(j$.util.clone(argsAsArray[i])); + } else { + clonedArgs.push(argsAsArray[i]); + } + } + context.args = clonedArgs; + } this.track = function(context) { + if(opts.cloneArgs) { + argCloner(context); + } calls.push(context); }; @@ -1125,6 +1174,11 @@ getJasmineRequireObj().CallTracker = function() { this.reset = function() { calls = []; }; + + this.saveArgumentsByValue = function() { + opts.cloneArgs = true; + }; + } return CallTracker; @@ -1214,8 +1268,7 @@ getJasmineRequireObj().Clock = function() { self.tick = function(millis) { if (installed) { - mockDate.tick(millis); - delayedFunctionScheduler.tick(millis); + delayedFunctionScheduler.tick(millis, function(millis) { mockDate.tick(millis); }); } else { throw new Error('Mock clock is not installed, use jasmine.clock().install()'); } @@ -1273,11 +1326,11 @@ getJasmineRequireObj().DelayedFunctionScheduler = function() { var currentTime = 0; var delayedFnCount = 0; - self.tick = function(millis) { + self.tick = function(millis, tickDate) { millis = millis || 0; var endTime = currentTime + millis; - runScheduledFunctions(endTime); + runScheduledFunctions(endTime, tickDate); currentTime = endTime; }; @@ -1380,13 +1433,18 @@ getJasmineRequireObj().DelayedFunctionScheduler = function() { } } - function runScheduledFunctions(endTime) { + function runScheduledFunctions(endTime, tickDate) { + tickDate = tickDate || function() {}; if (scheduledLookup.length === 0 || scheduledLookup[0] > endTime) { + tickDate(endTime - currentTime); return; } do { - currentTime = scheduledLookup.shift(); + var newCurrentTime = scheduledLookup.shift(); + tickDate(newCurrentTime - currentTime); + + currentTime = newCurrentTime; var funcsToRun = scheduledFunctions[currentTime]; delete scheduledFunctions[currentTime]; @@ -1405,6 +1463,11 @@ getJasmineRequireObj().DelayedFunctionScheduler = function() { // scheduled in a funcToRun from forcing an extra iteration currentTime !== endTime && scheduledLookup[0] <= endTime); + + // ran out of functions to call, but still time left on the clock + if (currentTime !== endTime) { + tickDate(endTime - currentTime); + } } } @@ -1841,6 +1904,7 @@ getJasmineRequireObj().QueueRunner = function(j$) { called = true; fn(); } + return null; }; } @@ -1952,14 +2016,26 @@ getJasmineRequireObj().ReportDispatcher = function() { } var reporters = []; + var fallbackReporter = null; this.addReporter = function(reporter) { reporters.push(reporter); }; + this.provideFallbackReporter = function(reporter) { + fallbackReporter = reporter; + }; + + this.clearReporters = function() { + reporters = []; + }; + return this; function dispatch(method, args) { + if (reporters.length === 0 && fallbackReporter !== null) { + reporters.push(fallbackReporter); + } for (var i = 0; i < reporters.length; i++) { var reporter = reporters[i]; if (reporter[method]) { @@ -1975,26 +2051,36 @@ getJasmineRequireObj().ReportDispatcher = function() { getJasmineRequireObj().SpyRegistry = function(j$) { + var getErrorMsg = j$.formatErrorMsg('', 'spyOn(, )'); + function SpyRegistry(options) { options = options || {}; var currentSpies = options.currentSpies || function() { return []; }; + this.allowRespy = function(allow){ + this.respy = allow; + }; + this.spyOn = function(obj, methodName) { + if (j$.util.isUndefined(obj)) { - throw new Error('spyOn could not find an object to spy upon for ' + methodName + '()'); + throw new Error(getErrorMsg('could not find an object to spy upon for ' + methodName + '()')); } if (j$.util.isUndefined(methodName)) { - throw new Error('No method name supplied'); + throw new Error(getErrorMsg('No method name supplied')); } if (j$.util.isUndefined(obj[methodName])) { - throw new Error(methodName + '() method does not exist'); + throw new Error(getErrorMsg(methodName + '() method does not exist')); } - if (obj[methodName] && j$.isSpy(obj[methodName])) { - //TODO?: should this return the current spy? Downside: may cause user confusion about spy state - throw new Error(methodName + ' has already been spied upon'); + if (obj[methodName] && j$.isSpy(obj[methodName]) ) { + if ( !!this.respy ){ + return obj[methodName]; + }else { + throw new Error(getErrorMsg(methodName + ' has already been spied upon')); + } } var descriptor; @@ -2005,28 +2091,39 @@ getJasmineRequireObj().SpyRegistry = function(j$) { } if (descriptor && !(descriptor.writable || descriptor.set)) { - throw new Error(methodName + ' is not declared writable or has no setter'); + throw new Error(getErrorMsg(methodName + ' is not declared writable or has no setter')); } - var spy = j$.createSpy(methodName, obj[methodName]); + var originalMethod = obj[methodName], + spiedMethod = j$.createSpy(methodName, originalMethod), + restoreStrategy; + + if (Object.prototype.hasOwnProperty.call(obj, methodName)) { + restoreStrategy = function() { + obj[methodName] = originalMethod; + }; + } else { + restoreStrategy = function() { + if (!delete obj[methodName]) { + obj[methodName] = originalMethod; + } + }; + } currentSpies().push({ - spy: spy, - baseObj: obj, - methodName: methodName, - originalValue: obj[methodName] + restoreObjectToOriginalState: restoreStrategy }); - obj[methodName] = spy; + obj[methodName] = spiedMethod; - return spy; + return spiedMethod; }; this.clearSpies = function() { var spies = currentSpies(); - for (var i = 0; i < spies.length; i++) { + for (var i = spies.length - 1; i >= 0; i--) { var spyEntry = spies[i]; - spyEntry.baseObj[spyEntry.methodName] = spyEntry.originalValue; + spyEntry.restoreObjectToOriginalState(); } }; } @@ -2034,7 +2131,7 @@ getJasmineRequireObj().SpyRegistry = function(j$) { return SpyRegistry; }; -getJasmineRequireObj().SpyStrategy = function() { +getJasmineRequireObj().SpyStrategy = function(j$) { function SpyStrategy(options) { options = options || {}; @@ -2081,6 +2178,9 @@ getJasmineRequireObj().SpyStrategy = function() { }; this.callFake = function(fn) { + if(!j$.isFunction_(fn)) { + throw new Error('Argument passed to callFake should be a function, got ' + fn); + } plan = fn; return getSpy(); }; @@ -2125,13 +2225,13 @@ getJasmineRequireObj().Suite = function(j$) { }; Suite.prototype.getFullName = function() { - var fullName = this.description; - for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) { + var fullName = []; + for (var parentSuite = this; parentSuite; parentSuite = parentSuite.parentSuite) { if (parentSuite.parentSuite) { - fullName = parentSuite.description + ' ' + fullName; + fullName.unshift(parentSuite.description); } } - return fullName; + return fullName.join(' '); }; Suite.prototype.disable = function() { @@ -2665,6 +2765,18 @@ getJasmineRequireObj().errors = function() { ExpectationFailed: ExpectationFailed }; }; +getJasmineRequireObj().formatErrorMsg = function() { + function generateErrorMsg(domain, usage) { + var usageDefinition = usage ? '\nUsage: ' + usage : ''; + + return function errorMsg(msg) { + return domain + ' : ' + msg + usageDefinition; + }; + } + + return generateErrorMsg; +}; + getJasmineRequireObj().matchersUtil = function(j$) { // TODO: what to do about jasmine.pp not being inject? move to JSON.stringify? gut PrettyPrinter? @@ -2828,35 +2940,43 @@ getJasmineRequireObj().matchersUtil = function(j$) { var size = 0; // Recursively compare objects and arrays. // Compare array lengths to determine if a deep comparison is necessary. - if (className == '[object Array]' && a.length !== b.length) { - result = false; - } + if (className == '[object Array]') { + size = a.length; + if (size !== b.length) { + return false; + } - if (result) { - // Objects with different constructors are not equivalent, but `Object`s - // or `Array`s from different frames are. - if (className !== '[object Array]') { - var aCtor = a.constructor, bCtor = b.constructor; - if (aCtor !== bCtor && !(isFunction(aCtor) && aCtor instanceof aCtor && - isFunction(bCtor) && bCtor instanceof bCtor)) { + while (size--) { + result = eq(a[size], b[size], aStack, bStack, customTesters); + if (!result) { return false; } } - // Deep compare objects. - for (var key in a) { - if (has(a, key)) { - // Count the expected number of properties. - size++; - // Deep compare each member. - if (!(result = has(b, key) && eq(a[key], b[key], aStack, bStack, customTesters))) { break; } - } + } else { + + // Objects with different constructors are not equivalent, but `Object`s + // or `Array`s from different frames are. + var aCtor = a.constructor, bCtor = b.constructor; + if (aCtor !== bCtor && !(isObjectConstructor(aCtor) && + isObjectConstructor(bCtor))) { + return false; } - // Ensure that both objects contain the same number of properties. - if (result) { - for (key in b) { - if (has(b, key) && !(size--)) { break; } - } - result = !size; + } + + // Deep compare objects. + var aKeys = keys(a, className == '[object Array]'), key; + size = aKeys.length; + + // Ensure that both objects contain the same number of properties before comparing deep equality. + if (keys(b, className == '[object Array]').length !== size) { return false; } + + while (size--) { + key = aKeys[size]; + // Deep compare each member + result = has(b, key) && eq(a[key], b[key], aStack, bStack, customTesters); + + if (!result) { + return false; } } // Remove the first object from the stack of traversed objects. @@ -2865,14 +2985,52 @@ getJasmineRequireObj().matchersUtil = function(j$) { return result; - function has(obj, key) { - return Object.prototype.hasOwnProperty.call(obj, key); - } + function keys(obj, isArray) { + var allKeys = Object.keys ? Object.keys(obj) : + (function(o) { + var keys = []; + for (var key in o) { + if (has(o, key)) { + keys.push(key); + } + } + return keys; + })(obj); - function isFunction(obj) { - return typeof obj === 'function'; + if (!isArray) { + return allKeys; + } + + var extraKeys = []; + if (allKeys.length === 0) { + return allKeys; + } + + for (var x = 0; x < allKeys.length; x++) { + if (!allKeys[x].match(/^[0-9]+$/)) { + extraKeys.push(allKeys[x]); + } + } + + return extraKeys; } } + + function has(obj, key) { + return Object.prototype.hasOwnProperty.call(obj, key); + } + + function isFunction(obj) { + return typeof obj === 'function'; + } + + function isObjectConstructor(ctor) { + // aCtor instanceof aCtor is true for the Object and Function + // constructors (since a constructor is-a Function and a function is-a + // Object). We don't just compare ctor === Object because the constructor + // might come from a different frame with different globals. + return isFunction(ctor) && ctor instanceof ctor; + } }; getJasmineRequireObj().toBe = function() { @@ -2952,6 +3110,21 @@ getJasmineRequireObj().toBeGreaterThan = function() { }; +getJasmineRequireObj().toBeGreaterThanOrEqual = function() { + + function toBeGreaterThanOrEqual() { + return { + compare: function(actual, expected) { + return { + pass: actual >= expected + }; + } + }; + } + + return toBeGreaterThanOrEqual; +}; + getJasmineRequireObj().toBeLessThan = function() { function toBeLessThan() { return { @@ -2966,6 +3139,21 @@ getJasmineRequireObj().toBeLessThan = function() { return toBeLessThan; }; +getJasmineRequireObj().toBeLessThanOrEqual = function() { + function toBeLessThanOrEqual() { + return { + + compare: function(actual, expected) { + return { + pass: actual <= expected + }; + } + }; + } + + return toBeLessThanOrEqual; +}; + getJasmineRequireObj().toBeNaN = function(j$) { function toBeNaN() { @@ -3074,17 +3262,19 @@ getJasmineRequireObj().toEqual = function() { getJasmineRequireObj().toHaveBeenCalled = function(j$) { + var getErrorMsg = j$.formatErrorMsg('', 'expect().toHaveBeenCalled()'); + function toHaveBeenCalled() { return { compare: function(actual) { var result = {}; if (!j$.isSpy(actual)) { - throw new Error('Expected a spy, but got ' + j$.pp(actual) + '.'); + throw new Error(getErrorMsg('Expected a spy, but got ' + j$.pp(actual) + '.')); } if (arguments.length > 1) { - throw new Error('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith'); + throw new Error(getErrorMsg('Does not take arguments, use toHaveBeenCalledWith')); } result.pass = actual.calls.any(); @@ -3103,18 +3293,20 @@ getJasmineRequireObj().toHaveBeenCalled = function(j$) { getJasmineRequireObj().toHaveBeenCalledTimes = function(j$) { + var getErrorMsg = j$.formatErrorMsg('', 'expect().toHaveBeenCalledTimes()'); + function toHaveBeenCalledTimes() { return { compare: function(actual, expected) { if (!j$.isSpy(actual)) { - throw new Error('Expected a spy, but got ' + j$.pp(actual) + '.'); + throw new Error(getErrorMsg('Expected a spy, but got ' + j$.pp(actual) + '.')); } var args = Array.prototype.slice.call(arguments, 0), result = { pass: false }; - if(!expected){ - throw new Error('Expected times failed is required as an argument.'); + if (!j$.isNumber_(expected)){ + throw new Error(getErrorMsg('The expected times failed is a required argument and must be a number.')); } actual = args[0]; @@ -3134,6 +3326,8 @@ getJasmineRequireObj().toHaveBeenCalledTimes = function(j$) { getJasmineRequireObj().toHaveBeenCalledWith = function(j$) { + var getErrorMsg = j$.formatErrorMsg('', 'expect().toHaveBeenCalledWith(...arguments)'); + function toHaveBeenCalledWith(util, customEqualityTesters) { return { compare: function() { @@ -3143,7 +3337,7 @@ getJasmineRequireObj().toHaveBeenCalledWith = function(j$) { result = { pass: false }; if (!j$.isSpy(actual)) { - throw new Error('Expected a spy, but got ' + j$.pp(actual) + '.'); + throw new Error(getErrorMsg('Expected a spy, but got ' + j$.pp(actual) + '.')); } if (!actual.calls.any()) { @@ -3168,11 +3362,13 @@ getJasmineRequireObj().toHaveBeenCalledWith = function(j$) { getJasmineRequireObj().toMatch = function(j$) { + var getErrorMsg = j$.formatErrorMsg('', 'expect().toMatch( || )'); + function toMatch() { return { compare: function(actual, expected) { if (!j$.isString_(expected) && !j$.isA_('RegExp', expected)) { - throw new Error('Expected is not a String or a RegExp'); + throw new Error(getErrorMsg('Expected is not a String or a RegExp')); } var regexp = new RegExp(expected); @@ -3189,6 +3385,8 @@ getJasmineRequireObj().toMatch = function(j$) { getJasmineRequireObj().toThrow = function(j$) { + var getErrorMsg = j$.formatErrorMsg('', 'expect(function() {}).toThrow()'); + function toThrow(util) { return { compare: function(actual, expected) { @@ -3197,7 +3395,7 @@ getJasmineRequireObj().toThrow = function(j$) { thrown; if (typeof actual != 'function') { - throw new Error('Actual is not a Function'); + throw new Error(getErrorMsg('Actual is not a Function')); } try { @@ -3235,6 +3433,9 @@ getJasmineRequireObj().toThrow = function(j$) { }; getJasmineRequireObj().toThrowError = function(j$) { + + var getErrorMsg = j$.formatErrorMsg('', 'expect(function() {}).toThrowError(, )'); + function toThrowError () { return { compare: function(actual) { @@ -3244,7 +3445,7 @@ getJasmineRequireObj().toThrowError = function(j$) { thrown; if (typeof actual != 'function') { - throw new Error('Actual is not a Function'); + throw new Error(getErrorMsg('Actual is not a Function')); } var errorMatcher = getMatcher.apply(null, arguments); @@ -3300,15 +3501,15 @@ getJasmineRequireObj().toThrowError = function(j$) { errorType = arguments[1]; expected = arguments[2]; if (!isAnErrorType(errorType)) { - throw new Error('Expected error type is not an Error.'); + throw new Error(getErrorMsg('Expected error type is not an Error.')); } } if (expected && !isStringOrRegExp(expected)) { if (errorType) { - throw new Error('Expected error message is not a string or RegExp.'); + throw new Error(getErrorMsg('Expected error message is not a string or RegExp.')); } else { - throw new Error('Expected is not an Error, string, or RegExp.'); + throw new Error(getErrorMsg('Expected is not an Error, string, or RegExp.')); } } @@ -3450,5 +3651,5 @@ getJasmineRequireObj().interface = function(jasmine, env) { }; getJasmineRequireObj().version = function() { - return '2.4.1'; + return '2.5.2'; }; diff --git a/_SpecRunner.html b/_SpecRunner.html index 3162ac6..b97ee0a 100644 --- a/_SpecRunner.html +++ b/_SpecRunner.html @@ -30,7 +30,7 @@ - + @@ -38,6 +38,8 @@ + + diff --git a/build/odataresources.js b/build/odataresources.js index db320f9..19bea3a 100644 --- a/build/odataresources.js +++ b/build/odataresources.js @@ -1,301 +1,304 @@ -angular.module('ODataResources', ['ng']);; - -angular.module('ODataResources'). - factory('$odataOperators', [function() { - - var rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g; - var trim = function(value) { - return value.replace(rtrim, ''); - }; - - - var filterOperators = { - 'eq':['=','==','==='], - 'ne':['!=','!==','<>'], - 'gt':['>'], - 'ge':['>=','>=='], - 'lt':['<'], - 'le':['<=','<=='], - 'and':['&&'], - 'or':['||'], - 'not':['!'], - 'add':['+'], - 'sub':['-'], - 'mul':['*'], - 'div':['/'], - 'mod':['%'], - }; - - var convertOperator = function(from){ - var input = trim(from).toLowerCase(); - var key; - for(key in filterOperators) - { - if(input === key) return key; - - var possibleValues = filterOperators[key]; - for (var i = 0; i < possibleValues.length; i++) { - if(input === possibleValues[i]){ - return key; - } - } - } - - throw "Operator "+ from+" not found"; - }; - - return { - operators : filterOperators, - convert:convertOperator, - }; - }]); -;angular.module('ODataResources'). -factory('$odataValue', [ - - function() { - var illegalChars = { - '%': '%25', - '+': '%2B', - '/': '%2F', - '?': '%3F', - '#': '%23', - '&': '%26' - }; - var escapeIllegalChars = function(string) { - for (var key in illegalChars) { - string = string.replace(key, illegalChars[key]); - } - string = string.replace(/'/g, "''"); - return string; - }; - var ODataValue = function(input, type) { - this.value = input; - this.type = type; - }; - - var generateDate = function(date,isOdataV4){ - if(!isOdataV4){ - return "datetime'" + date.getFullYear() + "-" + ("0" + (date.getMonth() + 1)).slice(-2) + "-" + ("0" + date.getDate()).slice(-2) + "T" + ("0" + date.getHours()).slice(-2) + ":" + ("0" + date.getMinutes()).slice(-2)+':'+("0" + date.getSeconds()).slice(-2) + "'"; - }else{ - return date.getFullYear() + "-" + ("0" + (date.getMonth() + 1)).slice(-2) + "-" + ("0" + date.getDate()).slice(-2) + "T" + ("0" + date.getHours()).slice(-2) + ":" + ("0" + date.getMinutes()).slice(-2)+':'+("0" + date.getSeconds()).slice(-2) + "Z"; - } - }; - - var generateGuid = function(guidValue, isOdataV4){ - if(!isOdataV4){ - return "guid'"+guidValue+"'"; - }else{ - return guidValue; - } - }; - - var generateDateOffset = function (date, isOdataV4) { - if (!isOdataV4) { - return "datetimeoffset'" + date.getFullYear() + "-" + ("0" + (date.getMonth() + 1)).slice(-2) + "-" + ("0" + date.getDate()).slice(-2) + "T" + ("0" + date.getHours()).slice(-2) + ":" + ("0" + date.getMinutes()).slice(-2) + ':' + ("0" + date.getSeconds()).slice(-2) + "'"; - } else { - return date.getFullYear() + "-" + ("0" + (date.getMonth() + 1)).slice(-2) + "-" + ("0" + date.getDate()).slice(-2) + "T" + ("0" + date.getHours()).slice(-2) + ":" + ("0" + date.getMinutes()).slice(-2) + ':' + ("0" + date.getSeconds()).slice(-2) + "Z"; - } - }; - - ODataValue.prototype.executeWithUndefinedType = function(isOdataV4) { - if (angular.isString(this.value)) { - return "'" + escapeIllegalChars(this.value) + "'"; - } else if (this.value === false) { - return "false"; - } else if (this.value === true) { - return "true"; - } else if (angular.isDate(this.value)) { - return generateDate(this.value,isOdataV4); - } else if (!isNaN(this.value)) { - return this.value; - } else { - throw "Unrecognized type of " + this.value; - } - }; - - ODataValue.prototype.executeWithType = function(isOdataV4){ - if(this.value === true || this.value === false){ - if(this.type.toLowerCase() === "boolean"){ - return !!this.value+""; - }else if(this.type.toLowerCase() === "string"){ - return "'"+!!this.value+"'"; - }else { - throw "Cannot convert bool ("+this.value+") into "+this.type; - } - } - if(angular.isDate(this.value)){ - if(this.type.toLowerCase() === "decimal"){ - return this.value.getTime()+"M"; - }else if(this.type.toLowerCase() === "int32"){ - return this.value.getTime()+""; - }else if(this.type.toLowerCase() === "single"){ - return this.value.getTime()+"f"; - }else if(this.type.toLowerCase() === "double"){ - return this.value.getTime()+"d"; - }else if(this.type.toLowerCase() === "datetime"){ - return generateDate(this.value,isOdataV4); - } else if (this.type.toLowerCase() === "datetimeoffset") { - return generateDateOffset(new Date(this.value), isOdataV4); - }else if(this.type.toLowerCase()==="string"){ - return "'"+this.value.toISOString()+"'"; - }else { - throw "Cannot convert date ("+this.value+") into "+this.type; - } - } - if(angular.isString(this.value)){ - if(this.type.toLowerCase() === "guid"){ - return generateGuid(this.value,isOdataV4); - }else if(this.type.toLowerCase() === "datetime"){ - return generateDate(new Date(this.value),isOdataV4); - } else if (this.type.toLowerCase() === "datetimeoffset") { - return generateDateOffset(new Date(this.value), isOdataV4); - }else if(this.type.toLowerCase() === "single"){ - return parseFloat(this.value)+"f"; - }else if(this.type.toLowerCase() === "double"){ - return parseFloat(this.value)+"d"; - }else if(this.type.toLowerCase() === "decimal"){ - return parseFloat(this.value)+"M"; - }else if(this.type.toLowerCase() === "boolean"){ - return this.value; - }else if(this.type.toLowerCase() === "int32"){ - return parseInt(this.value)+""; - }else { - throw "Cannot convert "+this.value+" into "+this.type; - } - }else if(!isNaN(this.value)){ - if(this.type.toLowerCase() === "boolean"){ - return !!this.value+""; - }else if(this.type.toLowerCase() === "decimal"){ - return this.value+"M"; - }else if(this.type.toLowerCase() === "double"){ - return this.value+"d"; - }else if(this.type.toLowerCase() === "single"){ - return this.value+"f"; - }else if(this.type.toLowerCase() === "byte"){ - return (this.value%255).toString(16); - }else if(this.type.toLowerCase() === "datetime"){ - return generateDate(new Date(this.value),isOdataV4); - }else if(this.type.toLowerCase() === "string"){ - return "'"+this.value+"'"; - }else { - throw "Cannot convert number ("+this.value+") into "+this.type; - } - } - else{ - throw "Source type of "+this.value+" to be conververted into "+this.type+"is not supported"; - } - }; - - ODataValue.prototype.execute = function(isOdataV4) { - if(this.value === null){ - return 'null'; - } - - if (this.type === undefined) { - return this.executeWithUndefinedType(isOdataV4); - } else { - return this.executeWithType(isOdataV4); - } - }; - return ODataValue; - - } -]);;angular.module('ODataResources'). -factory('$odataProperty', [function() { - -var ODataProperty = function(input){ - this.value = input; - }; - - ODataProperty.prototype.execute = function(){ - return this.value; - }; - return ODataProperty; -}]); - ;angular.module('ODataResources'). -factory('$odataBinaryOperation', ['$odataOperators','$odataProperty','$odataValue',function($odataOperators,ODataProperty,ODataValue) { - - var ODataBinaryOperation = function(a1,a2,a3){ - if(a1===undefined){ - throw "The property of a filter cannot be undefined"; - } - - if(a2 === undefined){ - throw "The value of a filter cannot be undefined"; - } - - if(a3 === undefined){ - //If strings are specified, we assume that the first one is the object property and the second one its value - - if(angular.isFunction(a1.execute)){ - this.operandA = a1; - }else{ - this.operandA = new ODataProperty(a1); - } - if(a2!==null && angular.isFunction(a2.execute)){ - this.operandB = a2; - }else{ - this.operandB = new ODataValue(a2); - } - - this.filterOperator = 'eq'; - } - else{ - if(angular.isFunction(a1.execute)){ - this.operandA = a1; - }else{ - this.operandA = new ODataProperty(a1); - } - if(a3!==null && angular.isFunction(a3.execute)){ - this.operandB = a3; - }else{ - this.operandB = new ODataValue(a3); - } - - this.filterOperator = $odataOperators.convert(a2); - } - }; - - - ODataBinaryOperation.prototype.execute = function(isODatav4,noParenthesis){ - var result = this.operandA.execute(isODatav4)+" "+this.filterOperator+" " +this.operandB.execute(isODatav4); - if(!noParenthesis) - result = "("+result+")"; - - return result; - }; - - ODataBinaryOperation.prototype.or = function(a1,a2,a3){ - var other; - if(a2!==undefined){ - other = new ODataBinaryOperation(a1,a2,a3); - } - else if(angular.isFunction(a1.execute)){ - other = a1; - } - else{ - throw "The object " +a1 +" passed as a parameter of the or method is not valid"; - } - return new ODataBinaryOperation(this,"or",other); - }; - - ODataBinaryOperation.prototype.and = function(a1,a2,a3){ - var other; - if(a2!==undefined){ - other = new ODataBinaryOperation(a1,a2,a3); - } - else if(angular.isFunction(a1.execute)){ - other = a1; - } - else{ - throw "The object " +a1 +" passed as a parameter of the and method is not valid"; - } - return new ODataBinaryOperation(this,"and",other); - }; - - return ODataBinaryOperation; -} - +angular.module('ODataResources', ['ng']);; + +angular.module('ODataResources'). + factory('$odataOperators', [function() { + + var rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g; + var trim = function(value) { + return value.replace(rtrim, ''); + }; + + + var filterOperators = { + 'eq':['=','==','==='], + 'ne':['!=','!==','<>'], + 'gt':['>'], + 'ge':['>=','>=='], + 'lt':['<'], + 'le':['<=','<=='], + 'and':['&&'], + 'or':['||'], + 'not':['!'], + 'add':['+'], + 'sub':['-'], + 'mul':['*'], + 'div':['/'], + 'mod':['%'], + }; + + var convertOperator = function(from){ + var input = trim(from).toLowerCase(); + var key; + for(key in filterOperators) + { + if(input === key) return key; + + var possibleValues = filterOperators[key]; + for (var i = 0; i < possibleValues.length; i++) { + if(input === possibleValues[i]){ + return key; + } + } + } + + throw "Operator "+ from+" not found"; + }; + + return { + operators : filterOperators, + convert:convertOperator, + }; + }]); +;angular.module('ODataResources'). +factory('$odataValue', [ + + function() { + var illegalChars = { + '%': '%25', + '+': '%2B', + '/': '%2F', + '?': '%3F', + '#': '%23', + '&': '%26' + }; + var escapeIllegalChars = function(string) { + for (var key in illegalChars) { + string = string.replace(key, illegalChars[key]); + } + string = string.replace(/'/g, "''"); + return string; + }; + var ODataValue = function(input, type, isCustomType) { + this.value = input; + this.type = type; + this.isCustomType = isCustomType; + }; + + var generateDate = function(date,isOdataV4){ + if(!isOdataV4){ + return "datetime'" + date.getFullYear() + "-" + ("0" + (date.getMonth() + 1)).slice(-2) + "-" + ("0" + date.getDate()).slice(-2) + "T" + ("0" + date.getHours()).slice(-2) + ":" + ("0" + date.getMinutes()).slice(-2)+':'+("0" + date.getSeconds()).slice(-2) + "'"; + }else{ + return date.getFullYear() + "-" + ("0" + (date.getMonth() + 1)).slice(-2) + "-" + ("0" + date.getDate()).slice(-2) + "T" + ("0" + date.getHours()).slice(-2) + ":" + ("0" + date.getMinutes()).slice(-2)+':'+("0" + date.getSeconds()).slice(-2) + "Z"; + } + }; + + var generateGuid = function(guidValue, isOdataV4){ + if(!isOdataV4){ + return "guid'"+guidValue+"'"; + }else{ + return guidValue; + } + }; + + var generateDateOffset = function (date, isOdataV4) { + if (!isOdataV4) { + return "datetimeoffset'" + date.getFullYear() + "-" + ("0" + (date.getMonth() + 1)).slice(-2) + "-" + ("0" + date.getDate()).slice(-2) + "T" + ("0" + date.getHours()).slice(-2) + ":" + ("0" + date.getMinutes()).slice(-2) + ':' + ("0" + date.getSeconds()).slice(-2) + "'"; + } else { + return date.getFullYear() + "-" + ("0" + (date.getMonth() + 1)).slice(-2) + "-" + ("0" + date.getDate()).slice(-2) + "T" + ("0" + date.getHours()).slice(-2) + ":" + ("0" + date.getMinutes()).slice(-2) + ':' + ("0" + date.getSeconds()).slice(-2) + "Z"; + } + }; + + ODataValue.prototype.executeWithUndefinedType = function(isOdataV4) { + if (angular.isString(this.value)) { + return "'" + escapeIllegalChars(this.value) + "'"; + } else if (this.value === false) { + return "false"; + } else if (this.value === true) { + return "true"; + } else if (angular.isDate(this.value)) { + return generateDate(this.value,isOdataV4); + } else if (!isNaN(this.value)) { + return this.value; + } else { + throw "Unrecognized type of " + this.value; + } + }; + + ODataValue.prototype.executeWithType = function(isOdataV4){ + if(this.value === true || this.value === false){ + if(this.type.toLowerCase() === "boolean"){ + return !!this.value+""; + }else if(this.type.toLowerCase() === "string"){ + return "'"+!!this.value+"'"; + }else { + throw "Cannot convert bool ("+this.value+") into "+this.type; + } + } + if(angular.isDate(this.value)){ + if(this.type.toLowerCase() === "decimal"){ + return this.value.getTime()+"M"; + }else if(this.type.toLowerCase() === "int32"){ + return this.value.getTime()+""; + }else if(this.type.toLowerCase() === "single"){ + return this.value.getTime()+"f"; + }else if(this.type.toLowerCase() === "double"){ + return this.value.getTime()+"d"; + }else if(this.type.toLowerCase() === "datetime"){ + return generateDate(this.value,isOdataV4); + } else if (this.type.toLowerCase() === "datetimeoffset") { + return generateDateOffset(new Date(this.value), isOdataV4); + }else if(this.type.toLowerCase()==="string"){ + return "'"+this.value.toISOString()+"'"; + }else { + throw "Cannot convert date ("+this.value+") into "+this.type; + } + } + if(angular.isString(this.value)){ + if(this.type.toLowerCase() === "guid"){ + return generateGuid(this.value,isOdataV4); + }else if(this.type.toLowerCase() === "datetime"){ + return generateDate(new Date(this.value),isOdataV4); + } else if (this.type.toLowerCase() === "datetimeoffset") { + return generateDateOffset(new Date(this.value), isOdataV4); + }else if(this.type.toLowerCase() === "single"){ + return parseFloat(this.value)+"f"; + }else if(this.type.toLowerCase() === "double"){ + return parseFloat(this.value)+"d"; + }else if(this.type.toLowerCase() === "decimal"){ + return parseFloat(this.value)+"M"; + }else if(this.type.toLowerCase() === "boolean"){ + return this.value; + }else if(this.type.toLowerCase() === "int32"){ + return parseInt(this.value)+""; + }else if(this.isCustomType){ + return this.type + "'" + this.value + "'"; + }else{ + throw "Cannot convert "+this.value+" into "+this.type; + } + }else if(!isNaN(this.value)){ + if(this.type.toLowerCase() === "boolean"){ + return !!this.value+""; + }else if(this.type.toLowerCase() === "decimal"){ + return this.value+"M"; + }else if(this.type.toLowerCase() === "double"){ + return this.value+"d"; + }else if(this.type.toLowerCase() === "single"){ + return this.value+"f"; + }else if(this.type.toLowerCase() === "byte"){ + return (this.value%255).toString(16); + }else if(this.type.toLowerCase() === "datetime"){ + return generateDate(new Date(this.value),isOdataV4); + }else if(this.type.toLowerCase() === "string"){ + return "'"+this.value+"'"; + }else { + throw "Cannot convert number ("+this.value+") into "+this.type; + } + } + else{ + throw "Source type of "+this.value+" to be conververted into "+this.type+"is not supported"; + } + }; + + ODataValue.prototype.execute = function(isOdataV4) { + if(this.value === null){ + return 'null'; + } + + if (this.type === undefined) { + return this.executeWithUndefinedType(isOdataV4); + } else { + return this.executeWithType(isOdataV4); + } + }; + return ODataValue; + + } +]);;angular.module('ODataResources'). +factory('$odataProperty', [function() { + +var ODataProperty = function(input){ + this.value = input; + }; + + ODataProperty.prototype.execute = function(){ + return this.value; + }; + return ODataProperty; +}]); + ;angular.module('ODataResources'). +factory('$odataBinaryOperation', ['$odataOperators','$odataProperty','$odataValue',function($odataOperators,ODataProperty,ODataValue) { + + var ODataBinaryOperation = function(a1,a2,a3){ + if(a1===undefined){ + throw "The property of a filter cannot be undefined"; + } + + if(a2 === undefined){ + throw "The value of a filter cannot be undefined"; + } + + if(a3 === undefined){ + //If strings are specified, we assume that the first one is the object property and the second one its value + + if(angular.isFunction(a1.execute)){ + this.operandA = a1; + }else{ + this.operandA = new ODataProperty(a1); + } + if(a2!==null && angular.isFunction(a2.execute)){ + this.operandB = a2; + }else{ + this.operandB = new ODataValue(a2); + } + + this.filterOperator = 'eq'; + } + else{ + if(angular.isFunction(a1.execute)){ + this.operandA = a1; + }else{ + this.operandA = new ODataProperty(a1); + } + if(a3!==null && angular.isFunction(a3.execute)){ + this.operandB = a3; + }else{ + this.operandB = new ODataValue(a3); + } + + this.filterOperator = $odataOperators.convert(a2); + } + }; + + + ODataBinaryOperation.prototype.execute = function(isODatav4,noParenthesis){ + var result = this.operandA.execute(isODatav4)+" "+this.filterOperator+" " +this.operandB.execute(isODatav4); + if(!noParenthesis) + result = "("+result+")"; + + return result; + }; + + ODataBinaryOperation.prototype.or = function(a1,a2,a3){ + var other; + if(a2!==undefined){ + other = new ODataBinaryOperation(a1,a2,a3); + } + else if(angular.isFunction(a1.execute)){ + other = a1; + } + else{ + throw "The object " +a1 +" passed as a parameter of the or method is not valid"; + } + return new ODataBinaryOperation(this,"or",other); + }; + + ODataBinaryOperation.prototype.and = function(a1,a2,a3){ + var other; + if(a2!==undefined){ + other = new ODataBinaryOperation(a1,a2,a3); + } + else if(angular.isFunction(a1.execute)){ + other = a1; + } + else{ + throw "The object " +a1 +" passed as a parameter of the and method is not valid"; + } + return new ODataBinaryOperation(this,"and",other); + }; + + return ODataBinaryOperation; +} + ]);;angular.module('ODataResources'). factory('$odataExpandPredicate', ['$odataPredicate', '$odataBinaryOperation', '$odataOrderByStatement', function (ODataPredicate, ODataBinaryOperation, ODataOrderByStatement) { @@ -398,141 +401,141 @@ factory('$odataExpandPredicate', ['$odataPredicate', '$odataBinaryOperation', '$ }; return ODataExpandPredicate; -}]);;angular.module('ODataResources'). -factory('$odataMethodCall', ['$odataProperty', '$odataValue', - function(ODataProperty, ODataValue) { - - var ODataMethodCall = function(methodName) { - if (methodName === undefined || methodName === "") - throw "Method name should be defined"; - - this.params = []; - - if (arguments.length < 2) - throw "Method should be invoked with arguments"; - - for (var i = 1; i < arguments.length; i++) { - var value = arguments[i]; - if (angular.isFunction(value.execute)) { - this.params.push(value); - } else { - //We assume the first one is the object property; - if (i == 1) { - this.params.push(new ODataProperty(value)); - } else { - this.params.push(new ODataValue(value)); - } - } - } - - this.methodName = methodName; - }; - - ODataMethodCall.prototype.execute = function() { - var lambdaOperators = ["any", "all"]; - var invocation = ""; - - if(lambdaOperators.indexOf(this.methodName) > -1) { - for (var i = 0; i < this.params.length; i++) { - if (i === 0) { - invocation += this.params[i].execute(); - invocation += "/"; - invocation += this.methodName; - } else if(i === 1) { - invocation += "("; - invocation += this.params[i].value; - invocation += ":"; - } else { - invocation += this.params[i].execute(); - invocation += ")"; - } - } - } else { - invocation += this.methodName + "("; - - for (var j = 0; j < this.params.length; j++) { - if (j > 0) - invocation += ","; - - invocation += this.params[j].execute(); - } - invocation += ")"; - } - - return invocation; - }; - - return ODataMethodCall; - } -]);;angular.module('ODataResources'). -factory('$odataOrderByStatement', [function($odataOperators,ODataBinaryOperation,ODataPredicate) { - - var ODataOrderByStatement = function(propertyName, sortOrder){ - if(propertyName===undefined){ - throw "Orderby should be passed a property name but got undefined"; - } - - this.propertyName = propertyName; - - this.direction = sortOrder || "asc"; - }; - - ODataOrderByStatement.prototype.execute = function() { - return this.propertyName+" "+this.direction; - }; - - return ODataOrderByStatement; -}]);;angular.module('ODataResources'). -factory('$odataPredicate', ['$odataBinaryOperation',function(ODataBinaryOperation) { - - - - var ODataPredicate = function(a1,a2,a3){ - if(angular.isFunction(a1.execute) && a2 === undefined){ - return a1; - } - else{ - return new ODataBinaryOperation(a1,a2,a3); - } - }; - - ODataPredicate.and = function(andStatements){ - if(andStatements.length>0){ - var finalOperation = andStatements[0]; - - for (var i = 1; i < andStatements.length; i++) { - finalOperation = new ODataBinaryOperation(finalOperation,'and',andStatements[i]); - } - return finalOperation; - } - throw "No statements specified"; - }; - - ODataPredicate.or = function(orStatements){ - if(orStatements.length>0){ - var finalOperation = orStatements[0]; - - for (var i = 1; i < orStatements.length; i++) { - finalOperation = new ODataBinaryOperation(finalOperation,'or',orStatements[i]); - } - return finalOperation; - } - throw "No statements specified for OR predicate"; - }; - - - ODataPredicate.create = function(a1,a2,a3){ - if(angular.isFunction(a1.execute) && a2 === undefined){ - return a1; - } - else{ - return new ODataBinaryOperation(a1,a2,a3); - } - }; - - return ODataPredicate; - -}]); +}]);;angular.module('ODataResources'). +factory('$odataMethodCall', ['$odataProperty', '$odataValue', + function(ODataProperty, ODataValue) { + + var ODataMethodCall = function(methodName) { + if (methodName === undefined || methodName === "") + throw "Method name should be defined"; + + this.params = []; + + if (arguments.length < 2) + throw "Method should be invoked with arguments"; + + for (var i = 1; i < arguments.length; i++) { + var value = arguments[i]; + if (angular.isFunction(value.execute)) { + this.params.push(value); + } else { + //We assume the first one is the object property; + if (i == 1) { + this.params.push(new ODataProperty(value)); + } else { + this.params.push(new ODataValue(value)); + } + } + } + + this.methodName = methodName; + }; + + ODataMethodCall.prototype.execute = function() { + var lambdaOperators = ["any", "all"]; + var invocation = ""; + + if(lambdaOperators.indexOf(this.methodName) > -1) { + for (var i = 0; i < this.params.length; i++) { + if (i === 0) { + invocation += this.params[i].execute(); + invocation += "/"; + invocation += this.methodName; + } else if(i === 1) { + invocation += "("; + invocation += this.params[i].value; + invocation += ":"; + } else { + invocation += this.params[i].execute(); + invocation += ")"; + } + } + } else { + invocation += this.methodName + "("; + + for (var j = 0; j < this.params.length; j++) { + if (j > 0) + invocation += ","; + + invocation += this.params[j].execute(); + } + invocation += ")"; + } + + return invocation; + }; + + return ODataMethodCall; + } +]);;angular.module('ODataResources'). +factory('$odataOrderByStatement', [function($odataOperators,ODataBinaryOperation,ODataPredicate) { + + var ODataOrderByStatement = function(propertyName, sortOrder){ + if(propertyName===undefined){ + throw "Orderby should be passed a property name but got undefined"; + } + + this.propertyName = propertyName; + + this.direction = sortOrder || "asc"; + }; + + ODataOrderByStatement.prototype.execute = function() { + return this.propertyName+" "+this.direction; + }; + + return ODataOrderByStatement; +}]);;angular.module('ODataResources'). +factory('$odataPredicate', ['$odataBinaryOperation',function(ODataBinaryOperation) { + + + + var ODataPredicate = function(a1,a2,a3){ + if(angular.isFunction(a1.execute) && a2 === undefined){ + return a1; + } + else{ + return new ODataBinaryOperation(a1,a2,a3); + } + }; + + ODataPredicate.and = function(andStatements){ + if(andStatements.length>0){ + var finalOperation = andStatements[0]; + + for (var i = 1; i < andStatements.length; i++) { + finalOperation = new ODataBinaryOperation(finalOperation,'and',andStatements[i]); + } + return finalOperation; + } + throw "No statements specified"; + }; + + ODataPredicate.or = function(orStatements){ + if(orStatements.length>0){ + var finalOperation = orStatements[0]; + + for (var i = 1; i < orStatements.length; i++) { + finalOperation = new ODataBinaryOperation(finalOperation,'or',orStatements[i]); + } + return finalOperation; + } + throw "No statements specified for OR predicate"; + }; + + + ODataPredicate.create = function(a1,a2,a3){ + if(angular.isFunction(a1.execute) && a2 === undefined){ + return a1; + } + else{ + return new ODataBinaryOperation(a1,a2,a3); + } + }; + + return ODataPredicate; + +}]); ;angular.module('ODataResources'). factory('$odataProvider', ['$odataOperators', '$odataBinaryOperation', '$odataPredicate', '$odataOrderByStatement', '$odataExpandPredicate', function($odataOperators, ODataBinaryOperation, ODataPredicate, ODataOrderByStatement, ODataExpandPredicate) { @@ -1464,20 +1467,20 @@ factory('$odataProvider', ['$odataOperators', '$odataBinaryOperation', '$odataPr })(window, window.angular); -;angular.module('ODataResources'). -factory('$odata', ['$odataBinaryOperation','$odataProvider','$odataValue', - '$odataProperty','$odataMethodCall','$odataPredicate','$odataOrderByStatement','$odataExpandPredicate', - function(ODataBinaryOperation,ODataProvider,ODataValue,ODataProperty,ODataMethodCall,ODataPredicate,ODataOrderByStatement,ODataExpandPredicate) { - - return { - Provider : ODataProvider, - BinaryOperation : ODataBinaryOperation, - Value : ODataValue, - Property : ODataProperty, - Func : ODataMethodCall, - Predicate : ODataPredicate, - OrderBy : ODataOrderByStatement, - ExpandPredicate : ODataExpandPredicate, - }; - +;angular.module('ODataResources'). +factory('$odata', ['$odataBinaryOperation','$odataProvider','$odataValue', + '$odataProperty','$odataMethodCall','$odataPredicate','$odataOrderByStatement','$odataExpandPredicate', + function(ODataBinaryOperation,ODataProvider,ODataValue,ODataProperty,ODataMethodCall,ODataPredicate,ODataOrderByStatement,ODataExpandPredicate) { + + return { + Provider : ODataProvider, + BinaryOperation : ODataBinaryOperation, + Value : ODataValue, + Property : ODataProperty, + Func : ODataMethodCall, + Predicate : ODataPredicate, + OrderBy : ODataOrderByStatement, + ExpandPredicate : ODataExpandPredicate, + }; + }]); \ No newline at end of file diff --git a/build/odataresources.min.js b/build/odataresources.min.js index 5eed018..4c2674f 100644 --- a/build/odataresources.min.js +++ b/build/odataresources.min.js @@ -1,2 +1,2 @@ -/*! ODataResources 2016-10-04 */ -angular.module("ODataResources",["ng"]),angular.module("ODataResources").factory("$odataOperators",[function(){var a=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,b=function(b){return b.replace(a,"")},c={eq:["=","==","==="],ne:["!=","!==","<>"],gt:[">"],ge:[">=",">=="],lt:["<"],le:["<=","<=="],and:["&&"],or:["||"],not:["!"],add:["+"],sub:["-"],mul:["*"],div:["/"],mod:["%"]},d=function(a){var d,e=b(a).toLowerCase();for(d in c){if(e===d)return d;for(var f=c[d],g=0;g-1)for(var c=0;c0&&(b+=","),b+=this.params[d].execute();b+=")"}return b},c}]),angular.module("ODataResources").factory("$odataOrderByStatement",[function(a,b,c){var d=function(a,b){if(void 0===a)throw"Orderby should be passed a property name but got undefined";this.propertyName=a,this.direction=b||"asc"};return d.prototype.execute=function(){return this.propertyName+" "+this.direction},d}]),angular.module("ODataResources").factory("$odataPredicate",["$odataBinaryOperation",function(a){var b=function(b,c,d){return angular.isFunction(b.execute)&&void 0===c?b:new a(b,c,d)};return b.and=function(b){if(b.length>0){for(var c=b[0],d=1;d0){for(var c=b[0],d=1;d0&&(b="$filter="+c.and(this.filters).execute(this.isv4,!0)),this.sortOrders.length>0)for(""!==b&&(b+="&"),b+="$orderby=",a=0;a0&&(b+=","),b+=this.sortOrders[a].execute();for(this.takeAmount&&(""!==b&&(b+="&"),b+="$top="+this.takeAmount),this.skipAmount&&(""!==b&&(b+="&"),b+="$skip="+this.skipAmount),this.expandables.length>0&&(""!==b&&(b+="&"),b+="$expand="+this.expandables.join(",")),this.selectables.length>0&&(""!==b&&(b+="&"),b+="$select="+this.selectables.join(",")),this.hasInlineCount>0&&(""!==b&&(b+="&"),b+=this.isv4?"$count=true":"$inlinecount=allpages"),this.formatBy&&(""!==b&&(b+="&"),b+="$format="+this.formatBy),a=0;a0&&(d="?"+d),this.$$callback("("+a+")"+d,b,c,!0,!1,f.bind(this,"get"))},g.prototype.count=function(a,b){if(!angular.isFunction(this.$$callback))throw"Cannot execute count, no callback was specified";a=a||angular.noop,b=b||angular.noop;var c=this.execute();return c.length>0&&(c="/?"+c),this.$$callback("/$count"+c,a,b,!0,!1,f.bind(this,"count"))},g.prototype.withInlineCount=function(){return this.hasInlineCount=!0,this};var h=function(a){var b=a.shift(),c=b;return a.length>0&&(c=c+"($expand="+h(a)+")"),c};return g.prototype.expand=function(a){if(!angular.isString(a)&&!angular.isArray(a))throw"Invalid parameter passed to expand method ("+a+")";if(""!==a){var b=a;if(this.isv4)angular.isArray(a)||(a=Array.prototype.slice.call(arguments)),b=h(a);else{b=angular.isArray(a)?a.join("/"):Array.prototype.slice.call(arguments).join("/");for(var c=0;c=0;b--)this.selectables.push(a[b]);return this}},g.prototype.re=function(a){if(this.$$reusables)for(var b in this.$$reusables)if(angular.isArray(this.$$reusables[b]))for(var c=0;cf&&a!==c;f++){var i=e[f];a=null!==a?a[i]:c}return a}function f(a,c){c=c||{},b.forEach(c,function(a,b){delete c[b]});for(var d in a)!a.hasOwnProperty(d)||"$"===d.charAt(0)&&"$"===d.charAt(1)||(c[d]=a[d]);return c}var g=b.$$minErr("$resource"),h=/^(\.[a-zA-Z_$@][0-9a-zA-Z_$@]*)+$/;b.module("ODataResources").provider("$odataresource",function(){var a=this;this.defaults={stripTrailingSlashes:!0,actions:{get:{method:"GET"},save:{method:"POST"},query:{method:"GET",isArray:!0},remove:{method:"DELETE"},"delete":{method:"DELETE"},update:{method:"PUT"},odata:{method:"GET",isArray:!0}}},this.$get=["$http","$q","$odata",function(d,h,i){function j(a){return k(a,!0).replace(/%26/gi,"&").replace(/%3D/gi,"=").replace(/%2B/gi,"+")}function k(a,b){return encodeURIComponent(a).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,b?"%20":"+")}function l(b,c){this.template=b,this.defaults=p({},a.defaults,c),this.urlParams={}}function m(j,k,t,u){function v(a,b){var c={};return b=p({},k,b),o(b,function(b,d){r(b)&&(b=b()),c[d]=b&&b.charAt&&"@"==b.charAt(0)?e(a,b.substr(1)):b}),c}function w(a){return a.resource}function x(a){f(a||{},this)}u=u||{},b.isString(k)&&(u.odatakey=k,k={});var y=new l(j,u);t=p({},a.defaults.actions,t),x.prototype.toJSON=function(){var a=p({},this);return delete a.$promise,delete a.$resolved,a},x.store=function(a){var c=s.filter(function(b){return b.resource===a});return c.length?(Array.prototype.splice.call(arguments,0,1,c[0]),b.extend.apply(b,arguments)):(Array.prototype.splice.call(arguments,0,1,{resource:a}),c=b.extend.apply(b,arguments),s.push(c),c)},x.isResource=function(a){return s.filter(function(b){return b.resource===a}).length},x.store.get=function(a){var b=s.filter(function(b){return b.resource===a});return b.length?b[0]:null},x.store.getHeaders=function(a){var b=x.store.get(a);return b?b.headers:null},x.store.copyHeaders=function(a,b){return x.store(a,{headers:x.store.getHeaders(b)})},x.store.getConfig=function(a){var b=x.store.get(a);return b?b.config:null},x.store.updateConfig=function(a){if(arguments.length<2)return!1;var c=["url","paramDefaults","action","options"],d=arguments.length>2&&b.isString(arguments[1])?Array.prototype.slice.call(arguments,1,5).reduce(function(a,b,d){return a[c[d]]=b,a},{}):arguments[1];return x.isResource(d)&&(d=x.store.getConfig(d)),b.extend(t,d.actions||{}),b.extend(k,d.paramDefaults||{}),b.extend(u,d.options||{}),b.isDefined(d.url)&&b.isString(d.url)&&(j=d.url),y=new l(j,u),x.store(a,{config:{url:j,paramDefaults:k,actions:t,options:u},pendingCorrection:!1}),!0},x.store.pendingCorrection=function(a){var b=x.store.get(a);return b?b.pendingCorrection||!1:!1},x.store.getRefreshingResource=function(a){var b=s.filter(function(b){return b.refreshedAs===a});return b?b[0]:null},o(t,function(a,e){var i=/^(POST|PUT|PATCH)$/i.test(a.method);x[e]=function(l,m,s,z,B,C,D,E,F){function G(c){var d=c.data,h=R.$promise;if(d&&b.isNumber(d["@odata.count"])&&(d.count=d["@odata.count"]),d&&(b.isString(d["@odata.context"])||b.isString(d["odata.metadata"]))&&d.value&&b.isArray(d.value)){var i=d;d=d.value;for(var j in i)"value"!==j&&(R[j]=i[j])}if(d){if(b.isArray(d)!==(!D&&!!a.isArray)&&!E)throw g("badcfg","Error in resource configuration for action `{0}`. Expected response to contain an {1} but got an {2} (Request: {3} {4})",e,!D&&a.isArray?"array":"object",b.isArray(d)?"array":"object",S.method,S.url);if(b.isArray(d)&&E){if(!(d.length>0))throw"The response returned no result";d=d[0]}!D&&a.isArray&&isNaN(parseInt(d))?(R.length=0,o(d,function(a){if("object"==typeof a){var b=new x(a);A(b,F,!1),R.push(b)}else R.push(a)})):(f(d,R),R.$promise=h)}return b.isNumber(d)&&D?R.result=d:!isNaN(parseInt(d))&&D&&(R.result=parseInt(d)),R.$resolved=!0,c.resource=R,x.store(R,{headers:c.headers()}),T(c)||c}function H(a){R.$resolved=!0;var b=x.store.getRefreshingResource(R);return b&&b.preventErrorLooping?(x.store(b.resource,{preventErrorLooping:!1}),h.reject(a)):(x.store(R,{headers:a.headers(),preventErrorLooping:!0}),K((U||n)(a)||a))}function I(a){return(N||n)(a,x.store.getHeaders(R)),a}function J(a){var b=x.store.getRefreshingResource(R);return b&&b.preventErrorLooping?(x.store(b.resource,{preventErrorLooping:!1}),h.reject(a)):(x.store(R,{preventErrorLooping:!0}),K((O||n)(a)||a).then(function(a){return(N||n)(a,x.store.getHeaders(R)),a}))}function K(a){if(b.isDefined(a)&&b.isObject(a)&&b.isObject(a.$correction)){x.store.updateConfig(R,a.$correction);var c=R.$refresh();return x.store(R,{refreshedAs:c}),c.$promise.then(L)}return b.isDefined(a)&&b.isDefined(a.$value)&&a.$correction&&(x.store(R,{pendingCorrection:a.$correction}),a=a.$value),x.isResource(a)?a.$promise.then(L):b.isDefined(a)&&b.isFunction(a.then)?a.then(L):h.reject(a)}function L(a){return x.isResource(a)?(x.store.copyHeaders(R,a),x.store.pendingCorrection(R)&&x.store.updateConfig(R,a),x.store(R,{preventErrorLooping:!1}),f(a,R),R):b.isDefined(a)&&b.isObject(a)&&b.isFunction(a.headers)?h.when(a).then(G):h.when({data:a,headers:function(){return null}}).then(G)}var M,N,O,P={};switch(arguments.length){case 9:case 8:case 7:case 6:case 4:O=z,N=s;case 3:case 2:if(!r(m)){P=l,M=m,N=s;break}if(r(l)){N=l,O=m;break}N=m,O=s;case 1:r(l)?N=l:i?M=l:P=l;break;case 0:break;default:throw g("badargs","Expected up to 4 arguments [params, data, success, error], got {0} arguments",arguments.length)}var Q=this instanceof x,R=Q?M:!D&&a.isArray?[]:new x(M),S={},T=a.interceptor&&a.interceptor.response||w,U=a.interceptor&&a.interceptor.responseError||c;A(R,F),o(a,function(a,b){"params"!=b&&"isArray"!=b&&"interceptor"!=b&&(S[b]=q(a))}),i&&(S.data=M),y.setUrlParams(S,p({},v(M,a.params||{}),P),a.url,M,B),!B||""===C||D&&!E?""!==C&&D&&(S.url+=C):S.url+="?"+C,u.ignoreLoadingBar&&(S.ignoreLoadingBar=!0);var V=d(S).then(G,H).then(I,J);return Q?V:(R.$promise=V,R.$resolved=!1,x.store(R,{config:{url:j,paramDefaults:k,actions:t,options:u}}),R)},x.prototype["$"+e]=function(a,b,c){r(a)&&(c=b,b=a,a={});var d=x[e].call(this,a,this,b,c);return d.$promise||d}});var z=x.odata;x.odata=function(a){var b=function(a,b,c,d,e,f){return z({},{},b,c,!0,a,d,e,f)},c=new i.Provider(b,u.isodatav4,this.$refresh?this.$refresh.$$persistence:null);return u.persistence?c.re():c};var A=function(a,c,d){if(d="boolean"==typeof d?d:!0,b.isDefined(a)&&b.isDefined(c)){var e=B.bind(a);e.$$persistence=b.isFunction(c)?c(d):c,Object.defineProperty(a,"$refresh",{enumerable:!1,configurable:!0,writable:!0,value:e})}},B=function(a,b){var d=function(a,b,c,d,e,f){return z({},{},b,c,!0,a,d,e,f)},e=new i.Provider(d,u.isodatav4,this.$refresh.$$persistence);if(e=e.re(),"count"==this.$refresh.$$persistence.$$type)return e.count();if("single"==this.$refresh.$$persistence.$$type)return e.single();var f=e.execute(),g=this instanceof Array;return x[g?"query":"get"].call(c,{},g?{}:this,a,b,g,(g?"":"?")+f,!g,!1,this.$refresh.$$persistence)};return x.bind=function(a){return m(j,p({},k,a),t)},x}var n=b.noop,o=b.forEach,p=b.extend,q=b.copy,r=b.isFunction,s=[];return l.prototype={setUrlParams:function(a,c,d,e,f){var h,i,k=this,l=d||k.template;if(l===k.template&&("PUT"===a.method||"DELETE"===a.method||"GET"==a.method&&!f||"PATCH"==a.method)&&b.isString(k.defaults.odatakey)){k.defaults.stripTrailingSlashes&&(l=l.replace(/\/+$/,"")||"/");var m=k.defaults.odatakey.split(","),n=m.map(function(a){return m.length>1?a+"=:"+a:":"+a});l=l+"("+n.join(",")+")",e&&o(m,function(a){c[a]=e[a]})}var p=k.urlParams={};o(l.split(/\W/),function(a){if("hasOwnProperty"===a)throw g("badname","hasOwnProperty is not a valid parameter name.");!new RegExp("^\\d+$").test(a)&&a&&new RegExp("(^|[^\\\\]):"+a+"(\\W|$)").test(l)&&(p[a]=!0)}),l=l.replace(/\\:/g,":"),c=c||{},o(k.urlParams,function(a,d){h=c.hasOwnProperty(d)?c[d]:k.defaults[d],b.isDefined(h)&&null!==h?(i=j(h),l=l.replace(new RegExp(":"+d+"(\\W|$)","g"),function(a,b){return i+b})):l=l.replace(new RegExp("(/?):"+d+"(\\W|$)","g"),function(a,b,c){return"/"==c.charAt(0)?c:b+c})}),k.defaults.stripTrailingSlashes&&(l=l.replace(/\/+$/,"")||"/"),l=l.replace(/\/\.(?=\w+($|\?))/,"."),a.url=l.replace(/\/\\\./,"/."),o(c,function(b,c){k.urlParams[c]||(a.params=a.params||{},a.params[c]=b)})}},m}]})}(window,window.angular),angular.module("ODataResources").factory("$odata",["$odataBinaryOperation","$odataProvider","$odataValue","$odataProperty","$odataMethodCall","$odataPredicate","$odataOrderByStatement","$odataExpandPredicate",function(a,b,c,d,e,f,g,h){return{Provider:b,BinaryOperation:a,Value:c,Property:d,Func:e,Predicate:f,OrderBy:g,ExpandPredicate:h}}]); \ No newline at end of file +/*! angular-odata-resources 2016-11-29 */ +angular.module("ODataResources",["ng"]),angular.module("ODataResources").factory("$odataOperators",[function(){var a=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,b=function(b){return b.replace(a,"")},c={eq:["=","==","==="],ne:["!=","!==","<>"],gt:[">"],ge:[">=",">=="],lt:["<"],le:["<=","<=="],and:["&&"],or:["||"],not:["!"],add:["+"],sub:["-"],mul:["*"],div:["/"],mod:["%"]},d=function(a){var d,e=b(a).toLowerCase();for(d in c){if(e===d)return d;for(var f=c[d],g=0;g-1)for(var c=0;c0&&(b+=","),b+=this.params[d].execute();b+=")"}return b},c}]),angular.module("ODataResources").factory("$odataOrderByStatement",[function(a,b,c){var d=function(a,b){if(void 0===a)throw"Orderby should be passed a property name but got undefined";this.propertyName=a,this.direction=b||"asc"};return d.prototype.execute=function(){return this.propertyName+" "+this.direction},d}]),angular.module("ODataResources").factory("$odataPredicate",["$odataBinaryOperation",function(a){var b=function(b,c,d){return angular.isFunction(b.execute)&&void 0===c?b:new a(b,c,d)};return b.and=function(b){if(b.length>0){for(var c=b[0],d=1;d0){for(var c=b[0],d=1;d0&&(b="$filter="+c.and(this.filters).execute(this.isv4,!0)),this.sortOrders.length>0)for(""!==b&&(b+="&"),b+="$orderby=",a=0;a0&&(b+=","),b+=this.sortOrders[a].execute();for(this.takeAmount&&(""!==b&&(b+="&"),b+="$top="+this.takeAmount),this.skipAmount&&(""!==b&&(b+="&"),b+="$skip="+this.skipAmount),this.expandables.length>0&&(""!==b&&(b+="&"),b+="$expand="+this.expandables.join(",")),this.selectables.length>0&&(""!==b&&(b+="&"),b+="$select="+this.selectables.join(",")),this.hasInlineCount>0&&(""!==b&&(b+="&"),b+=this.isv4?"$count=true":"$inlinecount=allpages"),this.formatBy&&(""!==b&&(b+="&"),b+="$format="+this.formatBy),a=0;a0&&(d="?"+d),this.$$callback("("+a+")"+d,b,c,!0,!1,f.bind(this,"get"))},g.prototype.count=function(a,b){if(!angular.isFunction(this.$$callback))throw"Cannot execute count, no callback was specified";a=a||angular.noop,b=b||angular.noop;var c=this.execute();return c.length>0&&(c="/?"+c),this.$$callback("/$count"+c,a,b,!0,!1,f.bind(this,"count"))},g.prototype.withInlineCount=function(){return this.hasInlineCount=!0,this};var h=function(a){var b=a.shift(),c=b;return a.length>0&&(c=c+"($expand="+h(a)+")"),c};return g.prototype.expand=function(a){if(!angular.isString(a)&&!angular.isArray(a))throw"Invalid parameter passed to expand method ("+a+")";if(""!==a){var b=a;if(this.isv4)angular.isArray(a)||(a=Array.prototype.slice.call(arguments)),b=h(a);else{b=angular.isArray(a)?a.join("/"):Array.prototype.slice.call(arguments).join("/");for(var c=0;c=0;b--)this.selectables.push(a[b]);return this}},g.prototype.re=function(a){if(this.$$reusables)for(var b in this.$$reusables)if(angular.isArray(this.$$reusables[b]))for(var c=0;c2&&b.isString(arguments[1])?Array.prototype.slice.call(arguments,1,5).reduce(function(a,b,d){return a[c[d]]=b,a},{}):arguments[1];return x.isResource(d)&&(d=x.store.getConfig(d)),b.extend(t,d.actions||{}),b.extend(k,d.paramDefaults||{}),b.extend(u,d.options||{}),b.isDefined(d.url)&&b.isString(d.url)&&(j=d.url),y=new l(j,u),x.store(a,{config:{url:j,paramDefaults:k,actions:t,options:u},pendingCorrection:!1}),!0},x.store.pendingCorrection=function(a){var b=x.store.get(a);return!!b&&(b.pendingCorrection||!1)},x.store.getRefreshingResource=function(a){var b=s.filter(function(b){return b.refreshedAs===a});return b?b[0]:null},o(t,function(a,e){var i=/^(POST|PUT|PATCH)$/i.test(a.method);x[e]=function(l,m,s,z,B,C,D,E,F){function G(c){var d=c.data,h=R.$promise;if(d&&b.isNumber(d["@odata.count"])&&(d.count=d["@odata.count"]),d&&(b.isString(d["@odata.context"])||b.isString(d["odata.metadata"]))&&d.value&&b.isArray(d.value)){var i=d;d=d.value;for(var j in i)"value"!==j&&(R[j]=i[j])}if(d){if(b.isArray(d)!==(!D&&!!a.isArray)&&!E)throw g("badcfg","Error in resource configuration for action `{0}`. Expected response to contain an {1} but got an {2} (Request: {3} {4})",e,!D&&a.isArray?"array":"object",b.isArray(d)?"array":"object",S.method,S.url);if(b.isArray(d)&&E){if(!(d.length>0))throw"The response returned no result";d=d[0]}!D&&a.isArray&&isNaN(parseInt(d))?(R.length=0,o(d,function(a){if("object"==typeof a){var b=new x(a);A(b,F,!1),R.push(b)}else R.push(a)})):(f(d,R),R.$promise=h)}return b.isNumber(d)&&D?R.result=d:!isNaN(parseInt(d))&&D&&(R.result=parseInt(d)),R.$resolved=!0,c.resource=R,x.store(R,{headers:c.headers()}),T(c)||c}function H(a){R.$resolved=!0;var b=x.store.getRefreshingResource(R);return b&&b.preventErrorLooping?(x.store(b.resource,{preventErrorLooping:!1}),h.reject(a)):(x.store(R,{headers:a.headers(),preventErrorLooping:!0}),K((U||n)(a)||a))}function I(a){return(N||n)(a,x.store.getHeaders(R)),a}function J(a){var b=x.store.getRefreshingResource(R);return b&&b.preventErrorLooping?(x.store(b.resource,{preventErrorLooping:!1}),h.reject(a)):(x.store(R,{preventErrorLooping:!0}),K((O||n)(a)||a).then(function(a){return(N||n)(a,x.store.getHeaders(R)),a}))}function K(a){if(b.isDefined(a)&&b.isObject(a)&&b.isObject(a.$correction)){x.store.updateConfig(R,a.$correction);var c=R.$refresh();return x.store(R,{refreshedAs:c}),c.$promise.then(L)}return b.isDefined(a)&&b.isDefined(a.$value)&&a.$correction&&(x.store(R,{pendingCorrection:a.$correction}),a=a.$value),x.isResource(a)?a.$promise.then(L):b.isDefined(a)&&b.isFunction(a.then)?a.then(L):h.reject(a)}function L(a){return x.isResource(a)?(x.store.copyHeaders(R,a),x.store.pendingCorrection(R)&&x.store.updateConfig(R,a),x.store(R,{preventErrorLooping:!1}),f(a,R),R):b.isDefined(a)&&b.isObject(a)&&b.isFunction(a.headers)?h.when(a).then(G):h.when({data:a,headers:function(){return null}}).then(G)}var M,N,O,P={};switch(arguments.length){case 9:case 8:case 7:case 6:case 4:O=z,N=s;case 3:case 2:if(!r(m)){P=l,M=m,N=s;break}if(r(l)){N=l,O=m;break}N=m,O=s;case 1:r(l)?N=l:i?M=l:P=l;break;case 0:break;default:throw g("badargs","Expected up to 4 arguments [params, data, success, error], got {0} arguments",arguments.length)}var Q=this instanceof x,R=Q?M:!D&&a.isArray?[]:new x(M),S={},T=a.interceptor&&a.interceptor.response||w,U=a.interceptor&&a.interceptor.responseError||c;A(R,F),o(a,function(a,b){"params"!=b&&"isArray"!=b&&"interceptor"!=b&&(S[b]=q(a))}),i&&(S.data=M),y.setUrlParams(S,p({},v(M,a.params||{}),P),a.url,M,B),!B||""===C||D&&!E?""!==C&&D&&(S.url+=C):S.url+="?"+C,u.ignoreLoadingBar&&(S.ignoreLoadingBar=!0);var V=d(S).then(G,H).then(I,J);return Q?V:(R.$promise=V,R.$resolved=!1,x.store(R,{config:{url:j,paramDefaults:k,actions:t,options:u}}),R)},x.prototype["$"+e]=function(a,b,c){r(a)&&(c=b,b=a,a={});var d=x[e].call(this,a,this,b,c);return d.$promise||d}});var z=x.odata;x.odata=function(a){var b=function(a,b,c,d,e,f){return z({},{},b,c,!0,a,d,e,f)},c=new i.Provider(b,u.isodatav4,this.$refresh?this.$refresh.$$persistence:null);return u.persistence?c.re():c};var A=function(a,c,d){if(d="boolean"!=typeof d||d,b.isDefined(a)&&b.isDefined(c)){var e=B.bind(a);e.$$persistence=b.isFunction(c)?c(d):c,Object.defineProperty(a,"$refresh",{enumerable:!1,configurable:!0,writable:!0,value:e})}},B=function(a,b){var d=function(a,b,c,d,e,f){return z({},{},b,c,!0,a,d,e,f)},e=new i.Provider(d,u.isodatav4,this.$refresh.$$persistence);if(e=e.re(),"count"==this.$refresh.$$persistence.$$type)return e.count();if("single"==this.$refresh.$$persistence.$$type)return e.single();var f=e.execute(),g=this instanceof Array;return x[g?"query":"get"].call(c,{},g?{}:this,a,b,g,(g?"":"?")+f,!g,!1,this.$refresh.$$persistence)};return x.bind=function(a){return m(j,p({},k,a),t)},x}var n=b.noop,o=b.forEach,p=b.extend,q=b.copy,r=b.isFunction,s=[];return l.prototype={setUrlParams:function(a,c,d,e,f){var h,i,k=this,l=d||k.template;if(l===k.template&&("PUT"===a.method||"DELETE"===a.method||"GET"==a.method&&!f||"PATCH"==a.method)&&b.isString(k.defaults.odatakey)){k.defaults.stripTrailingSlashes&&(l=l.replace(/\/+$/,"")||"/");var m=k.defaults.odatakey.split(","),n=m.map(function(a){return m.length>1?a+"=:"+a:":"+a});l=l+"("+n.join(",")+")",e&&o(m,function(a){c[a]=e[a]})}var p=k.urlParams={};o(l.split(/\W/),function(a){if("hasOwnProperty"===a)throw g("badname","hasOwnProperty is not a valid parameter name.");!new RegExp("^\\d+$").test(a)&&a&&new RegExp("(^|[^\\\\]):"+a+"(\\W|$)").test(l)&&(p[a]=!0)}),l=l.replace(/\\:/g,":"),c=c||{},o(k.urlParams,function(a,d){h=c.hasOwnProperty(d)?c[d]:k.defaults[d],b.isDefined(h)&&null!==h?(i=j(h),l=l.replace(new RegExp(":"+d+"(\\W|$)","g"),function(a,b){return i+b})):l=l.replace(new RegExp("(/?):"+d+"(\\W|$)","g"),function(a,b,c){return"/"==c.charAt(0)?c:b+c})}),k.defaults.stripTrailingSlashes&&(l=l.replace(/\/+$/,"")||"/"),l=l.replace(/\/\.(?=\w+($|\?))/,"."),a.url=l.replace(/\/\\\./,"/."),o(c,function(b,c){k.urlParams[c]||(a.params=a.params||{},a.params[c]=b)})}},m}]})}(window,window.angular),angular.module("ODataResources").factory("$odata",["$odataBinaryOperation","$odataProvider","$odataValue","$odataProperty","$odataMethodCall","$odataPredicate","$odataOrderByStatement","$odataExpandPredicate",function(a,b,c,d,e,f,g,h){return{Provider:b,BinaryOperation:a,Value:c,Property:d,Func:e,Predicate:f,OrderBy:g,ExpandPredicate:h}}]); \ No newline at end of file diff --git a/src/odatavalue.js b/src/odatavalue.js index 8216c96..b73c20e 100644 --- a/src/odatavalue.js +++ b/src/odatavalue.js @@ -17,9 +17,10 @@ factory('$odataValue', [ string = string.replace(/'/g, "''"); return string; }; - var ODataValue = function(input, type) { + var ODataValue = function(input, type, isCustomType) { this.value = input; this.type = type; + this.isCustomType = isCustomType; }; var generateDate = function(date,isOdataV4){ @@ -108,7 +109,9 @@ factory('$odataValue', [ return this.value; }else if(this.type.toLowerCase() === "int32"){ return parseInt(this.value)+""; - }else { + }else if(this.isCustomType){ + return this.type + "'" + this.value + "'"; + }else{ throw "Cannot convert "+this.value+" into "+this.type; } }else if(!isNaN(this.value)){ From 0087d883c8351903c3ac047923c1ce304abaa75d Mon Sep 17 00:00:00 2001 From: Andrey Shvydky Date: Fri, 6 Jan 2017 15:32:17 +0200 Subject: [PATCH 2/2] test added for custom type value --- build/odataresources.min.js | 2 +- specs/ODataResourcesTest.js | 665 ++++++++++++++++++------------------ 2 files changed, 339 insertions(+), 328 deletions(-) diff --git a/build/odataresources.min.js b/build/odataresources.min.js index 4c2674f..c41fdf9 100644 --- a/build/odataresources.min.js +++ b/build/odataresources.min.js @@ -1,2 +1,2 @@ -/*! angular-odata-resources 2016-11-29 */ +/*! angular-odata-resources 2017-01-06 */ angular.module("ODataResources",["ng"]),angular.module("ODataResources").factory("$odataOperators",[function(){var a=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,b=function(b){return b.replace(a,"")},c={eq:["=","==","==="],ne:["!=","!==","<>"],gt:[">"],ge:[">=",">=="],lt:["<"],le:["<=","<=="],and:["&&"],or:["||"],not:["!"],add:["+"],sub:["-"],mul:["*"],div:["/"],mod:["%"]},d=function(a){var d,e=b(a).toLowerCase();for(d in c){if(e===d)return d;for(var f=c[d],g=0;g-1)for(var c=0;c0&&(b+=","),b+=this.params[d].execute();b+=")"}return b},c}]),angular.module("ODataResources").factory("$odataOrderByStatement",[function(a,b,c){var d=function(a,b){if(void 0===a)throw"Orderby should be passed a property name but got undefined";this.propertyName=a,this.direction=b||"asc"};return d.prototype.execute=function(){return this.propertyName+" "+this.direction},d}]),angular.module("ODataResources").factory("$odataPredicate",["$odataBinaryOperation",function(a){var b=function(b,c,d){return angular.isFunction(b.execute)&&void 0===c?b:new a(b,c,d)};return b.and=function(b){if(b.length>0){for(var c=b[0],d=1;d0){for(var c=b[0],d=1;d0&&(b="$filter="+c.and(this.filters).execute(this.isv4,!0)),this.sortOrders.length>0)for(""!==b&&(b+="&"),b+="$orderby=",a=0;a0&&(b+=","),b+=this.sortOrders[a].execute();for(this.takeAmount&&(""!==b&&(b+="&"),b+="$top="+this.takeAmount),this.skipAmount&&(""!==b&&(b+="&"),b+="$skip="+this.skipAmount),this.expandables.length>0&&(""!==b&&(b+="&"),b+="$expand="+this.expandables.join(",")),this.selectables.length>0&&(""!==b&&(b+="&"),b+="$select="+this.selectables.join(",")),this.hasInlineCount>0&&(""!==b&&(b+="&"),b+=this.isv4?"$count=true":"$inlinecount=allpages"),this.formatBy&&(""!==b&&(b+="&"),b+="$format="+this.formatBy),a=0;a0&&(d="?"+d),this.$$callback("("+a+")"+d,b,c,!0,!1,f.bind(this,"get"))},g.prototype.count=function(a,b){if(!angular.isFunction(this.$$callback))throw"Cannot execute count, no callback was specified";a=a||angular.noop,b=b||angular.noop;var c=this.execute();return c.length>0&&(c="/?"+c),this.$$callback("/$count"+c,a,b,!0,!1,f.bind(this,"count"))},g.prototype.withInlineCount=function(){return this.hasInlineCount=!0,this};var h=function(a){var b=a.shift(),c=b;return a.length>0&&(c=c+"($expand="+h(a)+")"),c};return g.prototype.expand=function(a){if(!angular.isString(a)&&!angular.isArray(a))throw"Invalid parameter passed to expand method ("+a+")";if(""!==a){var b=a;if(this.isv4)angular.isArray(a)||(a=Array.prototype.slice.call(arguments)),b=h(a);else{b=angular.isArray(a)?a.join("/"):Array.prototype.slice.call(arguments).join("/");for(var c=0;c=0;b--)this.selectables.push(a[b]);return this}},g.prototype.re=function(a){if(this.$$reusables)for(var b in this.$$reusables)if(angular.isArray(this.$$reusables[b]))for(var c=0;c2&&b.isString(arguments[1])?Array.prototype.slice.call(arguments,1,5).reduce(function(a,b,d){return a[c[d]]=b,a},{}):arguments[1];return x.isResource(d)&&(d=x.store.getConfig(d)),b.extend(t,d.actions||{}),b.extend(k,d.paramDefaults||{}),b.extend(u,d.options||{}),b.isDefined(d.url)&&b.isString(d.url)&&(j=d.url),y=new l(j,u),x.store(a,{config:{url:j,paramDefaults:k,actions:t,options:u},pendingCorrection:!1}),!0},x.store.pendingCorrection=function(a){var b=x.store.get(a);return!!b&&(b.pendingCorrection||!1)},x.store.getRefreshingResource=function(a){var b=s.filter(function(b){return b.refreshedAs===a});return b?b[0]:null},o(t,function(a,e){var i=/^(POST|PUT|PATCH)$/i.test(a.method);x[e]=function(l,m,s,z,B,C,D,E,F){function G(c){var d=c.data,h=R.$promise;if(d&&b.isNumber(d["@odata.count"])&&(d.count=d["@odata.count"]),d&&(b.isString(d["@odata.context"])||b.isString(d["odata.metadata"]))&&d.value&&b.isArray(d.value)){var i=d;d=d.value;for(var j in i)"value"!==j&&(R[j]=i[j])}if(d){if(b.isArray(d)!==(!D&&!!a.isArray)&&!E)throw g("badcfg","Error in resource configuration for action `{0}`. Expected response to contain an {1} but got an {2} (Request: {3} {4})",e,!D&&a.isArray?"array":"object",b.isArray(d)?"array":"object",S.method,S.url);if(b.isArray(d)&&E){if(!(d.length>0))throw"The response returned no result";d=d[0]}!D&&a.isArray&&isNaN(parseInt(d))?(R.length=0,o(d,function(a){if("object"==typeof a){var b=new x(a);A(b,F,!1),R.push(b)}else R.push(a)})):(f(d,R),R.$promise=h)}return b.isNumber(d)&&D?R.result=d:!isNaN(parseInt(d))&&D&&(R.result=parseInt(d)),R.$resolved=!0,c.resource=R,x.store(R,{headers:c.headers()}),T(c)||c}function H(a){R.$resolved=!0;var b=x.store.getRefreshingResource(R);return b&&b.preventErrorLooping?(x.store(b.resource,{preventErrorLooping:!1}),h.reject(a)):(x.store(R,{headers:a.headers(),preventErrorLooping:!0}),K((U||n)(a)||a))}function I(a){return(N||n)(a,x.store.getHeaders(R)),a}function J(a){var b=x.store.getRefreshingResource(R);return b&&b.preventErrorLooping?(x.store(b.resource,{preventErrorLooping:!1}),h.reject(a)):(x.store(R,{preventErrorLooping:!0}),K((O||n)(a)||a).then(function(a){return(N||n)(a,x.store.getHeaders(R)),a}))}function K(a){if(b.isDefined(a)&&b.isObject(a)&&b.isObject(a.$correction)){x.store.updateConfig(R,a.$correction);var c=R.$refresh();return x.store(R,{refreshedAs:c}),c.$promise.then(L)}return b.isDefined(a)&&b.isDefined(a.$value)&&a.$correction&&(x.store(R,{pendingCorrection:a.$correction}),a=a.$value),x.isResource(a)?a.$promise.then(L):b.isDefined(a)&&b.isFunction(a.then)?a.then(L):h.reject(a)}function L(a){return x.isResource(a)?(x.store.copyHeaders(R,a),x.store.pendingCorrection(R)&&x.store.updateConfig(R,a),x.store(R,{preventErrorLooping:!1}),f(a,R),R):b.isDefined(a)&&b.isObject(a)&&b.isFunction(a.headers)?h.when(a).then(G):h.when({data:a,headers:function(){return null}}).then(G)}var M,N,O,P={};switch(arguments.length){case 9:case 8:case 7:case 6:case 4:O=z,N=s;case 3:case 2:if(!r(m)){P=l,M=m,N=s;break}if(r(l)){N=l,O=m;break}N=m,O=s;case 1:r(l)?N=l:i?M=l:P=l;break;case 0:break;default:throw g("badargs","Expected up to 4 arguments [params, data, success, error], got {0} arguments",arguments.length)}var Q=this instanceof x,R=Q?M:!D&&a.isArray?[]:new x(M),S={},T=a.interceptor&&a.interceptor.response||w,U=a.interceptor&&a.interceptor.responseError||c;A(R,F),o(a,function(a,b){"params"!=b&&"isArray"!=b&&"interceptor"!=b&&(S[b]=q(a))}),i&&(S.data=M),y.setUrlParams(S,p({},v(M,a.params||{}),P),a.url,M,B),!B||""===C||D&&!E?""!==C&&D&&(S.url+=C):S.url+="?"+C,u.ignoreLoadingBar&&(S.ignoreLoadingBar=!0);var V=d(S).then(G,H).then(I,J);return Q?V:(R.$promise=V,R.$resolved=!1,x.store(R,{config:{url:j,paramDefaults:k,actions:t,options:u}}),R)},x.prototype["$"+e]=function(a,b,c){r(a)&&(c=b,b=a,a={});var d=x[e].call(this,a,this,b,c);return d.$promise||d}});var z=x.odata;x.odata=function(a){var b=function(a,b,c,d,e,f){return z({},{},b,c,!0,a,d,e,f)},c=new i.Provider(b,u.isodatav4,this.$refresh?this.$refresh.$$persistence:null);return u.persistence?c.re():c};var A=function(a,c,d){if(d="boolean"!=typeof d||d,b.isDefined(a)&&b.isDefined(c)){var e=B.bind(a);e.$$persistence=b.isFunction(c)?c(d):c,Object.defineProperty(a,"$refresh",{enumerable:!1,configurable:!0,writable:!0,value:e})}},B=function(a,b){var d=function(a,b,c,d,e,f){return z({},{},b,c,!0,a,d,e,f)},e=new i.Provider(d,u.isodatav4,this.$refresh.$$persistence);if(e=e.re(),"count"==this.$refresh.$$persistence.$$type)return e.count();if("single"==this.$refresh.$$persistence.$$type)return e.single();var f=e.execute(),g=this instanceof Array;return x[g?"query":"get"].call(c,{},g?{}:this,a,b,g,(g?"":"?")+f,!g,!1,this.$refresh.$$persistence)};return x.bind=function(a){return m(j,p({},k,a),t)},x}var n=b.noop,o=b.forEach,p=b.extend,q=b.copy,r=b.isFunction,s=[];return l.prototype={setUrlParams:function(a,c,d,e,f){var h,i,k=this,l=d||k.template;if(l===k.template&&("PUT"===a.method||"DELETE"===a.method||"GET"==a.method&&!f||"PATCH"==a.method)&&b.isString(k.defaults.odatakey)){k.defaults.stripTrailingSlashes&&(l=l.replace(/\/+$/,"")||"/");var m=k.defaults.odatakey.split(","),n=m.map(function(a){return m.length>1?a+"=:"+a:":"+a});l=l+"("+n.join(",")+")",e&&o(m,function(a){c[a]=e[a]})}var p=k.urlParams={};o(l.split(/\W/),function(a){if("hasOwnProperty"===a)throw g("badname","hasOwnProperty is not a valid parameter name.");!new RegExp("^\\d+$").test(a)&&a&&new RegExp("(^|[^\\\\]):"+a+"(\\W|$)").test(l)&&(p[a]=!0)}),l=l.replace(/\\:/g,":"),c=c||{},o(k.urlParams,function(a,d){h=c.hasOwnProperty(d)?c[d]:k.defaults[d],b.isDefined(h)&&null!==h?(i=j(h),l=l.replace(new RegExp(":"+d+"(\\W|$)","g"),function(a,b){return i+b})):l=l.replace(new RegExp("(/?):"+d+"(\\W|$)","g"),function(a,b,c){return"/"==c.charAt(0)?c:b+c})}),k.defaults.stripTrailingSlashes&&(l=l.replace(/\/+$/,"")||"/"),l=l.replace(/\/\.(?=\w+($|\?))/,"."),a.url=l.replace(/\/\\\./,"/."),o(c,function(b,c){k.urlParams[c]||(a.params=a.params||{},a.params[c]=b)})}},m}]})}(window,window.angular),angular.module("ODataResources").factory("$odata",["$odataBinaryOperation","$odataProvider","$odataValue","$odataProperty","$odataMethodCall","$odataPredicate","$odataOrderByStatement","$odataExpandPredicate",function(a,b,c,d,e,f,g,h){return{Provider:b,BinaryOperation:a,Value:c,Property:d,Func:e,Predicate:f,OrderBy:g,ExpandPredicate:h}}]); \ No newline at end of file diff --git a/specs/ODataResourcesTest.js b/specs/ODataResourcesTest.js index bfce73f..f45c543 100644 --- a/specs/ODataResourcesTest.js +++ b/specs/ODataResourcesTest.js @@ -10,29 +10,29 @@ (function() { "use strict"; var $odataresource; - var $httpBackend; + var $httpBackend; var $odata; - var scope; + var scope; var _config; - describe('ODataResources Service', function () { - beforeEach(module('ODataResources')); + describe('ODataResources Service', function () { + beforeEach(module('ODataResources')); beforeEach(function () { inject(function (_$odataresource_, _$httpBackend_, _$odata_, $rootScope) { - angular.module('ODataResources').config(function ($httpProvider) { - $httpProvider.interceptors.push(function () { - return { - 'request': function (config) { - _config = config; - return config; - }, - }; - }); + angular.module('ODataResources').config(function ($httpProvider) { + $httpProvider.interceptors.push(function () { + return { + 'request': function (config) { + _config = config; + return config; + }, + }; + }); }); $odataresource = _$odataresource_; $httpBackend = _$httpBackend_; $odata = _$odata_; configureHttpBackend($httpBackend); - scope = $rootScope; + scope = $rootScope; }); }); afterEach(function() { @@ -130,6 +130,17 @@ .toBe(1); }); + it('filters should work with custom type', function() { + $httpBackend.expectGET("/user?$filter=Gender eq Enum.Namespace.Gender'Female'") + .respond(200, [1, 2]); + User.odata() + .filter(new $odata.Predicate("Gender", new $odata.Value("Female", "Enum.Namespace.Gender", true))) + .query(); + $httpBackend.flush(); + expect(1) + .toBe(1); + }); + it('should work with complex queries', function() { $httpBackend.expectGET("/user?$filter=(Name eq 'Raphael') and (Age gt 20)&$orderby=Name desc&$top=20&$skip=10") .respond(200, [1, 2]); @@ -602,52 +613,52 @@ .toBe(true); $httpBackend.flush(); }); - }); - describe('Method call options', function() { - it('should work with custom urls', function () { - var successInterceptor = jasmine.createSpy('sucessInterceptor'); + }); + describe('Method call options', function() { + it('should work with custom urls', function () { + var successInterceptor = jasmine.createSpy('sucessInterceptor'); var ProductRating = $odataresource('/Products(:productId)/ProductService.Rate', { productId: "@ProductID" }, { update: { method: 'PUT', interceptor: { response: successInterceptor } } }); $httpBackend.expectPUT("/Products(5)/ProductService.Rate") - .respond(204, undefined, undefined, 'No Content'); - var productRating = new ProductRating(); - productRating.ProductID = 5; - productRating.Rating = 10; + .respond(204, undefined, undefined, 'No Content'); + var productRating = new ProductRating(); + productRating.ProductID = 5; + productRating.Rating = 10; var response = productRating.$update(); - $httpBackend.flush(); - console.log(successInterceptor.calls.mostRecent()); - expect(successInterceptor).toHaveBeenCalled(); - expect(successInterceptor.calls.mostRecent().args[0].status).toBe(204); - expect(successInterceptor.calls.mostRecent().args[0].statusText).toBe('No Content'); - }); - it('should work with custom actions', function () { - var successInterceptor = jasmine.createSpy('sucessInterceptor'); - var Products = $odataresource('/Products', {}, { - rate: { - method: 'PUT', - url: '/Products(:productId)/ProductService.Rate', - params: { - productId: '@ProductID', - }, - interceptor: { - response: successInterceptor - }, - }, - }, { odatakey: 'ProductID' }); - $httpBackend.expectGET('/Products(5)') - .respond(200, { ProductID: 5, Rating: 9 }); - var product = Products.odata().get(5); - $httpBackend.flush(); - expect(product.ProductID).toBe(5); - expect(product.Rating).toBe(9); + $httpBackend.flush(); + console.log(successInterceptor.calls.mostRecent()); + expect(successInterceptor).toHaveBeenCalled(); + expect(successInterceptor.calls.mostRecent().args[0].status).toBe(204); + expect(successInterceptor.calls.mostRecent().args[0].statusText).toBe('No Content'); + }); + it('should work with custom actions', function () { + var successInterceptor = jasmine.createSpy('sucessInterceptor'); + var Products = $odataresource('/Products', {}, { + rate: { + method: 'PUT', + url: '/Products(:productId)/ProductService.Rate', + params: { + productId: '@ProductID', + }, + interceptor: { + response: successInterceptor + }, + }, + }, { odatakey: 'ProductID' }); + $httpBackend.expectGET('/Products(5)') + .respond(200, { ProductID: 5, Rating: 9 }); + var product = Products.odata().get(5); + $httpBackend.flush(); + expect(product.ProductID).toBe(5); + expect(product.Rating).toBe(9); $httpBackend.expectPUT("/Products(5)/ProductService.Rate") - .respond(204, undefined, undefined, 'No Content'); - product.Rating = 10; + .respond(204, undefined, undefined, 'No Content'); + product.Rating = 10; product.$rate(); - $httpBackend.flush(); - expect(successInterceptor).toHaveBeenCalled(); - expect(successInterceptor.calls.mostRecent().args[0].status).toBe(204); - expect(successInterceptor.calls.mostRecent().args[0].statusText).toBe('No Content'); - }); + $httpBackend.flush(); + expect(successInterceptor).toHaveBeenCalled(); + expect(successInterceptor.calls.mostRecent().args[0].status).toBe(204); + expect(successInterceptor.calls.mostRecent().args[0].statusText).toBe('No Content'); + }); }); describe('OData v4 not explicitly specified', function() { var User; @@ -761,39 +772,39 @@ .toBe(10); }); - it('should work with key\'s specified as comma seperated list in options', function () { - User = $odataresource('/user', {}, {}, { - odatakey: 'id,id2' + it('should work with key\'s specified as comma seperated list in options', function () { + User = $odataresource('/user', {}, {}, { + odatakey: 'id,id2' }); $httpBackend.expectGET("/user") - .respond(200, { + .respond(200, { "@odata.context": "http://host/service/$metadata#Collection(Edm.String)", - "value": [{ + "value": [{ name: 'Test', - id: 1, - id2: 1, - },{ + id: 1, + id2: 1, + },{ name: 'Test2', - id: 1, - id2: 2, - }, { + id: 1, + id2: 2, + }, { name: 'Foo', - id: 2, - id2: 1, - }, { + id: 2, + id2: 1, + }, { name: 'Foo2', - id: 2, - id2: 2, - }, { + id: 2, + id2: 2, + }, { name: 'Bar', - id: 3, - id2: 1, - }, { + id: 3, + id2: 1, + }, { name: 'Bar2', - id: 3, - id2: 2, + id: 3, + id2: 2, }], - 'count': 10 + 'count': 10 }); var result = User.odata() .query(); @@ -804,7 +815,7 @@ $httpBackend.flush(); console.log(result); expect(result.count) - .toBe(10); + .toBe(10); }); it('should delete', function() { @@ -936,7 +947,7 @@ $httpBackend.flush(); expect(result.count) .toBe(10); - }); + }); }); describe('OData v4 explicitly specified', function() { var User; @@ -1152,253 +1163,253 @@ $httpBackend.flush(); expect(1).toBe(1); }); - }); - describe('OData $refresh feature', function() { - var User; - beforeEach(function () { }); - // should run re() on the odata method automatically if options.persistence - it('shouldn\'t apply $refresh to initial odataresource object', function() { - User = $odataresource('/user', {}, {}, { persistence: true }); - expect(User.$refresh).not.toBeDefined(); - }); - it('should add limited persisted $refresh to individual odataresource objects of query response', function() { - User = $odataresource('/user', {}, {}, { persistence: true }); - $httpBackend.expectGET('/user?$top=10&$select=name,id').respond(200, { - "@odata.context": "http://host/service/$metadata#Collection(Edm.String)", - "value": [ - { - name: 'Test', - id: 1, - }, { - name: 'Foo', - id: 2, - }, { - name: 'Bar', - id: 3, - } - ], - 'count': 3 - }); - var result = User.odata().select('name').select('id').take(10).query(function (response) { - expect(result.$refresh).toBeDefined(); - expect(result[0].$refresh).toBeDefined(); - expect(result.$refresh.$$persistence).not.toBe(result[0].$refresh.$$persistence); - expect(result[0].$odata().execute()).toBe('$select=name,id'); - }); - $httpBackend.flush(); - }); - it('should add full persisted $refresh to non get query response', function () { - User = $odataresource('/user', {}, {}, {persistence: true }); - $httpBackend.expectGET('/user?$top=10&$select=name,id').respond(200, { - "@odata.context": "http://host/service/$metadata#Collection(Edm.String)", - "value": [ - { - name: 'Test', - id: 1, - }, { - name: 'Foo', - id: 2, - }, { - name: 'Bar', - id: 3, - } - ], - 'count': 3 - }); - var result = User.odata().select('name').select('id').take(10).query(function(response) { - expect(result.$refresh).toBeDefined(); - expect(result.$refresh.$$persistence.takeAmount).toBe(10); - }); - $httpBackend.flush(); - }); - it('should return individual item with individual item instance $refresh', function() { - User = $odataresource('/user', {}, {}, { isodatav4: true, odatakey: 'id', persistence: true }); - $httpBackend.expectGET('/user?$top=10&$select=name,id').respond(200, { - "@odata.context": "http://host/service/$metadata#Collection(Edm.String)", - "value": [ - { - name: 'Test', - id: 1, - }, { - name: 'Foo', - id: 2, - }, { - name: 'Bar', - id: 3, - } - ], - 'count': 3 - }); - - var result = User.odata().select('name').select('id').take(10).query(function(response) { - expect(result[0].$refresh).toBeDefined(); - $httpBackend.expectGET('/user(1)?$select=name,id').respond(200, { + }); + describe('OData $refresh feature', function() { + var User; + beforeEach(function () { }); + // should run re() on the odata method automatically if options.persistence + it('shouldn\'t apply $refresh to initial odataresource object', function() { + User = $odataresource('/user', {}, {}, { persistence: true }); + expect(User.$refresh).not.toBeDefined(); + }); + it('should add limited persisted $refresh to individual odataresource objects of query response', function() { + User = $odataresource('/user', {}, {}, { persistence: true }); + $httpBackend.expectGET('/user?$top=10&$select=name,id').respond(200, { + "@odata.context": "http://host/service/$metadata#Collection(Edm.String)", + "value": [ + { + name: 'Test', + id: 1, + }, { + name: 'Foo', + id: 2, + }, { + name: 'Bar', + id: 3, + } + ], + 'count': 3 + }); + var result = User.odata().select('name').select('id').take(10).query(function (response) { + expect(result.$refresh).toBeDefined(); + expect(result[0].$refresh).toBeDefined(); + expect(result.$refresh.$$persistence).not.toBe(result[0].$refresh.$$persistence); + expect(result[0].$odata().execute()).toBe('$select=name,id'); + }); + $httpBackend.flush(); + }); + it('should add full persisted $refresh to non get query response', function () { + User = $odataresource('/user', {}, {}, {persistence: true }); + $httpBackend.expectGET('/user?$top=10&$select=name,id').respond(200, { + "@odata.context": "http://host/service/$metadata#Collection(Edm.String)", + "value": [ + { + name: 'Test', + id: 1, + }, { + name: 'Foo', + id: 2, + }, { + name: 'Bar', + id: 3, + } + ], + 'count': 3 + }); + var result = User.odata().select('name').select('id').take(10).query(function(response) { + expect(result.$refresh).toBeDefined(); + expect(result.$refresh.$$persistence.takeAmount).toBe(10); + }); + $httpBackend.flush(); + }); + it('should return individual item with individual item instance $refresh', function() { + User = $odataresource('/user', {}, {}, { isodatav4: true, odatakey: 'id', persistence: true }); + $httpBackend.expectGET('/user?$top=10&$select=name,id').respond(200, { + "@odata.context": "http://host/service/$metadata#Collection(Edm.String)", + "value": [ + { + name: 'Test', + id: 1, + }, { + name: 'Foo', + id: 2, + }, { + name: 'Bar', + id: 3, + } + ], + 'count': 3 + }); + + var result = User.odata().select('name').select('id').take(10).query(function(response) { + expect(result[0].$refresh).toBeDefined(); + $httpBackend.expectGET('/user(1)?$select=name,id').respond(200, { name: 'Test', - id: 1, - }); - result[0].$refresh(function(response2) { - expect(response2.id).toBe(1); - expect(response2.$refresh).toBeDefined(); - }); - }); - - $httpBackend.flush(); - }); - it('should return an array when array instance $refresh', function() { - User = $odataresource('/user', {}, {}, { isodatav4: true, odatakey: 'id', persistence: true }); - $httpBackend.expectGET('/user?$top=3&$select=name,id').respond(200, { - "@odata.context": "http://host/service/$metadata#Collection(Edm.String)", - "value": [ - { - name: 'Test', - id: 1, - }, { - name: 'Foo', - id: 2, - }, { - name: 'Bar', - id: 3, - } - ], - 'count': 3 - }); - - var result = User.odata().select('name').select('id').take(3).query(function(response) { - expect(result.$refresh).toBeDefined(); - $httpBackend.expectGET('/user?$top=3&$select=name,id').respond(200, { - "@odata.context": "http://host/service/$metadata#Collection(Edm.String)", - "value": [ - { - name: 'Test', - id: 1, - }, { - name: 'Foo', - id: 2, - }, { - name: 'Bar', - id: 3, - } - ], - 'count': 3 - }); - result.$refresh(function(response2) { - expect(response2.count).toBe(3); - expect(response2.$refresh).toBeDefined(); - }); - }); - - $httpBackend.flush(); - }); - it('should return a single response when single instance $refresh', function() { - User = $odataresource('/user', {}, {}, { isodatav4: true, odatakey: 'id', persistence: true }); - $httpBackend.expectGET('/user?$top=3&$select=name,id').respond(200, { - "@odata.context": "http://host/service/$metadata#Collection(Edm.String)", - "value": [ - { - name: 'Test', - id: 1, - }, { - name: 'Foo', - id: 2, - }, { - name: 'Bar', - id: 3, - } - ], - 'count': 3 - }); - - var result = User.odata().select('name').select('id').take(3).single(function(response) { - expect(result.$refresh).toBeDefined(); - $httpBackend.expectGET('/user?$top=3&$select=name,id').respond(200, { - "@odata.context": "http://host/service/$metadata#Collection(Edm.String)", - "value": [ - { - name: 'Test', - id: 1, - }, { - name: 'Foo', - id: 2, - }, { - name: 'Bar', - id: 3, - } - ], - 'count': 3 - }); - result.$refresh(function(response2) { - expect(response2.id).toBe(1); - expect(response2.$refresh).toBeDefined(); - }); - }); - - $httpBackend.flush(); - }); - it('should return an new count on a count instance $refresh', function() { - User = $odataresource('/user', {}, {}, { isodatav4: true, odatakey: 'id', persistence: true }); - $httpBackend.expectGET("/user/$count/?$top=3&$select=name,id").respond(200, 15); - - var result = User.odata().select('name').select('id').take(3).count(function(response) { - expect(result.$refresh).toBeDefined(); - $httpBackend.expectGET("/user/$count/?$top=3&$select=name,id").respond(200, 15); - result.$refresh(function(response2) { - expect(response2.result).toBe(15); - expect(response2.$refresh0.toBeDefined()); - }); - }); - - $httpBackend.flush(); - }); - }); - describe('HttpConfig options', function () { - var User; - beforeEach(function() {}); - it('should have noLoadingBar property when option set.', function () { - $httpBackend.expectGET("/user").respond(200); - User = $odataresource("/user", {}, {}, { ignoreLoadingBar: true }); - User.odata().query(); - $httpBackend.flush(); - expect(_config.ignoreLoadingBar).toBeDefined(); - expect(_config.ignoreLoadingBar).toBe(true); - }); - it('should not have noLoadingBar property when option not set.', function () { - $httpBackend.expectGET("/user").respond(200); - User = $odataresource("/user"); - User.odata().query(); - $httpBackend.flush(); - expect(_config.ignoreLoadingBar).not.toBeDefined(); - }); - }); - describe('Configuration and Options', function() { - var User, Metadata; - beforeEach(function () { }); - it('should allow post initialization updates', function() { - $httpBackend.whenGET('/user$metadata').respond(200, 'test meteadata'); - $httpBackend.whenGET('/user').respond(200, [{ UserId: 5 }]); - Metadata = $odataresource('/user$metadata', {}, { - get: { - transformResponse: function(data) { - return data.replace('', ''); - }, - }, - }, {}); - User = $odataresource('/user', {}, {}, { isodatav4: true }); - var user = User.odata().query(); - $httpBackend.flush(); - expect(user[0].UserId).toBe(5); - $httpBackend.expectPUT('/user').respond(500, undefined, undefined, 'Internal Server Error'); - user[0].$update(); - $httpBackend.flush(); - var metadata = Metadata.odata().single(function (response) { - expect(User.store.updateConfig(user)).toBe(false); - User.store.updateConfig(user, '/user', {}, {}, { odatakey: 'UserId' }); - }); - $httpBackend.flush(); - $httpBackend.expectPUT('/user(6)').respond(204, undefined, undefined, 'No Content'); - user[0].UserId = 6; - user[0].$update(); - $httpBackend.flush(); - }); - }); + id: 1, + }); + result[0].$refresh(function(response2) { + expect(response2.id).toBe(1); + expect(response2.$refresh).toBeDefined(); + }); + }); + + $httpBackend.flush(); + }); + it('should return an array when array instance $refresh', function() { + User = $odataresource('/user', {}, {}, { isodatav4: true, odatakey: 'id', persistence: true }); + $httpBackend.expectGET('/user?$top=3&$select=name,id').respond(200, { + "@odata.context": "http://host/service/$metadata#Collection(Edm.String)", + "value": [ + { + name: 'Test', + id: 1, + }, { + name: 'Foo', + id: 2, + }, { + name: 'Bar', + id: 3, + } + ], + 'count': 3 + }); + + var result = User.odata().select('name').select('id').take(3).query(function(response) { + expect(result.$refresh).toBeDefined(); + $httpBackend.expectGET('/user?$top=3&$select=name,id').respond(200, { + "@odata.context": "http://host/service/$metadata#Collection(Edm.String)", + "value": [ + { + name: 'Test', + id: 1, + }, { + name: 'Foo', + id: 2, + }, { + name: 'Bar', + id: 3, + } + ], + 'count': 3 + }); + result.$refresh(function(response2) { + expect(response2.count).toBe(3); + expect(response2.$refresh).toBeDefined(); + }); + }); + + $httpBackend.flush(); + }); + it('should return a single response when single instance $refresh', function() { + User = $odataresource('/user', {}, {}, { isodatav4: true, odatakey: 'id', persistence: true }); + $httpBackend.expectGET('/user?$top=3&$select=name,id').respond(200, { + "@odata.context": "http://host/service/$metadata#Collection(Edm.String)", + "value": [ + { + name: 'Test', + id: 1, + }, { + name: 'Foo', + id: 2, + }, { + name: 'Bar', + id: 3, + } + ], + 'count': 3 + }); + + var result = User.odata().select('name').select('id').take(3).single(function(response) { + expect(result.$refresh).toBeDefined(); + $httpBackend.expectGET('/user?$top=3&$select=name,id').respond(200, { + "@odata.context": "http://host/service/$metadata#Collection(Edm.String)", + "value": [ + { + name: 'Test', + id: 1, + }, { + name: 'Foo', + id: 2, + }, { + name: 'Bar', + id: 3, + } + ], + 'count': 3 + }); + result.$refresh(function(response2) { + expect(response2.id).toBe(1); + expect(response2.$refresh).toBeDefined(); + }); + }); + + $httpBackend.flush(); + }); + it('should return an new count on a count instance $refresh', function() { + User = $odataresource('/user', {}, {}, { isodatav4: true, odatakey: 'id', persistence: true }); + $httpBackend.expectGET("/user/$count/?$top=3&$select=name,id").respond(200, 15); + + var result = User.odata().select('name').select('id').take(3).count(function(response) { + expect(result.$refresh).toBeDefined(); + $httpBackend.expectGET("/user/$count/?$top=3&$select=name,id").respond(200, 15); + result.$refresh(function(response2) { + expect(response2.result).toBe(15); + expect(response2.$refresh0.toBeDefined()); + }); + }); + + $httpBackend.flush(); + }); + }); + describe('HttpConfig options', function () { + var User; + beforeEach(function() {}); + it('should have noLoadingBar property when option set.', function () { + $httpBackend.expectGET("/user").respond(200); + User = $odataresource("/user", {}, {}, { ignoreLoadingBar: true }); + User.odata().query(); + $httpBackend.flush(); + expect(_config.ignoreLoadingBar).toBeDefined(); + expect(_config.ignoreLoadingBar).toBe(true); + }); + it('should not have noLoadingBar property when option not set.', function () { + $httpBackend.expectGET("/user").respond(200); + User = $odataresource("/user"); + User.odata().query(); + $httpBackend.flush(); + expect(_config.ignoreLoadingBar).not.toBeDefined(); + }); + }); + describe('Configuration and Options', function() { + var User, Metadata; + beforeEach(function () { }); + it('should allow post initialization updates', function() { + $httpBackend.whenGET('/user$metadata').respond(200, 'test meteadata'); + $httpBackend.whenGET('/user').respond(200, [{ UserId: 5 }]); + Metadata = $odataresource('/user$metadata', {}, { + get: { + transformResponse: function(data) { + return data.replace('', ''); + }, + }, + }, {}); + User = $odataresource('/user', {}, {}, { isodatav4: true }); + var user = User.odata().query(); + $httpBackend.flush(); + expect(user[0].UserId).toBe(5); + $httpBackend.expectPUT('/user').respond(500, undefined, undefined, 'Internal Server Error'); + user[0].$update(); + $httpBackend.flush(); + var metadata = Metadata.odata().single(function (response) { + expect(User.store.updateConfig(user)).toBe(false); + User.store.updateConfig(user, '/user', {}, {}, { odatakey: 'UserId' }); + }); + $httpBackend.flush(); + $httpBackend.expectPUT('/user(6)').respond(204, undefined, undefined, 'No Content'); + user[0].UserId = 6; + user[0].$update(); + $httpBackend.flush(); + }); + }); }); })();