From 5ccc9d5e47fd71ca0bdf7097bc5f9c76404c1916 Mon Sep 17 00:00:00 2001 From: Johannes Rudolph Date: Wed, 12 Mar 2014 16:21:55 +0100 Subject: Add some scalachecks roundtrips for more confidence, fixes #29 --- src/test/scala/spray/json/RoundTripSpecs.scala | 63 ++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 src/test/scala/spray/json/RoundTripSpecs.scala (limited to 'src') diff --git a/src/test/scala/spray/json/RoundTripSpecs.scala b/src/test/scala/spray/json/RoundTripSpecs.scala new file mode 100644 index 0000000..51df48d --- /dev/null +++ b/src/test/scala/spray/json/RoundTripSpecs.scala @@ -0,0 +1,63 @@ +package spray.json + +import org.specs2.mutable.Specification +import org.scalacheck._ +import org.specs2.matcher.ScalaCheckMatchers + +object JsValueGenerators { + import Gen._ + import Arbitrary.arbitrary + + // some characters have special meaning in parboiled + // see org.parboiled.support.Chars, we have to exclude those + val parseableString: Gen[String] = arbitrary[String].map(_.filterNot(_ > 0xfd00)) + 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) + 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 ScalaCheckMatchers { + 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 + } + } +} -- cgit v1.2.3