如何为数据集描述创建spock风格的DSL?

Rom*_*man 4 java groovy spock

我想在spock数据驱动的规范格式中有一个数据集描述:

'Key'   |    'Value'    |    'Comments'
1       |    'foo'      |    'something'
2       |    'bar'      |    'something else'
Run Code Online (Sandbox Code Playgroud)

这必须转换为像2D数组(或任何可能实现的).

有任何想法如何实现这种数据描述?

ps最大的问题是换行检测,其余的可以通过or在Object上重载来实现metaClass.

epi*_*ian 5

|操作是左结合的,所以在这个表中的一行将被解析,如:

('Key' | 'Value') | 'Comments'
Run Code Online (Sandbox Code Playgroud)

然后你可以做什么来检测每一行的开始和结束位置是让|opeator返回一个包含其操作数的列表,然后为每个人|询问左操作数(即this)是否是一个列表.如果是,则意味着它是一行的延续; 如果它不是列表,则意味着它是一个新行.

以下是使用类别解析这些数据集的DSL的完整示例,以避免覆盖Object元类的内容:

@Category(Object)
class DatasetCategory {
    // A static property for holding the results of the DSL.
    static results

    def or(other) {
        if (this instanceof List) {
            // Already in a row. Add the value to the row.
            return this << other
        } else {
            // A new row.
            def row = [this, other]
            results << row
            return row
        }
    }
}

// This is the method that receives a closure with the DSL and returns the 
// parsed result.
def dataset(Closure cl) {
    // Initialize results and execute closure using the DatasetCategory.
    DatasetCategory.results = []
    use (DatasetCategory) { cl() }

    // Convert the 2D results array into a list of objects:
    def table = DatasetCategory.results
    def header = table.head()
    def rows = table.tail()
    rows.collect { row -> 
        [header, row].transpose().collectEntries { it } 
    }
}

// Example usage.
def data = dataset {
    'Key'   |    'Value'    |    'Comments'
    1       |    'foo'      |    'something'
    2       |    'bar'      |    'something else'
}

// Correcness test :)
assert data == [
    [Key: 1, Value: 'foo', Comments: 'something'],
    [Key: 2, Value: 'bar', Comments: 'something else']
]
Run Code Online (Sandbox Code Playgroud)

在这个例子中,我将表解析为一个映射列表,但是在DSL闭包运行之后,您应该可以使用DatasetCategory的结果执行任何操作.