Generating random/sample json based on a schema in Scala

342 Views Asked by At

I need to generate some radom json sample, compliant to a schema dynamically. Meaning that the input would be a schema (e.g. json-schema) and the output would a json that complies to it.

I'm looking for pointers. Any suggestions ?

1

There are 1 best solutions below

0
talex On

This is not complete solution, but you can get it from here.

Let's assume we have our domain objects we want to generate:

case class Dummy1(foo: String)
case class Dummy11(foo: Dummy1)

If we do this:


object O {
  implicit def stringR: Random[String] = new Random[String] {
    override def generate(): String = "s"
  }

  implicit def intR: Random[Int] = new Random[Int] {
    override def generate(): Int = 1
  }

  implicit def tupleR[T1: Random, T2: Random]: Random[(T1, T2)] = new Random[(T1, T2)] {
    override def generate(): (T1, T2) = {
      val t1: T1 = G.random[T1]()
      val t2: T2 = G.random[T2]()
      (t1, t2)
    }
  }
}

object G {
  def random[R: Random](): R = {
    implicitly[Random[R]].generate()
  }
}

then we will be able to generate some primitive values:

  import O._

  val s: String = G.random[String]()
  val i: Int = G.random[Int]()
  val t: (Int, String) = G.random[(Int, String)]()

  println("s=" + s)
  println("i=" + i)
  println("t=" + t)

Now to jump to custom type we need to add

  def randomX[R: Random, T](f: R=>T): Random[T] = {
    val value: Random[R] = implicitly[Random[R]]
    new Random[T] {
      override def generate(): T = f.apply(value.generate())
    }
  }

to our G object.

Now we can

  import O._
  val d1: Dummy1 = G.randomX(Dummy1.apply).generate()
  println("d1=" + d1)

and with some extra effort even

  import O._
  implicit val d1Gen: Random[Dummy1] = G.randomX(Dummy1.apply)
  val d11: Dummy11 = G.randomX(Dummy11.apply).generate()
  println("d11=" + d11)

Now you need to extend it to all primitive you have, add real implementation of random and support classes with more then 1 field and you ready to go.

You may even make some fancy library out of it.