@@ -438,6 +438,119 @@ angular.mock.$LogProvider = function() {
438438} ;
439439
440440
441+ /**
442+ * @ngdoc service
443+ * @name ngMock.$interval
444+ *
445+ * @description
446+ * Mock implementation of the $interval service.
447+ *
448+ * Use {@link ngMock.$interval#flush `$interval.flush(millis)`} to
449+ * move forward by `millis` milliseconds and trigger any functions scheduled to run in that
450+ * time.
451+ *
452+ * @param {function() } fn A function that should be called repeatedly.
453+ * @param {number } delay Number of milliseconds between each function call.
454+ * @param {number= } [count=0] Number of times to repeat. If not set, or 0, will repeat
455+ * indefinitely.
456+ * @param {boolean= } [invokeApply=true] If set to `false` skips model dirty checking, otherwise
457+ * will invoke `fn` within the {@link ng.$rootScope.Scope#$apply $apply} block.
458+ * @returns {promise } A promise which will be notified on each iteration.
459+ */
460+ angular . mock . $IntervalProvider = function ( ) {
461+ this . $get = [ '$rootScope' , '$q' ,
462+ function ( $rootScope , $q ) {
463+ var repeatFns = [ ] ,
464+ nextRepeatId = 0 ,
465+ now = 0 ;
466+
467+ var $interval = function ( fn , delay , count , invokeApply ) {
468+ var deferred = $q . defer ( ) ,
469+ promise = deferred . promise ,
470+ count = ( isDefined ( count ) ) ? count : 0 ,
471+ iteration = 0 ,
472+ skipApply = ( isDefined ( invokeApply ) && ! invokeApply ) ;
473+
474+ promise . then ( null , null , fn ) ;
475+
476+ promise . $$intervalId = nextRepeatId ;
477+
478+ function tick ( ) {
479+ deferred . notify ( iteration ++ ) ;
480+
481+ if ( count > 0 && iteration >= count ) {
482+ var fnIndex ;
483+ deferred . resolve ( iteration ) ;
484+
485+ angular . forEach ( repeatFns , function ( fn , index ) {
486+ if ( fn . id === promise . $$intervalId ) fnIndex = index ;
487+ } ) ;
488+
489+ if ( fnIndex !== undefined ) {
490+ repeatFns . splice ( fnIndex , 1 ) ;
491+ }
492+ }
493+
494+ if ( ! skipApply ) $rootScope . $apply ( ) ;
495+ } ;
496+
497+ repeatFns . push ( {
498+ nextTime :( now + delay ) ,
499+ delay : delay ,
500+ fn : tick ,
501+ id : nextRepeatId ,
502+ deferred : deferred
503+ } ) ;
504+ repeatFns . sort ( function ( a , b ) { return a . nextTime - b . nextTime ; } ) ;
505+
506+ nextRepeatId ++ ;
507+ return promise ;
508+ } ;
509+
510+ $interval . cancel = function ( promise ) {
511+ var fnIndex ;
512+
513+ angular . forEach ( repeatFns , function ( fn , index ) {
514+ if ( fn . id === promise . $$intervalId ) fnIndex = index ;
515+ } ) ;
516+
517+ if ( fnIndex !== undefined ) {
518+ repeatFns [ fnIndex ] . deferred . reject ( 'canceled' ) ;
519+ repeatFns . splice ( fnIndex , 1 ) ;
520+ return true ;
521+ }
522+
523+ return false ;
524+ } ;
525+
526+ /**
527+ * @ngdoc method
528+ * @name ngMock.$interval#flush
529+ * @methodOf ngMock.$interval
530+ * @description
531+ *
532+ * Runs interval tasks scheduled to be run in the next `millis` milliseconds.
533+ *
534+ * @param {number= } millis maximum timeout amount to flush up until.
535+ *
536+ * @return {number } The amount of time moved forward.
537+ */
538+ $interval . flush = function ( millis ) {
539+ now += millis ;
540+ while ( repeatFns . length && repeatFns [ 0 ] . nextTime <= now ) {
541+ var task = repeatFns [ 0 ] ;
542+ task . fn ( ) ;
543+ task . nextTime += task . delay ;
544+ repeatFns . sort ( function ( a , b ) { return a . nextTime - b . nextTime ; } ) ;
545+ }
546+ return millis ;
547+ } ;
548+
549+ return $interval ;
550+ } ] ;
551+ } ;
552+
553+
441554( function ( ) {
442555 var R_ISO8061_STR = / ^ ( \d { 4 } ) - ? ( \d \d ) - ? ( \d \d ) (?: T ( \d \d ) (?: \: ? ( \d \d ) (?: \: ? ( \d \d ) (?: \. ( \d { 3 } ) ) ? ) ? ) ? ( Z | ( [ + - ] ) ( \d \d ) : ? ( \d \d ) ) ) ? $ / ;
443556
@@ -1581,6 +1694,7 @@ angular.module('ngMock', ['ng']).provider({
15811694 $browser : angular . mock . $BrowserProvider ,
15821695 $exceptionHandler : angular . mock . $ExceptionHandlerProvider ,
15831696 $log : angular . mock . $LogProvider ,
1697+ $interval : angular . mock . $IntervalProvider ,
15841698 $httpBackend : angular . mock . $HttpBackendProvider ,
15851699 $rootElement : angular . mock . $RootElementProvider
15861700} ) . config ( function ( $provide ) {
0 commit comments