diff options
author | Johannes Rudolph <johannes_rudolph@gmx.de> | 2012-05-29 15:33:52 +0200 |
---|---|---|
committer | Johannes Rudolph <johannes_rudolph@gmx.de> | 2012-05-29 15:33:52 +0200 |
commit | 5aa2dff8b2559e7b90c189994cf004da6263b024 (patch) | |
tree | 56a0ab4235f386867141751a20301eadbdc03bce /src | |
parent | e3384ed05ff9d9f1ad26ef3c95bd9f4decf2da17 (diff) | |
download | spray-json-5aa2dff8b2559e7b90c189994cf004da6263b024.tar.gz spray-json-5aa2dff8b2559e7b90c189994cf004da6263b024.tar.bz2 spray-json-5aa2dff8b2559e7b90c189994cf004da6263b024.zip |
more error conditions checked and properly handled
Diffstat (limited to 'src')
-rw-r--r-- | src/main/scala/cc/spray/json/JsonLenses.scala | 24 | ||||
-rw-r--r-- | src/test/scala/cc/spray/json/JsonLensesSpec.scala | 64 |
2 files changed, 63 insertions, 25 deletions
diff --git a/src/main/scala/cc/spray/json/JsonLenses.scala b/src/main/scala/cc/spray/json/JsonLenses.scala index e90b51c..e5efff6 100644 --- a/src/main/scala/cc/spray/json/JsonLenses.scala +++ b/src/main/scala/cc/spray/json/JsonLenses.scala @@ -10,6 +10,14 @@ object JsonLenses { implicit def rightBiasEither[A, B](e: Either[A, B]): Either.RightProjection[A, B] = e.right + case class GetOrThrow[B](e: Either[Throwable, B]) { + def getOrThrow: B = e match { + case Right(b) => b + case Left(e) => throw e + } + } + implicit def orThrow[B](e: Either[Throwable, B]): GetOrThrow[B] = GetOrThrow(e) + trait MonadicReader[T] { def read(js: JsValue): Validated[T] } @@ -116,15 +124,11 @@ object JsonLenses { p => retr(p).flatMap(mapValue(_)(_.as[T])) def get[T: MonadicReader]: JsValue => M[T] = - p => getSecure[T].apply(p) match { - case Right(e) => e - case Left(e) => - throw e - } + p => getSecure[T].apply(p).getOrThrow def ![U](op: Operation): Update = new Update { def apply(parent: JsValue): JsValue = - updated(op(_))(parent).get + updated(op(_))(parent).getOrThrow } } @@ -175,7 +179,7 @@ object JsonLenses { def retr: JsValue => SafeJsValue = v => getField(v).flatMap { - _.map(Right(_)).getOrElse(Left(new IllegalArgumentException("Missing field '%s' in '%s'" format (name, v)))) + _.map(Right(_)).getOrElse(Left(new IllegalArgumentException("Expected field '%s' in '%s'" format (name, v)))) } def getField(v: JsValue): Validated[Option[JsValue]] = asObj(v) map { o => @@ -243,8 +247,6 @@ object JsonLenses { } } - def filter(pred: JsPred): SeqProjection = ??? - def set[T: JsonWriter](t: T): Operation = new Operation { def apply(value: Option[JsValue]): SafeJsValue = Right(jsonWriter[T].write(t)) @@ -255,7 +257,7 @@ object JsonLenses { def apply(value: Option[JsValue]): SafeJsValue = value match { case Some(x) => apply(x) - case None => Left(new IllegalArgumentException("Need a value operate on")) + case None => Left(new IllegalArgumentException("Need a value to operate on")) } } @@ -264,8 +266,8 @@ object JsonLenses { value.as[T] map (v => jsonWriter[T].write(f(v))) } + def filter(pred: JsPred): SeqProjection = ??? def append(update: Update): Operation = ??? - def update(update: Update): Operation = ??? def extract[M[_], T](value: Projection[M])(f: M[T] => Update): Operation = ??? diff --git a/src/test/scala/cc/spray/json/JsonLensesSpec.scala b/src/test/scala/cc/spray/json/JsonLensesSpec.scala index 85e10e3..d1df898 100644 --- a/src/test/scala/cc/spray/json/JsonLensesSpec.scala +++ b/src/test/scala/cc/spray/json/JsonLensesSpec.scala @@ -3,6 +3,8 @@ package cc.spray.json import DefaultJsonProtocol._ import org.specs2.mutable.Specification +import org.specs2.matcher.{BeMatching, Matcher} +import java.util.regex.Pattern class JsonLensesSpec extends Specification { val json = JsonParser( @@ -28,7 +30,15 @@ class JsonLensesSpec extends Specification { "Lenses" should { "access" in { "field" in { - json extract "n".get[Int] must be_==(2) + "existing" in { + json extract "n".get[Int] must be_==(2) + } + "missing" in { + json extract "z".get[Int] must throwAn[IllegalArgumentException]("""Expected field 'z' in '{"n":2,"els":[{"name":"John","money":23},{"name":"Paul","money":42}]}'""") + } + "wrong type" in { + json extract "n".get[String] must throwA[DeserializationException]("Expected String as JsString, but got 2") + } } "field of member" in { val json = JsonParser("""{"n": {"b": 4}}""") @@ -36,9 +46,16 @@ class JsonLensesSpec extends Specification { json extract ("n" / "b").get[Int] must be_==(4) } "element of array" in { - val json = JsonParser("""["a", "b", 2, 5, 8, 3]""") + "existing" in { + val json = JsonParser("""["a", "b", 2, 5, 8, 3]""") + + json extract element(3).get[Int] must be_==(5) + } + "out of bounds" in { + val json = JsonParser("""["a", "b", 2, 5, 8, 3]""") - json extract element(3).get[Int] must be_==(5) + json extract element(38).get[Int] must throwAn[IndexOutOfBoundsException]("Too little elements in array: [\"a\",\"b\",2,5,8,3] size: 6 index: 38") + } } "finding an element" in { "in a homogenous array" in { @@ -62,28 +79,43 @@ class JsonLensesSpec extends Specification { "modify" in { "set field" in { - val simple = JsonParser( """{"n": 12}""") + "existing" in { + val simple = JsonParser( """{"n": 12}""") - simple.update(n ! set(23)) must be_json( """{"n": 23}""") + simple.update(n ! set(23)) must be_json( """{"n": 23}""") + } + "missing" in { + val json = JsonParser( """{"n": {"b": 4}}""") + + json update ("n" / "c" ! set(23)) must be_json( """{"n": {"b": 4, "c": 23}}""") + } } "update field" in { - val simple = JsonParser( """{"n": 12}""") - simple.update(n ! updated[Int](_ + 1)) must be_json( """{"n": 13}""") + "existing" in { + val simple = JsonParser( """{"n": 12}""") + simple.update(n ! updated[Int](_ + 1)) must be_json( """{"n": 13}""") + } + "wrong type" in { + val simple = JsonParser( """{"n": 12}""") + simple.update(n ! updated[String](_ + "test")) must throwA[DeserializationException]("Expected String as JsString, but got 12") + } + "missing" in { + val simple = JsonParser( """{"n": 12}""") + simple.update(field("z") ! updated[Int](_ + 1)) must throwAn[IllegalArgumentException]("Need a value to operate on") + } } "set field of member" in { val json = JsonParser( """{"n": {"b": 4}}""") json update ("n" / "b" ! set(23)) must be_json( """{"n": {"b": 23}}""") } - "create field of member" in { - val json = JsonParser( """{"n": {"b": 4}}""") - - json update ("n" / "c" ! set(23)) must be_json( """{"n": {"b": 4, "c": 23}}""") - } "update field of member" in { - val json = JsonParser( """{"n": {"b": 4}}""") + "existing" in { + val json = JsonParser( """{"n": {"b": 4}}""") + + json update ("n" / "b" ! updated[Int](1 +)) must be_json( """{"n": {"b": 5}}""") + } - json update ("n" / "b" ! updated[Int](1 +)) must be_json( """{"n": {"b": 5}}""") } "set element of array" in { val json = JsonParser("""["a", "b", 2, 5, 8, 3]""") @@ -116,4 +148,8 @@ class JsonLensesSpec extends Specification { def be_json(json: String) = be_==(JsonParser(json)) + + override def throwA[E <: Throwable](message: String = ".*")(implicit m: ClassManifest[E]): Matcher[Any] = { + throwA(m).like { case e => createExpectable(e.getMessage).applyMatcher(new BeMatching(".*"+Pattern.quote(message)+".*")) } + } } |