Skip to content
This repository was archived by the owner on Feb 26, 2024. It is now read-only.

Commit f0affeb

Browse files
v1.7.4
1 parent ce9e948 commit f0affeb

File tree

3 files changed

+119
-99
lines changed

3 files changed

+119
-99
lines changed

angular-mocks.js

Lines changed: 116 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* @license AngularJS v1.7.3
2+
* @license AngularJS v1.7.4
33
* (c) 2010-2018 Google, Inc. http://angularjs.org
44
* License: MIT
55
*/
@@ -10,15 +10,16 @@
1010
/* global routeToRegExp: true */
1111

1212
/**
13-
* @param path {string} path
14-
* @param opts {Object} options
15-
* @return {?Object}
13+
* @param {string} path - The path to parse. (It is assumed to have query and hash stripped off.)
14+
* @param {Object} opts - Options.
15+
* @return {Object} - An object containing an array of path parameter names (`keys`) and a regular
16+
* expression (`regexp`) that can be used to identify a matching URL and extract the path
17+
* parameter values.
1618
*
1719
* @description
18-
* Normalizes the given path, returning a regular expression
19-
* and the original path.
20+
* Parses the given path, extracting path parameter names and a regular expression to match URLs.
2021
*
21-
* Inspired by pathRexp in visionmedia/express/lib/utils.js.
22+
* Originally inspired by `pathRexp` in `visionmedia/express/lib/utils.js`.
2223
*/
2324
function routeToRegExp(path, opts) {
2425
var keys = [];
@@ -28,11 +29,11 @@ function routeToRegExp(path, opts) {
2829
.replace(/(\/)?:(\w+)(\*\?|[?*])?/g, function(_, slash, key, option) {
2930
var optional = option === '?' || option === '*?';
3031
var star = option === '*' || option === '*?';
31-
keys.push({ name: key, optional: optional });
32+
keys.push({name: key, optional: optional});
3233
slash = slash || '';
3334
return (
3435
(optional ? '(?:' + slash : slash + '(?:') +
35-
(star ? '([^?#]+?)' : '([^/?#]+)') +
36+
(star ? '(.+?)' : '([^/]+)') +
3637
(optional ? '?)?' : ')')
3738
);
3839
})
@@ -43,7 +44,6 @@ function routeToRegExp(path, opts) {
4344
}
4445

4546
return {
46-
originalPath: path,
4747
keys: keys,
4848
regexp: new RegExp(
4949
'^' + pattern + '(?:[?#]|$)',
@@ -951,7 +951,7 @@ angular.mock.TzDate.prototype = Date.prototype;
951951
* You need to require the `ngAnimateMock` module in your test suite for instance `beforeEach(module('ngAnimateMock'))`
952952
*/
953953
angular.mock.animate = angular.module('ngAnimateMock', ['ng'])
954-
.info({ angularVersion: '1.7.3' })
954+
.info({ angularVersion: '1.7.4' })
955955

956956
.config(['$provide', function($provide) {
957957

@@ -1825,8 +1825,8 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) {
18251825
* See {@link ngMock.$httpBackend#when `when`} for more info.
18261826
*/
18271827
$httpBackend.whenRoute = function(method, url) {
1828-
var pathObj = routeToRegExp(url, {caseInsensitiveMatch: true, ignoreTrailingSlashes: true});
1829-
return $httpBackend.when(method, pathObj.regexp, undefined, undefined, pathObj.keys);
1828+
var parsed = parseRouteUrl(url);
1829+
return $httpBackend.when(method, parsed.regexp, undefined, undefined, parsed.keys);
18301830
};
18311831

18321832
/**
@@ -2009,8 +2009,8 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) {
20092009
* See {@link ngMock.$httpBackend#expect `expect`} for more info.
20102010
*/
20112011
$httpBackend.expectRoute = function(method, url) {
2012-
var pathObj = routeToRegExp(url, {caseInsensitiveMatch: true, ignoreTrailingSlashes: true});
2013-
return $httpBackend.expect(method, pathObj.regexp, undefined, undefined, pathObj.keys);
2012+
var parsed = parseRouteUrl(url);
2013+
return $httpBackend.expect(method, parsed.regexp, undefined, undefined, parsed.keys);
20142014
};
20152015

20162016

@@ -2138,6 +2138,12 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) {
21382138
};
21392139
});
21402140
}
2141+
2142+
function parseRouteUrl(url) {
2143+
var strippedUrl = stripQueryAndHash(url);
2144+
var parseOptions = {caseInsensitiveMatch: true, ignoreTrailingSlashes: true};
2145+
return routeToRegExp(strippedUrl, parseOptions);
2146+
}
21412147
}
21422148

21432149
function assertArgDefined(args, index, name) {
@@ -2146,110 +2152,124 @@ function assertArgDefined(args, index, name) {
21462152
}
21472153
}
21482154

2155+
function stripQueryAndHash(url) {
2156+
return url.replace(/[?#].*$/, '');
2157+
}
21492158

2150-
function MockHttpExpectation(method, url, data, headers, keys) {
2151-
2152-
function getUrlParams(u) {
2153-
var params = u.slice(u.indexOf('?') + 1).split('&');
2154-
return params.sort();
2155-
}
2156-
2157-
function compareUrl(u) {
2158-
return (url.slice(0, url.indexOf('?')) === u.slice(0, u.indexOf('?')) &&
2159-
getUrlParams(url).join() === getUrlParams(u).join());
2160-
}
2159+
function MockHttpExpectation(expectedMethod, expectedUrl, expectedData, expectedHeaders,
2160+
expectedKeys) {
21612161

2162-
this.data = data;
2163-
this.headers = headers;
2162+
this.data = expectedData;
2163+
this.headers = expectedHeaders;
21642164

2165-
this.match = function(m, u, d, h) {
2166-
if (method !== m) return false;
2167-
if (!this.matchUrl(u)) return false;
2168-
if (angular.isDefined(d) && !this.matchData(d)) return false;
2169-
if (angular.isDefined(h) && !this.matchHeaders(h)) return false;
2165+
this.match = function(method, url, data, headers) {
2166+
if (expectedMethod !== method) return false;
2167+
if (!this.matchUrl(url)) return false;
2168+
if (angular.isDefined(data) && !this.matchData(data)) return false;
2169+
if (angular.isDefined(headers) && !this.matchHeaders(headers)) return false;
21702170
return true;
21712171
};
21722172

2173-
this.matchUrl = function(u) {
2174-
if (!url) return true;
2175-
if (angular.isFunction(url.test)) return url.test(u);
2176-
if (angular.isFunction(url)) return url(u);
2177-
return (url === u || compareUrl(u));
2173+
this.matchUrl = function(url) {
2174+
if (!expectedUrl) return true;
2175+
if (angular.isFunction(expectedUrl.test)) return expectedUrl.test(url);
2176+
if (angular.isFunction(expectedUrl)) return expectedUrl(url);
2177+
return (expectedUrl === url || compareUrlWithQuery(url));
21782178
};
21792179

2180-
this.matchHeaders = function(h) {
2181-
if (angular.isUndefined(headers)) return true;
2182-
if (angular.isFunction(headers)) return headers(h);
2183-
return angular.equals(headers, h);
2180+
this.matchHeaders = function(headers) {
2181+
if (angular.isUndefined(expectedHeaders)) return true;
2182+
if (angular.isFunction(expectedHeaders)) return expectedHeaders(headers);
2183+
return angular.equals(expectedHeaders, headers);
21842184
};
21852185

2186-
this.matchData = function(d) {
2187-
if (angular.isUndefined(data)) return true;
2188-
if (data && angular.isFunction(data.test)) return data.test(d);
2189-
if (data && angular.isFunction(data)) return data(d);
2190-
if (data && !angular.isString(data)) {
2191-
return angular.equals(angular.fromJson(angular.toJson(data)), angular.fromJson(d));
2186+
this.matchData = function(data) {
2187+
if (angular.isUndefined(expectedData)) return true;
2188+
if (expectedData && angular.isFunction(expectedData.test)) return expectedData.test(data);
2189+
if (expectedData && angular.isFunction(expectedData)) return expectedData(data);
2190+
if (expectedData && !angular.isString(expectedData)) {
2191+
return angular.equals(angular.fromJson(angular.toJson(expectedData)), angular.fromJson(data));
21922192
}
21932193
// eslint-disable-next-line eqeqeq
2194-
return data == d;
2194+
return expectedData == data;
21952195
};
21962196

21972197
this.toString = function() {
2198-
return method + ' ' + url;
2198+
return expectedMethod + ' ' + expectedUrl;
21992199
};
22002200

2201-
this.params = function(u) {
2202-
return angular.extend(parseQuery(), pathParams());
2201+
this.params = function(url) {
2202+
var queryStr = url.indexOf('?') === -1 ? '' : url.substring(url.indexOf('?') + 1);
2203+
var strippedUrl = stripQueryAndHash(url);
22032204

2204-
function pathParams() {
2205-
var keyObj = {};
2206-
if (!url || !angular.isFunction(url.test) || !keys || keys.length === 0) return keyObj;
2205+
return angular.extend(extractParamsFromQuery(queryStr), extractParamsFromPath(strippedUrl));
2206+
};
22072207

2208-
var m = url.exec(u);
2209-
if (!m) return keyObj;
2210-
for (var i = 1, len = m.length; i < len; ++i) {
2211-
var key = keys[i - 1];
2212-
var val = m[i];
2213-
if (key && val) {
2214-
keyObj[key.name || key] = val;
2215-
}
2216-
}
2208+
function compareUrlWithQuery(url) {
2209+
var urlWithQueryRe = /^([^?]*)\?(.*)$/;
2210+
2211+
var expectedMatch = urlWithQueryRe.exec(expectedUrl);
2212+
var actualMatch = urlWithQueryRe.exec(url);
2213+
2214+
return !!(expectedMatch && actualMatch) &&
2215+
(expectedMatch[1] === actualMatch[1]) &&
2216+
(normalizeQuery(expectedMatch[2]) === normalizeQuery(actualMatch[2]));
2217+
}
2218+
2219+
function normalizeQuery(queryStr) {
2220+
return queryStr.split('&').sort().join('&');
2221+
}
2222+
2223+
function extractParamsFromPath(strippedUrl) {
2224+
var keyObj = {};
2225+
2226+
if (!expectedUrl || !angular.isFunction(expectedUrl.test) ||
2227+
!expectedKeys || !expectedKeys.length) return keyObj;
2228+
2229+
var match = expectedUrl.exec(strippedUrl);
2230+
if (!match) return keyObj;
22172231

2218-
return keyObj;
2232+
for (var i = 1, len = match.length; i < len; ++i) {
2233+
var key = expectedKeys[i - 1];
2234+
var val = match[i];
2235+
if (key && val) {
2236+
keyObj[key.name || key] = val;
2237+
}
22192238
}
22202239

2221-
function parseQuery() {
2222-
var obj = {}, key_value, key,
2223-
queryStr = u.indexOf('?') > -1
2224-
? u.substring(u.indexOf('?') + 1)
2225-
: '';
2226-
2227-
angular.forEach(queryStr.split('&'), function(keyValue) {
2228-
if (keyValue) {
2229-
key_value = keyValue.replace(/\+/g,'%20').split('=');
2230-
key = tryDecodeURIComponent(key_value[0]);
2231-
if (angular.isDefined(key)) {
2232-
var val = angular.isDefined(key_value[1]) ? tryDecodeURIComponent(key_value[1]) : true;
2233-
if (!hasOwnProperty.call(obj, key)) {
2234-
obj[key] = val;
2235-
} else if (angular.isArray(obj[key])) {
2236-
obj[key].push(val);
2237-
} else {
2238-
obj[key] = [obj[key],val];
2239-
}
2240-
}
2240+
return keyObj;
2241+
}
2242+
2243+
function extractParamsFromQuery(queryStr) {
2244+
var obj = {},
2245+
keyValuePairs = queryStr.split('&').
2246+
filter(angular.identity). // Ignore empty segments.
2247+
map(function(keyValue) { return keyValue.replace(/\+/g, '%20').split('='); });
2248+
2249+
angular.forEach(keyValuePairs, function(pair) {
2250+
var key = tryDecodeURIComponent(pair[0]);
2251+
if (angular.isDefined(key)) {
2252+
var val = angular.isDefined(pair[1]) ? tryDecodeURIComponent(pair[1]) : true;
2253+
if (!hasOwnProperty.call(obj, key)) {
2254+
obj[key] = val;
2255+
} else if (angular.isArray(obj[key])) {
2256+
obj[key].push(val);
2257+
} else {
2258+
obj[key] = [obj[key], val];
22412259
}
2242-
});
2243-
return obj;
2244-
}
2245-
function tryDecodeURIComponent(value) {
2246-
try {
2247-
return decodeURIComponent(value);
2248-
} catch (e) {
2249-
// Ignore any invalid uri component
22502260
}
2261+
});
2262+
2263+
return obj;
2264+
}
2265+
2266+
function tryDecodeURIComponent(value) {
2267+
try {
2268+
return decodeURIComponent(value);
2269+
} catch (e) {
2270+
// Ignore any invalid uri component
22512271
}
2252-
};
2272+
}
22532273
}
22542274

22552275
function createMockXhr() {
@@ -2649,7 +2669,7 @@ angular.module('ngMock', ['ng']).provider({
26492669
$provide.decorator('$rootScope', angular.mock.$RootScopeDecorator);
26502670
$provide.decorator('$controller', createControllerDecorator($compileProvider));
26512671
$provide.decorator('$httpBackend', angular.mock.$httpBackendDecorator);
2652-
}]).info({ angularVersion: '1.7.3' });
2672+
}]).info({ angularVersion: '1.7.4' });
26532673

26542674
/**
26552675
* @ngdoc module
@@ -2664,7 +2684,7 @@ angular.module('ngMock', ['ng']).provider({
26642684
*/
26652685
angular.module('ngMockE2E', ['ng']).config(['$provide', function($provide) {
26662686
$provide.decorator('$httpBackend', angular.mock.e2e.$httpBackendDecorator);
2667-
}]).info({ angularVersion: '1.7.3' });
2687+
}]).info({ angularVersion: '1.7.4' });
26682688

26692689
/**
26702690
* @ngdoc service

bower.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
{
22
"name": "angular-mocks",
3-
"version": "1.7.3",
3+
"version": "1.7.4",
44
"license": "MIT",
55
"main": "./angular-mocks.js",
66
"ignore": [],
77
"dependencies": {
8-
"angular": "1.7.3"
8+
"angular": "1.7.4"
99
}
1010
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "angular-mocks",
3-
"version": "1.7.3",
3+
"version": "1.7.4",
44
"description": "AngularJS mocks for testing",
55
"main": "angular-mocks.js",
66
"scripts": {

0 commit comments

Comments
 (0)