Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // summary : Json4s scala json API cookbook as unit test cases.
- // keywords : scalatest, json4s, json
- // publish : gist, snippet
- // authors : david
- // id : b2de4720-2d03-44bf-92cf-1c4f67ac1864
- import $ivy.`org.json4s::json4s-native:3.6.5`
- import $ivy.`org.json4s::json4s-jackson:3.6.5`
- import $ivy.`org.json4s::json4s-ext:3.6.5`
- import $ivy.`org.scalatest::scalatest:3.0.5`
- import org.scalatest._
- import org.scalatest.Matchers._
- import java.time.{OffsetDateTime, ZonedDateTime}
- case class Someone(name:String, age:Int)
- case class Event(when:OffsetDateTime, who:Someone, what:String)
- object JsonJson4sCookBook extends FlatSpec {
- override def suiteName = "JsonJson4sCookBook"
- "json4s" should "parse json strings" in {
- import org.json4s.native.JsonMethods.{parse}
- implicit val formats = org.json4s.DefaultFormats
- val json = """{"name":"John Doe", "age":42}"""
- val doc = parse(json)
- (doc \\ "name").extract[String] should equal("John Doe")
- }
- it should "pretty render json" in {
- import org.json4s.native.JsonMethods.{parse,pretty,render}
- implicit val formats = org.json4s.DefaultFormats
- val jvalue = parse("""{"name":"John Doe", "age":42}""")
- val result: String = pretty(render(jvalue))
- result.split("\n") should have size(4)
- }
- it should "serialize case classes to json" in {
- import org.json4s.native.Serialization.{read, write}
- implicit val formats = org.json4s.DefaultFormats
- val someone = Someone(name="John Doe", age=42)
- val json: String = write(someone)
- read[Someone](json) should equal(someone)
- }
- it should "manage java8 time" in {
- import org.json4s.native.Serialization.{read, write}
- import org.json4s.DefaultFormats
- import org.json4s.ext.JavaTimeSerializers
- implicit val formats = DefaultFormats ++ JavaTimeSerializers.all // Warning : by default it doesn't manage milliseconds ! See next test, and lossless method
- val when = OffsetDateTime.parse("2042-01-01T01:42:42Z")
- val event = Event(when, Someone("John Doe", 42), "future birth")
- val json:String = write(event)
- val eventBack = read[Event](json)
- eventBack should equal(event)
- }
- it should "extract ZonedDateTime/OffsetDatetime with milliseconds" in {
- import org.json4s.native.JsonMethods.{parse,render,compact}
- import org.json4s.DefaultFormats
- import org.json4s.ext.JavaTimeSerializers
- implicit val formats = DefaultFormats.lossless ++ JavaTimeSerializers.all // USE .lossless for milliseconds to ba taken into account !
- val timestamp = "2042-01-01T01:42:42.042Z"
- val json = s"""{"when":"$timestamp"}"""
- val jvalue = parse(json)
- (jvalue \ "when").extract[ZonedDateTime] // Human readable date time, do not use for equals, comparison...
- (jvalue \ "when").extract[OffsetDateTime] should equal(OffsetDateTime.parse(timestamp))
- compact(render(jvalue)) should equal(json)
- }
- it should "have a way to detect empty object" in {
- import org.json4s.native.JsonMethods.{parse,render,compact,pretty}
- import org.json4s._
- implicit val formats = DefaultFormats
- implicit val serialization = native.Serialization
- val json = """{"emptyObject":{}, "value":4242, "notEmptyObject":{"that":42} } """
- val jvalue = parse(json)
- val notFound1 = (jvalue \ "somethingNotHere")
- notFound1 should be(JNothing)
- val notFound2 = (jvalue \\ "somethingNotHere")
- notFound2 should be(JObject())
- val emptyObject = (jvalue \ "emptyObject").extract[JObject]
- emptyObject.values.isEmpty should be(true)
- emptyObject.children.isEmpty should be(true)
- emptyObject.children.size should be(0)
- val notEmptyObject = (jvalue \ "notEmptyObject").extract[JObject]
- notEmptyObject.values.isEmpty should be(false)
- notEmptyObject.children.isEmpty should be(false)
- notEmptyObject.children.size should be >(0)
- val aValue = (jvalue \ "value")
- aValue should not be(JNothing)
- aValue should not be(JObject())
- aValue.extractOpt[Int] should be(Some(4242))
- }
- it should "be possible to work with POJO objects" in {
- import org.json4s.native.JsonMethods.{parse,render,compact,pretty}
- import org.json4s.native.Serialization
- import org.json4s.native.Serialization.{read, write}
- import org.json4s.JsonDSL._
- import org.json4s._
- import java.awt.Point
- implicit val formats = DefaultFormats + FieldSerializer[Point]()
- implicit val serialization = Serialization
- val reference = ("x"-> 24) ~ ("y"->42)
- val point = new Point(24, 42)
- val jsonString = write(point)
- val json = parse(jsonString)
- json should equal(reference)
- // Alternative way
- Extraction.decompose(point) should equal(reference)
- }
- it should "be possible to work with POJO objects even when the class is unknown" in {
- import org.json4s.jackson.JsonMethods.{parse,render,compact,pretty}
- import org.json4s.jackson.Serialization
- import org.json4s.jackson.Serialization.{read, write}
- import org.json4s.JsonDSL._
- import org.json4s._
- val reference = ("x"-> 24) ~ ("y"->42)
- //val clazz = Class.forName("java.awt.Point")
- //val cons = clazz.getConstructor(classOf[Int], classOf[Int])
- //val point = cons.newInstance(new java.lang.Integer(24), new java.lang.Integer(42)).asInstanceOf[Object]
- val point = new java.awt.Point(24, 42)
- //val customSerializer = classOf[FieldSerializer].newInstance()
- implicit val formats = DefaultFormats //+ customSerializer //FieldSerializer[java.awt.Point]()
- implicit val serialization = Serialization
- Extraction.decompose(point) should equal(reference)
- // TODO - current status : decompose doesn't introspect dynamically allocated java types
- }
- it should "map a ScalaMap to a json object" in {
- import org.json4s._
- import org.json4s.native.JsonMethods.{render,compact,pretty}
- val now = new java.util.Date()
- val nowIso8601 = now.toInstant.toString // ~ 2018-09-25T12:59:21.315Z
- val input = Map("age"->42, "name"->"John Doe", "now"->now)
- implicit val formats = DefaultFormats.lossless // for milliseconds in iso8601 dates...
- val jvalue = Extraction.decompose(input)
- val json = pretty(render(jvalue))
- info(json)
- compact(render(jvalue)) shouldBe s"""{"age":42,"name":"John Doe","now":"${nowIso8601}"}"""
- }
- it should "be possible to extract a Map from a json object" in {
- import org.json4s._
- import org.json4s.native.JsonMethods.{render,compact,pretty}
- implicit val formats = DefaultFormats.lossless // for milliseconds in iso8601 dates...
- val someone = Someone("john", 42)
- val jvalue = Extraction.decompose(someone)
- val jmap = jvalue.extract[Map[String,Any]]
- jmap shouldBe Map("name"->"john", "age"->42)
- }
- }
- JsonJson4sCookBook.execute()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement