Wednesday, February 29, 2012

I need to finish off some work for the beta release of Dart for Hipsters, but first must honor the gods of my chain, who have been so very good to me, with a (hopefully) brief link in the chain...

Because I love testing, have included a chapter on testing in Dart for Hipsters. This would not normally be that much of a stretch, but in a bleeding edge language like Dart, the testing harness is only available in the "bleeding_edge" branch. Now that's bleeding edge.

Surprisingly, this bleeding edge bleeding edge testing harness works fairly well and includes some worthwhile features. What it does not include is a test coverage tool even though it has a tab for it:

And indeed, the getCoverageSummary method is nowhere to be found in either the darttest or unittest paths. I eventually find it, not it bleeding_edge/dart/client/testing, but in bleeding_edge/dart/compiler/lib.

With that, I get something in the tab, but it is zero test coverage despite the fact that I do have some coverage:

After looking through some of the code in compiler/coverage.dart, I begin to suspect that this code simply holds coverage information, but does not actually perform the tracking (perhaps the compiler does this). In fact, back in my test code, I can use a couple of the methods to set the expected number of function calls, and pretend that I made that call:

I have already warned readers that the testing chapter is bleeding edge, so I don't think it will come as a shock to them that the Coverage tab is not ready yet. Nevertheless, I am still excited enough by Dart testing to retain the chapter.

Tuesday, February 28, 2012

One of the cool things about working through a brand new language like Dart is happening across weird little nooks and crannies of the language specification. One such example is the call operator which seems to be a way to get objects to behave like functions. Or I could be misreading the spec, I have a hard time with that kind of thing.

My best guess is that I can define an operator named call() to set this up, so I will try this out with my Hipster MVC framework. For now, I will make it an alias for save() on the HipsterModel class.

I have already defined other operator methods in Dart. In the HipsterModel, for instance, I have the square brackets operator that allows developers to lookup attributes in models as if the model were a Map (e.g. comic_book['title']). This is defined using the operator keyword:

Sigh. Re-reading the spec again, it really seems as though it ought to be call(). Perhaps it is not yet supported? I try a dummy operator to see if the message is the same, and indeed, "invalid operator overloading" seems to mean that the token is not an operator:

I try the latest version of Dartium only to find the same thing. Grr...

It is at this point that I finally stumble across a description of how call()will work in Dart. At the very top, it states that this is brand new and not implemented yet. Darn it. On the bright-side, it does seem that my understanding of how it will work is correct.

Regardless, I refuse to give up until I have done something tonight, no matter how ridiculous. So I overload the pipe operator for HispterModel so that it saves itself and pipes the response into the supplied callback:

Monday, February 27, 2012

While writing the dynamic behaviors chapter in Dart for Hipsters, it occurred to me that I had skipped right over the noSuchMethod() method in my exploration of Dart. So tonight I revisit my Hipster MVC library to see if I can vary between local a remote storage with noSuchMethod().

I have yet to even try noSuchMethod(), but my guess is that it serves the same purpose as method_missing() in Ruby. That is, if a method is not explicitly defined in a class or any of its super classes, then noSuchMethod() should be invoked with the name of the method and the list of arguments. Furthermore, as a method on Object, it should be inherited by all classes. Then again, I could be completely off-base.

I glossed over the topic in Dart for Hipsters, but left the following psuedo-code as placeholder:

It works in the sense that I do not see my NoSuchMethodException. It also works in the sense that _defaultSave() is invoked. Those two small victories mean that my understanding of noSuchMethod() is more or less correct—it is invoked if Dart is otherwise unable to resolve the requested method.

Things go awry inside the on.load event listener. After the record is saved via XHR, the event listener attempts to invoke the optional callback, with less than ideal results:

What does Dart do with the optional label (callback in this case)? Since the result is a List, I can only assume that it ignores the optional parameter label, so I grab the first argument in noSuchMethod() and use that as the optional callback parameter to _defaultSave():

Since useLocal() is hard-coded to true, I give it a try and, indeed, I am storing locally:

I am now well-armed to write the noSuchMethod() section. That said, the current usefulness is limited to methods with fixed arity. Optional parameters in Dart boast that position does not matter: new Comics(el: '#comics', collection: my_comics) is the same as new Comics(collection: my_comics, el: '#comics'). This would definitely not be the case with dynamic methods implemented by noSuchMethod. Whether this is by design to limit dynamic methods or if a newer implementation is on the way, I cannot say. But I will have to find out for the book...

Sunday, February 26, 2012

While writing the Events chapter in Dart for Hipsters, I got to thinking about the square brackets operator for the Element#on getter. I know that it works for the existing events, such as click events:

Saturday, February 25, 2012

Yesterday, I began exploring type checking in Dart by running my test suite in checked mode (starting Dartium with --enable_type_checks). It did not have quite the effect that I expected and I cannot say that it improved my test suite. So today, am going to have a type-checked look at some of my code that is not yet tested. Perhaps type checking will prove of more use there.

So I load up my application in test mode and... it still works:

When I try to delete one of those test comic books, however, I get a big old stack trace:

Dart has a funny view of truthiness—everything but the boolean true is false. So even if my collection is non-null, the above will always return an empty string. So, yay! Type checking found a bug. I address it by explicitly comparing to null:

This turns out to be a bit more subtle. When an instance of AddComicForm is created, I am not assigning the optional el parameter in the constructor. Thus el is null, which is not an Element, resulting in a document.query() of null. Since document.query() expects a String, I am now getting a type checking error.

In this particular case, it is not a bug because AddComicForm overrides post_initialize to create this.el. Thus, any other view operations will succeed because this.el is defined. But that is only true for this particular class. If someone else created a view with no el, there would be errors. What I really need is something like Backbone.js's ensureElement. I will worry about that another day. For now, I make the this.el assigment conditional on el being supplied and I assert that this.el has been defined after post_initialize:

With the post_initialize() method in place, I am again able to bring up the add-new-comic form:

Everything else seems to work. I can again add, delete and view my comics collection—even in type checking mode.

The type checking option seemed more of an annoyance with testing than a help, but it definitely seems to help when actually coding. Without it, I had allowed at least one bug to get into my Hipster MVC framework along some questionable choices. It seems that coding in type checking mode is good advice—even if most users will run in regular mode.

Friday, February 24, 2012

An intriguing feature of Dart is the ability to run the VM in checked mode. As I have coded Dart for the past couple of months, I have noticed a certain... looseness in its enforcement of types. It is not just that I avoided declaring any type information for the better part of the first month that I coded in Dart. I have also noticed that Dart is perfectly willing to let me declare a variable as one thing, but assign something else entirely to it.

I have come to regard types in Dart as little more than documentation. To be sure, it is very useful documentation, but since types are not enforced (as best I can tell), I can code very like I am used to in dynamic languages like Ruby and Javascript.

There are times, though, that it bothers me knowing that I could be missing out on bugs that loose typing might be allowing. That was part of the motivation of getting comfortable with testing these last couple of days, but still... I should not be able to assign a list of Maps:

But I cannot add a Map to List<HipsterModel> models instance variable. I do not quite understand this, but I do know how to resolve the failure. I need to import HispterModel into the test suite so that I can create a dummy sub-class:

I don't know that I have really gained much through this exercise of typed checking testing. If anything, I was closer to using mocks in a situation in which it was fine to do so. I think tomorrow I will explore more of the code to see if there are any other potential benefits to this type checking stuff.

Thursday, February 23, 2012

Today, I continue exploring unit testing in Dart. I am using the bleeding edge in-browser testing suite, which has worked fairly well so far. It seems as though it is meant to be run right on top of the live application, which could be interesting—add a <script> tag and see the test suite results overlayed on the application.

I have tested most of the Collection aspects of the HipsterCollection class from my Hipster MVC framework. Tonight I hope to cover the Ajax features. First up, the fetch() method. I am not sure how to go about doing this, so I start by verifying that calling fetch() directly on the base class fails (a sub-class needs to define url()):

That test.json file exists. Even if I load it in the test page via script tag, I still get a CORS violation.

I deal with with the same thing when I use Jasmine to test JS applications, but at least with those I can use libraries like sinon.js to fake XHR responses. I cannot do that in Dart without somehow telling my MVC library to use a different XHR object. Luckily, I can do just that.

Based on Backbone.sync, the HipsterSync class allows me to redefine the manner in which storage operations are performed. By default, it uses XHR, but I can swap that out for a no-op:

When I run the test suite now, I see the no-op print() output in the Dart console:

[sync] get / Instance of 'TestHipsterCollection'

And all of my tests are again passing:

They might be passing, but I am not really testing anything other than that the application does not crash. To be sure, there is value in that, but I can do better. The HipsterSync call is an asynchronous callback. Rooting through the bleeding edge test suite, I come across the asyncTest() function. This is not a vows.js-style assertion that a specific callback is invoked. Rather, it provides a mechanism to say that any number of callbacks will be invoked and a way to signify that they were actually called.

In this case, I expect that my sync callback will be invoked once. To verify that it has been called, I invoke callbackDone() inside the sync method:

Actually, that is not so much failing as preventing the suite from completing. That is better than nothing, but it would be preferable to say that, if the proper number of callbacks have not been invoked in a certain amount of time, then the test fails. Something to investigate another day.

Wednesday, February 22, 2012

Having gotten a dummy Dart unit test to pass last night, I try my hand at testing some of the Hipster MVC library code with which I have been playing.

First, I copy the testing directory from dart bleeding edge into my app. Tonight I store the contents of testing, the unittest and darttest sub-directories, under tests/lib in my main application directory:

Tuesday, February 21, 2012

I am somewhat test obsessed. I have been exploring Dart for nearly 2 months and have not even considered testing, which is why I am only somewhat test obsessed. But tonight I can ignore the nagging doubts no longer.

So first, I install subversion (seriously, who still uses subversion?):

sudo apt-get install subversion

Then I can checkout the testing path:

➜ tmp svn co http://dart.googlecode.com/svn/branches/bleeding_edge/dart/client/testing/
A testing/unittest
A testing/unittest/shared.dart
A testing/unittest/dom_for_unittest.js
A testing/unittest/unittest.dart
A testing/unittest/coverage_controller.js
A testing/unittest/unittest_vm.dart
A testing/unittest/dom_for_unittest.dart
A testing/unittest/test_controller.js
A testing/unittest/unittest_node.dart
A testing/unittest/unittest_dartest.dart
A testing/dartest
A testing/dartest/dartest.dart
A testing/dartest/css.dart
A testing/dartest/resources
A testing/dartest/resources/expand.png
A testing/dartest/resources/min.png
A testing/dartest/resources/close.png
A testing/dartest/resources/max.png
A testing/dartest/resources/img2base64.py
A testing/dartest/README.txt
Checked out revision 4421.

Lastly, I remove subversion, just on principle:

➜ tmp sudo apt-get remove subversion

It seems as though this is meant to be run in the browser (I would hazard a guess that it needs to be Dartium)—the README mentions an overlay window and the libraries make use of dart:html. So I create a test HTML in the testing directory with a reference to the Dart code being tested:

That resolves the stack trace, but I am not quite sure that it worked. The results overlay seems oddly free of green:

Ah ha! It seems that I need to manually run my test suite by clicking on that play button. When I do so, I see green:

If I intentionally break the test:

test('Test Description',(){
Expect.equals(42, myAddFunc(1,2));
});

Then, when I reload and run my suite again, I see red. I can even click on the failing spec to get a good idea what went wrong:

That is a good stopping point for today. The Coverage tab is not working for me, so I may pick up with that tomorrow. Then again, I am eager to see how this plays with live code, so I may ignore the Coverage tab for a little while longer.

Monday, February 20, 2012

Up tonight, hopefully a quick exploration of iterators in Dart. Iterators are the mechanism in Dart that allow any object to be used in a for-in block. I do not necessarily think that my ImageCarousel class needs an iterator to do its thing, but it is the most recent collection-like thing that I have to play with, so...

First up, I define the carousel as extending Iterable:

class ImageCarousel implements Iterable {
// ...
}

To actually implement Iterable, I need to define an iterable() method:

I am really coming around to the this.XXX constructor parameter format in Dart. It is a crazy easy way to say that the first argument passed to the constructor (in this case an instance of ImageCarousel from its iterator() method), should be assigned to the imageCarousel instance variable. In addition to assigning the instance variable, I also initialize the position of the iterator to -1 so that the next element will be the zeroeth of the array in ImageCarousel (ah, Array indexing).

Next, I define the hasNext() boolean function. That is easy enough—as long as _pos is before the last index in the array, there is a next element to be returned:

I am also starting to really dig the hash-rocket short hand for function and method bodies—I can skip the return keyword and the curly braces (win, win). Because arrays start at zero, the lastIndex of an array is the length minus 1. I define a getter for this solely to make the hasNext() function easier to read.

