From 2d9d58352e818b31f03d76c0c967834285c383d6 Mon Sep 17 00:00:00 2001 From: rickb777 Date: Fri, 3 May 2013 10:57:37 +0100 Subject: [PATCH 1/3] Added Idea ipr file. --- jerkson.ipr | 205 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 205 insertions(+) create mode 100644 jerkson.ipr diff --git a/jerkson.ipr b/jerkson.ipr new file mode 100644 index 0000000..3c1aa19 --- /dev/null +++ b/jerkson.ipr @@ -0,0 +1,205 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From b6889c582ed306a7b4a24ab0f4cbff9120d76a94 Mon Sep 17 00:00:00 2001 From: rickb777 Date: Fri, 3 May 2013 11:00:03 +0100 Subject: [PATCH 2/3] Added further tests so that optional collections are covered in the case-class tests. --- jerkson.ipr | 205 ---------------------------------------------------- 1 file changed, 205 deletions(-) delete mode 100644 jerkson.ipr diff --git a/jerkson.ipr b/jerkson.ipr deleted file mode 100644 index 3c1aa19..0000000 --- a/jerkson.ipr +++ /dev/null @@ -1,205 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From 9f8f37a81ae04a55deac09dfd4bd4fc59fd6d375 Mon Sep 17 00:00:00 2001 From: rickb777 Date: Fri, 3 May 2013 11:00:21 +0100 Subject: [PATCH 3/3] Added further tests so that optional collections are covered in the case-class tests. --- .gitignore | 4 +- .../jerkson/util/CaseClassSigParser.scala | 2 +- .../jerkson/tests/CaseClassSupportSpec.scala | 146 ++++++++++++++---- .../jerkson/tests/ExampleCaseClasses.scala | 14 +- 4 files changed, 135 insertions(+), 31 deletions(-) diff --git a/.gitignore b/.gitignore index 5a0e4a9..9b0346d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,10 @@ .idea* +*.iws +*.ipr *.iml target - .classpath .project .settings .cache +/out/ diff --git a/src/main/scala/com/codahale/jerkson/util/CaseClassSigParser.scala b/src/main/scala/com/codahale/jerkson/util/CaseClassSigParser.scala index a5f695d..7b009fb 100644 --- a/src/main/scala/com/codahale/jerkson/util/CaseClassSigParser.scala +++ b/src/main/scala/com/codahale/jerkson/util/CaseClassSigParser.scala @@ -108,7 +108,7 @@ object CaseClassSigParser { val defaultMethod = try { Some(companionClass.getMethod("apply$default$%d".format(idx + 1))) } catch { - case _ ⇒ None // indicates no default value was supplied + case _: Exception ⇒ None // indicates no default value was supplied } val defaultValue = defaultMethod.map(m ⇒ Some(m.invoke(companionObject))).getOrElse(None) Tuple3(ms.name, typeRef2JavaType(t, factory, classLoader, containedTypes), defaultValue) :: Nil diff --git a/src/test/scala/com/codahale/jerkson/tests/CaseClassSupportSpec.scala b/src/test/scala/com/codahale/jerkson/tests/CaseClassSupportSpec.scala index 9f5be7c..fa1c0ec 100644 --- a/src/test/scala/com/codahale/jerkson/tests/CaseClassSupportSpec.scala +++ b/src/test/scala/com/codahale/jerkson/tests/CaseClassSupportSpec.scala @@ -107,7 +107,7 @@ class CaseClassSupportSpec extends FlatSpec with ShouldMatchers { generate(CaseClassWithJsonNode(new IntNode(2))) should equal( """{"value":2}""") } - "A case class with members of all ScalaSig types" should "be pasrable from a JSON object with those fields" in { + "A case class with members of all ScalaSig types" should "be parsable from a JSON object with those fields" in { val json = """ { "map": { @@ -135,39 +135,131 @@ class CaseClassSupportSpec extends FlatSpec with ShouldMatchers { "any": true, "anyRef": "wah", "intMap": { - "1": "1" + "1": "10" }, "longMap": { - "2": 2 + "2": 20 } } """ - parse[CaseClassWithAllTypes](json) should equal( - CaseClassWithAllTypes( - map = Map("one" -> "two"), - set = Set(1, 2, 3), - string = "woo", - list = List(4, 5, 6), - seq = Seq(7, 8, 9), - indexedSeq = IndexedSeq(16, 17, 18), - vector = Vector(22, 23, 24), - bigDecimal = BigDecimal("12.0"), - bigInt = BigInt("13"), - int = 1, - long = 2L, - char = 'x', - bool = false, - short = 14, - byte = 15, - float = 34.5f, - double = 44.9d, - any = true, - anyRef = "wah", - intMap = Map(1 -> 1), - longMap = Map(2L -> 2L) - ) + val expected = CaseClassWithAllTypes( + map = Map("one" -> "two"), + set = Set(1, 2, 3), + string = "woo", + list = List(4, 5, 6), + seq = Seq(7, 8, 9), + indexedSeq = IndexedSeq(16, 17, 18), + vector = Vector(22, 23, 24), + bigDecimal = BigDecimal("12.0"), + bigInt = BigInt("13"), + int = 1, + long = 2L, + char = 'x', + bool = false, + short = 14, + byte = 15, + float = 34.5f, + double = 44.9d, + any = true, + anyRef = "wah", + intMap = Map(1 -> 10), + longMap = Map(2L -> 20L) ) + val actual = parse[CaseClassWithAllTypes](json) + actual should equal(expected) + parse[CaseClassWithAllTypes](generate(actual)) should equal(expected) + } + + + "A case class with supplied optional members of Scala collection types" should "be parsable from a JSON object with those fields" in { + val json = """ + { + "map": { + "one": "two" + }, + "set": [1, 2, 3], + "list": [4, 5, 6], + "seq": [7, 8, 9], + "indexedSeq": [16, 17, 18], + "vector": [22, 23, 24], + "intMap": { + "1": 10 + }, + "longMap": { + "2": 20 + } + } + """ + + val expected = CaseClassWithOptionalCollectionTypes( + map = Some(Map("one" -> "two")), + set = Some(Set(1, 2, 3)), + list = Some(List(4, 5, 6)), + seq = Some(Seq(7, 8, 9)), + indexedSeq = Some(IndexedSeq(16, 17, 18)), + vector = Some(Vector(22, 23, 24)), + intMap = Some(Map(1 -> 10)), + longMap = Some(Map(2L -> 20L)) + ) + val actual = parse[CaseClassWithOptionalCollectionTypes](json) + actual should equal(expected) + val generatedJson = generate(actual).replaceAll("[\n\t ]", "") + generatedJson should equal(json.replaceAll("[\n\t ]", "")) + parse[CaseClassWithOptionalCollectionTypes](generatedJson) should equal(expected) + } + + + "A case class with optional members of empty Scala collection types" should "be parsable from a JSON object with those fields" in { + val json = """ + { + "map": {}, + "set": [], + "list": [], + "seq": [], + "collection": [], + "indexedSeq": [], + "randomAccessSeq": [], + "vector": [], + "intMap": {}, + "longMap": {} + } + """ + + val expected = CaseClassWithOptionalCollectionTypes( + map = Some(Map.empty), + set = Some(Set.empty), + list = Some(List.empty), + seq = Some(Seq.empty), + indexedSeq = Some(IndexedSeq.empty), + vector = Some(Vector.empty), + intMap = Some(Map.empty), + longMap = Some(Map.empty) + ) + val actual = parse[CaseClassWithOptionalCollectionTypes](json) + actual should equal(expected) + parse[CaseClassWithOptionalCollectionTypes](generate(actual)) should equal(expected) + } + + + "A case class with absent optional members of Scala collection types" should "be parsable from a JSON object with those fields" in { + val json = """ + {} + """ + + val expected = CaseClassWithOptionalCollectionTypes( + map = None, + set = None, + list = None, + seq = None, + indexedSeq = None, + vector = None, + intMap = None, + longMap = None + ) + val actual = parse[CaseClassWithOptionalCollectionTypes](json) + actual should equal(expected) + parse[CaseClassWithOptionalCollectionTypes](generate(actual)) should equal(expected) } diff --git a/src/test/scala/com/codahale/jerkson/tests/ExampleCaseClasses.scala b/src/test/scala/com/codahale/jerkson/tests/ExampleCaseClasses.scala index c78a5af..797947f 100644 --- a/src/test/scala/com/codahale/jerkson/tests/ExampleCaseClasses.scala +++ b/src/test/scala/com/codahale/jerkson/tests/ExampleCaseClasses.scala @@ -7,6 +7,7 @@ import com.codahale.jerkson.JsonSnakeCase case class CaseClass(id: Long, name: String) case class CaseClassWithDefaultString(id: Long, name: String = "Coda") + case class CaseClassWithDefaultInt(id: Long, answer: Int = 42) case class CaseClassWithLazyVal(id: Long) { @@ -59,6 +60,15 @@ case class CaseClassWithAllTypes(map: Map[String, String], intMap: Map[Int, Int], longMap: Map[Long, Long]) +case class CaseClassWithOptionalCollectionTypes(map: Option[Map[String, String]], + set: Option[Set[Int]], + list: Option[List[Int]], + seq: Option[Seq[Int]], + indexedSeq: Option[IndexedSeq[Int]], + vector: Option[Vector[Int]], + intMap: Option[Map[Int, Int]], + longMap: Option[Map[Long, Long]]) + object OuterObject { case class NestedCaseClass(id: Long) @@ -67,8 +77,8 @@ object OuterObject { } } -case class CaseClassWithTwoConstructors(id: Long, name: String) { - def this(id: Long) = this(id, "New User") +case class CaseClassWithTwoConstructors(id: Long, name: String) { + def this(id: Long) = this(id, "New User") } @JsonSnakeCase