cucumber/cucumber-jvm-scala

Provide out-of-the-box support for mapping Datatables to Scala case classes

gaeljw opened this issue · 2 comments

I believe the Cucumber Scala should provide an easy way to map Datatables to case classes.

case class MyCaseClass(a: Int, b: String)

Given("expression") { (data:Datatable) =>
   val myData = data.asLists(classOf[MyCaseClass])
}

I'm not sure if this should be part of Cucumber Scala by default (if it's possible) or this has to be an optional feature that users can enable by inheriting a trait for instance. I guess it depends on how it's implemented 🤔

This was possible in with version 2.x and as far as I know, for now, it has to be implemented with custom transformers and/or type registry.

Example of implementation in Cucumber Scala 4.7:

trait TypeRegistry extends TypeRegistryConfigurer {

  override def locale(): Locale = Locale.ENGLISH

  override def configureTypeRegistry(typeRegistry: api.TypeRegistry): Unit = {
    val transformer = new DefaultTransformer()
    typeRegistry.setDefaultDataTableEntryTransformer(transformer)
    typeRegistry.setDefaultDataTableCellTransformer(transformer)
    typeRegistry.setDefaultParameterTransformer(transformer)
  }

}

class DefaultTransformer
  extends ParameterByTypeTransformer
    with TableEntryByTypeTransformer
    with TableCellByTypeTransformer {

  var objectMapper: ObjectMapper = new ObjectMapper()
  objectMapper.registerModule(DefaultScalaModule)

  override def transform(s: String, `type`: Type): AnyRef = {
    objectMapper.convertValue(s, objectMapper.constructType(`type`))
  }

  override def transform[T](entry: JMap[String, String], `type`: Class[T], cellTransformer: TableCellByTypeTransformer): T = {
    objectMapper.convertValue(entry, objectMapper.constructType(`type`))
  }

  override def transform[T](value: String, cellType: Class[T]): T = {
    objectMapper.convertValue(value, objectMapper.constructType(cellType))
  }

}

This was possible in with version 2.x and as far as I know, for now, it has to be implemented with custom transformers and/or type registry.

This was done by XStream library which was build into Cucumber. This was not a good long term solution and replaced with the setDefault*Transformer on the type registry. I would not recommend continuing with TypeRegistryConfigurer but rather implementing these like step definitions. For example cucumber-java uses annotations for this.

https://github.com/cucumber/cucumber-jvm/tree/master/java#default-transformers

edit: I see you made #32 to cover that already.

Ok, then this one will be solved by #32 :)