Groovy And JScience Sunday, June 04, 2006

I have been spending a lot of time investigating Groovy lately. I wanted to dig in to writing a Groovy Category so I started writing some code to support things like this...


def duration = 30.minutes + 2.hours


Before I got too far along there I discovered that John Wilson had already implemented a lot of that in his TimeCategory which is part of Google Data Support.

I had recently read a JNB article that Lance Finney had written on JScience and that gave me another idea. I decided to write a Groovy Category that would use JScience to support things like this...


def len = 2.kilometers + 500.meters


Since I wanted to do this as an exercise I decided to not even do any research to find out if anyone had already implemented something like this. I wanted to build this for my own benefit as a learning exercise. I started by expressing some of my own requirements in the form of a Groovy Unit Test like this...


class JScienceTest extends GroovyTestCase {

void testConversions() {
use(JScienceCategory) {
def len = 2.kilometers
assertEquals 2.0, len.kilometers, 0.00001
assertEquals 2.0E3, len.meters, 0.00001
assertEquals 2.0E5, len.centimeters, 0.00001
assertEquals 2.0E6, len.millimeters, 0.00001
assertEquals 2.0E9, len.micrometers, 0.00001
assertEquals 2.0E12, len.nanometers, 0.00001

def len2 = 400.centimeters
assertEquals 4.0E-3, len2.kilometers, 0.00001
assertEquals 4.0, len2.meters, 0.00001
assertEquals 4.0E2, len2.centimeters, 0.00001
assertEquals 4.0E3, len2.millimeters, 0.00001
assertEquals 4.0E6, len2.micrometers, 0.00001
assertEquals 4.0E9, len2.nanometers, 0.00001
}
}

void testAddition() {
use(JScienceCategory) {
def len = 2.kilometers + 500.meters
assertEquals 2.5, len.kilometers, 0.00001
}
}

void testSubtraction() {
use(JScienceCategory) {
def len = 3.kilometers - 500.meters
assertEquals 2.5, len.kilometers, 0.00001
}
}

void testMultiplication() {
use(JScienceCategory) {
def len = 3.kilometers * 2
assertEquals 6.0, len.kilometers, 0.00001
}
}

void testDivision() {
use(JScienceCategory) {
def len = 42.meters / 3
assertEquals 14.0, len.meters, 0.00001
}
}
}


My Groovy Kung Fu is still developing and I had not done anything at all with JScience before this. Even with those limitations I was able to get all of those tests passing in about an an hour.

Would you rather do this in Java...

Measure length = Measure.valueOf(50, SI.CENTI(SI.METER)).plus(Measure.valueOf(25.0, SI.METER));
Measure lengthInCentimeters = length.to(SI.CENTI(SI.METER));
System.out.println("length in centimeters is " + lengthInCentimeters.getEstimatedValue());


Or do this in Groovy...

def length = 50.centimeters + 25.meters
println "length in centimeters is ${length.centimeters}"


Isn't Groovy fun? :)

1 comments:

Antony Stubbs said...

Please, post the code! That's a great idea and especially something people would find really useful for unit tests (me!) :)

If it's not complete, I would be interested in helping you finish it up!

_______________________
stubbisms.wordpress.com