Skip to content

Commit 4bba7f0

Browse files
committed
test: expand edge-case coverage for mapper and class refs
1 parent cc815e0 commit 4bba7f0

8 files changed

Lines changed: 206 additions & 0 deletions

File tree

modules/deserializer/src/test/java/org/msuo/config2java/CoreLeafParsingTest.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,19 @@ void enum_unknown_reportsEnumUnknown() {
4141
ConfigDeserializationException ex = fails(obj("mode", "NOPE"), EnumLeaf.class);
4242
assertSingleError(ex, ConfigErrorTypes.EnumUnknown.class, "mode");
4343
}
44+
45+
@Test
46+
void enum_nonString_reportsEnumExpectedString() {
47+
ConfigDeserializationException ex = fails(obj("mode", 1), EnumLeaf.class);
48+
assertSingleError(ex, ConfigErrorTypes.EnumExpectedString.class, "mode");
49+
}
50+
51+
@Test
52+
void leafString_nonScalar_reportsExpectedScalar() {
53+
ConfigDeserializationException ex = fails(
54+
obj("name", new Object()),
55+
StringLeaf.class
56+
);
57+
assertSingleError(ex, ConfigErrorTypes.ExpectedScalar.class, "name");
58+
}
4459
}

modules/deserializer/src/test/java/org/msuo/config2java/CoreOptionalsCollectionsAndMapsTest.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,22 @@ void mapKeyWrongType_reportsNoOneArgCtorOnKeyPath() {
6464
);
6565
assertSingleError(ex, ConfigErrorTypes.NoOneArgCtor.class, "limits", "{foo}");
6666
}
67+
68+
@Test
69+
void listGivenScalar_reportsCollectionExpected() {
70+
ConfigDeserializationException ex = fails(
71+
obj("tags", 1),
72+
ListOfLeaf.class
73+
);
74+
assertSingleError(ex, ConfigErrorTypes.CollectionExpected.class, "tags");
75+
}
76+
77+
@Test
78+
void mapGivenScalar_reportsMapExpected() {
79+
ConfigDeserializationException ex = fails(
80+
obj("limits", 1),
81+
MapOfLeaf.class
82+
);
83+
assertSingleError(ex, ConfigErrorTypes.MapExpected.class, "limits");
84+
}
6785
}

modules/deserializer/src/test/java/org/msuo/config2java/CoreTypeEdgeCasesTest.java

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import static org.junit.jupiter.api.Assertions.*;
44

55
import java.lang.reflect.Field;
6+
import java.lang.reflect.InvocationTargetException;
67
import java.lang.reflect.ParameterizedType;
78
import java.lang.reflect.Type;
89
import java.lang.reflect.WildcardType;
@@ -101,6 +102,36 @@ static final class ClassRefSuperclassHolder {
101102
public Class<LocalBase> impl;
102103
}
103104

