Wednesday, April 30, 2014

Polymer Elements as Text Fixtures


Up today, I test angular-bind-polymer.

As much fun as it has been mucking around with dynamically building Polymer definitions, I think my timebox around the exploration has expired. Off the top of my head, I cannot even say why I decided a test was needed in the first place (who needs a memory when you blog every day — it was because I think I can significantly simplify the code).

The angular-bind-polymer library enables double data binding between AngularJS attributes and Polymer attributes. Pushing changes down from AngularJS into a Polymer works out of the box. Listening for changes from Polymer so that bound variables in the current Angular scope does not work (at least it did not a while back). Hence the need the angular-bind-polymer directive.

To test my directive, I need a generic custom element, which is what started me on my little adventure to generate dynamic Polymer definitions. I had great fun along the way, but it is time to get the test written as best I can so that I can move on. Which, of course, begs the question of what is best practice when you need to work with a generic Polymer in tests?

I think I probably came close late last week when I wrote a simple definition in a test fixture file and loaded it as part of the Karma / Jasmine setup:
var script = document.createElement("script");
script.src = "/base/bower_components/platform/platform.js";
document.getElementsByTagName("head")[0].appendChild(script);

var link = document.createElement("link");
link.rel = "import";
link.href = "/base/test/x-double.html";
document.getElementsByTagName("head")[0].appendChild(link);
// ...
With the definition loaded in the Karma setup, I can then test pure custom elements by building them in test setup (aka beforeEach):
  var container, customElement;
  beforeEach(function(){
    container = document.createElement('div');
    document.body.appendChild(container);

    container.innerHTML = '';
    customElement = container.children[0];

    var done = false;
    setTimeout(function(){ done = true; }, 0);
    waitsFor(function(){ return done; });
  });
Creating the container <div> and the <x-double> custom element are simple DOM manipulations—as is adding them to the document body. I declare the container and customElement outside the beforeEach() function scope so that I can remove them after each test and so that I can set actual test expectations on the customElement. The only real trick in there is the waitsFor() which I figured out last week. It ensures that the Polymer library has had a chance to decorate <x-double> with all of the methods that are described in the Polymer definition.

Setting expectations in tests is then simple:
  it('works', function(){
    expect(customElement.getAttribute('out')).toEqual('84');
  });
Now to get the Angular directive test setup properly. Tomorrow.



Day #50

No comments:

Post a Comment