angularjs-rails-resource 1.0.0.pre.4 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bower.json +1 -1
- data/lib/angularjs-rails-resource/version.rb +1 -1
- data/package.json +1 -1
- data/test/lib/angular/angular-cookies.js +24 -6
- data/test/lib/angular/angular-loader.js +138 -32
- data/test/lib/angular/angular-mocks.js +666 -396
- data/test/lib/angular/angular-route.js +911 -0
- data/test/lib/angular/angular-sanitize.js +212 -148
- data/test/lib/angular/angular-scenario.js +17060 -12378
- data/test/lib/angular/angular.js +10869 -6644
- metadata +6 -14
- data/test/lib/angular/angular-bootstrap-prettify.js +0 -1838
- data/test/lib/angular/angular-bootstrap.js +0 -167
- data/test/lib/angular/angular-locale_en-us.js +0 -4
- data/test/lib/angular/angular-mobile.js +0 -267
- data/test/lib/angular/angular-resource.js +0 -521
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f3bf9757cba16ef593b4a0b823c29d61f47910d5
|
4
|
+
data.tar.gz: 62a2d930c231b2e6a54dbeb718dca18eb4c2ff9c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 610c9c4762c53128e74996a87d27c83d59ce9a186d093f614092673d084c9cf441e5cb6107a08e8599b5ae384f900e577c8c9c3ee9d39b714f75f6d2524e055e
|
7
|
+
data.tar.gz: 59ca8304a0d22e07a7fc00bbf1552fdb28d6da859207dc74276762838441b1f43ef97cc3e3e53777dc2d842d7b22652c673d685e615325527241dcdbd05b1914
|
data/bower.json
CHANGED
data/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "angularjs-rails-resource",
|
3
3
|
"description" : "A resource factory inspired by $resource from AngularJS",
|
4
|
-
"version": "1.0.0
|
4
|
+
"version": "1.0.0",
|
5
5
|
"main" : "dist/angularjs-rails-resource.min.js",
|
6
6
|
"homepage" : "https://github.com/FineLinePrototyping/angularjs-rails-resource.git",
|
7
7
|
"author" : "",
|
@@ -1,14 +1,25 @@
|
|
1
1
|
/**
|
2
|
-
* @license AngularJS v1.
|
3
|
-
* (c) 2010-
|
2
|
+
* @license AngularJS v1.2.6
|
3
|
+
* (c) 2010-2014 Google, Inc. http://angularjs.org
|
4
4
|
* License: MIT
|
5
5
|
*/
|
6
|
-
(function(window, angular, undefined) {
|
7
|
-
'use strict';
|
6
|
+
(function(window, angular, undefined) {'use strict';
|
8
7
|
|
9
8
|
/**
|
10
9
|
* @ngdoc overview
|
11
10
|
* @name ngCookies
|
11
|
+
* @description
|
12
|
+
*
|
13
|
+
* # ngCookies
|
14
|
+
*
|
15
|
+
* The `ngCookies` module provides a convenient wrapper for reading and writing browser cookies.
|
16
|
+
*
|
17
|
+
* {@installModule cookies}
|
18
|
+
*
|
19
|
+
* <div doc-module-components="ngCookies"></div>
|
20
|
+
*
|
21
|
+
* See {@link ngCookies.$cookies `$cookies`} and
|
22
|
+
* {@link ngCookies.$cookieStore `$cookieStore`} for usage.
|
12
23
|
*/
|
13
24
|
|
14
25
|
|
@@ -24,6 +35,8 @@ angular.module('ngCookies', ['ng']).
|
|
24
35
|
* Only a simple Object is exposed and by adding or removing properties to/from
|
25
36
|
* this object, new cookies are created/deleted at the end of current $eval.
|
26
37
|
*
|
38
|
+
* Requires the {@link ngCookies `ngCookies`} module to be installed.
|
39
|
+
*
|
27
40
|
* @example
|
28
41
|
<doc:example>
|
29
42
|
<doc:source>
|
@@ -68,7 +81,8 @@ angular.module('ngCookies', ['ng']).
|
|
68
81
|
|
69
82
|
|
70
83
|
/**
|
71
|
-
* Pushes all the cookies from the service to the browser and verifies if all cookies were
|
84
|
+
* Pushes all the cookies from the service to the browser and verifies if all cookies were
|
85
|
+
* stored.
|
72
86
|
*/
|
73
87
|
function push() {
|
74
88
|
var name,
|
@@ -128,6 +142,9 @@ angular.module('ngCookies', ['ng']).
|
|
128
142
|
* Provides a key-value (string-object) storage, that is backed by session cookies.
|
129
143
|
* Objects put or retrieved from this storage are automatically serialized or
|
130
144
|
* deserialized by angular's toJson/fromJson.
|
145
|
+
*
|
146
|
+
* Requires the {@link ngCookies `ngCookies`} module to be installed.
|
147
|
+
*
|
131
148
|
* @example
|
132
149
|
*/
|
133
150
|
factory('$cookieStore', ['$cookies', function($cookies) {
|
@@ -145,7 +162,8 @@ angular.module('ngCookies', ['ng']).
|
|
145
162
|
* @returns {Object} Deserialized cookie value.
|
146
163
|
*/
|
147
164
|
get: function(key) {
|
148
|
-
|
165
|
+
var value = $cookies[key];
|
166
|
+
return value ? angular.fromJson(value) : value;
|
149
167
|
},
|
150
168
|
|
151
169
|
/**
|
@@ -1,10 +1,84 @@
|
|
1
1
|
/**
|
2
|
-
* @license AngularJS v1.
|
3
|
-
* (c) 2010-
|
2
|
+
* @license AngularJS v1.2.6
|
3
|
+
* (c) 2010-2014 Google, Inc. http://angularjs.org
|
4
4
|
* License: MIT
|
5
5
|
*/
|
6
6
|
|
7
|
-
(
|
7
|
+
(function() {'use strict';
|
8
|
+
|
9
|
+
/**
|
10
|
+
* @description
|
11
|
+
*
|
12
|
+
* This object provides a utility for producing rich Error messages within
|
13
|
+
* Angular. It can be called as follows:
|
14
|
+
*
|
15
|
+
* var exampleMinErr = minErr('example');
|
16
|
+
* throw exampleMinErr('one', 'This {0} is {1}', foo, bar);
|
17
|
+
*
|
18
|
+
* The above creates an instance of minErr in the example namespace. The
|
19
|
+
* resulting error will have a namespaced error code of example.one. The
|
20
|
+
* resulting error will replace {0} with the value of foo, and {1} with the
|
21
|
+
* value of bar. The object is not restricted in the number of arguments it can
|
22
|
+
* take.
|
23
|
+
*
|
24
|
+
* If fewer arguments are specified than necessary for interpolation, the extra
|
25
|
+
* interpolation markers will be preserved in the final string.
|
26
|
+
*
|
27
|
+
* Since data will be parsed statically during a build step, some restrictions
|
28
|
+
* are applied with respect to how minErr instances are created and called.
|
29
|
+
* Instances should have names of the form namespaceMinErr for a minErr created
|
30
|
+
* using minErr('namespace') . Error codes, namespaces and template strings
|
31
|
+
* should all be static strings, not variables or general expressions.
|
32
|
+
*
|
33
|
+
* @param {string} module The namespace to use for the new minErr instance.
|
34
|
+
* @returns {function(string, string, ...): Error} instance
|
35
|
+
*/
|
36
|
+
|
37
|
+
function minErr(module) {
|
38
|
+
return function () {
|
39
|
+
var code = arguments[0],
|
40
|
+
prefix = '[' + (module ? module + ':' : '') + code + '] ',
|
41
|
+
template = arguments[1],
|
42
|
+
templateArgs = arguments,
|
43
|
+
stringify = function (obj) {
|
44
|
+
if (typeof obj === 'function') {
|
45
|
+
return obj.toString().replace(/ \{[\s\S]*$/, '');
|
46
|
+
} else if (typeof obj === 'undefined') {
|
47
|
+
return 'undefined';
|
48
|
+
} else if (typeof obj !== 'string') {
|
49
|
+
return JSON.stringify(obj);
|
50
|
+
}
|
51
|
+
return obj;
|
52
|
+
},
|
53
|
+
message, i;
|
54
|
+
|
55
|
+
message = prefix + template.replace(/\{\d+\}/g, function (match) {
|
56
|
+
var index = +match.slice(1, -1), arg;
|
57
|
+
|
58
|
+
if (index + 2 < templateArgs.length) {
|
59
|
+
arg = templateArgs[index + 2];
|
60
|
+
if (typeof arg === 'function') {
|
61
|
+
return arg.toString().replace(/ ?\{[\s\S]*$/, '');
|
62
|
+
} else if (typeof arg === 'undefined') {
|
63
|
+
return 'undefined';
|
64
|
+
} else if (typeof arg !== 'string') {
|
65
|
+
return toJson(arg);
|
66
|
+
}
|
67
|
+
return arg;
|
68
|
+
}
|
69
|
+
return match;
|
70
|
+
});
|
71
|
+
|
72
|
+
message = message + '\nhttp://errors.angularjs.org/1.2.6/' +
|
73
|
+
(module ? module + '/' : '') + code;
|
74
|
+
for (i = 2; i < arguments.length; i++) {
|
75
|
+
message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' +
|
76
|
+
encodeURIComponent(stringify(arguments[i]));
|
77
|
+
}
|
78
|
+
|
79
|
+
return new Error(message);
|
80
|
+
};
|
81
|
+
}
|
8
82
|
|
9
83
|
/**
|
10
84
|
* @ngdoc interface
|
@@ -16,11 +90,19 @@
|
|
16
90
|
|
17
91
|
function setupModuleLoader(window) {
|
18
92
|
|
93
|
+
var $injectorMinErr = minErr('$injector');
|
94
|
+
var ngMinErr = minErr('ng');
|
95
|
+
|
19
96
|
function ensure(obj, name, factory) {
|
20
97
|
return obj[name] || (obj[name] = factory());
|
21
98
|
}
|
22
99
|
|
23
|
-
|
100
|
+
var angular = ensure(window, 'angular', Object);
|
101
|
+
|
102
|
+
// We need to expose `angular.$$minErr` to modules such as `ngResource` that reference it during bootstrap
|
103
|
+
angular.$$minErr = angular.$$minErr || minErr;
|
104
|
+
|
105
|
+
return ensure(angular, 'module', function() {
|
24
106
|
/** @type {Object.<string, angular.Module>} */
|
25
107
|
var modules = {};
|
26
108
|
|
@@ -29,15 +111,19 @@ function setupModuleLoader(window) {
|
|
29
111
|
* @name angular.module
|
30
112
|
* @description
|
31
113
|
*
|
32
|
-
* The `angular.module` is a global place for creating and
|
33
|
-
* modules
|
114
|
+
* The `angular.module` is a global place for creating, registering and retrieving Angular
|
115
|
+
* modules.
|
116
|
+
* All modules (angular core or 3rd party) that should be available to an application must be
|
34
117
|
* registered using this mechanism.
|
35
118
|
*
|
119
|
+
* When passed two or more arguments, a new module is created. If passed only one argument, an
|
120
|
+
* existing module (the name passed as the first argument to `module`) is retrieved.
|
121
|
+
*
|
36
122
|
*
|
37
123
|
* # Module
|
38
124
|
*
|
39
|
-
* A module is a
|
40
|
-
* is used to configure the {@link AUTO.$injector $injector}.
|
125
|
+
* A module is a collection of services, directives, filters, and configuration information.
|
126
|
+
* `angular.module` is used to configure the {@link AUTO.$injector $injector}.
|
41
127
|
*
|
42
128
|
* <pre>
|
43
129
|
* // Create a new module
|
@@ -48,7 +134,6 @@ function setupModuleLoader(window) {
|
|
48
134
|
*
|
49
135
|
* // configure existing services inside initialization blocks.
|
50
136
|
* myModule.config(function($locationProvider) {
|
51
|
-
'use strict';
|
52
137
|
* // Configure existing providers
|
53
138
|
* $locationProvider.hashPrefix('!');
|
54
139
|
* });
|
@@ -65,19 +150,28 @@ function setupModuleLoader(window) {
|
|
65
150
|
* {@link angular.bootstrap} to simplify this process for you.
|
66
151
|
*
|
67
152
|
* @param {!string} name The name of the module to create or retrieve.
|
68
|
-
* @param {Array.<string>=} requires If specified then new module is being created. If
|
69
|
-
* the module is being retrieved for further configuration.
|
153
|
+
* @param {Array.<string>=} requires If specified then new module is being created. If
|
154
|
+
* unspecified then the the module is being retrieved for further configuration.
|
70
155
|
* @param {Function} configFn Optional configuration function for the module. Same as
|
71
|
-
* {@link angular.Module#
|
156
|
+
* {@link angular.Module#methods_config Module#config()}.
|
72
157
|
* @returns {module} new module with the {@link angular.Module} api.
|
73
158
|
*/
|
74
159
|
return function module(name, requires, configFn) {
|
160
|
+
var assertNotHasOwnProperty = function(name, context) {
|
161
|
+
if (name === 'hasOwnProperty') {
|
162
|
+
throw ngMinErr('badname', 'hasOwnProperty is not a valid {0} name', context);
|
163
|
+
}
|
164
|
+
};
|
165
|
+
|
166
|
+
assertNotHasOwnProperty(name, 'module');
|
75
167
|
if (requires && modules.hasOwnProperty(name)) {
|
76
168
|
modules[name] = null;
|
77
169
|
}
|
78
170
|
return ensure(modules, name, function() {
|
79
171
|
if (!requires) {
|
80
|
-
throw
|
172
|
+
throw $injectorMinErr('nomod', "Module '{0}' is not available! You either misspelled " +
|
173
|
+
"the module name or forgot to load it. If registering a module ensure that you " +
|
174
|
+
"specify the dependencies as the second argument.", name);
|
81
175
|
}
|
82
176
|
|
83
177
|
/** @type {!Array.<Array.<*>>} */
|
@@ -100,7 +194,8 @@ function setupModuleLoader(window) {
|
|
100
194
|
* @propertyOf angular.Module
|
101
195
|
* @returns {Array.<string>} List of module names which must be loaded before this module.
|
102
196
|
* @description
|
103
|
-
* Holds the list of modules which the injector will load before the current module is
|
197
|
+
* Holds the list of modules which the injector will load before the current module is
|
198
|
+
* loaded.
|
104
199
|
*/
|
105
200
|
requires: requires,
|
106
201
|
|
@@ -119,7 +214,8 @@ function setupModuleLoader(window) {
|
|
119
214
|
* @name angular.Module#provider
|
120
215
|
* @methodOf angular.Module
|
121
216
|
* @param {string} name service name
|
122
|
-
* @param {Function} providerType Construction function for creating new instance of the
|
217
|
+
* @param {Function} providerType Construction function for creating new instance of the
|
218
|
+
* service.
|
123
219
|
* @description
|
124
220
|
* See {@link AUTO.$provide#provider $provide.provider()}.
|
125
221
|
*/
|
@@ -175,27 +271,34 @@ function setupModuleLoader(window) {
|
|
175
271
|
* @name angular.Module#animation
|
176
272
|
* @methodOf angular.Module
|
177
273
|
* @param {string} name animation name
|
178
|
-
* @param {Function} animationFactory Factory function for creating new instance of an
|
274
|
+
* @param {Function} animationFactory Factory function for creating new instance of an
|
275
|
+
* animation.
|
179
276
|
* @description
|
180
277
|
*
|
181
|
-
*
|
182
|
-
*
|
278
|
+
* **NOTE**: animations take effect only if the **ngAnimate** module is loaded.
|
279
|
+
*
|
280
|
+
*
|
281
|
+
* Defines an animation hook that can be later used with
|
282
|
+
* {@link ngAnimate.$animate $animate} service and directives that use this service.
|
283
|
+
*
|
183
284
|
* <pre>
|
184
|
-
* module.animation('animation-name', function($inject1, $inject2) {
|
285
|
+
* module.animation('.animation-name', function($inject1, $inject2) {
|
185
286
|
* return {
|
186
|
-
*
|
187
|
-
*
|
188
|
-
*
|
189
|
-
*
|
190
|
-
*
|
287
|
+
* eventName : function(element, done) {
|
288
|
+
* //code to run the animation
|
289
|
+
* //once complete, then run done()
|
290
|
+
* return function cancellationFunction(element) {
|
291
|
+
* //code to cancel the animation
|
292
|
+
* }
|
293
|
+
* }
|
191
294
|
* }
|
192
295
|
* })
|
193
296
|
* </pre>
|
194
297
|
*
|
195
|
-
* See {@link
|
196
|
-
* {@link
|
298
|
+
* See {@link ngAnimate.$animateProvider#register $animateProvider.register()} and
|
299
|
+
* {@link ngAnimate ngAnimate module} for more information.
|
197
300
|
*/
|
198
|
-
animation: invokeLater('$
|
301
|
+
animation: invokeLater('$animateProvider', 'register'),
|
199
302
|
|
200
303
|
/**
|
201
304
|
* @ngdoc method
|
@@ -212,7 +315,8 @@ function setupModuleLoader(window) {
|
|
212
315
|
* @ngdoc method
|
213
316
|
* @name angular.Module#controller
|
214
317
|
* @methodOf angular.Module
|
215
|
-
* @param {string} name Controller name
|
318
|
+
* @param {string|Object} name Controller name, or an object map of controllers where the
|
319
|
+
* keys are the names and the values are the constructors.
|
216
320
|
* @param {Function} constructor Controller constructor function.
|
217
321
|
* @description
|
218
322
|
* See {@link ng.$controllerProvider#register $controllerProvider.register()}.
|
@@ -223,11 +327,12 @@ function setupModuleLoader(window) {
|
|
223
327
|
* @ngdoc method
|
224
328
|
* @name angular.Module#directive
|
225
329
|
* @methodOf angular.Module
|
226
|
-
* @param {string} name
|
330
|
+
* @param {string|Object} name Directive name, or an object map of directives where the
|
331
|
+
* keys are the names and the values are the factories.
|
227
332
|
* @param {Function} directiveFactory Factory function for creating new instance of
|
228
333
|
* directives.
|
229
334
|
* @description
|
230
|
-
* See {@link ng.$compileProvider#
|
335
|
+
* See {@link ng.$compileProvider#methods_directive $compileProvider.directive()}.
|
231
336
|
*/
|
232
337
|
directive: invokeLater('$compileProvider', 'directive'),
|
233
338
|
|
@@ -274,7 +379,7 @@ function setupModuleLoader(window) {
|
|
274
379
|
return function() {
|
275
380
|
invokeQueue[insertMethod || 'push']([provider, method, arguments]);
|
276
381
|
return moduleInstance;
|
277
|
-
}
|
382
|
+
};
|
278
383
|
}
|
279
384
|
});
|
280
385
|
};
|
@@ -282,7 +387,8 @@ function setupModuleLoader(window) {
|
|
282
387
|
|
283
388
|
}
|
284
389
|
|
285
|
-
|
390
|
+
setupModuleLoader(window);
|
391
|
+
})(window);
|
286
392
|
|
287
393
|
/**
|
288
394
|
* Closure compiler type information
|
@@ -1,10 +1,11 @@
|
|
1
1
|
/**
|
2
|
-
* @license AngularJS v1.
|
3
|
-
* (c) 2010-
|
2
|
+
* @license AngularJS v1.2.6
|
3
|
+
* (c) 2010-2014 Google, Inc. http://angularjs.org
|
4
4
|
* License: MIT
|
5
|
-
*
|
6
|
-
* TODO(vojta): wrap whole file into closure during build
|
7
5
|
*/
|
6
|
+
(function(window, angular, undefined) {
|
7
|
+
|
8
|
+
'use strict';
|
8
9
|
|
9
10
|
/**
|
10
11
|
* @ngdoc overview
|
@@ -29,7 +30,7 @@ angular.mock = {};
|
|
29
30
|
* that there are several helper methods available which can be used in tests.
|
30
31
|
*/
|
31
32
|
angular.mock.$BrowserProvider = function() {
|
32
|
-
this.$get = function(){
|
33
|
+
this.$get = function() {
|
33
34
|
return new angular.mock.$Browser();
|
34
35
|
};
|
35
36
|
};
|
@@ -75,6 +76,13 @@ angular.mock.$Browser = function() {
|
|
75
76
|
};
|
76
77
|
|
77
78
|
|
79
|
+
/**
|
80
|
+
* @name ngMock.$browser#defer.now
|
81
|
+
* @propertyOf ngMock.$browser
|
82
|
+
*
|
83
|
+
* @description
|
84
|
+
* Current milliseconds mock time.
|
85
|
+
*/
|
78
86
|
self.defer.now = 0;
|
79
87
|
|
80
88
|
|
@@ -110,7 +118,7 @@ angular.mock.$Browser = function() {
|
|
110
118
|
if (self.deferredFns.length) {
|
111
119
|
self.defer.now = self.deferredFns[self.deferredFns.length-1].time;
|
112
120
|
} else {
|
113
|
-
throw Error('No deferred tasks to be flushed');
|
121
|
+
throw new Error('No deferred tasks to be flushed');
|
114
122
|
}
|
115
123
|
}
|
116
124
|
|
@@ -118,13 +126,6 @@ angular.mock.$Browser = function() {
|
|
118
126
|
self.deferredFns.shift().fn();
|
119
127
|
}
|
120
128
|
};
|
121
|
-
/**
|
122
|
-
* @name ngMock.$browser#defer.now
|
123
|
-
* @propertyOf ngMock.$browser
|
124
|
-
*
|
125
|
-
* @description
|
126
|
-
* Current milliseconds mock time.
|
127
|
-
*/
|
128
129
|
|
129
130
|
self.$$baseHref = '';
|
130
131
|
self.baseHref = function() {
|
@@ -162,7 +163,7 @@ angular.mock.$Browser.prototype = {
|
|
162
163
|
|
163
164
|
cookies: function(name, value) {
|
164
165
|
if (name) {
|
165
|
-
if (value
|
166
|
+
if (angular.isUndefined(value)) {
|
166
167
|
delete this.cookieHash[name];
|
167
168
|
} else {
|
168
169
|
if (angular.isString(value) && //strings only
|
@@ -190,8 +191,8 @@ angular.mock.$Browser.prototype = {
|
|
190
191
|
* @name ngMock.$exceptionHandlerProvider
|
191
192
|
*
|
192
193
|
* @description
|
193
|
-
* Configures the mock implementation of {@link ng.$exceptionHandler} to rethrow or to log errors
|
194
|
-
* into the `$exceptionHandler`.
|
194
|
+
* Configures the mock implementation of {@link ng.$exceptionHandler} to rethrow or to log errors
|
195
|
+
* passed into the `$exceptionHandler`.
|
195
196
|
*/
|
196
197
|
|
197
198
|
/**
|
@@ -241,13 +242,13 @@ angular.mock.$ExceptionHandlerProvider = function() {
|
|
241
242
|
*
|
242
243
|
* @param {string} mode Mode of operation, defaults to `rethrow`.
|
243
244
|
*
|
244
|
-
* - `rethrow`: If any errors are
|
245
|
+
* - `rethrow`: If any errors are passed into the handler in tests, it typically
|
245
246
|
* means that there is a bug in the application or test, so this mock will
|
246
247
|
* make these tests fail.
|
247
|
-
* - `log`: Sometimes it is desirable to test that an error is thrown, for this case the `log`
|
248
|
-
* array of errors in `$exceptionHandler.errors`, to allow later
|
249
|
-
* See {@link ngMock.$log#assertEmpty assertEmpty()} and
|
250
|
-
*
|
248
|
+
* - `log`: Sometimes it is desirable to test that an error is thrown, for this case the `log`
|
249
|
+
* mode stores an array of errors in `$exceptionHandler.errors`, to allow later
|
250
|
+
* assertion of them. See {@link ngMock.$log#assertEmpty assertEmpty()} and
|
251
|
+
* {@link ngMock.$log#reset reset()}
|
251
252
|
*/
|
252
253
|
this.mode = function(mode) {
|
253
254
|
switch(mode) {
|
@@ -270,7 +271,7 @@ angular.mock.$ExceptionHandlerProvider = function() {
|
|
270
271
|
handler.errors = errors;
|
271
272
|
break;
|
272
273
|
default:
|
273
|
-
throw Error("Unknown mode '" + mode + "', only 'log'/'rethrow' modes are allowed!");
|
274
|
+
throw new Error("Unknown mode '" + mode + "', only 'log'/'rethrow' modes are allowed!");
|
274
275
|
}
|
275
276
|
};
|
276
277
|
|
@@ -293,18 +294,32 @@ angular.mock.$ExceptionHandlerProvider = function() {
|
|
293
294
|
*
|
294
295
|
*/
|
295
296
|
angular.mock.$LogProvider = function() {
|
297
|
+
var debug = true;
|
296
298
|
|
297
299
|
function concat(array1, array2, index) {
|
298
300
|
return array1.concat(Array.prototype.slice.call(array2, index));
|
299
301
|
}
|
300
302
|
|
303
|
+
this.debugEnabled = function(flag) {
|
304
|
+
if (angular.isDefined(flag)) {
|
305
|
+
debug = flag;
|
306
|
+
return this;
|
307
|
+
} else {
|
308
|
+
return debug;
|
309
|
+
}
|
310
|
+
};
|
301
311
|
|
302
312
|
this.$get = function () {
|
303
313
|
var $log = {
|
304
314
|
log: function() { $log.log.logs.push(concat([], arguments, 0)); },
|
305
315
|
warn: function() { $log.warn.logs.push(concat([], arguments, 0)); },
|
306
316
|
info: function() { $log.info.logs.push(concat([], arguments, 0)); },
|
307
|
-
error: function() { $log.error.logs.push(concat([], arguments, 0)); }
|
317
|
+
error: function() { $log.error.logs.push(concat([], arguments, 0)); },
|
318
|
+
debug: function() {
|
319
|
+
if (debug) {
|
320
|
+
$log.debug.logs.push(concat([], arguments, 0));
|
321
|
+
}
|
322
|
+
}
|
308
323
|
};
|
309
324
|
|
310
325
|
/**
|
@@ -322,36 +337,75 @@ angular.mock.$LogProvider = function() {
|
|
322
337
|
* @propertyOf ngMock.$log
|
323
338
|
*
|
324
339
|
* @description
|
325
|
-
* Array of logged
|
340
|
+
* Array of messages logged using {@link ngMock.$log#log}.
|
341
|
+
*
|
342
|
+
* @example
|
343
|
+
* <pre>
|
344
|
+
* $log.log('Some Log');
|
345
|
+
* var first = $log.log.logs.unshift();
|
346
|
+
* </pre>
|
326
347
|
*/
|
327
348
|
$log.log.logs = [];
|
328
349
|
/**
|
329
350
|
* @ngdoc property
|
330
|
-
* @name ngMock.$log#
|
351
|
+
* @name ngMock.$log#info.logs
|
331
352
|
* @propertyOf ngMock.$log
|
332
353
|
*
|
333
354
|
* @description
|
334
|
-
* Array of logged
|
355
|
+
* Array of messages logged using {@link ngMock.$log#info}.
|
356
|
+
*
|
357
|
+
* @example
|
358
|
+
* <pre>
|
359
|
+
* $log.info('Some Info');
|
360
|
+
* var first = $log.info.logs.unshift();
|
361
|
+
* </pre>
|
335
362
|
*/
|
336
|
-
$log.
|
363
|
+
$log.info.logs = [];
|
337
364
|
/**
|
338
365
|
* @ngdoc property
|
339
|
-
* @name ngMock.$log#
|
366
|
+
* @name ngMock.$log#warn.logs
|
340
367
|
* @propertyOf ngMock.$log
|
341
368
|
*
|
342
369
|
* @description
|
343
|
-
* Array of logged
|
370
|
+
* Array of messages logged using {@link ngMock.$log#warn}.
|
371
|
+
*
|
372
|
+
* @example
|
373
|
+
* <pre>
|
374
|
+
* $log.warn('Some Warning');
|
375
|
+
* var first = $log.warn.logs.unshift();
|
376
|
+
* </pre>
|
344
377
|
*/
|
345
|
-
$log.
|
378
|
+
$log.warn.logs = [];
|
346
379
|
/**
|
347
380
|
* @ngdoc property
|
348
381
|
* @name ngMock.$log#error.logs
|
349
382
|
* @propertyOf ngMock.$log
|
350
383
|
*
|
351
384
|
* @description
|
352
|
-
* Array of logged
|
385
|
+
* Array of messages logged using {@link ngMock.$log#error}.
|
386
|
+
*
|
387
|
+
* @example
|
388
|
+
* <pre>
|
389
|
+
* $log.log('Some Error');
|
390
|
+
* var first = $log.error.logs.unshift();
|
391
|
+
* </pre>
|
353
392
|
*/
|
354
393
|
$log.error.logs = [];
|
394
|
+
/**
|
395
|
+
* @ngdoc property
|
396
|
+
* @name ngMock.$log#debug.logs
|
397
|
+
* @propertyOf ngMock.$log
|
398
|
+
*
|
399
|
+
* @description
|
400
|
+
* Array of messages logged using {@link ngMock.$log#debug}.
|
401
|
+
*
|
402
|
+
* @example
|
403
|
+
* <pre>
|
404
|
+
* $log.debug('Some Error');
|
405
|
+
* var first = $log.debug.logs.unshift();
|
406
|
+
* </pre>
|
407
|
+
*/
|
408
|
+
$log.debug.logs = [];
|
355
409
|
};
|
356
410
|
|
357
411
|
/**
|
@@ -360,20 +414,22 @@ angular.mock.$LogProvider = function() {
|
|
360
414
|
* @methodOf ngMock.$log
|
361
415
|
*
|
362
416
|
* @description
|
363
|
-
* Assert that the all of the logging methods have no logged messages. If messages present, an
|
417
|
+
* Assert that the all of the logging methods have no logged messages. If messages present, an
|
418
|
+
* exception is thrown.
|
364
419
|
*/
|
365
420
|
$log.assertEmpty = function() {
|
366
421
|
var errors = [];
|
367
|
-
angular.forEach(['error', 'warn', 'info', 'log'], function(logLevel) {
|
422
|
+
angular.forEach(['error', 'warn', 'info', 'log', 'debug'], function(logLevel) {
|
368
423
|
angular.forEach($log[logLevel].logs, function(log) {
|
369
424
|
angular.forEach(log, function (logItem) {
|
370
|
-
errors.push('MOCK $log (' + logLevel + '): ' + String(logItem) + '\n' +
|
425
|
+
errors.push('MOCK $log (' + logLevel + '): ' + String(logItem) + '\n' +
|
426
|
+
(logItem.stack || ''));
|
371
427
|
});
|
372
428
|
});
|
373
429
|
});
|
374
430
|
if (errors.length) {
|
375
|
-
errors.unshift("Expected $log to be empty! Either a message was logged unexpectedly, or
|
376
|
-
"log message was not checked and removed:");
|
431
|
+
errors.unshift("Expected $log to be empty! Either a message was logged unexpectedly, or "+
|
432
|
+
"an expected log message was not checked and removed:");
|
377
433
|
errors.push('');
|
378
434
|
throw new Error(errors.join('\n---------\n'));
|
379
435
|
}
|
@@ -385,260 +441,371 @@ angular.mock.$LogProvider = function() {
|
|
385
441
|
};
|
386
442
|
|
387
443
|
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
var neg = '';
|
414
|
-
if (num < 0) {
|
415
|
-
neg = '-';
|
416
|
-
num = -num;
|
417
|
-
}
|
418
|
-
num = '' + num;
|
419
|
-
while(num.length < digits) num = '0' + num;
|
420
|
-
if (trim)
|
421
|
-
num = num.substr(num.length - digits);
|
422
|
-
return neg + num;
|
423
|
-
}
|
424
|
-
|
425
|
-
|
426
|
-
/**
|
427
|
-
* @ngdoc object
|
428
|
-
* @name angular.mock.TzDate
|
429
|
-
* @description
|
430
|
-
*
|
431
|
-
* *NOTE*: this is not an injectable instance, just a globally available mock class of `Date`.
|
432
|
-
*
|
433
|
-
* Mock of the Date type which has its timezone specified via constructor arg.
|
434
|
-
*
|
435
|
-
* The main purpose is to create Date-like instances with timezone fixed to the specified timezone
|
436
|
-
* offset, so that we can test code that depends on local timezone settings without dependency on
|
437
|
-
* the time zone settings of the machine where the code is running.
|
438
|
-
*
|
439
|
-
* @param {number} offset Offset of the *desired* timezone in hours (fractions will be honored)
|
440
|
-
* @param {(number|string)} timestamp Timestamp representing the desired time in *UTC*
|
441
|
-
*
|
442
|
-
* @example
|
443
|
-
* !!!! WARNING !!!!!
|
444
|
-
* This is not a complete Date object so only methods that were implemented can be called safely.
|
445
|
-
* To make matters worse, TzDate instances inherit stuff from Date via a prototype.
|
446
|
-
*
|
447
|
-
* We do our best to intercept calls to "unimplemented" methods, but since the list of methods is
|
448
|
-
* incomplete we might be missing some non-standard methods. This can result in errors like:
|
449
|
-
* "Date.prototype.foo called on incompatible Object".
|
450
|
-
*
|
451
|
-
* <pre>
|
452
|
-
* var newYearInBratislava = new TzDate(-1, '2009-12-31T23:00:00Z');
|
453
|
-
* newYearInBratislava.getTimezoneOffset() => -60;
|
454
|
-
* newYearInBratislava.getFullYear() => 2010;
|
455
|
-
* newYearInBratislava.getMonth() => 0;
|
456
|
-
* newYearInBratislava.getDate() => 1;
|
457
|
-
* newYearInBratislava.getHours() => 0;
|
458
|
-
* newYearInBratislava.getMinutes() => 0;
|
459
|
-
* newYearInBratislava.getSeconds() => 0;
|
460
|
-
* </pre>
|
461
|
-
*
|
462
|
-
*/
|
463
|
-
angular.mock.TzDate = function (offset, timestamp) {
|
464
|
-
var self = new Date(0);
|
465
|
-
if (angular.isString(timestamp)) {
|
466
|
-
var tsStr = timestamp;
|
467
|
-
|
468
|
-
self.origDate = jsonStringToDate(timestamp);
|
469
|
-
|
470
|
-
timestamp = self.origDate.getTime();
|
471
|
-
if (isNaN(timestamp))
|
472
|
-
throw {
|
473
|
-
name: "Illegal Argument",
|
474
|
-
message: "Arg '" + tsStr + "' passed into TzDate constructor is not a valid date string"
|
475
|
-
};
|
476
|
-
} else {
|
477
|
-
self.origDate = new Date(timestamp);
|
478
|
-
}
|
479
|
-
|
480
|
-
var localOffset = new Date(timestamp).getTimezoneOffset();
|
481
|
-
self.offsetDiff = localOffset*60*1000 - offset*1000*60*60;
|
482
|
-
self.date = new Date(timestamp + self.offsetDiff);
|
444
|
+
/**
|
445
|
+
* @ngdoc service
|
446
|
+
* @name ngMock.$interval
|
447
|
+
*
|
448
|
+
* @description
|
449
|
+
* Mock implementation of the $interval service.
|
450
|
+
*
|
451
|
+
* Use {@link ngMock.$interval#methods_flush `$interval.flush(millis)`} to
|
452
|
+
* move forward by `millis` milliseconds and trigger any functions scheduled to run in that
|
453
|
+
* time.
|
454
|
+
*
|
455
|
+
* @param {function()} fn A function that should be called repeatedly.
|
456
|
+
* @param {number} delay Number of milliseconds between each function call.
|
457
|
+
* @param {number=} [count=0] Number of times to repeat. If not set, or 0, will repeat
|
458
|
+
* indefinitely.
|
459
|
+
* @param {boolean=} [invokeApply=true] If set to `false` skips model dirty checking, otherwise
|
460
|
+
* will invoke `fn` within the {@link ng.$rootScope.Scope#methods_$apply $apply} block.
|
461
|
+
* @returns {promise} A promise which will be notified on each iteration.
|
462
|
+
*/
|
463
|
+
angular.mock.$IntervalProvider = function() {
|
464
|
+
this.$get = ['$rootScope', '$q',
|
465
|
+
function($rootScope, $q) {
|
466
|
+
var repeatFns = [],
|
467
|
+
nextRepeatId = 0,
|
468
|
+
now = 0;
|
483
469
|
|
484
|
-
|
485
|
-
|
486
|
-
|
470
|
+
var $interval = function(fn, delay, count, invokeApply) {
|
471
|
+
var deferred = $q.defer(),
|
472
|
+
promise = deferred.promise,
|
473
|
+
iteration = 0,
|
474
|
+
skipApply = (angular.isDefined(invokeApply) && !invokeApply);
|
487
475
|
|
488
|
-
|
489
|
-
|
490
|
-
};
|
476
|
+
count = (angular.isDefined(count)) ? count : 0,
|
477
|
+
promise.then(null, null, fn);
|
491
478
|
|
492
|
-
|
493
|
-
return self.date.getFullYear();
|
494
|
-
};
|
479
|
+
promise.$$intervalId = nextRepeatId;
|
495
480
|
|
496
|
-
|
497
|
-
|
498
|
-
};
|
481
|
+
function tick() {
|
482
|
+
deferred.notify(iteration++);
|
499
483
|
|
500
|
-
|
501
|
-
|
502
|
-
|
484
|
+
if (count > 0 && iteration >= count) {
|
485
|
+
var fnIndex;
|
486
|
+
deferred.resolve(iteration);
|
503
487
|
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
self.getMinutes = function() {
|
509
|
-
return self.date.getMinutes();
|
510
|
-
};
|
488
|
+
angular.forEach(repeatFns, function(fn, index) {
|
489
|
+
if (fn.id === promise.$$intervalId) fnIndex = index;
|
490
|
+
});
|
511
491
|
|
512
|
-
|
513
|
-
|
514
|
-
|
492
|
+
if (fnIndex !== undefined) {
|
493
|
+
repeatFns.splice(fnIndex, 1);
|
494
|
+
}
|
495
|
+
}
|
515
496
|
|
516
|
-
|
517
|
-
|
518
|
-
};
|
497
|
+
if (!skipApply) $rootScope.$apply();
|
498
|
+
}
|
519
499
|
|
520
|
-
|
521
|
-
|
522
|
-
|
500
|
+
repeatFns.push({
|
501
|
+
nextTime:(now + delay),
|
502
|
+
delay: delay,
|
503
|
+
fn: tick,
|
504
|
+
id: nextRepeatId,
|
505
|
+
deferred: deferred
|
506
|
+
});
|
507
|
+
repeatFns.sort(function(a,b){ return a.nextTime - b.nextTime;});
|
523
508
|
|
524
|
-
|
525
|
-
return
|
509
|
+
nextRepeatId++;
|
510
|
+
return promise;
|
526
511
|
};
|
527
512
|
|
528
|
-
|
529
|
-
|
530
|
-
};
|
513
|
+
$interval.cancel = function(promise) {
|
514
|
+
var fnIndex;
|
531
515
|
|
532
|
-
|
533
|
-
|
534
|
-
|
516
|
+
angular.forEach(repeatFns, function(fn, index) {
|
517
|
+
if (fn.id === promise.$$intervalId) fnIndex = index;
|
518
|
+
});
|
535
519
|
|
536
|
-
|
537
|
-
|
538
|
-
|
520
|
+
if (fnIndex !== undefined) {
|
521
|
+
repeatFns[fnIndex].deferred.reject('canceled');
|
522
|
+
repeatFns.splice(fnIndex, 1);
|
523
|
+
return true;
|
524
|
+
}
|
539
525
|
|
540
|
-
|
541
|
-
return self.origDate.getUTCMinutes();
|
526
|
+
return false;
|
542
527
|
};
|
543
528
|
|
544
|
-
|
545
|
-
|
529
|
+
/**
|
530
|
+
* @ngdoc method
|
531
|
+
* @name ngMock.$interval#flush
|
532
|
+
* @methodOf ngMock.$interval
|
533
|
+
* @description
|
534
|
+
*
|
535
|
+
* Runs interval tasks scheduled to be run in the next `millis` milliseconds.
|
536
|
+
*
|
537
|
+
* @param {number=} millis maximum timeout amount to flush up until.
|
538
|
+
*
|
539
|
+
* @return {number} The amount of time moved forward.
|
540
|
+
*/
|
541
|
+
$interval.flush = function(millis) {
|
542
|
+
now += millis;
|
543
|
+
while (repeatFns.length && repeatFns[0].nextTime <= now) {
|
544
|
+
var task = repeatFns[0];
|
545
|
+
task.fn();
|
546
|
+
task.nextTime += task.delay;
|
547
|
+
repeatFns.sort(function(a,b){ return a.nextTime - b.nextTime;});
|
548
|
+
}
|
549
|
+
return millis;
|
546
550
|
};
|
547
551
|
|
548
|
-
|
549
|
-
|
550
|
-
|
552
|
+
return $interval;
|
553
|
+
}];
|
554
|
+
};
|
551
555
|
|
552
|
-
self.getDay = function() {
|
553
|
-
return self.date.getDay();
|
554
|
-
};
|
555
556
|
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
557
|
+
/* jshint -W101 */
|
558
|
+
/* The R_ISO8061_STR regex is never going to fit into the 100 char limit!
|
559
|
+
* This directive should go inside the anonymous function but a bug in JSHint means that it would
|
560
|
+
* not be enacted early enough to prevent the warning.
|
561
|
+
*/
|
562
|
+
var R_ISO8061_STR = /^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?:\:?(\d\d)(?:\:?(\d\d)(?:\.(\d{3}))?)?)?(Z|([+-])(\d\d):?(\d\d)))?$/;
|
563
|
+
|
564
|
+
function jsonStringToDate(string) {
|
565
|
+
var match;
|
566
|
+
if (match = string.match(R_ISO8061_STR)) {
|
567
|
+
var date = new Date(0),
|
568
|
+
tzHour = 0,
|
569
|
+
tzMin = 0;
|
570
|
+
if (match[9]) {
|
571
|
+
tzHour = int(match[9] + match[10]);
|
572
|
+
tzMin = int(match[9] + match[11]);
|
567
573
|
}
|
574
|
+
date.setUTCFullYear(int(match[1]), int(match[2]) - 1, int(match[3]));
|
575
|
+
date.setUTCHours(int(match[4]||0) - tzHour,
|
576
|
+
int(match[5]||0) - tzMin,
|
577
|
+
int(match[6]||0),
|
578
|
+
int(match[7]||0));
|
579
|
+
return date;
|
580
|
+
}
|
581
|
+
return string;
|
582
|
+
}
|
568
583
|
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
'setMinutes', 'setMonth', 'setSeconds', 'setTime', 'setUTCDate', 'setUTCFullYear',
|
573
|
-
'setUTCHours', 'setUTCMilliseconds', 'setUTCMinutes', 'setUTCMonth', 'setUTCSeconds',
|
574
|
-
'setYear', 'toDateString', 'toGMTString', 'toJSON', 'toLocaleFormat', 'toLocaleString',
|
575
|
-
'toLocaleTimeString', 'toSource', 'toString', 'toTimeString', 'toUTCString', 'valueOf'];
|
576
|
-
|
577
|
-
angular.forEach(unimplementedMethods, function(methodName) {
|
578
|
-
self[methodName] = function() {
|
579
|
-
throw Error("Method '" + methodName + "' is not implemented in the TzDate mock");
|
580
|
-
};
|
581
|
-
});
|
584
|
+
function int(str) {
|
585
|
+
return parseInt(str, 10);
|
586
|
+
}
|
582
587
|
|
583
|
-
|
584
|
-
|
588
|
+
function padNumber(num, digits, trim) {
|
589
|
+
var neg = '';
|
590
|
+
if (num < 0) {
|
591
|
+
neg = '-';
|
592
|
+
num = -num;
|
593
|
+
}
|
594
|
+
num = '' + num;
|
595
|
+
while(num.length < digits) num = '0' + num;
|
596
|
+
if (trim)
|
597
|
+
num = num.substr(num.length - digits);
|
598
|
+
return neg + num;
|
599
|
+
}
|
585
600
|
|
586
|
-
//make "tzDateInstance instanceof Date" return true
|
587
|
-
angular.mock.TzDate.prototype = Date.prototype;
|
588
|
-
})();
|
589
601
|
|
590
602
|
/**
|
591
|
-
* @ngdoc
|
592
|
-
* @name angular.mock.
|
603
|
+
* @ngdoc object
|
604
|
+
* @name angular.mock.TzDate
|
593
605
|
* @description
|
594
606
|
*
|
595
|
-
*
|
596
|
-
*
|
607
|
+
* *NOTE*: this is not an injectable instance, just a globally available mock class of `Date`.
|
608
|
+
*
|
609
|
+
* Mock of the Date type which has its timezone specified via constructor arg.
|
610
|
+
*
|
611
|
+
* The main purpose is to create Date-like instances with timezone fixed to the specified timezone
|
612
|
+
* offset, so that we can test code that depends on local timezone settings without dependency on
|
613
|
+
* the time zone settings of the machine where the code is running.
|
614
|
+
*
|
615
|
+
* @param {number} offset Offset of the *desired* timezone in hours (fractions will be honored)
|
616
|
+
* @param {(number|string)} timestamp Timestamp representing the desired time in *UTC*
|
597
617
|
*
|
598
618
|
* @example
|
619
|
+
* !!!! WARNING !!!!!
|
620
|
+
* This is not a complete Date object so only methods that were implemented can be called safely.
|
621
|
+
* To make matters worse, TzDate instances inherit stuff from Date via a prototype.
|
622
|
+
*
|
623
|
+
* We do our best to intercept calls to "unimplemented" methods, but since the list of methods is
|
624
|
+
* incomplete we might be missing some non-standard methods. This can result in errors like:
|
625
|
+
* "Date.prototype.foo called on incompatible Object".
|
599
626
|
*
|
600
627
|
* <pre>
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
window.setTimeout.expect(10).process();
|
610
|
-
expect(val).toEqual(123);
|
611
|
-
});
|
628
|
+
* var newYearInBratislava = new TzDate(-1, '2009-12-31T23:00:00Z');
|
629
|
+
* newYearInBratislava.getTimezoneOffset() => -60;
|
630
|
+
* newYearInBratislava.getFullYear() => 2010;
|
631
|
+
* newYearInBratislava.getMonth() => 0;
|
632
|
+
* newYearInBratislava.getDate() => 1;
|
633
|
+
* newYearInBratislava.getHours() => 0;
|
634
|
+
* newYearInBratislava.getMinutes() => 0;
|
635
|
+
* newYearInBratislava.getSeconds() => 0;
|
612
636
|
* </pre>
|
613
637
|
*
|
614
638
|
*/
|
615
|
-
angular.mock.
|
616
|
-
var
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
mockWindow.setTimeout.expect = function(delay) {
|
628
|
-
if (setTimeoutQueue.length > 0) {
|
629
|
-
return {
|
630
|
-
process: function() {
|
631
|
-
setTimeoutQueue.shift().fn();
|
632
|
-
}
|
639
|
+
angular.mock.TzDate = function (offset, timestamp) {
|
640
|
+
var self = new Date(0);
|
641
|
+
if (angular.isString(timestamp)) {
|
642
|
+
var tsStr = timestamp;
|
643
|
+
|
644
|
+
self.origDate = jsonStringToDate(timestamp);
|
645
|
+
|
646
|
+
timestamp = self.origDate.getTime();
|
647
|
+
if (isNaN(timestamp))
|
648
|
+
throw {
|
649
|
+
name: "Illegal Argument",
|
650
|
+
message: "Arg '" + tsStr + "' passed into TzDate constructor is not a valid date string"
|
633
651
|
};
|
634
|
-
|
635
|
-
|
636
|
-
|
652
|
+
} else {
|
653
|
+
self.origDate = new Date(timestamp);
|
654
|
+
}
|
655
|
+
|
656
|
+
var localOffset = new Date(timestamp).getTimezoneOffset();
|
657
|
+
self.offsetDiff = localOffset*60*1000 - offset*1000*60*60;
|
658
|
+
self.date = new Date(timestamp + self.offsetDiff);
|
659
|
+
|
660
|
+
self.getTime = function() {
|
661
|
+
return self.date.getTime() - self.offsetDiff;
|
662
|
+
};
|
663
|
+
|
664
|
+
self.toLocaleDateString = function() {
|
665
|
+
return self.date.toLocaleDateString();
|
666
|
+
};
|
667
|
+
|
668
|
+
self.getFullYear = function() {
|
669
|
+
return self.date.getFullYear();
|
670
|
+
};
|
671
|
+
|
672
|
+
self.getMonth = function() {
|
673
|
+
return self.date.getMonth();
|
674
|
+
};
|
675
|
+
|
676
|
+
self.getDate = function() {
|
677
|
+
return self.date.getDate();
|
678
|
+
};
|
679
|
+
|
680
|
+
self.getHours = function() {
|
681
|
+
return self.date.getHours();
|
682
|
+
};
|
683
|
+
|
684
|
+
self.getMinutes = function() {
|
685
|
+
return self.date.getMinutes();
|
686
|
+
};
|
687
|
+
|
688
|
+
self.getSeconds = function() {
|
689
|
+
return self.date.getSeconds();
|
690
|
+
};
|
691
|
+
|
692
|
+
self.getMilliseconds = function() {
|
693
|
+
return self.date.getMilliseconds();
|
694
|
+
};
|
695
|
+
|
696
|
+
self.getTimezoneOffset = function() {
|
697
|
+
return offset * 60;
|
698
|
+
};
|
699
|
+
|
700
|
+
self.getUTCFullYear = function() {
|
701
|
+
return self.origDate.getUTCFullYear();
|
702
|
+
};
|
703
|
+
|
704
|
+
self.getUTCMonth = function() {
|
705
|
+
return self.origDate.getUTCMonth();
|
706
|
+
};
|
707
|
+
|
708
|
+
self.getUTCDate = function() {
|
709
|
+
return self.origDate.getUTCDate();
|
710
|
+
};
|
711
|
+
|
712
|
+
self.getUTCHours = function() {
|
713
|
+
return self.origDate.getUTCHours();
|
637
714
|
};
|
638
715
|
|
639
|
-
|
716
|
+
self.getUTCMinutes = function() {
|
717
|
+
return self.origDate.getUTCMinutes();
|
718
|
+
};
|
719
|
+
|
720
|
+
self.getUTCSeconds = function() {
|
721
|
+
return self.origDate.getUTCSeconds();
|
722
|
+
};
|
723
|
+
|
724
|
+
self.getUTCMilliseconds = function() {
|
725
|
+
return self.origDate.getUTCMilliseconds();
|
726
|
+
};
|
727
|
+
|
728
|
+
self.getDay = function() {
|
729
|
+
return self.date.getDay();
|
730
|
+
};
|
731
|
+
|
732
|
+
// provide this method only on browsers that already have it
|
733
|
+
if (self.toISOString) {
|
734
|
+
self.toISOString = function() {
|
735
|
+
return padNumber(self.origDate.getUTCFullYear(), 4) + '-' +
|
736
|
+
padNumber(self.origDate.getUTCMonth() + 1, 2) + '-' +
|
737
|
+
padNumber(self.origDate.getUTCDate(), 2) + 'T' +
|
738
|
+
padNumber(self.origDate.getUTCHours(), 2) + ':' +
|
739
|
+
padNumber(self.origDate.getUTCMinutes(), 2) + ':' +
|
740
|
+
padNumber(self.origDate.getUTCSeconds(), 2) + '.' +
|
741
|
+
padNumber(self.origDate.getUTCMilliseconds(), 3) + 'Z';
|
742
|
+
};
|
743
|
+
}
|
744
|
+
|
745
|
+
//hide all methods not implemented in this mock that the Date prototype exposes
|
746
|
+
var unimplementedMethods = ['getUTCDay',
|
747
|
+
'getYear', 'setDate', 'setFullYear', 'setHours', 'setMilliseconds',
|
748
|
+
'setMinutes', 'setMonth', 'setSeconds', 'setTime', 'setUTCDate', 'setUTCFullYear',
|
749
|
+
'setUTCHours', 'setUTCMilliseconds', 'setUTCMinutes', 'setUTCMonth', 'setUTCSeconds',
|
750
|
+
'setYear', 'toDateString', 'toGMTString', 'toJSON', 'toLocaleFormat', 'toLocaleString',
|
751
|
+
'toLocaleTimeString', 'toSource', 'toString', 'toTimeString', 'toUTCString', 'valueOf'];
|
752
|
+
|
753
|
+
angular.forEach(unimplementedMethods, function(methodName) {
|
754
|
+
self[methodName] = function() {
|
755
|
+
throw new Error("Method '" + methodName + "' is not implemented in the TzDate mock");
|
756
|
+
};
|
757
|
+
});
|
758
|
+
|
759
|
+
return self;
|
640
760
|
};
|
641
761
|
|
762
|
+
//make "tzDateInstance instanceof Date" return true
|
763
|
+
angular.mock.TzDate.prototype = Date.prototype;
|
764
|
+
/* jshint +W101 */
|
765
|
+
|
766
|
+
angular.mock.animate = angular.module('mock.animate', ['ng'])
|
767
|
+
|
768
|
+
.config(['$provide', function($provide) {
|
769
|
+
|
770
|
+
$provide.decorator('$animate', function($delegate) {
|
771
|
+
var animate = {
|
772
|
+
queue : [],
|
773
|
+
enabled : $delegate.enabled,
|
774
|
+
flushNext : function(name) {
|
775
|
+
var tick = animate.queue.shift();
|
776
|
+
|
777
|
+
if (!tick) throw new Error('No animation to be flushed');
|
778
|
+
if(tick.method !== name) {
|
779
|
+
throw new Error('The next animation is not "' + name +
|
780
|
+
'", but is "' + tick.method + '"');
|
781
|
+
}
|
782
|
+
tick.fn();
|
783
|
+
return tick;
|
784
|
+
}
|
785
|
+
};
|
786
|
+
|
787
|
+
angular.forEach(['enter','leave','move','addClass','removeClass'], function(method) {
|
788
|
+
animate[method] = function() {
|
789
|
+
var params = arguments;
|
790
|
+
animate.queue.push({
|
791
|
+
method : method,
|
792
|
+
params : params,
|
793
|
+
element : angular.isElement(params[0]) && params[0],
|
794
|
+
parent : angular.isElement(params[1]) && params[1],
|
795
|
+
after : angular.isElement(params[2]) && params[2],
|
796
|
+
fn : function() {
|
797
|
+
$delegate[method].apply($delegate, params);
|
798
|
+
}
|
799
|
+
});
|
800
|
+
};
|
801
|
+
});
|
802
|
+
|
803
|
+
return animate;
|
804
|
+
});
|
805
|
+
|
806
|
+
}]);
|
807
|
+
|
808
|
+
|
642
809
|
/**
|
643
810
|
* @ngdoc function
|
644
811
|
* @name angular.mock.dump
|
@@ -646,9 +813,11 @@ angular.mock.createMockWindow = function() {
|
|
646
813
|
*
|
647
814
|
* *NOTE*: this is not an injectable instance, just a globally available function.
|
648
815
|
*
|
649
|
-
* Method for serializing common angular objects (scope, elements, etc..) into strings, useful for
|
816
|
+
* Method for serializing common angular objects (scope, elements, etc..) into strings, useful for
|
817
|
+
* debugging.
|
650
818
|
*
|
651
|
-
* This method is also available on window, where it can be used to display objects on debug
|
819
|
+
* This method is also available on window, where it can be used to display objects on debug
|
820
|
+
* console.
|
652
821
|
*
|
653
822
|
* @param {*} object - any object to turn into string.
|
654
823
|
* @return {string} a serialized string of the argument
|
@@ -678,6 +847,8 @@ angular.mock.dump = function(object) {
|
|
678
847
|
} else if (object instanceof Error) {
|
679
848
|
out = object.stack || ('' + object.name + ': ' + object.message);
|
680
849
|
} else {
|
850
|
+
// TODO(i): this prevents methods being logged,
|
851
|
+
// we should have a better way to serialize objects
|
681
852
|
out = angular.toJson(object, true);
|
682
853
|
}
|
683
854
|
} else {
|
@@ -691,7 +862,7 @@ angular.mock.dump = function(object) {
|
|
691
862
|
offset = offset || ' ';
|
692
863
|
var log = [offset + 'Scope(' + scope.$id + '): {'];
|
693
864
|
for ( var key in scope ) {
|
694
|
-
if (
|
865
|
+
if (Object.prototype.hasOwnProperty.call(scope, key) && !key.match(/^(\$|this)/)) {
|
695
866
|
log.push(' ' + key + ': ' + angular.toJson(scope[key]));
|
696
867
|
}
|
697
868
|
}
|
@@ -709,10 +880,10 @@ angular.mock.dump = function(object) {
|
|
709
880
|
* @ngdoc object
|
710
881
|
* @name ngMock.$httpBackend
|
711
882
|
* @description
|
712
|
-
* Fake HTTP backend implementation suitable for unit testing
|
883
|
+
* Fake HTTP backend implementation suitable for unit testing applications that use the
|
713
884
|
* {@link ng.$http $http service}.
|
714
885
|
*
|
715
|
-
* *Note*: For fake
|
886
|
+
* *Note*: For fake HTTP backend implementation suitable for end-to-end testing or backend-less
|
716
887
|
* development please see {@link ngMockE2E.$httpBackend e2e $httpBackend mock}.
|
717
888
|
*
|
718
889
|
* During unit testing, we want our unit tests to run quickly and have no external dependencies so
|
@@ -805,75 +976,100 @@ angular.mock.dump = function(object) {
|
|
805
976
|
*
|
806
977
|
*
|
807
978
|
* # Unit testing with mock $httpBackend
|
979
|
+
* The following code shows how to setup and use the mock backend in unit testing a controller.
|
980
|
+
* First we create the controller under test
|
808
981
|
*
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
982
|
+
<pre>
|
983
|
+
// The controller code
|
984
|
+
function MyController($scope, $http) {
|
985
|
+
var authToken;
|
986
|
+
|
987
|
+
$http.get('/auth.py').success(function(data, status, headers) {
|
988
|
+
authToken = headers('A-Token');
|
989
|
+
$scope.user = data;
|
990
|
+
});
|
991
|
+
|
992
|
+
$scope.saveMessage = function(message) {
|
993
|
+
var headers = { 'Authorization': authToken };
|
994
|
+
$scope.status = 'Saving...';
|
995
|
+
|
996
|
+
$http.post('/add-msg.py', message, { headers: headers } ).success(function(response) {
|
997
|
+
$scope.status = '';
|
998
|
+
}).error(function() {
|
999
|
+
$scope.status = 'ERROR!';
|
1000
|
+
});
|
1001
|
+
};
|
1002
|
+
}
|
1003
|
+
</pre>
|
1004
|
+
*
|
1005
|
+
* Now we setup the mock backend and create the test specs.
|
1006
|
+
*
|
1007
|
+
<pre>
|
1008
|
+
// testing controller
|
1009
|
+
describe('MyController', function() {
|
1010
|
+
var $httpBackend, $rootScope, createController;
|
1011
|
+
|
1012
|
+
beforeEach(inject(function($injector) {
|
1013
|
+
// Set up the mock http service responses
|
1014
|
+
$httpBackend = $injector.get('$httpBackend');
|
1015
|
+
// backend definition common for all tests
|
1016
|
+
$httpBackend.when('GET', '/auth.py').respond({userId: 'userX'}, {'A-Token': 'xxx'});
|
825
1017
|
|
826
|
-
|
827
|
-
|
1018
|
+
// Get hold of a scope (i.e. the root scope)
|
1019
|
+
$rootScope = $injector.get('$rootScope');
|
1020
|
+
// The $controller service is used to create instances of controllers
|
1021
|
+
var $controller = $injector.get('$controller');
|
828
1022
|
|
829
|
-
|
830
|
-
|
1023
|
+
createController = function() {
|
1024
|
+
return $controller('MyController', {'$scope' : $rootScope });
|
1025
|
+
};
|
1026
|
+
}));
|
831
1027
|
|
832
|
-
|
833
|
-
|
834
|
-
|
1028
|
+
|
1029
|
+
afterEach(function() {
|
1030
|
+
$httpBackend.verifyNoOutstandingExpectation();
|
1031
|
+
$httpBackend.verifyNoOutstandingRequest();
|
1032
|
+
});
|
835
1033
|
|
836
1034
|
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
|
1035
|
+
it('should fetch authentication token', function() {
|
1036
|
+
$httpBackend.expectGET('/auth.py');
|
1037
|
+
var controller = createController();
|
1038
|
+
$httpBackend.flush();
|
1039
|
+
});
|
841
1040
|
|
842
1041
|
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
$httpBackend.flush();
|
847
|
-
});
|
1042
|
+
it('should send msg to server', function() {
|
1043
|
+
var controller = createController();
|
1044
|
+
$httpBackend.flush();
|
848
1045
|
|
1046
|
+
// now you don’t care about the authentication, but
|
1047
|
+
// the controller will still send the request and
|
1048
|
+
// $httpBackend will respond without you having to
|
1049
|
+
// specify the expectation and response for this request
|
849
1050
|
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
|
1051
|
+
$httpBackend.expectPOST('/add-msg.py', 'message content').respond(201, '');
|
1052
|
+
$rootScope.saveMessage('message content');
|
1053
|
+
expect($rootScope.status).toBe('Saving...');
|
1054
|
+
$httpBackend.flush();
|
1055
|
+
expect($rootScope.status).toBe('');
|
1056
|
+
});
|
856
1057
|
|
857
|
-
var controller = scope.$new(MyController);
|
858
|
-
$httpBackend.flush();
|
859
|
-
controller.saveMessage('message content');
|
860
|
-
expect(controller.status).toBe('Saving...');
|
861
|
-
$httpBackend.flush();
|
862
|
-
expect(controller.status).toBe('');
|
863
|
-
});
|
864
1058
|
|
1059
|
+
it('should send auth header', function() {
|
1060
|
+
var controller = createController();
|
1061
|
+
$httpBackend.flush();
|
865
1062
|
|
866
|
-
|
867
|
-
|
868
|
-
|
869
|
-
|
870
|
-
|
871
|
-
}).respond(201, '');
|
1063
|
+
$httpBackend.expectPOST('/add-msg.py', undefined, function(headers) {
|
1064
|
+
// check if the header was send, if it wasn't the expectation won't
|
1065
|
+
// match the request and the test will fail
|
1066
|
+
return headers['Authorization'] == 'xxx';
|
1067
|
+
}).respond(201, '');
|
872
1068
|
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
|
1069
|
+
$rootScope.saveMessage('whatever');
|
1070
|
+
$httpBackend.flush();
|
1071
|
+
});
|
1072
|
+
});
|
877
1073
|
</pre>
|
878
1074
|
*/
|
879
1075
|
angular.mock.$HttpBackendProvider = function() {
|
@@ -898,7 +1094,8 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
|
|
898
1094
|
var definitions = [],
|
899
1095
|
expectations = [],
|
900
1096
|
responses = [],
|
901
|
-
responsesPush = angular.bind(responses, responses.push)
|
1097
|
+
responsesPush = angular.bind(responses, responses.push),
|
1098
|
+
copy = angular.copy;
|
902
1099
|
|
903
1100
|
function createResponse(status, data, headers) {
|
904
1101
|
if (angular.isFunction(status)) return status;
|
@@ -911,7 +1108,7 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
|
|
911
1108
|
}
|
912
1109
|
|
913
1110
|
// TODO(vojta): change params to: method, url, data, headers, callback
|
914
|
-
function $httpBackend(method, url, data, callback, headers) {
|
1111
|
+
function $httpBackend(method, url, data, callback, headers, timeout, withCredentials) {
|
915
1112
|
var xhr = new MockXhr(),
|
916
1113
|
expectation = expectations[0],
|
917
1114
|
wasExpected = false;
|
@@ -922,24 +1119,42 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
|
|
922
1119
|
: angular.toJson(data);
|
923
1120
|
}
|
924
1121
|
|
1122
|
+
function wrapResponse(wrapped) {
|
1123
|
+
if (!$browser && timeout && timeout.then) timeout.then(handleTimeout);
|
1124
|
+
|
1125
|
+
return handleResponse;
|
1126
|
+
|
1127
|
+
function handleResponse() {
|
1128
|
+
var response = wrapped.response(method, url, data, headers);
|
1129
|
+
xhr.$$respHeaders = response[2];
|
1130
|
+
callback(copy(response[0]), copy(response[1]), xhr.getAllResponseHeaders());
|
1131
|
+
}
|
1132
|
+
|
1133
|
+
function handleTimeout() {
|
1134
|
+
for (var i = 0, ii = responses.length; i < ii; i++) {
|
1135
|
+
if (responses[i] === handleResponse) {
|
1136
|
+
responses.splice(i, 1);
|
1137
|
+
callback(-1, undefined, '');
|
1138
|
+
break;
|
1139
|
+
}
|
1140
|
+
}
|
1141
|
+
}
|
1142
|
+
}
|
1143
|
+
|
925
1144
|
if (expectation && expectation.match(method, url)) {
|
926
1145
|
if (!expectation.matchData(data))
|
927
|
-
throw Error('Expected ' + expectation + ' with different data\n' +
|
1146
|
+
throw new Error('Expected ' + expectation + ' with different data\n' +
|
928
1147
|
'EXPECTED: ' + prettyPrint(expectation.data) + '\nGOT: ' + data);
|
929
1148
|
|
930
1149
|
if (!expectation.matchHeaders(headers))
|
931
|
-
throw Error('Expected ' + expectation + ' with different headers\n' +
|
932
|
-
|
933
|
-
|
1150
|
+
throw new Error('Expected ' + expectation + ' with different headers\n' +
|
1151
|
+
'EXPECTED: ' + prettyPrint(expectation.headers) + '\nGOT: ' +
|
1152
|
+
prettyPrint(headers));
|
934
1153
|
|
935
1154
|
expectations.shift();
|
936
1155
|
|
937
1156
|
if (expectation.response) {
|
938
|
-
responses.push(
|
939
|
-
var response = expectation.response(method, url, data, headers);
|
940
|
-
xhr.$$respHeaders = response[2];
|
941
|
-
callback(response[0], response[1], xhr.getAllResponseHeaders());
|
942
|
-
});
|
1157
|
+
responses.push(wrapResponse(expectation));
|
943
1158
|
return;
|
944
1159
|
}
|
945
1160
|
wasExpected = true;
|
@@ -950,21 +1165,17 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
|
|
950
1165
|
if (definition.match(method, url, data, headers || {})) {
|
951
1166
|
if (definition.response) {
|
952
1167
|
// if $browser specified, we do auto flush all requests
|
953
|
-
($browser ? $browser.defer : responsesPush)(
|
954
|
-
var response = definition.response(method, url, data, headers);
|
955
|
-
xhr.$$respHeaders = response[2];
|
956
|
-
callback(response[0], response[1], xhr.getAllResponseHeaders());
|
957
|
-
});
|
1168
|
+
($browser ? $browser.defer : responsesPush)(wrapResponse(definition));
|
958
1169
|
} else if (definition.passThrough) {
|
959
|
-
$delegate(method, url, data, callback, headers);
|
960
|
-
} else throw Error('No response defined !');
|
1170
|
+
$delegate(method, url, data, callback, headers, timeout, withCredentials);
|
1171
|
+
} else throw new Error('No response defined !');
|
961
1172
|
return;
|
962
1173
|
}
|
963
1174
|
}
|
964
1175
|
throw wasExpected ?
|
965
|
-
Error('No response defined !') :
|
966
|
-
Error('Unexpected request: ' + method + ' ' + url + '\n' +
|
967
|
-
|
1176
|
+
new Error('No response defined !') :
|
1177
|
+
new Error('Unexpected request: ' + method + ' ' + url + '\n' +
|
1178
|
+
(expectation ? 'Expected ' + expectation : 'No more request expected'));
|
968
1179
|
}
|
969
1180
|
|
970
1181
|
/**
|
@@ -976,13 +1187,15 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
|
|
976
1187
|
*
|
977
1188
|
* @param {string} method HTTP method.
|
978
1189
|
* @param {string|RegExp} url HTTP url.
|
979
|
-
* @param {(string|RegExp)=} data HTTP request body
|
1190
|
+
* @param {(string|RegExp|function(string))=} data HTTP request body or function that receives
|
1191
|
+
* data string and returns true if the data is as expected.
|
980
1192
|
* @param {(Object|function(Object))=} headers HTTP headers or function that receives http header
|
981
1193
|
* object and returns true if the headers match the current definition.
|
982
|
-
* @returns {requestHandler} Returns an object with `respond` method that
|
1194
|
+
* @returns {requestHandler} Returns an object with `respond` method that controls how a matched
|
983
1195
|
* request is handled.
|
984
1196
|
*
|
985
|
-
* - respond –
|
1197
|
+
* - respond –
|
1198
|
+
* `{function([status,] data[, headers])|function(function(method, url, data, headers)}`
|
986
1199
|
* – The respond method takes a set of static data to be returned or a function that can return
|
987
1200
|
* an array containing response status (number), response data (string) and response headers
|
988
1201
|
* (Object).
|
@@ -1052,7 +1265,8 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
|
|
1052
1265
|
* Creates a new backend definition for POST requests. For more info see `when()`.
|
1053
1266
|
*
|
1054
1267
|
* @param {string|RegExp} url HTTP url.
|
1055
|
-
* @param {(string|RegExp)=} data HTTP request body
|
1268
|
+
* @param {(string|RegExp|function(string))=} data HTTP request body or function that receives
|
1269
|
+
* data string and returns true if the data is as expected.
|
1056
1270
|
* @param {(Object|function(Object))=} headers HTTP headers.
|
1057
1271
|
* @returns {requestHandler} Returns an object with `respond` method that control how a matched
|
1058
1272
|
* request is handled.
|
@@ -1066,7 +1280,8 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
|
|
1066
1280
|
* Creates a new backend definition for PUT requests. For more info see `when()`.
|
1067
1281
|
*
|
1068
1282
|
* @param {string|RegExp} url HTTP url.
|
1069
|
-
* @param {(string|RegExp)=} data HTTP request body
|
1283
|
+
* @param {(string|RegExp|function(string))=} data HTTP request body or function that receives
|
1284
|
+
* data string and returns true if the data is as expected.
|
1070
1285
|
* @param {(Object|function(Object))=} headers HTTP headers.
|
1071
1286
|
* @returns {requestHandler} Returns an object with `respond` method that control how a matched
|
1072
1287
|
* request is handled.
|
@@ -1095,13 +1310,16 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
|
|
1095
1310
|
*
|
1096
1311
|
* @param {string} method HTTP method.
|
1097
1312
|
* @param {string|RegExp} url HTTP url.
|
1098
|
-
* @param {(string|RegExp)=} data HTTP request body
|
1313
|
+
* @param {(string|RegExp|function(string)|Object)=} data HTTP request body or function that
|
1314
|
+
* receives data string and returns true if the data is as expected, or Object if request body
|
1315
|
+
* is in JSON format.
|
1099
1316
|
* @param {(Object|function(Object))=} headers HTTP headers or function that receives http header
|
1100
1317
|
* object and returns true if the headers match the current expectation.
|
1101
1318
|
* @returns {requestHandler} Returns an object with `respond` method that control how a matched
|
1102
1319
|
* request is handled.
|
1103
1320
|
*
|
1104
|
-
* - respond –
|
1321
|
+
* - respond –
|
1322
|
+
* `{function([status,] data[, headers])|function(function(method, url, data, headers)}`
|
1105
1323
|
* – The respond method takes a set of static data to be returned or a function that can return
|
1106
1324
|
* an array containing response status (number), response data (string) and response headers
|
1107
1325
|
* (Object).
|
@@ -1164,7 +1382,9 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
|
|
1164
1382
|
* Creates a new request expectation for POST requests. For more info see `expect()`.
|
1165
1383
|
*
|
1166
1384
|
* @param {string|RegExp} url HTTP url.
|
1167
|
-
* @param {(string|RegExp)=} data HTTP request body
|
1385
|
+
* @param {(string|RegExp|function(string)|Object)=} data HTTP request body or function that
|
1386
|
+
* receives data string and returns true if the data is as expected, or Object if request body
|
1387
|
+
* is in JSON format.
|
1168
1388
|
* @param {Object=} headers HTTP headers.
|
1169
1389
|
* @returns {requestHandler} Returns an object with `respond` method that control how a matched
|
1170
1390
|
* request is handled.
|
@@ -1178,7 +1398,9 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
|
|
1178
1398
|
* Creates a new request expectation for PUT requests. For more info see `expect()`.
|
1179
1399
|
*
|
1180
1400
|
* @param {string|RegExp} url HTTP url.
|
1181
|
-
* @param {(string|RegExp)=} data HTTP request body
|
1401
|
+
* @param {(string|RegExp|function(string)|Object)=} data HTTP request body or function that
|
1402
|
+
* receives data string and returns true if the data is as expected, or Object if request body
|
1403
|
+
* is in JSON format.
|
1182
1404
|
* @param {Object=} headers HTTP headers.
|
1183
1405
|
* @returns {requestHandler} Returns an object with `respond` method that control how a matched
|
1184
1406
|
* request is handled.
|
@@ -1192,7 +1414,9 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
|
|
1192
1414
|
* Creates a new request expectation for PATCH requests. For more info see `expect()`.
|
1193
1415
|
*
|
1194
1416
|
* @param {string|RegExp} url HTTP url.
|
1195
|
-
* @param {(string|RegExp)=} data HTTP request body
|
1417
|
+
* @param {(string|RegExp|function(string)|Object)=} data HTTP request body or function that
|
1418
|
+
* receives data string and returns true if the data is as expected, or Object if request body
|
1419
|
+
* is in JSON format.
|
1196
1420
|
* @param {Object=} headers HTTP headers.
|
1197
1421
|
* @returns {requestHandler} Returns an object with `respond` method that control how a matched
|
1198
1422
|
* request is handled.
|
@@ -1225,11 +1449,11 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
|
|
1225
1449
|
*/
|
1226
1450
|
$httpBackend.flush = function(count) {
|
1227
1451
|
$rootScope.$digest();
|
1228
|
-
if (!responses.length) throw Error('No pending request to flush !');
|
1452
|
+
if (!responses.length) throw new Error('No pending request to flush !');
|
1229
1453
|
|
1230
1454
|
if (angular.isDefined(count)) {
|
1231
1455
|
while (count--) {
|
1232
|
-
if (!responses.length) throw Error('No more pending request to flush !');
|
1456
|
+
if (!responses.length) throw new Error('No more pending request to flush !');
|
1233
1457
|
responses.shift()();
|
1234
1458
|
}
|
1235
1459
|
} else {
|
@@ -1253,13 +1477,13 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
|
|
1253
1477
|
* "afterEach" clause.
|
1254
1478
|
*
|
1255
1479
|
* <pre>
|
1256
|
-
* afterEach($httpBackend.
|
1480
|
+
* afterEach($httpBackend.verifyNoOutstandingExpectation);
|
1257
1481
|
* </pre>
|
1258
1482
|
*/
|
1259
1483
|
$httpBackend.verifyNoOutstandingExpectation = function() {
|
1260
1484
|
$rootScope.$digest();
|
1261
1485
|
if (expectations.length) {
|
1262
|
-
throw Error('Unsatisfied requests: ' + expectations.join(', '));
|
1486
|
+
throw new Error('Unsatisfied requests: ' + expectations.join(', '));
|
1263
1487
|
}
|
1264
1488
|
};
|
1265
1489
|
|
@@ -1280,7 +1504,7 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
|
|
1280
1504
|
*/
|
1281
1505
|
$httpBackend.verifyNoOutstandingRequest = function() {
|
1282
1506
|
if (responses.length) {
|
1283
|
-
throw Error('Unflushed requests: ' + responses.length);
|
1507
|
+
throw new Error('Unflushed requests: ' + responses.length);
|
1284
1508
|
}
|
1285
1509
|
};
|
1286
1510
|
|
@@ -1305,14 +1529,14 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
|
|
1305
1529
|
function createShortMethods(prefix) {
|
1306
1530
|
angular.forEach(['GET', 'DELETE', 'JSONP'], function(method) {
|
1307
1531
|
$httpBackend[prefix + method] = function(url, headers) {
|
1308
|
-
return $httpBackend[prefix](method, url, undefined, headers)
|
1309
|
-
}
|
1532
|
+
return $httpBackend[prefix](method, url, undefined, headers);
|
1533
|
+
};
|
1310
1534
|
});
|
1311
1535
|
|
1312
1536
|
angular.forEach(['PUT', 'POST', 'PATCH'], function(method) {
|
1313
1537
|
$httpBackend[prefix + method] = function(url, data, headers) {
|
1314
|
-
return $httpBackend[prefix](method, url, data, headers)
|
1315
|
-
}
|
1538
|
+
return $httpBackend[prefix](method, url, data, headers);
|
1539
|
+
};
|
1316
1540
|
});
|
1317
1541
|
}
|
1318
1542
|
}
|
@@ -1345,7 +1569,8 @@ function MockHttpExpectation(method, url, data, headers) {
|
|
1345
1569
|
this.matchData = function(d) {
|
1346
1570
|
if (angular.isUndefined(data)) return true;
|
1347
1571
|
if (data && angular.isFunction(data.test)) return data.test(d);
|
1348
|
-
if (data &&
|
1572
|
+
if (data && angular.isFunction(data)) return data(d);
|
1573
|
+
if (data && !angular.isString(data)) return angular.equals(data, angular.fromJson(d));
|
1349
1574
|
return data == d;
|
1350
1575
|
};
|
1351
1576
|
|
@@ -1376,7 +1601,8 @@ function MockXhr() {
|
|
1376
1601
|
};
|
1377
1602
|
|
1378
1603
|
this.getResponseHeader = function(name) {
|
1379
|
-
// the lookup must be case insensitive,
|
1604
|
+
// the lookup must be case insensitive,
|
1605
|
+
// that's why we try two quick lookups first and full scan last
|
1380
1606
|
var header = this.$$respHeaders[name];
|
1381
1607
|
if (header) return header;
|
1382
1608
|
|
@@ -1411,7 +1637,7 @@ function MockXhr() {
|
|
1411
1637
|
*
|
1412
1638
|
* This service is just a simple decorator for {@link ng.$timeout $timeout} service
|
1413
1639
|
* that adds a "flush" and "verifyNoPendingTasks" methods.
|
1414
|
-
*/
|
1640
|
+
*/
|
1415
1641
|
|
1416
1642
|
angular.mock.$TimeoutDecorator = function($delegate, $browser) {
|
1417
1643
|
|
@@ -1422,9 +1648,11 @@ angular.mock.$TimeoutDecorator = function($delegate, $browser) {
|
|
1422
1648
|
* @description
|
1423
1649
|
*
|
1424
1650
|
* Flushes the queue of pending tasks.
|
1651
|
+
*
|
1652
|
+
* @param {number=} delay maximum timeout amount to flush up until
|
1425
1653
|
*/
|
1426
|
-
$delegate.flush = function() {
|
1427
|
-
$browser.defer.flush();
|
1654
|
+
$delegate.flush = function(delay) {
|
1655
|
+
$browser.defer.flush(delay);
|
1428
1656
|
};
|
1429
1657
|
|
1430
1658
|
/**
|
@@ -1437,7 +1665,7 @@ angular.mock.$TimeoutDecorator = function($delegate, $browser) {
|
|
1437
1665
|
*/
|
1438
1666
|
$delegate.verifyNoPendingTasks = function() {
|
1439
1667
|
if ($browser.deferredFns.length) {
|
1440
|
-
throw Error('Deferred tasks to flush (' + $browser.deferredFns.length + '): ' +
|
1668
|
+
throw new Error('Deferred tasks to flush (' + $browser.deferredFns.length + '): ' +
|
1441
1669
|
formatPendingTasksAsString($browser.deferredFns));
|
1442
1670
|
}
|
1443
1671
|
};
|
@@ -1460,7 +1688,7 @@ angular.mock.$TimeoutDecorator = function($delegate, $browser) {
|
|
1460
1688
|
angular.mock.$RootElementProvider = function() {
|
1461
1689
|
this.$get = function() {
|
1462
1690
|
return angular.element('<div ng-app></div>');
|
1463
|
-
}
|
1691
|
+
};
|
1464
1692
|
};
|
1465
1693
|
|
1466
1694
|
/**
|
@@ -1468,18 +1696,27 @@ angular.mock.$RootElementProvider = function() {
|
|
1468
1696
|
* @name ngMock
|
1469
1697
|
* @description
|
1470
1698
|
*
|
1471
|
-
*
|
1472
|
-
*
|
1699
|
+
* # ngMock
|
1700
|
+
*
|
1701
|
+
* The `ngMock` module providers support to inject and mock Angular services into unit tests.
|
1702
|
+
* In addition, ngMock also extends various core ng services such that they can be
|
1703
|
+
* inspected and controlled in a synchronous manner within test code.
|
1704
|
+
*
|
1705
|
+
* {@installModule mocks}
|
1706
|
+
*
|
1707
|
+
* <div doc-module-components="ngMock"></div>
|
1708
|
+
*
|
1473
1709
|
*/
|
1474
1710
|
angular.module('ngMock', ['ng']).provider({
|
1475
1711
|
$browser: angular.mock.$BrowserProvider,
|
1476
1712
|
$exceptionHandler: angular.mock.$ExceptionHandlerProvider,
|
1477
1713
|
$log: angular.mock.$LogProvider,
|
1714
|
+
$interval: angular.mock.$IntervalProvider,
|
1478
1715
|
$httpBackend: angular.mock.$HttpBackendProvider,
|
1479
1716
|
$rootElement: angular.mock.$RootElementProvider
|
1480
|
-
}).config(function($provide) {
|
1717
|
+
}).config(['$provide', function($provide) {
|
1481
1718
|
$provide.decorator('$timeout', angular.mock.$TimeoutDecorator);
|
1482
|
-
});
|
1719
|
+
}]);
|
1483
1720
|
|
1484
1721
|
/**
|
1485
1722
|
* @ngdoc overview
|
@@ -1490,9 +1727,9 @@ angular.module('ngMock', ['ng']).provider({
|
|
1490
1727
|
* Currently there is only one mock present in this module -
|
1491
1728
|
* the {@link ngMockE2E.$httpBackend e2e $httpBackend} mock.
|
1492
1729
|
*/
|
1493
|
-
angular.module('ngMockE2E', ['ng']).config(function($provide) {
|
1730
|
+
angular.module('ngMockE2E', ['ng']).config(['$provide', function($provide) {
|
1494
1731
|
$provide.decorator('$httpBackend', angular.mock.e2e.$httpBackendDecorator);
|
1495
|
-
});
|
1732
|
+
}]);
|
1496
1733
|
|
1497
1734
|
/**
|
1498
1735
|
* @ngdoc object
|
@@ -1532,7 +1769,7 @@ angular.module('ngMockE2E', ['ng']).config(function($provide) {
|
|
1532
1769
|
*
|
1533
1770
|
* // adds a new phone to the phones array
|
1534
1771
|
* $httpBackend.whenPOST('/phones').respond(function(method, url, data) {
|
1535
|
-
* phones.push(angular.
|
1772
|
+
* phones.push(angular.fromJson(data));
|
1536
1773
|
* });
|
1537
1774
|
* $httpBackend.whenGET(/^\/templates\//).passThrough();
|
1538
1775
|
* //...
|
@@ -1557,7 +1794,8 @@ angular.module('ngMockE2E', ['ng']).config(function($provide) {
|
|
1557
1794
|
* @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that
|
1558
1795
|
* control how a matched request is handled.
|
1559
1796
|
*
|
1560
|
-
* - respond –
|
1797
|
+
* - respond –
|
1798
|
+
* `{function([status,] data[, headers])|function(function(method, url, data, headers)}`
|
1561
1799
|
* – The respond method takes a set of static data to be returned or a function that can return
|
1562
1800
|
* an array containing response status (number), response data (string) and response headers
|
1563
1801
|
* (Object).
|
@@ -1659,7 +1897,8 @@ angular.module('ngMockE2E', ['ng']).config(function($provide) {
|
|
1659
1897
|
* control how a matched request is handled.
|
1660
1898
|
*/
|
1661
1899
|
angular.mock.e2e = {};
|
1662
|
-
angular.mock.e2e.$httpBackendDecorator =
|
1900
|
+
angular.mock.e2e.$httpBackendDecorator =
|
1901
|
+
['$rootScope', '$delegate', '$browser', createHttpBackendMock];
|
1663
1902
|
|
1664
1903
|
|
1665
1904
|
angular.mock.clearDataCache = function() {
|
@@ -1667,36 +1906,24 @@ angular.mock.clearDataCache = function() {
|
|
1667
1906
|
cache = angular.element.cache;
|
1668
1907
|
|
1669
1908
|
for(key in cache) {
|
1670
|
-
if (
|
1909
|
+
if (Object.prototype.hasOwnProperty.call(cache,key)) {
|
1671
1910
|
var handle = cache[key].handle;
|
1672
1911
|
|
1673
|
-
handle && angular.element(handle.elem).
|
1912
|
+
handle && angular.element(handle.elem).off();
|
1674
1913
|
delete cache[key];
|
1675
1914
|
}
|
1676
1915
|
}
|
1677
1916
|
};
|
1678
1917
|
|
1679
1918
|
|
1680
|
-
window.jstestdriver && (function(window) {
|
1681
|
-
/**
|
1682
|
-
* Global method to output any number of objects into JSTD console. Useful for debugging.
|
1683
|
-
*/
|
1684
|
-
window.dump = function() {
|
1685
|
-
var args = [];
|
1686
|
-
angular.forEach(arguments, function(arg) {
|
1687
|
-
args.push(angular.mock.dump(arg));
|
1688
|
-
});
|
1689
|
-
jstestdriver.console.log.apply(jstestdriver.console, args);
|
1690
|
-
if (window.console) {
|
1691
|
-
window.console.log.apply(window.console, args);
|
1692
|
-
}
|
1693
|
-
};
|
1694
|
-
})(window);
|
1695
1919
|
|
1920
|
+
if(window.jasmine || window.mocha) {
|
1696
1921
|
|
1697
|
-
|
1922
|
+
var currentSpec = null,
|
1923
|
+
isSpecRunning = function() {
|
1924
|
+
return currentSpec && (window.mocha || currentSpec.queue.running);
|
1925
|
+
};
|
1698
1926
|
|
1699
|
-
var currentSpec = null;
|
1700
1927
|
|
1701
1928
|
beforeEach(function() {
|
1702
1929
|
currentSpec = this;
|
@@ -1710,7 +1937,7 @@ window.jstestdriver && (function(window) {
|
|
1710
1937
|
currentSpec = null;
|
1711
1938
|
|
1712
1939
|
if (injector) {
|
1713
|
-
injector.get('$rootElement').
|
1940
|
+
injector.get('$rootElement').off();
|
1714
1941
|
injector.get('$browser').pollFns.length = 0;
|
1715
1942
|
}
|
1716
1943
|
|
@@ -1729,10 +1956,6 @@ window.jstestdriver && (function(window) {
|
|
1729
1956
|
angular.callbacks.counter = 0;
|
1730
1957
|
});
|
1731
1958
|
|
1732
|
-
function isSpecRunning() {
|
1733
|
-
return currentSpec && (window.mocha || currentSpec.queue.running);
|
1734
|
-
}
|
1735
|
-
|
1736
1959
|
/**
|
1737
1960
|
* @ngdoc function
|
1738
1961
|
* @name angular.mock.module
|
@@ -1745,9 +1968,11 @@ window.jstestdriver && (function(window) {
|
|
1745
1968
|
*
|
1746
1969
|
* See {@link angular.mock.inject inject} for usage example
|
1747
1970
|
*
|
1748
|
-
* @param {...(string|Function)} fns any number of modules which are represented as string
|
1971
|
+
* @param {...(string|Function|Object)} fns any number of modules which are represented as string
|
1749
1972
|
* aliases or as anonymous module initialization functions. The modules are used to
|
1750
|
-
* configure the injector. The 'ng' and 'ngMock' modules are automatically loaded.
|
1973
|
+
* configure the injector. The 'ng' and 'ngMock' modules are automatically loaded. If an
|
1974
|
+
* object literal is passed they will be register as values in the module, the key being
|
1975
|
+
* the module name and the value being what is returned.
|
1751
1976
|
*/
|
1752
1977
|
window.module = angular.mock.module = function() {
|
1753
1978
|
var moduleFns = Array.prototype.slice.call(arguments, 0);
|
@@ -1755,11 +1980,19 @@ window.jstestdriver && (function(window) {
|
|
1755
1980
|
/////////////////////
|
1756
1981
|
function workFn() {
|
1757
1982
|
if (currentSpec.$injector) {
|
1758
|
-
throw Error('Injector already created, can not register a module!');
|
1983
|
+
throw new Error('Injector already created, can not register a module!');
|
1759
1984
|
} else {
|
1760
1985
|
var modules = currentSpec.$modules || (currentSpec.$modules = []);
|
1761
1986
|
angular.forEach(moduleFns, function(module) {
|
1762
|
-
|
1987
|
+
if (angular.isObject(module) && !angular.isArray(module)) {
|
1988
|
+
modules.push(function($provide) {
|
1989
|
+
angular.forEach(module, function(value, key) {
|
1990
|
+
$provide.value(key, value);
|
1991
|
+
});
|
1992
|
+
});
|
1993
|
+
} else {
|
1994
|
+
modules.push(module);
|
1995
|
+
}
|
1763
1996
|
});
|
1764
1997
|
}
|
1765
1998
|
}
|
@@ -1776,8 +2009,40 @@ window.jstestdriver && (function(window) {
|
|
1776
2009
|
* instance of {@link AUTO.$injector $injector} per test, which is then used for
|
1777
2010
|
* resolving references.
|
1778
2011
|
*
|
1779
|
-
* See also {@link angular.mock.module module}
|
1780
2012
|
*
|
2013
|
+
* ## Resolving References (Underscore Wrapping)
|
2014
|
+
* Often, we would like to inject a reference once, in a `beforeEach()` block and reuse this
|
2015
|
+
* in multiple `it()` clauses. To be able to do this we must assign the reference to a variable
|
2016
|
+
* that is declared in the scope of the `describe()` block. Since we would, most likely, want
|
2017
|
+
* the variable to have the same name of the reference we have a problem, since the parameter
|
2018
|
+
* to the `inject()` function would hide the outer variable.
|
2019
|
+
*
|
2020
|
+
* To help with this, the injected parameters can, optionally, be enclosed with underscores.
|
2021
|
+
* These are ignored by the injector when the reference name is resolved.
|
2022
|
+
*
|
2023
|
+
* For example, the parameter `_myService_` would be resolved as the reference `myService`.
|
2024
|
+
* Since it is available in the function body as _myService_, we can then assign it to a variable
|
2025
|
+
* defined in an outer scope.
|
2026
|
+
*
|
2027
|
+
* ```
|
2028
|
+
* // Defined out reference variable outside
|
2029
|
+
* var myService;
|
2030
|
+
*
|
2031
|
+
* // Wrap the parameter in underscores
|
2032
|
+
* beforeEach( inject( function(_myService_){
|
2033
|
+
* myService = _myService_;
|
2034
|
+
* }));
|
2035
|
+
*
|
2036
|
+
* // Use myService in a series of tests.
|
2037
|
+
* it('makes use of myService', function() {
|
2038
|
+
* myService.doStuff();
|
2039
|
+
* });
|
2040
|
+
*
|
2041
|
+
* ```
|
2042
|
+
*
|
2043
|
+
* See also {@link angular.mock.module angular.mock.module}
|
2044
|
+
*
|
2045
|
+
* ## Example
|
1781
2046
|
* Example of what a typical jasmine tests looks like with the inject method.
|
1782
2047
|
* <pre>
|
1783
2048
|
*
|
@@ -1810,7 +2075,7 @@ window.jstestdriver && (function(window) {
|
|
1810
2075
|
* inject(function(version) {
|
1811
2076
|
* expect(version).toEqual('overridden');
|
1812
2077
|
* });
|
1813
|
-
* )
|
2078
|
+
* });
|
1814
2079
|
* });
|
1815
2080
|
*
|
1816
2081
|
* </pre>
|
@@ -1833,7 +2098,9 @@ window.jstestdriver && (function(window) {
|
|
1833
2098
|
}
|
1834
2099
|
for(var i = 0, ii = blockFns.length; i < ii; i++) {
|
1835
2100
|
try {
|
2101
|
+
/* jshint -W040 *//* Jasmine explicitly provides a `this` object when calling functions */
|
1836
2102
|
injector.invoke(blockFns[i] || angular.noop, this);
|
2103
|
+
/* jshint +W040 */
|
1837
2104
|
} catch (e) {
|
1838
2105
|
if(e.stack && errorForStack) e.stack += '\n' + errorForStack.stack;
|
1839
2106
|
throw e;
|
@@ -1843,4 +2110,7 @@ window.jstestdriver && (function(window) {
|
|
1843
2110
|
}
|
1844
2111
|
}
|
1845
2112
|
};
|
1846
|
-
}
|
2113
|
+
}
|
2114
|
+
|
2115
|
+
|
2116
|
+
})(window, window.angular);
|