Loading...

Friday, March 19, 2010

Grails Goodness: Generate ANT Build Script

In versions of Grails before version 1.2 we got an ANT script with Ivy support when we created a new application. With Grails 1.2 we don't get the ANT script anymore automatically. But we can still generate the build file and Ivy configuration files, but we have to use a separate command: integrateWith. The complete command is:

$ grails integrateWith --ant

Tuesday, March 16, 2010

Grails Goodness: See Test Output on the Command Line

As from Grails 1.2 we can see the output from test scripts directly on the console. We must use the arguments -echoOut and -echoErr when we run the tests.

$ grails test-app -echoOut -echoErr

Monday, March 15, 2010

Grails Goodness: Using MetaClass with Testing

We can use the metaClass property of classes to define behavior we want to use in our tests. But if we do, the change is not only for the duration of a test method, but for the entire test run. This is because we make a change at class level and other tests that use the class will get the new added behavior. To limit our change to a test method we first use the registerMetaClass() method. Grails will remove our added behavior automatically after the test method is finished.

Let's see this with an example. We have a domain class User which uses the Searchable plugin. This plugin will add a search() and we want to use in our test case.

class User {
    static searchable = true
    String username
}

class UserTests extends GrailsUnitTestCase {
    void testSearch() {
        registerMetaClass User
        User.metaClass.static.search = { searchText ->
            [results: [new User(username:'mrhaki')],
             total: 1, offset: 0, scores: [1]] 
        }
        assertEquals 'mrhaki', User.search('mrhaki').results[0].username
    }
}

Friday, March 12, 2010

Grails Goodness: No More Questions

Sometimes when we run Grails commands we get asked questions via user prompts. For example if we invoke $ grails create-domain-class Simple we get a message that it is good practice to use package names and the question "Do you want to continue? (y,n)". We need to answer this question to continue, but what if we are not able to answer the question, for example if the script is run on a continuous integration server? We pass the argument --non-interactive to the grails command and now we don't get a question and the script continues by using the default value for the answer. So in our example we can run $ grails create-domain-class Simple --non-interactive.

Thursday, March 11, 2010

Groovy Goodness: Use Keywords as Method Names

Normally we cannot use keywords in Java or Groovy to use as method names. But in Groovy we can. We need to enclose the keyword between single or double quotes as we define the method. In the following example we create a method with the name switch, which is a Java/Groovy keyword.

class User {

    String username
    
    String 'switch'() {
        username = username.reverse()
    }

}

def u = new User(username: 'mrhaki')
assert 'ikahrm' == u.switch()

Wednesday, March 10, 2010

Grails Goodness: Get Values from Parameters with Same Name

Grails supports type conversion on request parameters. But it is also easy to handle multiple request parameters with the same name in Grails. We use the list() method on the params and we are sure we get back a list with values. Even if only one parameter with the given name is returned we get back a list.

// File: grails-app/controllers/SimpleController.groovy
class SimpleController {

    def test = {
        // Handles a query like 'http://localhost:8080/simple?role=admin&role=user'
        def roles = params.list('role')
        render roles.join(',')  // Returns admin,user
    }

}

Tuesday, March 9, 2010

Groovy Goodness: Use Strings as Subscript Operator

Groovy adds the method getAt(String) to the Collection class. We can use it to request property values from elements in a list.

class User { String name }
def list = [new Date(), new User(name: 'mrhaki'), 42.0, 'Groovy Rocks!']

assert ['java.util.Date', 'User', 'java.math.BigDecimal', 'java.lang.String'] == list['class']['name']

Monday, March 8, 2010

Groovy Goodness: Use Ranges as Subscript Operators

In Groovy we can use variables as subscript operators to get values from a list.

def list = ['Java', 'Groovy', 'Scala']

def index = 0
def indices = [0,2]
def range = (1..-1)

assert 'Java' == list[index]
assert ['Java', 'Scala'] == list[indices]
assert ['Groovy', 'Scala'] == list[range]

Friday, March 5, 2010

Groovy Goodness: Intersect Collections

In Groovy we have a lot of useful methods to work with collections and lists. For example if we have two lists and want to determine which elements are in both lists, we can use the intersect() method. We can use the disjoint() to test if both collections contain common elements are not.

def one = ['Java', 'Groovy', 'Scala']
def two = ['Groovy', 'JRuby', 'Java']
def three = ['C++', 'C##']

assert ['Groovy', 'Java'] == one.intersect(two)
assert [] == one.intersect(three)
assert one.disjoint(three)
assert !one.disjoint(two)

Thursday, March 4, 2010

Groovy Goodness: Invoke Methods Dynamically

In Groovy we can invoke a method just like in Java: we simply type the name of the method in our code. But what if we want to invoke a method name, but we don't know the name yet when we write the code, but we do know it at runtime? We can use the Reflection API for example to invoke the method, but in Groovy it can be shorter. In Groovy we can use a variable value for method invocation with a GString. The GString is evaluated at runtime and the result must be the method name we want to invoke.

class Simple {
    def hello(value) {
        "Hello $value, how are you?"
    }
    
    def goodbye() {
        "Have a nice trip."
    }
}

def s = new Simple()
def methods = ['hello', 'goodbye']

assert 'Hello mrhaki, how are you?', s."$methods[0]"('mrhaki')
assert 'Have a nice trip.', s."$methods[1]"