BuilderSupport

我对抽象类BuildSupport很好奇:怎么可以做这么多神奇的事情呢?比如SwingBuilder和AntBuilder。

因此我写了如下一个Groovy测试来刨析一下其行为:

package groovy.util
 
class SpoofBuilder extends BuilderSupport{
    def log = []
    protected void setParent(Object parent, Object child){
        log << "sp"
        log << parent
        log << child
    }
    protected Object createNode(Object name){
        log << 'cn1'
        log <<  name
        return 'x'
    }
    protected Object createNode(Object name, Object value){
        log << 'cn2'
        log << name
        log << value
        return 'x'
    }
    protected Object createNode(Object name, Map attributes){
        log << 'cn3'
        log << name
        attributes.each{entry -> log << entry.key; log << entry.value}
        return 'x'
    }
    protected Object createNode(Object name, Map attributes, Object value){
        log << 'cn4'
        log << name
        attributes.each{entry -> log << entry.key; log << entry.value}
        log << value
        return 'x'
    }
    protected void nodeCompleted(Object parent, Object node) {
        log << 'nc'
        log << parent
        log << node
    }
}
 
// simple node
def b = new SpoofBuilder()
assert b.log == []
def node = b.foo()
assert b.log == ['cn1','foo','nc',null, node]
 
// simple node with value
def b = new SpoofBuilder()
def node = b.foo('value')
assert b.log == ['cn2','foo','value', 'nc',null,node]
 
// simple node with one attribute
def b = new SpoofBuilder()
def node = b.foo(name:'value')
assert b.log == [
    'cn3','foo', 'name','value', 'nc',null,'x']
 
// how is closure applied?
def b = new SpoofBuilder()
b.foo(){
    b.bar()
}
assert b.log == [
    'cn1','foo',
        'cn1','bar',
    'sp', 'x', 'x',
        'nc','x','x',
    'nc',null,'x']

SpoofBuilder只是一个简单的BuilderSupport实例,除了记录被调用的日志和每个节点(node)返回'x'以为,什么事情都没有做。

测试的部分采用不同方式来调用SpoofBuilder,其日志揭示了在”Build”过程中那些方法被调用。 此测试同时也验证了我假想的builder模式的工作方式,在此基础上,我又写了一个用于Canoo WebTest的AntBuilder。

. “MacroStepBuilder”允许在Groovy代码中使用Canoo WebTest “steps” (为了测试遍历一个webapp),因此Groovy现在已经是Canoo WebTest 社区的一等公民了。

在编写以上的测试过程中,我也磕磕碰碰了一些事情,这是其中的两点:

  • 我不能写一个完全成熟的具体单独方法的GroovyTestCase子类,以方便各种不同的测试。我还不知道如何在我的TestCase中将SpoofBuilder作为一个内部类,在这点上,我非常感谢有人能帮助我。
  • 我希望象Ruby那样,Strings的<<操作符操作的是String本身(就象列表所做的),而不是一个拷贝(copy)(译者:其实StringBuilder应该是作者所期望的)。在我看来Strings的<<操作符跟Lists是不一致的,等同于”+“操作符。

而我很欣赏的两点是:

  • 列表中的==操作符是非常清晰和简洁
  • 当断言失败时,显示计算过的表达式(evaluated expression),这可以让你在写断言的时候,节省很多的工作。大多数的情况下,你不需要额外的信息。
 
wiki/advanced_usage_guide/buildersupport.txt · 最后更改: 2008-06-22 20:06 由 agile.guo
 
Recent changes RSS feed Creative Commons License Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki