Подтвердить что ты не робот

NgAnimate 1.4.7 unit test не вызывает функции анимации

Я работаю из этого урока и имеет googled ad nauseum, но я не могу получить то, что кажется тривиальным ngAnimate unit test работает.

У меня ngAnimate хорошо работает в приложении. Все основные библиотеки Angular - это версии 1.4.7.

Модуль

angular.module 'MyAnimation', [ 'ngAnimate' ]
  .animation '.added-class', ->
    addClass: (element, className, done) ->
      console.log 'add class triggered'
      element.css 'opacity', '0.5'
      done()

Test

describe 'MyAnimation', ->
  beforeEach -> module 'ngAnimate'
  beforeEach -> module 'ngAnimateMock'
  beforeEach -> module 'MyAnimation'

  it 'animates', -> inject ($animate, $rootScope, $rootElement) ->
    $animate.enabled(true)
    divElement = angular.element '<div>my div</div>'

    # Kick off initial digest loop in which no animations are run.
    $rootScope.$digest()

    # Trigger animation.
    $animate.addClass divElement, 'added-class'
    $rootScope.$digest()

    # Tried this, doesn't seem to do anything.
    # $animate.flush()

    # Results in AssertionError: expected '' to equal '0.5'
    expect(divElement.css('opacity')).to.eq '0.5'

Я уверен, что модуль включен в тест, но запуск $animate.enter даже не дает мне мой вывод log.

Я пробовал это с другими функциями $animate, и я ничего не получаю. Помощь?

4b9b3361

Ответ 1

После серьезного перекопа в исходный код Angular кажется, что виновником является внутренняя проверка areAnimationsAllowed, которая использует Angular чтобы определить, нужно ли прервать анимацию раньше. Помимо прочего, он проверяет, что анимированный node является потомком $rootElement и тела документа.

Здесь у вас есть два варианта.

  • Plunker. Прикрепите node анимацию к $rootElement и прикрепите $rootElement к телу. Последнее необходимо, потому что ngMock на самом деле заглушает $rootElement с отсоединенным <div> node, хранящимся в памяти. Пример:
var element, body, root;
beforeEach(module('ngAnimate', 'ngAnimateMock', 'MyAnimation'));
beforeEach(inject(function ($animate, $document, $rootElement, $rootScope) {
  // enable animations globally
  $animate.enabled(true);

  // create a node to be animated and inject it into the DOM
  element = angular.element('<div></div>');
  root = $rootElement.append(element)[0];
  body = $document[0].body;
  body.appendChild(root);

  // trigger initial digest
  $rootScope.$digest();
}));
afterEach(function () {
  // clean up
  body.removeChild(root);
});
  1. Plunker. Не тестируйте свою анимацию с помощью $animate.addClass, но вместо этого используйте службу $$animateJs нижнего уровня. Angular использует внутри своих собственных тестов, я предполагаю, что вы обойдете вышеуказанную проверку. Пример:
it('should animate', inject(function ($animate, $$animateJs) {
  // trigger animation
  $$animateJs(element, 'addClass', {
    addClass: 'added-class'
  }).start();
  $animate.flush();
}));

Если вы запустите Plunkers и проверьте консоль, вы увидите сообщение "addClass triggered". Я также добавил пару утверждений.

Оба решения хакерские и недокументированные, и оба становятся все более активными, если ваша анимация addClass делает что-то асинхронное (что я предполагаю, что оно будет). К сожалению, я не могу найти лучший способ тестирования анимации JS. Раньше я фактически игнорировал код анимации из-за охвата, потому что это было трудно проверить.