1
2
3
4
5
6 package dev.metaschema.databind.codegen.typeinfo;
7
8 import static org.junit.jupiter.api.Assertions.assertEquals;
9 import static org.junit.jupiter.api.Assertions.assertNotNull;
10 import static org.junit.jupiter.api.Assertions.assertTrue;
11
12 import com.squareup.javapoet.ClassName;
13 import com.squareup.javapoet.ParameterizedTypeName;
14 import com.squareup.javapoet.TypeName;
15 import com.squareup.javapoet.WildcardTypeName;
16
17 import org.jmock.Expectations;
18 import org.jmock.junit5.JUnit5Mockery;
19 import org.jmock.lib.concurrent.Synchroniser;
20 import org.junit.jupiter.api.Test;
21 import org.junit.jupiter.api.extension.RegisterExtension;
22
23 import java.util.HashMap;
24 import java.util.List;
25 import java.util.Map;
26
27 import dev.metaschema.core.model.IAssemblyDefinition;
28 import dev.metaschema.core.model.IChoiceGroupInstance;
29 import dev.metaschema.core.model.JsonGroupAsBehavior;
30 import dev.metaschema.core.util.ObjectUtils;
31 import dev.metaschema.databind.codegen.config.IBindingConfiguration;
32 import dev.metaschema.databind.codegen.config.IChoiceGroupBindingConfiguration;
33 import dev.metaschema.databind.codegen.config.IDefinitionBindingConfiguration;
34 import dev.metaschema.databind.codegen.typeinfo.def.IAssemblyDefinitionTypeInfo;
35 import edu.umd.cs.findbugs.annotations.NonNull;
36
37
38
39
40 class ChoiceGroupTypeInfoImplTest {
41
42 @RegisterExtension
43 JUnit5Mockery context = new JUnit5Mockery() {
44 {
45 setThreadingPolicy(new Synchroniser());
46 }
47 };
48
49 @NonNull
50 private final IChoiceGroupInstance choiceGroupInstance
51 = ObjectUtils.notNull(context.mock(IChoiceGroupInstance.class));
52 @NonNull
53 private final IAssemblyDefinition assemblyDefinition = ObjectUtils.notNull(context.mock(IAssemblyDefinition.class));
54 @NonNull
55 private final IAssemblyDefinitionTypeInfo parentTypeInfo
56 = ObjectUtils.notNull(context.mock(IAssemblyDefinitionTypeInfo.class));
57
58
59
60
61
62 @Test
63 void testGetJavaFieldTypeReturnsWildcardTypeWhenConfigured() {
64 IBindingConfiguration bindingConfig = ObjectUtils.notNull(context.mock(IBindingConfiguration.class));
65 IDefinitionBindingConfiguration defConfig
66 = ObjectUtils.notNull(context.mock(IDefinitionBindingConfiguration.class));
67 IChoiceGroupBindingConfiguration choiceConfig
68 = ObjectUtils.notNull(context.mock(IChoiceGroupBindingConfiguration.class));
69
70 String groupAsName = "test-choices";
71 String itemTypeName = "com.example.ITestInterface";
72 ClassName itemClass = ClassName.bestGuess(itemTypeName);
73
74 Map<String, IChoiceGroupBindingConfiguration> choiceGroupBindings = new HashMap<>();
75 choiceGroupBindings.put(groupAsName, choiceConfig);
76
77
78 DefaultTypeResolver typeResolver = new DefaultTypeResolver(bindingConfig);
79
80 context.checking(new Expectations() {
81 {
82
83 allowing(parentTypeInfo).getTypeResolver();
84 will(returnValue(typeResolver));
85
86 allowing(choiceGroupInstance).getMaxOccurs();
87 will(returnValue(-1));
88
89 allowing(choiceGroupInstance).getContainingDefinition();
90 will(returnValue(assemblyDefinition));
91
92 allowing(bindingConfig).getBindingConfigurationForDefinition(assemblyDefinition);
93 will(returnValue(defConfig));
94
95 allowing(choiceGroupInstance).getGroupAsName();
96 will(returnValue(groupAsName));
97
98 allowing(defConfig).getChoiceGroupBindings();
99 will(returnValue(choiceGroupBindings));
100
101 allowing(choiceConfig).getItemTypeName();
102 will(returnValue(itemTypeName));
103
104 allowing(choiceConfig).isUseWildcard();
105 will(returnValue(true));
106
107 allowing(choiceGroupInstance).getJsonGroupAsBehavior();
108 will(returnValue(JsonGroupAsBehavior.SINGLETON_OR_LIST));
109 }
110 });
111
112 ChoiceGroupTypeInfoImpl typeInfo = new ChoiceGroupTypeInfoImpl(choiceGroupInstance, parentTypeInfo);
113 TypeName result = typeInfo.getJavaFieldType();
114
115 assertNotNull(result);
116 assertTrue(result instanceof ParameterizedTypeName, "Expected ParameterizedTypeName");
117
118 ParameterizedTypeName paramType = (ParameterizedTypeName) result;
119 assertEquals(ClassName.get(List.class), paramType.rawType);
120 assertEquals(1, paramType.typeArguments.size());
121
122 TypeName itemType = paramType.typeArguments.get(0);
123 assertTrue(itemType instanceof WildcardTypeName, "Expected WildcardTypeName for item type");
124
125 WildcardTypeName wildcardType = (WildcardTypeName) itemType;
126 assertEquals(1, wildcardType.upperBounds.size());
127 assertEquals(itemClass, wildcardType.upperBounds.get(0));
128 }
129
130
131
132
133
134 @Test
135 void testGetJavaFieldTypeReturnsNonWildcardTypeWhenNotConfigured() {
136 IBindingConfiguration bindingConfig = ObjectUtils.notNull(context.mock(IBindingConfiguration.class));
137 IDefinitionBindingConfiguration defConfig
138 = ObjectUtils.notNull(context.mock(IDefinitionBindingConfiguration.class));
139 IChoiceGroupBindingConfiguration choiceConfig
140 = ObjectUtils.notNull(context.mock(IChoiceGroupBindingConfiguration.class));
141
142 String groupAsName = "test-choices";
143 String itemTypeName = "com.example.ITestInterface";
144 ClassName itemClass = ClassName.bestGuess(itemTypeName);
145
146 Map<String, IChoiceGroupBindingConfiguration> choiceGroupBindings = new HashMap<>();
147 choiceGroupBindings.put(groupAsName, choiceConfig);
148
149 DefaultTypeResolver typeResolver = new DefaultTypeResolver(bindingConfig);
150
151 context.checking(new Expectations() {
152 {
153 allowing(parentTypeInfo).getTypeResolver();
154 will(returnValue(typeResolver));
155
156 allowing(choiceGroupInstance).getMaxOccurs();
157 will(returnValue(-1));
158
159 allowing(choiceGroupInstance).getContainingDefinition();
160 will(returnValue(assemblyDefinition));
161
162 allowing(bindingConfig).getBindingConfigurationForDefinition(assemblyDefinition);
163 will(returnValue(defConfig));
164
165 allowing(choiceGroupInstance).getGroupAsName();
166 will(returnValue(groupAsName));
167
168 allowing(defConfig).getChoiceGroupBindings();
169 will(returnValue(choiceGroupBindings));
170
171 allowing(choiceConfig).getItemTypeName();
172 will(returnValue(itemTypeName));
173
174 allowing(choiceConfig).isUseWildcard();
175 will(returnValue(false));
176
177 allowing(choiceGroupInstance).getJsonGroupAsBehavior();
178 will(returnValue(JsonGroupAsBehavior.SINGLETON_OR_LIST));
179 }
180 });
181
182 ChoiceGroupTypeInfoImpl typeInfo = new ChoiceGroupTypeInfoImpl(choiceGroupInstance, parentTypeInfo);
183 TypeName result = typeInfo.getJavaFieldType();
184
185 assertNotNull(result);
186 assertTrue(result instanceof ParameterizedTypeName, "Expected ParameterizedTypeName");
187
188 ParameterizedTypeName paramType = (ParameterizedTypeName) result;
189 assertEquals(ClassName.get(List.class), paramType.rawType);
190 assertEquals(1, paramType.typeArguments.size());
191
192
193 TypeName itemType = paramType.typeArguments.get(0);
194 assertEquals(itemClass, itemType);
195 }
196
197
198
199
200 @Test
201 void testGetJavaFieldTypeReturnsMapWithWildcardForKeyedGroups() {
202 IBindingConfiguration bindingConfig = ObjectUtils.notNull(context.mock(IBindingConfiguration.class));
203 IDefinitionBindingConfiguration defConfig
204 = ObjectUtils.notNull(context.mock(IDefinitionBindingConfiguration.class));
205 IChoiceGroupBindingConfiguration choiceConfig
206 = ObjectUtils.notNull(context.mock(IChoiceGroupBindingConfiguration.class));
207
208 String groupAsName = "test-choices";
209 String itemTypeName = "com.example.ITestInterface";
210 ClassName itemClass = ClassName.bestGuess(itemTypeName);
211
212 Map<String, IChoiceGroupBindingConfiguration> choiceGroupBindings = new HashMap<>();
213 choiceGroupBindings.put(groupAsName, choiceConfig);
214
215 DefaultTypeResolver typeResolver = new DefaultTypeResolver(bindingConfig);
216
217 context.checking(new Expectations() {
218 {
219 allowing(parentTypeInfo).getTypeResolver();
220 will(returnValue(typeResolver));
221
222 allowing(choiceGroupInstance).getMaxOccurs();
223 will(returnValue(-1));
224
225 allowing(choiceGroupInstance).getContainingDefinition();
226 will(returnValue(assemblyDefinition));
227
228 allowing(bindingConfig).getBindingConfigurationForDefinition(assemblyDefinition);
229 will(returnValue(defConfig));
230
231 allowing(choiceGroupInstance).getGroupAsName();
232 will(returnValue(groupAsName));
233
234 allowing(defConfig).getChoiceGroupBindings();
235 will(returnValue(choiceGroupBindings));
236
237 allowing(choiceConfig).getItemTypeName();
238 will(returnValue(itemTypeName));
239
240 allowing(choiceConfig).isUseWildcard();
241 will(returnValue(true));
242
243 allowing(choiceGroupInstance).getJsonGroupAsBehavior();
244 will(returnValue(JsonGroupAsBehavior.KEYED));
245 }
246 });
247
248 ChoiceGroupTypeInfoImpl typeInfo = new ChoiceGroupTypeInfoImpl(choiceGroupInstance, parentTypeInfo);
249 TypeName result = typeInfo.getJavaFieldType();
250
251 assertNotNull(result);
252 assertTrue(result instanceof ParameterizedTypeName, "Expected ParameterizedTypeName");
253
254 ParameterizedTypeName paramType = (ParameterizedTypeName) result;
255 assertEquals(ClassName.get(Map.class), paramType.rawType);
256 assertEquals(2, paramType.typeArguments.size());
257
258
259 TypeName keyType = paramType.typeArguments.get(0);
260 assertEquals(ClassName.get(String.class), keyType);
261
262
263 TypeName valueType = paramType.typeArguments.get(1);
264 assertTrue(valueType instanceof WildcardTypeName, "Expected WildcardTypeName for value type");
265
266 WildcardTypeName wildcardType = (WildcardTypeName) valueType;
267 assertEquals(1, wildcardType.upperBounds.size());
268 assertEquals(itemClass, wildcardType.upperBounds.get(0));
269 }
270
271
272
273
274 @Test
275 void testGetJavaFieldTypeReturnsSingletonWhenMaxOccursIsOne() {
276 ClassName itemClass = ClassName.get(Object.class);
277 IBindingConfiguration bindingConfig = ObjectUtils.notNull(context.mock(IBindingConfiguration.class));
278 DefaultTypeResolver typeResolver = new DefaultTypeResolver(bindingConfig);
279
280 context.checking(new Expectations() {
281 {
282 allowing(parentTypeInfo).getTypeResolver();
283 will(returnValue(typeResolver));
284
285 allowing(choiceGroupInstance).getMaxOccurs();
286 will(returnValue(1));
287
288 allowing(choiceGroupInstance).getContainingDefinition();
289 will(returnValue(assemblyDefinition));
290
291 allowing(bindingConfig).getBindingConfigurationForDefinition(assemblyDefinition);
292 will(returnValue(null));
293 }
294 });
295
296 ChoiceGroupTypeInfoImpl typeInfo = new ChoiceGroupTypeInfoImpl(choiceGroupInstance, parentTypeInfo);
297 TypeName result = typeInfo.getJavaFieldType();
298
299 assertNotNull(result);
300 assertEquals(itemClass, result);
301 }
302
303
304
305
306
307 @Test
308 void testGetJavaFieldTypeReturnsListOfObjectWhenNoBindingConfig() {
309 ClassName itemClass = ClassName.get(Object.class);
310 IBindingConfiguration bindingConfig = ObjectUtils.notNull(context.mock(IBindingConfiguration.class));
311 DefaultTypeResolver typeResolver = new DefaultTypeResolver(bindingConfig);
312
313 context.checking(new Expectations() {
314 {
315 allowing(parentTypeInfo).getTypeResolver();
316 will(returnValue(typeResolver));
317
318 allowing(choiceGroupInstance).getMaxOccurs();
319 will(returnValue(-1));
320
321 allowing(choiceGroupInstance).getContainingDefinition();
322 will(returnValue(assemblyDefinition));
323
324 allowing(bindingConfig).getBindingConfigurationForDefinition(assemblyDefinition);
325 will(returnValue(null));
326
327 allowing(choiceGroupInstance).getJsonGroupAsBehavior();
328 will(returnValue(JsonGroupAsBehavior.SINGLETON_OR_LIST));
329 }
330 });
331
332 ChoiceGroupTypeInfoImpl typeInfo = new ChoiceGroupTypeInfoImpl(choiceGroupInstance, parentTypeInfo);
333 TypeName result = typeInfo.getJavaFieldType();
334
335 assertNotNull(result);
336 assertTrue(result instanceof ParameterizedTypeName, "Expected ParameterizedTypeName");
337
338 ParameterizedTypeName paramType = (ParameterizedTypeName) result;
339 assertEquals(ClassName.get(List.class), paramType.rawType);
340 assertEquals(1, paramType.typeArguments.size());
341 assertEquals(itemClass, paramType.typeArguments.get(0));
342 }
343
344
345
346
347 @Test
348 void testGetJavaFieldTypeWithMaxOccursGreaterThanOne() {
349 IBindingConfiguration bindingConfig = ObjectUtils.notNull(context.mock(IBindingConfiguration.class));
350 IDefinitionBindingConfiguration defConfig
351 = ObjectUtils.notNull(context.mock(IDefinitionBindingConfiguration.class));
352 IChoiceGroupBindingConfiguration choiceConfig
353 = ObjectUtils.notNull(context.mock(IChoiceGroupBindingConfiguration.class));
354
355 String groupAsName = "test-choices";
356 String itemTypeName = "com.example.ITestInterface";
357
358 Map<String, IChoiceGroupBindingConfiguration> choiceGroupBindings = new HashMap<>();
359 choiceGroupBindings.put(groupAsName, choiceConfig);
360
361 DefaultTypeResolver typeResolver = new DefaultTypeResolver(bindingConfig);
362
363 context.checking(new Expectations() {
364 {
365 allowing(parentTypeInfo).getTypeResolver();
366 will(returnValue(typeResolver));
367
368 allowing(choiceGroupInstance).getMaxOccurs();
369 will(returnValue(5));
370
371 allowing(choiceGroupInstance).getContainingDefinition();
372 will(returnValue(assemblyDefinition));
373
374 allowing(bindingConfig).getBindingConfigurationForDefinition(assemblyDefinition);
375 will(returnValue(defConfig));
376
377 allowing(choiceGroupInstance).getGroupAsName();
378 will(returnValue(groupAsName));
379
380 allowing(defConfig).getChoiceGroupBindings();
381 will(returnValue(choiceGroupBindings));
382
383 allowing(choiceConfig).getItemTypeName();
384 will(returnValue(itemTypeName));
385
386 allowing(choiceConfig).isUseWildcard();
387 will(returnValue(true));
388
389 allowing(choiceGroupInstance).getJsonGroupAsBehavior();
390 will(returnValue(JsonGroupAsBehavior.SINGLETON_OR_LIST));
391 }
392 });
393
394 ChoiceGroupTypeInfoImpl typeInfo = new ChoiceGroupTypeInfoImpl(choiceGroupInstance, parentTypeInfo);
395 TypeName result = typeInfo.getJavaFieldType();
396
397 assertNotNull(result);
398 assertTrue(result instanceof ParameterizedTypeName, "Expected ParameterizedTypeName");
399
400 ParameterizedTypeName paramType = (ParameterizedTypeName) result;
401 assertEquals(ClassName.get(List.class), paramType.rawType);
402
403 TypeName itemType = paramType.typeArguments.get(0);
404 assertTrue(itemType instanceof WildcardTypeName, "Expected WildcardTypeName");
405 }
406 }