I am fairly excited to have a continuous integration solution for Patterns in Polymer. This is probably something I should have done a long time back, but I now run tests whenever Dart is updated and at least daily to check for newer versions of Polymer. This should go a long way toward helping (forcing) me to keep the book up to date. I am not quite done, however.
I have the each chapter's project code under test for the JavaScript edition of the book. But the Dart edition is not quite so complete. Hopefully this will not be too hard to rectify. Many chapters share similar code so the tests can be similar (or identical), which is what I found with the JavaScript tests. But I am not going to start there. Instead, I am curious if my struggles with testing the internationalization solution in JavaScript will continue into Dart.
I do not have any “real” trouble testing Polymer elements in JavaScript, just expressing the tests succinctly. The need to wait an event loop for Polymer to render changes leads to awkward
beforeEach()
blocks like: describe('it can localize to French', function(){
beforeEach(function(done) {
el.locale = 'fr';
setTimeout(done, 0); // One event loop for element to update
});
it('(fr)', function(){
expect(el.shadowRoot.textContent).toContain('Bonjour');
});
});
Hopefully Dart's async support will make this a little cleaner.The
pubspec.yaml
configuration file depends on unconstrained versions of Polymer and scheduled_test:name: i18n dependencies: polymer: any dev_dependencies: scheduled_test: any transformers: - polymer: entry_points: web/index.htmlThe scheduled_test library is a slight variation on unittest (both are from the Dart core team), but with better asynchronous support.
A test of the element is fairly straigh-forward. With scheduled_tests, I need to wrap everything that would otherwise happen asynchronously in a
schedule()
. In this case, I schedule Polymer being ready, the <hello-you>
element being ready, and then the test itself:main() { initPolymer(); PolymerElement _el; setUp((){ schedule(()=> Polymer.onReady); schedule((){ _el = createElement('<hello-you></hello-you>'); document.body.append(_el); var _completer = new Completer(); _el.async((_)=> _completer.complete()); return _completer.future; }); currentSchedule.onComplete.schedule(() => _el.remove()); }); group("<hello-you/> (i18n)", (){ test('defaults to English', (){ schedule((){ expect(_el.shadowRoot.text, contains('Hello')); }); }); }); // ... }That passes, and has the definite advantage of being cleaner than the JavaScript equivalent (which required those unsightly
beforeEach()
blocks). But, this only passes when I run this in the browser from pub serve
, which starts a test build on http://localhost:8081
.The problem is that my i18n solution loads its localizations from separate JSON files via Ajax (actually
core-ajax
Polymer elememts). Loading files via Ajax will not work with a normal content_shell command-line run:$ content_shell --dump-render-tree --allow-file-access-from-files test/index.html #READY CONSOLE MESSAGE: unittest-suite-wait-for-done CONSOLE MESSAGE: FAIL: <hello-you/> (i18n) defaults to English Caught The schedule had 3 errors: ScheduleError: "Instance of '_XMLHttpRequestProgressEvent'" Stack chain: | dart:html _handleMutation ...It looks like I am going to have to start pub server, then run content_shell tests against it instead of local files:
$ content_shell --dump-render-tree http://localhost:8081/ #READY CONSOLE MESSAGE: unittest-suite-wait-for-done CONSOLE MESSAGE: PASS: <hello-you/> (i18n) defaults to English CONSOLE MESSAGE: CONSOLE MESSAGE: All 1 tests passed. CONSOLE MESSAGE: unittest-suite-success CONSOLE WARNING: line 213: PASSWhich is not ideal, but it will work. Dart Pub, which is the package manager for Dart, includes a web server that is primarily useful for smoke testing applications and elements. It normally spins up a web server on localhost:8080. But, if pub notices a
test
subdirectory, it will spin up a secondary server on localhost:8081:$ pub serve ... Loading polymer transformers... (1.1s) Serving i18n web on http://localhost:8080 Serving i18n test on http://localhost:8081Since Dart pub is already installed as part of Dart, I do not need to worry about extra dependencies on my test server. I just spin up
pub serve
and run my tests as usual. In fact, this is a nice answer to the one of the benefits of a test runner in JavaScript-land.Day #190
No comments:
Post a Comment