summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohannes Rudolph <johannes_rudolph@gmx.de>2012-05-29 15:33:52 +0200
committerJohannes Rudolph <johannes_rudolph@gmx.de>2012-05-29 15:33:52 +0200
commit5aa2dff8b2559e7b90c189994cf004da6263b024 (patch)
tree56a0ab4235f386867141751a20301eadbdc03bce /src
parente3384ed05ff9d9f1ad26ef3c95bd9f4decf2da17 (diff)
downloadspray-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.scala24
-rw-r--r--src/test/scala/cc/spray/json/JsonLensesSpec.scala64
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)+".*")) }
+ }
}