@@ -2,113 +2,142 @@ package enumeratum
22
33import org .scalatest .OptionValues ._
44import org .scalatest .{ FunSpec , Matchers }
5- import play .api .libs .json .{ JsNumber , JsResult , JsString }
5+ import play .api .libs .json ._
66
77class EnumFormatsSpec extends FunSpec with Matchers {
88
9- describe(" reads" ) {
10- val reads = EnumFormats .reads(Dummy )
11-
12- it(" should create a reads that works with valid values" ) {
13- reads.reads(JsString (" A" )).asOpt.value should be(Dummy .A )
14- }
15-
16- it(" should create a reads that fails with invalid values" ) {
17- reads.reads(JsString (" D" )).isError should be(true )
18- errorMessages(reads.reads(JsString (" D" ))) should be(Seq (" error.expected.validenumvalue" ))
19- reads.reads(JsNumber (2 )).isError should be(true )
20- errorMessages(reads.reads(JsNumber (2 ))) should be(Seq (" error.expected.enumstring" ))
21- }
22- }
23-
24- describe(" reads insensitive" ) {
25- val reads = EnumFormats .reads(Dummy , true )
26-
27- it(" should create a reads that works with valid values disregarding case" ) {
28- reads.reads(JsString (" A" )).asOpt.value should be(Dummy .A )
29- reads.reads(JsString (" a" )).asOpt.value should be(Dummy .A )
30- }
9+ testScenario(
10+ descriptor = " normal operation" ,
11+ reads = EnumFormats .reads(Dummy ),
12+ readSuccessExpectations = Map (" A" -> Dummy .A ),
13+ readErrors = Map (" C" -> Seq (" error.expected.validenumvalue" )),
14+ writes = EnumFormats .writes(Dummy ),
15+ writeExpectations = Map (Dummy .A -> " A" ),
16+ formats = EnumFormats .formats(Dummy )
17+ )
18+
19+ testScenario(
20+ descriptor = " case insensitive" ,
21+ reads = EnumFormats .reads(enum = Dummy , insensitive = true ),
22+ readSuccessExpectations = Map (
23+ " A" -> Dummy .A ,
24+ " a" -> Dummy .A
25+ ),
26+ readErrors = Map .empty,
27+ writes = EnumFormats .writes(Dummy ),
28+ writeExpectations = Map (Dummy .A -> " A" ),
29+ formats = EnumFormats .formats(enum = Dummy , insensitive = true )
30+ )
31+
32+ testScenario(
33+ descriptor = " lower case transformed" ,
34+ reads = EnumFormats .readsLowercaseOnly(Dummy ),
35+ readSuccessExpectations = Map (
36+ " a" -> Dummy .A
37+ ),
38+ readErrors = Map (
39+ " A" -> Seq (" error.expected.validenumvalue" )
40+ ),
41+ writes = EnumFormats .writesLowercaseOnly(Dummy ),
42+ writeExpectations = Map (Dummy .A -> " a" ),
43+ formats = EnumFormats .formatsLowerCaseOnly(Dummy )
44+ )
45+
46+ testScenario(
47+ descriptor = " upper case transformed" ,
48+ reads = EnumFormats .readsUppercaseOnly(Dummy ),
49+ readSuccessExpectations = Map (
50+ " A" -> Dummy .A ,
51+ " C" -> Dummy .c
52+ ),
53+ readErrors = Map (
54+ " a" -> Seq (" error.expected.validenumvalue" )
55+ ),
56+ writes = EnumFormats .writesUppercaseOnly(Dummy ),
57+ writeExpectations = Map (Dummy .A -> " A" ),
58+ formats = EnumFormats .formatsUppercaseOnly(Dummy )
59+ )
60+
61+ // Bunch of shared testing methods
62+
63+ private def errorMessages (jsResult : JsResult [_]): Seq [String ] =
64+ jsResult.fold(
65+ _.collect {
66+ case (path, errors) => errors.map(_.message).mkString
67+ },
68+ _ => Seq .empty
69+ )
3170
32- it(" should create a reads that fails with invalid values" ) {
33- reads.reads(JsString (" D" )).isError should be(true )
34- errorMessages(reads.reads(JsString (" D" ))) should be(Seq (" error.expected.validenumvalue" ))
35- reads.reads(JsNumber (2 )).isError should be(true )
36- errorMessages(reads.reads(JsNumber (2 ))) should be(Seq (" error.expected.enumstring" ))
37- }
71+ private def testScenario (
72+ descriptor : String ,
73+ reads : Reads [Dummy ],
74+ readSuccessExpectations : Map [String , Dummy ],
75+ readErrors : Map [String , Seq [String ]],
76+ writes : Writes [Dummy ],
77+ writeExpectations : Map [Dummy , String ],
78+ formats : Format [Dummy ]
79+ ): Unit = describe(descriptor) {
80+ testReads(reads, readSuccessExpectations, readErrors)
81+ testWrites(writes, writeExpectations)
82+ testFormats(formats, readSuccessExpectations, readErrors, writeExpectations)
3883 }
3984
40- describe(" reads lower case" ) {
41- val reads = EnumFormats .readsLowercaseOnly(Dummy )
42-
43- it(" should create a reads that works with valid values that are lower case" ) {
44- reads.reads(JsString (" a" )).asOpt.value should be(Dummy .A )
45- }
46-
47- it(" should create a reads that fails with invalid values" ) {
48- reads.reads(JsString (" A" )).isError should be(true )
49- errorMessages(reads.reads(JsString (" A" ))) should be(Seq (" error.expected.validenumvalue" ))
85+ /**
86+ * Shared scenarios for testing Reads
87+ */
88+ private def testReads (
89+ reads : Reads [Dummy ],
90+ expectedSuccesses : Map [String , Dummy ],
91+ expectedErrors : Map [String , Seq [String ]]
92+ ): Unit = describe(" Reads" ) {
93+ val expectedFails : Map [JsValue , Seq [String ]] = {
94+ val withJsValueKeys = expectedErrors.map { case (k, v) => JsString (k) -> v }
95+ // Add standard errors
96+ withJsValueKeys ++ Map (
97+ JsNumber (2 ) -> Seq (" error.expected.enumstring" ),
98+ JsString (" D" ) -> Seq (" error.expected.validenumvalue" )
99+ )
50100 }
51- }
52-
53- describe(" reads upper case" ) {
54- val reads = EnumFormats .readsUppercaseOnly(Dummy )
55101
56- it(" should create a reads that works with valid values that are lower case" ) {
57- reads.reads(JsString (" A" )).asOpt.value should be(Dummy .A )
102+ it(" should create a reads that works with valid values" ) {
103+ expectedSuccesses.foreach {
104+ case (name, expected) =>
105+ reads.reads(JsString (name)).asOpt.value should be(expected)
106+ }
58107 }
59108
60109 it(" should create a reads that fails with invalid values" ) {
61- reads.reads(JsString (" a" )).isError should be(true )
62- errorMessages(reads.reads(JsString (" a" ))) should be(Seq (" error.expected.validenumvalue" ))
110+ expectedFails.foreach {
111+ case (k, v) =>
112+ val result = reads.reads(k)
113+ result.isError shouldBe true
114+ errorMessages(result) shouldBe v
115+ }
63116 }
64117 }
65118
66- describe(" writes" ) {
67- val writer = EnumFormats .writes(Dummy )
68-
119+ /**
120+ * Shared scenarios for testing Writes
121+ */
122+ private def testWrites (writer : Writes [Dummy ], expectations : Map [Dummy , String ]): Unit = describe(" Writes" ) {
69123 it(" should create a writes that writes enum values to JsString" ) {
70- writer.writes(Dummy .A ) should be(JsString (" A" ))
71- }
72- }
73-
74- describe(" writes lower case" ) {
75- val writer = EnumFormats .writesLowercaseOnly(Dummy )
76-
77- it(" should create a writes that writes enum values to JsString as lower case" ) {
78- writer.writes(Dummy .A ) should be(JsString (" a" ))
124+ expectations.foreach {
125+ case (k, v) =>
126+ writer.writes(k) should be(JsString (v))
127+ }
79128 }
80129 }
81130
82- describe(" writes upper case" ) {
83- val writer = EnumFormats .writesUppercaseOnly(Dummy )
84-
85- it(" should create a writes that writes enum values to JsString as upper case" ) {
86- writer.writes(Dummy .A ) should be(JsString (" A" ))
87- }
131+ /**
132+ * Shared scenarios for testing Formats
133+ */
134+ private def testFormats (
135+ formats : Format [Dummy ],
136+ expectedReadSuccesses : Map [String , Dummy ],
137+ expectedReadErrors : Map [String , Seq [String ]],
138+ expectedWrites : Map [Dummy , String ]
139+ ): Unit = describe(" Formats" ) {
140+ testReads(formats, expectedReadSuccesses, expectedReadErrors)
141+ testWrites(formats, expectedWrites)
88142 }
89-
90- describe(" formats" ) {
91- val format = EnumFormats .formats(Dummy )
92-
93- it(" should create a format that works with valid values" ) {
94- format.reads(JsString (" A" )).asOpt.value should be(Dummy .A )
95- }
96-
97- it(" should create a format that fails with invalid values" ) {
98- format.reads(JsString (" D" )).isError should be(true )
99- format.reads(JsNumber (2 )).isError should be(true )
100- }
101-
102- it(" should create a format that writes enum values to JsString" ) {
103- format.writes(Dummy .A ) should be(JsString (" A" ))
104- }
105- }
106-
107- def errorMessages (jsResult : JsResult [_]): Seq [String ] =
108- jsResult.fold(
109- _.collect {
110- case (path, errors) => errors.map(_.message).mkString
111- },
112- _ => Seq .empty
113- )
114- }
143+ }
0 commit comments