Last up, I implement the next() method, which return the element at _pos as well as increments _pos for the next time through. I also have to throw an exception if next() has navigated past the bounds of the object being iterated:

Sunday, February 19, 2012

Last night, I was able to get my Dart-based image carousel more or less working:

When the image on the right appears, it immediately covers the image that used to be there before it has a chance to rotate. The effect is less than desirable. Part of the problem is that I am starting the carousel at image #3 instead of #4:

The carousel achieves this effect by drawing each face of the carousel one at a time. When the carousel moves to the next image, it moves each image on the carousel. The animation effect comes from the CSS3 transform and translate transitions:

Finally, I have a next() method that rotates things by incrementing the internal _pos counter and telling the carousel to draw itself:

void next() {
_pos++;
draw();
}

Actually starting at #4 instead of #3 helps, but there is still some bleed though of #4 superimposed over #3. To resolve that, I start #4 with zero opacity and give #3 an opacity of 0.8. For good measure, I give #0 an opacity again of zero so that there is no abrupt disappearance when the image is removed. Since the _draw() method returns an Image element, and since the shorthand syntax for _draw0 through _draw4() returns the result on the right-hand side of the hash-rocket (=>) operator, I can apply these opacities in the draw() method like so:

When an image is added in slot #4, it has opacity zero. When it rotates to #3, it is assigned opacity of 0.8, which it retains as it move to #2 and #1. Finally, when it reaches #0, its opcacity is again set to zero where it can be safely removed from the UI.

The effect is much nicer:

After adding a prev() method to my carousel, I swap out the auto-rotating for a rotate by arrow key handler:

Last up tonight, I try compiling this into Javascript using Dart's frogc compiler. It works, but nothing displays, at least not under Firefox version 10. I trace this to frogc's use of -moz-transform-style in the generated JS. If I remove that:

Saturday, February 18, 2012

For the past few days I have been enjoying playing with the concept of an image gallery in Dart. Actually, it is as much playing with experimental CSS3 features as it has been Dart, but regardless, it has been fun.

I had gotten the gallery working to the point that I could move the main image off to the side, shrink and blur it:

The animation was all done with simple CSS3 (well, some of it was really CSS1):

Instead of doing something like that, I would like to make a more realistic carousel. Using CSS3 transform and translate, I ought to be able to make the images rotate about, like a carousel or merry-go-round. So I break things up in to an ImageCarousel class:

I am going to use panels on this carousel of width 250 pixels -- that should yield a carousel that is a little larger than 500 pixel wide, depending on perspective. For perspective, or the distance that the user is from the page, I use 1000 pixels.

I am still using the same transition of 1 second, easing into and out of motion. I "preserve-3d" so that the images do not look flat on the page. And lastly, I rotate the images, depending where on the carousel they happen to be. The actual 3D transform is done with CSS3 transforms. Here, I am rotating the image about the Y axis. The translate along the z-axis (out of the page) is necessary because the images to the left and right of the main image are rotated about the center of the image. That is, it would look as if one edge were sticking out of the page. To get everything looking OK, I have to ensure that the images behave as if they are a certain distance away from the center. The _depth() function is swiped from the very cool Intro to CSS 3D transforms article.

And it works. Kind of:

I need to improve the rotate-in transform so that it does not seem as though it overwrite the previous image, only for the previous image to pop out. Still, this is a pretty good start. I think tomorrow I will take some time to make it a little more Darty.

Friday, February 17, 2012

Today I continue to play with last night's images gallery. I hope to combine a few more animations together, if for no other reason than to see how easy it is in Dart. But first...

I keep coming across the #resource directive in the dart language spec. The spec states that they are used to "include extralinguistic resources (e.g., audio, video or graphics files)", which seems like they might be useful for an image gallery.

I try fiddling with the order a bit, but it seems pretty clear that, even though #resource() is in the spec, it it not yet implemented in Dartium.

Back to my regularly scheduled programming then...

The current gallery combines two animations as it moves through the list of images in the gallery. The two animations are mirrors of each other with the new image fading in while the old one fades out:

Tonight I am going to change the remove animation to shift the image to the right and behind the main image, making it smaller as it goes. I think this ought to be easy, but "ought" is usually the bane of my learning. And by bane, I mean it usually goes wildly wrong and I end up learning something.

