-
Notifications
You must be signed in to change notification settings - Fork 149
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
284 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,12 @@ | ||
sudo: false | ||
language: scala | ||
jdk: | ||
- openjdk6 | ||
- openjdk7 | ||
- oraclejdk7 | ||
- oraclejdk8 | ||
scala: | ||
- 2.11.4 | ||
- 2.11.5 | ||
- 2.10.4 | ||
script: "sbt clean coverage test" | ||
after_success: "sbt coveralls" |
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package enumeratum | ||
|
||
import play.api.data.format.Formatter | ||
import play.api.data.{ FormError, Forms => PlayForms, Mapping } | ||
|
||
/** | ||
* Created by Lloyd on 2/3/15. | ||
*/ | ||
object Forms { | ||
|
||
/** | ||
* Returns an [[Enum]] mapping | ||
*/ | ||
def maps[A](enum: Enum[A]): Mapping[A] = PlayForms.of(format(enum)) | ||
|
||
/** | ||
* Returns a Formatter for [[Enum]] | ||
*/ | ||
def format[A](enum: Enum[A]): Formatter[A] = new Formatter[A] { | ||
def bind(key: String, data: Map[String, String]) = { | ||
play.api.data.format.Formats.stringFormat.bind(key, data).right.flatMap { s => | ||
scala.util.control.Exception.allCatch[A] | ||
.either(enum.withName(s)) | ||
.left.map(e => Seq(FormError(key, "error.enum", Nil))) | ||
} | ||
} | ||
def unbind(key: String, value: A) = Map(key -> value.toString) | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package enumeratum | ||
|
||
import play.api.libs.json._ | ||
|
||
import scala.util.control.NonFatal | ||
|
||
/** | ||
* Holds JSON reads and writes for [[enumeratum.Enum]] | ||
*/ | ||
object Json { | ||
|
||
/** | ||
* Returns an Json Reads for a given enum [[Enum]] | ||
*/ | ||
def reads[A](enum: Enum[A]): Reads[A] = new Reads[A] { | ||
def reads(json: JsValue): JsResult[A] = json match { | ||
case JsString(s) => { | ||
try { | ||
JsSuccess(enum.withName(s)) | ||
} catch { | ||
case NonFatal(e) => JsError(s"Enumeration expected of type: '$enum', but it does not appear to contain the value: '$s'") | ||
} | ||
} | ||
case _ => JsError("String value expected") | ||
} | ||
} | ||
|
||
/** | ||
* Returns a Json writes for a given enum [[Enum]] | ||
*/ | ||
def writes[A](enum: Enum[A]): Writes[A] = new Writes[A] { | ||
def writes(v: A): JsValue = JsString(v.toString) | ||
} | ||
|
||
/** | ||
* Returns a Json format for a given enum [[Enum]] | ||
*/ | ||
def enumFormat[A](enum: Enum[A]): Format[A] = { | ||
Format(reads(enum), writes(enum)) | ||
} | ||
|
||
} |
36 changes: 36 additions & 0 deletions
36
enumeratum-play/src/main/scala/enumeratum/UrlBinders.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package enumeratum | ||
|
||
import play.api.mvc.PathBindable | ||
import play.api.mvc.QueryStringBindable | ||
import play.api.mvc.QueryStringBindable._ | ||
|
||
import scala.util.Try | ||
|
||
/** | ||
* Created by Lloyd on 2/3/15. | ||
*/ | ||
object UrlBinders { | ||
|
||
/** | ||
* Builds a [[PathBindable]] A for a given Enum A | ||
*/ | ||
def pathBinder[A](enum: Enum[A]): PathBindable[A] = new PathBindable[A] { | ||
def unbind(key: String, value: A): String = value.toString | ||
def bind(key: String, value: String): Either[String, A] = { | ||
Try(enum.withName(value)).toOption match { | ||
case Some(v) => Right(v) | ||
case _ => Left(s"Unknown value supplied for $enum '" + value + "'") | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Builds a [[QueryStringBindable]] A for a given Enum A | ||
*/ | ||
def queryBinder[A](enum: Enum[A]): QueryStringBindable[A] = new Parsing[A]( | ||
enum.withName, | ||
_.toString, | ||
(key, exception) => "Cannot parse parameter %s as an Enum: %s".format(key, exception.getMessage) | ||
) | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package enumeratum | ||
|
||
import org.scalatest._ | ||
|
||
/** | ||
* Created by Lloyd on 2/3/15. | ||
*/ | ||
class FormSpec extends FunSpec with Matchers { | ||
|
||
import Forms._ | ||
|
||
sealed trait DummyEnum | ||
|
||
object DummyEnum extends Enum[DummyEnum] { | ||
case object A extends DummyEnum | ||
case object B extends DummyEnum | ||
val values = findValues | ||
} | ||
|
||
describe("binder from #enumFormat") { | ||
|
||
val subject = format(DummyEnum) | ||
|
||
it("should bind proper strings into an Enum value") { | ||
val r1 = subject.bind("hello", Map("hello" -> "A")) | ||
val r2 = subject.bind("hello", Map("hello" -> "B")) | ||
r1 shouldBe Right(DummyEnum.A) | ||
r2 shouldBe Right(DummyEnum.B) | ||
} | ||
|
||
it("should fail to bind random strings") { | ||
val r = subject.bind("hello", Map("hello" -> "AARSE")) | ||
r should be('left) | ||
} | ||
|
||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package enumeratum | ||
|
||
import org.scalatest.{ Matchers, FunSpec } | ||
import play.api.libs.json.{ JsNumber, JsString } | ||
|
||
class JsonSpec extends FunSpec with Matchers { | ||
|
||
sealed trait DummyEnum | ||
object DummyEnum extends Enum[DummyEnum] { | ||
case object A extends DummyEnum | ||
case object B extends DummyEnum | ||
case object C extends DummyEnum | ||
val values = findValues | ||
} | ||
|
||
describe(".enumReads") { | ||
val reads = Json.reads(DummyEnum) | ||
|
||
it("should create a reads that works with valid values") { | ||
reads.reads(JsString("A")).get should be(DummyEnum.A) | ||
} | ||
|
||
it("should create a reads that fails with invalid values") { | ||
reads.reads(JsString("D")).isError should be(true) | ||
reads.reads(JsNumber(2)).isError should be(true) | ||
} | ||
} | ||
|
||
describe(".enumWrites") { | ||
val writer = Json.writes(DummyEnum) | ||
|
||
it("should create a writes that writes enum values to JsString") { | ||
writer.writes(DummyEnum.A) should be(JsString("A")) | ||
} | ||
} | ||
|
||
describe(".enumFormat") { | ||
val format = Json.enumFormat(DummyEnum) | ||
|
||
it("should create a format that works with valid values") { | ||
format.reads(JsString("A")).get should be(DummyEnum.A) | ||
} | ||
|
||
it("should create a format that fails with invalid values") { | ||
format.reads(JsString("D")).isError should be(true) | ||
format.reads(JsNumber(2)).isError should be(true) | ||
} | ||
|
||
it("should create a format that writes enum values to JsString") { | ||
format.writes(DummyEnum.A) should be(JsString("A")) | ||
} | ||
} | ||
|
||
} |
58 changes: 58 additions & 0 deletions
58
enumeratum-play/src/test/scala/enumeratum/UrlBindersSpec.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package enumeratum | ||
|
||
import UrlBinders._ | ||
import org.scalatest._ | ||
|
||
/** | ||
* Created by Lloyd on 2/3/15. | ||
*/ | ||
class UrlBindersSpec extends FunSpec with Matchers { | ||
|
||
sealed trait Dummy | ||
object Dummy extends Enum[Dummy] { | ||
case object A extends Dummy | ||
case object B extends Dummy | ||
case object C extends Dummy | ||
val values = findValues | ||
} | ||
|
||
describe(".pathBinder") { | ||
|
||
val subject = pathBinder(Dummy) | ||
|
||
it("should create an enumeration binder that can bind strings corresponding to enum strings") { | ||
subject.bind("hello", "A").right.get shouldBe Dummy.A | ||
} | ||
|
||
it("should create an enumeration binder that cannot bind strings not found in the enumeration") { | ||
subject.bind("hello", "Z").isLeft shouldBe true | ||
} | ||
|
||
it("should create an enumeration binder that can unbind values") { | ||
subject.unbind("hello", Dummy.A) shouldBe "A" | ||
subject.unbind("hello", Dummy.B) shouldBe "B" | ||
} | ||
|
||
} | ||
|
||
describe(".queryBinder") { | ||
|
||
val subject = queryBinder(Dummy) | ||
|
||
it("should create an enumeration binder that can bind strings corresponding to enum strings regardless of case") { | ||
subject.bind("hello", Map("hello" -> Seq("A"))).get.right.get should be(Dummy.A) | ||
} | ||
|
||
it("should create an enumeration binder that cannot bind strings not found in the enumeration") { | ||
subject.bind("hello", Map("hello" -> Seq("Z"))).get should be('left) | ||
subject.bind("hello", Map("helloz" -> Seq("A"))) shouldBe None | ||
} | ||
|
||
it("should create an enumeration binder that can unbind values") { | ||
subject.unbind("hello", Dummy.A) should be("hello=A") | ||
subject.unbind("hello", Dummy.B) should be("hello=B") | ||
} | ||
|
||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters