14
14
* limitations under the License.
15
15
*/
16
16
17
- package magnolify .avro . test
17
+ package magnolify .avro
18
18
19
- import java .io .{ByteArrayInputStream , ByteArrayOutputStream }
20
- import java .net .URI
21
- import java .nio .ByteBuffer
22
- import java .time .format .DateTimeFormatter
23
- import java .time .{Duration , Instant , LocalDate , LocalDateTime , LocalTime }
24
- import java .util .UUID
25
19
import cats ._
26
20
import com .fasterxml .jackson .core .JsonFactory
27
- import com .fasterxml .jackson .databind .{JsonNode , ObjectMapper }
21
+ import com .fasterxml .jackson .databind .JsonNode
22
+ import com .fasterxml .jackson .databind .ObjectMapper
28
23
import magnolify .avro ._
29
24
import magnolify .avro .unsafe ._
30
25
import magnolify .cats .auto ._
26
+ import magnolify .cats .TestEq ._
31
27
import magnolify .scalacheck .auto ._
28
+ import magnolify .scalacheck .TestArbitrary ._
32
29
import magnolify .shared .CaseMapper
30
+ import magnolify .shared .TestEnumType ._
33
31
import magnolify .test .Simple ._
34
- import magnolify .test .Time ._
35
32
import magnolify .test ._
36
33
import org .apache .avro .Schema
37
- import org .apache .avro .generic .{
38
- GenericDatumReader ,
39
- GenericDatumWriter ,
40
- GenericRecord ,
41
- GenericRecordBuilder
42
- }
43
- import org .apache .avro .io .{DecoderFactory , EncoderFactory }
34
+ import org .apache .avro .generic .GenericDatumReader
35
+ import org .apache .avro .generic .GenericDatumWriter
36
+ import org .apache .avro .generic .GenericRecord
37
+ import org .apache .avro .generic .GenericRecordBuilder
38
+ import org .apache .avro .io .DecoderFactory
39
+ import org .apache .avro .io .EncoderFactory
44
40
import org .scalacheck ._
45
41
42
+ import java .io .ByteArrayInputStream
43
+ import java .io .ByteArrayOutputStream
44
+ import java .net .URI
45
+ import java .nio .ByteBuffer
46
+ import java .time .Duration
47
+ import java .time .Instant
48
+ import java .time .LocalDate
49
+ import java .time .LocalDateTime
50
+ import java .time .LocalTime
51
+ import java .time .format .DateTimeFormatter
52
+ import java .util .UUID
53
+ import scala .jdk .CollectionConverters ._
46
54
import scala .reflect ._
47
55
import scala .util .Try
48
- import scala .jdk .CollectionConverters ._
49
56
50
57
class AvroTypeSuite extends MagnolifySuite {
51
58
private def test [T : Arbitrary : ClassTag ](implicit
@@ -98,34 +105,30 @@ class AvroTypeSuite extends MagnolifySuite {
98
105
}
99
106
}
100
107
108
+ implicit val arbBigDecimal : Arbitrary [BigDecimal ] =
109
+ Arbitrary (Gen .chooseNum(0L , Long .MaxValue ).map(BigDecimal (_, 0 )))
110
+ implicit val arbCountryCode : Arbitrary [CountryCode ] = Arbitrary (
111
+ Gen .oneOf(" US" , " UK" , " CA" , " MX" ).map(CountryCode (_))
112
+ )
113
+ implicit val afUri : AvroField [URI ] = AvroField .from[String ](URI .create)(_.toString)
114
+ implicit val afDuration : AvroField [Duration ] =
115
+ AvroField .from[Long ](Duration .ofMillis)(_.toMillis)
116
+ implicit val afCountryCode : AvroField [CountryCode ] =
117
+ AvroField .fixed[CountryCode ](2 )(bs => CountryCode (new String (bs)))(cc => cc.code.getBytes)
118
+
101
119
test[Integers ]
102
120
test[Floats ]
103
121
test[Required ]
104
122
test[Nullable ]
105
123
test[Repeated ]
106
124
test[Nested ]
107
125
test[Unsafe ]
108
-
109
- {
110
- import Collections ._
111
- test[Collections ]
112
- test[MoreCollections ]
113
- }
114
-
115
- {
116
- import Enums ._
117
- import UnsafeEnums ._
118
- test[Enums ]
119
- test[UnsafeEnums ]
120
- }
121
-
122
- {
123
- import Custom ._
124
- implicit val afUri : AvroField [URI ] = AvroField .from[String ](URI .create)(_.toString)
125
- implicit val afDuration : AvroField [Duration ] =
126
- AvroField .from[Long ](Duration .ofMillis)(_.toMillis)
127
- test[Custom ]
128
- }
126
+ test[Collections ]
127
+ test[MoreCollections ]
128
+ test[Enums ]
129
+ test[UnsafeEnums ]
130
+ test[Custom ]
131
+ test[AvroTypes ]
129
132
130
133
test(" AnyVal" ) {
131
134
implicit val at : AvroType [HasValueClass ] = AvroType [HasValueClass ]
@@ -138,12 +141,7 @@ class AvroTypeSuite extends MagnolifySuite {
138
141
}
139
142
140
143
{
141
- implicit val eqByteArray : Eq [Array [Byte ]] = Eq .by(_.toList)
142
- test[AvroTypes ]
143
- }
144
-
145
- {
146
- def f [T ](r : GenericRecord ): List [(String , Any )] =
144
+ def f (r : GenericRecord ): List [(String , Any )] =
147
145
r.get(" m" )
148
146
.asInstanceOf [java.util.Map [CharSequence , Any ]]
149
147
.asScala
@@ -158,50 +156,34 @@ class AvroTypeSuite extends MagnolifySuite {
158
156
test[Logical ]
159
157
160
158
{
161
- implicit val arbBigDecimal : Arbitrary [BigDecimal ] =
162
- Arbitrary (Gen .chooseNum(0L , Long .MaxValue ).map(BigDecimal (_, 0 )))
163
-
164
- {
165
- import magnolify .avro .logical .micros ._
166
- implicit val afBigDecimal : AvroField [BigDecimal ] = AvroField .bigDecimal(19 , 0 )
167
- test[LogicalMicros ]
168
- }
159
+ import magnolify .avro .logical .micros ._
160
+ test[LogicalMicros ]
169
161
170
162
test(" MicrosLogicalTypes" ) {
171
- import magnolify .avro .logical .micros ._
172
- implicit val afBigDecimal : AvroField [BigDecimal ] = AvroField .bigDecimal(19 , 0 )
173
-
174
163
val schema = AvroType [LogicalMicros ].schema
175
- assertLogicalType(schema, " bd" , " decimal" )
176
164
assertLogicalType(schema, " i" , " timestamp-micros" )
177
165
assertLogicalType(schema, " dt" , " local-timestamp-micros" , false )
178
166
assertLogicalType(schema, " t" , " time-micros" )
179
167
}
168
+ }
180
169
181
- {
182
- import magnolify .avro .logical .millis ._
183
- implicit val afBigDecimal : AvroField [BigDecimal ] = AvroField .bigDecimal(19 , 0 )
184
- test[LogicalMillis ]
185
- }
170
+ {
171
+ import magnolify .avro .logical .millis ._
172
+ test[LogicalMillis ]
186
173
187
174
test(" MilliLogicalTypes" ) {
188
- import magnolify .avro .logical .millis ._
189
- implicit val afBigDecimal : AvroField [BigDecimal ] = AvroField .bigDecimal(19 , 0 )
190
-
191
175
val schema = AvroType [LogicalMillis ].schema
192
- assertLogicalType(schema, " bd" , " decimal" )
193
176
assertLogicalType(schema, " i" , " timestamp-millis" )
194
177
assertLogicalType(schema, " dt" , " local-timestamp-millis" , false )
195
178
assertLogicalType(schema, " t" , " time-millis" )
196
179
}
180
+ }
197
181
198
- {
199
- import magnolify .avro .logical .bigquery ._
200
- test[LogicalBigQuery ]
201
- }
182
+ {
183
+ import magnolify .avro .logical .bigquery ._
184
+ test[LogicalBigQuery ]
202
185
203
186
test(" BigQueryLogicalTypes" ) {
204
- import magnolify .avro .logical .bigquery ._
205
187
// `registerLogicalTypes()` is necessary to correctly parse a custom logical type from string.
206
188
// if omitted, the returned string schema will be correct, but the logicalType field will be null.
207
189
// this is unfortunately global mutable state
@@ -215,21 +197,13 @@ class AvroTypeSuite extends MagnolifySuite {
215
197
}
216
198
}
217
199
218
- {
219
- implicit val arbCountryCode : Arbitrary [CountryCode ] = Arbitrary (
220
- Gen .oneOf(" US" , " UK" , " CA" , " MX" ).map(CountryCode (_))
221
- )
222
- implicit val afCountryCode : AvroField [CountryCode ] =
223
- AvroField .fixed[CountryCode ](2 )(bs => CountryCode (new String (bs)))(cc => cc.code.getBytes)
224
- test[Fixed ]
225
-
226
- test(" FixedDoc" ) {
227
- val at = ensureSerializable(AvroType [Fixed ])
228
- val schema = at.schema.getField(" countryCode" ).schema
229
- assertEquals(schema.getName, " CountryCode" )
230
- assertEquals(schema.getNamespace, " magnolify.avro.test" )
231
- assertEquals(schema.getDoc, " Fixed with doc" )
232
- }
200
+ test[Fixed ]
201
+ test(" FixedDoc" ) {
202
+ val at = ensureSerializable(AvroType [Fixed ])
203
+ val schema = at.schema.getField(" countryCode" ).schema
204
+ assertEquals(schema.getName, " CountryCode" )
205
+ assertEquals(schema.getNamespace, " magnolify.avro" )
206
+ assertEquals(schema.getDoc, " Fixed with doc" )
233
207
}
234
208
235
209
test(" AvroDoc" ) {
@@ -253,63 +227,62 @@ class AvroTypeSuite extends MagnolifySuite {
253
227
}
254
228
255
229
testFail(AvroType [DoubleRecordDoc ])(
256
- " More than one @doc annotation: magnolify.avro.test. DoubleRecordDoc"
230
+ " More than one @doc annotation: magnolify.avro.DoubleRecordDoc"
257
231
)
258
232
testFail(AvroType [DoubleFieldDoc ])(
259
- " More than one @doc annotation: magnolify.avro.test. DoubleFieldDoc#i"
233
+ " More than one @doc annotation: magnolify.avro.DoubleFieldDoc#i"
260
234
)
261
235
262
236
test(" EnumDoc" ) {
263
237
val at = ensureSerializable(AvroType [EnumDoc ])
264
238
assertEquals(at.schema.getField(" p" ).schema().getDoc, " Avro enum" )
265
239
}
266
240
267
- test( " DefaultInner " ) {
241
+ {
268
242
import magnolify .avro .logical .bigquery ._
269
- val at = ensureSerializable(AvroType [DefaultInner ])
270
- assertEquals(at(new GenericRecordBuilder (at.schema).build()), DefaultInner ())
271
- val inner = DefaultInner (
272
- 2 ,
273
- Some (2 ),
274
- List (2 , 2 ),
275
- Map (" b" -> 2 ),
276
- JavaEnums .Color .GREEN ,
277
- ScalaEnums .Color .Green ,
278
- BigDecimal (222.222 ),
279
- UUID .fromString(" 22223333-abcd-abcd-abcd-222233334444" ),
280
- Instant .ofEpochSecond(22334455L ),
281
- LocalDate .ofEpochDay(2233 ),
282
- LocalTime .of(2 , 3 , 4 ),
283
- LocalDateTime .of(2002 , 3 , 4 , 5 , 6 , 7 )
284
- )
285
- assertEquals(at(at(inner)), inner)
286
- }
243
+ test(" DefaultInner" ) {
244
+ val at = ensureSerializable(AvroType [DefaultInner ])
245
+ assertEquals(at(new GenericRecordBuilder (at.schema).build()), DefaultInner ())
246
+ val inner = DefaultInner (
247
+ 2 ,
248
+ Some (2 ),
249
+ List (2 , 2 ),
250
+ Map (" b" -> 2 ),
251
+ JavaEnums .Color .GREEN ,
252
+ ScalaEnums .Color .Green ,
253
+ BigDecimal (222.222 ),
254
+ UUID .fromString(" 22223333-abcd-abcd-abcd-222233334444" ),
255
+ Instant .ofEpochSecond(22334455L ),
256
+ LocalDate .ofEpochDay(2233 ),
257
+ LocalTime .of(2 , 3 , 4 ),
258
+ LocalDateTime .of(2002 , 3 , 4 , 5 , 6 , 7 )
259
+ )
260
+ assertEquals(at(at(inner)), inner)
261
+ }
287
262
288
- test(" DefaultOuter" ) {
289
- import magnolify . avro . logical . bigquery . _
290
- val at = ensureSerializable( AvroType [ DefaultOuter ] )
291
- assertEquals(at( new GenericRecordBuilder (at.schema).build()), DefaultOuter ())
292
- val inner = DefaultInner (
293
- 3 ,
294
- Some ( 3 ),
295
- List ( 3 , 3 ),
296
- Map ( " c " -> 3 ) ,
297
- JavaEnums .Color .BLUE ,
298
- ScalaEnums . Color . Blue ,
299
- BigDecimal ( 333.333 ),
300
- UUID .fromString( " 33334444-abcd-abcd-abcd-333344445555 " ),
301
- Instant .ofEpochSecond( 33445566L ),
302
- LocalDate .ofEpochDay( 3344 ),
303
- LocalTime .of(3 , 4 , 5 ),
304
- LocalDateTime .of( 2003 , 4 , 5 , 6 , 7 , 8 )
305
- )
306
- val outer = DefaultOuter (inner, Some (inner) )
307
- assertEquals(at(at(outer)), outer)
263
+ test(" DefaultOuter" ) {
264
+ val at = ensureSerializable( AvroType [ DefaultOuter ])
265
+ assertEquals(at( new GenericRecordBuilder (at.schema).build()), DefaultOuter () )
266
+ val inner = DefaultInner (
267
+ 3 ,
268
+ Some ( 3 ) ,
269
+ List ( 3 , 3 ),
270
+ Map ( " c " -> 3 ),
271
+ JavaEnums . Color . BLUE ,
272
+ ScalaEnums .Color .Blue ,
273
+ BigDecimal ( 333.333 ) ,
274
+ UUID .fromString( " 33334444-abcd-abcd-abcd-333344445555 " ),
275
+ Instant .ofEpochSecond( 33445566L ),
276
+ LocalDate .ofEpochDay( 3344 ),
277
+ LocalTime .of( 3 , 4 , 5 ),
278
+ LocalDateTime .of(2003 , 4 , 5 , 6 , 7 , 8 )
279
+ )
280
+ val outer = DefaultOuter (inner, Some (inner) )
281
+ assertEquals(at(at(outer)), outer )
282
+ }
308
283
}
309
284
310
- testFail(AvroType [SomeDefault ])(
311
- " Option[T] can only default to None"
312
- )
285
+ testFail(AvroType [SomeDefault ])(" Option[T] can only default to None" )
313
286
314
287
{
315
288
implicit val at : AvroType [LowerCamel ] = AvroType [LowerCamel ](CaseMapper (_.toUpperCase))
@@ -331,7 +304,7 @@ class AvroTypeSuite extends MagnolifySuite {
331
304
}
332
305
333
306
test(" BigDecimal" ) {
334
- import magnolify . avro . logical . bigquery . _
307
+ implicit val afBigDecimal : AvroField [ BigDecimal ] = AvroField .bigDecimal( 38 , 9 )
335
308
val at : AvroType [BigDec ] = AvroType [BigDec ]
336
309
337
310
val bigInt = " 1234567890123456789012345678901234567890"
@@ -362,8 +335,8 @@ case class MapPrimitive(m: Map[String, Int])
362
335
case class MapNested (m : Map [String , Nested ])
363
336
364
337
case class Logical (u : UUID , d : LocalDate )
365
- case class LogicalMicros (bd : BigDecimal , i : Instant , t : LocalTime , dt : LocalDateTime )
366
- case class LogicalMillis (bd : BigDecimal , i : Instant , t : LocalTime , dt : LocalDateTime )
338
+ case class LogicalMicros (i : Instant , t : LocalTime , dt : LocalDateTime )
339
+ case class LogicalMillis (i : Instant , t : LocalTime , dt : LocalDateTime )
367
340
case class LogicalBigQuery (bd : BigDecimal , i : Instant , t : LocalTime , dt : LocalDateTime )
368
341
case class BigDec (bd : BigDecimal )
369
342
0 commit comments