A blog about software development and other software related matters

Blog Archive

Monday, October 8, 2007

Catch the bug

Well iv just spent an hour or so on this cute little bug and thought to challenge you readers to catch it by yourself (using any debuggers IDE's etc.. isn't allowed!)
The code is in the Groovy programming language and involves two closures as follows:

def validate(assets){
def asset = assets.find() {a ->
[a.floor, a.houseNr, a.street, a.zipCode].find {val -> StringUtils.isEmpty(val)} !=null
asset == null ? 'all addresses are ok' : 'one address is partial'

This little method finds an asset within an asset list that has at least one empty address value (emptiness is asserted by org.apache.commons StringUtils).

The method makes use of two nested find methods (both accept two boolean closures) with this simple logic:
We are trying to find any asset (the wrapping find call) that has at least one empty address value (the inner find), simple enough right?

Well lets Write some tests:

def asset= new Asset()
asset.zipCode ='1234'
assetEquals('all addresses are ok',validate([asset]))// passes
assetEquals('one address is partial',validate([asset]))// passes
assetEquals('one address is partial',validate([asset]))// bug strikes here!

Well that one last test is weird, the first initial instinct of mine was to check that isEmpty handles null as empty (ill give you a hint, it does).
Feel free to tackle it now, its not that complicated (or is it?) the following paragraph will contain the solution so stop reading now! (thats if you don't want to cheat).

The solution:
Ok lets follow along that last test:

  • The validate method input includes an asset that has a nullified floor, the first find is called.

  • The first find calls its inner find method call.

  • Now here is the tricky part, the inner find manages to scan only the first array value (floor) and returns its value (which is null!), the !=null assertion returns false to its wrapping find,now since there are no more elements in the assets list the outer find returns the faulty null.

Thats it another bug squashed!

No comments: