summaryrefslogtreecommitdiffstats
path: root/js/vendor/angular-mocks/angular-mocks.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/vendor/angular-mocks/angular-mocks.js')
-rw-r--r--js/vendor/angular-mocks/angular-mocks.js727
1 files changed, 531 insertions, 196 deletions
diff --git a/js/vendor/angular-mocks/angular-mocks.js b/js/vendor/angular-mocks/angular-mocks.js
index 1ee6c67c0..34d360870 100644
--- a/js/vendor/angular-mocks/angular-mocks.js
+++ b/js/vendor/angular-mocks/angular-mocks.js
@@ -1,6 +1,6 @@
/**
- * @license AngularJS v1.3.20
- * (c) 2010-2014 Google, Inc. http://angularjs.org
+ * @license AngularJS v1.5.0
+ * (c) 2010-2016 Google, Inc. http://angularjs.org
* License: MIT
*/
(function(window, angular, undefined) {
@@ -64,10 +64,9 @@ angular.mock.$Browser = function() {
return listener;
};
+ self.$$applicationDestroyed = angular.noop;
self.$$checkUrlChange = angular.noop;
- self.cookieHash = {};
- self.lastCookieHash = {};
self.deferredFns = [];
self.deferredNextId = 0;
@@ -95,7 +94,7 @@ angular.mock.$Browser = function() {
if (fn.id === deferId) fnIndex = index;
});
- if (fnIndex !== undefined) {
+ if (angular.isDefined(fnIndex)) {
self.deferredFns.splice(fnIndex, 1);
return true;
}
@@ -147,11 +146,6 @@ angular.mock.$Browser.prototype = {
});
},
- addPollFn: function(pollFn) {
- this.pollFns.push(pollFn);
- return pollFn;
- },
-
url: function(url, replace, state) {
if (angular.isUndefined(state)) {
state = null;
@@ -170,25 +164,6 @@ angular.mock.$Browser.prototype = {
return this.$$state;
},
- cookies: function(name, value) {
- if (name) {
- if (angular.isUndefined(value)) {
- delete this.cookieHash[name];
- } else {
- if (angular.isString(value) && //strings only
- value.length <= 4096) { //strict cookie storage limits
- this.cookieHash[name] = value;
- }
- }
- } else {
- if (!angular.equals(this.cookieHash, this.lastCookieHash)) {
- this.lastCookieHash = angular.copy(this.cookieHash);
- this.cookieHash = angular.copy(this.cookieHash);
- }
- return this.cookieHash;
- }
- },
-
notifyWhenNoOutstandingRequests: function(fn) {
fn();
}
@@ -458,6 +433,7 @@ angular.mock.$LogProvider = function() {
* indefinitely.
* @param {boolean=} [invokeApply=true] If set to `false` skips model dirty checking, otherwise
* will invoke `fn` within the {@link ng.$rootScope.Scope#$apply $apply} block.
+ * @param {...*=} Pass additional parameters to the executed function.
* @returns {promise} A promise which will be notified on each iteration.
*/
angular.mock.$IntervalProvider = function() {
@@ -468,13 +444,17 @@ angular.mock.$IntervalProvider = function() {
now = 0;
var $interval = function(fn, delay, count, invokeApply) {
- var iteration = 0,
+ var hasParams = arguments.length > 4,
+ args = hasParams ? Array.prototype.slice.call(arguments, 4) : [],
+ iteration = 0,
skipApply = (angular.isDefined(invokeApply) && !invokeApply),
deferred = (skipApply ? $$q : $q).defer(),
promise = deferred.promise;
count = (angular.isDefined(count)) ? count : 0;
- promise.then(null, null, fn);
+ promise.then(null, null, (!hasParams) ? fn : function() {
+ fn.apply(null, args);
+ });
promise.$$intervalId = nextRepeatId;
@@ -489,7 +469,7 @@ angular.mock.$IntervalProvider = function() {
if (fn.id === promise.$$intervalId) fnIndex = index;
});
- if (fnIndex !== undefined) {
+ if (angular.isDefined(fnIndex)) {
repeatFns.splice(fnIndex, 1);
}
}
@@ -531,7 +511,7 @@ angular.mock.$IntervalProvider = function() {
if (fn.id === promise.$$intervalId) fnIndex = index;
});
- if (fnIndex !== undefined) {
+ if (angular.isDefined(fnIndex)) {
repeatFns[fnIndex].deferred.reject('canceled');
repeatFns.splice(fnIndex, 1);
return true;
@@ -581,20 +561,20 @@ function jsonStringToDate(string) {
tzHour = 0,
tzMin = 0;
if (match[9]) {
- tzHour = int(match[9] + match[10]);
- tzMin = int(match[9] + match[11]);
+ tzHour = toInt(match[9] + match[10]);
+ tzMin = toInt(match[9] + match[11]);
}
- date.setUTCFullYear(int(match[1]), int(match[2]) - 1, int(match[3]));
- date.setUTCHours(int(match[4] || 0) - tzHour,
- int(match[5] || 0) - tzMin,
- int(match[6] || 0),
- int(match[7] || 0));
+ date.setUTCFullYear(toInt(match[1]), toInt(match[2]) - 1, toInt(match[3]));
+ date.setUTCHours(toInt(match[4] || 0) - tzHour,
+ toInt(match[5] || 0) - tzMin,
+ toInt(match[6] || 0),
+ toInt(match[7] || 0));
return date;
}
return string;
}
-function int(str) {
+function toInt(str) {
return parseInt(str, 10);
}
@@ -606,8 +586,9 @@ function padNumber(num, digits, trim) {
}
num = '' + num;
while (num.length < digits) num = '0' + num;
- if (trim)
+ if (trim) {
num = num.substr(num.length - digits);
+ }
return neg + num;
}
@@ -657,11 +638,12 @@ angular.mock.TzDate = function(offset, timestamp) {
self.origDate = jsonStringToDate(timestamp);
timestamp = self.origDate.getTime();
- if (isNaN(timestamp))
+ if (isNaN(timestamp)) {
throw {
name: "Illegal Argument",
message: "Arg '" + tsStr + "' passed into TzDate constructor is not a valid date string"
};
+ }
} else {
self.origDate = new Date(timestamp);
}
@@ -776,77 +758,152 @@ angular.mock.TzDate = function(offset, timestamp) {
angular.mock.TzDate.prototype = Date.prototype;
/* jshint +W101 */
+
+/**
+ * @ngdoc service
+ * @name $animate
+ *
+ * @description
+ * Mock implementation of the {@link ng.$animate `$animate`} service. Exposes two additional methods
+ * for testing animations.
+ */
angular.mock.animate = angular.module('ngAnimateMock', ['ng'])
.config(['$provide', function($provide) {
- var reflowQueue = [];
- $provide.value('$$animateReflow', function(fn) {
- var index = reflowQueue.length;
- reflowQueue.push(fn);
- return function cancel() {
- reflowQueue.splice(index, 1);
+ $provide.factory('$$forceReflow', function() {
+ function reflowFn() {
+ reflowFn.totalReflows++;
+ }
+ reflowFn.totalReflows = 0;
+ return reflowFn;
+ });
+
+ $provide.factory('$$animateAsyncRun', function() {
+ var queue = [];
+ var queueFn = function() {
+ return function(fn) {
+ queue.push(fn);
+ };
};
+ queueFn.flush = function() {
+ if (queue.length === 0) return false;
+
+ for (var i = 0; i < queue.length; i++) {
+ queue[i]();
+ }
+ queue = [];
+
+ return true;
+ };
+ return queueFn;
});
- $provide.decorator('$animate', ['$delegate', '$$asyncCallback', '$timeout', '$browser', '$rootScope', '$$rAF',
- function($delegate, $$asyncCallback, $timeout, $browser, $rootScope, $$rAF) {
+ $provide.decorator('$$animateJs', ['$delegate', function($delegate) {
+ var runners = [];
+
+ var animateJsConstructor = function() {
+ var animator = $delegate.apply($delegate, arguments);
+ // If no javascript animation is found, animator is undefined
+ if (animator) {
+ runners.push(animator);
+ }
+ return animator;
+ };
+
+ animateJsConstructor.$closeAndFlush = function() {
+ runners.forEach(function(runner) {
+ runner.end();
+ });
+ runners = [];
+ };
+
+ return animateJsConstructor;
+ }]);
+
+ $provide.decorator('$animateCss', ['$delegate', function($delegate) {
+ var runners = [];
+
+ var animateCssConstructor = function(element, options) {
+ var animator = $delegate(element, options);
+ runners.push(animator);
+ return animator;
+ };
+
+ animateCssConstructor.$closeAndFlush = function() {
+ runners.forEach(function(runner) {
+ runner.end();
+ });
+ runners = [];
+ };
+
+ return animateCssConstructor;
+ }]);
+
+ $provide.decorator('$animate', ['$delegate', '$timeout', '$browser', '$$rAF', '$animateCss', '$$animateJs',
+ '$$forceReflow', '$$animateAsyncRun', '$rootScope',
+ function($delegate, $timeout, $browser, $$rAF, $animateCss, $$animateJs,
+ $$forceReflow, $$animateAsyncRun, $rootScope) {
var animate = {
queue: [],
cancel: $delegate.cancel,
- enabled: $delegate.enabled,
- triggerCallbackEvents: function() {
- $$asyncCallback.flush();
- },
- triggerCallbackPromise: function() {
- $timeout.flush(0);
- },
- triggerCallbacks: function() {
- this.triggerCallbackEvents();
- this.triggerCallbackPromise();
+ on: $delegate.on,
+ off: $delegate.off,
+ pin: $delegate.pin,
+ get reflows() {
+ return $$forceReflow.totalReflows;
},
- triggerReflow: function() {
- angular.forEach(reflowQueue, function(fn) {
- fn();
- });
- reflowQueue = [];
+ enabled: $delegate.enabled,
+ /**
+ * @ngdoc method
+ * @name $animate#closeAndFlush
+ * @description
+ *
+ * This method will close all pending animations (both {@link ngAnimate#javascript-based-animations Javascript}
+ * and {@link ngAnimate.$animateCss CSS}) and it will also flush any remaining animation frames and/or callbacks.
+ */
+ closeAndFlush: function() {
+ // we allow the flush command to swallow the errors
+ // because depending on whether CSS or JS animations are
+ // used, there may not be a RAF flush. The primary flush
+ // at the end of this function must throw an exception
+ // because it will track if there were pending animations
+ this.flush(true);
+ $animateCss.$closeAndFlush();
+ $$animateJs.$closeAndFlush();
+ this.flush();
},
- flush: function() {
+ /**
+ * @ngdoc method
+ * @name $animate#flush
+ * @description
+ *
+ * This method is used to flush the pending callbacks and animation frames to either start
+ * an animation or conclude an animation. Note that this will not actually close an
+ * actively running animation (see {@link ngMock.$animate#closeAndFlush `closeAndFlush()`} for that).
+ */
+ flush: function(hideErrors) {
$rootScope.$digest();
+
var doNextRun, somethingFlushed = false;
do {
doNextRun = false;
- if (reflowQueue.length) {
- doNextRun = somethingFlushed = true;
- this.triggerReflow();
- }
+
if ($$rAF.queue.length) {
- doNextRun = somethingFlushed = true;
$$rAF.flush();
- }
- if ($$asyncCallback.queue.length) {
doNextRun = somethingFlushed = true;
- this.triggerCallbackEvents();
}
- if (timeoutsRemaining()) {
- var oldValue = timeoutsRemaining();
- this.triggerCallbackPromise();
- var newValue = timeoutsRemaining();
- if (newValue < oldValue) {
- doNextRun = somethingFlushed = true;
- }
+
+ if ($$animateAsyncRun.flush()) {
+ doNextRun = somethingFlushed = true;
}
} while (doNextRun);
- if (!somethingFlushed) {
+ if (!somethingFlushed && !hideErrors) {
throw new Error('No pending animations ready to be closed or flushed');
}
$rootScope.$digest();
-
- function timeoutsRemaining() {
- return $browser.deferredFns.length;
- }
}
};
@@ -971,7 +1028,7 @@ angular.mock.dump = function(object) {
* - `$httpBackend.when` - specifies a backend definition
*
*
- * # Request Expectations vs Backend Definitions
+ * ## Request Expectations vs Backend Definitions
*
* Request expectations provide a way to make assertions about requests made by the application and
* to define responses for those requests. The test will fail if the expected requests are not made
@@ -1027,7 +1084,7 @@ angular.mock.dump = function(object) {
* the request. The response from the first matched definition is returned.
*
*
- * # Flushing HTTP requests
+ * ## Flushing HTTP requests
*
* The $httpBackend used in production always responds to requests asynchronously. If we preserved
* this behavior in unit testing, we'd have to create async unit tests, which are hard to write,
@@ -1037,7 +1094,7 @@ angular.mock.dump = function(object) {
* the async api of the backend, while allowing the test to execute synchronously.
*
*
- * # Unit testing with mock $httpBackend
+ * ## Unit testing with mock $httpBackend
* The following code shows how to setup and use the mock backend when unit testing a controller.
* First we create the controller under test:
*
@@ -1051,19 +1108,19 @@ angular.mock.dump = function(object) {
function MyController($scope, $http) {
var authToken;
- $http.get('/auth.py').success(function(data, status, headers) {
- authToken = headers('A-Token');
- $scope.user = data;
+ $http.get('/auth.py').then(function(response) {
+ authToken = response.headers('A-Token');
+ $scope.user = response.data;
});
$scope.saveMessage = function(message) {
var headers = { 'Authorization': authToken };
$scope.status = 'Saving...';
- $http.post('/add-msg.py', message, { headers: headers } ).success(function(response) {
+ $http.post('/add-msg.py', message, { headers: headers } ).then(function(response) {
$scope.status = '';
- }).error(function() {
- $scope.status = 'ERROR!';
+ }).catch(function() {
+ $scope.status = 'Failed...';
});
};
}
@@ -1144,7 +1201,7 @@ angular.mock.dump = function(object) {
$httpBackend.flush();
$httpBackend.expectPOST('/add-msg.py', undefined, function(headers) {
- // check if the header was send, if it wasn't the expectation won't
+ // check if the header was sent, if it wasn't the expectation won't
// match the request and the test will fail
return headers['Authorization'] == 'xxx';
}).respond(201, '');
@@ -1153,7 +1210,87 @@ angular.mock.dump = function(object) {
$httpBackend.flush();
});
});
- ```
+ ```
+ *
+ * ## Dynamic responses
+ *
+ * You define a response to a request by chaining a call to `respond()` onto a definition or expectation.
+ * If you provide a **callback** as the first parameter to `respond(callback)` then you can dynamically generate
+ * a response based on the properties of the request.
+ *
+ * The `callback` function should be of the form `function(method, url, data, headers, params)`.
+ *
+ * ### Query parameters
+ *
+ * By default, query parameters on request URLs are parsed into the `params` object. So a request URL
+ * of `/list?q=searchstr&orderby=-name` would set `params` to be `{q: 'searchstr', orderby: '-name'}`.
+ *
+ * ### Regex parameter matching
+ *
+ * If an expectation or definition uses a **regex** to match the URL, you can provide an array of **keys** via a
+ * `params` argument. The index of each **key** in the array will match the index of a **group** in the
+ * **regex**.
+ *
+ * The `params` object in the **callback** will now have properties with these keys, which hold the value of the
+ * corresponding **group** in the **regex**.
+ *
+ * This also applies to the `when` and `expect` shortcut methods.
+ *
+ *
+ * ```js
+ * $httpBackend.expect('GET', /\/user\/(.+)/, undefined, undefined, ['id'])
+ * .respond(function(method, url, data, headers, params) {
+ * // for requested url of '/user/1234' params is {id: '1234'}
+ * });
+ *
+ * $httpBackend.whenPATCH(/\/user\/(.+)\/article\/(.+)/, undefined, undefined, ['user', 'article'])
+ * .respond(function(method, url, data, headers, params) {
+ * // for url of '/user/1234/article/567' params is {user: '1234', article: '567'}
+ * });
+ * ```
+ *
+ * ## Matching route requests
+ *
+ * For extra convenience, `whenRoute` and `expectRoute` shortcuts are available. These methods offer colon
+ * delimited matching of the url path, ignoring the query string. This allows declarations
+ * similar to how application routes are configured with `$routeProvider`. Because these methods convert
+ * the definition url to regex, declaration order is important. Combined with query parameter parsing,
+ * the following is possible:
+ *
+ ```js
+ $httpBackend.whenRoute('GET', '/users/:id')
+ .respond(function(method, url, data, headers, params) {
+ return [200, MockUserList[Number(params.id)]];
+ });
+
+ $httpBackend.whenRoute('GET', '/users')
+ .respond(function(method, url, data, headers, params) {
+ var userList = angular.copy(MockUserList),
+ defaultSort = 'lastName',
+ count, pages, isPrevious, isNext;
+
+ // paged api response '/v1/users?page=2'
+ params.page = Number(params.page) || 1;
+
+ // query for last names '/v1/users?q=Archer'
+ if (params.q) {
+ userList = $filter('filter')({lastName: params.q});
+ }
+
+ pages = Math.ceil(userList.length / pagingLength);
+ isPrevious = params.page > 1;
+ isNext = params.page < pages;
+
+ return [200, {
+ count: userList.length,
+ previous: isPrevious,
+ next: isNext,
+ // sort field -> '/v1/users?sortBy=firstName'
+ results: $filter('orderBy')(userList, params.sortBy || defaultSort)
+ .splice((params.page - 1) * pagingLength, pagingLength)
+ }];
+ });
+ ```
*/
angular.mock.$HttpBackendProvider = function() {
this.$get = ['$rootScope', '$timeout', createHttpBackendMock];
@@ -1210,7 +1347,7 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) {
return handleResponse;
function handleResponse() {
- var response = wrapped.response(method, url, data, headers);
+ var response = wrapped.response(method, url, data, headers, wrapped.params(url));
xhr.$$respHeaders = response[2];
callback(copy(response[0]), copy(response[1]), xhr.getAllResponseHeaders(),
copy(response[3] || ''));
@@ -1228,14 +1365,16 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) {
}
if (expectation && expectation.match(method, url)) {
- if (!expectation.matchData(data))
+ if (!expectation.matchData(data)) {
throw new Error('Expected ' + expectation + ' with different data\n' +
'EXPECTED: ' + prettyPrint(expectation.data) + '\nGOT: ' + data);
+ }
- if (!expectation.matchHeaders(headers))
+ if (!expectation.matchHeaders(headers)) {
throw new Error('Expected ' + expectation + ' with different headers\n' +
'EXPECTED: ' + prettyPrint(expectation.headers) + '\nGOT: ' +
prettyPrint(headers));
+ }
expectations.shift();
@@ -1271,26 +1410,27 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) {
* Creates a new backend definition.
*
* @param {string} method HTTP method.
- * @param {string|RegExp|function(string)} url HTTP url or function that receives the url
- * and returns true if the url match the current definition.
+ * @param {string|RegExp|function(string)} url HTTP url or function that receives a url
+ * and returns true if the url matches the current definition.
* @param {(string|RegExp|function(string))=} data HTTP request body or function that receives
* data string and returns true if the data is as expected.
* @param {(Object|function(Object))=} headers HTTP headers or function that receives http header
* object and returns true if the headers match the current definition.
+ * @param {(Array)=} keys Array of keys to assign to regex matches in request url described above.
* @returns {requestHandler} Returns an object with `respond` method that controls how a matched
* request is handled. You can save this object for later use and invoke `respond` again in
* order to change how a matched request is handled.
*
* - respond –
* `{function([status,] data[, headers, statusText])
- * | function(function(method, url, data, headers)}`
+ * | function(function(method, url, data, headers, params)}`
* – The respond method takes a set of static data to be returned or a function that can
* return an array containing response status (number), response data (string), response
* headers (Object), and the text for the status (string). The respond method returns the
* `requestHandler` object for possible overrides.
*/
- $httpBackend.when = function(method, url, data, headers) {
- var definition = new MockHttpExpectation(method, url, data, headers),
+ $httpBackend.when = function(method, url, data, headers, keys) {
+ var definition = new MockHttpExpectation(method, url, data, headers, keys),
chain = {
respond: function(status, data, headers, statusText) {
definition.passThrough = undefined;
@@ -1317,9 +1457,10 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) {
* @description
* Creates a new backend definition for GET requests. For more info see `when()`.
*
- * @param {string|RegExp|function(string)} url HTTP url or function that receives the url
- * and returns true if the url match the current definition.
+ * @param {string|RegExp|function(string)} url HTTP url or function that receives a url
+ * and returns true if the url matches the current definition.
* @param {(Object|function(Object))=} headers HTTP headers.
+ * @param {(Array)=} keys Array of keys to assign to regex matches in request url described above.
* @returns {requestHandler} Returns an object with `respond` method that controls how a matched
* request is handled. You can save this object for later use and invoke `respond` again in
* order to change how a matched request is handled.
@@ -1331,9 +1472,10 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) {
* @description
* Creates a new backend definition for HEAD requests. For more info see `when()`.
*
- * @param {string|RegExp|function(string)} url HTTP url or function that receives the url
- * and returns true if the url match the current definition.
+ * @param {string|RegExp|function(string)} url HTTP url or function that receives a url
+ * and returns true if the url matches the current definition.
* @param {(Object|function(Object))=} headers HTTP headers.
+ * @param {(Array)=} keys Array of keys to assign to regex matches in request url described above.
* @returns {requestHandler} Returns an object with `respond` method that controls how a matched
* request is handled. You can save this object for later use and invoke `respond` again in
* order to change how a matched request is handled.
@@ -1345,9 +1487,10 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) {
* @description
* Creates a new backend definition for DELETE requests. For more info see `when()`.
*
- * @param {string|RegExp|function(string)} url HTTP url or function that receives the url
- * and returns true if the url match the current definition.
+ * @param {string|RegExp|function(string)} url HTTP url or function that receives a url
+ * and returns true if the url matches the current definition.
* @param {(Object|function(Object))=} headers HTTP headers.
+ * @param {(Array)=} keys Array of keys to assign to regex matches in request url described above.
* @returns {requestHandler} Returns an object with `respond` method that controls how a matched
* request is handled. You can save this object for later use and invoke `respond` again in
* order to change how a matched request is handled.
@@ -1359,11 +1502,12 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) {
* @description
* Creates a new backend definition for POST requests. For more info see `when()`.
*
- * @param {string|RegExp|function(string)} url HTTP url or function that receives the url
- * and returns true if the url match the current definition.
+ * @param {string|RegExp|function(string)} url HTTP url or function that receives a url
+ * and returns true if the url matches the current definition.
* @param {(string|RegExp|function(string))=} data HTTP request body or function that receives
* data string and returns true if the data is as expected.
* @param {(Object|function(Object))=} headers HTTP headers.
+ * @param {(Array)=} keys Array of keys to assign to regex matches in request url described above.
* @returns {requestHandler} Returns an object with `respond` method that controls how a matched
* request is handled. You can save this object for later use and invoke `respond` again in
* order to change how a matched request is handled.
@@ -1375,11 +1519,12 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) {
* @description
* Creates a new backend definition for PUT requests. For more info see `when()`.
*
- * @param {string|RegExp|function(string)} url HTTP url or function that receives the url
- * and returns true if the url match the current definition.
+ * @param {string|RegExp|function(string)} url HTTP url or function that receives a url
+ * and returns true if the url matches the current definition.
* @param {(string|RegExp|function(string))=} data HTTP request body or function that receives
* data string and returns true if the data is as expected.
* @param {(Object|function(Object))=} headers HTTP headers.
+ * @param {(Array)=} keys Array of keys to assign to regex matches in request url described above.
* @returns {requestHandler} Returns an object with `respond` method that controls how a matched
* request is handled. You can save this object for later use and invoke `respond` again in
* order to change how a matched request is handled.
@@ -1391,14 +1536,61 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) {
* @description
* Creates a new backend definition for JSONP requests. For more info see `when()`.
*
- * @param {string|RegExp|function(string)} url HTTP url or function that receives the url
- * and returns true if the url match the current definition.
+ * @param {string|RegExp|function(string)} url HTTP url or function that receives a url
+ * and returns true if the url matches the current definition.
+ * @param {(Array)=} keys Array of keys to assign to regex matches in request url described above.
* @returns {requestHandler} Returns an object with `respond` method that controls how a matched
* request is handled. You can save this object for later use and invoke `respond` again in
* order to change how a matched request is handled.
*/
createShortMethods('when');
+ /**
+ * @ngdoc method
+ * @name $httpBackend#whenRoute
+ * @description
+ * Creates a new backend definition that compares only with the requested route.
+ *
+ * @param {string} method HTTP method.
+ * @param {string} url HTTP url string that supports colon param matching.
+ * @returns {requestHandler} Returns an object with `respond` method that controls how a matched
+ * request is handled. You can save this object for later use and invoke `respond` again in
+ * order to change how a matched request is handled. See #when for more info.
+ */
+ $httpBackend.whenRoute = function(method, url) {
+ var pathObj = parseRoute(url);
+ return $httpBackend.when(method, pathObj.regexp, undefined, undefined, pathObj.keys);
+ };
+
+ function parseRoute(url) {
+ var ret = {
+ regexp: url
+ },
+ keys = ret.keys = [];
+
+ if (!url || !angular.isString(url)) return ret;
+
+ url = url
+ .replace(/([().])/g, '\\$1')
+ .replace(/(\/)?:(\w+)([\?\*])?/g, function(_, slash, key, option) {
+ var optional = option === '?' ? option : null;
+ var star = option === '*' ? option : null;
+ keys.push({ name: key, optional: !!optional });
+ slash = slash || '';
+ return ''
+ + (optional ? '' : slash)
+ + '(?:'
+ + (optional ? slash : '')
+ + (star && '(.+?)' || '([^/]+)')
+ + (optional || '')
+ + ')'
+ + (optional || '');
+ })
+ .replace(/([\/$\*])/g, '\\$1');
+
+ ret.regexp = new RegExp('^' + url, 'i');
+ return ret;
+ }
/**
* @ngdoc method
@@ -1407,27 +1599,28 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) {
* Creates a new request expectation.
*
* @param {string} method HTTP method.
- * @param {string|RegExp|function(string)} url HTTP url or function that receives the url
- * and returns true if the url match the current definition.
+ * @param {string|RegExp|function(string)} url HTTP url or function that receives a url
+ * and returns true if the url matches the current definition.
* @param {(string|RegExp|function(string)|Object)=} data HTTP request body or function that
* receives data string and returns true if the data is as expected, or Object if request body
* is in JSON format.
* @param {(Object|function(Object))=} headers HTTP headers or function that receives http header
* object and returns true if the headers match the current expectation.
+ * @param {(Array)=} keys Array of keys to assign to regex matches in request url described above.
* @returns {requestHandler} Returns an object with `respond` method that controls how a matched
* request is handled. You can save this object for later use and invoke `respond` again in
* order to change how a matched request is handled.
*
* - respond –
* `{function([status,] data[, headers, statusText])
- * | function(function(method, url, data, headers)}`
+ * | function(function(method, url, data, headers, params)}`
* – The respond method takes a set of static data to be returned or a function that can
* return an array containing response status (number), response data (string), response
* headers (Object), and the text for the status (string). The respond method returns the
* `requestHandler` object for possible overrides.
*/
- $httpBackend.expect = function(method, url, data, headers) {
- var expectation = new MockHttpExpectation(method, url, data, headers),
+ $httpBackend.expect = function(method, url, data, headers, keys) {
+ var expectation = new MockHttpExpectation(method, url, data, headers, keys),
chain = {
respond: function(status, data, headers, statusText) {
expectation.response = createResponse(status, data, headers, statusText);
@@ -1439,16 +1632,16 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) {
return chain;
};
-
/**
* @ngdoc method
* @name $httpBackend#expectGET
* @description
* Creates a new request expectation for GET requests. For more info see `expect()`.
*
- * @param {string|RegExp|function(string)} url HTTP url or function that receives the url
- * and returns true if the url match the current definition.
+ * @param {string|RegExp|function(string)} url HTTP url or function that receives a url
+ * and returns true if the url matches the current definition.
* @param {Object=} headers HTTP headers.
+ * @param {(Array)=} keys Array of keys to assign to regex matches in request url described above.
* @returns {requestHandler} Returns an object with `respond` method that controls how a matched
* request is handled. You can save this object for later use and invoke `respond` again in
* order to change how a matched request is handled. See #expect for more info.
@@ -1460,9 +1653,10 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) {
* @description
* Creates a new request expectation for HEAD requests. For more info see `expect()`.
*
- * @param {string|RegExp|function(string)} url HTTP url or function that receives the url
- * and returns true if the url match the current definition.
+ * @param {string|RegExp|function(string)} url HTTP url or function that receives a url
+ * and returns true if the url matches the current definition.
* @param {Object=} headers HTTP headers.
+ * @param {(Array)=} keys Array of keys to assign to regex matches in request url described above.
* @returns {requestHandler} Returns an object with `respond` method that controls how a matched
* request is handled. You can save this object for later use and invoke `respond` again in
* order to change how a matched request is handled.
@@ -1474,9 +1668,10 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) {
* @description
* Creates a new request expectation for DELETE requests. For more info see `expect()`.
*
- * @param {string|RegExp|function(string)} url HTTP url or function that receives the url
- * and returns true if the url match the current definition.
+ * @param {string|RegExp|function(string)} url HTTP url or function that receives a url
+ * and returns true if the url matches the current definition.
* @param {Object=} headers HTTP headers.
+ * @param {(Array)=} keys Array of keys to assign to regex matches in request url described above.
* @returns {requestHandler} Returns an object with `respond` method that controls how a matched
* request is handled. You can save this object for later use and invoke `respond` again in
* order to change how a matched request is handled.
@@ -1488,12 +1683,13 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) {
* @description
* Creates a new request expectation for POST requests. For more info see `expect()`.
*
- * @param {string|RegExp|function(string)} url HTTP url or function that receives the url
- * and returns true if the url match the current definition.
+ * @param {string|RegExp|function(string)} url HTTP url or function that receives a url
+ * and returns true if the url matches the current definition.
* @param {(string|RegExp|function(string)|Object)=} data HTTP request body or function that
* receives data string and returns true if the data is as expected, or Object if request body
* is in JSON format.
* @param {Object=} headers HTTP headers.
+ * @param {(Array)=} keys Array of keys to assign to regex matches in request url described above.
* @returns {requestHandler} Returns an object with `respond` method that controls how a matched
* request is handled. You can save this object for later use and invoke `respond` again in
* order to change how a matched request is handled.
@@ -1505,12 +1701,13 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) {
* @description
* Creates a new request expectation for PUT requests. For more info see `expect()`.</