Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
gaeljw opened this issue Apr 26, 2020 · 2 comments · Fixed by #37
Closed

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

gaeljw opened this issue Apr 26, 2020 · 2 comments · Fixed by #37
Labels
⚡ enhancement Request for new functionality
Milestone

Comments

@gaeljw
Copy link
Member

gaeljw commented Apr 26, 2020

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))
  }

}
@gaeljw gaeljw added the ⚡ enhancement Request for new functionality label Apr 26, 2020
@mpkorstanje
Copy link
Contributor

mpkorstanje commented Apr 26, 2020

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.

@gaeljw
Copy link
Member Author

gaeljw commented Apr 27, 2020

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
⚡ enhancement Request for new functionality
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants