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

标签 java groovy spock

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

'Key'   |    'Value'    |    'Comments'
1       |    'foo'      |    'something'
2       |    'bar'      |    'something else'

这必须转换为二维数组之类的东西(或任何可能实现的东西)。

有什么想法可以实现这个数据描述吗?

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

最佳答案

| 运算符是左关联的,因此该表中的一行将被解析为:

('Key' | 'Value') | 'Comments'

为了检测每一行的开始和结束位置,您可以做的是让 | 运算符返回一个包含其操作数的列表,然后针对每个 | 询问左边是否- 手操作数(即 this)是一个列表。如果是,则意味着它是一行的延续;如果它不是列表,则意味着它是一个新行。

这是使用 Category 解析这些数据集的 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']
]

在此示例中,我将表解析为 map 列表,但在 DSL 闭包运行后,您应该能够对 DatasetCategory 的结果执行任何您想做的事情。

关于java - 如何为数据集描述创建 spock 风格的 DSL?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13962536/

相关文章:

EJB 离线时的 JavaEE 通知

groovy - 在 Groovy 中使用闭包实现接口(interface) - 调用了什么方法?

java - 无法解析符号 'R' ,&无法解析 menu_main xml 中的符号

java - 有没有办法检查下一个标记是否是 END?

java - 加载父级时急切地获取子级

groovy - 如何在 groovy 中做方法别名?

grails - 为什么这种通用用法在 groovy 中不起作用?

spring - 在 Grails 中将 Activiti 连接为 Spring Bean

java - 如何使用私有(private)属性(property)创建 Spock Spy