angularjs-rails 1.2.14 → 1.2.15
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/lib/angularjs-rails/version.rb +2 -2
- data/vendor/assets/javascripts/angular-animate.js +4 -5
- data/vendor/assets/javascripts/angular-cookies.js +8 -9
- data/vendor/assets/javascripts/angular-loader.js +6 -8
- data/vendor/assets/javascripts/angular-mocks.js +10 -11
- data/vendor/assets/javascripts/angular-resource.js +13 -3
- data/vendor/assets/javascripts/angular-route.js +139 -134
- data/vendor/assets/javascripts/angular-sanitize.js +2 -2
- data/vendor/assets/javascripts/angular-scenario.js +190 -81
- data/vendor/assets/javascripts/angular-touch.js +16 -2
- data/vendor/assets/javascripts/angular.js +196 -81
- data/vendor/assets/javascripts/unstable/angular-animate.js +1613 -0
- data/vendor/assets/javascripts/unstable/angular-cookies.js +40 -29
- data/vendor/assets/javascripts/unstable/angular-loader.js +166 -58
- data/vendor/assets/javascripts/unstable/angular-mocks.js +832 -535
- data/vendor/assets/javascripts/unstable/angular-resource.js +266 -196
- data/vendor/assets/javascripts/unstable/angular-route.js +927 -0
- data/vendor/assets/javascripts/unstable/angular-sanitize.js +246 -180
- data/vendor/assets/javascripts/unstable/angular-scenario.js +19167 -13895
- data/vendor/assets/javascripts/unstable/{angular-mobile.js → angular-touch.js} +241 -126
- data/vendor/assets/javascripts/unstable/angular.js +12891 -8032
- metadata +5 -3
@@ -1,13 +1,14 @@
|
|
1
1
|
/**
|
2
|
-
* @license AngularJS v1.
|
3
|
-
* (c) 2010-
|
2
|
+
* @license AngularJS v1.3.0-beta.3
|
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
|
-
* @ngdoc
|
11
|
+
* @ngdoc object
|
11
12
|
* @name angular.mock
|
12
13
|
* @description
|
13
14
|
*
|
@@ -18,7 +19,7 @@ angular.mock = {};
|
|
18
19
|
/**
|
19
20
|
* ! This is a private undocumented service !
|
20
21
|
*
|
21
|
-
* @name
|
22
|
+
* @name $browser
|
22
23
|
*
|
23
24
|
* @description
|
24
25
|
* This service is a mock implementation of {@link ng.$browser}. It provides fake
|
@@ -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,12 @@ angular.mock.$Browser = function() {
|
|
75
76
|
};
|
76
77
|
|
77
78
|
|
79
|
+
/**
|
80
|
+
* @name $browser#defer.now
|
81
|
+
*
|
82
|
+
* @description
|
83
|
+
* Current milliseconds mock time.
|
84
|
+
*/
|
78
85
|
self.defer.now = 0;
|
79
86
|
|
80
87
|
|
@@ -95,8 +102,7 @@ angular.mock.$Browser = function() {
|
|
95
102
|
|
96
103
|
|
97
104
|
/**
|
98
|
-
* @name
|
99
|
-
* @methodOf ngMock.$browser
|
105
|
+
* @name $browser#defer.flush
|
100
106
|
*
|
101
107
|
* @description
|
102
108
|
* Flushes all pending requests and executes the defer callbacks.
|
@@ -110,7 +116,7 @@ angular.mock.$Browser = function() {
|
|
110
116
|
if (self.deferredFns.length) {
|
111
117
|
self.defer.now = self.deferredFns[self.deferredFns.length-1].time;
|
112
118
|
} else {
|
113
|
-
throw Error('No deferred tasks to be flushed');
|
119
|
+
throw new Error('No deferred tasks to be flushed');
|
114
120
|
}
|
115
121
|
}
|
116
122
|
|
@@ -118,13 +124,6 @@ angular.mock.$Browser = function() {
|
|
118
124
|
self.deferredFns.shift().fn();
|
119
125
|
}
|
120
126
|
};
|
121
|
-
/**
|
122
|
-
* @name ngMock.$browser#defer.now
|
123
|
-
* @propertyOf ngMock.$browser
|
124
|
-
*
|
125
|
-
* @description
|
126
|
-
* Current milliseconds mock time.
|
127
|
-
*/
|
128
127
|
|
129
128
|
self.$$baseHref = '';
|
130
129
|
self.baseHref = function() {
|
@@ -134,8 +133,7 @@ angular.mock.$Browser = function() {
|
|
134
133
|
angular.mock.$Browser.prototype = {
|
135
134
|
|
136
135
|
/**
|
137
|
-
* @name
|
138
|
-
* @methodOf ngMock.$browser
|
136
|
+
* @name $browser#poll
|
139
137
|
*
|
140
138
|
* @description
|
141
139
|
* run all fns in pollFns
|
@@ -162,7 +160,7 @@ angular.mock.$Browser.prototype = {
|
|
162
160
|
|
163
161
|
cookies: function(name, value) {
|
164
162
|
if (name) {
|
165
|
-
if (value
|
163
|
+
if (angular.isUndefined(value)) {
|
166
164
|
delete this.cookieHash[name];
|
167
165
|
} else {
|
168
166
|
if (angular.isString(value) && //strings only
|
@@ -186,17 +184,17 @@ angular.mock.$Browser.prototype = {
|
|
186
184
|
|
187
185
|
|
188
186
|
/**
|
189
|
-
* @ngdoc
|
190
|
-
* @name
|
187
|
+
* @ngdoc provider
|
188
|
+
* @name $exceptionHandlerProvider
|
191
189
|
*
|
192
190
|
* @description
|
193
|
-
* Configures the mock implementation of {@link ng.$exceptionHandler} to rethrow or to log errors
|
194
|
-
* into the `$exceptionHandler`.
|
191
|
+
* Configures the mock implementation of {@link ng.$exceptionHandler} to rethrow or to log errors
|
192
|
+
* passed into the `$exceptionHandler`.
|
195
193
|
*/
|
196
194
|
|
197
195
|
/**
|
198
|
-
* @ngdoc
|
199
|
-
* @name
|
196
|
+
* @ngdoc service
|
197
|
+
* @name $exceptionHandler
|
200
198
|
*
|
201
199
|
* @description
|
202
200
|
* Mock implementation of {@link ng.$exceptionHandler} that rethrows or logs errors passed
|
@@ -204,7 +202,7 @@ angular.mock.$Browser.prototype = {
|
|
204
202
|
* information.
|
205
203
|
*
|
206
204
|
*
|
207
|
-
*
|
205
|
+
* ```js
|
208
206
|
* describe('$exceptionHandlerProvider', function() {
|
209
207
|
*
|
210
208
|
* it('should capture log messages and exceptions', function() {
|
@@ -225,7 +223,7 @@ angular.mock.$Browser.prototype = {
|
|
225
223
|
* });
|
226
224
|
* });
|
227
225
|
* });
|
228
|
-
*
|
226
|
+
* ```
|
229
227
|
*/
|
230
228
|
|
231
229
|
angular.mock.$ExceptionHandlerProvider = function() {
|
@@ -233,8 +231,7 @@ angular.mock.$ExceptionHandlerProvider = function() {
|
|
233
231
|
|
234
232
|
/**
|
235
233
|
* @ngdoc method
|
236
|
-
* @name
|
237
|
-
* @methodOf ngMock.$exceptionHandlerProvider
|
234
|
+
* @name $exceptionHandlerProvider#mode
|
238
235
|
*
|
239
236
|
* @description
|
240
237
|
* Sets the logging mode.
|
@@ -244,10 +241,10 @@ angular.mock.$ExceptionHandlerProvider = function() {
|
|
244
241
|
* - `rethrow`: If any errors are passed into the handler in tests, it typically
|
245
242
|
* means that there is a bug in the application or test, so this mock will
|
246
243
|
* 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
|
-
*
|
244
|
+
* - `log`: Sometimes it is desirable to test that an error is thrown, for this case the `log`
|
245
|
+
* mode stores an array of errors in `$exceptionHandler.errors`, to allow later
|
246
|
+
* assertion of them. See {@link ngMock.$log#assertEmpty assertEmpty()} and
|
247
|
+
* {@link ngMock.$log#reset reset()}
|
251
248
|
*/
|
252
249
|
this.mode = function(mode) {
|
253
250
|
switch(mode) {
|
@@ -270,7 +267,7 @@ angular.mock.$ExceptionHandlerProvider = function() {
|
|
270
267
|
handler.errors = errors;
|
271
268
|
break;
|
272
269
|
default:
|
273
|
-
throw Error("Unknown mode '" + mode + "', only 'log'/'rethrow' modes are allowed!");
|
270
|
+
throw new Error("Unknown mode '" + mode + "', only 'log'/'rethrow' modes are allowed!");
|
274
271
|
}
|
275
272
|
};
|
276
273
|
|
@@ -284,7 +281,7 @@ angular.mock.$ExceptionHandlerProvider = function() {
|
|
284
281
|
|
285
282
|
/**
|
286
283
|
* @ngdoc service
|
287
|
-
* @name
|
284
|
+
* @name $log
|
288
285
|
*
|
289
286
|
* @description
|
290
287
|
* Mock implementation of {@link ng.$log} that gathers all logged messages in arrays
|
@@ -293,24 +290,37 @@ angular.mock.$ExceptionHandlerProvider = function() {
|
|
293
290
|
*
|
294
291
|
*/
|
295
292
|
angular.mock.$LogProvider = function() {
|
293
|
+
var debug = true;
|
296
294
|
|
297
295
|
function concat(array1, array2, index) {
|
298
296
|
return array1.concat(Array.prototype.slice.call(array2, index));
|
299
297
|
}
|
300
298
|
|
299
|
+
this.debugEnabled = function(flag) {
|
300
|
+
if (angular.isDefined(flag)) {
|
301
|
+
debug = flag;
|
302
|
+
return this;
|
303
|
+
} else {
|
304
|
+
return debug;
|
305
|
+
}
|
306
|
+
};
|
301
307
|
|
302
308
|
this.$get = function () {
|
303
309
|
var $log = {
|
304
310
|
log: function() { $log.log.logs.push(concat([], arguments, 0)); },
|
305
311
|
warn: function() { $log.warn.logs.push(concat([], arguments, 0)); },
|
306
312
|
info: function() { $log.info.logs.push(concat([], arguments, 0)); },
|
307
|
-
error: function() { $log.error.logs.push(concat([], arguments, 0)); }
|
313
|
+
error: function() { $log.error.logs.push(concat([], arguments, 0)); },
|
314
|
+
debug: function() {
|
315
|
+
if (debug) {
|
316
|
+
$log.debug.logs.push(concat([], arguments, 0));
|
317
|
+
}
|
318
|
+
}
|
308
319
|
};
|
309
320
|
|
310
321
|
/**
|
311
322
|
* @ngdoc method
|
312
|
-
* @name
|
313
|
-
* @methodOf ngMock.$log
|
323
|
+
* @name $log#reset
|
314
324
|
*
|
315
325
|
* @description
|
316
326
|
* Reset all of the logging arrays to empty.
|
@@ -318,86 +328,97 @@ angular.mock.$LogProvider = function() {
|
|
318
328
|
$log.reset = function () {
|
319
329
|
/**
|
320
330
|
* @ngdoc property
|
321
|
-
* @name
|
322
|
-
* @propertyOf ngMock.$log
|
331
|
+
* @name $log#log.logs
|
323
332
|
*
|
324
333
|
* @description
|
325
334
|
* Array of messages logged using {@link ngMock.$log#log}.
|
326
335
|
*
|
327
336
|
* @example
|
328
|
-
*
|
337
|
+
* ```js
|
329
338
|
* $log.log('Some Log');
|
330
339
|
* var first = $log.log.logs.unshift();
|
331
|
-
*
|
340
|
+
* ```
|
332
341
|
*/
|
333
342
|
$log.log.logs = [];
|
334
343
|
/**
|
335
344
|
* @ngdoc property
|
336
|
-
* @name
|
337
|
-
* @propertyOf ngMock.$log
|
345
|
+
* @name $log#info.logs
|
338
346
|
*
|
339
347
|
* @description
|
340
|
-
* Array of messages logged using {@link ngMock.$log#
|
348
|
+
* Array of messages logged using {@link ngMock.$log#info}.
|
341
349
|
*
|
342
350
|
* @example
|
343
|
-
*
|
344
|
-
* $log.
|
345
|
-
* var first = $log.
|
346
|
-
*
|
351
|
+
* ```js
|
352
|
+
* $log.info('Some Info');
|
353
|
+
* var first = $log.info.logs.unshift();
|
354
|
+
* ```
|
347
355
|
*/
|
348
|
-
$log.
|
356
|
+
$log.info.logs = [];
|
349
357
|
/**
|
350
358
|
* @ngdoc property
|
351
|
-
* @name
|
352
|
-
* @propertyOf ngMock.$log
|
359
|
+
* @name $log#warn.logs
|
353
360
|
*
|
354
361
|
* @description
|
355
|
-
* Array of messages logged using {@link ngMock.$log#
|
362
|
+
* Array of messages logged using {@link ngMock.$log#warn}.
|
356
363
|
*
|
357
364
|
* @example
|
358
|
-
*
|
359
|
-
* $log.
|
360
|
-
* var first = $log.
|
361
|
-
*
|
365
|
+
* ```js
|
366
|
+
* $log.warn('Some Warning');
|
367
|
+
* var first = $log.warn.logs.unshift();
|
368
|
+
* ```
|
362
369
|
*/
|
363
|
-
$log.
|
370
|
+
$log.warn.logs = [];
|
364
371
|
/**
|
365
372
|
* @ngdoc property
|
366
|
-
* @name
|
367
|
-
* @propertyOf ngMock.$log
|
373
|
+
* @name $log#error.logs
|
368
374
|
*
|
369
375
|
* @description
|
370
376
|
* Array of messages logged using {@link ngMock.$log#error}.
|
371
377
|
*
|
372
378
|
* @example
|
373
|
-
*
|
374
|
-
* $log.
|
379
|
+
* ```js
|
380
|
+
* $log.error('Some Error');
|
375
381
|
* var first = $log.error.logs.unshift();
|
376
|
-
*
|
382
|
+
* ```
|
377
383
|
*/
|
378
384
|
$log.error.logs = [];
|
385
|
+
/**
|
386
|
+
* @ngdoc property
|
387
|
+
* @name $log#debug.logs
|
388
|
+
*
|
389
|
+
* @description
|
390
|
+
* Array of messages logged using {@link ngMock.$log#debug}.
|
391
|
+
*
|
392
|
+
* @example
|
393
|
+
* ```js
|
394
|
+
* $log.debug('Some Error');
|
395
|
+
* var first = $log.debug.logs.unshift();
|
396
|
+
* ```
|
397
|
+
*/
|
398
|
+
$log.debug.logs = [];
|
379
399
|
};
|
380
400
|
|
381
401
|
/**
|
382
402
|
* @ngdoc method
|
383
|
-
* @name
|
384
|
-
* @methodOf ngMock.$log
|
403
|
+
* @name $log#assertEmpty
|
385
404
|
*
|
386
405
|
* @description
|
387
|
-
* Assert that the all of the logging methods have no logged messages. If messages present, an
|
406
|
+
* Assert that the all of the logging methods have no logged messages. If messages present, an
|
407
|
+
* exception is thrown.
|
388
408
|
*/
|
389
409
|
$log.assertEmpty = function() {
|
390
410
|
var errors = [];
|
391
|
-
angular.forEach(['error', 'warn', 'info', 'log'], function(logLevel) {
|
411
|
+
angular.forEach(['error', 'warn', 'info', 'log', 'debug'], function(logLevel) {
|
392
412
|
angular.forEach($log[logLevel].logs, function(log) {
|
393
413
|
angular.forEach(log, function (logItem) {
|
394
|
-
errors.push('MOCK $log (' + logLevel + '): ' + String(logItem) + '\n' +
|
414
|
+
errors.push('MOCK $log (' + logLevel + '): ' + String(logItem) + '\n' +
|
415
|
+
(logItem.stack || ''));
|
395
416
|
});
|
396
417
|
});
|
397
418
|
});
|
398
419
|
if (errors.length) {
|
399
|
-
errors.unshift("Expected $log to be empty! Either a message was logged unexpectedly, or
|
400
|
-
"log message was not checked and removed:");
|
420
|
+
errors.unshift("Expected $log to be empty! Either a message was logged unexpectedly, or "+
|
421
|
+
"an expected log message was not checked and removed:");
|
401
422
|
errors.push('');
|
402
423
|
throw new Error(errors.join('\n---------\n'));
|
403
424
|
}
|
@@ -409,261 +430,382 @@ angular.mock.$LogProvider = function() {
|
|
409
430
|
};
|
410
431
|
|
411
432
|
|
412
|
-
|
413
|
-
|
433
|
+
/**
|
434
|
+
* @ngdoc service
|
435
|
+
* @name $interval
|
436
|
+
*
|
437
|
+
* @description
|
438
|
+
* Mock implementation of the $interval service.
|
439
|
+
*
|
440
|
+
* Use {@link ngMock.$interval#flush `$interval.flush(millis)`} to
|
441
|
+
* move forward by `millis` milliseconds and trigger any functions scheduled to run in that
|
442
|
+
* time.
|
443
|
+
*
|
444
|
+
* @param {function()} fn A function that should be called repeatedly.
|
445
|
+
* @param {number} delay Number of milliseconds between each function call.
|
446
|
+
* @param {number=} [count=0] Number of times to repeat. If not set, or 0, will repeat
|
447
|
+
* indefinitely.
|
448
|
+
* @param {boolean=} [invokeApply=true] If set to `false` skips model dirty checking, otherwise
|
449
|
+
* will invoke `fn` within the {@link ng.$rootScope.Scope#$apply $apply} block.
|
450
|
+
* @returns {promise} A promise which will be notified on each iteration.
|
451
|
+
*/
|
452
|
+
angular.mock.$IntervalProvider = function() {
|
453
|
+
this.$get = ['$rootScope', '$q',
|
454
|
+
function($rootScope, $q) {
|
455
|
+
var repeatFns = [],
|
456
|
+
nextRepeatId = 0,
|
457
|
+
now = 0;
|
458
|
+
|
459
|
+
var $interval = function(fn, delay, count, invokeApply) {
|
460
|
+
var deferred = $q.defer(),
|
461
|
+
promise = deferred.promise,
|
462
|
+
iteration = 0,
|
463
|
+
skipApply = (angular.isDefined(invokeApply) && !invokeApply);
|
464
|
+
|
465
|
+
count = (angular.isDefined(count)) ? count : 0,
|
466
|
+
promise.then(null, null, fn);
|
414
467
|
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
468
|
+
promise.$$intervalId = nextRepeatId;
|
469
|
+
|
470
|
+
function tick() {
|
471
|
+
deferred.notify(iteration++);
|
472
|
+
|
473
|
+
if (count > 0 && iteration >= count) {
|
474
|
+
var fnIndex;
|
475
|
+
deferred.resolve(iteration);
|
476
|
+
|
477
|
+
angular.forEach(repeatFns, function(fn, index) {
|
478
|
+
if (fn.id === promise.$$intervalId) fnIndex = index;
|
479
|
+
});
|
480
|
+
|
481
|
+
if (fnIndex !== undefined) {
|
482
|
+
repeatFns.splice(fnIndex, 1);
|
483
|
+
}
|
484
|
+
}
|
485
|
+
|
486
|
+
if (!skipApply) $rootScope.$apply();
|
424
487
|
}
|
425
|
-
|
426
|
-
|
427
|
-
|
488
|
+
|
489
|
+
repeatFns.push({
|
490
|
+
nextTime:(now + delay),
|
491
|
+
delay: delay,
|
492
|
+
fn: tick,
|
493
|
+
id: nextRepeatId,
|
494
|
+
deferred: deferred
|
495
|
+
});
|
496
|
+
repeatFns.sort(function(a,b){ return a.nextTime - b.nextTime;});
|
497
|
+
|
498
|
+
nextRepeatId++;
|
499
|
+
return promise;
|
500
|
+
};
|
501
|
+
/**
|
502
|
+
* @ngdoc method
|
503
|
+
* @name $interval#cancel
|
504
|
+
*
|
505
|
+
* @description
|
506
|
+
* Cancels a task associated with the `promise`.
|
507
|
+
*
|
508
|
+
* @param {promise} promise A promise from calling the `$interval` function.
|
509
|
+
* @returns {boolean} Returns `true` if the task was successfully cancelled.
|
510
|
+
*/
|
511
|
+
$interval.cancel = function(promise) {
|
512
|
+
if(!promise) return false;
|
513
|
+
var fnIndex;
|
514
|
+
|
515
|
+
angular.forEach(repeatFns, function(fn, index) {
|
516
|
+
if (fn.id === promise.$$intervalId) fnIndex = index;
|
517
|
+
});
|
518
|
+
|
519
|
+
if (fnIndex !== undefined) {
|
520
|
+
repeatFns[fnIndex].deferred.reject('canceled');
|
521
|
+
repeatFns.splice(fnIndex, 1);
|
522
|
+
return true;
|
523
|
+
}
|
524
|
+
|
525
|
+
return false;
|
526
|
+
};
|
527
|
+
|
528
|
+
/**
|
529
|
+
* @ngdoc method
|
530
|
+
* @name $interval#flush
|
531
|
+
* @description
|
532
|
+
*
|
533
|
+
* Runs interval tasks scheduled to be run in the next `millis` milliseconds.
|
534
|
+
*
|
535
|
+
* @param {number=} millis maximum timeout amount to flush up until.
|
536
|
+
*
|
537
|
+
* @return {number} The amount of time moved forward.
|
538
|
+
*/
|
539
|
+
$interval.flush = function(millis) {
|
540
|
+
now += millis;
|
541
|
+
while (repeatFns.length && repeatFns[0].nextTime <= now) {
|
542
|
+
var task = repeatFns[0];
|
543
|
+
task.fn();
|
544
|
+
task.nextTime += task.delay;
|
545
|
+
repeatFns.sort(function(a,b){ return a.nextTime - b.nextTime;});
|
546
|
+
}
|
547
|
+
return millis;
|
548
|
+
};
|
549
|
+
|
550
|
+
return $interval;
|
551
|
+
}];
|
552
|
+
};
|
553
|
+
|
554
|
+
|
555
|
+
/* jshint -W101 */
|
556
|
+
/* The R_ISO8061_STR regex is never going to fit into the 100 char limit!
|
557
|
+
* This directive should go inside the anonymous function but a bug in JSHint means that it would
|
558
|
+
* not be enacted early enough to prevent the warning.
|
559
|
+
*/
|
560
|
+
var R_ISO8061_STR = /^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?:\:?(\d\d)(?:\:?(\d\d)(?:\.(\d{3}))?)?)?(Z|([+-])(\d\d):?(\d\d)))?$/;
|
561
|
+
|
562
|
+
function jsonStringToDate(string) {
|
563
|
+
var match;
|
564
|
+
if (match = string.match(R_ISO8061_STR)) {
|
565
|
+
var date = new Date(0),
|
566
|
+
tzHour = 0,
|
567
|
+
tzMin = 0;
|
568
|
+
if (match[9]) {
|
569
|
+
tzHour = int(match[9] + match[10]);
|
570
|
+
tzMin = int(match[9] + match[11]);
|
428
571
|
}
|
429
|
-
|
572
|
+
date.setUTCFullYear(int(match[1]), int(match[2]) - 1, int(match[3]));
|
573
|
+
date.setUTCHours(int(match[4]||0) - tzHour,
|
574
|
+
int(match[5]||0) - tzMin,
|
575
|
+
int(match[6]||0),
|
576
|
+
int(match[7]||0));
|
577
|
+
return date;
|
430
578
|
}
|
579
|
+
return string;
|
580
|
+
}
|
581
|
+
|
582
|
+
function int(str) {
|
583
|
+
return parseInt(str, 10);
|
584
|
+
}
|
431
585
|
|
432
|
-
|
433
|
-
|
586
|
+
function padNumber(num, digits, trim) {
|
587
|
+
var neg = '';
|
588
|
+
if (num < 0) {
|
589
|
+
neg = '-';
|
590
|
+
num = -num;
|
434
591
|
}
|
592
|
+
num = '' + num;
|
593
|
+
while(num.length < digits) num = '0' + num;
|
594
|
+
if (trim)
|
595
|
+
num = num.substr(num.length - digits);
|
596
|
+
return neg + num;
|
597
|
+
}
|
435
598
|
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
599
|
+
|
600
|
+
/**
|
601
|
+
* @ngdoc type
|
602
|
+
* @name angular.mock.TzDate
|
603
|
+
* @description
|
604
|
+
*
|
605
|
+
* *NOTE*: this is not an injectable instance, just a globally available mock class of `Date`.
|
606
|
+
*
|
607
|
+
* Mock of the Date type which has its timezone specified via constructor arg.
|
608
|
+
*
|
609
|
+
* The main purpose is to create Date-like instances with timezone fixed to the specified timezone
|
610
|
+
* offset, so that we can test code that depends on local timezone settings without dependency on
|
611
|
+
* the time zone settings of the machine where the code is running.
|
612
|
+
*
|
613
|
+
* @param {number} offset Offset of the *desired* timezone in hours (fractions will be honored)
|
614
|
+
* @param {(number|string)} timestamp Timestamp representing the desired time in *UTC*
|
615
|
+
*
|
616
|
+
* @example
|
617
|
+
* !!!! WARNING !!!!!
|
618
|
+
* This is not a complete Date object so only methods that were implemented can be called safely.
|
619
|
+
* To make matters worse, TzDate instances inherit stuff from Date via a prototype.
|
620
|
+
*
|
621
|
+
* We do our best to intercept calls to "unimplemented" methods, but since the list of methods is
|
622
|
+
* incomplete we might be missing some non-standard methods. This can result in errors like:
|
623
|
+
* "Date.prototype.foo called on incompatible Object".
|
624
|
+
*
|
625
|
+
* ```js
|
626
|
+
* var newYearInBratislava = new TzDate(-1, '2009-12-31T23:00:00Z');
|
627
|
+
* newYearInBratislava.getTimezoneOffset() => -60;
|
628
|
+
* newYearInBratislava.getFullYear() => 2010;
|
629
|
+
* newYearInBratislava.getMonth() => 0;
|
630
|
+
* newYearInBratislava.getDate() => 1;
|
631
|
+
* newYearInBratislava.getHours() => 0;
|
632
|
+
* newYearInBratislava.getMinutes() => 0;
|
633
|
+
* newYearInBratislava.getSeconds() => 0;
|
634
|
+
* ```
|
635
|
+
*
|
636
|
+
*/
|
637
|
+
angular.mock.TzDate = function (offset, timestamp) {
|
638
|
+
var self = new Date(0);
|
639
|
+
if (angular.isString(timestamp)) {
|
640
|
+
var tsStr = timestamp;
|
641
|
+
|
642
|
+
self.origDate = jsonStringToDate(timestamp);
|
643
|
+
|
644
|
+
timestamp = self.origDate.getTime();
|
645
|
+
if (isNaN(timestamp))
|
646
|
+
throw {
|
647
|
+
name: "Illegal Argument",
|
648
|
+
message: "Arg '" + tsStr + "' passed into TzDate constructor is not a valid date string"
|
649
|
+
};
|
650
|
+
} else {
|
651
|
+
self.origDate = new Date(timestamp);
|
447
652
|
}
|
448
653
|
|
654
|
+
var localOffset = new Date(timestamp).getTimezoneOffset();
|
655
|
+
self.offsetDiff = localOffset*60*1000 - offset*1000*60*60;
|
656
|
+
self.date = new Date(timestamp + self.offsetDiff);
|
449
657
|
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
* @description
|
454
|
-
*
|
455
|
-
* *NOTE*: this is not an injectable instance, just a globally available mock class of `Date`.
|
456
|
-
*
|
457
|
-
* Mock of the Date type which has its timezone specified via constructor arg.
|
458
|
-
*
|
459
|
-
* The main purpose is to create Date-like instances with timezone fixed to the specified timezone
|
460
|
-
* offset, so that we can test code that depends on local timezone settings without dependency on
|
461
|
-
* the time zone settings of the machine where the code is running.
|
462
|
-
*
|
463
|
-
* @param {number} offset Offset of the *desired* timezone in hours (fractions will be honored)
|
464
|
-
* @param {(number|string)} timestamp Timestamp representing the desired time in *UTC*
|
465
|
-
*
|
466
|
-
* @example
|
467
|
-
* !!!! WARNING !!!!!
|
468
|
-
* This is not a complete Date object so only methods that were implemented can be called safely.
|
469
|
-
* To make matters worse, TzDate instances inherit stuff from Date via a prototype.
|
470
|
-
*
|
471
|
-
* We do our best to intercept calls to "unimplemented" methods, but since the list of methods is
|
472
|
-
* incomplete we might be missing some non-standard methods. This can result in errors like:
|
473
|
-
* "Date.prototype.foo called on incompatible Object".
|
474
|
-
*
|
475
|
-
* <pre>
|
476
|
-
* var newYearInBratislava = new TzDate(-1, '2009-12-31T23:00:00Z');
|
477
|
-
* newYearInBratislava.getTimezoneOffset() => -60;
|
478
|
-
* newYearInBratislava.getFullYear() => 2010;
|
479
|
-
* newYearInBratislava.getMonth() => 0;
|
480
|
-
* newYearInBratislava.getDate() => 1;
|
481
|
-
* newYearInBratislava.getHours() => 0;
|
482
|
-
* newYearInBratislava.getMinutes() => 0;
|
483
|
-
* newYearInBratislava.getSeconds() => 0;
|
484
|
-
* </pre>
|
485
|
-
*
|
486
|
-
*/
|
487
|
-
angular.mock.TzDate = function (offset, timestamp) {
|
488
|
-
var self = new Date(0);
|
489
|
-
if (angular.isString(timestamp)) {
|
490
|
-
var tsStr = timestamp;
|
491
|
-
|
492
|
-
self.origDate = jsonStringToDate(timestamp);
|
493
|
-
|
494
|
-
timestamp = self.origDate.getTime();
|
495
|
-
if (isNaN(timestamp))
|
496
|
-
throw {
|
497
|
-
name: "Illegal Argument",
|
498
|
-
message: "Arg '" + tsStr + "' passed into TzDate constructor is not a valid date string"
|
499
|
-
};
|
500
|
-
} else {
|
501
|
-
self.origDate = new Date(timestamp);
|
502
|
-
}
|
658
|
+
self.getTime = function() {
|
659
|
+
return self.date.getTime() - self.offsetDiff;
|
660
|
+
};
|
503
661
|
|
504
|
-
|
505
|
-
self.
|
506
|
-
|
662
|
+
self.toLocaleDateString = function() {
|
663
|
+
return self.date.toLocaleDateString();
|
664
|
+
};
|
507
665
|
|
508
|
-
|
509
|
-
|
510
|
-
|
666
|
+
self.getFullYear = function() {
|
667
|
+
return self.date.getFullYear();
|
668
|
+
};
|
511
669
|
|
512
|
-
|
513
|
-
|
514
|
-
|
670
|
+
self.getMonth = function() {
|
671
|
+
return self.date.getMonth();
|
672
|
+
};
|
515
673
|
|
516
|
-
|
517
|
-
|
518
|
-
|
674
|
+
self.getDate = function() {
|
675
|
+
return self.date.getDate();
|
676
|
+
};
|
519
677
|
|
520
|
-
|
521
|
-
|
522
|
-
|
678
|
+
self.getHours = function() {
|
679
|
+
return self.date.getHours();
|
680
|
+
};
|
523
681
|
|
524
|
-
|
525
|
-
|
526
|
-
|
682
|
+
self.getMinutes = function() {
|
683
|
+
return self.date.getMinutes();
|
684
|
+
};
|
527
685
|
|
528
|
-
|
529
|
-
|
530
|
-
|
686
|
+
self.getSeconds = function() {
|
687
|
+
return self.date.getSeconds();
|
688
|
+
};
|
531
689
|
|
532
|
-
|
533
|
-
|
534
|
-
|
690
|
+
self.getMilliseconds = function() {
|
691
|
+
return self.date.getMilliseconds();
|
692
|
+
};
|
535
693
|
|
536
|
-
|
537
|
-
|
538
|
-
|
694
|
+
self.getTimezoneOffset = function() {
|
695
|
+
return offset * 60;
|
696
|
+
};
|
539
697
|
|
540
|
-
|
541
|
-
|
542
|
-
|
698
|
+
self.getUTCFullYear = function() {
|
699
|
+
return self.origDate.getUTCFullYear();
|
700
|
+
};
|
543
701
|
|
544
|
-
|
545
|
-
|
546
|
-
|
702
|
+
self.getUTCMonth = function() {
|
703
|
+
return self.origDate.getUTCMonth();
|
704
|
+
};
|
547
705
|
|
548
|
-
|
549
|
-
|
550
|
-
|
706
|
+
self.getUTCDate = function() {
|
707
|
+
return self.origDate.getUTCDate();
|
708
|
+
};
|
551
709
|
|
552
|
-
|
553
|
-
|
554
|
-
|
710
|
+
self.getUTCHours = function() {
|
711
|
+
return self.origDate.getUTCHours();
|
712
|
+
};
|
555
713
|
|
556
|
-
|
557
|
-
|
558
|
-
|
714
|
+
self.getUTCMinutes = function() {
|
715
|
+
return self.origDate.getUTCMinutes();
|
716
|
+
};
|
559
717
|
|
560
|
-
|
561
|
-
|
562
|
-
|
718
|
+
self.getUTCSeconds = function() {
|
719
|
+
return self.origDate.getUTCSeconds();
|
720
|
+
};
|
563
721
|
|
564
|
-
|
565
|
-
|
566
|
-
|
722
|
+
self.getUTCMilliseconds = function() {
|
723
|
+
return self.origDate.getUTCMilliseconds();
|
724
|
+
};
|
567
725
|
|
568
|
-
|
569
|
-
|
570
|
-
|
726
|
+
self.getDay = function() {
|
727
|
+
return self.date.getDay();
|
728
|
+
};
|
571
729
|
|
572
|
-
|
573
|
-
|
730
|
+
// provide this method only on browsers that already have it
|
731
|
+
if (self.toISOString) {
|
732
|
+
self.toISOString = function() {
|
733
|
+
return padNumber(self.origDate.getUTCFullYear(), 4) + '-' +
|
734
|
+
padNumber(self.origDate.getUTCMonth() + 1, 2) + '-' +
|
735
|
+
padNumber(self.origDate.getUTCDate(), 2) + 'T' +
|
736
|
+
padNumber(self.origDate.getUTCHours(), 2) + ':' +
|
737
|
+
padNumber(self.origDate.getUTCMinutes(), 2) + ':' +
|
738
|
+
padNumber(self.origDate.getUTCSeconds(), 2) + '.' +
|
739
|
+
padNumber(self.origDate.getUTCMilliseconds(), 3) + 'Z';
|
574
740
|
};
|
741
|
+
}
|
575
742
|
|
576
|
-
|
577
|
-
|
743
|
+
//hide all methods not implemented in this mock that the Date prototype exposes
|
744
|
+
var unimplementedMethods = ['getUTCDay',
|
745
|
+
'getYear', 'setDate', 'setFullYear', 'setHours', 'setMilliseconds',
|
746
|
+
'setMinutes', 'setMonth', 'setSeconds', 'setTime', 'setUTCDate', 'setUTCFullYear',
|
747
|
+
'setUTCHours', 'setUTCMilliseconds', 'setUTCMinutes', 'setUTCMonth', 'setUTCSeconds',
|
748
|
+
'setYear', 'toDateString', 'toGMTString', 'toJSON', 'toLocaleFormat', 'toLocaleString',
|
749
|
+
'toLocaleTimeString', 'toSource', 'toString', 'toTimeString', 'toUTCString', 'valueOf'];
|
750
|
+
|
751
|
+
angular.forEach(unimplementedMethods, function(methodName) {
|
752
|
+
self[methodName] = function() {
|
753
|
+
throw new Error("Method '" + methodName + "' is not implemented in the TzDate mock");
|
578
754
|
};
|
755
|
+
});
|
579
756
|
|
580
|
-
|
581
|
-
|
582
|
-
self.toISOString = function() {
|
583
|
-
return padNumber(self.origDate.getUTCFullYear(), 4) + '-' +
|
584
|
-
padNumber(self.origDate.getUTCMonth() + 1, 2) + '-' +
|
585
|
-
padNumber(self.origDate.getUTCDate(), 2) + 'T' +
|
586
|
-
padNumber(self.origDate.getUTCHours(), 2) + ':' +
|
587
|
-
padNumber(self.origDate.getUTCMinutes(), 2) + ':' +
|
588
|
-
padNumber(self.origDate.getUTCSeconds(), 2) + '.' +
|
589
|
-
padNumber(self.origDate.getUTCMilliseconds(), 3) + 'Z'
|
590
|
-
}
|
591
|
-
}
|
757
|
+
return self;
|
758
|
+
};
|
592
759
|
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
'setMinutes', 'setMonth', 'setSeconds', 'setTime', 'setUTCDate', 'setUTCFullYear',
|
597
|
-
'setUTCHours', 'setUTCMilliseconds', 'setUTCMinutes', 'setUTCMonth', 'setUTCSeconds',
|
598
|
-
'setYear', 'toDateString', 'toGMTString', 'toJSON', 'toLocaleFormat', 'toLocaleString',
|
599
|
-
'toLocaleTimeString', 'toSource', 'toString', 'toTimeString', 'toUTCString', 'valueOf'];
|
600
|
-
|
601
|
-
angular.forEach(unimplementedMethods, function(methodName) {
|
602
|
-
self[methodName] = function() {
|
603
|
-
throw Error("Method '" + methodName + "' is not implemented in the TzDate mock");
|
604
|
-
};
|
605
|
-
});
|
760
|
+
//make "tzDateInstance instanceof Date" return true
|
761
|
+
angular.mock.TzDate.prototype = Date.prototype;
|
762
|
+
/* jshint +W101 */
|
606
763
|
|
607
|
-
|
608
|
-
};
|
764
|
+
angular.mock.animate = angular.module('ngAnimateMock', ['ng'])
|
609
765
|
|
610
|
-
|
611
|
-
angular.mock.TzDate.prototype = Date.prototype;
|
612
|
-
})();
|
766
|
+
.config(['$provide', function($provide) {
|
613
767
|
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
*
|
622
|
-
* @example
|
623
|
-
*
|
624
|
-
* <pre>
|
625
|
-
beforeEach(module(function($provide) {
|
626
|
-
$provide.value('$window', window = angular.mock.createMockWindow());
|
627
|
-
}));
|
628
|
-
|
629
|
-
it('should do something', inject(function($window) {
|
630
|
-
var val = null;
|
631
|
-
$window.setTimeout(function() { val = 123; }, 10);
|
632
|
-
expect(val).toEqual(null);
|
633
|
-
window.setTimeout.expect(10).process();
|
634
|
-
expect(val).toEqual(123);
|
768
|
+
var reflowQueue = [];
|
769
|
+
$provide.value('$$animateReflow', function(fn) {
|
770
|
+
var index = reflowQueue.length;
|
771
|
+
reflowQueue.push(fn);
|
772
|
+
return function cancel() {
|
773
|
+
reflowQueue.splice(index, 1);
|
774
|
+
};
|
635
775
|
});
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
};
|
650
|
-
mockWindow.setTimeout.queue = setTimeoutQueue;
|
651
|
-
mockWindow.setTimeout.expect = function(delay) {
|
652
|
-
if (setTimeoutQueue.length > 0) {
|
653
|
-
return {
|
654
|
-
process: function() {
|
655
|
-
var tick = setTimeoutQueue.shift();
|
656
|
-
expect(tick.delay).toEqual(delay);
|
657
|
-
tick.fn();
|
776
|
+
|
777
|
+
$provide.decorator('$animate', function($delegate, $$asyncCallback) {
|
778
|
+
var animate = {
|
779
|
+
queue : [],
|
780
|
+
enabled : $delegate.enabled,
|
781
|
+
triggerCallbacks : function() {
|
782
|
+
$$asyncCallback.flush();
|
783
|
+
},
|
784
|
+
triggerReflow : function() {
|
785
|
+
angular.forEach(reflowQueue, function(fn) {
|
786
|
+
fn();
|
787
|
+
});
|
788
|
+
reflowQueue = [];
|
658
789
|
}
|
659
790
|
};
|
660
|
-
} else {
|
661
|
-
expect('SetTimoutQueue empty. Expecting delay of ').toEqual(delay);
|
662
|
-
}
|
663
|
-
};
|
664
791
|
|
665
|
-
|
666
|
-
|
792
|
+
angular.forEach(
|
793
|
+
['enter','leave','move','addClass','removeClass','setClass'], function(method) {
|
794
|
+
animate[method] = function() {
|
795
|
+
animate.queue.push({
|
796
|
+
event : method,
|
797
|
+
element : arguments[0],
|
798
|
+
args : arguments
|
799
|
+
});
|
800
|
+
$delegate[method].apply($delegate, arguments);
|
801
|
+
};
|
802
|
+
});
|
803
|
+
|
804
|
+
return animate;
|
805
|
+
});
|
806
|
+
|
807
|
+
}]);
|
808
|
+
|
667
809
|
|
668
810
|
/**
|
669
811
|
* @ngdoc function
|
@@ -672,9 +814,11 @@ angular.mock.createMockWindow = function() {
|
|
672
814
|
*
|
673
815
|
* *NOTE*: this is not an injectable instance, just a globally available function.
|
674
816
|
*
|
675
|
-
* Method for serializing common angular objects (scope, elements, etc..) into strings, useful for
|
817
|
+
* Method for serializing common angular objects (scope, elements, etc..) into strings, useful for
|
818
|
+
* debugging.
|
676
819
|
*
|
677
|
-
* This method is also available on window, where it can be used to display objects on debug
|
820
|
+
* This method is also available on window, where it can be used to display objects on debug
|
821
|
+
* console.
|
678
822
|
*
|
679
823
|
* @param {*} object - any object to turn into string.
|
680
824
|
* @return {string} a serialized string of the argument
|
@@ -704,6 +848,8 @@ angular.mock.dump = function(object) {
|
|
704
848
|
} else if (object instanceof Error) {
|
705
849
|
out = object.stack || ('' + object.name + ': ' + object.message);
|
706
850
|
} else {
|
851
|
+
// TODO(i): this prevents methods being logged,
|
852
|
+
// we should have a better way to serialize objects
|
707
853
|
out = angular.toJson(object, true);
|
708
854
|
}
|
709
855
|
} else {
|
@@ -717,7 +863,7 @@ angular.mock.dump = function(object) {
|
|
717
863
|
offset = offset || ' ';
|
718
864
|
var log = [offset + 'Scope(' + scope.$id + '): {'];
|
719
865
|
for ( var key in scope ) {
|
720
|
-
if (
|
866
|
+
if (Object.prototype.hasOwnProperty.call(scope, key) && !key.match(/^(\$|this)/)) {
|
721
867
|
log.push(' ' + key + ': ' + angular.toJson(scope[key]));
|
722
868
|
}
|
723
869
|
}
|
@@ -732,8 +878,8 @@ angular.mock.dump = function(object) {
|
|
732
878
|
};
|
733
879
|
|
734
880
|
/**
|
735
|
-
* @ngdoc
|
736
|
-
* @name
|
881
|
+
* @ngdoc service
|
882
|
+
* @name $httpBackend
|
737
883
|
* @description
|
738
884
|
* Fake HTTP backend implementation suitable for unit testing applications that use the
|
739
885
|
* {@link ng.$http $http service}.
|
@@ -742,8 +888,8 @@ angular.mock.dump = function(object) {
|
|
742
888
|
* development please see {@link ngMockE2E.$httpBackend e2e $httpBackend mock}.
|
743
889
|
*
|
744
890
|
* During unit testing, we want our unit tests to run quickly and have no external dependencies so
|
745
|
-
* we don’t want to send
|
746
|
-
*
|
891
|
+
* we don’t want to send [XHR](https://developer.mozilla.org/en/xmlhttprequest) or
|
892
|
+
* [JSONP](http://en.wikipedia.org/wiki/JSONP) requests to a real server. All we really need is
|
747
893
|
* to verify whether a certain request has been sent or not, or alternatively just let the
|
748
894
|
* application make requests, respond with pre-trained responses and assert that the end result is
|
749
895
|
* what we expect it to be.
|
@@ -821,86 +967,110 @@ angular.mock.dump = function(object) {
|
|
821
967
|
*
|
822
968
|
* # Flushing HTTP requests
|
823
969
|
*
|
824
|
-
* The $httpBackend used in production
|
825
|
-
*
|
826
|
-
*
|
827
|
-
*
|
828
|
-
*
|
829
|
-
*
|
830
|
-
* synchronously.
|
970
|
+
* The $httpBackend used in production always responds to requests asynchronously. If we preserved
|
971
|
+
* this behavior in unit testing, we'd have to create async unit tests, which are hard to write,
|
972
|
+
* to follow and to maintain. But neither can the testing mock respond synchronously; that would
|
973
|
+
* change the execution of the code under test. For this reason, the mock $httpBackend has a
|
974
|
+
* `flush()` method, which allows the test to explicitly flush pending requests. This preserves
|
975
|
+
* the async api of the backend, while allowing the test to execute synchronously.
|
831
976
|
*
|
832
977
|
*
|
833
978
|
* # Unit testing with mock $httpBackend
|
979
|
+
* The following code shows how to setup and use the mock backend when unit testing a controller.
|
980
|
+
* First we create the controller under test:
|
834
981
|
*
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
$scope.user = data;
|
840
|
-
});
|
841
|
-
|
842
|
-
this.saveMessage = function(message) {
|
843
|
-
$scope.status = 'Saving...';
|
844
|
-
$http.post('/add-msg.py', message).success(function(response) {
|
845
|
-
$scope.status = '';
|
846
|
-
}).error(function() {
|
847
|
-
$scope.status = 'ERROR!';
|
848
|
-
});
|
849
|
-
};
|
850
|
-
}
|
982
|
+
```js
|
983
|
+
// The controller code
|
984
|
+
function MyController($scope, $http) {
|
985
|
+
var authToken;
|
851
986
|
|
852
|
-
|
853
|
-
|
987
|
+
$http.get('/auth.py').success(function(data, status, headers) {
|
988
|
+
authToken = headers('A-Token');
|
989
|
+
$scope.user = data;
|
990
|
+
});
|
854
991
|
|
855
|
-
|
856
|
-
|
992
|
+
$scope.saveMessage = function(message) {
|
993
|
+
var headers = { 'Authorization': authToken };
|
994
|
+
$scope.status = 'Saving...';
|
857
995
|
|
858
|
-
|
859
|
-
|
860
|
-
|
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
|
+
```
|
1004
|
+
*
|
1005
|
+
* Now we setup the mock backend and create the test specs:
|
1006
|
+
*
|
1007
|
+
```js
|
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'});
|
1017
|
+
|
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');
|
1022
|
+
|
1023
|
+
createController = function() {
|
1024
|
+
return $controller('MyController', {'$scope' : $rootScope });
|
1025
|
+
};
|
1026
|
+
}));
|
861
1027
|
|
862
1028
|
|
863
|
-
|
864
|
-
|
865
|
-
|
866
|
-
|
1029
|
+
afterEach(function() {
|
1030
|
+
$httpBackend.verifyNoOutstandingExpectation();
|
1031
|
+
$httpBackend.verifyNoOutstandingRequest();
|
1032
|
+
});
|
1033
|
+
|
1034
|
+
|
1035
|
+
it('should fetch authentication token', function() {
|
1036
|
+
$httpBackend.expectGET('/auth.py');
|
1037
|
+
var controller = createController();
|
1038
|
+
$httpBackend.flush();
|
1039
|
+
});
|
867
1040
|
|
868
1041
|
|
869
|
-
|
870
|
-
|
871
|
-
|
872
|
-
$httpBackend.flush();
|
873
|
-
});
|
1042
|
+
it('should send msg to server', function() {
|
1043
|
+
var controller = createController();
|
1044
|
+
$httpBackend.flush();
|
874
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
|
875
1050
|
|
876
|
-
|
877
|
-
|
878
|
-
|
879
|
-
|
880
|
-
|
881
|
-
|
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
|
+
});
|
882
1057
|
|
883
|
-
var controller = scope.$new(MyController);
|
884
|
-
$httpBackend.flush();
|
885
|
-
controller.saveMessage('message content');
|
886
|
-
expect(controller.status).toBe('Saving...');
|
887
|
-
$httpBackend.flush();
|
888
|
-
expect(controller.status).toBe('');
|
889
|
-
});
|
890
1058
|
|
1059
|
+
it('should send auth header', function() {
|
1060
|
+
var controller = createController();
|
1061
|
+
$httpBackend.flush();
|
891
1062
|
|
892
|
-
|
893
|
-
|
894
|
-
|
895
|
-
|
896
|
-
|
897
|
-
}).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, '');
|
898
1068
|
|
899
|
-
|
900
|
-
|
901
|
-
|
902
|
-
|
903
|
-
|
1069
|
+
$rootScope.saveMessage('whatever');
|
1070
|
+
$httpBackend.flush();
|
1071
|
+
});
|
1072
|
+
});
|
1073
|
+
```
|
904
1074
|
*/
|
905
1075
|
angular.mock.$HttpBackendProvider = function() {
|
906
1076
|
this.$get = ['$rootScope', createHttpBackendMock];
|
@@ -924,7 +1094,8 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
|
|
924
1094
|
var definitions = [],
|
925
1095
|
expectations = [],
|
926
1096
|
responses = [],
|
927
|
-
responsesPush = angular.bind(responses, responses.push)
|
1097
|
+
responsesPush = angular.bind(responses, responses.push),
|
1098
|
+
copy = angular.copy;
|
928
1099
|
|
929
1100
|
function createResponse(status, data, headers) {
|
930
1101
|
if (angular.isFunction(status)) return status;
|
@@ -937,7 +1108,7 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
|
|
937
1108
|
}
|
938
1109
|
|
939
1110
|
// TODO(vojta): change params to: method, url, data, headers, callback
|
940
|
-
function $httpBackend(method, url, data, callback, headers, timeout) {
|
1111
|
+
function $httpBackend(method, url, data, callback, headers, timeout, withCredentials) {
|
941
1112
|
var xhr = new MockXhr(),
|
942
1113
|
expectation = expectations[0],
|
943
1114
|
wasExpected = false;
|
@@ -956,7 +1127,7 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
|
|
956
1127
|
function handleResponse() {
|
957
1128
|
var response = wrapped.response(method, url, data, headers);
|
958
1129
|
xhr.$$respHeaders = response[2];
|
959
|
-
callback(response[0], response[1], xhr.getAllResponseHeaders());
|
1130
|
+
callback(copy(response[0]), copy(response[1]), xhr.getAllResponseHeaders());
|
960
1131
|
}
|
961
1132
|
|
962
1133
|
function handleTimeout() {
|
@@ -972,13 +1143,13 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
|
|
972
1143
|
|
973
1144
|
if (expectation && expectation.match(method, url)) {
|
974
1145
|
if (!expectation.matchData(data))
|
975
|
-
throw Error('Expected ' + expectation + ' with different data\n' +
|
1146
|
+
throw new Error('Expected ' + expectation + ' with different data\n' +
|
976
1147
|
'EXPECTED: ' + prettyPrint(expectation.data) + '\nGOT: ' + data);
|
977
1148
|
|
978
1149
|
if (!expectation.matchHeaders(headers))
|
979
|
-
throw Error('Expected ' + expectation + ' with different headers\n' +
|
980
|
-
|
981
|
-
|
1150
|
+
throw new Error('Expected ' + expectation + ' with different headers\n' +
|
1151
|
+
'EXPECTED: ' + prettyPrint(expectation.headers) + '\nGOT: ' +
|
1152
|
+
prettyPrint(headers));
|
982
1153
|
|
983
1154
|
expectations.shift();
|
984
1155
|
|
@@ -996,33 +1167,35 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
|
|
996
1167
|
// if $browser specified, we do auto flush all requests
|
997
1168
|
($browser ? $browser.defer : responsesPush)(wrapResponse(definition));
|
998
1169
|
} else if (definition.passThrough) {
|
999
|
-
$delegate(method, url, data, callback, headers, timeout);
|
1000
|
-
} else throw Error('No response defined !');
|
1170
|
+
$delegate(method, url, data, callback, headers, timeout, withCredentials);
|
1171
|
+
} else throw new Error('No response defined !');
|
1001
1172
|
return;
|
1002
1173
|
}
|
1003
1174
|
}
|
1004
1175
|
throw wasExpected ?
|
1005
|
-
Error('No response defined !') :
|
1006
|
-
Error('Unexpected request: ' + method + ' ' + url + '\n' +
|
1007
|
-
|
1176
|
+
new Error('No response defined !') :
|
1177
|
+
new Error('Unexpected request: ' + method + ' ' + url + '\n' +
|
1178
|
+
(expectation ? 'Expected ' + expectation : 'No more request expected'));
|
1008
1179
|
}
|
1009
1180
|
|
1010
1181
|
/**
|
1011
1182
|
* @ngdoc method
|
1012
|
-
* @name
|
1013
|
-
* @methodOf ngMock.$httpBackend
|
1183
|
+
* @name $httpBackend#when
|
1014
1184
|
* @description
|
1015
1185
|
* Creates a new backend definition.
|
1016
1186
|
*
|
1017
1187
|
* @param {string} method HTTP method.
|
1018
|
-
* @param {string|RegExp} url HTTP url
|
1019
|
-
*
|
1188
|
+
* @param {string|RegExp|function(string)} url HTTP url or function that receives the url
|
1189
|
+
* and returns true if the url match the current definition.
|
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.
|
1020
1192
|
* @param {(Object|function(Object))=} headers HTTP headers or function that receives http header
|
1021
1193
|
* object and returns true if the headers match the current definition.
|
1022
|
-
* @returns {requestHandler} Returns an object with `respond` method that
|
1194
|
+
* @returns {requestHandler} Returns an object with `respond` method that controls how a matched
|
1023
1195
|
* request is handled.
|
1024
1196
|
*
|
1025
|
-
* - respond –
|
1197
|
+
* - respond –
|
1198
|
+
* `{function([status,] data[, headers])|function(function(method, url, data, headers)}`
|
1026
1199
|
* – The respond method takes a set of static data to be returned or a function that can return
|
1027
1200
|
* an array containing response status (number), response data (string) and response headers
|
1028
1201
|
* (Object).
|
@@ -1047,12 +1220,12 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
|
|
1047
1220
|
|
1048
1221
|
/**
|
1049
1222
|
* @ngdoc method
|
1050
|
-
* @name
|
1051
|
-
* @methodOf ngMock.$httpBackend
|
1223
|
+
* @name $httpBackend#whenGET
|
1052
1224
|
* @description
|
1053
1225
|
* Creates a new backend definition for GET requests. For more info see `when()`.
|
1054
1226
|
*
|
1055
|
-
* @param {string|RegExp} url HTTP url
|
1227
|
+
* @param {string|RegExp|function(string)} url HTTP url or function that receives the url
|
1228
|
+
* and returns true if the url match the current definition.
|
1056
1229
|
* @param {(Object|function(Object))=} headers HTTP headers.
|
1057
1230
|
* @returns {requestHandler} Returns an object with `respond` method that control how a matched
|
1058
1231
|
* request is handled.
|
@@ -1060,12 +1233,12 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
|
|
1060
1233
|
|
1061
1234
|
/**
|
1062
1235
|
* @ngdoc method
|
1063
|
-
* @name
|
1064
|
-
* @methodOf ngMock.$httpBackend
|
1236
|
+
* @name $httpBackend#whenHEAD
|
1065
1237
|
* @description
|
1066
1238
|
* Creates a new backend definition for HEAD requests. For more info see `when()`.
|
1067
1239
|
*
|
1068
|
-
* @param {string|RegExp} url HTTP url
|
1240
|
+
* @param {string|RegExp|function(string)} url HTTP url or function that receives the url
|
1241
|
+
* and returns true if the url match the current definition.
|
1069
1242
|
* @param {(Object|function(Object))=} headers HTTP headers.
|
1070
1243
|
* @returns {requestHandler} Returns an object with `respond` method that control how a matched
|
1071
1244
|
* request is handled.
|
@@ -1073,12 +1246,12 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
|
|
1073
1246
|
|
1074
1247
|
/**
|
1075
1248
|
* @ngdoc method
|
1076
|
-
* @name
|
1077
|
-
* @methodOf ngMock.$httpBackend
|
1249
|
+
* @name $httpBackend#whenDELETE
|
1078
1250
|
* @description
|
1079
1251
|
* Creates a new backend definition for DELETE requests. For more info see `when()`.
|
1080
1252
|
*
|
1081
|
-
* @param {string|RegExp} url HTTP url
|
1253
|
+
* @param {string|RegExp|function(string)} url HTTP url or function that receives the url
|
1254
|
+
* and returns true if the url match the current definition.
|
1082
1255
|
* @param {(Object|function(Object))=} headers HTTP headers.
|
1083
1256
|
* @returns {requestHandler} Returns an object with `respond` method that control how a matched
|
1084
1257
|
* request is handled.
|
@@ -1086,13 +1259,14 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
|
|
1086
1259
|
|
1087
1260
|
/**
|
1088
1261
|
* @ngdoc method
|
1089
|
-
* @name
|
1090
|
-
* @methodOf ngMock.$httpBackend
|
1262
|
+
* @name $httpBackend#whenPOST
|
1091
1263
|
* @description
|
1092
1264
|
* Creates a new backend definition for POST requests. For more info see `when()`.
|
1093
1265
|
*
|
1094
|
-
* @param {string|RegExp} url HTTP url
|
1095
|
-
*
|
1266
|
+
* @param {string|RegExp|function(string)} url HTTP url or function that receives the url
|
1267
|
+
* and returns true if the url match the current definition.
|
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.
|
1096
1270
|
* @param {(Object|function(Object))=} headers HTTP headers.
|
1097
1271
|
* @returns {requestHandler} Returns an object with `respond` method that control how a matched
|
1098
1272
|
* request is handled.
|
@@ -1100,13 +1274,14 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
|
|
1100
1274
|
|
1101
1275
|
/**
|
1102
1276
|
* @ngdoc method
|
1103
|
-
* @name
|
1104
|
-
* @methodOf ngMock.$httpBackend
|
1277
|
+
* @name $httpBackend#whenPUT
|
1105
1278
|
* @description
|
1106
1279
|
* Creates a new backend definition for PUT requests. For more info see `when()`.
|
1107
1280
|
*
|
1108
|
-
* @param {string|RegExp} url HTTP url
|
1109
|
-
*
|
1281
|
+
* @param {string|RegExp|function(string)} url HTTP url or function that receives the url
|
1282
|
+
* and returns true if the url match the current definition.
|
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.
|
1110
1285
|
* @param {(Object|function(Object))=} headers HTTP headers.
|
1111
1286
|
* @returns {requestHandler} Returns an object with `respond` method that control how a matched
|
1112
1287
|
* request is handled.
|
@@ -1114,12 +1289,12 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
|
|
1114
1289
|
|
1115
1290
|
/**
|
1116
1291
|
* @ngdoc method
|
1117
|
-
* @name
|
1118
|
-
* @methodOf ngMock.$httpBackend
|
1292
|
+
* @name $httpBackend#whenJSONP
|
1119
1293
|
* @description
|
1120
1294
|
* Creates a new backend definition for JSONP requests. For more info see `when()`.
|
1121
1295
|
*
|
1122
|
-
* @param {string|RegExp} url HTTP url
|
1296
|
+
* @param {string|RegExp|function(string)} url HTTP url or function that receives the url
|
1297
|
+
* and returns true if the url match the current definition.
|
1123
1298
|
* @returns {requestHandler} Returns an object with `respond` method that control how a matched
|
1124
1299
|
* request is handled.
|
1125
1300
|
*/
|
@@ -1128,20 +1303,23 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
|
|
1128
1303
|
|
1129
1304
|
/**
|
1130
1305
|
* @ngdoc method
|
1131
|
-
* @name
|
1132
|
-
* @methodOf ngMock.$httpBackend
|
1306
|
+
* @name $httpBackend#expect
|
1133
1307
|
* @description
|
1134
1308
|
* Creates a new request expectation.
|
1135
1309
|
*
|
1136
1310
|
* @param {string} method HTTP method.
|
1137
|
-
* @param {string|RegExp} url HTTP url
|
1138
|
-
*
|
1311
|
+
* @param {string|RegExp|function(string)} url HTTP url or function that receives the url
|
1312
|
+
* and returns true if the url match the current definition.
|
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.
|
1139
1316
|
* @param {(Object|function(Object))=} headers HTTP headers or function that receives http header
|
1140
1317
|
* object and returns true if the headers match the current expectation.
|
1141
1318
|
* @returns {requestHandler} Returns an object with `respond` method that control how a matched
|
1142
1319
|
* request is handled.
|
1143
1320
|
*
|
1144
|
-
* - respond –
|
1321
|
+
* - respond –
|
1322
|
+
* `{function([status,] data[, headers])|function(function(method, url, data, headers)}`
|
1145
1323
|
* – The respond method takes a set of static data to be returned or a function that can return
|
1146
1324
|
* an array containing response status (number), response data (string) and response headers
|
1147
1325
|
* (Object).
|
@@ -1159,12 +1337,12 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
|
|
1159
1337
|
|
1160
1338
|
/**
|
1161
1339
|
* @ngdoc method
|
1162
|
-
* @name
|
1163
|
-
* @methodOf ngMock.$httpBackend
|
1340
|
+
* @name $httpBackend#expectGET
|
1164
1341
|
* @description
|
1165
1342
|
* Creates a new request expectation for GET requests. For more info see `expect()`.
|
1166
1343
|
*
|
1167
|
-
* @param {string|RegExp} url HTTP url
|
1344
|
+
* @param {string|RegExp|function(string)} url HTTP url or function that receives the url
|
1345
|
+
* and returns true if the url match the current definition.
|
1168
1346
|
* @param {Object=} headers HTTP headers.
|
1169
1347
|
* @returns {requestHandler} Returns an object with `respond` method that control how a matched
|
1170
1348
|
* request is handled. See #expect for more info.
|
@@ -1172,12 +1350,12 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
|
|
1172
1350
|
|
1173
1351
|
/**
|
1174
1352
|
* @ngdoc method
|
1175
|
-
* @name
|
1176
|
-
* @methodOf ngMock.$httpBackend
|
1353
|
+
* @name $httpBackend#expectHEAD
|
1177
1354
|
* @description
|
1178
1355
|
* Creates a new request expectation for HEAD requests. For more info see `expect()`.
|
1179
1356
|
*
|
1180
|
-
* @param {string|RegExp} url HTTP url
|
1357
|
+
* @param {string|RegExp|function(string)} url HTTP url or function that receives the url
|
1358
|
+
* and returns true if the url match the current definition.
|
1181
1359
|
* @param {Object=} headers HTTP headers.
|
1182
1360
|
* @returns {requestHandler} Returns an object with `respond` method that control how a matched
|
1183
1361
|
* request is handled.
|
@@ -1185,12 +1363,12 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
|
|
1185
1363
|
|
1186
1364
|
/**
|
1187
1365
|
* @ngdoc method
|
1188
|
-
* @name
|
1189
|
-
* @methodOf ngMock.$httpBackend
|
1366
|
+
* @name $httpBackend#expectDELETE
|
1190
1367
|
* @description
|
1191
1368
|
* Creates a new request expectation for DELETE requests. For more info see `expect()`.
|
1192
1369
|
*
|
1193
|
-
* @param {string|RegExp} url HTTP url
|
1370
|
+
* @param {string|RegExp|function(string)} url HTTP url or function that receives the url
|
1371
|
+
* and returns true if the url match the current definition.
|
1194
1372
|
* @param {Object=} headers HTTP headers.
|
1195
1373
|
* @returns {requestHandler} Returns an object with `respond` method that control how a matched
|
1196
1374
|
* request is handled.
|
@@ -1198,13 +1376,15 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
|
|
1198
1376
|
|
1199
1377
|
/**
|
1200
1378
|
* @ngdoc method
|
1201
|
-
* @name
|
1202
|
-
* @methodOf ngMock.$httpBackend
|
1379
|
+
* @name $httpBackend#expectPOST
|
1203
1380
|
* @description
|
1204
1381
|
* Creates a new request expectation for POST requests. For more info see `expect()`.
|
1205
1382
|
*
|
1206
|
-
* @param {string|RegExp} url HTTP url
|
1207
|
-
*
|
1383
|
+
* @param {string|RegExp|function(string)} url HTTP url or function that receives the url
|
1384
|
+
* and returns true if the url match the current definition.
|
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.
|
1208
1388
|
* @param {Object=} headers HTTP headers.
|
1209
1389
|
* @returns {requestHandler} Returns an object with `respond` method that control how a matched
|
1210
1390
|
* request is handled.
|
@@ -1212,13 +1392,15 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
|
|
1212
1392
|
|
1213
1393
|
/**
|
1214
1394
|
* @ngdoc method
|
1215
|
-
* @name
|
1216
|
-
* @methodOf ngMock.$httpBackend
|
1395
|
+
* @name $httpBackend#expectPUT
|
1217
1396
|
* @description
|
1218
1397
|
* Creates a new request expectation for PUT requests. For more info see `expect()`.
|
1219
1398
|
*
|
1220
|
-
* @param {string|RegExp} url HTTP url
|
1221
|
-
*
|
1399
|
+
* @param {string|RegExp|function(string)} url HTTP url or function that receives the url
|
1400
|
+
* and returns true if the url match the current definition.
|
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.
|
1222
1404
|
* @param {Object=} headers HTTP headers.
|
1223
1405
|
* @returns {requestHandler} Returns an object with `respond` method that control how a matched
|
1224
1406
|
* request is handled.
|
@@ -1226,13 +1408,15 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
|
|
1226
1408
|
|
1227
1409
|
/**
|
1228
1410
|
* @ngdoc method
|
1229
|
-
* @name
|
1230
|
-
* @methodOf ngMock.$httpBackend
|
1411
|
+
* @name $httpBackend#expectPATCH
|
1231
1412
|
* @description
|
1232
1413
|
* Creates a new request expectation for PATCH requests. For more info see `expect()`.
|
1233
1414
|
*
|
1234
|
-
* @param {string|RegExp} url HTTP url
|
1235
|
-
*
|
1415
|
+
* @param {string|RegExp|function(string)} url HTTP url or function that receives the url
|
1416
|
+
* and returns true if the url match the current definition.
|
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.
|
1236
1420
|
* @param {Object=} headers HTTP headers.
|
1237
1421
|
* @returns {requestHandler} Returns an object with `respond` method that control how a matched
|
1238
1422
|
* request is handled.
|
@@ -1240,12 +1424,12 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
|
|
1240
1424
|
|
1241
1425
|
/**
|
1242
1426
|
* @ngdoc method
|
1243
|
-
* @name
|
1244
|
-
* @methodOf ngMock.$httpBackend
|
1427
|
+
* @name $httpBackend#expectJSONP
|
1245
1428
|
* @description
|
1246
1429
|
* Creates a new request expectation for JSONP requests. For more info see `expect()`.
|
1247
1430
|
*
|
1248
|
-
* @param {string|RegExp} url HTTP url
|
1431
|
+
* @param {string|RegExp|function(string)} url HTTP url or function that receives the url
|
1432
|
+
* and returns true if the url match the current definition.
|
1249
1433
|
* @returns {requestHandler} Returns an object with `respond` method that control how a matched
|
1250
1434
|
* request is handled.
|
1251
1435
|
*/
|
@@ -1254,8 +1438,7 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
|
|
1254
1438
|
|
1255
1439
|
/**
|
1256
1440
|
* @ngdoc method
|
1257
|
-
* @name
|
1258
|
-
* @methodOf ngMock.$httpBackend
|
1441
|
+
* @name $httpBackend#flush
|
1259
1442
|
* @description
|
1260
1443
|
* Flushes all pending requests using the trained responses.
|
1261
1444
|
*
|
@@ -1265,11 +1448,11 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
|
|
1265
1448
|
*/
|
1266
1449
|
$httpBackend.flush = function(count) {
|
1267
1450
|
$rootScope.$digest();
|
1268
|
-
if (!responses.length) throw Error('No pending request to flush !');
|
1451
|
+
if (!responses.length) throw new Error('No pending request to flush !');
|
1269
1452
|
|
1270
1453
|
if (angular.isDefined(count)) {
|
1271
1454
|
while (count--) {
|
1272
|
-
if (!responses.length) throw Error('No more pending request to flush !');
|
1455
|
+
if (!responses.length) throw new Error('No more pending request to flush !');
|
1273
1456
|
responses.shift()();
|
1274
1457
|
}
|
1275
1458
|
} else {
|
@@ -1283,8 +1466,7 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
|
|
1283
1466
|
|
1284
1467
|
/**
|
1285
1468
|
* @ngdoc method
|
1286
|
-
* @name
|
1287
|
-
* @methodOf ngMock.$httpBackend
|
1469
|
+
* @name $httpBackend#verifyNoOutstandingExpectation
|
1288
1470
|
* @description
|
1289
1471
|
* Verifies that all of the requests defined via the `expect` api were made. If any of the
|
1290
1472
|
* requests were not made, verifyNoOutstandingExpectation throws an exception.
|
@@ -1292,43 +1474,41 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
|
|
1292
1474
|
* Typically, you would call this method following each test case that asserts requests using an
|
1293
1475
|
* "afterEach" clause.
|
1294
1476
|
*
|
1295
|
-
*
|
1296
|
-
* afterEach($httpBackend.
|
1297
|
-
*
|
1477
|
+
* ```js
|
1478
|
+
* afterEach($httpBackend.verifyNoOutstandingExpectation);
|
1479
|
+
* ```
|
1298
1480
|
*/
|
1299
1481
|
$httpBackend.verifyNoOutstandingExpectation = function() {
|
1300
1482
|
$rootScope.$digest();
|
1301
1483
|
if (expectations.length) {
|
1302
|
-
throw Error('Unsatisfied requests: ' + expectations.join(', '));
|
1484
|
+
throw new Error('Unsatisfied requests: ' + expectations.join(', '));
|
1303
1485
|
}
|
1304
1486
|
};
|
1305
1487
|
|
1306
1488
|
|
1307
1489
|
/**
|
1308
1490
|
* @ngdoc method
|
1309
|
-
* @name
|
1310
|
-
* @methodOf ngMock.$httpBackend
|
1491
|
+
* @name $httpBackend#verifyNoOutstandingRequest
|
1311
1492
|
* @description
|
1312
1493
|
* Verifies that there are no outstanding requests that need to be flushed.
|
1313
1494
|
*
|
1314
1495
|
* Typically, you would call this method following each test case that asserts requests using an
|
1315
1496
|
* "afterEach" clause.
|
1316
1497
|
*
|
1317
|
-
*
|
1498
|
+
* ```js
|
1318
1499
|
* afterEach($httpBackend.verifyNoOutstandingRequest);
|
1319
|
-
*
|
1500
|
+
* ```
|
1320
1501
|
*/
|
1321
1502
|
$httpBackend.verifyNoOutstandingRequest = function() {
|
1322
1503
|
if (responses.length) {
|
1323
|
-
throw Error('Unflushed requests: ' + responses.length);
|
1504
|
+
throw new Error('Unflushed requests: ' + responses.length);
|
1324
1505
|
}
|
1325
1506
|
};
|
1326
1507
|
|
1327
1508
|
|
1328
1509
|
/**
|
1329
1510
|
* @ngdoc method
|
1330
|
-
* @name
|
1331
|
-
* @methodOf ngMock.$httpBackend
|
1511
|
+
* @name $httpBackend#resetExpectations
|
1332
1512
|
* @description
|
1333
1513
|
* Resets all request expectations, but preserves all backend definitions. Typically, you would
|
1334
1514
|
* call resetExpectations during a multiple-phase test when you want to reuse the same instance of
|
@@ -1345,14 +1525,14 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
|
|
1345
1525
|
function createShortMethods(prefix) {
|
1346
1526
|
angular.forEach(['GET', 'DELETE', 'JSONP'], function(method) {
|
1347
1527
|
$httpBackend[prefix + method] = function(url, headers) {
|
1348
|
-
return $httpBackend[prefix](method, url, undefined, headers)
|
1349
|
-
}
|
1528
|
+
return $httpBackend[prefix](method, url, undefined, headers);
|
1529
|
+
};
|
1350
1530
|
});
|
1351
1531
|
|
1352
1532
|
angular.forEach(['PUT', 'POST', 'PATCH'], function(method) {
|
1353
1533
|
$httpBackend[prefix + method] = function(url, data, headers) {
|
1354
|
-
return $httpBackend[prefix](method, url, data, headers)
|
1355
|
-
}
|
1534
|
+
return $httpBackend[prefix](method, url, data, headers);
|
1535
|
+
};
|
1356
1536
|
});
|
1357
1537
|
}
|
1358
1538
|
}
|
@@ -1373,6 +1553,7 @@ function MockHttpExpectation(method, url, data, headers) {
|
|
1373
1553
|
this.matchUrl = function(u) {
|
1374
1554
|
if (!url) return true;
|
1375
1555
|
if (angular.isFunction(url.test)) return url.test(u);
|
1556
|
+
if (angular.isFunction(url)) return url(u);
|
1376
1557
|
return url == u;
|
1377
1558
|
};
|
1378
1559
|
|
@@ -1385,7 +1566,8 @@ function MockHttpExpectation(method, url, data, headers) {
|
|
1385
1566
|
this.matchData = function(d) {
|
1386
1567
|
if (angular.isUndefined(data)) return true;
|
1387
1568
|
if (data && angular.isFunction(data.test)) return data.test(d);
|
1388
|
-
if (data &&
|
1569
|
+
if (data && angular.isFunction(data)) return data(d);
|
1570
|
+
if (data && !angular.isString(data)) return angular.equals(data, angular.fromJson(d));
|
1389
1571
|
return data == d;
|
1390
1572
|
};
|
1391
1573
|
|
@@ -1394,6 +1576,10 @@ function MockHttpExpectation(method, url, data, headers) {
|
|
1394
1576
|
};
|
1395
1577
|
}
|
1396
1578
|
|
1579
|
+
function createMockXhr() {
|
1580
|
+
return new MockXhr();
|
1581
|
+
}
|
1582
|
+
|
1397
1583
|
function MockXhr() {
|
1398
1584
|
|
1399
1585
|
// hack for testing $http, $httpBackend
|
@@ -1416,7 +1602,8 @@ function MockXhr() {
|
|
1416
1602
|
};
|
1417
1603
|
|
1418
1604
|
this.getResponseHeader = function(name) {
|
1419
|
-
// the lookup must be case insensitive,
|
1605
|
+
// the lookup must be case insensitive,
|
1606
|
+
// that's why we try two quick lookups first and full scan last
|
1420
1607
|
var header = this.$$respHeaders[name];
|
1421
1608
|
if (header) return header;
|
1422
1609
|
|
@@ -1445,39 +1632,39 @@ function MockXhr() {
|
|
1445
1632
|
|
1446
1633
|
|
1447
1634
|
/**
|
1448
|
-
* @ngdoc
|
1449
|
-
* @name
|
1635
|
+
* @ngdoc service
|
1636
|
+
* @name $timeout
|
1450
1637
|
* @description
|
1451
1638
|
*
|
1452
1639
|
* This service is just a simple decorator for {@link ng.$timeout $timeout} service
|
1453
1640
|
* that adds a "flush" and "verifyNoPendingTasks" methods.
|
1454
|
-
*/
|
1641
|
+
*/
|
1455
1642
|
|
1456
1643
|
angular.mock.$TimeoutDecorator = function($delegate, $browser) {
|
1457
1644
|
|
1458
1645
|
/**
|
1459
1646
|
* @ngdoc method
|
1460
|
-
* @name
|
1461
|
-
* @methodOf ngMock.$timeout
|
1647
|
+
* @name $timeout#flush
|
1462
1648
|
* @description
|
1463
1649
|
*
|
1464
1650
|
* Flushes the queue of pending tasks.
|
1651
|
+
*
|
1652
|
+
* @param {number=} delay maximum timeout amount to flush up until
|
1465
1653
|
*/
|
1466
|
-
$delegate.flush = function() {
|
1467
|
-
$browser.defer.flush();
|
1654
|
+
$delegate.flush = function(delay) {
|
1655
|
+
$browser.defer.flush(delay);
|
1468
1656
|
};
|
1469
1657
|
|
1470
1658
|
/**
|
1471
1659
|
* @ngdoc method
|
1472
|
-
* @name
|
1473
|
-
* @methodOf ngMock.$timeout
|
1660
|
+
* @name $timeout#verifyNoPendingTasks
|
1474
1661
|
* @description
|
1475
1662
|
*
|
1476
1663
|
* Verifies that there are no pending tasks that need to be flushed.
|
1477
1664
|
*/
|
1478
1665
|
$delegate.verifyNoPendingTasks = function() {
|
1479
1666
|
if ($browser.deferredFns.length) {
|
1480
|
-
throw Error('Deferred tasks to flush (' + $browser.deferredFns.length + '): ' +
|
1667
|
+
throw new Error('Deferred tasks to flush (' + $browser.deferredFns.length + '): ' +
|
1481
1668
|
formatPendingTasksAsString($browser.deferredFns));
|
1482
1669
|
}
|
1483
1670
|
};
|
@@ -1494,49 +1681,103 @@ angular.mock.$TimeoutDecorator = function($delegate, $browser) {
|
|
1494
1681
|
return $delegate;
|
1495
1682
|
};
|
1496
1683
|
|
1684
|
+
angular.mock.$RAFDecorator = function($delegate) {
|
1685
|
+
var queue = [];
|
1686
|
+
var rafFn = function(fn) {
|
1687
|
+
var index = queue.length;
|
1688
|
+
queue.push(fn);
|
1689
|
+
return function() {
|
1690
|
+
queue.splice(index, 1);
|
1691
|
+
};
|
1692
|
+
};
|
1693
|
+
|
1694
|
+
rafFn.supported = $delegate.supported;
|
1695
|
+
|
1696
|
+
rafFn.flush = function() {
|
1697
|
+
if(queue.length === 0) {
|
1698
|
+
throw new Error('No rAF callbacks present');
|
1699
|
+
}
|
1700
|
+
|
1701
|
+
var length = queue.length;
|
1702
|
+
for(var i=0;i<length;i++) {
|
1703
|
+
queue[i]();
|
1704
|
+
}
|
1705
|
+
|
1706
|
+
queue = [];
|
1707
|
+
};
|
1708
|
+
|
1709
|
+
return rafFn;
|
1710
|
+
};
|
1711
|
+
|
1712
|
+
angular.mock.$AsyncCallbackDecorator = function($delegate) {
|
1713
|
+
var callbacks = [];
|
1714
|
+
var addFn = function(fn) {
|
1715
|
+
callbacks.push(fn);
|
1716
|
+
};
|
1717
|
+
addFn.flush = function() {
|
1718
|
+
angular.forEach(callbacks, function(fn) {
|
1719
|
+
fn();
|
1720
|
+
});
|
1721
|
+
callbacks = [];
|
1722
|
+
};
|
1723
|
+
return addFn;
|
1724
|
+
};
|
1725
|
+
|
1497
1726
|
/**
|
1498
1727
|
*
|
1499
1728
|
*/
|
1500
1729
|
angular.mock.$RootElementProvider = function() {
|
1501
1730
|
this.$get = function() {
|
1502
1731
|
return angular.element('<div ng-app></div>');
|
1503
|
-
}
|
1732
|
+
};
|
1504
1733
|
};
|
1505
1734
|
|
1506
1735
|
/**
|
1507
|
-
* @ngdoc
|
1736
|
+
* @ngdoc module
|
1508
1737
|
* @name ngMock
|
1509
1738
|
* @description
|
1510
1739
|
*
|
1511
|
-
*
|
1512
|
-
*
|
1740
|
+
* # ngMock
|
1741
|
+
*
|
1742
|
+
* The `ngMock` module providers support to inject and mock Angular services into unit tests.
|
1743
|
+
* In addition, ngMock also extends various core ng services such that they can be
|
1744
|
+
* inspected and controlled in a synchronous manner within test code.
|
1745
|
+
*
|
1746
|
+
*
|
1747
|
+
* <div doc-module-components="ngMock"></div>
|
1748
|
+
*
|
1513
1749
|
*/
|
1514
1750
|
angular.module('ngMock', ['ng']).provider({
|
1515
1751
|
$browser: angular.mock.$BrowserProvider,
|
1516
1752
|
$exceptionHandler: angular.mock.$ExceptionHandlerProvider,
|
1517
1753
|
$log: angular.mock.$LogProvider,
|
1754
|
+
$interval: angular.mock.$IntervalProvider,
|
1518
1755
|
$httpBackend: angular.mock.$HttpBackendProvider,
|
1519
1756
|
$rootElement: angular.mock.$RootElementProvider
|
1520
|
-
}).config(function($provide) {
|
1757
|
+
}).config(['$provide', function($provide) {
|
1521
1758
|
$provide.decorator('$timeout', angular.mock.$TimeoutDecorator);
|
1522
|
-
|
1759
|
+
$provide.decorator('$$rAF', angular.mock.$RAFDecorator);
|
1760
|
+
$provide.decorator('$$asyncCallback', angular.mock.$AsyncCallbackDecorator);
|
1761
|
+
}]);
|
1523
1762
|
|
1524
1763
|
/**
|
1525
|
-
* @ngdoc
|
1764
|
+
* @ngdoc module
|
1526
1765
|
* @name ngMockE2E
|
1766
|
+
* @module ngMockE2E
|
1527
1767
|
* @description
|
1528
1768
|
*
|
1529
1769
|
* The `ngMockE2E` is an angular module which contains mocks suitable for end-to-end testing.
|
1530
1770
|
* Currently there is only one mock present in this module -
|
1531
1771
|
* the {@link ngMockE2E.$httpBackend e2e $httpBackend} mock.
|
1532
1772
|
*/
|
1533
|
-
angular.module('ngMockE2E', ['ng']).config(function($provide) {
|
1773
|
+
angular.module('ngMockE2E', ['ng']).config(['$provide', function($provide) {
|
1534
1774
|
$provide.decorator('$httpBackend', angular.mock.e2e.$httpBackendDecorator);
|
1535
|
-
});
|
1775
|
+
}]);
|
1536
1776
|
|
1537
1777
|
/**
|
1538
|
-
* @ngdoc
|
1539
|
-
* @name
|
1778
|
+
* @ngdoc service
|
1779
|
+
* @name $httpBackend
|
1780
|
+
* @module ngMockE2E
|
1540
1781
|
* @description
|
1541
1782
|
* Fake HTTP backend implementation suitable for end-to-end testing or backend-less development of
|
1542
1783
|
* applications that use the {@link ng.$http $http service}.
|
@@ -1562,7 +1803,7 @@ angular.module('ngMockE2E', ['ng']).config(function($provide) {
|
|
1562
1803
|
* To setup the application to run with this http backend, you have to create a module that depends
|
1563
1804
|
* on the `ngMockE2E` and your application modules and defines the fake backend:
|
1564
1805
|
*
|
1565
|
-
*
|
1806
|
+
* ```js
|
1566
1807
|
* myAppDev = angular.module('myAppDev', ['myApp', 'ngMockE2E']);
|
1567
1808
|
* myAppDev.run(function($httpBackend) {
|
1568
1809
|
* phones = [{name: 'phone1'}, {name: 'phone2'}];
|
@@ -1572,48 +1813,51 @@ angular.module('ngMockE2E', ['ng']).config(function($provide) {
|
|
1572
1813
|
*
|
1573
1814
|
* // adds a new phone to the phones array
|
1574
1815
|
* $httpBackend.whenPOST('/phones').respond(function(method, url, data) {
|
1575
|
-
* phones.push(angular.
|
1816
|
+
* phones.push(angular.fromJson(data));
|
1576
1817
|
* });
|
1577
1818
|
* $httpBackend.whenGET(/^\/templates\//).passThrough();
|
1578
1819
|
* //...
|
1579
1820
|
* });
|
1580
|
-
*
|
1821
|
+
* ```
|
1581
1822
|
*
|
1582
1823
|
* Afterwards, bootstrap your app with this new module.
|
1583
1824
|
*/
|
1584
1825
|
|
1585
1826
|
/**
|
1586
1827
|
* @ngdoc method
|
1587
|
-
* @name
|
1588
|
-
* @
|
1828
|
+
* @name $httpBackend#when
|
1829
|
+
* @module ngMockE2E
|
1589
1830
|
* @description
|
1590
1831
|
* Creates a new backend definition.
|
1591
1832
|
*
|
1592
1833
|
* @param {string} method HTTP method.
|
1593
|
-
* @param {string|RegExp} url HTTP url
|
1834
|
+
* @param {string|RegExp|function(string)} url HTTP url or function that receives the url
|
1835
|
+
* and returns true if the url match the current definition.
|
1594
1836
|
* @param {(string|RegExp)=} data HTTP request body.
|
1595
1837
|
* @param {(Object|function(Object))=} headers HTTP headers or function that receives http header
|
1596
1838
|
* object and returns true if the headers match the current definition.
|
1597
1839
|
* @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that
|
1598
1840
|
* control how a matched request is handled.
|
1599
1841
|
*
|
1600
|
-
* - respond –
|
1842
|
+
* - respond –
|
1843
|
+
* `{function([status,] data[, headers])|function(function(method, url, data, headers)}`
|
1601
1844
|
* – The respond method takes a set of static data to be returned or a function that can return
|
1602
1845
|
* an array containing response status (number), response data (string) and response headers
|
1603
1846
|
* (Object).
|
1604
1847
|
* - passThrough – `{function()}` – Any request matching a backend definition with `passThrough`
|
1605
|
-
* handler
|
1606
|
-
* server.
|
1848
|
+
* handler will be passed through to the real backend (an XHR request will be made to the
|
1849
|
+
* server.)
|
1607
1850
|
*/
|
1608
1851
|
|
1609
1852
|
/**
|
1610
1853
|
* @ngdoc method
|
1611
|
-
* @name
|
1612
|
-
* @
|
1854
|
+
* @name $httpBackend#whenGET
|
1855
|
+
* @module ngMockE2E
|
1613
1856
|
* @description
|
1614
1857
|
* Creates a new backend definition for GET requests. For more info see `when()`.
|
1615
1858
|
*
|
1616
|
-
* @param {string|RegExp} url HTTP url
|
1859
|
+
* @param {string|RegExp|function(string)} url HTTP url or function that receives the url
|
1860
|
+
* and returns true if the url match the current definition.
|
1617
1861
|
* @param {(Object|function(Object))=} headers HTTP headers.
|
1618
1862
|
* @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that
|
1619
1863
|
* control how a matched request is handled.
|
@@ -1621,12 +1865,13 @@ angular.module('ngMockE2E', ['ng']).config(function($provide) {
|
|
1621
1865
|
|
1622
1866
|
/**
|
1623
1867
|
* @ngdoc method
|
1624
|
-
* @name
|
1625
|
-
* @
|
1868
|
+
* @name $httpBackend#whenHEAD
|
1869
|
+
* @module ngMockE2E
|
1626
1870
|
* @description
|
1627
1871
|
* Creates a new backend definition for HEAD requests. For more info see `when()`.
|
1628
1872
|
*
|
1629
|
-
* @param {string|RegExp} url HTTP url
|
1873
|
+
* @param {string|RegExp|function(string)} url HTTP url or function that receives the url
|
1874
|
+
* and returns true if the url match the current definition.
|
1630
1875
|
* @param {(Object|function(Object))=} headers HTTP headers.
|
1631
1876
|
* @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that
|
1632
1877
|
* control how a matched request is handled.
|
@@ -1634,12 +1879,13 @@ angular.module('ngMockE2E', ['ng']).config(function($provide) {
|
|
1634
1879
|
|
1635
1880
|
/**
|
1636
1881
|
* @ngdoc method
|
1637
|
-
* @name
|
1638
|
-
* @
|
1882
|
+
* @name $httpBackend#whenDELETE
|
1883
|
+
* @module ngMockE2E
|
1639
1884
|
* @description
|
1640
1885
|
* Creates a new backend definition for DELETE requests. For more info see `when()`.
|
1641
1886
|
*
|
1642
|
-
* @param {string|RegExp} url HTTP url
|
1887
|
+
* @param {string|RegExp|function(string)} url HTTP url or function that receives the url
|
1888
|
+
* and returns true if the url match the current definition.
|
1643
1889
|
* @param {(Object|function(Object))=} headers HTTP headers.
|
1644
1890
|
* @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that
|
1645
1891
|
* control how a matched request is handled.
|
@@ -1647,12 +1893,13 @@ angular.module('ngMockE2E', ['ng']).config(function($provide) {
|
|
1647
1893
|
|
1648
1894
|
/**
|
1649
1895
|
* @ngdoc method
|
1650
|
-
* @name
|
1651
|
-
* @
|
1896
|
+
* @name $httpBackend#whenPOST
|
1897
|
+
* @module ngMockE2E
|
1652
1898
|
* @description
|
1653
1899
|
* Creates a new backend definition for POST requests. For more info see `when()`.
|
1654
1900
|
*
|
1655
|
-
* @param {string|RegExp} url HTTP url
|
1901
|
+
* @param {string|RegExp|function(string)} url HTTP url or function that receives the url
|
1902
|
+
* and returns true if the url match the current definition.
|
1656
1903
|
* @param {(string|RegExp)=} data HTTP request body.
|
1657
1904
|
* @param {(Object|function(Object))=} headers HTTP headers.
|
1658
1905
|
* @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that
|
@@ -1661,12 +1908,13 @@ angular.module('ngMockE2E', ['ng']).config(function($provide) {
|
|
1661
1908
|
|
1662
1909
|
/**
|
1663
1910
|
* @ngdoc method
|
1664
|
-
* @name
|
1665
|
-
* @
|
1911
|
+
* @name $httpBackend#whenPUT
|
1912
|
+
* @module ngMockE2E
|
1666
1913
|
* @description
|
1667
1914
|
* Creates a new backend definition for PUT requests. For more info see `when()`.
|
1668
1915
|
*
|
1669
|
-
* @param {string|RegExp} url HTTP url
|
1916
|
+
* @param {string|RegExp|function(string)} url HTTP url or function that receives the url
|
1917
|
+
* and returns true if the url match the current definition.
|
1670
1918
|
* @param {(string|RegExp)=} data HTTP request body.
|
1671
1919
|
* @param {(Object|function(Object))=} headers HTTP headers.
|
1672
1920
|
* @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that
|
@@ -1675,12 +1923,13 @@ angular.module('ngMockE2E', ['ng']).config(function($provide) {
|
|
1675
1923
|
|
1676
1924
|
/**
|
1677
1925
|
* @ngdoc method
|
1678
|
-
* @name
|
1679
|
-
* @
|
1926
|
+
* @name $httpBackend#whenPATCH
|
1927
|
+
* @module ngMockE2E
|
1680
1928
|
* @description
|
1681
1929
|
* Creates a new backend definition for PATCH requests. For more info see `when()`.
|
1682
1930
|
*
|
1683
|
-
* @param {string|RegExp} url HTTP url
|
1931
|
+
* @param {string|RegExp|function(string)} url HTTP url or function that receives the url
|
1932
|
+
* and returns true if the url match the current definition.
|
1684
1933
|
* @param {(string|RegExp)=} data HTTP request body.
|
1685
1934
|
* @param {(Object|function(Object))=} headers HTTP headers.
|
1686
1935
|
* @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that
|
@@ -1689,17 +1938,19 @@ angular.module('ngMockE2E', ['ng']).config(function($provide) {
|
|
1689
1938
|
|
1690
1939
|
/**
|
1691
1940
|
* @ngdoc method
|
1692
|
-
* @name
|
1693
|
-
* @
|
1941
|
+
* @name $httpBackend#whenJSONP
|
1942
|
+
* @module ngMockE2E
|
1694
1943
|
* @description
|
1695
1944
|
* Creates a new backend definition for JSONP requests. For more info see `when()`.
|
1696
1945
|
*
|
1697
|
-
* @param {string|RegExp} url HTTP url
|
1946
|
+
* @param {string|RegExp|function(string)} url HTTP url or function that receives the url
|
1947
|
+
* and returns true if the url match the current definition.
|
1698
1948
|
* @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that
|
1699
1949
|
* control how a matched request is handled.
|
1700
1950
|
*/
|
1701
1951
|
angular.mock.e2e = {};
|
1702
|
-
angular.mock.e2e.$httpBackendDecorator =
|
1952
|
+
angular.mock.e2e.$httpBackendDecorator =
|
1953
|
+
['$rootScope', '$delegate', '$browser', createHttpBackendMock];
|
1703
1954
|
|
1704
1955
|
|
1705
1956
|
angular.mock.clearDataCache = function() {
|
@@ -1707,36 +1958,23 @@ angular.mock.clearDataCache = function() {
|
|
1707
1958
|
cache = angular.element.cache;
|
1708
1959
|
|
1709
1960
|
for(key in cache) {
|
1710
|
-
if (
|
1961
|
+
if (Object.prototype.hasOwnProperty.call(cache,key)) {
|
1711
1962
|
var handle = cache[key].handle;
|
1712
1963
|
|
1713
|
-
handle && angular.element(handle.elem).
|
1964
|
+
handle && angular.element(handle.elem).off();
|
1714
1965
|
delete cache[key];
|
1715
1966
|
}
|
1716
1967
|
}
|
1717
1968
|
};
|
1718
1969
|
|
1719
1970
|
|
1720
|
-
window.
|
1721
|
-
/**
|
1722
|
-
* Global method to output any number of objects into JSTD console. Useful for debugging.
|
1723
|
-
*/
|
1724
|
-
window.dump = function() {
|
1725
|
-
var args = [];
|
1726
|
-
angular.forEach(arguments, function(arg) {
|
1727
|
-
args.push(angular.mock.dump(arg));
|
1728
|
-
});
|
1729
|
-
jstestdriver.console.log.apply(jstestdriver.console, args);
|
1730
|
-
if (window.console) {
|
1731
|
-
window.console.log.apply(window.console, args);
|
1732
|
-
}
|
1733
|
-
};
|
1734
|
-
})(window);
|
1735
|
-
|
1971
|
+
if(window.jasmine || window.mocha) {
|
1736
1972
|
|
1737
|
-
|
1973
|
+
var currentSpec = null,
|
1974
|
+
isSpecRunning = function() {
|
1975
|
+
return !!currentSpec;
|
1976
|
+
};
|
1738
1977
|
|
1739
|
-
var currentSpec = null;
|
1740
1978
|
|
1741
1979
|
beforeEach(function() {
|
1742
1980
|
currentSpec = this;
|
@@ -1750,7 +1988,7 @@ window.jstestdriver && (function(window) {
|
|
1750
1988
|
currentSpec = null;
|
1751
1989
|
|
1752
1990
|
if (injector) {
|
1753
|
-
injector.get('$rootElement').
|
1991
|
+
injector.get('$rootElement').off();
|
1754
1992
|
injector.get('$browser').pollFns.length = 0;
|
1755
1993
|
}
|
1756
1994
|
|
@@ -1769,10 +2007,6 @@ window.jstestdriver && (function(window) {
|
|
1769
2007
|
angular.callbacks.counter = 0;
|
1770
2008
|
});
|
1771
2009
|
|
1772
|
-
function isSpecRunning() {
|
1773
|
-
return currentSpec && (window.mocha || currentSpec.queue.running);
|
1774
|
-
}
|
1775
|
-
|
1776
2010
|
/**
|
1777
2011
|
* @ngdoc function
|
1778
2012
|
* @name angular.mock.module
|
@@ -1785,9 +2019,11 @@ window.jstestdriver && (function(window) {
|
|
1785
2019
|
*
|
1786
2020
|
* See {@link angular.mock.inject inject} for usage example
|
1787
2021
|
*
|
1788
|
-
* @param {...(string|Function)} fns any number of modules which are represented as string
|
2022
|
+
* @param {...(string|Function|Object)} fns any number of modules which are represented as string
|
1789
2023
|
* aliases or as anonymous module initialization functions. The modules are used to
|
1790
|
-
* configure the injector. The 'ng' and 'ngMock' modules are automatically loaded.
|
2024
|
+
* configure the injector. The 'ng' and 'ngMock' modules are automatically loaded. If an
|
2025
|
+
* object literal is passed they will be register as values in the module, the key being
|
2026
|
+
* the module name and the value being what is returned.
|
1791
2027
|
*/
|
1792
2028
|
window.module = angular.mock.module = function() {
|
1793
2029
|
var moduleFns = Array.prototype.slice.call(arguments, 0);
|
@@ -1795,11 +2031,19 @@ window.jstestdriver && (function(window) {
|
|
1795
2031
|
/////////////////////
|
1796
2032
|
function workFn() {
|
1797
2033
|
if (currentSpec.$injector) {
|
1798
|
-
throw Error('Injector already created, can not register a module!');
|
2034
|
+
throw new Error('Injector already created, can not register a module!');
|
1799
2035
|
} else {
|
1800
2036
|
var modules = currentSpec.$modules || (currentSpec.$modules = []);
|
1801
2037
|
angular.forEach(moduleFns, function(module) {
|
1802
|
-
|
2038
|
+
if (angular.isObject(module) && !angular.isArray(module)) {
|
2039
|
+
modules.push(function($provide) {
|
2040
|
+
angular.forEach(module, function(value, key) {
|
2041
|
+
$provide.value(key, value);
|
2042
|
+
});
|
2043
|
+
});
|
2044
|
+
} else {
|
2045
|
+
modules.push(module);
|
2046
|
+
}
|
1803
2047
|
});
|
1804
2048
|
}
|
1805
2049
|
}
|
@@ -1813,13 +2057,45 @@ window.jstestdriver && (function(window) {
|
|
1813
2057
|
* *NOTE*: This function is also published on window for easy access.<br>
|
1814
2058
|
*
|
1815
2059
|
* The inject function wraps a function into an injectable function. The inject() creates new
|
1816
|
-
* instance of {@link
|
2060
|
+
* instance of {@link auto.$injector $injector} per test, which is then used for
|
1817
2061
|
* resolving references.
|
1818
2062
|
*
|
1819
|
-
* See also {@link angular.mock.module module}
|
1820
2063
|
*
|
2064
|
+
* ## Resolving References (Underscore Wrapping)
|
2065
|
+
* Often, we would like to inject a reference once, in a `beforeEach()` block and reuse this
|
2066
|
+
* in multiple `it()` clauses. To be able to do this we must assign the reference to a variable
|
2067
|
+
* that is declared in the scope of the `describe()` block. Since we would, most likely, want
|
2068
|
+
* the variable to have the same name of the reference we have a problem, since the parameter
|
2069
|
+
* to the `inject()` function would hide the outer variable.
|
2070
|
+
*
|
2071
|
+
* To help with this, the injected parameters can, optionally, be enclosed with underscores.
|
2072
|
+
* These are ignored by the injector when the reference name is resolved.
|
2073
|
+
*
|
2074
|
+
* For example, the parameter `_myService_` would be resolved as the reference `myService`.
|
2075
|
+
* Since it is available in the function body as _myService_, we can then assign it to a variable
|
2076
|
+
* defined in an outer scope.
|
2077
|
+
*
|
2078
|
+
* ```
|
2079
|
+
* // Defined out reference variable outside
|
2080
|
+
* var myService;
|
2081
|
+
*
|
2082
|
+
* // Wrap the parameter in underscores
|
2083
|
+
* beforeEach( inject( function(_myService_){
|
2084
|
+
* myService = _myService_;
|
2085
|
+
* }));
|
2086
|
+
*
|
2087
|
+
* // Use myService in a series of tests.
|
2088
|
+
* it('makes use of myService', function() {
|
2089
|
+
* myService.doStuff();
|
2090
|
+
* });
|
2091
|
+
*
|
2092
|
+
* ```
|
2093
|
+
*
|
2094
|
+
* See also {@link angular.mock.module angular.mock.module}
|
2095
|
+
*
|
2096
|
+
* ## Example
|
1821
2097
|
* Example of what a typical jasmine tests looks like with the inject method.
|
1822
|
-
*
|
2098
|
+
* ```js
|
1823
2099
|
*
|
1824
2100
|
* angular.module('myApplicationModule', [])
|
1825
2101
|
* .value('mode', 'app')
|
@@ -1850,17 +2126,31 @@ window.jstestdriver && (function(window) {
|
|
1850
2126
|
* inject(function(version) {
|
1851
2127
|
* expect(version).toEqual('overridden');
|
1852
2128
|
* });
|
1853
|
-
* )
|
2129
|
+
* });
|
1854
2130
|
* });
|
1855
2131
|
*
|
1856
|
-
*
|
2132
|
+
* ```
|
1857
2133
|
*
|
1858
2134
|
* @param {...Function} fns any number of functions which will be injected using the injector.
|
1859
2135
|
*/
|
2136
|
+
|
2137
|
+
|
2138
|
+
|
2139
|
+
var ErrorAddingDeclarationLocationStack = function(e, errorForStack) {
|
2140
|
+
this.message = e.message;
|
2141
|
+
this.name = e.name;
|
2142
|
+
if (e.line) this.line = e.line;
|
2143
|
+
if (e.sourceId) this.sourceId = e.sourceId;
|
2144
|
+
if (e.stack && errorForStack)
|
2145
|
+
this.stack = e.stack + '\n' + errorForStack.stack;
|
2146
|
+
if (e.stackArray) this.stackArray = e.stackArray;
|
2147
|
+
};
|
2148
|
+
ErrorAddingDeclarationLocationStack.prototype.toString = Error.prototype.toString;
|
2149
|
+
|
1860
2150
|
window.inject = angular.mock.inject = function() {
|
1861
2151
|
var blockFns = Array.prototype.slice.call(arguments, 0);
|
1862
2152
|
var errorForStack = new Error('Declaration Location');
|
1863
|
-
return isSpecRunning() ? workFn() : workFn;
|
2153
|
+
return isSpecRunning() ? workFn.call(currentSpec) : workFn;
|
1864
2154
|
/////////////////////
|
1865
2155
|
function workFn() {
|
1866
2156
|
var modules = currentSpec.$modules || [];
|
@@ -1873,9 +2163,13 @@ window.jstestdriver && (function(window) {
|
|
1873
2163
|
}
|
1874
2164
|
for(var i = 0, ii = blockFns.length; i < ii; i++) {
|
1875
2165
|
try {
|
2166
|
+
/* jshint -W040 *//* Jasmine explicitly provides a `this` object when calling functions */
|
1876
2167
|
injector.invoke(blockFns[i] || angular.noop, this);
|
2168
|
+
/* jshint +W040 */
|
1877
2169
|
} catch (e) {
|
1878
|
-
if(e.stack && errorForStack)
|
2170
|
+
if (e.stack && errorForStack) {
|
2171
|
+
throw new ErrorAddingDeclarationLocationStack(e, errorForStack);
|
2172
|
+
}
|
1879
2173
|
throw e;
|
1880
2174
|
} finally {
|
1881
2175
|
errorForStack = null;
|
@@ -1883,4 +2177,7 @@ window.jstestdriver && (function(window) {
|
|
1883
2177
|
}
|
1884
2178
|
}
|
1885
2179
|
};
|
1886
|
-
}
|
2180
|
+
}
|
2181
|
+
|
2182
|
+
|
2183
|
+
})(window, window.angular);
|