Skip to content

Commit 7f8b2d8

Browse files
committed
[Avro] Add Map and List interoperability tests
1 parent 46245e0 commit 7f8b2d8

13 files changed

+886
-22
lines changed

avro/src/test/java/com/fasterxml/jackson/dataformat/avro/interop/ApacheAvroInteropUtil.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ protected Schema createSchema(Type type, Map<String, Schema> names) {
108108
}
109109
}
110110
}
111-
if (type instanceof Class<?> && ((Class<?>) type).getSuperclass() != null) {
111+
if (type instanceof Class<?> && ((Class<?>) type).getSuperclass() != null && !Enum.class.isAssignableFrom((Class<?>) type)) {
112112
// Raw class may extend a generic superclass
113113
// extract all the type bindings and add them to the map so they can be returned by the next block
114114
// Interfaces shouldn't matter here because interfaces can't have fields and avro only looks at fields.

avro/src/test/java/com/fasterxml/jackson/dataformat/avro/interop/InteropTestBase.java

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
package com.fasterxml.jackson.dataformat.avro.interop;
22

3+
import java.lang.reflect.ParameterizedType;
4+
import java.lang.reflect.Type;
5+
6+
import com.fasterxml.jackson.annotation.JsonProperty;
7+
8+
import lombok.AllArgsConstructor;
9+
import lombok.Data;
10+
import lombok.NoArgsConstructor;
311
import org.apache.avro.Schema;
412
import org.junit.runner.RunWith;
513
import org.junit.runners.Parameterized;
614

7-
import java.lang.reflect.ParameterizedType;
8-
import java.lang.reflect.Type;
9-
1015
import static com.fasterxml.jackson.dataformat.avro.interop.ApacheAvroInteropUtil.*;
1116

1217
/**
@@ -145,4 +150,18 @@ protected <T> T roundTrip(Type schemaType, T object) {
145150
}
146151
return (T) deserializeFunctor.apply(schema, serializeFunctor.apply(schema, object));
147152
}
153+
154+
public enum DummyEnum {
155+
NORTH, SOUTH, EAST, WEST
156+
}
157+
158+
@Data
159+
@NoArgsConstructor
160+
@AllArgsConstructor
161+
public static class DummyRecord {
162+
@JsonProperty(required = true)
163+
private String firstValue;
164+
@JsonProperty(required = true)
165+
private int secondValue;
166+
}
148167
}
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
package com.fasterxml.jackson.dataformat.avro.interop.arrays;
2+
3+
import java.util.*;
4+
import java.util.concurrent.ConcurrentSkipListSet;
5+
import java.util.concurrent.CopyOnWriteArrayList;
6+
import java.util.concurrent.CopyOnWriteArraySet;
7+
8+
import org.junit.Assume;
9+
import org.junit.Test;
10+
11+
import com.fasterxml.jackson.dataformat.avro.interop.InteropTestBase;
12+
13+
import static com.fasterxml.jackson.dataformat.avro.interop.ApacheAvroInteropUtil.apacheDeserializer;
14+
import static org.assertj.core.api.Assertions.assertThat;
15+
16+
/**
17+
* Tests collection subtypes such as {@link ArrayList}, {@link LinkedList}, {@link Stack}, {@link Set}, {@link HashSet}, {@link TreeSet},
18+
* {@link ConcurrentSkipListSet}, {@link CopyOnWriteArraySet}, and {@link CopyOnWriteArrayList} to ensure they are compatible with the
19+
* {@code ARRAY} schema type.
20+
*/
21+
public class CollectionSubtypeTest extends InteropTestBase {
22+
@Test
23+
public void testArrayList() {
24+
ArrayList<String> original = new ArrayList<>();
25+
original.add("test");
26+
original.add("Second");
27+
//
28+
ArrayList<String> result = roundTrip(type(ArrayList.class, String.class), original);
29+
//
30+
assertThat(result).isEqualTo(original);
31+
}
32+
33+
@Test
34+
public void testConcurrentSkipListSet() {
35+
ConcurrentSkipListSet<Integer> original = new ConcurrentSkipListSet<>();
36+
original.add(1234);
37+
original.add(98768234);
38+
//
39+
ConcurrentSkipListSet<Integer> result = roundTrip(type(ConcurrentSkipListSet.class, Integer.class), original);
40+
//
41+
assertThat(result).isEqualTo(original);
42+
}
43+
44+
@Test
45+
public void testCopyOnWriteArrayList() {
46+
CopyOnWriteArrayList<Integer> original = new CopyOnWriteArrayList<>();
47+
original.add(1234);
48+
original.add(98768234);
49+
//
50+
CopyOnWriteArrayList<Integer> result = roundTrip(type(CopyOnWriteArrayList.class, Integer.class), original);
51+
//
52+
assertThat(result).isEqualTo(original);
53+
}
54+
55+
@Test
56+
public void testCopyOnWriteArraySet() {
57+
CopyOnWriteArraySet<Integer> original = new CopyOnWriteArraySet<>();
58+
original.add(1234);
59+
original.add(98768234);
60+
//
61+
CopyOnWriteArraySet<Integer> result = roundTrip(type(CopyOnWriteArraySet.class, Integer.class), original);
62+
//
63+
assertThat(result).isEqualTo(original);
64+
}
65+
66+
@Test
67+
public void testEnumSet() {
68+
// Bug in apache deserializer, can't handle EnumSet
69+
Assume.assumeTrue(deserializeFunctor != apacheDeserializer);
70+
EnumSet<DummyEnum> original = EnumSet.of(DummyEnum.EAST, DummyEnum.NORTH);
71+
//
72+
EnumSet<DummyEnum> result = roundTrip(type(EnumSet.class, DummyEnum.class), original);
73+
//
74+
assertThat(result).isEqualTo(original);
75+
}
76+
77+
@Test
78+
public void testHashSet() {
79+
HashSet<Integer> original = new HashSet<>();
80+
original.add(1234);
81+
original.add(98768234);
82+
//
83+
HashSet<Integer> result = roundTrip(type(HashSet.class, Integer.class), original);
84+
//
85+
assertThat(result).isEqualTo(original);
86+
}
87+
88+
@Test
89+
public void testLinkedList() {
90+
LinkedList<Integer> original = new LinkedList<>();
91+
original.add(1234);
92+
original.add(98768234);
93+
//
94+
LinkedList<Integer> result = roundTrip(type(LinkedList.class, Integer.class), original);
95+
//
96+
assertThat(result).isEqualTo(original);
97+
}
98+
99+
@Test
100+
public void testList() {
101+
List<String> original = new ArrayList<>();
102+
original.add("test");
103+
original.add("Second");
104+
//
105+
List<String> result = roundTrip(type(List.class, String.class), original);
106+
//
107+
assertThat(result).isEqualTo(original);
108+
}
109+
110+
@Test
111+
public void testSet() {
112+
// Bug in apache deserializer, can't handle Set
113+
Assume.assumeTrue(deserializeFunctor != apacheDeserializer);
114+
Set<Integer> original = new HashSet<>();
115+
original.add(1234);
116+
original.add(98768234);
117+
//
118+
Set<Integer> result = roundTrip(type(Set.class, Integer.class), original);
119+
//
120+
assertThat(result).isEqualTo(original);
121+
}
122+
123+
@Test
124+
public void testStack() {
125+
Stack<Integer> original = new Stack<>();
126+
original.add(1234);
127+
original.add(98768234);
128+
//
129+
Stack<Integer> result = roundTrip(type(Stack.class, Integer.class), original);
130+
//
131+
assertThat(result).isEqualTo(original);
132+
}
133+
134+
@Test
135+
public void testTreeSet() {
136+
TreeSet<Integer> original = new TreeSet<>();
137+
original.add(1234);
138+
original.add(98768234);
139+
//
140+
TreeSet<Integer> result = roundTrip(type(TreeSet.class, Integer.class), original);
141+
//
142+
assertThat(result).isEqualTo(original);
143+
}
144+
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
package com.fasterxml.jackson.dataformat.avro.interop.arrays;
2+
3+
import java.util.ArrayList;
4+
import java.util.Collections;
5+
import java.util.List;
6+
import java.util.Map;
7+
8+
import org.junit.Test;
9+
10+
import com.fasterxml.jackson.dataformat.avro.interop.InteropTestBase;
11+
12+
import static org.assertj.core.api.Assertions.assertThat;
13+
import static org.assertj.core.api.Assertions.fail;
14+
15+
/**
16+
* Tests lists involving complex element types (Lists, Records, Maps, Enums)
17+
*/
18+
public class ListWithComplexTest extends InteropTestBase {
19+
@Test
20+
public void testEmptyListWithRecordElements() {
21+
List<DummyRecord> original = new ArrayList<>();
22+
//
23+
List<DummyRecord> result = roundTrip(type(List.class, DummyRecord.class), original);
24+
//
25+
assertThat(result).isEqualTo(original);
26+
}
27+
28+
@Test
29+
public void testListWithEnumElements() {
30+
List<DummyEnum> original = new ArrayList<>();
31+
original.add(DummyEnum.EAST);
32+
original.add(DummyEnum.WEST);
33+
//
34+
List<DummyEnum> result = roundTrip(type(List.class, DummyEnum.class), original);
35+
//
36+
assertThat(result).isEqualTo(original);
37+
}
38+
39+
@Test
40+
public void testListWithListElements() {
41+
List<List<List<String>>> original = new ArrayList<>();
42+
original.add(new ArrayList<List<String>>());
43+
original.get(0).add(Collections.singletonList("Hello"));
44+
original.add(new ArrayList<List<String>>());
45+
original.get(1).add(Collections.singletonList("World"));
46+
//
47+
List<List<List<String>>> result = roundTrip(type(List.class, type(List.class, type(List.class, String.class))), original);
48+
//
49+
assertThat(result).isEqualTo(original);
50+
}
51+
52+
@Test
53+
public void testListWithMapElements() {
54+
List<Map<String, Integer>> original = new ArrayList<>();
55+
original.add(Collections.singletonMap("Hello", 1));
56+
original.add(Collections.singletonMap("World", 2));
57+
//
58+
List<Map<String, Integer>> result = roundTrip(type(List.class, type(Map.class, String.class, Integer.class)), original);
59+
//
60+
assertThat(result).isEqualTo(original);
61+
}
62+
63+
@Test
64+
public void testListWithNullElements() {
65+
List<DummyRecord> original = new ArrayList<>();
66+
original.add(null);
67+
//
68+
try {
69+
roundTrip(type(List.class, DummyRecord.class), original);
70+
fail("Should throw an NPE");
71+
} catch (Throwable e) {
72+
// Avro NullPointerException
73+
// Jackson RuntimeException -> JsonMappingException -> NullPointerException
74+
while (e.getCause() != null && e.getCause() != e) {
75+
e = e.getCause();
76+
}
77+
assertThat(e).isInstanceOf(NullPointerException.class);
78+
}
79+
}
80+
81+
@Test
82+
public void testListWithRecordElements() {
83+
List<DummyRecord> original = new ArrayList<>();
84+
original.add(new DummyRecord("test", 2));
85+
original.add(new DummyRecord("test 2", 1235));
86+
original.add(new DummyRecord("test 3", -234));
87+
//
88+
List<DummyRecord> result = roundTrip(type(List.class, DummyRecord.class), original);
89+
//
90+
assertThat(result).isEqualTo(original);
91+
}
92+
}

0 commit comments

Comments
 (0)