diff options
author | Johannes Rudolph <johannes.rudolph@gmail.com> | 2014-03-12 16:21:55 +0100 |
---|---|---|
committer | Johannes Rudolph <johannes.rudolph@gmail.com> | 2014-03-12 16:21:55 +0100 |
commit | 5ccc9d5e47fd71ca0bdf7097bc5f9c76404c1916 (patch) | |
tree | 63e0c06f811e751daf676c5979b1272963c82732 /src/test/scala/spray/json | |
parent | df6863a973b1a2ded68e07eddbb9a2baa8daf169 (diff) | |
download | spray-json-5ccc9d5e47fd71ca0bdf7097bc5f9c76404c1916.tar.gz spray-json-5ccc9d5e47fd71ca0bdf7097bc5f9c76404c1916.tar.bz2 spray-json-5ccc9d5e47fd71ca0bdf7097bc5f9c76404c1916.zip |
Add some scalachecks roundtrips for more confidence, fixes #29
Diffstat (limited to 'src/test/scala/spray/json')
-rw-r--r-- | src/test/scala/spray/json/RoundTripSpecs.scala | 63 |
1 files changed, 63 insertions, 0 deletions
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 + } + } +} |