105+
static final class GenericClassRefHolder<U> {
106+
public Class<U> impl;
107+
}
108+
109+
abstract static class AbstractLeaf {
110+
AbstractLeaf(String value) {}
111+
}
112+
113+
static final class AbstractLeafHolder {
114+
public AbstractLeaf value;
115+
}
116+
117+
static final class ThrowingNoArg {
118+
ThrowingNoArg() {
119+
throw new IllegalStateException("boom");
120+
}
121+
}
122+
123+
static final class ThrowingNoArgHolder {
124+
public ThrowingNoArg bad;
125+
}
126+
127+
abstract static class AbstractNoArg {
128+
AbstractNoArg() {}
129+
}
130+
131+
static final class AbstractNoArgHolder {
132+
public AbstractNoArg bad;
133+
}
134+
104135
@Test
105136
void classReferenceField_resolvesAssignableClass() {
106137
ClassRefHolder cfg = ObjectMapper.deserialize(
@@ -159,6 +190,103 @@ void classReferenceField_acceptsSubclassForSuperclassField() {
159190
assertEquals(LocalDerived.class, cfg.impl);
160191
}
161192

193+
@Test
194+
void classReferenceField_withUnresolvedTypeVariable_reportsUnsupportedType() {
195+
ConfigDeserializationException ex = assertThrows(
196+
ConfigDeserializationException.class,
197+
() -> ObjectMapper.deserialize(
198+
wrap(obj("impl", LocalDerived.class.getName())),
199+
GenericClassRefHolder.class
200+
)
201+
);
202+
assertEquals(
203+
ConfigErrorTypes.UnsupportedType.class,
204+
ex.getErrors().get(0).getErrorType().getClass()
205+
);
206+
assertEquals(java.util.Arrays.asList("impl"), ex.getErrors().get(0).getPathSegments());
207+
}
208+
209+
@Test
210+
void leafCtorInstantiationFailure_reportsCtorCallFailed() {
211+
ConfigDeserializationException ex = assertThrows(
212+
ConfigDeserializationException.class,
213+
() -> ObjectMapper.deserialize(
214+
wrap(obj("value", "x")),
215+
AbstractLeafHolder.class
216+
)
217+
);
218+
assertEquals(
219+
ConfigErrorTypes.CtorCallFailed.class,
220+
ex.getErrors().get(0).getErrorType().getClass()
221+
);
222+
assertEquals(java.util.Arrays.asList("value"), ex.getErrors().get(0).getPathSegments());
223+
}
224+
225+
@Test
226+
void nestedNoArgConstructorThrowing_reportsCtorFailed() {
227+
ConfigDeserializationException ex = assertThrows(
228+
ConfigDeserializationException.class,
229+
() -> ObjectMapper.deserialize(
230+
wrap(obj("bad", obj())),
231+
ThrowingNoArgHolder.class
232+
)
233+
);
234+
assertEquals(
235+
ConfigErrorTypes.CtorFailed.class,
236+
ex.getErrors().get(0).getErrorType().getClass()
237+
);
238+
assertEquals(java.util.Arrays.asList("bad"), ex.getErrors().get(0).getPathSegments());
239+
}
240+
241+
@Test
242+
void nestedAbstractNoArgType_reportsInstantiateFailed() {
243+
ConfigDeserializationException ex = assertThrows(
244+
ConfigDeserializationException.class,
245+
() -> ObjectMapper.deserialize(
246+
wrap(obj("bad", obj())),
247+
AbstractNoArgHolder.class
248+
)
249+
);
250+
assertEquals(
251+
ConfigErrorTypes.InstantiateFailed.class,
252+
ex.getErrors().get(0).getErrorType().getClass()
253+
);
254+
assertEquals(java.util.Arrays.asList("bad"), ex.getErrors().get(0).getPathSegments());
255+
}
256+
257+
@Test
258+
void reflectionMapper_fieldWriteAccessBranch_mapsToFieldSetAccess() {
259+
ConfigErrorType error = ReflectionErrorMapper.fieldWriteError(
260+
new IllegalAccessException("x")
261+
);
262+
assertEquals(ConfigErrorTypes.FieldSetAccess.class, error.getClass());
263+
}
264+
265+
@Test
266+
void reflectionMapper_fieldWriteTypeBranch_mapsToFieldSetTypeMismatch() {
267+
ConfigErrorType error = ReflectionErrorMapper.fieldWriteError(
268+
new IllegalArgumentException("x")
269+
);
270+
assertEquals(ConfigErrorTypes.FieldSetTypeMismatch.class, error.getClass());
271+
}
272+
273+
@Test
274+
void reflectionMapper_fieldReadBranch_mapsToFieldReadAccess() {
275+
ConfigErrorType error = ReflectionErrorMapper.fieldReadError(
276+
new RuntimeException("x")
277+
);
278+
assertEquals(ConfigErrorTypes.FieldReadAccess.class, error.getClass());
279+
}
280+
281+
@Test
282+
void reflectionMapper_invocationCtorBranch_mapsToCtorFailed() {
283+
ConfigErrorType error = ReflectionErrorMapper.instantiateError(
284+
AbstractNoArg.class,
285+
new InvocationTargetException(new IllegalStateException("boom"))
286+
);
287+
assertEquals(ConfigErrorTypes.CtorFailed.class, error.getClass());
288+
}
289+
162290
private static java.util.Map<String, Object> obj(Object... kvs) {
163291
java.util.LinkedHashMap<String, Object> out = new java.util.LinkedHashMap<>();
164292
for (int i = 0; i < kvs.length; i += 2) {

modules/groovy2java/src/test/java/org/msuo/config2java/GroovyReflectionEdgeCasesTest.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,15 @@ void classReferenceField_rejectsNonAssignableClass() {
7878
assertSingleError(ex, ConfigErrorTypes.ClassRefNotAssignable.class, "impl");
7979
}
8080

81+
@Test
82+
void classReferenceField_rejectsUnknownClassName() {
83+
ConfigDeserializationException ex = fails(
84+
"return [impl: 'no.such.Type']",
85+
ClassReferenceField.class
86+
);
87+
assertSingleError(ex, ConfigErrorTypes.ClassRefNotFound.class, "impl");
88+
}
89+
8190
@Test
8291
void classReferenceField_requiresStringValue() {
8392
ConfigDeserializationException ex = fails(

modules/json2java/src/test/java/org/msuo/config2java/JsonReflectionEdgeCasesTest.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,15 @@ void classReferenceField_rejectsNonAssignableClass() {
7878
assertSingleError(ex, ConfigErrorTypes.ClassRefNotAssignable.class, "impl");
7979
}
8080

81+
@Test
82+
void classReferenceField_rejectsUnknownClassName() {
83+
ConfigDeserializationException ex = fails(
84+
"{\"impl\":\"no.such.Type\"}",
85+
ClassReferenceField.class
86+
);
87+
assertSingleError(ex, ConfigErrorTypes.ClassRefNotFound.class, "impl");
88+
}
89+
8190
@Test
8291
void classReferenceField_requiresStringValue() {
8392
ConfigDeserializationException ex = fails(

modules/lua2java/src/test/java/org/msuo/config2java/LuaReflectionEdgeCasesTest.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,15 @@ void classReferenceField_rejectsNonAssignableClass() {
7878
assertSingleError(ex, ConfigErrorTypes.ClassRefNotAssignable.class, "impl");
7979
}
8080

81+
@Test
82+
void classReferenceField_rejectsUnknownClassName() {
83+
ConfigDeserializationException ex = fails(
84+
"return { impl = 'no.such.Type' }",
85+
ClassReferenceField.class
86+
);
87+
assertSingleError(ex, ConfigErrorTypes.ClassRefNotFound.class, "impl");
88+
}
89+
8190
@Test
8291
void classReferenceField_requiresStringValue() {
8392
ConfigDeserializationException ex = fails(

modules/toml2java/src/test/java/org/msuo/config2java/TomlReflectionEdgeCasesTest.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,15 @@ void classReferenceField_rejectsNonAssignableClass() {
8181
assertSingleError(ex, ConfigErrorTypes.ClassRefNotAssignable.class, "impl");
8282
}
8383

84+
@Test
85+
void classReferenceField_rejectsUnknownClassName() {
86+
ConfigDeserializationException ex = fails(
87+
"impl = 'no.such.Type'",
88+
ClassReferenceField.class
89+
);
90+
assertSingleError(ex, ConfigErrorTypes.ClassRefNotFound.class, "impl");
91+
}
92+
8493
@Test
8594
void classReferenceField_requiresStringValue() {
8695
ConfigDeserializationException ex = fails(

modules/xml2java/src/test/java/org/msuo/config2java/XmlReflectionEdgeCasesTest.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,15 @@ void classReferenceField_rejectsNonAssignableClass() {
8181
assertSingleError(ex, ConfigErrorTypes.ClassRefNotAssignable.class, "impl");
8282
}
8383

84+
@Test
85+
void classReferenceField_rejectsUnknownClassName() {
86+
ConfigDeserializationException ex = fails(
87+
"<config><impl>no.such.Type</impl></config>",
88+
ClassReferenceField.class
89+
);
90+
assertSingleError(ex, ConfigErrorTypes.ClassRefNotFound.class, "impl");
91+
}
92+
8493
@Test
8594
void classReferenceField_requiresStringValue() {
8695
ConfigDeserializationException ex = fails(

0 commit comments

Comments
 (0)