diff options
Diffstat (limited to 'src/test/scala/spray/json')
-rw-r--r-- | src/test/scala/spray/json/AdditionalFormatsSpec.scala | 73 | ||||
-rw-r--r-- | src/test/scala/spray/json/BasicFormatsSpec.scala | 168 | ||||
-rw-r--r-- | src/test/scala/spray/json/CollectionFormatsSpec.scala | 82 | ||||
-rw-r--r-- | src/test/scala/spray/json/CompactPrinterSpec.scala | 76 | ||||
-rw-r--r-- | src/test/scala/spray/json/CustomFormatSpec.scala | 45 | ||||
-rw-r--r-- | src/test/scala/spray/json/HashCodeCollider.scala | 26 | ||||
-rw-r--r-- | src/test/scala/spray/json/JsonParserSpec.scala | 193 | ||||
-rw-r--r-- | src/test/scala/spray/json/PrettyPrinterSpec.scala | 71 | ||||
-rw-r--r-- | src/test/scala/spray/json/ProductFormatsSpec.scala | 209 | ||||
-rw-r--r-- | src/test/scala/spray/json/ReadmeSpec.scala | 98 | ||||
-rw-r--r-- | src/test/scala/spray/json/RoundTripSpecs.scala | 77 | ||||
-rw-r--r-- | src/test/scala/spray/json/SortedPrinterSpec.scala | 65 | ||||
-rw-r--r-- | src/test/scala/spray/json/StandardFormatsSpec.scala | 121 |
13 files changed, 0 insertions, 1304 deletions
diff --git a/src/test/scala/spray/json/AdditionalFormatsSpec.scala b/src/test/scala/spray/json/AdditionalFormatsSpec.scala deleted file mode 100644 index 01127e6..0000000 --- a/src/test/scala/spray/json/AdditionalFormatsSpec.scala +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2011 Mathias Doenitz - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package spray.json - -import org.specs2.mutable._ - -class AdditionalFormatsSpec extends Specification { - - case class Container[A](inner: Option[A]) - - object ReaderProtocol extends DefaultJsonProtocol { - implicit def containerReader[T :JsonFormat] = lift { - new JsonReader[Container[T]] { - def read(value: JsValue) = value match { - case JsObject(fields) if fields.contains("content") => Container(Some(jsonReader[T].read(fields("content")))) - case _ => deserializationError("Unexpected format: " + value.toString) - } - } - } - } - - object WriterProtocol extends DefaultJsonProtocol { - implicit def containerWriter[T :JsonFormat] = lift { - new JsonWriter[Container[T]] { - def write(obj: Container[T]) = JsObject("content" -> obj.inner.toJson) - } - } - } - - "The liftJsonWriter" should { - val obj = Container(Some(Container(Some(List(1, 2, 3))))) - - "properly write a Container[Container[List[Int]]] to JSON" in { - import WriterProtocol._ - obj.toJson.toString mustEqual """{"content":{"content":[1,2,3]}}""" - } - - "properly read a Container[Container[List[Int]]] from JSON" in { - import ReaderProtocol._ - """{"content":{"content":[1,2,3]}}""".parseJson.convertTo[Container[Container[List[Int]]]] mustEqual obj - } - } - - case class Foo(id: Long, name: String, foos: Option[List[Foo]] = None) - - object FooProtocol extends DefaultJsonProtocol { - implicit val fooProtocol: JsonFormat[Foo] = lazyFormat(jsonFormat(Foo, "id", "name", "foos")) - } - - "The lazyFormat wrapper" should { - "enable recursive format definitions" in { - import FooProtocol._ - val json = Foo(1, "a", Some(Foo(2, "b", Some(Foo(3, "c") :: Nil)) :: Foo(4, "d") :: Nil)).toJson - - json mustEqual - """{"id":1,"name":"a","foos":[{"id":2,"name":"b","foos":[{"id":3,"name":"c"}]},{"id":4,"name":"d"}]}""".parseJson - } - } -}
\ No newline at end of file diff --git a/src/test/scala/spray/json/BasicFormatsSpec.scala b/src/test/scala/spray/json/BasicFormatsSpec.scala deleted file mode 100644 index 454e1cc..0000000 --- a/src/test/scala/spray/json/BasicFormatsSpec.scala +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (C) 2011 Mathias Doenitz - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package spray.json - -import org.specs2.mutable._ - -class BasicFormatsSpec extends Specification with DefaultJsonProtocol { - - "The IntJsonFormat" should { - "convert an Int to a JsNumber" in { - 42.toJson mustEqual JsNumber(42) - } - "convert a JsNumber to an Int" in { - JsNumber(42).convertTo[Int] mustEqual 42 - } - } - - "The LongJsonFormat" should { - "convert a Long to a JsNumber" in { - 7563661897011259335L.toJson mustEqual JsNumber(7563661897011259335L) - } - "convert a JsNumber to a Long" in { - JsNumber(7563661897011259335L).convertTo[Long] mustEqual 7563661897011259335L - } - } - - "The FloatJsonFormat" should { - "convert a Float to a JsNumber" in { - 4.2f.toJson mustEqual JsNumber(4.2f) - } - "convert a Float.NaN to a JsNull" in { - Float.NaN.toJson mustEqual JsNull - } - "convert a Float.PositiveInfinity to a JsNull" in { - Float.PositiveInfinity.toJson mustEqual JsNull - } - "convert a Float.NegativeInfinity to a JsNull" in { - Float.NegativeInfinity.toJson mustEqual JsNull - } - "convert a JsNumber to a Float" in { - JsNumber(4.2f).convertTo[Float] mustEqual 4.2f - } - "convert a JsNull to a Float" in { - JsNull.convertTo[Float].isNaN mustEqual Float.NaN.isNaN - } - } - - "The DoubleJsonFormat" should { - "convert a Double to a JsNumber" in { - 4.2.toJson mustEqual JsNumber(4.2) - } - "convert a Double.NaN to a JsNull" in { - Double.NaN.toJson mustEqual JsNull - } - "convert a Double.PositiveInfinity to a JsNull" in { - Double.PositiveInfinity.toJson mustEqual JsNull - } - "convert a Double.NegativeInfinity to a JsNull" in { - Double.NegativeInfinity.toJson mustEqual JsNull - } - "convert a JsNumber to a Double" in { - JsNumber(4.2).convertTo[Double] mustEqual 4.2 - } - "convert a JsNull to a Double" in { - JsNull.convertTo[Double].isNaN mustEqual Double.NaN.isNaN - } - } - - "The ByteJsonFormat" should { - "convert a Byte to a JsNumber" in { - 42.asInstanceOf[Byte].toJson mustEqual JsNumber(42) - } - "convert a JsNumber to a Byte" in { - JsNumber(42).convertTo[Byte] mustEqual 42 - } - } - - "The ShortJsonFormat" should { - "convert a Short to a JsNumber" in { - 42.asInstanceOf[Short].toJson mustEqual JsNumber(42) - } - "convert a JsNumber to a Short" in { - JsNumber(42).convertTo[Short] mustEqual 42 - } - } - - "The BigDecimalJsonFormat" should { - "convert a BigDecimal to a JsNumber" in { - BigDecimal(42).toJson mustEqual JsNumber(42) - } - "convert a JsNumber to a BigDecimal" in { - JsNumber(42).convertTo[BigDecimal] mustEqual BigDecimal(42) - } - """convert a JsString to a BigDecimal (to allow the quoted-large-numbers pattern)""" in { - JsString("9223372036854775809").convertTo[BigDecimal] mustEqual BigDecimal("9223372036854775809") - } - } - - "The BigIntJsonFormat" should { - "convert a BigInt to a JsNumber" in { - BigInt(42).toJson mustEqual JsNumber(42) - } - "convert a JsNumber to a BigInt" in { - JsNumber(42).convertTo[BigInt] mustEqual BigInt(42) - } - """convert a JsString to a BigInt (to allow the quoted-large-numbers pattern)""" in { - JsString("9223372036854775809").convertTo[BigInt] mustEqual BigInt("9223372036854775809") - } - } - - "The UnitJsonFormat" should { - "convert Unit to a JsNumber(1)" in { - ().toJson mustEqual JsNumber(1) - } - "convert a JsNumber to Unit" in { - JsNumber(1).convertTo[Unit] mustEqual (()) - } - } - - "The BooleanJsonFormat" should { - "convert true to a JsTrue" in { true.toJson mustEqual JsTrue } - "convert false to a JsFalse" in { false.toJson mustEqual JsFalse } - "convert a JsTrue to true" in { JsTrue.convertTo[Boolean] mustEqual true } - "convert a JsFalse to false" in { JsFalse.convertTo[Boolean] mustEqual false } - } - - "The CharJsonFormat" should { - "convert a Char to a JsString" in { - 'c'.toJson mustEqual JsString("c") - } - "convert a JsString to a Char" in { - JsString("c").convertTo[Char] mustEqual 'c' - } - } - - "The StringJsonFormat" should { - "convert a String to a JsString" in { - "Hello".toJson mustEqual JsString("Hello") - } - "convert a JsString to a String" in { - JsString("Hello").convertTo[String] mustEqual "Hello" - } - } - - "The SymbolJsonFormat" should { - "convert a Symbol to a JsString" in { - Symbol("Hello").toJson mustEqual JsString("Hello") - } - "convert a JsString to a Symbol" in { - JsString("Hello").convertTo[Symbol] mustEqual Symbol("Hello") - } - } - -} diff --git a/src/test/scala/spray/json/CollectionFormatsSpec.scala b/src/test/scala/spray/json/CollectionFormatsSpec.scala deleted file mode 100644 index 9d6970b..0000000 --- a/src/test/scala/spray/json/CollectionFormatsSpec.scala +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2011 Mathias Doenitz - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package spray.json - -import org.specs2.mutable._ -import java.util.Arrays - -class CollectionFormatsSpec extends Specification with DefaultJsonProtocol { - - "The listFormat" should { - val list = List(1, 2, 3) - val json = JsArray(JsNumber(1), JsNumber(2), JsNumber(3)) - "convert a List[Int] to a JsArray of JsNumbers" in { - list.toJson mustEqual json - } - "convert a JsArray of JsNumbers to a List[Int]" in { - json.convertTo[List[Int]] mustEqual list - } - } - - "The arrayFormat" should { - val array = Array(1, 2, 3) - val json = JsArray(JsNumber(1), JsNumber(2), JsNumber(3)) - "convert an Array[Int] to a JsArray of JsNumbers" in { - array.toJson mustEqual json - } - "convert a JsArray of JsNumbers to an Array[Int]" in { - Arrays.equals(json.convertTo[Array[Int]], array) must beTrue - } - } - - "The mapFormat" should { - val map = Map("a" -> 1, "b" -> 2, "c" -> 3) - val json = JsObject("a" -> JsNumber(1), "b" -> JsNumber(2), "c" -> JsNumber(3)) - "convert a Map[String, Long] to a JsObject" in { - map.toJson mustEqual json - } - "be able to convert a JsObject to a Map[String, Long]" in { - json.convertTo[Map[String, Long]] mustEqual map - } - "throw an Exception when trying to serialize a map whose key are not serialized to JsStrings" in { - Map(1 -> "a").toJson must throwA(new SerializationException("Map key must be formatted as JsString, not '1'")) - } - } - - "The immutableSetFormat" should { - val set = Set(1, 2, 3) - val numbers = Set(JsNumber(1), JsNumber(2), JsNumber(3)) - "convert a Set[Int] to a JsArray of JsNumbers" in { - set.toJson.asInstanceOf[JsArray].elements.toSet mustEqual numbers - } - "convert a JsArray of JsNumbers to a Set[Int]" in { - JsArray(numbers.toVector).convertTo[Set[Int]] mustEqual set - } - } - - "The indexedSeqFormat" should { - val seq = collection.IndexedSeq(1, 2, 3) - val json = JsArray(JsNumber(1), JsNumber(2), JsNumber(3)) - "convert a Set[Int] to a JsArray of JsNumbers" in { - seq.toJson mustEqual json - } - "convert a JsArray of JsNumbers to a IndexedSeq[Int]" in { - json.convertTo[collection.IndexedSeq[Int]] mustEqual seq - } - } - -}
\ No newline at end of file diff --git a/src/test/scala/spray/json/CompactPrinterSpec.scala b/src/test/scala/spray/json/CompactPrinterSpec.scala deleted file mode 100644 index 6a9560b..0000000 --- a/src/test/scala/spray/json/CompactPrinterSpec.scala +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2011 Mathias Doenitz - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package spray.json - -import org.specs2.mutable._ - -class CompactPrinterSpec extends Specification { - - "The CompactPrinter" should { - "print JsNull to 'null'" in { - CompactPrinter(JsNull) mustEqual "null" - } - "print JsTrue to 'true'" in { - CompactPrinter(JsTrue) mustEqual "true" - } - "print JsFalse to 'false'" in { - CompactPrinter(JsFalse) mustEqual "false" - } - "print JsNumber(0) to '0'" in { - CompactPrinter(JsNumber(0)) mustEqual "0" - } - "print JsNumber(1.23) to '1.23'" in { - CompactPrinter(JsNumber(1.23)) mustEqual "1.23" - } - "print JsNumber(1.23) to '1.23'" in { - CompactPrinter(JsNumber(1.23)) mustEqual "1.23" - } - "print JsNumber(-1E10) to '-1E10'" in { - CompactPrinter(JsNumber(-1E10)) mustEqual "-1.0E+10" - } - "print JsNumber(12.34e-10) to '12.34e-10'" in { - CompactPrinter(JsNumber(12.34e-10)) mustEqual "1.234E-9" - } - "print JsString(\"xyz\") to \"xyz\"" in { - CompactPrinter(JsString("xyz")) mustEqual "\"xyz\"" - } - "properly escape special chars in JsString" in { - CompactPrinter(JsString("\"\\\b\f\n\r\t")) mustEqual """"\"\\\b\f\n\r\t"""" - CompactPrinter(JsString("\u1000")) mustEqual "\"\u1000\"" - CompactPrinter(JsString("\u0100")) mustEqual "\"\u0100\"" - CompactPrinter(JsString("\u0010")) mustEqual "\"\\u0010\"" - CompactPrinter(JsString("\u0001")) mustEqual "\"\\u0001\"" - CompactPrinter(JsString("\u001e")) mustEqual "\"\\u001e\"" - // don't escape as it isn't required by the spec - CompactPrinter(JsString("\u007f")) mustEqual "\"\u007f\"" - CompactPrinter(JsString("飞机因此受到损伤")) mustEqual "\"飞机因此受到损伤\"" - CompactPrinter(JsString("\uD834\uDD1E")) mustEqual "\"\uD834\uDD1E\"" - } - "properly print a simple JsObject" in ( - CompactPrinter(JsObject("key" -> JsNumber(42), "key2" -> JsString("value"))) - mustEqual """{"key":42,"key2":"value"}""" - ) - "properly print a simple JsArray" in ( - CompactPrinter(JsArray(JsNull, JsNumber(1.23), JsObject("key" -> JsBoolean(true)))) - mustEqual """[null,1.23,{"key":true}]""" - ) - "properly print a JSON padding (JSONP) if requested" in { - CompactPrinter(JsTrue, Some("customCallback")) mustEqual("customCallback(true)") - } - } - -}
\ No newline at end of file diff --git a/src/test/scala/spray/json/CustomFormatSpec.scala b/src/test/scala/spray/json/CustomFormatSpec.scala deleted file mode 100644 index 2397abc..0000000 --- a/src/test/scala/spray/json/CustomFormatSpec.scala +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2011 Mathias Doenitz - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package spray.json - -import org.specs2.mutable.Specification - -class CustomFormatSpec extends Specification with DefaultJsonProtocol { - - case class MyType(name: String, value: Int) - - implicit val MyTypeProtocol = new RootJsonFormat[MyType] { - def read(json: JsValue) = { - json.asJsObject.getFields("name", "value") match { - case Seq(JsString(name), JsNumber(value)) => MyType(name, value.toInt) - case _ => deserializationError("Expected fields: 'name' (JSON string) and 'value' (JSON number)") - } - } - def write(obj: MyType) = JsObject("name" -> JsString(obj.name), "value" -> JsNumber(obj.value)) - } - - "A custom JsonFormat built with 'asJsonObject'" should { - val value = MyType("bob", 42) - "correctly deserialize valid JSON content" in { - """{ "name": "bob", "value": 42 }""".parseJson.convertTo[MyType] mustEqual value - } - "support full round-trip (de)serialization" in { - value.toJson.convertTo[MyType] mustEqual value - } - } - -}
\ No newline at end of file diff --git a/src/test/scala/spray/json/HashCodeCollider.scala b/src/test/scala/spray/json/HashCodeCollider.scala deleted file mode 100644 index 57388b9..0000000 --- a/src/test/scala/spray/json/HashCodeCollider.scala +++ /dev/null @@ -1,26 +0,0 @@ -package spray.json - -/** - * Helper that creates strings that all share the same hashCode == 0. - * - * Adapted from MIT-licensed code by Andriy Plokhotnyuk - * at https://github.com/plokhotnyuk/jsoniter-scala/blob/26b5ecdd4f8c2ab7e97bd8106cefdda4c1e701ce/jsoniter-scala-benchmark/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/macros/HashCodeCollider.scala#L6. - */ -object HashCodeCollider { - val visibleChars = (33 until 127).filterNot(c => c == '\\' || c == '"') - def asciiChars: Iterator[Int] = visibleChars.toIterator - def asciiCharsAndHash(previousHash: Int): Iterator[(Int, Int)] = visibleChars.toIterator.map(c => c -> (previousHash + c) * 31) - - /** Creates an iterator of Strings that all have hashCode == 0 */ - def zeroHashCodeIterator(): Iterator[String] = - for { - (i0, h0) <- asciiCharsAndHash(0) - (i1, h1) <- asciiCharsAndHash(h0) - (i2, h2) <- asciiCharsAndHash(h1) if (((h2 + 32) * 923521) ^ ((h2 + 127) * 923521)) < 0 - (i3, h3) <- asciiCharsAndHash(h2) if (((h3 + 32) * 29791) ^ ((h3 + 127) * 29791)) < 0 - (i4, h4) <- asciiCharsAndHash(h3) if (((h4 + 32) * 961) ^ ((h4 + 127) * 961)) < 0 - (i5, h5) <- asciiCharsAndHash(h4) if (((h5 + 32) * 31) ^ ((h5 + 127) * 31)) < 0 - (i6, h6) <- asciiCharsAndHash(h5) if ((h6 + 32) ^ (h6 + 127)) < 0 - (i7, h7) <- asciiCharsAndHash(h6) if h6 + i7 == 0 - } yield new String(Array(i0, i1, i2, i3, i4, i5, i6, i7).map(_.toChar)) -} diff --git a/src/test/scala/spray/json/JsonParserSpec.scala b/src/test/scala/spray/json/JsonParserSpec.scala deleted file mode 100644 index 1ca0ddc..0000000 --- a/src/test/scala/spray/json/JsonParserSpec.scala +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright (C) 2011 Mathias Doenitz - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package spray.json - -import org.specs2.mutable._ - -import scala.util.control.NonFatal - -class JsonParserSpec extends Specification { - - "The JsonParser" should { - "parse 'null' to JsNull" in { - JsonParser("null") === JsNull - } - "parse 'true' to JsTrue" in { - JsonParser("true") === JsTrue - } - "parse 'false' to JsFalse" in { - JsonParser("false") === JsFalse - } - "parse '0' to JsNumber" in { - JsonParser("0") === JsNumber(0) - } - "parse '1.23' to JsNumber" in { - JsonParser("1.23") === JsNumber(1.23) - } - "parse '-1E10' to JsNumber" in { - JsonParser("-1E10") === JsNumber("-1E+10") - } - "parse '12.34e-10' to JsNumber" in { - JsonParser("12.34e-10") === JsNumber("1.234E-9") - } - "parse \"xyz\" to JsString" in { - JsonParser("\"xyz\"") === JsString("xyz") - } - "parse escapes in a JsString" in { - JsonParser(""""\"\\/\b\f\n\r\t"""") === JsString("\"\\/\b\f\n\r\t") - JsonParser("\"L\\" + "u00e4nder\"") === JsString("Länder") - } - "parse all representations of the slash (SOLIDUS) character in a JsString" in { - JsonParser( "\"" + "/\\/\\u002f" + "\"") === JsString("///") - } - "parse a simple JsObject" in ( - JsonParser(""" { "key" :42, "key2": "value" }""") === - JsObject("key" -> JsNumber(42), "key2" -> JsString("value")) - ) - "parse a simple JsArray" in ( - JsonParser("""[null, 1.23 ,{"key":true } ] """) === - JsArray(JsNull, JsNumber(1.23), JsObject("key" -> JsTrue)) - ) - "parse directly from UTF-8 encoded bytes" in { - val json = JsObject( - "7-bit" -> JsString("This is regular 7-bit ASCII text."), - "2-bytes" -> JsString("2-byte UTF-8 chars like £, æ or Ö"), - "3-bytes" -> JsString("3-byte UTF-8 chars like ヨ, ᄅ or ᐁ."), - "4-bytes" -> JsString("4-byte UTF-8 chars like \uD801\uDC37, \uD852\uDF62 or \uD83D\uDE01.")) - JsonParser(json.prettyPrint.getBytes("UTF-8")) === json - } - "parse directly from UTF-8 encoded bytes when string starts with a multi-byte character" in { - val json = JsString("£0.99") - JsonParser(json.prettyPrint.getBytes("UTF-8")) === json - } - "be reentrant" in { - import scala.concurrent.{Await, Future} - import scala.concurrent.duration._ - import scala.concurrent.ExecutionContext.Implicits.global - - val largeJsonSource = scala.io.Source.fromInputStream(getClass.getResourceAsStream("/test.json")).mkString - val list = Await.result( - Future.traverse(List.fill(20)(largeJsonSource))(src => Future(JsonParser(src))), - 5.seconds - ) - list.map(_.asInstanceOf[JsObject].fields("questions").asInstanceOf[JsArray].elements.size) === List.fill(20)(100) - } - "not show bad performance characteristics when object keys' hashCodes collide" in { - val numKeys = 10000 - val value = "null" - - val regularKeys = Iterator.from(1).map(i => s"key_$i").take(numKeys) - val collidingKeys = HashCodeCollider.zeroHashCodeIterator().take(numKeys) - - def createJson(keys: Iterator[String]): String = keys.mkString("""{"""", s"""":$value,"""", s"""":$value}""") - - def nanoBench(block: => Unit): Long = { - // great microbenchmark (the comment must be kept, otherwise it's not true) - val f = block _ - - // warmup - (1 to 10).foreach(_ => f()) - - val start = System.nanoTime() - f() - val end = System.nanoTime() - end - start - } - - val regularJson = createJson(regularKeys) - val collidingJson = createJson(collidingKeys) - - val regularTime = nanoBench { JsonParser(regularJson) } - val collidingTime = nanoBench { JsonParser(collidingJson) } - - collidingTime / regularTime must be < 2L // speed must be in same order of magnitude - } - - "produce proper error messages" in { - def errorMessage(input: String, settings: JsonParserSettings = JsonParserSettings.default) = - try JsonParser(input, settings) catch { case e: JsonParser.ParsingException => e.getMessage } - - errorMessage("""[null, 1.23 {"key":true } ]""") === - """Unexpected character '{' at input index 12 (line 1, position 13), expected ']': - |[null, 1.23 {"key":true } ] - | ^ - |""".stripMargin - - errorMessage("""[null, 1.23, { key":true } ]""") === - """Unexpected character 'k' at input index 16 (line 1, position 17), expected '"': - |[null, 1.23, { key":true } ] - | ^ - |""".stripMargin - - errorMessage("""{"a}""") === - """Unexpected end-of-input at input index 4 (line 1, position 5), expected '"': - |{"a} - | ^ - |""".stripMargin - - errorMessage("""{}x""") === - """Unexpected character 'x' at input index 2 (line 1, position 3), expected end-of-input: - |{}x - | ^ - |""".stripMargin - - "reject numbers which are too big / have too high precision" in { - val settings = JsonParserSettings.default.withMaxNumberCharacters(5) - errorMessage("123.4567890", settings) === - "Number too long:The number starting with '123.4567890' had 11 characters which is more than the allowed limit " + - "maxNumberCharacters = 5. If this is legit input consider increasing the limit." - } - } - - "fail gracefully for deeply nested structures" in { - val queue = new java.util.ArrayDeque[String]() - - // testing revealed that each recursion will need approx. 280 bytes of stack space - val depth = 1500 - val runnable = new Runnable { - override def run(): Unit = - try { - val nested = "[{\"key\":" * (depth / 2) - JsonParser(nested) - queue.push("didn't fail") - } catch { - case s: StackOverflowError => queue.push("stackoverflow") - case NonFatal(e) => - queue.push(s"nonfatal: ${e.getMessage}") - } - } - - val thread = new Thread(null, runnable, "parser-test", 655360) - thread.start() - thread.join() - queue.peek() === "nonfatal: JSON input nested too deeply:JSON input was nested more deeply than the configured limit of maxNesting = 1000" - } - - "parse multiple values when allowTrailingInput" in { - val parser = new JsonParser("""{"key":1}{"key":2}""") - parser.parseJsValue(true) === JsObject("key" -> JsNumber(1)) - parser.parseJsValue(true) === JsObject("key" -> JsNumber(2)) - } - "reject trailing input when !allowTrailingInput" in { - def parser = JsonParser("""{"key":1}x""") - parser must throwA[JsonParser.ParsingException].like { - case e: JsonParser.ParsingException => e.getMessage must contain("expected end-of-input") - } - } - - } -} diff --git a/src/test/scala/spray/json/PrettyPrinterSpec.scala b/src/test/scala/spray/json/PrettyPrinterSpec.scala deleted file mode 100644 index b547f59..0000000 --- a/src/test/scala/spray/json/PrettyPrinterSpec.scala +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2011 Mathias Doenitz - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package spray.json - -import scala.collection.immutable.ListMap -import org.specs2.mutable._ - -class PrettyPrinterSpec extends Specification { - - "The PrettyPrinter" should { - "print a more complicated JsObject nicely aligned" in { - val js = JsonParser { - """{ - | "Boolean no": false, - | "Boolean yes":true, - | "Unic\u00f8de" : "Long string with newline\nescape", - | "key with \"quotes\"" : "string", - | "key with spaces": null, - | "number": -1.2323424E-5, - | "simpleKey" : "some value", - | "sub object" : { - | "sub key": 26.5, - | "a": "b", - | "array": [1, 2, { "yes":1, "no":0 }, ["a", "b", null], false] - | }, - | "zero": 0 - |}""".stripMargin - } - def fixedFieldOrder(js: JsValue): JsValue = js match { - case JsObject(fields) => JsObject(ListMap(fields.toSeq.sortBy(_._1).map { case (k, v) => (k, fixedFieldOrder(v)) }:_*)) - case x => x - } - - PrettyPrinter(fixedFieldOrder(js)) mustEqual { - """{ - | "Boolean no": false, - | "Boolean yes": true, - | "Unic\u00f8de": "Long string with newline\nescape", - | "key with \"quotes\"": "string", - | "key with spaces": null, - | "number": -0.000012323424, - | "simpleKey": "some value", - | "sub object": { - | "a": "b", - | "array": [1, 2, { - | "no": 0, - | "yes": 1 - | }, ["a", "b", null], false], - | "sub key": 26.5 - | }, - | "zero": 0 - |}""".stripMargin - } - } - } - -}
\ No newline at end of file diff --git a/src/test/scala/spray/json/ProductFormatsSpec.scala b/src/test/scala/spray/json/ProductFormatsSpec.scala deleted file mode 100644 index f42c46d..0000000 --- a/src/test/scala/spray/json/ProductFormatsSpec.scala +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Copyright (C) 2011 Mathias Doenitz - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package spray.json - -import org.specs2.mutable._ - -class ProductFormatsSpec extends Specification { - - case class Test0() - case class Test2(a: Int, b: Option[Double]) - case class Test3[A, B](as: List[A], bs: List[B]) - case class Test4(t2: Test2) - case class TestTransient(a: Int, b: Option[Double]) { - @transient var c = false - } - @SerialVersionUID(1L) // SerialVersionUID adds a static field to the case class - case class TestStatic(a: Int, b: Option[Double]) - case class TestMangled(`foo-bar!`: Int, `User ID`: String, `ü$bavf$u56ú$`: Boolean, `-x-`: Int, `=><+-*/!@#%^&~?|`: Float) - - trait TestProtocol { - this: DefaultJsonProtocol => - implicit val test0Format = jsonFormat0(Test0) - implicit val test2Format = jsonFormat2(Test2) - implicit def test3Format[A: JsonFormat, B: JsonFormat] = jsonFormat2(Test3.apply[A, B]) - implicit def test4Format = jsonFormat1(Test4) - implicit def testTransientFormat = jsonFormat2(TestTransient) - implicit def testStaticFormat = jsonFormat2(TestStatic) - implicit def testMangledFormat = jsonFormat5(TestMangled) - } - object TestProtocol1 extends DefaultJsonProtocol with TestProtocol - object TestProtocol2 extends DefaultJsonProtocol with TestProtocol with NullOptions - - "A JsonFormat created with `jsonFormat`, for a case class with 2 elements," should { - import TestProtocol1._ - val obj = Test2(42, Some(4.2)) - val json = JsObject("a" -> JsNumber(42), "b" -> JsNumber(4.2)) - "convert to a respective JsObject" in { - obj.toJson mustEqual json - } - "convert a JsObject to the respective case class instance" in { - json.convertTo[Test2] mustEqual obj - } - "throw a DeserializationException if the JsObject does not all required members" in ( - JsObject("b" -> JsNumber(4.2)).convertTo[Test2] must - throwA(new DeserializationException("Object is missing required member 'a'")) - ) - "not require the presence of optional fields for deserialization" in { - JsObject("a" -> JsNumber(42)).convertTo[Test2] mustEqual Test2(42, None) - } - "not render `None` members during serialization" in { - Test2(42, None).toJson mustEqual JsObject("a" -> JsNumber(42)) - } - "ignore additional members during deserialization" in { - JsObject("a" -> JsNumber(42), "b" -> JsNumber(4.2), "c" -> JsString(Symbol("no"))).convertTo[Test2] mustEqual obj - } - "not depend on any specific member order for deserialization" in { - JsObject("b" -> JsNumber(4.2), "a" -> JsNumber(42)).convertTo[Test2] mustEqual obj - } - "throw a DeserializationException if the JsValue is not a JsObject" in ( - JsNull.convertTo[Test2] must throwA(new DeserializationException("Object expected in field 'a'")) - ) - "expose the fieldName in the DeserializationException when able" in { - JsNull.convertTo[Test2] must throwA[DeserializationException].like { - case DeserializationException(_, _, fieldNames) => fieldNames mustEqual "a" :: Nil - } - } - "expose all gathered fieldNames in the DeserializationException" in { - JsObject("t2" -> JsObject("a" -> JsString("foo"))).convertTo[Test4] must throwA[DeserializationException].like { - case DeserializationException(_, _, fieldNames) => fieldNames mustEqual "t2" :: "a" :: Nil - } - } - } - - "A JsonProtocol mixing in NullOptions" should { - "render `None` members to `null`" in { - import TestProtocol2._ - Test2(42, None).toJson mustEqual JsObject("a" -> JsNumber(42), "b" -> JsNull) - } - } - - "A JsonFormat for a generic case class and created with `jsonFormat`" should { - import TestProtocol1._ - val obj = Test3(42 :: 43 :: Nil, "x" :: "y" :: "z" :: Nil) - val json = JsObject( - "as" -> JsArray(JsNumber(42), JsNumber(43)), - "bs" -> JsArray(JsString("x"), JsString("y"), JsString("z")) - ) - "convert to a respective JsObject" in { - obj.toJson mustEqual json - } - "convert a JsObject to the respective case class instance" in { - json.convertTo[Test3[Int, String]] mustEqual obj - } - } - "A JsonFormat for a case class with 18 parameters and created with `jsonFormat`" should { - object Test18Protocol extends DefaultJsonProtocol { - implicit val test18Format = jsonFormat18(Test18) - } - case class Test18( - a1: String, - a2: String, - a3: String, - a4: String, - a5: Int, - a6: String, - a7: String, - a8: String, - a9: String, - a10: String, - a11: String, - a12: Double, - a13: String, - a14: String, - a15: String, - a16: String, - a17: String, - a18: String) - - import Test18Protocol._ - val obj = Test18("a1", "a2", "a3", "a4", 5, "a6", "a7", "a8", "a9", - "a10", "a11", 12d, "a13", "a14", "a15", "a16", "a17", "a18") - - val json = JsonParser("""{"a1":"a1","a2":"a2","a3":"a3","a4":"a4","a5":5,"a6":"a6","a7":"a7","a8":"a8","a9":"a9","a10":"a10","a11":"a11","a12":12.0,"a13":"a13","a14":"a14","a15":"a15","a16":"a16","a17":"a17","a18":"a18"}""") - "convert to a respective JsObject" in { - obj.toJson mustEqual json - } - "convert a JsObject to the respective case class instance" in { - json.convertTo[Test18] mustEqual obj - } - } - - "A JsonFormat for a generic case class with an explicitly provided type parameter" should { - "support the jsonFormat1 syntax" in { - case class Box[A](a: A) - object BoxProtocol extends DefaultJsonProtocol { - implicit val boxFormat = jsonFormat1(Box[Int]) - } - import BoxProtocol._ - Box(42).toJson === JsObject(Map("a" -> JsNumber(42))) - } - } - - "A JsonFormat for a case class with transient fields and created with `jsonFormat`" should { - import TestProtocol1._ - val obj = TestTransient(42, Some(4.2)) - val json = JsObject("a" -> JsNumber(42), "b" -> JsNumber(4.2)) - "convert to a respective JsObject" in { - obj.toJson mustEqual json - } - "convert a JsObject to the respective case class instance" in { - json.convertTo[TestTransient] mustEqual obj - } - } - - "A JsonFormat for a case class with static fields and created with `jsonFormat`" should { - import TestProtocol1._ - val obj = TestStatic(42, Some(4.2)) - val json = JsObject("a" -> JsNumber(42), "b" -> JsNumber(4.2)) - "convert to a respective JsObject" in { - obj.toJson mustEqual json - } - "convert a JsObject to the respective case class instance" in { - json.convertTo[TestStatic] mustEqual obj - } - } - - "A JsonFormat created with `jsonFormat`, for a case class with 0 elements," should { - import TestProtocol1._ - val obj = Test0() - val json = JsObject() - "convert to a respective JsObject" in { - obj.toJson mustEqual json - } - "convert a JsObject to the respective case class instance" in { - json.convertTo[Test0] mustEqual obj - } - "ignore additional members during deserialization" in { - JsObject("a" -> JsNumber(42)).convertTo[Test0] mustEqual obj - } - "throw a DeserializationException if the JsValue is not a JsObject" in ( - JsNull.convertTo[Test0] must throwA(new DeserializationException("Object expected")) - ) - } - - "A JsonFormat created with `jsonFormat`, for a case class with mangled-name members," should { - import TestProtocol1._ - val json = """{"ü$bavf$u56ú$":true,"=><+-*/!@#%^&~?|":1.0,"foo-bar!":42,"-x-":26,"User ID":"Karl"}""".parseJson - "produce the correct JSON" in { - TestMangled(42, "Karl", true, 26, 1.0f).toJson === json - } - "convert a JsObject to the respective case class instance" in { - json.convertTo[TestMangled] === TestMangled(42, "Karl", true, 26, 1.0f) - } - } -} diff --git a/src/test/scala/spray/json/ReadmeSpec.scala b/src/test/scala/spray/json/ReadmeSpec.scala deleted file mode 100644 index 306b656..0000000 --- a/src/test/scala/spray/json/ReadmeSpec.scala +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (C) 2011 Mathias Doenitz - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package spray.json - -import org.specs2.mutable._ - -class ReadmeSpec extends Specification { - - "The Usage snippets" should { - "behave as expected" in { - import DefaultJsonProtocol._ - - val source = """{ "some": "JSON source" }""" - val jsonAst = source.parseJson - jsonAst mustEqual JsObject("some" -> JsString("JSON source")) - - val json2 = jsonAst.prettyPrint - json2 mustEqual - """{ - | "some": "JSON source" - |}""".stripMargin - - val jsonAst2 = List(1, 2, 3).toJson - jsonAst2 mustEqual JsArray(JsNumber(1), JsNumber(2), JsNumber(3)) - } - } - - case class Color(name: String, red: Int, green: Int, blue: Int) - val color = Color("CadetBlue", 95, 158, 160) - - "The case class example" should { - "behave as expected" in { - object MyJsonProtocol extends DefaultJsonProtocol { - implicit val colorFormat = jsonFormat4(Color) - } - import MyJsonProtocol._ - color.toJson.convertTo[Color] mustEqual color - } - } - - "The non case class (array) example" should { - "behave as expected" in { - object MyJsonProtocol extends DefaultJsonProtocol { - implicit object ColorJsonFormat extends JsonFormat[Color] { - def write(c: Color) = - JsArray(JsString(c.name), JsNumber(c.red), JsNumber(c.green), JsNumber(c.blue)) - - def read(value: JsValue) = value match { - case JsArray(Seq(JsString(name), JsNumber(red), JsNumber(green), JsNumber(blue))) => - new Color(name, red.toInt, green.toInt, blue.toInt) - case _ => deserializationError("Color expected") - } - } - } - import MyJsonProtocol._ - color.toJson.convertTo[Color] mustEqual color - } - } - - "The non case class (object) example" should { - "behave as expected" in { - object MyJsonProtocol extends DefaultJsonProtocol { - implicit object ColorJsonFormat extends JsonFormat[Color] { - def write(c: Color) = JsObject( - "name" -> JsString(c.name), - "red" -> JsNumber(c.red), - "green" -> JsNumber(c.green), - "blue" -> JsNumber(c.blue) - ) - def read(value: JsValue) = { - value.asJsObject.getFields("name", "red", "green", "blue") match { - case Seq(JsString(name), JsNumber(red), JsNumber(green), JsNumber(blue)) => - new Color(name, red.toInt, green.toInt, blue.toInt) - case _ => throw new DeserializationException("Color expected") - } - } - } - } - import MyJsonProtocol._ - color.toJson.convertTo[Color] mustEqual color - } - } - -}
\ No newline at end of file diff --git a/src/test/scala/spray/json/RoundTripSpecs.scala b/src/test/scala/spray/json/RoundTripSpecs.scala deleted file mode 100644 index 6bee7b4..0000000 --- a/src/test/scala/spray/json/RoundTripSpecs.scala +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2011 Mathias Doenitz - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package spray.json - -import org.specs2.mutable.Specification -import org.scalacheck._ -import org.specs2.ScalaCheck - -object JsValueGenerators { - import Gen._ - import Arbitrary.arbitrary - - val parseableString: Gen[String] = Gen.someOf(('\u0020' to '\u007E').toVector).map(_.mkString) - val genString: Gen[JsString] = parseableString.map(JsString(_)) - val genBoolean: Gen[JsBoolean] = oneOf(JsFalse, JsTrue) - val genLongNumber: Gen[JsNumber] = arbitrary[Long].map(JsNumber(_)) - val genIntNumber: Gen[JsNumber] = arbitrary[Long].map(JsNumber(_)) - val genDoubleNumber: Gen[JsNumber] = arbitrary[Long].map(JsNumber(_)) - def genArray(depth: Int): Gen[JsArray] = - if (depth == 0) JsArray() - else - for { - n <- choose(0, 15) - els <- Gen.containerOfN[List, JsValue](n, genValue(depth - 1)) - } yield JsArray(els.toVector) - def genField(depth: Int): Gen[(String, JsValue)] = - for { - key <- parseableString - value <- genValue(depth) - } yield key -> value - def genObject(depth: Int): Gen[JsObject] = - if (depth == 0) JsObject() - else - for { - n <- choose(0, 15) - fields <- Gen.containerOfN[List, (String, JsValue)](n, genField(depth - 1)) - } yield JsObject(fields: _*) - - def genValue(depth: Int): Gen[JsValue] = - oneOf( - JsNull: Gen[JsValue], - genString, - genBoolean, - genLongNumber, - genDoubleNumber, - genIntNumber, - genArray(depth), - genObject(depth)) - implicit val arbitraryValue: Arbitrary[JsValue] = Arbitrary(genValue(5)) -} - -class RoundTripSpecs extends Specification with ScalaCheck { - import JsValueGenerators.arbitraryValue - - "Parsing / Printing round-trip" should { - "starting from JSON using compactPrint" in prop { (json: JsValue) => - json.compactPrint.parseJson must_== json - } - "starting from JSON using prettyPrint" in prop { (json: JsValue) => - json.prettyPrint.parseJson must_== json - } - } -} diff --git a/src/test/scala/spray/json/SortedPrinterSpec.scala b/src/test/scala/spray/json/SortedPrinterSpec.scala deleted file mode 100644 index f91640e..0000000 --- a/src/test/scala/spray/json/SortedPrinterSpec.scala +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2011 Mathias Doenitz - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package spray.json - -import org.specs2.mutable._ - -class SortedPrinterSpec extends Specification { - - "The SortedPrinter" should { - "print a more complicated JsObject nicely aligned with fields sorted" in { - val obj = JsonParser { - """{ - | "Unic\u00f8de" : "Long string with newline\nescape", - | "Boolean no": false, - | "number": -1.2323424E-5, - | "key with \"quotes\"" : "string", - | "key with spaces": null, - | "simpleKey" : "some value", - | "zero": 0, - | "sub object" : { - | "sub key": 26.5, - | "a": "b", - | "array": [1, 2, { "yes":1, "no":0 }, ["a", "b", null], false] - | }, - | "Boolean yes":true - |}""".stripMargin - } - SortedPrinter(obj) mustEqual { - """{ - | "Boolean no": false, - | "Boolean yes": true, - | "Unic\u00f8de": "Long string with newline\nescape", - | "key with \"quotes\"": "string", - | "key with spaces": null, - | "number": -0.000012323424, - | "simpleKey": "some value", - | "sub object": { - | "a": "b", - | "array": [1, 2, { - | "no": 0, - | "yes": 1 - | }, ["a", "b", null], false], - | "sub key": 26.5 - | }, - | "zero": 0 - |}""".stripMargin - } - } - } - -} diff --git a/src/test/scala/spray/json/StandardFormatsSpec.scala b/src/test/scala/spray/json/StandardFormatsSpec.scala deleted file mode 100644 index 833f06a..0000000 --- a/src/test/scala/spray/json/StandardFormatsSpec.scala +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (C) 2011 Mathias Doenitz - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package spray.json - -import org.specs2.mutable._ -import scala.Right - -class StandardFormatsSpec extends Specification with DefaultJsonProtocol { - - "The optionFormat" should { - "convert None to JsNull" in { - None.asInstanceOf[Option[Int]].toJson mustEqual JsNull - } - "convert JsNull to None" in { - JsNull.convertTo[Option[Int]] mustEqual None - } - "convert Some(Hello) to JsString(Hello)" in { - Some("Hello").asInstanceOf[Option[String]].toJson mustEqual JsString("Hello") - } - "convert JsString(Hello) to Some(Hello)" in { - JsString("Hello").convertTo[Option[String]] mustEqual Some("Hello") - } - } - - "The eitherFormat" should { - val a: Either[Int, String] = Left(42) - val b: Either[Int, String] = Right("Hello") - - "convert the left side of an Either value to Json" in { - a.toJson mustEqual JsNumber(42) - } - "convert the right side of an Either value to Json" in { - b.toJson mustEqual JsString("Hello") - } - "convert the left side of an Either value from Json" in { - JsNumber(42).convertTo[Either[Int, String]] mustEqual Left(42) - } - "convert the right side of an Either value from Json" in { - JsString("Hello").convertTo[Either[Int, String]] mustEqual Right("Hello") - } - } - - "The tuple1Format" should { - "convert (42) to a JsNumber" in { - Tuple1(42).toJson mustEqual JsNumber(42) - } - "be able to convert a JsNumber to a Tuple1[Int]" in { - JsNumber(42).convertTo[Tuple1[Int]] mustEqual Tuple1(42) - } - } - - "The tuple2Format" should { - val json = JsArray(JsNumber(42), JsNumber(4.2)) - "convert (42, 4.2) to a JsArray" in { - (42, 4.2).toJson mustEqual json - } - "be able to convert a JsArray to a (Int, Double)]" in { - json.convertTo[(Int, Double)] mustEqual ((42, 4.2)) - } - } - - "The tuple3Format" should { - val json = JsArray(JsNumber(42), JsNumber(4.2), JsNumber(3)) - "convert (42, 4.2, 3) to a JsArray" in { - (42, 4.2, 3).toJson mustEqual json - } - "be able to convert a JsArray to a (Int, Double, Int)]" in { - json.convertTo[(Int, Double, Int)] mustEqual ((42, 4.2, 3)) - } - } - "The tuple4Format" should { - val json = JsArray(JsNumber(42), JsNumber(4.2), JsNumber(3), JsNumber(4)) - "convert (42, 4.2, 3, 4) to a JsArray" in { - (42, 4.2, 3, 4).toJson mustEqual json - } - "be able to convert a JsArray to a (Int, Double, Int, Int)]" in { - json.convertTo[(Int, Double, Int, Int)] mustEqual ((42, 4.2, 3, 4)) - } - } - "The tuple5Format" should { - val json = JsArray(JsNumber(42), JsNumber(4.2), JsNumber(3), JsNumber(4), JsNumber(5)) - "convert (42, 4.2, 3, 4, 5) to a JsArray" in { - (42, 4.2, 3, 4, 5).toJson mustEqual json - } - "be able to convert a JsArray to a (Int, Double, Int, Int, Int)]" in { - json.convertTo[(Int, Double, Int, Int, Int)] mustEqual ((42, 4.2, 3, 4, 5)) - } - } - "The tuple6Format" should { - val json = JsArray(JsNumber(42), JsNumber(4.2), JsNumber(3), JsNumber(4), JsNumber(5), JsNumber(6)) - "convert (42, 4.2, 3, 4, 5, 6) to a JsArray" in { - (42, 4.2, 3, 4, 5, 6).toJson mustEqual json - } - "be able to convert a JsArray to a (Int, Double, Int, Int, Int, Int)]" in { - json.convertTo[(Int, Double, Int, Int, Int, Int)] mustEqual ((42, 4.2, 3, 4, 5, 6)) - } - } - "The tuple7Format" should { - val json = JsArray(JsNumber(42), JsNumber(4.2), JsNumber(3), JsNumber(4), JsNumber(5), JsNumber(6), JsNumber(7)) - "convert (42, 4.2, 3, 4, 5, 6, 7) to a JsArray" in { - (42, 4.2, 3, 4, 5, 6, 7).toJson mustEqual json - } - "be able to convert a JsArray to a (Int, Double, Int, Int, Int, Int, Int)]" in { - json.convertTo[(Int, Double, Int, Int, Int, Int, Int)] mustEqual ((42, 4.2, 3, 4, 5, 6, 7)) - } - } -} |