Monday, April 14, 2014

Can No Longer Test Polymer.dart Code


My tests are broken. Again. Time to fix my tests.

Actually, I have tests that have not passed for months at this point. Tonight, I am just going to fix the test that broke in the last 4 days (since I upgraded to Polymer.dart). Hmmm... this might not bode well for a solid test suite for Patterns in Polymer. I'll save that for another day. For now, I just want to get one Polymer element under test...

The first thing that I need to change is the no-longer-used initPolymer() from my test setup:
library x_pizza_test;

import 'package:scheduled_test/scheduled_test.dart';
import 'package:polymer/polymer.dart';


main() {
  initPolymer();

  // DOM element to hold test element
  PolymerElement _el;
  // Page object for better testing
  XPizzaComponent xPizza;

  // Tests here...
}
After deleting that line, I need another way to start the Polymer platform in my tests. In application code, this is now done with a <link> import, so I add that to the test page that holds my browser tests:
<head>
  <!-- Load Polymer -->
  <link rel="import" href="packages/polymer/polymer.html">

  <!-- Load component(s) -->
  <link rel="import" href="packages/model_example/elements/x-pizza.html">
  <script type="application/dart" src="test.dart"></script>
  <script src="packages/unittest/test_controller.js"></script>
</head>
With that, I get a nice failing test:
FAIL: [defaults] it has no toppings
  Caught ScheduleError:
  | Class 'HtmlElement' has no instance method 'async'.
  | 
  | NoSuchMethodError: method not found: 'async'
  | Receiver: Instance of 'HtmlElement'
  | Arguments: [Closure: (dynamic) => dynamic]
I think this is an indication that Polymer has not finished initializing when the test runs. The async() method on Polymer elements is something of a cure-all when it comes to dealing with the asynchronous nature of Polymer elements. It updates all observed variables in the associated Polymer and tells the polyfilled platform to flush—to process all queued UI updates. Since this is failing—and failing on an HtmlElement element instead of a PolymerElement—it seems likely that I need to wait for Polymer… to be ready.

I have to confess that I am unsure how to check for Polymer to be ready in Dart. In JavaScript, it is done by listening for a polymer-ready event, so I create a scheduled_test (unittest suped up for async) schedule to listen for polymer-ready:
main() {
  PolymerElement _el;
  XPizzaComponent xPizza;

  setUp((){
    schedule((){
      var _completer = new Completer();
      document.body.on['polymer-ready'].listen((_){
        _completer.complete();
      });
      return _completer.future;
    });
    // More setup...
  });
  // Tests here...
}
That seems to work. At least it changes the error message, which I count for progress.

The error message is now the Dart VM complaining about two main() entry points:
Dartium currently only allows a single Dart script tag per application, and in the future it will run them in separtate isolates.  To prepare for this all the following script tags need to be updated to use the mime-type "application/dart;component=1" instead of "application/dart":
​
Error: 

http://localhost:8081/:-1:
Only one Dart script tag allowed per document
Taking the advice the error message, I make my test part of the web component isolate with the mime type of application/dart;component=1:
<head>
  <!-- Load Polymer -->
  <link rel="import" href="packages/polymer/polymer.html">

  <!-- Load component(s) -->
  <link rel="import" href="packages/model_example/elements/x-pizza.html">
  <script src="packages/unittest/test_controller.js"></script>
</head>
<body>
  <!-- The actual tests -->
  <script type="application/dart;component=1" src="test.dart"></script>
</body>
That still does not work. The error message is now a baffling:
Exception: Unhandled exception:
Exception: The "smoke" library has not been configured. Make sure you import and configure one of the implementations (package:smoke/mirrors.dart or package:smoke/static.dart).
#0      throwNotConfiguredError (package:smoke/src/implementation.dart:34:3)
#1      typeInspector (package:smoke/src/implementation.dart:26:5)
#2      query (package:smoke/smoke.dart:85:20)
#3      _getPublishedProperties (package:polymer/src/declaration.dart:409:31)
#4      PolymerDeclaration.publishAttributes (package:polymer/src/declaration.dart:175:39)
#5      PolymerDeclaration.buildType (package:polymer/src/declaration.dart:95:22)
#6      PolymerDeclaration.register (package:polymer/src/declaration.dart:72:14)
#7      _hookJsPolymer.registerDart. (package:polymer/src/loader.dart:100:75)
#8      _rootRun (dart:async/zone.dart:719)
#9      _ZoneDelegate.run (dart:async/zone.dart:453)
#10     _CustomizedZone.run (dart:async/zone.dart:663)
#11     _hookJsPolymer.registerDart (package:polymer/src/loader.dart:99:22)
Ya know, if every time the library changes it takes me a hour of fiddling to get a single test passing, then I really have no hope of testing the Dart version of the book. But test I must, so...

I will have to pick back up with this tomorrow.



Day #34


1 comment: