Monday, June 30, 2014

Benchmarking Dart (and dart2js) Code in the Browser


I am a benchmarking fool. I so enjoyed benchmarking various implementations of the Factory Method pattern, that I try it again today. Yesterday I ran the benchmarks from the command-line. Today, I wonder what my options are for benchmarking Dart code in the browser.

To benchmark Dart from the command-line, I used the dart system command that comes with the SDK. For good measure, I also compiled my benchmark harness into JavaScript and ran it with node.js. Amazingly, that worked without any effort on my part.

It worked so well, I thought why not try it in the browser? There may wind up being a web-specific design pattern or two in Design Patterns in Dart, so while this benchmarking stuff is fresh in my brain, I ought to see how it might work in the browser instead of from the command-line. With a qualifier...

Even though these benchmarks will be run in the browser, I want the results readily accessible from the command-line. I would like the ability to review progress of any benchmarks as I refine pattern approaches and that needs to be automated or it simply won't happen.

So I create a web sub-directory in my factory_method sample code, copy in yesterday's benchmark.dart and start with a simple index.html:
<!DOCTYPE html>
<html>
  <head>
    <script type="application/dart" src="benchmark.dart"></script>
    <script src="packages/browser/dart.js"></script>
  </head>
  <body></body>
</html>
I do not know how these things are normally done in JavaScript, but if I want the console.log output from Dart code, I stick with content_shell, which is bundled with the SDK. And this works right off the bat:
$ content_shell --dump-render-tree web/index.html
#READY
CONSOLE MESSAGE: Factory Method — Subclass(RunTime): 0.09106837778077291 us.
CONSOLE MESSAGE: Factory Method — Map of Factories(RunTime): 1.8514472763359118 us.
CONSOLE MESSAGE: Factory Method — Mirrors(RunTime): 12.328632014991616 us.
Content-Type: text/plain
layer at (0,0) size 800x600
  RenderView at (0,0) size 800x600
layer at (0,0) size 800x8
  RenderBlock {HTML} at (0,0) size 800x8
    RenderBody {BODY} at (8,8) size 784x0
#EOF
#EOF
#EOF
Nice. Those numbers are comparable to the Dart command-line numbers from yesterday, so all appears to be in good shape with benchmarking pure Dart in the browser. What about dart2js compiled JavaScript?

I could try dumping it into a test runner like Karma, but that seems crazy. I mean more crazy than most of the stuff I try. Maybe content_shell will work for this as well? To test that out, I pub build my benchmark application which compiles the index.html page and associated code:
$ pub build
Loading source assets...
Building factory_method_code...
[Info from Dart2JS]:
Compiling factory_method_code|web/benchmark.dart...
[Dart2JS on factory_method_code|web/benchmark.dart]:
1 warning(s) suppressed in dart:_js_mirrors.
[Warning from Dart2JS]:
web/benchmark.dart:
2391 methods retained for use by dart:mirrors out of 3411 total methods (70%).
[Info from Dart2JS on factory_method_code|web/benchmark.dart]:
packages/factory_method_code/mirrors.dart:3:1:
This import is not annotated with @MirrorsUsed, which may lead to unnecessarily large generated code.
Try adding '@MirrorsUsed(...)' as described at https://goo.gl/Akrrog.
import 'dart:mirrors';
^^^^^^^^^^^^^^^^^^^^^^
[Info from Dart2JS]:
Took 0:00:13.648601 to compile factory_method_code|web/benchmark.dart.
Built 5 files to "build".
Note to self: I really need to look into that @MirrorUsed annotation. Some other day.

For now, I have compiled JavaScript and page in the build directory:
$ tree -L 2 build
build
└── web
    ├── benchmark.dart.js
    ├── benchmark.dart.precompiled.js
    ├── index.html
    └── packages

2 directories, 3 files
I cannot just run that code because content_shell from the Dart SDK has the Dart VM included. With the Dart VM available, content_shell would try to run the Dart code which was not included in the build process.

So, just to see if this works, I hand-edit the generated HTML to directly point to the compiled benchmark.dart.js file instead of relying on the usual browser/dart.js to do it:
<!DOCTYPE html>
<html>
  <head>
    <!-- <script type="application/dart" src="benchmark.dart"></script> -->
    <!-- <script src="packages/browser/dart.js"></script> -->
    <script src="benchmark.dart.js"></script>
  </head>
  <body></body>
</html>
With that, I can run content_shell against build/web/index.html to find:
content_shell --dump-render-tree build/web/index.html
CONSOLE MESSAGE: line 14349: Factory Method — Subclass(RunTime): 0.46883995866706923 us.
CONSOLE MESSAGE: line 14349: Factory Method — Map of Factories(RunTime): 5.1614768017425146 us.
CONSOLE MESSAGE: line 14349: Factory Method — Mirrors(RunTime): 16.81279790176282 us.
Content-Type: text/plain
layer at (0,0) size 800x600
  RenderView at (0,0) size 800x600
layer at (0,0) size 800x8
  RenderBlock {HTML} at (0,0) size 800x8
    RenderBody {BODY} at (8,8) size 784x0
#EOF
#EOF
#EOF
Again, those numbers are comparable to the command-line dart2js results from yesterday which seems to confirm that this will work.

Unless someone cares an awful lot (and tells me that I am mistaken), this seems a reasonable approach to benchmarking in the browser. I may poke around a little more tomorrow—or jump right into adding a pub build transformer to automatically change the <script> tags that I hand edited today.

But so far, this seems promising.


Day #108

Sunday, June 29, 2014

Benchmarking dart2js Code


I probably have enough initial research on the Factory Method to get me started with Design Patterns in Dart. I do not necessarily need to have all the questions answered at this point, but I hope to have done enough to begin to understand what questions to ask.

But before I move on from this creational design pattern to a (likely) behavioral pattern, I would like to try one more benchmark. Specifically, I would like to see how my mirror-based pattern fares in the benchmark_harness sweepstakes.

The classic Factory Method pattern done in Dart looks something like:
abstract class Creator {
  Product productMaker();
}

abstract class Product {}

class ConcreteCreator extends Creator {
  productMaker()=> new ConcreteProduct();
}

class ConcreteProduct extends Product {}
The intent here is to defer the specific instance of the product to be created to a subclass. Here, the Creator does not know which subclass of Product that a subclass would want, so it declares productMaker() as an abstract method (in Dart, that means no method body). A subclass of the creator—here ConcreteCreator—then defines producMaker() to return something useful.

For me, it is helpful to think of the creator class as the base collection class in a web MVC framework. In such a case, the framework collection has no way of know what kinds of models it will be holding, so it defers the creation of those objects to the subclass in actual application code.

In contrast to this subclass approach, the mirror approach does not rely on the concrete creator to generate concrete products. Instead, it merely defines the class that will be used. The creator base class can use that to generate instances of the concrete product—thanks to the magic of mirrors:
import 'dart:mirrors';

abstract class Creator {
  Type productClass;

  Product productMaker() {
    return reflectClass(productClass).
      newInstance(const Symbol(''), []).
      reflectee;
  }
}

abstract class Product {}

class ConcreteCreator extends Creator {
  Type productClass = ConcreteProduct;
}

class ConcreteProduct extends Product {}
Regardless of your feelings on the syntax of mirrors in the Creator base class, the remainder of the code in the pattern is mercifully terse. But how fast is it?

Using the same approach to benchmarking that I have for the subclass approach (and last night's map-of-factories), my benchmark harness for my mirror approach looks like:
import 'package:benchmark_harness/benchmark_harness.dart';
import 'package:factory_method_code/mirrors.dart' as Mirrors;
// ...
class FactoryMethodMirrorBenchmark extends BenchmarkBase {
  const FactoryMethodMirrorBenchmark() : super("Factory Method — Mirrors");
  static void main() { new FactoryMethodMirrorBenchmark().report(); }
  void run() {
    new Mirrors.ConcreteCreator().productMaker();
  }
}
As in the other Factory method approaches, I am measuring the time that it takes to create an instance of the concrete creator and invoke the productMaker(). I add this benchmark to the main() entry point in my code as:
import 'package:benchmark_harness/benchmark_harness.dart';
// ...
main() {
  FactoryMethodSubclassBenchmark.main();
  FactoryMethodMapBenchmark.main();
  FactoryMethodMirrorBenchmark.main();
}
With that, I find:
$ dart tool/benchmark.dart                
Factory Method — Subclass(RunTime): 0.08687553108098094 us.
Factory Method — Map of Factories(RunTime): 1.7346083861377035 us.
Factory Method — Mirrors(RunTime): 12.741612833352447 us.
Well, that was pretty much to be expected. The map-of-factories approach is 20 times slower than the traditional subclass approach and the mirror approach is 7 times slower than the map of factories. This does not rule out the slower two approaches as they can still be useful in certain situations—especially when it is unlikely that many concrete products will be instantiated. Still, it darned handy to be able to understand the tradeoffs when making these decisions.

Except...

Do I really understand the tradeoffs as the code is likely to be run? Since the primary usage of Dart code is compiled to JavaScript. I really ought to understand what the numbers are like when compiled. But how?

As a first pass, I simply compile to JavaScript:
$ dart2js -o factory_method/tool/benchmark.dart.js factory_method/tool/benchmark.dart
Hint: 1 warning(s) suppressed in dart:_js_mirrors.
factory_method/tool/benchmark.dart:
Hint: 2391 methods retained for use by dart:mirrors out of 3411 total methods (70%).

factory_method/tool/packages/factory_method_code/mirrors.dart:3:1:
Info: This import is not annotated with @MirrorsUsed, which may lead to unnecessarily large generated code.
Try adding '@MirrorsUsed(...)' as described at https://goo.gl/Akrrog.
import 'dart:mirrors';
^^^^^^^^^^^^^^^^^^^^^^
Then I run the JavaScript with Node.js:
$ node factory_method/tool/benchmark.dart.js
Factory Method — Subclass(RunTime): 0.11682296216069209 us.
Factory Method — Map of Factories(RunTime): 4.732708458059921 us.
Factory Method — Mirrors(RunTime): 8.318221896887321 us.
Whoa. That actually worked.

Also: tnteresting. The mirror version (even though it is likely huge) is noticeably faster than its Dart counterpart whereas the other two approaches are significantly slower than their counterparts.

That aside, the map-of-factories approach is 40 times slower than the subclass approach, which is around the same order of magnitude as the Dart difference. The mirror approach is only twice as slow as the map-of-factories approach. That is still worth noting, but if you are a fan of the resulting code, then perhaps mirrors should not be immediately overlooked.

I also note that I am surprised that Node was able to run the dart2js output without any problem. Perhaps it should not surprise me, but I expected at least one or two problems. This was a pleasant surprise.


Day #107

Saturday, June 28, 2014

Benchmarking Apples and Apples


I left off yesterday with some initial benchmarks for Design Patterns in Dart. The benchmark_harness makes that pretty darn easy. What I found was that one of my Factory Method pattern implementation was not the same as the other.

Speed is not the only concern when picking an implementation, but it is certainly good to know. For the Factory Method, the fastest that I found was the classic subclass approach:
abstract class Creator {
  Product productMaker();
}

abstract class Product {}

class ConcreteCreator extends Creator {
  productMaker()=> new ConcreteProduct();
}

class ConcreteProduct extends Product {}
The abstract creator describes that subclasses will be responsible for choosing the class to instantiate. In this case it is a new ConcreteProduct, mirroring the role in the pattern. When I use the pattern in Dart Comics, the collection chooses to create a concrete ComicBook. The point being that the subclass can choose whatever it likes. And it is fast.

The alternate approach uses a Map of factories, enabling the top-level creator to sport a default implementation:
typedef Product productFactory();
Map<Type, productFactory> Factory = {
  ConcreteCreator: (){ return new ConcreteProduct(); }
};

abstract class Creator {
  Product productMaker()=> Factory[this.runtimeType]();
}

abstract class Product {}

class ConcreteCreator extends Creator {}
class ConcreteProduct extends Product {}
Yesterday, I found that subclass approach was roughly 600% faster than the map-of-factories implementation. It is actually even better than that. After updating to Dart 1.5, the results are now:
$ dart tool/benchmark.dart
Factory Method — Subclass(RunTime): 0.08871921437716161 us.
Factory Method — Map of Factories(RunTime): 1.7642425092468361 us.
1800% faster. That's craziness. But...

It is not quite a fair comparison. The productMaker() from the subclass version immediately creates the concrete instance. Calling the productMaker() method in the map-of-factories version does not immediately instantiate the concrete instance. Instead, it calls a closure that creates and returns the object. Perhaps this indirection makes a difference?

To find out, I replace the productMaker() method in the map-of-factories approach with a getter that returns the factory method:
typedef Product productFactory();
Map<Type, productFactory> Factory = {
  ConcreteCreator: (){ return new ConcreteProduct(); }
};

abstract class Creator {
  productFactory get productMaker=> Factory[this.runtimeType];
}
// ...
The dynamic language dork in me loves this kind of thing, but it is probably a little hard to read. The productMaker getter returns the Map lookup in Factory. The value returned from the Factory lookup, and hence from the productMaker getter, is a closure—an anonymous function. This return value can be invoked with the call operator—open and closing parenthesis. So it looks just like a method call:
new MapOfFactories.ConcreteCreator().productMaker();
But it is not a method—I am immediately invoking the result of the Map lookup.

Cool, eh? Well, I like it. Anyway, the result of all that? No change whatsoever:
$ dart tool/benchmark.dart
Factory Method — Subclass(RunTime): 0.08664997297170718 us.
Factory Method — Map of Factories(RunTime): 1.7268800975341878 us.
Well, maybe a slight improvement, but it is unclear if the improvement is statistically significant.

So, unless I am missing some obvious way to improve things, my map-of-factories approach is 20 times slower than the subclass approach. There are times in which this will not matter (e.g. when I am not creating a large quantity of concrete products), but this certainly needs to factor into choosing an implementation.


Day #106

Friday, June 27, 2014

Benchmarking Factory Method Pattern Approaches in Dart


A week of background work on Design Patterns in Dart has left me with more questions than answers. I expected as much.

The big questions that I have only started to grasp mostly revolve around organizing code that will support the book—especially “code in the wild.” Since most code will be available on GitHub, I will likely at least have an account there, but I might need an Organization with multiple accounts to keep everything organized. As private repos and submodules dance in my head, I try to keep my sights on something a little more concrete—benchmarks.

At least some the reasoning behind certain design patterns and approaches to design patterns will be born of performance concerns, so I need to start thinking about how to approach this. Do I keep the harness in a public repository? Do I have a public facing book repository with the harness that includes the private book repository as a submodule? Submodules? Really?

Gah! I'm terrible at maintaining focus on the small stuff. BUT, for tonight I am just going to set up a test harness in the Factory Method code that I have devised so far to see how it runs.

I have mostly been working with existing codebases so far, but for benchmarking, it is best to use small, sample code lest additional complexity impact the numbers. So I start a new factory_method Dart Pub package, starting with the pubspec.yaml package file:
name: factory_method_code
dev_dependencies:
  benchmark_harness: any
For benchmarking in Dart, the benchmark_harness is probably all that anyone will ever need. Before installing it from pubspec.yaml, I lay out the rest of the code. I start with lib/subclass.dart which contains a subclass example of the Factory method:
library factory_method_subclass;

abstract class Creator {
  Product productMaker();
}

abstract class Product {}

class ConcreteCreator extends Creator {
  productMaker()=> new ConcreteProduct();
}

class ConcreteProduct extends Product {}
Next, I create the benchmark “tool” in tool/benchmark.dart:
import 'package:benchmark_harness/benchmark_harness.dart';
import 'package:factory_method_code/subclass.dart';

class FactoryMethodSubclassBenchmark extends BenchmarkBase {
  const FactoryMethodSubclassBenchmark() : super("Factory Method — Subclass");

  static void main() {
    new FactoryMethodSubclassBenchmark().report();
  }

  // The benchmark code.
  void run() {
    new ConcreteCreator().productMaker();
  }
}

main() {
  // Run FactoryMethodSubclassBenchmark
  FactoryMethodSubclassBenchmark.main();
}
Most of that is copied directly from the Example provided on the benchmark_harness page.

With the code and directory structure in place, I now install the pubspec.yaml dependencies with pub install:
➜  factory_method git:(master) ✗ pub install
Resolving dependencies... (1.4s)
Downloading benchmark_harness 1.0.4...
Got dependencies!
With that, I can run my benchmark:
➜  factory_method git:(master) ✗ dart tool/benchmark.dart
Factory Method — Subclass(RunTime): 0.24725152118407764 us.
OK that is definitely a number, but without something to compare it to, it is a pretty useless number. I might as well compare it to the map-of-factories approach to Factory Method from last night. I think this can be boiled down to:
typedef Product productMaker();
Map<Type, productMaker> Factory = {
  ConcreteCreator: (){ return new ConcreteProduct(); }
};

abstract class Creator {
  Product productMaker()=> Factory[this.runtimeType]();
}

abstract class Product {}

class ConcreteCreator extends Creator {}

class ConcreteProduct extends Product {}
When it comes to the benchmarking code, I hit my first snag. The creator and product classes are names the same in both samples. If I import both into my benchmark file, I will get class conflicts. So I need to prefix the imports:
import 'package:benchmark_harness/benchmark_harness.dart';
import 'package:factory_method_code/subclass.dart' as Subclass;
import 'package:factory_method_code/map_of_factories.dart' as MapOfFactories;

class FactoryMethodSubclassBenchmark extends BenchmarkBase {
  // ...
  void run() {
    new Subclass.ConcreteCreator().productMaker();
  }
}

class FactoryMethodMapBenchmark extends BenchmarkBase {
  const FactoryMethodMapBenchmark() : super("Factory Method — Map of Factories");

  static void main() {
    new FactoryMethodMapBenchmark().report();
  }

  void run() {
    new MapOfFactories.ConcreteCreator().productMaker();
  }
}

main() {
  FactoryMethodSubclassBenchmark.main();
  FactoryMethodMapBenchmark.main();
}
Aside from that, everything else works perfectly. And when I run my double benchmarks, I get:
➜  factory_method git:(master) ✗ dart tool/benchmark.dart
Factory Method — Subclass(RunTime): 0.24548983015417866 us.
Factory Method — Map of Factories(RunTime): 1.900878681170371 us.
Yikes! The map of factories approach is more than 600% slower. I expected the subclass approach to be quicker, but that amount really surprises me. So much so that I wonder if I am testing both at similar levels of abstraction. I will ruminate on this tomorrow (and also pull in tests of my mirror approach).

Regardless, this benchmarking approach seems reasonable. It is good to be aware of the need to prefix the imports, but that aside, this seems a good way to obtain admittedly illuminating numbers.


Day #105

Thursday, June 26, 2014

Compile Time Constant Factory Method


Tonight I continue to poke and prod the first design pattern destined for Design Patterns in Dart...

I really like yesterday's map-of-factories approach to the Factory Method pattern in Dart. The approach, first suggested to me by Vadim Tsushko removes the immediate responsibility of Factory Methods from subclasses of the creator class and instead places them in a Map of factories. I think I may have left some room for improvement though...

The classic Factory Method pattern starts with an abstract creator class that includes an abstract creator method:
abstract class Creator {
  Product productMaker();
  // ...
}
The Product is similarly abstract—the concrete subclass of Product is deferred to the concrete subclass of Creator. Leaving the productMaker() method abstract says just that: the subclass needs to define a productMaker() method that returns a subclass of Product:
class ConcreteCreator extends Creator {
  productMaker()=> new ConcreteProduct();
}
Yesterday's variation does away with the creator subclass, which is quite nice if the factory method is the only reason to define a subclass. Instead, the top-level creator class now looks up the factory method in a simple Map:
typedef Product productFactory();
class Creator {
  static Map<Type, productFactory> factory = new Map();
  Product productMaker(type) => factory[type]();
  // ...
}
Here, I typedef a function that takes no arguments and returns some kind of concrete Product (just like the original productMaker() factory method). The static factory map is then a key/value store in which the keys are types and the values are product factories.

Either approach (subclass or map-of-factories) will work as a Factory Method implementation. I have yet to benchmark the two. In the absence of that admittedly useful information, the choice between the two comes down to context or personal preference. In the web MVC framework example that I used yesterday, it probably makes more sense to use the subclass approach as I have to create subclasses anyway and the map-of-factories was a little awkward. If the concrete classes are all part of the same codebase or if a parallel class hierarchy needs factories, then map-of-factories seems the better approach.

I do not want to dwell on those question too much just yet. Instead, I am wondering if including the map-of-factories in the creator class is the right approach. Perhaps this was just the codebase upon which I was experimenting last night, but it felt a little messy having it in the same class.

Instead, I would like an entirely separate Factory class to hold this information. Something along the lines of:
typedef Product productFactory();
class Factory {
  static Map<Type, productFactory> factory = new Map();
}
So I give that a try in my Hipster MVC (abstract creator and product) and Dart Comics (concrete creator and product) codebases. In Hipster MVC, the HipsterCollection class had served as the abstract creator, creating HipsterModel objects from attributes fetched via a RESTful backend. Last night it got the map-of-factories treatment. Tonight, I move that out into a separate Factory class:
typedef HipsterModel modelMaker(Map attrs);

class Factory {
  static Map factory = new Map();
}
This works just fine. HipsterCollection is now capable of creating concrete instances of HipsterModel (e.g. ComicBook from Dart Comics) using this Factory:
class HipsterCollection extends IterableBase {
  // ...
  HipsterModel modelMaker(attrs) => Factory.factory[this.runtimeType](attrs);
  // ...
}
But you know what? Factory.factory looks ugly. It would be much cooler if that were just:
  HipsterModel modelMaker(attrs) => Factory[this.runtimeType](attrs);
Unfortunately operators, like the square bracket lookup operator, cannot be static:
class _Factory {
  static Map<Type, modelMaker> factory = new Map();

  // This won't work!!!
  static operator [](type) => factory[type];
}
I know this does not work because I try it out only to get a nice little exception:
Internal error: 'package:hipster_mvc/hipster_factory.dart': error: line 11 pos 19: operator overloading functions cannot be static
  static operator [](type) => factory[type];
Bah!

All is not lost… as long as I am willing to resort to some compile time constant chicanery. And of course I am more than willing. I rename the Factory class as _Factory and declare a compile time constant of Factory which of type _Factory:
_Factory Factory = const _Factory();

class _Factory {
  static Map<Type, modelMaker> factory = new Map();

  const _Factory();
  operator [](type) => factory[type];
  operator []=(type, function) { factory[type] = function; }
}
Which does the trick, though it feels a little dirty. Dirty because I declare a compile-time constant whose sole purpose is to store changing key-value pairs. But it works because the instance variable factory fails on the _Factory instance which leaves Dart to fall back on static variable lookup.

And it is at this point that I realize that, yes, I am an idiot.

Because I have gone to all of this effort even though an empty HashMap is also a compile time constant. So the _Factory class and Factory compile time constant can be replaced with:
typedef HipsterModel modelMaker(Map attrs);
Map<Type, modelMaker> Factory = {};
Well, that was a long way to go to wind up with a simple HashMap lookup.

Ah well, maybe that const + static method trick will come in handy some day. Stranger things have happened.

But for today, I have my map-of-factories in better shape with an extremely small amount of code. Demonstrating publicly that I'm a dummy is a small price to pay for that!

Tomorrow: benchmarking.



Day #104

Wednesday, June 25, 2014

A Map of Factories for the Factory Method Pattern


Sometimes there is no substitute for doing something stupid—just to see why it is stupid. It is one thing to read that a thing is stupid, but that tactile feeling of failure leaves an imprint that sticks with a person like a quality case of food poisoning. The body may expel the immediate repercussions of food poisoning, but it will be a long time before you try that particular Mediterranean bistro again.

Toward that end I have been doing dumb things with mirrors, named constructors and default implementation approaches to the Factory Method pattern in Dart. Actually not all of those are dumb—it depends on the context in which they are used. And that's going to be a big part of my job in Design Patterns in Dart—figuring out which approaches are decent in the right circumstances and which are the coding equivalent of food poisoning.

Also, I need to come up with really good food poisoning descriptions so that I can fully imprint on the hearty reader which approaches truly are stupid (and why). But that's a skill I can develop later. For now, I try another approach to the Factory Method pattern. This one promises to be rather good...

I continue to work with the Hipster MVC framework. It is a toy MVC framework for the web (built primarily to support Dart for Hipsters). Toy or not, frameworks are fertile ground for raising robust Factory Method patterns. In this case, it has an abstract product, HipsterModel (the “M” in this framework's MVC). It also has an abstract creator, HipsterCollection. The current implementation of the Factory Method in this creator class is the modelMaker():
abstract class HipsterCollection extends IterableBase {
  HipsterModel modelMaker(Map attrs);
  // ...
}
This abstract method is declared so that subclasses will define a method that accepts a Map of attributes and returns a concrete product of type HipsterModel. The concrete creator implementation for a comic book collection (like the one in the Dart Comics application) might look something like:
class Comics extends HipsterCollection {
  modelMaker(attrs) => new ComicBook(attrs);
  String url = '/comics';
}
This is a classic implementation of the Factory Method pattern, done in Dart. It is particularly effective in this framework example. The intent is to maintain a relationship between the creator class (HipsterCollection) and the product class (HipsterModel). Since the framework has no business knowing the concrete class types (ComicBook), using Factory Method defers the concrete instantiation to the concrete creator class.

This approach works pretty darn well for a framework, but there are other approaches to the pattern. An interesting one was suggested by Vadim Tsushko in the comments of a previous post. In Vadim's approach, a subclass of the creator is not responsible for creating concrete products. Instead, that responsibility goes into a Map:
typedef HipsterModel modelMaker(Map attrs);
Map<Type, modelMaker> factory = new Map();
The factory map above is keyed by a Type and returns functions of the modelMaker type. In this approach, modelMaker is typedef'd as a function that accepts a map of attributes and returns an object of type HipsterModel. In other words, modelMaker functions have the exact same signature that my current modelMaker() method has.

To explore this approach in Hipster MVC, I declare the typedef in the collection class and add the factory as a static class variable on the same:
typedef HipsterModel modelMaker(Map attrs);

class HipsterCollection extends IterableBase {
  // ...
  static Map<Type, modelMaker> factory = new Map();

  HipsterModel modelMaker(Map attrs) => factory[this.runtimeType](attrs);
  // ...
}
The modelMaker() method is no longer abstract. Its definition returns the result of invoking the factory for the current runtime type.

The factory for the Comics collection can be added as:
HipsterCollection.factory[Comics] = (attrs) => new Models.ComicBook(attrs);
Once that is registered, an instance of Comics that needs a model (e.g. if it GETs a record via a REST backend) can get one by invoking modelMaker with the attributes. This will lookup the correct factory based on the object's runtimeType, which is Comics. The anonymous function associated with this type will be invoked with the supplied attributes and the result returned.

I rather like that. The implementation is succinct. The resulting code might be a little hard to read, but the associated typedef and Map types clear things up nicely. The result is a subclass of the creator that does no creating itself:
class Comics extends HipsterCollection {
  String url = '/comics';
  // NO LONGER NEEDED :)
  // modelMaker(attrs) => new ComicBook(attrs);
}
The only downside is also a potential benefit, depending on the context. In the case of my framework, I had to assign the HipsterCollection.factory in the main() entry point:
main() {
  HipsterCollection.factory[Comics] = (attrs) => new Models.ComicBook(attrs);
  // ...
}
In certain circumstances this could be a benefit—keeping all of the factory registration in on place. In the case of my framework, this is probably not a good practice. Since I have to subclass the creator class anyway, I might as well put the creator method in that subclass. Even so, I like the factory map approach enough that I will likely include it in the book.


Day #103

Tuesday, June 24, 2014

Default Implementation in Dart Factory Method


Up tonight, I continue my exploration of the Factory Method pattern in Dart. Tonight, I explore a variation in which a default implementation is provided in the base creator class.

Before starting, I note that my current framework sample code may be insufficient for adequately describing the various use-cases of Factory Method. The framework Factory Method comes from the Hipster MVC framework (well, toy framework largely written in support of Dart for Hipsters). The abstract creator in the framework is the collection part of the MVC. It is aptly named HipsterCollection:
abstract class HipsterCollection extends IterableBase {
  // ...
  HipsterModel modelMaker(attrs);
  // ...
}
This abstract creator expects concrete creators to define modelMaker() with appropriate concrete products—in this case the product being a type of HipsterModel, the model in the MVC framework. The sample code that I have been using is a collection of comics books. In this case, ComicBook serves as the concrete product class, extending HipterModel. The concrete creator class, ComicCollection, then subclasses HipsterCollection, defining the modelMaker() factory method as:
class Comics extends HipsterCollection {
  modelMaker(attrs) => new ComicBook(attrs);
  // ...
}
That implementation of the Factory Method pattern works just fine for my framework. The Hispter MVC framework and the application that contains the code defining the abstract portions of the framework are completely separate. One can be a publicly hosted package and the other an application in a private repository. The framework delegates the knowledge of the product class to that private application which is ideal since the publicly available framework should not have any knowledge of application code.

Although this works fine, it does present a slight problem. Programmers using my framework will often wind up with a number of very small creator classes like Comics:
class Comics extends HipsterCollection {
  modelMaker(attrs) => new ComicBook(attrs);
  get url => '/comics';
}
As the Gang of Four book puts it, “Subclassing is fine when the client has to subclass the creator class anyway, but otherwise the client now must deal with another point of evolution.” In my current Comics, I don't really need to subclass HipsterCollection. To be sure, HipsterCollection should expect to be subclassed so that custom events can be set, but in this particular example, I could get away with what the Gang of Four describe as a default implementation.

Unfortunately, here I hit the limitation of my example code. It makes no sense for my public framework to be aware of how to create ComicBook instances. I should explore some of the parameterized examples from the Gang of Four, but I will leave that for another day and another code source. For now, I use a variation in which the client code stores the product class in a static variable, providing a useful default implementation.

In this case, the client code no longer creates an instance of ComicsCollection:
var my_comics_collection = new Collections.Comics();
Instead, it first defines the class to be used when creating models and then creates an instance of HipsterCollection:
HipsterCollection.modelClass = Models.ComicBook;
var my_comics_collection = new HipsterCollection()..url = '/comics';
To support that, HispterCollection can no longer be abstract. Instead it needs to support a reasonable default—using the modelClass static variable:
class HipsterCollection extends IterableBase {
  // ...
  static Type modelClass = HipsterModel;

  HipsterModel modelMaker(attrs) =>
    reflectClass(modelClass).
      newInstance(const Symbol(''), [attrs]).
      reflectee;

  String url;
  // ...
}
Unfortunately, this means the return of Dart mirrors. That might not be a horrible solution in some cases, but I ought to be able to avoid it under most circumstances. This current implementation precludes multiple collection types since HipsterCollection.modelClass can only have one value at a time (I could cache the class in an instance variable, but this already feels awkward).

I think tomorrow it is time to explore the global Map of factory closures proposed in comments from previous nights' posts. Then I need to work up an illustrative example of Factory Method in a single codebase so that some of these other approaches might work—without resorting to mirrors.



Day #102

Monday, June 23, 2014

Named Constructors in Dart Factory Method


As pointed out to me in comments, Dart mirrors are unlikely to be the most efficient means for implementing the Factory Method pattern in Dart. But I don't care, I love this dynamic language stuff too darn much.

OK, OK, that's not 100% true. I do care about speed and efficiency in my code. I also very much care about speed a a factor for the solutions that will go into Design Patterns in Dart. That said, I am not trying to find the one and only solution when I first investigate a pattern. I am interested in finding as many reasonable implementations as possible so that I might have several to fit different use cases in the book.

Sometimes speed might be the most important need, sometimes it might be clarity, and other times a programmer may need a solution that minimizes the number of classes and subclasses. I really also ought to include potential drawbacks to each pattern or, as the Gang of Four book puts it, consequences of each. One of the consequences of the Factory Method pattern mentioned by the Gang of Four is the difficulty that arises when refactoring constructors.

Since the Factory Method pattern concerns itself with creating new objects, the difficulty in refactoring arises when the constructor needs to change. Consider the concrete creator in the Hipster MVC framework:
class Comics extends HipsterCollection {
  modelMaker(attrs) => new ComicBook(attrs);
  get url => '/comics';
}
In this case, the modelMaker() method plays the role of Factory Method. Where the HipsterCollection base class leaves this method abstract, the concrete creator must define the implementation. But what happens when the constructor has to change because some unrelated client code needs to supply different arguments? What happens when Hipster MVC becomes super popular only to find that a single argument to modelMaker() is insufficient in 20% of the use cases? Is a huge rewrite inevitable? Is a breaking, major version change the only option?

Thanks to Dart's optional method parameters, I could probably accommodate some change, but it would be nice if these kinds of changes could occur independently of each other. This seems like a job for Dart's named constructors.

Currently, my Factory Pattern's abstract product class, HispterModel, declares a constructor that optionally accepts attributes:
class HipsterModel {
  // ...
  HipsterModel([this.attributes]) {
    if (attributes == null) attributes = {};
    _onSave = new StreamController.broadcast();
    _onDelete = new StreamController.broadcast();
  }
  // ...
}
It might make sense for this default constructor to treat attributes as optional, but when creating concrete products as part of a collection, this might prove problematic. With named constructors, I can leave the default case as optionally accepting mode attributes, but, when constructed from a collection, it can be required:
class HipsterModel {
  // ...
  HipsterModel([this.attributes]) {
    if (attributes == null) attributes = {};
    _onSave = new StreamController.broadcast();
    _onDelete = new StreamController.broadcast();
  }
  HipsterModel.collectionMaker(Map attrs): this(attrs);
  // ...
}
My concrete creator would use this named constructor in the Factory Method:
class Comics extends HipsterCollection {
  modelMaker(attrs) => new ComicBook.collectionMaker(attrs);
  get url => '/comics';
}
This has the advantage of allowing the two constructors to evolve independently of each other, which is a decided win. This would also play nicely with last night's mirror-based Factory Method implementation.

But all is not rosy with this approach—mostly due to Dart's treatment of constructors in subclasses. Specifically, they are not inherited. Because of this, I already had to declare a constructor for the optional arguments version. Now I have to do so for the named constructor as well:
class ComicBook extends HipsterModel {
  ComicBook([attributes]) : super(attributes);
  ComicBook.collectionMaker(attributes) : super.collectionMaker(attributes);
}
There is no way around this restriction in Dart. If concrete product classes like ComicBook are needed (because they define some additional, domain-specific properties or methods), then I will need to declare both constructors.

There might be cases in which this overhead is acceptable—maybe even desirable. Even so, it is probably worth some more investigation in this area to see if more general purpose solutions exist. Toward that end, I will pick back up with factory constructors tomorrow.


Day #102

Sunday, June 22, 2014

Dart Mirrors for Better Factory Method


Today I continue my exploration of the Factory Method for Design Patterns in Dart. The pattern is a simple enough pattern and I was able to find a ready example in some my own Dart code last night.

Today I would like to explore the specific implementation of the creator class in the pattern. The canonical example from the Gang of Four book is similar that that I used last night from Hipster MVC. The creator class is abstract, expecting the subclass to define the method that creates a HipsterModel instance:
abstract class HipsterCollection extends IterableBase {
  HipsterModel modelMaker(attrs);
  String get url;
  // ...
}
A example of concrete creator class comes from Dart Comics, which defines the factory method as:
class Comics extends HipsterCollection {
  modelMaker(attrs) => new ComicBook(attrs);
  get url => '/comics';
}
That is simple enough and a nice example of the pattern. It is especially nice that the example comes from a simpleton's MVC framework, which ought to be accessible for my intended audience.

When I first created the Hipster MVC framework, Dart was still in its infancy and there was no way to store and use classes at run-time. The dynamic language part of me was more than a little disappointed, but the Factory Method pattern eased my concerns. A little.

Since then, Dart has evolved quite a bit—to the point that is has a dart:mirrors package built into the core language library. Tonight, I would like to use that package to implement the Factory Method pattern using an alternate approach given by the Gang of Four—by storing the class information in the subclass and having the baseclass create new instances from that information.

The concrete creator class then becomes something like:
class Comics extends HipsterCollection {
  // modelMaker(attrs) => new ComicBook(attrs);
  Type get modelClass => ComicBook;
  get url => '/comics';
}
I like that very much. Perhaps I am too much a dynamic language person at heart, but returning just the class feels better.

There is a trade-off, especially in Dart. The resulting abstract creator gets a little more complicated. There is not much left that is abstract—just the concrete instance of HipsterModel that will be used to create instance in the collection. The added complexity comes in the form the no-longer-abstract modelMaker(), which has to obtain a class mirror of the type, and then use that to get an instance of the particular class:
import 'dart:mirrors';
// ...
abstract class HipsterCollection extends IterableBase {
  Type get modelClass;
  HipsterModel modelMaker(attrs) {
    ClassMirror modelMirror = reflectClass(modelClass);
    return modelMirror.newInstance(const Symbol(''), [attrs]).reflectee;
  }
  String get url;
  // ...
}
OK, that's not too horrible, but it still requires explanation whereas the abstract Factory Method approach did not.

Before jumping into the explanation, there is still a little more cleanup possible. Now that the creator method is in the baseclass, the concrete class no longer needs getter methods. Instead, I can use plain-old instance variables for things like the modelClass:
class Comics extends HipsterCollection {
  Type modelClass = ComicBook;
  String url = '/comics';
}
The base constructor class then looks like:
abstract class HipsterCollection extends IterableBase {
  // ...
  Type modelClass;
  HipsterModel modelMaker(attrs) {
    ClassMirror modelMirror = reflectClass(modelClass);
    return modelMirror.newInstance(const Symbol(''), [attrs]).reflectee;
  }
  String url;
  // ...
}
That helps, especially since this approach still has a messy modelMaker() factory method. This approach reflects on the current modelClass, which comes from a concrete subclass of HipsterCollection like Comics. In this case, it reflects on the ComicBook class to get a class mirror of that class. To get an instance from that mirror, I use the newInstance() method. That does not return a new instance, but rather an instance mirror. To get the actual instance, I go through the reflectee property.

That explanation is relatively clean. The noise comes from the two arguments to the newInstance() method. The first is a symbol… of an empty string. The second is the attributes that will be used to create a ComicBook instance—but wrapped in a list. The second argument is a little easier to explain—it is simply the list of arguments supplied to a constructor. In this case, there is a single argument—the attributes of a ComicBook.

More difficult to understand—but with the promise of something useful in the Factory Method pattern—is the first argument to newInstance(). The empty string Symbol is how we tell newInstance() to use the unnamed, default constructor for ComicBook—e.g. new ComicBook({'title': 'Sandman', 'author': 'Neil Gaiman'}). Given that we use this constructor by default, how might “other constructors” be useful in the context of Factory Method?

One of the consequences and potential drawbacks of the Factory Method pattern is that it makes code evolution problematic. If the constructor signature needs to change at some point down the line, all of the concrete classes that rely on the current implementation would have to change as well. Or, if the concrete classes require a change, then any other code that relies on the current default constructor would have to change as well. I believe that Dart's named constructors will help with that—and I will explore them tomorrow.



Day #101

Saturday, June 21, 2014

Dart Factory Method Pattern


It's time to start laying the foundation for Design Patterns in Dart. There is still work to be done on Patterns in Polymer (especially the screencasts for “Extras” readers), but for a variety of reasons, I need to start exploring how I am going to approach a design patterns book.

I have vague plans for how I would like to organize the book. Some of those plans will work, others… not so much. One of my best laid plans is to include examples of each pattern from the wild—similar to the original classic. I am unsure how well that will work. It is difficult, at best, to find implementations of each pattern in the wild that are clean enough to lend support to a book narrative. Since Dart is so new, it will be that much more difficult to find such examples (though I have definitely seen more than a few).

Regardless, I might as well start somewhere, so tonight… I cheat.

I start with the Factory Method pattern. What makes this a cheat is the source of it in the “wild.” I first saw this in Dart when I used it while building the Hipster MVC framework to support part of the narrative in Dart for Hipsters.

I actually went out of my way to not refer to this as a pattern at the time, but I need to start referring to things with proper names—especially if I am going to write a book in which names are so important. So…

Hipster MVC provides an abstract creator class in the form of HispterCollection:
abstract class HipsterCollection extends IterableBase {
  HipsterModel modelMaker(attrs);
  String get url;
  // ...
}
The factory method in this class is modelMaker().

The concrete creator class comes from the dart-comics repository. The Comics class extends the HipsterCollection abstract creator class and implements the creator method:
class Comics extends HipsterCollection {
  modelMaker(attrs) => new ComicBook(attrs);
  get url => '/comics';
}
Dang, that's actually a pretty nice example. Event the return type from the abstract and concrete creator classes line up. The abstract class declares it as HipsterModel and the concrete class returns a new ComicBook instance, which is a subclass of HipsterModel:
class ComicBook extends HipsterModel {
  ComicBook(attributes) : super(attributes);
}
About the only thing missing is the ability to create instances of ComicBook from a class name instead of method. This is given as an example in the Gang of Four book (in Smalltalk). It is also something that I, coming from a Perl, Ruby, JavaScript, anything-but-Java background would have preferred to use when I first wrote Dart for Hipsters. But it was not an option at the time since Dart lacked support for mirrors.

Now that Dart has some pretty nice support for mirrors, this ought to work just fine. And so I will tackle that tomorrow.



Day #100

Friday, June 20, 2014

More Dart Testing of JavaScript Polymer Elements


I finally got so fed up with JavaScript testing frameworks last night that I did something truly silly. I started testing my JavaScript with Dart.

I begin to despair of the state of testing in JavaScript. It seems that no matter how much progress is made, testing new things will always be prohibitively hard. The ever growing number of JavaScript testing frameworks and runners do a fair job of facilitating known coding domains, but stray too far from the known and… ick.

The ick last night came in the form if a simple Polymer element, <apply-author-styles>. This element copies CSS from the main page into other Polymer elements—the idea being that native elements inside these other Polymer elements should look like native elements on the page. The actual test is ridiculously easy: add a <style> to the page, insert <apply-author-styles> into test element, and verify that the same <style> is now part of the test element's shadow DOM.

Four days ago I made the mistake of starting a post exploring this test with the questions, “how hard can it be?”

Well, Karma can not handle it because there is no way to alter the test page to insert a <style> tag (at least not without resorting to JavaScript which won't work on this element). It turns out that grunt-contrib-jasmine will not work either, mostly because its browser is incompatible with Polymer.

I have no doubt that there is a test runner / test framework out there that is capable of the job, but I have no desire to spend my days building on an already too familiar knowledge of so many JavaScript testing frameworks. Life is too damn short.

So last night, I gave up and used Dart. And it just worked. I am not going to claim that Dart is the end solution for all JavaScript testing, but it worked in this case and not without good reason. The default implementation is embedded in a Chrome variant so both Dart and JavaScript code should work. Dart has an excellent built-in testing framework and runner. So it seemed worth a try and I was rewarded. That said, there are still a couple of outstanding questions.

First up, is why does the test pass in content_shell, but not in Dartium? As mentioned above, the test is simple enough: I define a page style that includes orange button borders, include <apply-author-styles> to a test fixture tag <x-foo>, then test:
  group("[styles]", (){
    test('the app returns OK', (){
      var xFoo = query('x-foo');
      expect(xFoo.shadowRoot.text, contains('orange'));
    });
  });
Isn't that a pretty test? I find the <x-foo> tag on the test page and set my expectation that its shadow root contains “orange.” This works fine in content_shell, the headless testing version of Dartium:
CONSOLE MESSAGE: unittest-suite-wait-for-done
CONSOLE MESSAGE: PASS: [styles] the app returns OK
CONSOLE MESSAGE: 
CONSOLE MESSAGE: All 1 tests passed.
CONSOLE MESSAGE: unittest-suite-success
CONSOLE WARNING: line 213: PASS
But fails in Dartium proper:
unittest-suite-wait-for-done
ERROR: [styles] the app returns OK
  Test failed: Caught The null object does not have a getter 'text'.
  
  NoSuchMethodError: method not found: 'text'
  Receiver: null
  Arguments: []
  dart:core-patch/object_patch.dart 45                                                                                       Object.noSuchMethod
  test.dart 22:30 
It seems that my test <x-foo> element simply does not have a shadowRoot. Since it is null, calling text on it raises an exception. But why?

If I inspect the actual element on the page, it really does not have a shadow DOM:



Compare the same element as seen on Chrome 35:



In the JavaScript console settings for Dartium, the “Show Shadow DOM” setting is enabled and yet… no shadow DOM. And I cannot figure out why. My best guess is that the version of Chromium (34) against with Dartium is built lacks some native functionality that Polymer would otherwise use. Lacking that, it places the element directly in the light DOM which works visually, but breaks my test.

I am a little concerned that content_shell works differently than Dartium. Interestingly, it reports a really old Chrome version in the navigator.userAgent property:
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/19.77.34.5 (Dart) Safari/537.36"
I may have to report that. For now, I am content that it behaves like it ought to behave.

To prove that it is not all sunshine and roses, I still need to deal with some impedance mismatch between Dart and JavaScript. Specifically, the project is laid out like a Bower project, not a Dart project. This forces me manually symlink a bunch of things in the test directory:
➜  apply-author-styles git:(master) ✗ ls -l test
total 28
drwxr-xr-x 2 chris chris 4096 Jun 19 23:37 apply-author-styles
lrwxrwxrwx 1 chris chris   29 Jun 19 23:32 core-ajax -> ../bower_components/core-ajax
lrwxrwxrwx 1 chris chris   39 Jun 19 23:32 core-component-page -> ../bower_components/core-component-page
-rw-r--r-- 1 chris chris  634 Jun 19 23:49 index.html
lrwxrwxrwx 1 chris chris   11 Jun 19 23:37 packages -> ../packages
lrwxrwxrwx 1 chris chris   28 Jun 19 23:32 platform -> ../bower_components/platform
lrwxrwxrwx 1 chris chris   27 Jun 19 23:32 polymer -> ../bower_components/polymer
-rw-r--r-- 1 chris chris  773 Jun 20 23:07 test.dart
-rwxr-xr-x 1 chris chris  292 Jun 20 22:18 test_runner.sh
-rw-r--r-- 1 chris chris  300 Jun 19 23:44 x-foo.html
Crazy as it might seem, I am still using Grunt to manage the test run (mostly for the simple, static web server). Thankfully, it includes symlink and clean tasks. So I install those:
$ npm install grunt-contrib-symlink --save-dev
$ npm install grunt-contrib-clean --save-dev
Then I load those tasks in my Gruntfile.js:
module.exports = function(grunt) {
  grunt.initConfig({
    // ...
  });

  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-symlink');
  grunt.loadNpmTasks('grunt-shell');
  grunt.loadNpmTasks('grunt-contrib-connect');
  grunt.loadNpmTasks('grunt-contrib-clean');

  grunt.registerTask('default', ['symlink:test_files', 'connect', 'shell:test', 'clean:test_files']);
};
Also in there, I start my default testing task with a new symlink:test_files task and end with a clean:test_files task. Configuration of both is fairly easy thanks to the nice documentation:
module.exports = function(grunt) {
  // Project configuration.
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    // ...
    symlink: {
      test_files: {
        files: [
          {
            expand: true,
            overwrite: true,
            cwd: 'bower_components',
            src: ['*'],
            dest: 'test'
          }
        ]
      }
    },
    // ...
    clean: {
      test_files: ['test/core-*', 'test/platform', 'test/polymer']
    }
  });
  // ...
  grunt.registerTask('default', ['symlink:test_files', 'connect', 'shell:test', 'clean:test_files']);
};
That cleans things up fairly nicely. Now when I run my default grunt command, it starts by creating the necessary symbolic links, runs the static server, then the tests, and finally cleans everything up after itself.

Unfortunately, this leaves me in a state of using NPM, Grunt, Bower, and Dart on this very simple Polymer element. It might be worth investigating replacing Grunt/NPM with something like Hop in Dart. But I leave that for another day.


Day #99

Thursday, June 19, 2014

Testing JavaScript Polymers… With Dart


Look, this isn't that hard. In order to test my <apply-author-styles> Polymer element, I need a test page that:
  1. holds a test Polymer element that uses <apply-author-styles>
  2. Can run in a server so that XHR request can be made
  3. Has custom styles that can be pulled from the page into the test custom element
Try as I might with grunt-contrib-jasmine and Karma, I cannot do this. grunt-contrib-jasmine and Polymer do not get along. Karma refuses to allow me to add custom CSS to the test context—at least not statically.

So you know what? I give up. I'm testing with Dart.

I already have Grunt setup in this project, so I stick with it here. In this case, I want a simple static server against which to run my tests (there is a simple Ajax component). I already have that in the form of grunt-contrib-connect. Now I need a way to run Dart tests against this JavaScript element (yes, I'm serious).

Since there is no grunt-contrib-dart yet (why not?!), I install grunt-shell:
$ npm install --save-dev grunt-shell
Then I add this to the imported tasks in my Gruntfile.js and define my test_runner.sh shell task that will run my Dart tests:
module.exports = function(grunt) {
  // Project configuration.
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    // ...
    connect: {
      server: {
        options: {
          port: 8100,
          keepalive: false
        }
      }
    },
    shell: {
      test: {
        command: 'test/test_runner.sh'
      }
    }
  });

  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-shell');
  grunt.loadNpmTasks('grunt-contrib-connect');

  grunt.registerTask('default', ['connect', 'shell:test']);
};
The test_runner.sh script is a simple fork of content_shell that comes bundled with Dart for headless testing—but real headless testing with an actual browser. The test_runner.sh script looks like:
#!/bin/bash

# Run a set of Dart Unit tests
results=$(content_shell --dump-render-tree http://localhost:8100/test/ 2>&1)
echo -e "$results"

# check to see if DumpRenderTree tests
# fails, since it always returns 0
if [[ "$results" == *"Some tests failed"* ]]
then
    exit 1
fi

echo
echo "Looks good!"
OK with that, I have my runner in place. Grunt will start grunt-contrib-connect as part of the default task and content_shell will run my test at http://localhost:8100/test/. Now I just need to define the test.

I start with a test context page that *I* can write:
<head>
  <!-- Load Polymer -->
  <script src="/bower_components/platform/platform.js"></script>

  <!-- Load component(s) -->
  <link rel="import" href="x-foo.html">

  <!-- Style that will apply to both page and Polymer elements -->
  <style>
    button { border: 5px solid orange; }
  </style>
</head>
<body>
  <div id=test><!-- Test element -->
    <x-foo></x-foo>
  </div>
  <div id=page><!-- Page element -->
    <button type=button>Test in Main Page</button>
  </div>
</body>
In there, I have the page style—orange buttons—that I want to apply to my <x-foo> test element that makes use of <apply-author-styles>. The <x-foo> element was defined a couple of days ago as:
<link rel="import" href="polymer/polymer.html">
<link rel="import" href="apply-author-styles/apply-author-styles.html">
<polymer-element name="x-foo" noscript>
  <template>
    <apply-author-styles></apply-author-styles>
    <button id=test type=button>Test</button>
  </template>
</polymer-element>
That <apply-author-styles> should change the style of the button inside the element (something the old, deprecated applyAuthorStyles Polymer property used to do). I don't need to actually test that the button is orange. I may try that another day, but for now, I just need to know that that page style has been copied to the shadow DOM of my element. Or, in test form:
library main_test;

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

main(){
  group("[styles]", (){
    test('the app returns OK', (){
      var xFoo = query('x-foo');
      expect(xFoo.shadowRoot.text, contains('orange'));
    });
  });
}
Which does the trick:
CONSOLE MESSAGE: unittest-suite-wait-for-done
CONSOLE MESSAGE: PASS: [styles] the app returns OK
CONSOLE MESSAGE: All 1 tests passed.
CONSOLE MESSAGE: unittest-suite-success
That is not quite perfect—there is some discrepancy between running it in the browser and from content_shell that bears some investigation. Still, it is so very nice to have a testing framework that runs in the browser, can test easily against a custom page context, and actually passes.

As crazy as it might seem to run a Dart test runner for JavaScript code, the crazier thing might be fighting ever more obscure JavaScript testing frameworks. So I may end up sticking with this.


Day #98

Wednesday, June 18, 2014

Getting Started on grunt-contrib-jasmine for Polymer Testing (Thwarted)


Yesterday was one of those days that I start something I truly believe is easy only to wind up fighting every single decision and ultimately fail to accomplish my task. With a day between me and that failure, I believe my failure was not so much due to underestimating the difficulty of the problem. Rather, it was a stubborn inability to recognize that I was fighting my chosen tools too much.

I am trying to test the new apply-author-styles tag. It is a relatively simple Polymer element to be used in other Polymer elements so that these elements can adapt the same styles that are used on the page using the elements. That is, if my page styles <button> elements to have orange borders, then <apply-author-styles> inside another custom element should ensure that <button> elements in the custom element will have an orange border as well.

To test, I need two things: a page with styles and a custom Polymer element with <apply-author-styles> in its template. Yesterday I got the latter setup without difficulty. The <x-foo> test element should do the trick nicely:
<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="../apply-author-styles.html">
<polymer-element name="x-foo" noscript>
  <template>
    <apply-author-styles></apply-author-styles>
    <button id=test type=button>Test</button>
  </template>
</polymer-element>
After some unrelated fights with both Karma and Jasmine, I finally realized that I had no way to hand alter the test page that Karma uses as its testing environment. I had no way to add the various styles that I need to test.

To be clear, I could dynamically add <link> and <style> tags to the Karma test page, but part of the functionality that I spiked into <apply-author-styles> was to ignore dynamically added styles. I fought with Karma. A lot. Eventually I found that there is no way to specify an alternate test context page in Karma. Which just stinks.

So I am faced with two options: fight Karma again or trying something new. Both have their appeal (I think I could hack in basic support for alternate context.html), but I opt for something new tonight. Specifically, grunt-contrib-jasmine.

I start by installing it:
$ npm install grunt-contrib-jasmine --save-dev
...
Done. Phantomjs binary available at /home/chris/repos/apply-author-styles/node_modules/grunt-contrib-jasmine/node_modules/grunt-lib-phantomjs/node_modules/phantomjs/lib/phantom/bin/phantomjs
grunt-contrib-jasmine@0.6.5 node_modules/grunt-contrib-jasmine
├── es5-shim@2.3.0
├── lodash@2.4.1
├── rimraf@2.1.4 (graceful-fs@1.2.3)
├── chalk@0.4.0 (has-color@0.1.7, ansi-styles@1.0.0, strip-ansi@0.1.1)
└── grunt-lib-phantomjs@0.4.0 (eventemitter2@0.4.13, semver@1.0.14, temporary@0.0.8, phantomjs@1.9.7-9)
I believe that I am going to need a simple web server to test this, so I also install grunt-contrib-connect:
$ npm install grunt-contrib-connect --save-dev
In addition to the previous dependencies that I have in this project, my package.json configuration file now looks like:
{
  "name": "apply-author-styles",
  "devDependencies": {
    "grunt": "~0.4.1",
    "grunt-contrib-watch": "~0.5.3",
    "grunt-contrib-jasmine": "~0.6.5",
    "grunt-contrib-connect": "~0.8.0"
  }
}
I add both tasks to my Gruntfile.js:
module.exports = function(grunt) {
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    // ...
  });
  // ...
  grunt.loadNpmTasks('grunt-contrib-jasmine');
  grunt.loadNpmTasks('grunt-contrib-connect');
};
Then I configure both such that the tests will run on port 8100:
module.exports = function(grunt) {
  // Project configuration.
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    // ...
    connect: {
      server: {
        options: {
          port: 8100
        }
      }
    },
    jasmine: {
      src: ['app/**/*.js'],
      options: {
        host: 'http://127.0.0.1:8100/',
        specs: 'test/*Spec.js',
      }
    }
  });
  // ...
};
The last thing that I need in there is a task that will start the test server and then run my tests:
module.exports = function(grunt) {
  // Project configuration.
  grunt.initConfig({
    // ...
  });
  // ...
  grunt.registerTask('default', ['connect', 'jasmine']);
};
I make this my default task because I hope that this will be my main use for Grunt in this project.

I already have NOP spec in the test directory from my work yesterday and, it works:
$ grunt
Running "connect:server" (connect) task
Started connect web server on http://0.0.0.0:8100

Running "jasmine:src" (jasmine) task
Testing jasmine specs via PhantomJS

 <apply-author-styles>
   styles of elements using is
     ✓ should apply page CSS from <style> tags

1 spec in 0.017s.
>> 0 failures

Done, without errors.
All of this looks promising… until I try to add Polymer to the mix. I have a setup script that I can add as a helper in grunt-contrib-jasmine:
    // ...
    jasmine: {
      src: ['app/**/*.js'],
      options: {
        host: 'http://127.0.0.1:8100/',
        helpers: ['test/PolymerSetup.js'],
        specs: 'test/*Spec.js'
      }
    }
    // ...
The setup script adds the usual Polymer links and scripts to the page <head> and it works fine in Karma. But, when I run this in grunt-contrib-jasmine, I get:
➜  apply-author-styles git:(master) ✗ grunt
Running "connect:server" (connect) task
Started connect web server on http://0.0.0.0:8100

Running "jasmine:src" (jasmine) task
Testing jasmine specs via PhantomJS


log: platform.js is not the first script on the page. See http://www.polymer-project.org/docs/start/platform.html#setup for details.
>> ReferenceError: Can't find variable: Window at
>> http:/127.0.0.1:8100/bower_components/platform/platform.js:13 
>> http:/127.0.0.1:8100/bower_components/platform/platform.js:13 
...
And then I realize that I have already given up on PhantomJS (which is used by grunt-contrib-jasmine) with Polymer.

Ugh. I just don't think any of the objections from back then have been resolved. So it looks like I'm back to Karma and that ugliness. Sometimes it really is difficult to be so obsessive about testing...



Day #97

Tuesday, June 17, 2014

Karma Testing CSS in Polymer (Thwarted)


Up tonight, a bit of CSS testing. I don't know that I have ever tested code whose primary purpose was manipulating CSS, but how hard can it be?

The testing will apply to the newly minted <apply-author-styles> element. I will use the familiar combination of Karma and Jasmine to run the tests.

I start from a fixture page. In my test I will use a sample Polymer element, <x-foo>, and assert that various page classes should apply:
<polymer-element name="x-foo">
  <template>
    <apply-author-styles></apply-author-styles>
    <button id=test>Test</button>
  </template>
</polymer-element>
I start by forcing my HTML files in Karma to be treated as HTML source files, not fixtures (which would be available in the __html__ top-level lookup):
// ...
    preprocessors: null,

    files: [
      'test/PolymerSetup.js',
      {pattern: 'apply-author-styles.html', included: false, served: true},
      {pattern: 'apply_author_styles.js', included: false, served: true},
      {pattern: 'bower_components/**', included: false, served: true},
      'test/**/*Spec.js',
      {pattern: 'test/*.html', included: false, served: true}
    ],
    // ...
