Friday 27 June 2008

Must-have Firefox Plugins for Web Development

Firefox Plugins for Web Development

When developing new code (or updating existing code), I use a very small number of extensions for Firefox.


  • Joe Hewitt's Firebug plugin
    - You can debug and inline Javascript, inspect and edit the DOM elements on the page and update CSS rules on-the-fly. This is probably the number one tool for me.

    Visit his site and from there install Firebug

  • Chris Pederick's Web Developer toolbar
    - Adds the ability to disable Javascript, CSS and view all kinds of DOM structure information. Built-in validation tools allow for markup validation against the W3C validators.

    Download the plugin for Firefox

  • Alex Sirota's ColorZilla plugin (http://www.iosart.com/firefox/colorzilla/)
    - Allows you to inspect the colour of elements on the page. This is useful for choosing colours for CSS rules (and when an image editor is not readily available to do the job).

    Download the ColorZilla 1.9 for Firefox

Of course there are others that I use as well (Selenium IDE, YSlow and TamperData are definitely worth a mention), but these represent the core.

Whilst this addresses Firefox, there are plenty of tools available for other browsers - look for a post covering some of those for Internet Explorer and Safari.

Wednesday 25 June 2008

Practical Front End Coding Resources

Here are some useful blogs, articles, books and forums that I think are representative of the sites that I use for front-end problems, solutions and inspiration. I hope you get some mileage from them!


CSS/HTML

Javascript/AJAX

SEO

Monday 23 June 2008

The Quartz Plugin

The docs for the quartz plugin are more than adequate for installation and usage, but they don't give you any help how to test. The first step is to make sure quartz is stopped on your test machines, otherwise jobs will fire at random during a test run and breaking things.

You do this by editing QuartzConfig.groovy and setting autoStartup=false for your test / dev environments.

Next I added a quartz action to our FixtureController. The job name is simply the class name.

class FixtureController {
def quartzScheduler

def quartz = {
if (params.triggerJob) {
quartzScheduler.start()
quartzScheduler.triggerJob(params.triggerJob, 'GRAILS_JOBS')
} else if (params.standby) {
quartzScheduler.standby()
}
render("<pre>${quartzScheduler.metaData}</pre>")
}
}


You can now trigger your job by hitting http://server:port/fixture/quartz?triggerJob=MyJob

The quartz jobs are (obviously) asynchronous, so your test harness will need some way of checking when they've started, and when they are finished. In the past we used a status page with a meta-refresh, that rendered the word 'continue' when some condition had been met. Once you know the job has started, set quartz back into standby in order to minimise the risk of other jobs kicking off half way through your tests.

Stemming and the Grails Searchable Plugin

The standard analyizer that compass defaults to doesn't support stemming. The closest you can get is to use wild card searches. If you want to go the whole hog, here's what you have to do...

1. Open /grails-app/conf/SearchableConfiguration.groovy and replace

Map compassSettings = [:]

with

Map compassSettings = ['compass.engine.analyzer.default.type': 'snowball',
'compass.engine.analyzer.default.name': 'English',
'compass.engine.analyzer.search.type': 'snowball',
'compass.engine.analyzer.search.name': 'English']


2. Use queryString(<luceneQuery>, <params>) in your search service rather than the 'term' or 'wildcard' commands. e.g.

queryString("name:${match}", [boost: 10])

You're supposed to be able to specify the analyzer to use as a parameter to queryString, but I haven't tried this yet, as for my app I only need to support English.

3. Don't even bother trying to get stemming working if you use term, the plugin simply ignores any analyzer settings and constructs the StandardAnalyser from a hard coded class name. I raised a feature request for this, but it was bounced because Maurice thinks we should be forced to write lucene queries by hand. Never mind that the point of whole point of compass was to isolate your from the underlying search engine technology, or that DSLs are a much nicer mechanism for query creation than string manipulation. Ho Hum.

Pessimistic Locking in Grails

I blogged about this a few weeks ago, then decided I really ought to create a few test cases to back up what I was spouting and raise a JIRA. Finally done. Here it is.

GRAILS-3156

Good news is the grails guys have scheduled a fix for v1.0.4

For anyone with an aversion to clicking links the long and short of it is that you can't pessimistically lock anything with the grails API. Instead you have to fall back to using hibernate and even then the only reliable way seems to be to clear the session and perform either a session.get(DomainObj.class, id, LockMode.UPGRADE) or session.load(DomainObj.class, id, LockMode.UPGRADE).

If you're not keen on clearing the entire session, you could try evicting the object you're about to lock instead, but this can cause other problems. Failing that you could write some db dependent SQL like 'LOCK <table> IN ACCESS EXCLUSIVE MODE'. Just make sure you check the db docs and pick the least restrictive lock that will do the job.

Friday 20 June 2008

Refactoring GANT

Its quite easy to build complicated GANT scripts - and not much has been written about how to refactor them.

Its not so obvious that you can call other targets directly, and with a bit of care you can re-use some of the built in grails targets like testApp.

The first step is to include anohter script like this:

includeTargets << new File("${basedir}/scripts/OtherScript.groovy")

Note: this does have implications in that you can overwrite variables and targets by including (and it does this silently without warning).

You can then reference another target from your target like this:

target(runMigration: "Run the Migration Tests") {
testMigration()
testApp()
}

There are some caveats however - one being that the useful "testApp" target (provided by grails) has a built in System.exit which causes your entire script to fail. You can get around this by hooking the exit event and storing the error code instead of exiting like this:

target('exit':"override exit") { code ->
// Save the exit code.
testAppExitCode = code
}


While all this does help - there is still a slight "whiff" to gant programming, however some of these tricks can help keep your gant scripts tidier.

Tim

Wednesday 18 June 2008

String, GString type and equality

This might be very schoolboy blog for some of you - I still hope that it might be useful to avoid some bugs.

Some weeks back my pair and I were fixing a bug that finally boiled down to the fact that the contains() method on a List returned false if the list contained the GString counterpart of the same literal.

Having played a bit I learned a couple of things about GStrings. Please find some bullet points and the code snippet bellow.

Type:
1. def var1 = "this is a String instead of a GString even if it is surrounded by double quotes - can has no dollar sign"
2. def var2 = "this is a GString because it contains a dollar sign - $var1"
3. String var3 = "this is a string because it was defined as a String"
4. String var4 = "$var3 - this is still a string because it was defined as a String"

Equality
1. a String and a GString can be ==
2. a String and a GString are NEVER equals()
3. as a consequence a list containing a literal will not return true if the type (GString/String) does not match


class WhereIsYourDummyTests extends GroovyTestCase {
def e = "y"
def dummy = "dumm$e"

void assertTypeIsStringForAFixGString() {
assert e instanceof java.lang.String
assert dummy instanceof groovy.lang.GString
}

void testEqualsNotEquals() {
assert "dummy" == dummy
assert dummy == "dummy"

// WATCH OUT HERE
assertFalse("dummy".equals(dummy))
assertFalse(dummy.equals("dummy"))
}

void testContainsDoesntContain() {
assert ['dummy'].contains("dummy")
assert ["dummy"].contains('dummy')
assert [dummy].contains(dummy)

// THIS IS TRICKY:
assert ![dummy].contains("dummy")
assert ![dummy].contains('dummy')
assert !["dummy"].contains(dummy)
assert !['dummy'].contains(dummy)

assert [dummy.toString()].contains("dummy")
assert [dummy.toString()].contains('dummy')
}

void testContainsIfVariablesAreStringInsteadOfDef() {
String e = "y" // String instead of def
String dummy = "dumm$e" // String instead of def

assert ['dummy'].contains("dummy")
assert ["dummy"].contains('dummy')
assert [dummy].contains(dummy)

assert [dummy].contains("dummy")
assert [dummy].contains('dummy')
assert ["dummy"].contains(dummy)
assert ['dummy'].contains(dummy)

assert [dummy.toString()].contains("dummy")
assert [dummy.toString()].contains('dummy')
}
}

Tuesday 17 June 2008

Tuesday 10 June 2008

Groovy & Grails Tutorials

Found this link on groovy and grails tutorials. Might be useful to have a look every once in a while:
http://www.grailstutorials.com