Archive

Archive for September, 2009

Visual Indicating Constraints in Grails View Generation

September 17th, 2009 Flo No comments

There was thread in the gr8forum recently regarding assigning css classes on property input fields depending on associated constraints. I think this is a nice idea and played around a bit and it turned out that this is quite simple. Here is my solution without changing grails source code.

At first you have to install Artifact and Scaffolding Templates using:

grails install-templates

This will install the templates that will be used for static scaffolding to src\templates.
Now you can customize them by simply editing the appropriate file, e.g., \src\templates\scaffolding\Controller.groovy if you want to change the Controller template.

At first I define for which Constraints I care, e.g.,

def iCareAbout = [org.codehaus.groovy.grails.validation.ConstrainedProperty.BLANK_CONSTRAINT, org.codehaus.groovy.grails.validation.ConstrainedProperty.NULLABLE_CONSTRAINT]

A property with constraints applied is represented as ConstrainedProperty. There is a method name called getAppliedConstraints where you get a Map of applied constraints to that property. Then you need to filter out the ones you care about.

Base class for all Constraints is AbstractConstraint but there are subclasses for special constraints like AbstractVetoingConstraint for nullable and blank and AbstractPersistentConstraint for unique constraint that may need access to database (for generating id on some databases).

Alltogether this looks like:

cp.getAppliedConstraints().findAll{i -> iCareAbout.contains(i.name) }.each { it.each { print it.constraintParameter?" " + it.name:" not" + it.name } }

This iterates over the constraints you care about and looks at the constraintParameter, which is a Boolean (at least for blank and nullable), is set. If it is set it prints the name of the constraint, if not it prints “not” + the name.

This enables you to style the elements later through css classes.

<tr class="prop<% cp.getAppliedConstraints().findAll{i -> iCareAbout.contains(i.name) }.each { it.each { print it.constraintParameter?" " + it.name:" not" + it.name } } %>">
	...
</tr>

The full file can be downloaded here.

For a Domain class like

class Book {
	String name
	Boolean inLibrary

	static constraints = {
		name(blank: false, matches:"[a-zA-Z]+")
		inLibrary(nullable: false)
		}

}

The output would look like:

<tr class="prop notblank notnullable">
	<td valign="top" class="name">
		<label for="name">Name:</label>
	</td>
	...
</tr> 

<tr class="prop notnullable">
	<td valign="top" class="name">
		<label for="inLibrary">In Library:</label>
	</td>
	...
</tr>

Notice the not nullable constraints applied automatically and the matches constraint is not taken into account.

BTW: There is also a open issue in the JIRA about that http://jira.codehaus.org/browse/GRAILS-270 so if you are interested then you can watch and vote it.

Categories: Allgemein Tags:

Clearing Console in Cygwin

September 9th, 2009 Flo 1 comment

Just a short one but hopefully helpful!

I’m working a lot on Windows at the moment but I have Cygwin installed as Unix environment, e.g., for working with git scm.
One thing I thing I was missing is that I could not clear the console with “cls” which was pretty annoying.

After doing a little research I figured out how to fix that.

1. using CTRL – L
2. defining an alias like

alias clear='cmd /c cls'

If you just type it in a cygwin shell it will only be available for the current session.

If you want to make this alias persistent you need to edit ~/.bashrc with your favourite editor and add it.

You will also find many other predefined aliases there which are commented out.

Categories: howto Tags:

ClipX Clipboard Manager

September 7th, 2009 Flo No comments

I’d like to introduce you to my favourite program today!

I pretty use the clipboard a lot as a temporary storage. Unfortunately the default clipboard is limited to one entry.
There’s an really awesome program out there called ClipX.

ClipX is a tiny clipboard history manager. It is sweet, it is free, use it.

So how does it work? The good thing is that basically everything stays the same. You keep using STRG C and STRG V for default copy & paste.
But you can define an alternative paste combination (I used STRG SHIFT V) to get that small popup menu and see a history of the last 10 entries, but you can configure that.

ClipX in Action (http://www.bluemars.org/)



Once used to it’s really a great helper and I could not imagine working without this little friend. You can also save and preview multiple pictures.

There is also a plugin system but I did not use it very much, I only got one plugin to have sticky notes. There are also hotkeys to quickly do a google search.

clipxsettings

Download it at at http://www.bluemars.org/clipx/ and give it a try, I’m sure you’ll love it!
FYI: I stumbled upon it Jeff Atwood’s excellent Blog

Categories: programs Tags:

Unit Testing Delete Actions in Grails

September 4th, 2009 Flo 6 comments

I’m quite new in Groovy and Grails and wanted to share some of my lessons learned while
writing my first unit tests in Grails.

Fortunately at the time I started unit testing in Grails the Testing Plugin had already moved into Grails core.
The documentation is quite good so it’s a good idea to start there.

Today I had a little problem testing the delete method on a Controller. Let’s say I have a Domain class Song which looks like

//  Song.groovy
class Song {
    String name =""
}

I have a method in my Controller that deletes a Song like the delete action from static scaffolding. After calling the action I want to make sure that my count of Songs has decreased.
My first attempt looked like:

// SongTests.groovy
class SongTests extends GrailsUnitTestCase {

    def testSongs
    Song s1, s2

    protected void setUp() {
        super.setUp()
        s1 = new Song(name: "Song 1")
        s2 = new Song(name: "Song 2")
        testSongs = [s1, s2]
        mockDomain(Song, testSongs)
    }

    void testDelete() {
        int oldSize = testSongs.size()
        s1.delete() // Note: Normally this would happen somewhere in the controller action.
        assertEquals oldSize - 1, testSongs.size()
    }
}

But this test struggles to pass. I did some println’s and looked at the testSongs List and noticed that it did not change. After doing some research I found the cause of my problem in MockUtils.groovy

//  MockUtils.groovy
....
    static GrailsDomainClass mockDomain(Class clazz, Map errorsMap, List testInstances = []) {

        ....
        def rootInstances = testInstances.findAll { clazz.isInstance(it) } // findAll creates a new List!!!
        def childInstances = testInstances.findAll { clazz.isInstance(it) && it.class != clazz }.groupBy { it.class }

        TEST_INSTANCES[clazz] = rootInstances
        addDynamicFinders(clazz, rootInstances)
        addGetMethods(clazz, dc, rootInstances)
        addCountMethods(clazz, dc, rootInstances)
        addListMethod(clazz, rootInstances)
        addValidateMethod(clazz, dc, errorsMap, rootInstances)
        addDynamicInstanceMethods(clazz, rootInstances)
        addOtherStaticMethods(clazz, rootInstances)
...
}

private static void addDynamicInstanceMethods(Class clazz, List testInstances) {
...
        // Add delete() method.
        clazz.metaClass.delete = { Map args = [:] ->
            for (int i in 0..<testInstances.size()) {
                if (testInstances[i] == delegate) {
                    testInstances.remove(i)
                    break;
                }
            }
        }
...
}

The problem was, that findAll creates a new list. Since delete just removes the element from the internal list, the original list keeps passed in as second parameter to the mockFor method stays
untouched.

With this in mind the updated test looked like:

    void testDelete() {
        int oldSize = Song.count()
        s1.delete()
        assertEquals oldSize - 1, Song.count()
    }

Which works perfectly.
If you are just getting started too I would recommend you the following sites which give a good introduction to this topic:

The Definitive Guide to Grails Book from Graeme Rocher and Jeff Brown:
http://www.amazon.de/Definitive-Guide-Grails-Experts-Voice/dp/1590597583

Glen Smith’s Blog – MockFor(March) Series:
http://blogs.bytecode.com.au/glen/2008/03/04/mockfor-march—overcoming-grails-testing-inertia.html
http://blogs.bytecode.com.au/glen/2008/03/07/mockfor-march—unit-testing-grails-taglibs.html
http://blogs.bytecode.com.au/glen/2008/03/12/mockfor-march—unit-testing-grails-controllers.html
http://blogs.bytecode.com.au/glen/2008/03/27/mockfor-march—unit-testing-grails-services.html

Groovy Testing guide:
http://docs.codehaus.org/display/GROOVY/Testing+Guide

Make.Go.Now – Ode to MockFor(March)
http://www.make-go-now.com/2009/03/05/ode-to-mockformarch-part-1-testing-constraints/
http://www.make-go-now.com/2009/04/17/ode-to-mockformarch-part-2-mockdomain/

IBM developerWorks:
Mastering Grails: Testing your Grails application
Mastering Grails Series

Delicous in general and my stream
http://delicious.com/
http://delicious.com/fsalbrechter

If you have any suggestions or found an error I’d be happy if you drop me a line.

Categories: grails, groovy, howto Tags: , , ,