siriusxm/snapshot4s

Feature Request: Custom inline types support

Closed this issue · 3 comments

It would be nice to provide a mechanism for adding custom types to the inline snapshot tester.

I was able to hack one in myself, but I reckon cleaner hooks into pprint could be managed.

See here,

import java.util.UUID

case class HelloWorld(name: String, uuid: UUID)

object HelloWorld {
  def test():HelloWorld = HelloWorld("caoilte", UUID.fromString("b8d4b9b6-faaa-4446-bcd9-abd902c5174b"))
}

  val pprinter = pprint.copy(
    additionalHandlers = {
      case u:UUID => pprint.Tree.Literal(s"""UUID.fromString("${u.toString}")""")
    }
  )
  implicit val reprForHelloWorld: Repr[HelloWorld] = (h:HelloWorld) => pprinter.apply(h).plainText

  test("say hello") {
    assertInlineSnapshot(HelloWorld.test(), ???)
  }

or here for a full project (not sure scastie is up to this - but would be cool if it was)
https://github.com/caoilte/snapshot4s-playground/blob/main/src/test/scala/example/HelloSpec.scala

Might be limited demand until a mechanism for managing auto-generation of imports is decided upon, but thought I'd create the issue in case this hack was interesting to others.

Thank you for bringing this up @caoilte!

I think that's a really useful workaround for custom types. The least we can do is to document the Repr typeclass. Just to be clear, the underlying implementation doesn't have to rely on pprint.

We are still considering our long-term options for the default implementation of Repr and how it should work. For now pprint works fine, but we have noticed some quirks when the datatype has a custom toString implementation. So I think we'll hold off on tightening the bind to pprint for now.

Good points! Totally agree. Really looking forward to watching the project develop. It's already one of my favourites!

Great to hear that! We have extended the docs in #36, there's a new page https://siriusxm.github.io/snapshot4s/custom-types-support about implementing Repr for custom types. Hopefully this should be enough for now 😉