Skip to content

Instantly share code, notes, and snippets.

@bherrmann7
Created October 12, 2009 18:21
Show Gist options
  • Save bherrmann7/208598 to your computer and use it in GitHub Desktop.
Save bherrmann7/208598 to your computer and use it in GitHub Desktop.
how to record some of what a closure does when it runs
// CriteriaRecorder - this gist lets you wrap a closure so you can record and manipulate the list of things the closure attempts to invoke.. Good for unit testing closures which build up GORM requests
class Node {
String name
def args
String render(StringBuilder sb, int level){
sb.append ' '.multiply(level*4)
sb.append name+'('+args.join(',')+')\n'
}
}
class Branch extends Node {
List<Node> nodes = []
String render(StringBuilder sb, int level){
sb.append ' '.multiply(level*4)
if(name)
sb.append name+' '
sb.append '{\n'
// should dump args +args+'\n'
nodes.each { node ->
node.render(sb,level+1)
}
sb.append ' '.multiply(level*4)+'}\n'
}
}
class CriteriaRecorder {
Branch root = new Branch(name:'')
List<Branch> stack = [ root ]
CriteriaRecorder(Closure cl){
cl.delegate = this
cl()
}
void methodMissing(String name, args) {
if(args && args[-1] instanceof Closure ){
Branch branch = new Branch(name:name,args: args.size()==1? null:args[0..-2])
stack[-1].nodes.add branch
stack.push branch
def clz = args[-1]
//clz.delegate = this
clz()
stack.pop()
} else {
stack[-1].nodes.add new Node(name:name, args:args)
}
}
String toString(){
StringBuilder sb = new StringBuilder()
root.render(sb,0)
sb.toString()
}
}
def clx = {
max(7)
spoon {
fork(99)
}
}
def cr = new CriteriaRecorder(clx)
assert cr.toString(), '''{
max(7)
spoon {
fork(99)
}
}
'''
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment