Advertisement
Guest User

Untitled

a guest
Jun 15th, 2019
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.62 KB | None | 0 0
  1. // summary : Json4s scala json API cookbook as unit test cases.
  2. // keywords : scalatest, json4s, json
  3. // publish : gist, snippet
  4. // authors : david
  5. // id : b2de4720-2d03-44bf-92cf-1c4f67ac1864
  6.  
  7.  
  8. import $ivy.`org.json4s::json4s-native:3.6.5`
  9. import $ivy.`org.json4s::json4s-jackson:3.6.5`
  10. import $ivy.`org.json4s::json4s-ext:3.6.5`
  11. import $ivy.`org.scalatest::scalatest:3.0.5`
  12. import org.scalatest._
  13. import org.scalatest.Matchers._
  14.  
  15. import java.time.{OffsetDateTime, ZonedDateTime}
  16.  
  17. case class Someone(name:String, age:Int)
  18. case class Event(when:OffsetDateTime, who:Someone, what:String)
  19.  
  20. object JsonJson4sCookBook extends FlatSpec {
  21. override def suiteName = "JsonJson4sCookBook"
  22.  
  23. "json4s" should "parse json strings" in {
  24. import org.json4s.native.JsonMethods.{parse}
  25. implicit val formats = org.json4s.DefaultFormats
  26. val json = """{"name":"John Doe", "age":42}"""
  27. val doc = parse(json)
  28. (doc \\ "name").extract[String] should equal("John Doe")
  29. }
  30.  
  31. it should "pretty render json" in {
  32. import org.json4s.native.JsonMethods.{parse,pretty,render}
  33. implicit val formats = org.json4s.DefaultFormats
  34. val jvalue = parse("""{"name":"John Doe", "age":42}""")
  35. val result: String = pretty(render(jvalue))
  36. result.split("\n") should have size(4)
  37. }
  38.  
  39. it should "serialize case classes to json" in {
  40. import org.json4s.native.Serialization.{read, write}
  41. implicit val formats = org.json4s.DefaultFormats
  42. val someone = Someone(name="John Doe", age=42)
  43. val json: String = write(someone)
  44. read[Someone](json) should equal(someone)
  45. }
  46.  
  47. it should "manage java8 time" in {
  48. import org.json4s.native.Serialization.{read, write}
  49. import org.json4s.DefaultFormats
  50. import org.json4s.ext.JavaTimeSerializers
  51. implicit val formats = DefaultFormats ++ JavaTimeSerializers.all // Warning : by default it doesn't manage milliseconds ! See next test, and lossless method
  52. val when = OffsetDateTime.parse("2042-01-01T01:42:42Z")
  53. val event = Event(when, Someone("John Doe", 42), "future birth")
  54. val json:String = write(event)
  55. val eventBack = read[Event](json)
  56. eventBack should equal(event)
  57. }
  58.  
  59. it should "extract ZonedDateTime/OffsetDatetime with milliseconds" in {
  60. import org.json4s.native.JsonMethods.{parse,render,compact}
  61. import org.json4s.DefaultFormats
  62. import org.json4s.ext.JavaTimeSerializers
  63. implicit val formats = DefaultFormats.lossless ++ JavaTimeSerializers.all // USE .lossless for milliseconds to ba taken into account !
  64. val timestamp = "2042-01-01T01:42:42.042Z"
  65. val json = s"""{"when":"$timestamp"}"""
  66. val jvalue = parse(json)
  67. (jvalue \ "when").extract[ZonedDateTime] // Human readable date time, do not use for equals, comparison...
  68. (jvalue \ "when").extract[OffsetDateTime] should equal(OffsetDateTime.parse(timestamp))
  69. compact(render(jvalue)) should equal(json)
  70. }
  71.  
  72. it should "have a way to detect empty object" in {
  73. import org.json4s.native.JsonMethods.{parse,render,compact,pretty}
  74. import org.json4s._
  75.  
  76. implicit val formats = DefaultFormats
  77. implicit val serialization = native.Serialization
  78.  
  79. val json = """{"emptyObject":{}, "value":4242, "notEmptyObject":{"that":42} } """
  80. val jvalue = parse(json)
  81.  
  82. val notFound1 = (jvalue \ "somethingNotHere")
  83. notFound1 should be(JNothing)
  84.  
  85. val notFound2 = (jvalue \\ "somethingNotHere")
  86. notFound2 should be(JObject())
  87.  
  88. val emptyObject = (jvalue \ "emptyObject").extract[JObject]
  89. emptyObject.values.isEmpty should be(true)
  90. emptyObject.children.isEmpty should be(true)
  91. emptyObject.children.size should be(0)
  92.  
  93. val notEmptyObject = (jvalue \ "notEmptyObject").extract[JObject]
  94. notEmptyObject.values.isEmpty should be(false)
  95. notEmptyObject.children.isEmpty should be(false)
  96. notEmptyObject.children.size should be >(0)
  97.  
  98. val aValue = (jvalue \ "value")
  99. aValue should not be(JNothing)
  100. aValue should not be(JObject())
  101. aValue.extractOpt[Int] should be(Some(4242))
  102. }
  103.  
  104. it should "be possible to work with POJO objects" in {
  105. import org.json4s.native.JsonMethods.{parse,render,compact,pretty}
  106. import org.json4s.native.Serialization
  107. import org.json4s.native.Serialization.{read, write}
  108. import org.json4s.JsonDSL._
  109. import org.json4s._
  110. import java.awt.Point
  111.  
  112. implicit val formats = DefaultFormats + FieldSerializer[Point]()
  113. implicit val serialization = Serialization
  114.  
  115. val reference = ("x"-> 24) ~ ("y"->42)
  116.  
  117. val point = new Point(24, 42)
  118.  
  119. val jsonString = write(point)
  120. val json = parse(jsonString)
  121. json should equal(reference)
  122.  
  123. // Alternative way
  124. Extraction.decompose(point) should equal(reference)
  125. }
  126.  
  127.  
  128. it should "be possible to work with POJO objects even when the class is unknown" in {
  129. import org.json4s.jackson.JsonMethods.{parse,render,compact,pretty}
  130. import org.json4s.jackson.Serialization
  131. import org.json4s.jackson.Serialization.{read, write}
  132. import org.json4s.JsonDSL._
  133. import org.json4s._
  134.  
  135. val reference = ("x"-> 24) ~ ("y"->42)
  136.  
  137. //val clazz = Class.forName("java.awt.Point")
  138. //val cons = clazz.getConstructor(classOf[Int], classOf[Int])
  139. //val point = cons.newInstance(new java.lang.Integer(24), new java.lang.Integer(42)).asInstanceOf[Object]
  140.  
  141. val point = new java.awt.Point(24, 42)
  142. //val customSerializer = classOf[FieldSerializer].newInstance()
  143.  
  144. implicit val formats = DefaultFormats //+ customSerializer //FieldSerializer[java.awt.Point]()
  145. implicit val serialization = Serialization
  146.  
  147. Extraction.decompose(point) should equal(reference)
  148. // TODO - current status : decompose doesn't introspect dynamically allocated java types
  149. }
  150.  
  151.  
  152. it should "map a ScalaMap to a json object" in {
  153. import org.json4s._
  154. import org.json4s.native.JsonMethods.{render,compact,pretty}
  155.  
  156. val now = new java.util.Date()
  157. val nowIso8601 = now.toInstant.toString // ~ 2018-09-25T12:59:21.315Z
  158. val input = Map("age"->42, "name"->"John Doe", "now"->now)
  159.  
  160. implicit val formats = DefaultFormats.lossless // for milliseconds in iso8601 dates...
  161.  
  162. val jvalue = Extraction.decompose(input)
  163. val json = pretty(render(jvalue))
  164. info(json)
  165. compact(render(jvalue)) shouldBe s"""{"age":42,"name":"John Doe","now":"${nowIso8601}"}"""
  166. }
  167.  
  168. it should "be possible to extract a Map from a json object" in {
  169. import org.json4s._
  170. import org.json4s.native.JsonMethods.{render,compact,pretty}
  171. implicit val formats = DefaultFormats.lossless // for milliseconds in iso8601 dates...
  172.  
  173. val someone = Someone("john", 42)
  174. val jvalue = Extraction.decompose(someone)
  175. val jmap = jvalue.extract[Map[String,Any]]
  176. jmap shouldBe Map("name"->"john", "age"->42)
  177. }
  178.  
  179. }
  180.  
  181. JsonJson4sCookBook.execute()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement