dimanche 28 juin 2015

Unit testing AngularJS directive wrapping Snap.svg

I'm trying to create an Angular directive to wrap Snap.svg functionality, but I'm having trouble with unit testing it. So far I have a directive that looks like this:

'use strict';

angular.module('rpApp')
  .directive('rpSvgMap', function () {
    return {
      template: '<svg id="" width="" height=""></svg>',
      restrict: 'E',
      replace: true,
      // Don't isolate scope because we want to attach rpMap to parent scope
      link: function postLink(scope, element, attrs) {
        // Set up Snap.svg wrapper
        scope.rpMap = Snap('#' + attrs.id);
      }
    };
  });

And my Karma/Jasmine tests look like this:

'use strict';

describe('Directive: rpSvgMap', function () {

  // load the directive's module
  beforeEach(module('rpApp'));

  var element,
    scope;

    beforeEach(inject(function($rootScope,$compile) {
        scope = $rootScope.$new();
        element =
      '<rp-svg-map id="anyOldID" width="800" height="400" src="../../assets/testmap.svg"></rp-svg-map>';

        element = $compile(element)(scope);
        scope.$digest();
  }));

  describe('on initialization', function() {
    it('should create an SVG element with the provided dimensions and id', function() {
      expect(element.attr('id')).toBe('anyOldID');
      expect(element.attr('height')).toBe('400');
      expect(element.attr('width')).toBe('800');
    });
    it('should provide a working Snap.svg drawing surface', function() {
      var testCircle = scope.rpMap.circle(100,150,200);
      expect(testCircle.attr(cx)).toBe(100);
    });

});

The first test passes, and the second one fails as scope.rpMap always comes back as "null".

In the browser, this works just fine -- if I attach $scope to the window in my controller, rpMap is correctly wrapped by Snap.svg and rpMap.circle() correctly draws a circle.

So far as I can tell, the testing environment is properly loading snap.svg as a dependency and I'm reading scope properly out of the directive. For instance, if I add:

scope.hasSnap = angular.isFunction(Snap);

to the directive's link function, then this test passes:

it('should tell us when Snap.svg is available', function() {
      expect(scope.hasSnap).toBe(true);
    });

Snap() is not async and changing the beforeAll/it to asynchronous mode does not help.

Any ideas what I'm doing wrong here?

Aucun commentaire:

Enregistrer un commentaire