diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/model/graphql/GraphQLRequestSerializer.java b/src/main/java/com/kobylynskyi/graphql/codegen/model/graphql/GraphQLRequestSerializer.java index 8f145d901..885dabc80 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/model/graphql/GraphQLRequestSerializer.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/model/graphql/GraphQLRequestSerializer.java @@ -145,7 +145,7 @@ public static String getEntry(Object input) { /** * Serialize object to a string * - * @param input can be any object or collection of objects. + * @param input can be any object or collection/map of objects. * @param useObjectMapper if true, then use Jackson's ObjectMapper to convert from object to string, * otherwise use toString * @return serialized object @@ -154,19 +154,16 @@ public static String getEntry(Object input) { public static String getEntry(Object input, boolean useObjectMapper) { if (input == null) { return null; - } - if (input instanceof Collection) { - StringJoiner joiner = new StringJoiner(", ", "[ ", " ]"); - for (Object collectionEntry : (Collection) input) { - joiner.add(getEntry(collectionEntry, useObjectMapper)); - } - return joiner.toString(); - } - if (useObjectMapper) { + } else if (useObjectMapper) { return objectMapperWriteValueAsString(input); - } - if (input instanceof Enum) { - return input.toString(); + } else if (input instanceof Collection) { + return serializeCollection((Collection) input, useObjectMapper); + } else if (input instanceof Map) { + return serializeMap((Map) input, useObjectMapper); + } else if (input instanceof Map.Entry) { + return serializeMapEntry((Map.Entry) input, useObjectMapper); + } else if (input instanceof Enum) { + return serializeEnum((Enum) input); } else if (input instanceof String) { return escapeJsonString(input.toString()); } else if (input.getClass().getName().equals("scala.Some")) { // TODO: move to Scala Serializer @@ -180,13 +177,29 @@ public static String getEntry(Object input, boolean useObjectMapper) { } } + public static String serializeCollection(Collection input, boolean useObjectMapper) { + StringJoiner joiner = new StringJoiner(", ", "[ ", " ]"); + for (Object entry : input) { + joiner.add(getEntry(entry, useObjectMapper)); + } + return joiner.toString(); + } - public static String objectMapperWriteValueAsString(Object input) { - try { - return OBJECT_MAPPER.writeValueAsString(input); - } catch (JsonProcessingException e) { - throw new UnableToBuildJsonQueryException(e); + public static String serializeMap(Map input, boolean useObjectMapper) { + StringJoiner joiner = new StringJoiner(", ", "{ ", " }"); + for (Map.Entry entry : input.entrySet()) { + joiner.add(getEntry(entry, useObjectMapper)); } + return joiner.toString(); + } + + public static String serializeMapEntry(Map.Entry input, boolean useObjectMapper) { + // no need to quote String key + return input.getKey() + ": " + getEntry(input.getValue(), useObjectMapper); + } + + public static String serializeEnum(Enum input) { + return input.toString(); } /** @@ -231,4 +244,12 @@ public static String escapeJsonString(String stringValue) { return sb.toString(); } + public static String objectMapperWriteValueAsString(Object input) { + try { + return OBJECT_MAPPER.writeValueAsString(input); + } catch (JsonProcessingException e) { + throw new UnableToBuildJsonQueryException(e); + } + } + } diff --git a/src/test/java/com/kobylynskyi/graphql/codegen/model/graphql/GraphQLRequestSerializerTest.java b/src/test/java/com/kobylynskyi/graphql/codegen/model/graphql/GraphQLRequestSerializerTest.java index 1aa928c38..aa90a4378 100644 --- a/src/test/java/com/kobylynskyi/graphql/codegen/model/graphql/GraphQLRequestSerializerTest.java +++ b/src/test/java/com/kobylynskyi/graphql/codegen/model/graphql/GraphQLRequestSerializerTest.java @@ -26,6 +26,8 @@ import java.time.ZoneOffset; import java.time.ZonedDateTime; import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; import java.util.function.Function; import java.util.stream.Stream; @@ -422,6 +424,7 @@ void serialize_collectionRequest_Null(String name, Function serializer, + Function expectedQueryDecorator) { + Map entries = new HashMap<>(); + entries.put("entryInt", 1); + entries.put("entryString", "2"); + entries.put("entryFloat", 3.3); + entries.put("entryNull", null); + EventsByIdsQueryRequest request = new EventsByIdsQueryRequest.Builder() + .setContextId("something") + .setIds(null) + .setTranslated(false) + .setEntries(entries) + .build(); + GraphQLRequest graphQLRequest = new GraphQLRequest(request, + new EventResponseProjection() + .id() + ); + String serializedQuery = serializer.apply(graphQLRequest).replaceAll(" +", " ").trim(); + String expectedQueryStr = "query eventsByIds { " + + "eventsByIds(contextId: \"something\", translated: false, entries: " + + "{ entryNull: null, entryInt: 1, entryFloat: 3.3, entryString: \"2\" }){ id } }"; + assertEquals(expectedQueryDecorator.apply(expectedQueryStr), serializedQuery); + } + @ParameterizedTest(name = "{0}") @MethodSource("provideAllSerializers") void serialize_AllInputsNull(String name, Function serializer, diff --git a/src/test/java/com/kobylynskyi/graphql/codegen/model/graphql/data/EventsByIdsQueryRequest.java b/src/test/java/com/kobylynskyi/graphql/codegen/model/graphql/data/EventsByIdsQueryRequest.java index 9964789d9..d20480962 100644 --- a/src/test/java/com/kobylynskyi/graphql/codegen/model/graphql/data/EventsByIdsQueryRequest.java +++ b/src/test/java/com/kobylynskyi/graphql/codegen/model/graphql/data/EventsByIdsQueryRequest.java @@ -37,6 +37,10 @@ public void setTranslated(Boolean translated) { this.input.put("translated", translated); } + public void setEntries(Map entries) { + this.input.put("entries", entries); + } + @Override public GraphQLOperation getOperationType() { return OPERATION_TYPE; @@ -72,6 +76,7 @@ public static class Builder { private String contextId; private Collection ids; private Boolean translated; + private Map entries; public Builder() { } @@ -91,12 +96,18 @@ public Builder setTranslated(Boolean translated) { return this; } + public Builder setEntries(Map entries) { + this.entries = entries; + return this; + } + public EventsByIdsQueryRequest build() { EventsByIdsQueryRequest obj = new EventsByIdsQueryRequest(); obj.setContextId(contextId); obj.setIds(ids); obj.setTranslated(translated); + obj.setEntries(entries); return obj; }