Then, in the PolymerSetup.js file that I still use for my Polymer testing, I load the definition for this test Polymer element in addition to loading <apply-author-styles>:
// ...

// 2. Load component(s)
var link = document.createElement("link");
link.rel = "import";
link.href = "/base/apply-author-styles.html";
document.getElementsByTagName("head")[0].appendChild(link);

var fixtureLink = document.createElement("link");
fixtureLink.rel = "import";
fixtureLink.href = "/base/test/x-foo.html";
document.getElementsByTagName("head")[0].appendChild(fixtureLink);

I keep forgetting that I am using Jasmine 2.0 nowadays and it takes me a while to remember how to install that. I need to add it to my NPM package.json file:
{
  "name": "apply-author-styles",
  "devDependencies": {
    "grunt": "~0.4.1",
    "grunt-contrib-watch": "~0.5.3",
    "karma-jasmine": "~0.2.0",
    "karma-chrome-launcher": ">0.0"
  }
}
And then run npm install. How could I possibly forget to configure and run a server-side package manager when configuring a client-side testing framework? It is completely obvious.

Ahem.

Finally, I am able to write a test:
describe('<apply-author-styles>', function(){
  var container, el;

  beforeEach(function(){
    container = document.createElement("div");
    el = document.createElement("x-foo");
    container.appendChild(el);
    document.body.appendChild(container);

  });

  afterEach(function(){
    document.body.removeChild(container);
  });

  describe('styles of elements using is', function(){
    it('should apply page CSS from <style> tags', function(){
      // ???
    });
  });
});
Unfortunately, I wind up stuck trying to test my specific element at this point. One of the main features of <apply-author-styles> is that it ignores styles that are not hard-coded in the original HTML document. Unfortunately, getting access to the original source document that is used to hold Karma tests—and to change it for a particular test run—seems difficult. At best.

