Wednesday 29 October 2008

GGUG meeting tomorrow

Just an FYI that this months Grails user group meeting is tomorrow night. Here is the link if you want to come. Grails meetup

Joda DateTime Ranges

Recently I was attempting to create a Range representing the difference between two DateTime values so I could assert in a test that a date time value fell into that range. I was using Joda Time's DateTime class. The java.util.Date class is compatible with Groovy's ObjectRange becuase it's decorated with next and previous methods by the GDK. Joda's DateTime isn't, so I ended up doing this:
    DateTime start = new DateTime()
DateTime end = start.plusYears(1)
Range range = start.millis..end.millis
I could have created a custom Range implementation but I'd have lost the option of using the x..y notation and I'm a sucker for brevity. I figured Groovy has an IntRange class so there's probably a LongRange as well. As it turns out there isn't and what I ended up with is an ObjectRange.

Fundamentally this works, although I did find something worth bearing in mind. When it came to my assertion I tried to do this:
    static void assertInRange(Range expected, actual) {
if (!expected.contains(actual) {
fail("Expected value in range:<${expected}> but was:<${actual}>")
}
}
Simple enough, right? Except running the code caused the test to hang. Looking into the implementation of ObjectRange it became clear why. Groovy's Range interface extends java.util.List and that's where the contains method is specified. For compatibility with the List interface ObjectRange iterates over the values between its from and to properties using the next method I mentioned above. When from and to are Long instances, it turns out this iteration takes a while - on my 2.16GHz iMac the contains method takes over 4½ minutes on a 1 year range!

The Range interface also specifies a containsWithinBounds method and ObjectRange implements this by simply checking that the argument is >= from and <=to. Changing my assertion to use containsWithinBounds got rid of the long wait.

What ObjectRange is doing does make perfect sense. Given two arbitrary objects that implement Comparable and the next and previous methods it needs to implement contains in a way that conforms to the List interface. When you think about how the GDK implements next and previous on java.util.Date for example you can see that there may be possible values of a given class that fall inside a range but would never be part of the List generated by repeatedly using next on the range's from property. This isn't true of Long, of course, but ObjectRange is a general purpose class. The IntRange class has a much optimised version of contains and so could a theoretical LongRange implementation.

Anyway, getting back to the example. After changing contains to containsWithinBounds the code ran much faster, unfortunately it also threw java.lang.OutOfMemoryError: Java heap space. It turns out this is down to how GString handles the ObjectRange value I inserted into it. It spots that the object it's got implements List and uses InvokerHelper.toListString on it. This will attempt to create a String in the form "[0, 1, 2, 3...]". As you can imagine, building such a String is going to take some doing with over 31½ billion elements in the List, hence the heap space ran out.

A final working implementation of my assertion method is:
    static void assertInRange(Range expected, actual) {
if (!expected.containsWithinBounds(actual)) {
fail "Expected:<${expected.toString()}> but was:<${actual}>"
}
}
I think going for the custom Range implementation in the first place might have actually been the right choice.

Saturday 18 October 2008

Gmock - Groovy Mock

Mock Object are key players in Unit Testing. Groovy support natively some mock object with MockFor and StubFor but their functionality are quite limited and the syntax heavy - you'll understand when you nest 7 'use' closures.

Gmock aims to simplified mocking in Groovy through a intuitive syntax and a great readability. In a nutshell a Gmock test look like:

void testTree(){
def mockTree = mock()
mockTree.load('fruit').returns('apple')
play {
assertEquals "apple", mockTree.load('fruit')
}
}
This is it!. Expectation are being setup by calling normal method on you mock object. The code under test is executed within the play closure and your mocks are automatically verified after it.

The current version gmock-0.2 support the most basic functionality you would expect from a mocking framework. Version 0.3 should see static method mocking and property mocking. Future development are described in the Roadmap.

Wednesday 15 October 2008

Selenium and Firefox 3

Those of you who've tried to run the selenium test suite using Firefox 3 as the browser have probably found that Firefox hangs trying to create the temporary profile. You could do some tedious mucking about with selenium.browser="*custom /usr/lib/firefox/firefox -no-remote -P selenium", manually configure the proxy, etc. However, it turns out there's a simpler solution.

Please note this is nothing to do with Selenium IDE, if you're having problems with that in conjunction with Firefox 3 this won't help.

Tuesday 14 October 2008

A “clearfix” CSS redux

We use a CSS technique called "clearfix" within several projects. This is implemented as a class (called "clearfix") that is applied to a parent element that contains floated child elements.

I wrote a post over at Code Couch that attempts to explain the reason for doing this in the first place, describes the CSS that we use and provides plenty of links for detailed reference.

Thursday 9 October 2008

XHTML — myths and reality

Tina Holmboe is a member of the XHTML Working Group and has an interesting write-up XHTML — myths and reality that discusses the current state of XHTML and dismisses some popular inaccuracies.

Having hyped up the post, it is rather old news - although it is discussed in simple (simplistic?) terms which I find is better than overloading with jargon.

Here are some hilights:

Lack of support for XHTML is a fact of life on the web in 2008. Prior to the 3.0 series of Firefox the XHTML processor in Gecko was so poor that Mozilla's own engineers recommended against it;
No version of Internet Explorer up to, and including, IE 8 support XHTML at all, and a number of other browsers such as Lynx were never written to handle XML in the first place.

I wrote a post for another blog a while back that looked into how you can identify the appropriate doctype for your web page - and stumbled across this "lack of support" for XHTML in modern browsers. You can read the original post How to choose a doctype if you are interested.

Whilst XHTML remains a much more structured (and cleaner) choice to deliver content to the browser, I have yet to work on a single project where it is actually required.

XHTML is the default for use within the Grails framework - even though the worlds most prolific browser doesn't support it. Hmmm.

Programmatic Transactions

By default grails starts a new transaction the first time it enters a service method and commits the transaction when it returns. You can disable this behaviour by declaring your service to be non transactional.

Sometimes you need more fine grained control. Here's a link to a great discussion which unfortunately doesn't seem to have made it into the Grails manual yet, however this is still talking about declarative transactions, rather than programmatic ones.

If you really do want programmatic transactions you can use
DomainObj.withTransactions { TransactionStatus ts ->
serviceA.doStuff()
serviceA.doMoreStuff()
serviceB.yawn()
}

But the caveat (and reason for this post) is that in the above scenario will only create a new transaction if one does not already exist. If the above is placed in a controller it will work fine. If it's placed in a service with
static boolean transactional = false

it will work fine, PROVIDING that the service is being called by a controller or other non-transactional service, however if your non-transactional service is called by a transactional one, the withTransactions block will have no effect.