3
import org.specs2.mutable.Specification
6
import java.sql.Timestamp
7
import org.json4s.scalap.scalasig.ClassSymbol
9
case class RRSimple(id: Int, name: String, items: List[String], createdAt: Date)
10
case class RRSimpleJoda(id: Int, name: String, items: List[String], createdAt: DateTime)
11
case class RROption(id: Int, name: String, status: Option[String], code: Option[Int], createdAt: Date, deletedAt: Option[Date])
12
case class RRTypeParam[T](id: Int, name: String, value: T, opt: Option[T], seq: Seq[T], map: Map[String, T])
13
case class Response(data: List[Map[String, Int]])
14
case class NestedType(dat: List[Map[Double, Option[Int]]], lis: List[List[List[List[List[Int]]]]])
15
case class NestedType3(dat: List[Map[Double, Option[List[Option[Int]]]]], lis: List[List[List[List[List[Int]]]]])
16
case class NestedType4(dat: List[Map[Double, Option[List[Map[Long, Option[Int]]]]]], lis: List[List[List[List[List[Int]]]]])
17
case class NestedType5(dat: List[Map[Double, Option[List[Map[Long, Option[Map[Byte, Either[Double, Long]]]]]]]], lis: List[List[List[List[List[Int]]]]])
18
case class NestedResType[T, S, V <: Option[S]](t: T, v: V, dat: List[Map[T, V]], lis: List[List[List[List[List[S]]]]])
24
case class FromTrait(name: String)
25
case class FromTraitRROption(id: Int, name: String, status: Option[String], code: Option[Int], createdAt: Date, deletedAt: Option[Date])
26
// case class FromTraitRRTypeParam[T](id: Int, name: String, value: T, opt: Option[T], seq: Seq[T], map: Map[String, T])
30
object HasTrait extends WithCaseClass {
31
def descr = Reflector.describe[FromTrait]
33
class ContainsCaseClass {
34
case class InternalType(name: String)
36
def methodWithCaseClass = {
37
case class InMethod(name: String)
38
implicit val formats: Formats = DefaultFormats.withCompanions(classOf[InMethod] -> this)
39
Reflector.describe[InMethod]
42
def methodWithClosure = {
44
case class InFunction(name: String)
45
// val st = Reflector.scalaTypeOf[InFunction] // -> Reflector.describe[InFunction]
46
// val sig = ScalaSigReader.findScalaSig(st.erasure)
47
// val classes = sig.get.symbols.collect({ case c: ClassSymbol => c })
49
Reflector.describe[InFunction]
59
val complex: RRSimple = RRSimple(1, "ba", Nil, new Date)
60
val string: String = "bla"
61
val primitive: Int = 1
62
val optPrimitive: Option[Int] = Some(3)
65
class ReflectorSpec extends Specification {
67
implicit val formats: Formats = DefaultFormats.withCompanions(
68
classOf[PathTypes.HasTrait.FromTrait] -> PathTypes.HasTrait,
69
classOf[PathTypes.HasTrait.FromTraitRROption] -> PathTypes.HasTrait
74
val inst = new PathTypes.ContainsCaseClass
76
"describe a class defined in a class constructor" in {
77
val fmts: Formats = formats.withCompanions(classOf[inst.InternalType] -> inst)
78
Reflector.describe(manifest[PathTypes.HasTrait.FromTrait], fmts) match {
79
case d: ClassDescriptor =>
80
d.constructors must not(beEmpty)
81
d.constructors.head.params.size must_== 2
82
d.properties.size must_== 1
83
case _ => fail("Expected a class descriptor")
87
"describe a class defined in a trait constructor" in {
88
Reflector.describe[PathTypes.HasTrait.FromTrait] match {
89
case d: ClassDescriptor =>
90
d.constructors must not(beEmpty)
91
d.constructors.head.params.size must_== 2
92
d.properties.size must_== 1
93
d.companion.map(_.instance) must_== Some(PathTypes.HasTrait.FromTrait)
94
d.constructors.head.params(0).defaultValue.get() must_== PathTypes.HasTrait
95
case _ => fail("Expected a class descriptor")
99
"describe a class defined in a method" in {
100
// inst.methodWithCaseClass match {
101
// case d: ClassDescriptor =>
103
// d.constructors must not(beEmpty)
104
// d.constructors.head.params.size must_== 1
105
// d.properties.size must_== 1
106
// case _ => fail("Expected a class descriptor")
108
inst.methodWithCaseClass must throwA[MappingException]
111
"describe a class defined in a closure" in {
112
inst.methodWithClosure must throwA[MappingException]
114
"describe a case object" in {
115
val descr = Reflector.describe(TheObject.getClass).asInstanceOf[ClassDescriptor]
116
val res = descr.mostComprehensive must not(throwAn[Exception])
117
println(Reflector.describe(TheObject.getClass))
121
"describe primitives" in {
122
Reflector.describe[Int] must_== PrimitiveDescriptor(Reflector.scalaTypeOf[Int])
123
Reflector.describe[Byte] must_== PrimitiveDescriptor(Reflector.scalaTypeOf[Byte])
124
Reflector.describe[Short] must_== PrimitiveDescriptor(Reflector.scalaTypeOf[Short])
125
Reflector.describe[Long] must_== PrimitiveDescriptor(Reflector.scalaTypeOf[Long])
126
Reflector.describe[Double] must_== PrimitiveDescriptor(Reflector.scalaTypeOf[Double])
127
Reflector.describe[Float] must_== PrimitiveDescriptor(Reflector.scalaTypeOf[Float])
128
Reflector.describe[java.lang.Integer] must_== PrimitiveDescriptor(Reflector.scalaTypeOf[java.lang.Integer])
129
Reflector.describe[java.lang.Byte] must_== PrimitiveDescriptor(Reflector.scalaTypeOf[java.lang.Byte])
130
Reflector.describe[java.lang.Short] must_== PrimitiveDescriptor(Reflector.scalaTypeOf[java.lang.Short])
131
Reflector.describe[java.lang.Long] must_== PrimitiveDescriptor(Reflector.scalaTypeOf[java.lang.Long])
132
Reflector.describe[java.lang.Double] must_== PrimitiveDescriptor(Reflector.scalaTypeOf[java.lang.Double])
133
Reflector.describe[java.lang.Float] must_== PrimitiveDescriptor(Reflector.scalaTypeOf[java.lang.Float])
134
Reflector.describe[BigInt] must_== PrimitiveDescriptor(Reflector.scalaTypeOf[BigInt])
135
Reflector.describe[BigDecimal] must_== PrimitiveDescriptor(Reflector.scalaTypeOf[BigDecimal])
136
Reflector.describe[java.math.BigInteger] must_== PrimitiveDescriptor(Reflector.scalaTypeOf[java.math.BigInteger])
137
Reflector.describe[java.math.BigDecimal] must_== PrimitiveDescriptor(Reflector.scalaTypeOf[java.math.BigDecimal])
138
Reflector.describe[String] must_== PrimitiveDescriptor(Reflector.scalaTypeOf[String])
139
Reflector.describe[Date] must_== PrimitiveDescriptor(Reflector.scalaTypeOf[Date])
140
Reflector.describe[Timestamp] must_== PrimitiveDescriptor(Reflector.scalaTypeOf[Timestamp])
143
"describe a simple case class" in {
144
val desc = Reflector.describe[RRSimple].asInstanceOf[ClassDescriptor]
145
desc.constructors.size must_== 1
146
val params = desc.constructors.head.params
147
params(0).name must_== "id"
148
params(0).defaultValue must beNone
149
params(0).argType must_== Reflector.scalaTypeOf[Int]
150
params(1).name must_== "name"
151
params(1).defaultValue must beNone
152
params(1).argType must_== Reflector.scalaTypeOf[String]
153
params(2).name must_== "items"
154
params(2).defaultValue must beNone
155
params(2).argType must_== Reflector.scalaTypeOf[List[String]]
156
params(3).name must_== "createdAt"
157
params(3).defaultValue must beNone
158
params(3).argType must_== Reflector.scalaTypeOf[Date]
160
"describe a simple joda case class" in {
161
val desc = Reflector.describe[RRSimpleJoda].asInstanceOf[ClassDescriptor]
162
desc.constructors.size must_== 1
163
val params = desc.constructors.head.params
164
params(0).name must_== "id"
165
params(0).defaultValue must beNone
166
params(0).argType must_== Reflector.scalaTypeOf[Int]
167
params(1).name must_== "name"
168
params(1).defaultValue must beNone
169
params(1).argType must_== Reflector.scalaTypeOf[String]
170
params(2).name must_== "items"
171
params(2).defaultValue must beNone
172
params(2).argType must_== Reflector.scalaTypeOf[List[String]]
173
params(3).name must_== "createdAt"
174
params(3).defaultValue must beNone
175
params(3).argType must_== Reflector.scalaTypeOf[DateTime]
177
"Describe a case class with options" in {
178
val desc = Reflector.describe[RROption].asInstanceOf[ClassDescriptor]
179
desc.constructors.size must_== 1
180
val params = desc.constructors.head.params
181
params(0).name must_== "id"
182
params(0).defaultValue must beNone
183
params(0).argType must_== Reflector.scalaTypeOf[Int]
184
params(1).name must_== "name"
185
params(1).defaultValue must beNone
186
params(1).argType must_== Reflector.scalaTypeOf[String]
187
params(2).name must_== "status"
188
params(2).defaultValue must beNone
189
params(2).argType must_== Reflector.scalaTypeOf[Option[String]]
190
params(2).argType.typeArgs must_== Seq(Reflector.scalaTypeOf[String])
191
params(3).name must_== "code"
192
params(3).defaultValue must beNone
193
params(3).argType must_== Reflector.scalaTypeOf[Option[Int]]
194
params(3).argType must_!= Reflector.scalaTypeOf[Option[String]]
195
params(3).argType.typeArgs must_== Seq(Reflector.scalaTypeOf[Int])
196
params(4).name must_== "createdAt"
197
params(4).defaultValue must beNone
198
params(4).argType must_== Reflector.scalaTypeOf[Date]
199
params(5).name must_== "deletedAt"
200
params(5).defaultValue must beNone
201
params(5).argType must_== Reflector.scalaTypeOf[Option[Date]]
202
params(5).argType.typeArgs must_== Seq(Reflector.scalaTypeOf[Date])
205
"describe a type parameterized class" in {
206
val desc = Reflector.describe[RRTypeParam[Int]].asInstanceOf[ClassDescriptor]
207
desc.constructors.size must_== 1
208
val params = desc.constructors.head.params
209
params(0).name must_== "id"
210
params(0).defaultValue must beNone
211
params(0).argType must_== Reflector.scalaTypeOf[Int]
212
params(1).name must_== "name"
213
params(1).defaultValue must beNone
214
params(1).argType must_== Reflector.scalaTypeOf[String]
215
params(2).name must_== "value"
216
params(2).defaultValue must beNone
217
params(2).argType must_== Reflector.scalaTypeOf[Int]
218
params(3).name must_== "opt"
219
params(3).defaultValue must beNone
220
params(3).argType must_== Reflector.scalaTypeOf[Option[Int]]
221
params(4).name must_== "seq"
222
params(4).defaultValue must beNone
223
params(4).argType must_== Reflector.scalaTypeOf[Seq[Int]]
224
params(5).name must_== "map"
225
params(5).defaultValue must beNone
226
params(5).argType must_== Reflector.scalaTypeOf[Map[String, Int]]
229
"describe a type with nested generic types" in {
230
val desc = Reflector.describe[NestedType].asInstanceOf[ClassDescriptor]
231
desc.constructors.size must_== 1
232
val params = desc.constructors.head.params
233
params(0).name must_== "dat"
234
params(0).defaultValue must beNone
235
params(0).argType must_== Reflector.scalaTypeOf[List[Map[Double, Option[Int]]]]
236
params(1).name must_== "lis"
237
params(1).defaultValue must beNone
238
params(1).argType must_== Reflector.scalaTypeOf[List[List[List[List[List[Int]]]]]]
241
"describe a type with nested generic types 2" in {
242
val desc = Reflector.describe[NestedType3].asInstanceOf[ClassDescriptor]
243
desc.constructors.size must_== 1
244
val params = desc.constructors.head.params
245
params(0).name must_== "dat"
246
params(0).defaultValue must beNone
247
params(0).argType must_== Reflector.scalaTypeOf[List[Map[Double, Option[List[Option[Int]]]]]]
248
params(1).name must_== "lis"
249
params(1).defaultValue must beNone
250
params(1).argType must_== Reflector.scalaTypeOf[List[List[List[List[List[Int]]]]]]
253
"describe a type with nested generic types 3" in {
254
val desc = Reflector.describe[NestedType4].asInstanceOf[ClassDescriptor]
255
desc.constructors.size must_== 1
256
val params = desc.constructors.head.params
257
params(0).name must_== "dat"
258
params(0).defaultValue must beNone
259
params(0).argType must_== Reflector.scalaTypeOf[List[Map[Double, Option[List[Map[Long, Option[Int]]]]]]]
260
params(1).name must_== "lis"
261
params(1).defaultValue must beNone
262
params(1).argType must_== Reflector.scalaTypeOf[List[List[List[List[List[Int]]]]]]
265
"describe a type with nested generic types 4" in {
266
val desc = Reflector.describe[NestedType5].asInstanceOf[ClassDescriptor]
267
desc.constructors.size must_== 1
268
val params = desc.constructors.head.params
269
params(0).name must_== "dat"
270
params(0).defaultValue must beNone
271
params(0).argType must_== Reflector.scalaTypeOf[List[Map[Double, Option[List[Map[Long, Option[Map[Byte, Either[Double, Long]]]]]]]]]
272
params(1).name must_== "lis"
273
params(1).defaultValue must beNone
274
params(1).argType must_== Reflector.scalaTypeOf[List[List[List[List[List[Int]]]]]]
277
"describe a type with nested generic types parameters" in {
278
val desc = Reflector.describe[NestedResType[Double, Int, Option[Int]]].asInstanceOf[ClassDescriptor]
279
desc.constructors.size must_== 1
280
val params = desc.constructors.head.params
281
params(0).name must_== "t"
282
params(0).defaultValue must beNone
283
params(0).argType must_== Reflector.scalaTypeOf[Double]
284
params(1).name must_== "v"
285
params(1).defaultValue must beNone
286
params(1).argType must_== Reflector.scalaTypeOf[Option[Int]]
287
params(2).name must_== "dat"
288
params(2).defaultValue must beNone
289
params(2).argType must_== Reflector.scalaTypeOf[List[Map[Double, Option[Int]]]]
290
params(3).name must_== "lis"
291
params(3).defaultValue must beNone
292
params(3).argType must_== Reflector.scalaTypeOf[List[List[List[List[List[Int]]]]]]
295
"describe a class with a wildcard parameter" in {
296
val desc = Reflector.describe[Objs].asInstanceOf[ClassDescriptor]
297
desc.constructors.size must_== 1
298
val params = desc.constructors.head.params
299
params(0).name must_== "objects"
300
params(0).argType must_== Reflector.scalaTypeOf[List[Obj[_]]]
303
"describe the fields of a class" in {
304
val desc = Reflector.describe[NormalClass].asInstanceOf[ClassDescriptor]
305
desc.constructors.size must_== 1
306
val params = desc.properties
307
params.size must_== 4
308
params(0).name must_== "complex"
309
params(0).returnType must_== Reflector.scalaTypeOf[RRSimple]
310
params(1).name must_== "string"
311
params(1).returnType must_== Reflector.scalaTypeOf[String]
312
params(2).name must_== "primitive"
313
params(2).returnType must_== Reflector.scalaTypeOf[Int]
314
params(3).name must_== "optPrimitive"
315
params(3).returnType must_== Reflector.scalaTypeOf[Option[Int]]
318
"Describe a case class with options defined in a trait" in {
319
val desc = Reflector.describe[PathTypes.HasTrait.FromTraitRROption].asInstanceOf[ClassDescriptor]
320
desc.constructors.size must_== 1
321
desc.companion.map(_.instance) must_== Some(PathTypes.HasTrait.FromTraitRROption)
322
desc.constructors.head.params(0).defaultValue.get() must_== PathTypes.HasTrait
324
val params = desc.constructors.head.params.filterNot(_.name==ScalaSigReader.OuterFieldName)
325
params(0).name must_== "id"
326
params(0).defaultValue must beNone
327
params(0).argType must_== Reflector.scalaTypeOf[Int]
328
params(1).name must_== "name"
329
params(1).defaultValue must beNone
330
params(1).argType must_== Reflector.scalaTypeOf[String]
331
params(2).name must_== "status"
332
params(2).defaultValue must beNone
333
params(2).argType must_== Reflector.scalaTypeOf[Option[String]]
334
params(2).argType.typeArgs must_== Seq(Reflector.scalaTypeOf[String])
335
params(3).name must_== "code"
336
params(3).defaultValue must beNone
337
params(3).argType must_== Reflector.scalaTypeOf[Option[Int]]
338
params(3).argType must_!= Reflector.scalaTypeOf[Option[String]]
339
params(3).argType.typeArgs must_== Seq(Reflector.scalaTypeOf[Int])
340
params(4).name must_== "createdAt"
341
params(4).defaultValue must beNone
342
params(4).argType must_== Reflector.scalaTypeOf[Date]
343
params(5).name must_== "deletedAt"
344
params(5).defaultValue must beNone
345
params(5).argType must_== Reflector.scalaTypeOf[Option[Date]]
346
params(5).argType.typeArgs must_== Seq(Reflector.scalaTypeOf[Date])