@@ -2,113 +2,142 @@ package enumeratum
2
2
3
3
import org .scalatest .OptionValues ._
4
4
import org .scalatest .{ FunSpec , Matchers }
5
- import play .api .libs .json .{ JsNumber , JsResult , JsString }
5
+ import play .api .libs .json ._
6
6
7
7
class EnumFormatsSpec extends FunSpec with Matchers {
8
8
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
+ )
31
70
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)
38
83
}
39
84
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
+ )
50
100
}
51
- }
52
-
53
- describe(" reads upper case" ) {
54
- val reads = EnumFormats .readsUppercaseOnly(Dummy )
55
101
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
+ }
58
107
}
59
108
60
109
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
+ }
63
116
}
64
117
}
65
118
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" ) {
69
123
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
+ }
79
128
}
80
129
}
81
130
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)
88
142
}
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