mardi 9 juin 2015

Test with mouseover & mouseleave only works when executed alone or in $timeout() function

I have written tests for this directive that shows bootstrap tooltips:

.directive('mwTooltip', function () {
  return {
    restrict: 'A',
    scope: {
      text: '@mwTooltip',
      placement: '@'
    },
    link: function (scope, el) {
      var offText = scope.$watch('text', function (newVal) {
        el.popover('destroy');
        el.popover({
          trigger: 'hover',
          placement: scope.placement || 'bottom',
          content: newVal,
          container: 'body'
        });
      });

      scope.$on('$destroy', function () {
        var popover = el.data('bs.popover');
        if (popover && popover.tip()) {
          popover.tip().detach().remove();
        }
        offText();
      });
    }
  };
})

This test does not pass:

describe('mwTooltip', function () {
  var $compile;
  var $rootScope;
  var scope;
  var el;
  var isolateScope;

  beforeEach(module('mwComponents'));

  beforeEach(inject(function (_$compile_, _$rootScope_) {
    $compile = _$compile_;
    $rootScope = _$rootScope_;
    scope = _$rootScope_.$new();

    el = angular.element(
      '<span mw-tooltip="Tooltip"></span>'
    );

    $compile(el)(scope);
    isolateScope = el.isolateScope();
    scope.$digest();
  }));

  afterEach(function () {
    scope.$destroy();

  });

  it('should show and remove a tooltip', function () {
    el.trigger('mouseover');
    expect(angular.element('.popover').text()).toEqual('Tooltip');

    el.trigger('mouseleave');
    expect(angular.element('.popover').text()).toEqual('');
  });

});

The error is:

PhantomJS 1.9.8 (Mac OS X 0.0.0): Executed 114 of 311 SUCCESS (0 secs / 0.446 secs)
PhantomJS 1.9.8 (Mac OS X 0.0.0) mwTooltip should show and remove a tooltip FAILED
Expected 'Tooltip' to equal ''.
  at /Users/mles/portal-admin/test/ui/mwComponents/mw-tooltip.js:34
PhantomJS 1.9.8 (Mac OS X 0.0.0): Executed 306 of 311 (1 FAILED) (skipped 5) (18.48 secs / 18.539 secs)

However if I put the test in a $timeout it works:

it('should show and remove a tooltip', function ($timeout) {
  el.trigger('mouseover');
  expect(angular.element('.popover').text()).toEqual('Tooltip');

  $timeout(function () {
    el.trigger('mouseleave');
    expect(angular.element('.popover').text()).toEqual('');
  }, 0);
});

or if it is run as a single test (notice the fbefore the it)

fit('should show and remove a tooltip', function () {
  el.trigger('mouseover');
  expect(angular.element('.popover').text()).toEqual('Tooltip');

  el.trigger('mouseleave');
  expect(angular.element('.popover').text()).toEqual('');
});

Am I missing some kind of async call here?

Aucun commentaire:

Enregistrer un commentaire