Tellurium Tutorial Series: Groovy Closures

3 views
Skip to first unread message

John.Ji...@gmail.com

unread,
Jan 15, 2009, 12:33:56 PM1/15/09
to tellurium-users
What is a Closure? A Groovy closure is like a "code block" or a method
pointer. It is a piece of code that is defined and then executed at a
later point. The main feature of Closures is that it "bound" to
variables within the scope where they are defined. For more details,
please see

http://groovy.codehaus.org/Closures

Tellurium uses Groovy Closure pretty heavily. For example, in the
DslContext class, you may see methods similar to the following click
method,


def click(String uid){
WorkflowContext context = WorkflowContext.getDefaultContext()
ui.walkTo(context, uid)?.click(){ loc, String[] events ->
String locator = locatorMapping(context, loc)
eventHandler.click(locator, events)
}
}

and in the Button object, you have the method

def click(Closure c) {

c(locator, respondToEvents)
}

You may got confused at the first sight. Let us elaborate more on it.

First we can clearly define the closure as

Closure c = { loc, String[] events ->
String locator = locatorMapping(context, loc)
eventHandler.click(locator, events)
}

Note, the block of code "c" will carry the variables "context",
eventHandler, and method locatorMapping in DslContext class to other
classes where the closure is executed, for example, the Button class.
Also, be aware that the Closure "c" needs input parameters "loc" and
"events", which should be provided by the class that executes the
Closure.

With that, we can write the method more clearly as

def click(String uid){
WorkflowContext context = WorkflowContext.getDefaultContext()

Closure c = { loc, String[] events ->
String locator = locatorMapping(context, loc)
eventHandler.click(locator, events)
}

UiObject object = ui.walkTo(context, uid)
if(object != null)
object.click(c)
}

Here assume the object is Button, then the click method in Button is
called, which is equals to

def click(Closure c) {
loc = this.locator
String[] events = this.respondToEvents
String locator = locatorMapping(context, loc)
eventHandler.click(locator, events)
}

As you see, the actual call flow is as follows,

call click(uid) in DslContext
|
find the Button object by calling the "walkTo" method
|
call click(Closure c) in Button
|
call locatorMapping() method in DslContext to get runtime
locator
|
call click(locator, events) in eventHandler

You may be surprised to see that the Closure c in the Button object
can
access variables and methods defined in DslContext class, i.e, where
the Closure c
is defined. That is a feature of Closure.

The benefit of this is that we have a center place DslContext to deal
with locator processing and
event handling. Otherwise, you have to scatter the same things in each
Ui object,
which is really not elegant.

Hope this can help you understand the framework better.

Thanks,

Jian
Reply all
Reply to author
Forward
0 new messages