I may have to alter my approach. Tomorrow.



Day #96

Monday, June 16, 2014

A Tag Named apply-author-styles


It occurs to me that, in the absence of the now-deprecated applyAuthorStyles in Polymer, it might be nice to have an <apply-author-styles> tag in Polymer. That is, if I define my custom polymer elements with <apply-author-styles>:
<link rel="import"
      href="apply-author-styles.html">
<script src="../bower_components/snap.svg/dist/snap.svg.js"></script>
<polymer-element name="x-pizza">
  <template>
    <apply-author-styles></apply-author-styles>
    <!-- ... --->
  </template>
  <script src="x_pizza.js"></script>
</polymer-element>
Then native elements (e.g. buttons) should pick up whatever crazy styles are defined in the top level document:



I figured out how to apply “author” styles over the past two nights. Now it is mostly a question of “if” and “how” to accomplish the same from a child custom element.

To find out, I remove all of the previous nights' code from my custom pizza building <x-pizza> Polymer element. With apply-author-styles.html imported and <apply-author-styles> in <x-pizza>'s <template> tag as from the beginning of this post, I am ready to start on the actual <apply-author-styles> Polymer definition.

I begin with the <polymer-element> definition in apply-author-styles.html:
<link rel="import"
      href="../bower_components/core-ajax/core-ajax.html">