Thursday, February 16, 2012

Adam Smith has a very nice canvas-based image gallery written in Dart (may take a while to load) up on the githubs. I am still undecided about including SVG / canvas stuff in Dart for Hipsters, but I do think a chapter on animation is in order. I have already experimented with simple animations in Dart, this seems like a good chance to do something a little more interesting.

The problem? There is no animation. Instead the element displays immediately. Since it is the newly added element, it immediately covers up the old element. After way too much fiddling, I find that a timeout, even of only a couple of milliseconds allows the transition to work:

Wednesday, February 15, 2012

Last night I figured out how to inject shared behavior in Dart. Today I need to use that knowledge to support an injectable sync in my HipsterMVC framework.

First up, I convert yesterday's proof of concept to something resembling what I envision as the final product. The HipsterSync class exposes a setter (sync=) allowing application code to inject behavior, and a method for internal libraries to invoke the appropriate behavior. I start with:

Nice. My proof of concept is closer to being reality. Next, I need to do something real with the default implementation. I remove the injected behavior. Then, back in HipsterSync, I add the Ajax that used to be in HipsterCollection#fetch():

Ah. That _handleOnLoad callback method is defined back in the collection class. I need a mechanism to pass that into HipsterSync. Those options look like a good place to start. In HipsterCollection, pass the on-load callback via an 'onLoad' key:

In here, I have adapted my local storage solution. In order for both local storage and Ajax to submit data to the on-load callback, I had to alter the callback to expect data rather than an event from which the data could be extracted. Once that is done, the injected behavior of local storage is working:

Cool! I can switch back and forth between local storage and the default Ajax implementation by adding and removing the HipsterSync.sync local behavior. I still need to get all of this working with my model class, but hopefully that will prove relatively easy now that I have my collection working properly.

Tuesday, February 14, 2012

At the B'more on Rails meetup tonight, Nick Gauthier, my Recipes with Backbone co-author, included an interesting discussion on frameworks vs. libraries. He pointed out that frameworks generally call user written application code whereas libraries encourage application code to call library code (usually through inheritance). It occurs to me that this is the crux of my recent struggles with my Dart MVC framework—I am having a hell of a time injecting a sync() method for my model and collection classes to call.

I had planned on giving this a miss, but, partly egged on by Nick and partly by comments from Justin Fagnani in last night's post, I am going to try again.

My first attempt tonight focuses on using a global variable to hold this information. I do not expect to stick with a global, but just hope to use it as a proof of concept. First, I establish a "internal" version of a variable that will point to my sync function:

var internal_sync = null;

Then I define an externally facing setter function for the internal version:

var internal_sync = null;
set sync(fn) {
internal_sync = fn;
}

In my framework, internal_sync would have a default Ajax implementation, but the developer could inject different behavior by setting a different function via the external sync= setter.

And this works, to a certain extent. In my main() entry point, I can set sync and invoke the new behavior:

Inside main() I set the sync= setter to a function that prints out an argument and returns a "hip new behavior". I then invoke the function that is now referred to by the internal_sync global variable. And it works. I see the set function being called and I see the "hip new behavior":

[new_sync] Injected, yo
sync: hip new behavior

The problem is that this internal_sync variable is not available inside libraries. For instance, the Collections.Comics.dart library is imported and used in main() after the updated internal_sync is set:

I get similar results if I try to treat this internal_sync as a function.

It is not possible to declare variables before #import() statements in Dart, nor is it possible to include code via #source() before #import(). So, if the problem is that the global is declared too late, then I am out of luck.

I switch tactics at this point. If a global variable will not work, perhaps a class methods will. So I define a HipsterSync class in HipsterSync.dart with a familiar class variable and class setter:

And... that does the trick! In the Dart console, I see the output from main():

[new_sync] Injected, yo
sync: hip new behavior

Followed immediately by the output from the newly set HipsterSync.sync when invoked by the collection's fetch() method:

[new_sync] fetch, yo
[fetch] sync: hip new behavior

It took me a while to figure that out (and much thanks to Justin Fagnani for pointing me in the right direction), but I am finally able to inject model and collection syncing behavior into my MVC framework. Using static methods to set and hold this behavior also ensures that the behavior can be shared between both the collection and model classes. I am excited.