Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

ngAnimate interferes with unit tests concerning ngClass in v1.2.0-rc.2 and an aside... #4023

Closed
wizardwerdna opened this issue Sep 17, 2013 · 3 comments

Comments

@wizardwerdna
Copy link
Contributor

I have some unit tests for a directive that worked fine until I migrated to the latest release candidate. The tests pass without incident even under the RC, but fail if the main module includes 'ngAnimate', even where, as here, the application has no animations defined or used. Somehow a routine synchronous test goes funky.

The application works fine when run in production.

The following plnkr illustrates the problem:

http://plnkr.co/edit/ZpdjrlZMADdeGxKYpR9Z?p=preview

The directive

app.directive('directive', function(){
  return {
    template: '<dir ng-class="blues()">'+
                'This text is {{blues()}}, but the test failed.'+
               '</dir>',
    restrict: 'E',
    replace: true,
    link: function(scope, element, attrs){
      scope.blues = function(){return 'blue';};
    }
  };
});

The test

  ...
  beforeEach(inject(function($rootScope, $compile) {
    scope = $rootScope.$new();
    element = $compile('<directive></directive>')(scope);
    $rootScope.$digest();
  }));
  ...
  it('should have the text be blue', function() {
    expect(element.hasClass('blue')).toBeTruthy();
  });
  ...

(just remove ngAnimate in the app.js definition of the main module to see tests pass).

The problem seems to have something to do with the recent changes to ng-class and animation. No amount of research seems to work. What's going on?

Pure aside: I note that the angular.mock.animate decorator doesn't seem to get installed merely by adding angular-mock.js to my build in ordinary course. ($animate does not have flushNext coded.) Do I need to do anything special, or load in any particular order to make the config work right?

@matsko
Copy link
Contributor

matsko commented Sep 30, 2013

In an effort to keep ngAnimate animation onComplete events as async, a timeout is called. In this case, before the blue class is added, the timeout has to be fired, but angular-mocks.js buffers the result.

Here's a fix for your code:
http://plnkr.co/edit/27KAnbvH28kfDzgRLocA?p=preview

The solution may be to change this inside of ngAnimate. So the timeout only occurs on the callback and not when there is no animation. @IgorMinar what do you think?

@matsko
Copy link
Contributor

matsko commented Oct 1, 2013

@wizardwerdna there is no reason to use $timeout anyone in that spot. So this fix will make your code work without any changes: matsko@d546a83

@matsko
Copy link
Contributor

matsko commented Oct 11, 2013

@wizardwerdna unfortunately with the recent commits to ngAnimate, you are required to call $timeout.flush() once or twice during each animation for each directive as well as $rootScope.$digest() if you use $animate directly.

My suggestion is to avoid including ngAnimate as a dep in your test code unless you really want to perform testing on it.

jamesdaily pushed a commit to jamesdaily/angular.js that referenced this issue Jan 27, 2014
jamesdaily pushed a commit to jamesdaily/angular.js that referenced this issue Jan 27, 2014
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.