Skip to content

Commit 3a4d88b

Browse files
authored
Merge pull request #1172 from WebFuzzing/issue-#1171
#1171 support for enums as keys for maps
2 parents e3d2177 + ccad429 commit 3a4d88b

File tree

3 files changed

+63
-3
lines changed

3 files changed

+63
-3
lines changed

client-java/instrumentation/src/main/java/org/evomaster/client/java/instrumentation/object/ClassToSchema.java

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -329,11 +329,36 @@ private static String getSchema(Type type, Boolean useRefObject, List<Class<?>>
329329
return fieldArraySchema(klass, pType, nested, allNested, objectFieldsRequired, converters);
330330
}
331331

332-
if ((klass != null && Map.class.isAssignableFrom(klass)) || pType != null && Map.class.isAssignableFrom((Class) pType.getRawType())) {
332+
if ((klass != null && Map.class.isAssignableFrom(klass))
333+
|| pType != null && Map.class.isAssignableFrom((Class) pType.getRawType())) {
334+
333335
if (pType != null && pType.getActualTypeArguments().length > 0) {
334336
Type keyType = pType.getActualTypeArguments()[0];
335-
if (keyType != String.class) {
336-
throw new IllegalStateException("only support Map with String key");
337+
338+
if(keyType instanceof Class && ((Class<?>) keyType).isEnum()) {
339+
/*
340+
peculiar case... the keys of a map are an enumeration, so can have only a restricted
341+
set of them. can't add any key. adding constraints would be quite complex...
342+
so maybe a valid option is to treat it as an object?
343+
TODO should verify if any side-effects, eg when dealing with null VS undefined
344+
*/
345+
Type valueType = pType.getActualTypeArguments()[1];
346+
List<String> properties = new ArrayList<>();
347+
List<String> propertiesNames = new ArrayList<>();
348+
Class<?> enumKeys = (Class<?>) keyType;
349+
for(Object e : enumKeys.getEnumConstants()){
350+
String key = e.toString();
351+
String fieldName = key;
352+
String fieldSchema;
353+
fieldSchema = named(fieldName, getOrDeriveSchema(valueType, true, nested, false, converters));
354+
properties.add(fieldSchema);
355+
propertiesNames.add("\"" + fieldName + "\"");
356+
}
357+
return fieldObjectSchema(properties, propertiesNames, false);
358+
}
359+
360+
if (keyType != String.class ) {
361+
throw new IllegalStateException("only support Map with String and Enum keys. Not supported type: " + keyType);
337362
}
338363
}
339364

client-java/instrumentation/src/test/java/org/evomaster/client/java/instrumentation/object/ClassToSchemaTest.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,33 @@ private JsonObject parse(String schema){
2424
return JsonParser.parseString("{" + schema + "}").getAsJsonObject();
2525
}
2626

27+
28+
@Test
29+
public void testDtoEnumMap(){
30+
31+
String schema = ClassToSchema.getOrDeriveNonNestedSchema(DtoEnumMap.class);
32+
JsonObject json = parse(schema);
33+
34+
JsonObject obj = json.get(DtoEnumMap.class.getName()).getAsJsonObject();
35+
assertNotNull(obj);
36+
assertNotNull(obj.get("type"));
37+
assertNotNull(obj.get("properties"));
38+
assertEquals(2, obj.entrySet().size());
39+
40+
assertEquals("object", obj.get("type").getAsString());
41+
42+
JsonObject propertiesJson = obj.get("properties").getAsJsonObject();
43+
assertEquals(1, propertiesJson.entrySet().size());
44+
45+
JsonObject data = propertiesJson.get("data").getAsJsonObject();
46+
JsonObject propertiesData = data.get("properties").getAsJsonObject();
47+
assertEquals(3, propertiesData.entrySet().size());
48+
49+
assertEquals("boolean", propertiesData.get("ONE").getAsJsonObject().get("type").getAsString());
50+
assertEquals("boolean", propertiesData.get("TWO").getAsJsonObject().get("type").getAsString());
51+
assertEquals("boolean", propertiesData.get("THREE").getAsJsonObject().get("type").getAsString());
52+
}
53+
2754
@Test
2855
public void testBase(){
2956

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package org.evomaster.client.java.instrumentation.object.dtos;
2+
3+
import java.util.Map;
4+
5+
public class DtoEnumMap {
6+
7+
public Map<SimpleEnum, Boolean> data;
8+
}

0 commit comments

Comments
 (0)