vendor/assets/javascripts/angular-mocks.js in angularjs-rails-1.2.0.rc2 vs vendor/assets/javascripts/angular-mocks.js in angularjs-rails-1.2.0.rc3

- old
+ new

@@ -1,7 +1,7 @@ /** - * @license AngularJS v1.2.0-rc.2 + * @license AngularJS v1.2.0-rc.3 * (c) 2010-2012 Google, Inc. http://angularjs.org * License: MIT * * TODO(vojta): wrap whole file into closure during build */ @@ -73,10 +73,17 @@ self.deferredFns.sort(function(a,b){ return a.time - b.time;}); return self.deferredNextId++; }; + /** + * @name ngMock.$browser#defer.now + * @propertyOf ngMock.$browser + * + * @description + * Current milliseconds mock time. + */ self.defer.now = 0; self.defer.cancel = function(deferId) { var fnIndex; @@ -117,33 +124,10 @@ while (self.deferredFns.length && self.deferredFns[0].time <= self.defer.now) { self.deferredFns.shift().fn(); } }; - /** - * @name ngMock.$browser#defer.flushNext - * @methodOf ngMock.$browser - * - * @description - * Flushes next pending request and compares it to the provided delay - * - * @param {number=} expectedDelay the delay value that will be asserted against the delay of the next timeout function - */ - self.defer.flushNext = function(expectedDelay) { - var tick = self.deferredFns.shift(); - expect(tick.time).toEqual(expectedDelay); - tick.fn(); - }; - - /** - * @name ngMock.$browser#defer.now - * @propertyOf ngMock.$browser - * - * @description - * Current milliseconds mock time. - */ - self.$$baseHref = ''; self.baseHref = function() { return this.$$baseHref; }; }; @@ -452,10 +436,123 @@ return $log; }; }; +/** + * @ngdoc service + * @name ngMock.$interval + * + * @description + * Mock implementation of the $interval service. + * + * Use {@link ngMock.$interval#flush `$interval.flush(millis)`} to + * move forward by `millis` milliseconds and trigger any functions scheduled to run in that + * time. + * + * @param {function()} fn A function that should be called repeatedly. + * @param {number} delay Number of milliseconds between each function call. + * @param {number=} [count=0] Number of times to repeat. If not set, or 0, will repeat + * indefinitely. + * @param {boolean=} [invokeApply=true] If set to `false` skips model dirty checking, otherwise + * will invoke `fn` within the {@link ng.$rootScope.Scope#$apply $apply} block. + * @returns {promise} A promise which will be notified on each iteration. + */ +angular.mock.$IntervalProvider = function() { + this.$get = ['$rootScope', '$q', + function($rootScope, $q) { + var repeatFns = [], + nextRepeatId = 0, + now = 0; + + var $interval = function(fn, delay, count, invokeApply) { + var deferred = $q.defer(), + promise = deferred.promise, + count = (angular.isDefined(count)) ? count : 0, + iteration = 0, + skipApply = (angular.isDefined(invokeApply) && !invokeApply); + + promise.then(null, null, fn); + + promise.$$intervalId = nextRepeatId; + + function tick() { + deferred.notify(iteration++); + + if (count > 0 && iteration >= count) { + var fnIndex; + deferred.resolve(iteration); + + angular.forEach(repeatFns, function(fn, index) { + if (fn.id === promise.$$intervalId) fnIndex = index; + }); + + if (fnIndex !== undefined) { + repeatFns.splice(fnIndex, 1); + } + } + + if (!skipApply) $rootScope.$apply(); + }; + + repeatFns.push({ + nextTime:(now + delay), + delay: delay, + fn: tick, + id: nextRepeatId, + deferred: deferred + }); + repeatFns.sort(function(a,b){ return a.nextTime - b.nextTime;}); + + nextRepeatId++; + return promise; + }; + + $interval.cancel = function(promise) { + var fnIndex; + + angular.forEach(repeatFns, function(fn, index) { + if (fn.id === promise.$$intervalId) fnIndex = index; + }); + + if (fnIndex !== undefined) { + repeatFns[fnIndex].deferred.reject('canceled'); + repeatFns.splice(fnIndex, 1); + return true; + } + + return false; + }; + + /** + * @ngdoc method + * @name ngMock.$interval#flush + * @methodOf ngMock.$interval + * @description + * + * Runs interval tasks scheduled to be run in the next `millis` milliseconds. + * + * @param {number=} millis maximum timeout amount to flush up until. + * + * @return {number} The amount of time moved forward. + */ + $interval.flush = function(millis) { + now += millis; + while (repeatFns.length && repeatFns[0].nextTime <= now) { + var task = repeatFns[0]; + task.fn(); + task.nextTime += task.delay; + repeatFns.sort(function(a,b){ return a.nextTime - b.nextTime;}); + } + return millis; + }; + + return $interval; + }]; +}; + + (function() { var R_ISO8061_STR = /^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?:\:?(\d\d)(?:\:?(\d\d)(?:\.(\d{3}))?)?)?(Z|([+-])(\d\d):?(\d\d)))?$/; function jsonStringToDate(string) { var match; @@ -670,11 +767,11 @@ tick.fn(); return tick; } }; - forEach(['enter','leave','move','addClass','removeClass'], function(method) { + angular.forEach(['enter','leave','move','addClass','removeClass'], function(method) { animate[method] = function() { var params = arguments; animate.queue.push({ method : method, params : params, @@ -745,11 +842,11 @@ function serializeScope(scope, offset) { offset = offset || ' '; var log = [offset + 'Scope(' + scope.$id + '): {']; for ( var key in scope ) { - if (scope.hasOwnProperty(key) && !key.match(/^(\$|this)/)) { + if (Object.prototype.hasOwnProperty.call(scope, key) && !key.match(/^(\$|this)/)) { log.push(' ' + key + ': ' + angular.toJson(scope[key])); } } var child = scope.$$childHead; while(child) { @@ -1595,10 +1692,11 @@ */ angular.module('ngMock', ['ng']).provider({ $browser: angular.mock.$BrowserProvider, $exceptionHandler: angular.mock.$ExceptionHandlerProvider, $log: angular.mock.$LogProvider, + $interval: angular.mock.$IntervalProvider, $httpBackend: angular.mock.$HttpBackendProvider, $rootElement: angular.mock.$RootElementProvider }).config(function($provide) { $provide.decorator('$timeout', angular.mock.$TimeoutDecorator); }); @@ -1787,11 +1885,11 @@ angular.mock.clearDataCache = function() { var key, cache = angular.element.cache; for(key in cache) { - if (cache.hasOwnProperty(key)) { + if (Object.prototype.hasOwnProperty.call(cache,key)) { var handle = cache[key].handle; handle && angular.element(handle.elem).off(); delete cache[key]; } @@ -1890,12 +1988,44 @@ * * The inject function wraps a function into an injectable function. The inject() creates new * instance of {@link AUTO.$injector $injector} per test, which is then used for * resolving references. * - * See also {@link angular.mock.module module} * + * ## Resolving References (Underscore Wrapping) + * Often, we would like to inject a reference once, in a `beforeEach()` block and reuse this + * in multiple `it()` clauses. To be able to do this we must assign the reference to a variable + * that is declared in the scope of the `describe()` block. Since we would, most likely, want + * the variable to have the same name of the reference we have a problem, since the parameter + * to the `inject()` function would hide the outer variable. + * + * To help with this, the injected parameters can, optionally, be enclosed with underscores. + * These are ignored by the injector when the reference name is resolved. + * + * For example, the parameter `_myService_` would be resolved as the reference `myService`. + * Since it is available in the function body as _myService_, we can then assign it to a variable + * defined in an outer scope. + * + * ``` + * // Defined out reference variable outside + * var myService; + * + * // Wrap the parameter in underscores + * beforeEach( inject( function(_myService_){ + * myService = _myService_; + * })); + * + * // Use myService in a series of tests. + * it('makes use of myService', function() { + * myService.doStuff(); + * }); + * + * ``` + * + * See also {@link angular.mock.module angular.mock.module} + * + * ## Example * Example of what a typical jasmine tests looks like with the inject method. * <pre> * * angular.module('myApplicationModule', []) * .value('mode', 'app') @@ -1924,14 +2054,14 @@ * }); * * inject(function(version) { * expect(version).toEqual('overridden'); * }); - * )); + * }); * }); * * </pre> - * + * * @param {...Function} fns any number of functions which will be injected using the injector. */ window.inject = angular.mock.inject = function() { var blockFns = Array.prototype.slice.call(arguments, 0); var errorForStack = new Error('Declaration Location');