Up tonight, I finish off changes to the changes-from-the-outside chapter of Patterns in Polymer. During my recent hiatus, I got loads of great feedback on this and other chapters. I still have two more bits of advice to put to use in this chapter: better Polymer detection and better node finding.
First, it was pointed out that relying on a “double underscore” property is likely not a recipe for long term success. While waiting on a custom element to be upgraded by Polymer, I had been polling for the
__upgraded__
property:function onPolymerReady(el, fn) { if (el.__upgraded__) fn(); else setTimeout(function(){onPolymerReady(el, fn);}, 10); }Although the semantics of the property name fit my need here, it is bad form to use an internal property as indicated by the double underscores. So I instead wait for a significant Polymer property:
$
.Happily, the code change is minor:
function onPolymerReady(el, fn) { if (el.$) fn(); else setTimeout(function(){onPolymerReady(el, fn);}, 10); }And, even more happily, my tests from last night continue to work so I am good to go with that change.
Next up is a change that reminds me that I really need to get back to Dart:
Math.random()
testing in JavaScript. The simple <hello-you>
Polymer element that is being tested in this chapter can randomly change the color of the <h2>
element:Per some other feedback on the chapter, I need to change how the
<h2>
element is found. Before I do that, I need a test to verify the existing functionality. But how to test a random number? If this were Dart, I could seed the random number. But, since this is JavaScript, I need to stub Math.random
. Thankfully, I stuck with the Karma test runner's default testing framework, Jasmine. That means that I can spy on Math.random
and return a value that ensures that I always see the last value in “randomized” list: describe('clicking', function(){
beforeEach(function(){
spyOn(Math, "random").andReturn(0.99);
// ...
});
// ...
});
In my case, the color green is the last in the list: describe('clicking', function(){
beforeEach(function(){
spyOn(Math, "random").andReturn(0.99);
// ...
});
it('randomly changes the title\'s color', function(){
var button = el.shadowRoot.querySelector('button');
var e = document.createEvent('MouseEvent');
e.initMouseEvent(
"click", true, true, window,
0, 0, 0, 80, 20,
false, false, false, false, 0, null
);
button.dispatchEvent(e);
var h2 = el.shadowRoot.querySelector('h2');
expect(h2.style.color).toEqual('green');
});
});
I verify that this is actually doing what I think it does by changing the andReturn
value from 0.99
to zero. The test then fails because the color is red instead of green. In other words, I have a decent test.With that, I can simplify the code that randomizes the color from this:
feelingLucky: function() {
var num = Math.floor(colors.length*Math.random());
this.color = colors[num];
this.
shadowRoot.
querySelector('h2').
style.color = this.color;
}
Instead, I can give the <h2>
an ID and use Polymer's automatic node finding: feelingLucky: function() {
var num = Math.floor(colors.length*Math.random());
this.color = colors[num];
this.$.hello.style.color = this.color;
}
And, since my test continues to pass, I am safe in the knowledge that I have not introduced any bugs into the narrative of the chapter.One chapter down, 14 to go. Actually, it is not as bad as all that. Now that I am getting in the regression testing groove, I expect the remainder of the chapters to go a little smoother. Of course, some of the chapters have more feedback than others, so I still need to hop to it. Which I do right now...
Day #3
No comments:
Post a Comment