diff options
| author | Matias Niemelä | 2013-08-28 19:32:20 -0400 | 
|---|---|---|
| committer | Misko Hevery | 2013-09-03 17:06:49 -0700 | 
| commit | 36ad40b18cfdd0690411a5169aa94e222946b5cf (patch) | |
| tree | 221c73bebdd87e91fa56fb3bc55cbf67e59cc0c0 /test/ng | |
| parent | 4e15c4fb47e93c1f6619a09125bc9a350e39b113 (diff) | |
| download | angular.js-36ad40b18cfdd0690411a5169aa94e222946b5cf.tar.bz2 | |
fix(ngAnimate): ensure that ngClass is always compiled before enter, leave and move animations
Closes #3727
Closes #3603
Diffstat (limited to 'test/ng')
| -rw-r--r-- | test/ng/directive/ngClassSpec.js | 123 | 
1 files changed, 95 insertions, 28 deletions
diff --git a/test/ng/directive/ngClassSpec.js b/test/ng/directive/ngClassSpec.js index a7148b6c..f0989f4a 100644 --- a/test/ng/directive/ngClassSpec.js +++ b/test/ng/directive/ngClassSpec.js @@ -308,40 +308,107 @@ describe('ngClass', function() {  describe('ngClass animations', function() {    var body, element, $rootElement; -  beforeEach(module('mock.animate')); - -  it("should avoid calling addClass accidentally when removeClass is going on", +  it("should avoid calling addClass accidentally when removeClass is going on", function() { +    module('mock.animate');      inject(function($compile, $rootScope, $animate, $timeout) { +      var element = angular.element('<div ng-class="val"></div>'); +      var body = jqLite(document.body); +      body.append(element); +      $compile(element)($rootScope); -    var element = angular.element('<div ng-class="val"></div>'); -    var body = jqLite(document.body); -    body.append(element); -    $compile(element)($rootScope); +      expect($animate.queue.length).toBe(0); -    expect($animate.queue.length).toBe(0); +      $rootScope.val = 'one'; +      $rootScope.$digest(); +      $animate.flushNext('addClass'); +      $animate.flushNext('addClass'); +      expect($animate.queue.length).toBe(0); -    $rootScope.val = 'one'; -    $timeout.flush(); +      $rootScope.val = ''; +      $rootScope.$digest(); +      $animate.flushNext('removeClass'); //only removeClass is called +      expect($animate.queue.length).toBe(0); -    $rootScope.$digest(); -    $animate.flushNext('addClass'); -    $animate.flushNext('addClass'); -    expect($animate.queue.length).toBe(0); +      $rootScope.val = 'one'; +      $rootScope.$digest(); +      $animate.flushNext('addClass'); +      expect($animate.queue.length).toBe(0); -    $rootScope.val = ''; -    $rootScope.$digest(); -    $animate.flushNext('removeClass'); //only removeClass is called -    expect($animate.queue.length).toBe(0); +      $rootScope.val = 'two'; +      $rootScope.$digest(); +      $animate.flushNext('removeClass'); +      $animate.flushNext('addClass'); +      expect($animate.queue.length).toBe(0); +    }); +  }); -    $rootScope.val = 'one'; -    $rootScope.$digest(); -    $animate.flushNext('addClass'); -    expect($animate.queue.length).toBe(0); +  it("should consider the ngClass expression evaluation before performing an animation", function() { + +    //mocks are not used since the enter delegation method is called before addClass and +    //it makes it impossible to test to see that addClass is called first +    module('ngAnimate'); + +    var digestQueue = []; +    module(function($animateProvider) { +      $animateProvider.register('.crazy', function() { +        return { +          enter : function(element, done) { +            element.data('state', 'crazy-enter'); +            done(); +          } +        }; +      }); + +      return function($rootScope) { +        var before = $rootScope.$$postDigest; +        $rootScope.$$postDigest = function() { +          var args = arguments; +          digestQueue.push(function() { +            before.apply($rootScope, args); +          }); +        }; +      }; +    }); +    inject(function($compile, $rootScope, $rootElement, $animate, $timeout, $document) { -    $rootScope.val = 'two'; -    $rootScope.$digest(); -    $animate.flushNext('removeClass'); -    $animate.flushNext('addClass'); -    expect($animate.queue.length).toBe(0); -  })); +      //since we skip animations upon first digest, this needs to be set to true +      $animate.enabled(true); + +      $rootScope.val = 'crazy'; +      var element = angular.element('<div ng-class="val"></div>'); +      jqLite($document[0].body).append($rootElement); + +      $compile(element)($rootScope); + +      var enterComplete = false; +      $animate.enter(element, $rootElement, null, function() { +        enterComplete = true; +      }); + +      //jquery doesn't compare both elements properly so let's use the nodes +      expect(element.parent()[0]).toEqual($rootElement[0]); +      expect(element.hasClass('crazy')).toBe(false); +      expect(enterComplete).toBe(false); + +      expect(digestQueue.length).toBe(1); +      $rootScope.$digest(); + +      $timeout.flush(); + +      expect(element.hasClass('crazy')).toBe(true); +      expect(enterComplete).toBe(false); + +      digestQueue.shift()(); //enter +      expect(digestQueue.length).toBe(0); + +      //we don't normally need this, but since the timing between digests +      //is spaced-out then it is required so that the original digestion +      //is kicked into gear +      $rootScope.$digest(); +      $timeout.flush(); + +      expect(element.data('state')).toBe('crazy-enter'); +      expect(enterComplete).toBe(true); +    }); +  });  });  | 