<polymer-element name="apply-author-styles">
  <script src="apply_author_styles.js"></script>
</polymer-element>
This is simple enough. I import <core-ajax> to fetch the original parent page for comparison (as done last night). The rest sources the apply_author_styles.js backing class definition—there is no UI presence for this element.

With that out of the way, I start the JavaScript definition finding the main page document and the shadow root of the element that I am targeting:
Polymer('apply-author-styles', {
  attached: function() {
    this.parent = this.parentNode;
    this.authorDocument = this.ownerDocument;
    this.fetchOriginalOwnerDocument();
  },
  // ...
});
I need the parent node for access to the shadow root of the element that is holding <apply-author-styles>. I need the main document so that I only apply styles from the original, un-JavaScripted source. To get access, I fetch it with another, core Polymer element, <core-ajax> and, once I get it I start applying styles:
Polymer('apply-author-styles', {
  attached: function() {
    // ...
    this.fetchOriginalOwnerDocument();
  },

  fetchOriginalOwnerDocument: function() {
    var doc = this.originalAuthorDocument = document.createElement('core-ajax');
    doc.addEventListener('core-complete', this.addExternalCss.bind(this));
    doc.url = this.authorDocument.location.href;
    doc.go();
  },
  // ...
});
The addExternalCss() method is nearly identical to yesterday's version:
Polymer('apply-author-styles', {
  // ...
  fetchOriginalOwnerDocument: function() {
    var doc = this.originalAuthorDocument = document.createElement('core-ajax');
    doc.addEventListener('core-complete', this.addExternalCss.bind(this));
    doc.url = this.authorDocument.location.href;
    doc.go();
  },

  addExternalCss: function() {
    for (var i=0; i<this.authorDocument.head.children.length; i++) {
      var el = this.authorDocument.head.children[i];
      if (!this._isSupportedTag(el)) continue;
      if (!this._isFromOriginalAuthorDocument(el)) continue;

      var clone = el.cloneNode(true);
      if (clone.href != 'undefined') {
        clone.href = new URL(clone.href, document.baseURI).href;
      }
      this.parent.appendChild(clone);
    }

    // TODO: is this really the best way to handle this?
    this.element.convertSheetsToStyles(this.parent);
  },
  // ...
});
I gain access to Polymer's convertSheetsToStyles() method, which creates Polymer-ready versions of the various styles that are copied into the shadow root of <x-pizza>, not through <x-pizza>, but through <apple-author-styles>. I call that method with <x-pizza>'s shadow root, which feels a little wrong… except that it works

Not only does it work in Chrome, but in Firefox and even Internet Explorer:



So it looks like applyAuthorStyles is back—now in Polymer custom element form.

Without further ado… I introduce apply-author-styles.


Day #95

Sunday, June 15, 2014

Comparing the Original Owner Document


This is going to be a little esoteric, I think...

I have a means to replicate the old, deprecated applyAuthorStyles in Polymer elements. The idea is that I want certain elements—especially native elements like buttons—to look the same inside of custom elements as they do on the rest of the page. Until recently, this was the purview of the applyAuthorStyles setting in Polymer objects.

The working solution that I have is something of a brute force approach to the problem: I copy all stylesheet <link> and <style> tags into the shadow DOM of my custom element. It turns out that, with a few tweaks, this approach works just fine—even with odd orange borders applied to Bootstrap.com buttons:



A nice benefit of this approach is that there is no secondary request for external <link> stylesheets. The browser makes a request for the resource when it sees the <link> tag in the <head> of the page, but then relies on browser cache when it see a request for the same resource later:



The only drawback to this approach is that it pulls in all of the stylesheet <link> and <style> tags into the shadow DOM—even those that were added dynamically by Polymer. This does not result in any additional HTTP requests nor does it appear to affect styles, but I still object to this.

To get around this, I am going to compare the current CSS-related content in the main page—the “owner document” in Polymer parlance—with the original content of the main page. The only way to accomplish this (that I know of) is to re-fetch the original document via XHR. This seems ugly, but let's get on with it...

I replace yesterday's immediate copying of page styles into my Polymer element:
  attached: function() {
    this.addExternalCss();
    this.updatePizzaState();
  },
With a fetch of the original page via XHR:
Polymer('x-pizza', {
  created: function(){
    this.fetchOriginalOwnerDocument();
  },

Or, since this is Polymer, I use <core-ajax> to fetch the resource:
  fetchOriginalOwnerDocument: function() {
    var doc = this.originalOwnerDocument = document.createElement('core-ajax');
    doc.addEventListener('core-complete', this.addExternalCss.bind(this));
    doc.url = this.ownerDocument.location.href;
    doc.go();
  },
When the original owner document is fetched, then I call yesterday's addExternalCss() method. It still runs through the children of the owner document's <head>. Instead of skipping non-<style> and non-<link> tags. I now need an additional check to skip text that does not match content in the original document. Regular expressions to the rescue:
  addExternalCss: function() {
    var originalHtml = this.originalOwnerDocument.response;

    for (var i=0; i<this.ownerDocument.head.children.length; i++) {
      var el = this.ownerDocument.head.children[i];
      if (el.tagName != 'LINK' && el.tagName != 'STYLE') continue;

      var re = new RegExp(el.outerHTML);
      if (!re.test(originalHtml)) continue;

      var clone = el.cloneNode(true);
      if (clone.href != 'undefined') {
        clone.href = new URL(clone.href, document.baseURI).href;
      }
      this.shadowRoot.appendChild(clone);
    }

    // TODO: is this really the best way to handle this?
    this.element.convertSheetsToStyles(this.shadowRoot);
  },
That actually does the trick. I now have only three new stylesheet related tags appended to my shodow DOM:



I do find that some of the dynamically added CSS does not generate valid regular expressions. Rather than spend time parsing them and dealing with edge cases, I ignore them for now with a lovely try-catch:
  addExternalCss: function() {
    var originalHtml = this.originalOwnerDocument.response;

    for (var i=0; i<this.ownerDocument.head.children.length; i++) {
      var el = this.ownerDocument.head.children[i];
      if (el.tagName != 'LINK' && el.tagName != 'STYLE') continue;

      var re;
        try {
          re = new RegExp(el.outerHTML);
        } catch (x) {
          continue;
        }
      if (!re.test(originalHtml)) continue;

      var clone = el.cloneNode(true);
      if (clone.href != 'undefined') {
        clone.href = new URL(clone.href, document.baseURI).href;
      }
      this.shadowRoot.appendChild(clone);
    }

    // TODO: is this really the best way to handle this?
    this.element.convertSheetsToStyles(this.shadowRoot);
  },
That method is getting out of hand. It was not great before the try-catch, but it just looks way too big now. Still, it works. Hopefully I can distill this down into something easily resusable. Tomorrow.


Day #94