Skip to content

Issue/72 #73

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 17, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
target/
.idea/
.ensime*
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,11 @@ import org.zalando.jsonapi.model.Attribute
import org.zalando.jsonapi.model.implicits.JsonApiObjectValueConversions._

object AttributeConversions {
implicit def convertToStringAttribute(nameString: (String, String)) = Attribute(nameString._1, nameString._2)
implicit def convertToIntAttribute(nameInt: (String, Int)) = Attribute(nameInt._1, nameInt._2)
implicit def convertToLongAttribute(nameLong: (String, Long)) = Attribute(nameLong._1, nameLong._2)
implicit def convertToDoubleAttribute(nameDouble: (String, Double)) = Attribute(nameDouble._1, nameDouble._2)
implicit def convertToFloatAttribute(nameFloat: (String, Float)) = Attribute(nameFloat._1, nameFloat._2)
implicit def convertToBooleanAttribute(nameInt: (String, Boolean)) = Attribute(nameInt._1, nameInt._2)
implicit def convertPairToOptionalAttribute(pair: (String, Option[_])): Option[Attribute] = {
pair._2.map(Attribute(pair._1, _))
}

implicit def convertToOptionalStringAttribute(nameString: (String, Option[String])) = nameString._2.map(nameString._1 -> _:Attribute)
implicit def convertToOptionalIntAttribute(nameInt: (String, Option[Int])) = nameInt._2.map(nameInt._1 -> _:Attribute)
implicit def convertToOptionalLongAttribute(nameLong: (String, Option[Long])) = nameLong._2.map(nameLong._1 -> _:Attribute)
implicit def convertToOptionalDoubleAttribute(nameDouble: (String, Option[Double])) = nameDouble._2.map(nameDouble._1 -> _:Attribute)
implicit def convertToOptionalFloatAttribute(nameFloat: (String, Option[Float])) = nameFloat._2.map(nameFloat._1 -> _:Attribute)
implicit def convertToOptionalBooleanAttribute(nameInt: (String, Option[Boolean])) = nameInt._2.map(nameInt._1 -> _:Attribute)
implicit def convertPairToAttribute(pair: (String, _)): Attribute = {
Attribute(pair._1, pair._2)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,43 @@ package org.zalando.jsonapi.model.implicits

import scala.language.implicitConversions

import org.zalando.jsonapi.model.Attribute
import org.zalando.jsonapi.model.JsonApiObject._

object JsonApiObjectValueConversions {
implicit def convertStringToStringValue(string: String) = StringValue(string)
implicit def convertIntToNumberValue(int: Int) = NumberValue(int)
implicit def convertLongToNumberValue(long: Long) = NumberValue(long)
implicit def convertDoubleToNumberValue(double: Double) = NumberValue(double)
implicit def convertFloatToNumberValue(float: Float) = NumberValue(float)
implicit def convertBooleanToBooleanValue(boolean: Boolean) = BooleanValue(boolean)
implicit def convertAnyToValue(any: Any): Value = {
any match {
case(string: String) ⇒
StringValue(string)
case(int: Int) ⇒
NumberValue(int)
case(long: Long) ⇒
NumberValue(long)
case(double: Double) ⇒
NumberValue(double)
case(float: Float) ⇒
NumberValue(float)
case true ⇒
TrueValue
case false ⇒
FalseValue
case null ⇒
NullValue
case value: Value ⇒
value
case(map: Map[_,_]) ⇒
JsObjectValue(
map.map {
case(name: String, value) ⇒
Attribute(name, convertAnyToValue(value))
case _ ⇒
throw UnconvertibleTypeError("Maps must have string keys to be converted to JsonApiObject Values")
}.toList
)
case(seq: Seq[_]) ⇒
JsArrayValue(seq.map(convertAnyToValue))
case _ ⇒
throw UnconvertibleTypeError(any)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.zalando.jsonapi.model.implicits

case class UnconvertibleTypeError(msg: String) extends Exception(msg)

object UnconvertibleTypeError {
def apply(any: Any): UnconvertibleTypeError = {
UnconvertibleTypeError(s"Can not convert ${any.getClass.getName} to JsonApiObject Value")
}
}
9 changes: 9 additions & 0 deletions src/main/scala/org/zalando/jsonapi/model/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,15 @@ package object model {
*/
case object NullValue extends Value

/**
* An attribute value that is true
*/
val TrueValue = BooleanValue(true)

/**
* An attribute value that is false
*/
val FalseValue = BooleanValue(false)
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,49 @@ import org.zalando.jsonapi.model.implicits.AttributeConversions._
class AttributeConversionsSpec extends WordSpec with Matchers {
"scala tuples" should {
"be converted to string attributes" in {
convertToStringAttribute("name" -> "string") should be(Attribute("name", StringValue("string")))
convertPairToAttribute("name" "string") should be(Attribute("name", StringValue("string")))
}
"be converted to number attributes" in {
convertToIntAttribute("name" -> 42) should be(Attribute("name", NumberValue(42)))
convertToLongAttribute("name" -> 42l) should be(Attribute("name", NumberValue(42)))
convertToFloatAttribute("name" -> 42f) should be(Attribute("name", NumberValue(42)))
convertToDoubleAttribute("name" -> 42d) should be(Attribute("name", NumberValue(42)))
convertPairToAttribute("name" 42) should be(Attribute("name", NumberValue(42)))
convertPairToAttribute("name" 42l) should be(Attribute("name", NumberValue(42)))
convertPairToAttribute("name" 42f) should be(Attribute("name", NumberValue(42)))
convertPairToAttribute("name" 42d) should be(Attribute("name", NumberValue(42)))
}
"be converted to boolean attributes" in {
convertToBooleanAttribute("name" -> true) should be(Attribute("name", BooleanValue(true)))
convertToBooleanAttribute("name" -> false) should be(Attribute("name", BooleanValue(false)))
convertPairToAttribute("name" → true) should be(Attribute("name", TrueValue))
convertPairToAttribute("name" → false) should be(Attribute("name", FalseValue))
}
"be converted to null attributes" in {
convertPairToAttribute(("name" → null)) should be(Attribute("name", NullValue))
}
"be converted to js object attributes" in {
convertPairToAttribute(("name" → Map("null" → null))) should be(Attribute("name", JsObjectValue(List(Attribute("null", NullValue)))))
}
"be converted to js array attributes" in {
convertPairToAttribute(("name" → List(null))) should be(Attribute("name", JsArrayValue(List(NullValue))))
}

"be converted to optional string attributes" in {
convertToOptionalStringAttribute("name" -> Option("string")) should be(Option(Attribute("name", StringValue("string"))))
convertPairToOptionalAttribute("name" Option("string")) should be(Option(Attribute("name", StringValue("string"))))
}
"be converted to optional number attributes" in {
convertToOptionalIntAttribute("name" -> Option(42)) should be(Option(Attribute("name", NumberValue(42))))
convertToOptionalLongAttribute("name" -> Option(42l)) should be(Option(Attribute("name", NumberValue(42))))
convertToOptionalFloatAttribute("name" -> Option(42f)) should be(Option(Attribute("name", NumberValue(42))))
convertToOptionalDoubleAttribute("name" -> Option(42d)) should be(Option(Attribute("name", NumberValue(42))))
convertPairToOptionalAttribute("name" Option(42)) should be(Option(Attribute("name", NumberValue(42))))
convertPairToOptionalAttribute("name" Option(42l)) should be(Option(Attribute("name", NumberValue(42))))
convertPairToOptionalAttribute("name" Option(42f)) should be(Option(Attribute("name", NumberValue(42))))
convertPairToOptionalAttribute("name" Option(42d)) should be(Option(Attribute("name", NumberValue(42))))
}
"be converted to optional boolean attributes" in {
convertToOptionalBooleanAttribute("name" -> Option(true)) should be(Option(Attribute("name", BooleanValue(true))))
convertToOptionalBooleanAttribute("name" -> Option(false)) should be(Option(Attribute("name", BooleanValue(false))))
convertPairToOptionalAttribute("name" → Option(true)) should be(Option(Attribute("name", BooleanValue(true))))
convertPairToOptionalAttribute("name" → Option(false)) should be(Option(Attribute("name", BooleanValue(false))))
}
"be converted to optional null attributes" in {
convertPairToOptionalAttribute(("name" → Option(null))) should be(None)
}
"be converted to optional js object attributes" in {
convertPairToOptionalAttribute(("name" → Option(Map("null" → null)))) should be(Option(Attribute("name", JsObjectValue(List(Attribute("null", NullValue))))))
}
"be converted to optional js array attributes" in {
convertPairToOptionalAttribute(("name" → Option(List(null)))) should be(Option(Attribute("name", JsArrayValue(List(NullValue)))))
}
}
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,65 @@

package org.zalando.jsonapi.model.implicits

import org.scalatest.{Matchers, WordSpec}
import org.zalando.jsonapi.model.Attribute
import org.zalando.jsonapi.model.JsonApiObject._
import org.zalando.jsonapi.model.implicits.JsonApiObjectValueConversions._

class JsonApiObjectValueConversionsSpec extends WordSpec with Matchers {
"scala values" should {
"be converted to string values" in {
convertStringToStringValue("string") should be(StringValue("string"))
convertAnyToValue("string") should be(StringValue("string"))
}
"be converted to number values" in {
convertIntToNumberValue(42) should be(NumberValue(42))
convertLongToNumberValue(42l) should be(NumberValue(42))
convertFloatToNumberValue(42f) should be(NumberValue(42))
convertDoubleToNumberValue(42d) should be(NumberValue(42))
convertAnyToValue(42) should be(NumberValue(42))
convertAnyToValue(42l) should be(NumberValue(42))
convertAnyToValue(42f) should be(NumberValue(42))
convertAnyToValue(42d) should be(NumberValue(42))
}
"be converted to boolean values" in {
convertBooleanToBooleanValue(true) should be(BooleanValue(true))
convertBooleanToBooleanValue(false) should be(BooleanValue(false))
convertAnyToValue(true) should be(TrueValue)
convertAnyToValue(false) should be(FalseValue)
}
"be converted to js array values" in {
convertAnyToValue(Seq("one", 2, Map("3" → 4d), false, null)) should be(JsArrayValue(List(
StringValue("one"),
NumberValue(2),
JsObjectValue(List(Attribute("3", NumberValue(4d)))),
FalseValue,
NullValue
)))
}
"be converted to js object values" in {
convertAnyToValue(Map(
"one" → 2,
"3" → List(4f, true, null)
)) should be(JsObjectValue(List(
Attribute("one", NumberValue(2)),
Attribute("3", JsArrayValue(List(
NumberValue(4f),
TrueValue,
NullValue
)))
)))
}
"be converted to null values" in {
convertAnyToValue(null) should be(NullValue)
}
"be left alone" in {
for {
value ← Seq(NullValue, TrueValue, FalseValue, StringValue("value"), NumberValue(1))
} {
convertAnyToValue(value) should be (value)
}
}
"throw an error for unconvertible types" in {
the[UnconvertibleTypeError] thrownBy {
convertAnyToValue(Map(1 → 2))
} should have message "Maps must have string keys to be converted to JsonApiObject Values"

the[UnconvertibleTypeError] thrownBy {
convertAnyToValue(new java.util.Date)
} should have message "Can not convert java.util.Date to JsonApiObject Value"
}
}
}