From a2741113333a26dfb13690e9dd0d0df8b24dfbc7 Mon Sep 17 00:00:00 2001 From: Marvin Froeder Date: Thu, 21 Nov 2024 16:42:35 -0300 Subject: [PATCH] Make it possible to use Optional on payloads --- .../VertxTypesafeGraphQLClientProxy.java | 9 +++ .../java/tck/graphql/typesafe/Animal.java | 34 +++++++++-- .../graphql/typesafe/OptionalBehavior.java | 60 ++++++++++++------- 3 files changed, 76 insertions(+), 27 deletions(-) diff --git a/client/implementation-vertx/src/main/java/io/smallrye/graphql/client/vertx/typesafe/VertxTypesafeGraphQLClientProxy.java b/client/implementation-vertx/src/main/java/io/smallrye/graphql/client/vertx/typesafe/VertxTypesafeGraphQLClientProxy.java index f9fe262d9..83f122e69 100644 --- a/client/implementation-vertx/src/main/java/io/smallrye/graphql/client/vertx/typesafe/VertxTypesafeGraphQLClientProxy.java +++ b/client/implementation-vertx/src/main/java/io/smallrye/graphql/client/vertx/typesafe/VertxTypesafeGraphQLClientProxy.java @@ -15,6 +15,7 @@ import java.util.Date; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.OptionalDouble; import java.util.OptionalInt; import java.util.OptionalLong; @@ -337,6 +338,9 @@ private JsonValue value(Object value) { if (type.isMap()) { return mapValue(value); } + if (type.isOptional()) { + return optionalValue(value); + } return objectValue(value, type.fields()); } @@ -416,6 +420,11 @@ private JsonArray mapValue(Object value) { return array.build(); } + private JsonValue optionalValue(Object value) { + Optional optional = (Optional) value; + return value(optional.orElse(null)); + } + private Collection values(Object value) { return value.getClass().isArray() ? array(value) : (Collection) value; } diff --git a/client/tck/src/main/java/tck/graphql/typesafe/Animal.java b/client/tck/src/main/java/tck/graphql/typesafe/Animal.java index b3a10ec46..658789d88 100644 --- a/client/tck/src/main/java/tck/graphql/typesafe/Animal.java +++ b/client/tck/src/main/java/tck/graphql/typesafe/Animal.java @@ -1,6 +1,7 @@ package tck.graphql.typesafe; import java.util.Objects; +import java.util.Optional; import java.util.OptionalDouble; import java.util.OptionalInt; import java.util.OptionalLong; @@ -10,6 +11,7 @@ public class Animal { private OptionalInt numberOfLegs; private OptionalLong numberOfTeeth; private OptionalDouble price; + private Optional alias; public Animal() { } @@ -17,25 +19,30 @@ public Animal() { public Animal(String name, OptionalInt numberOfLegs, OptionalLong numberOfTeeth, - OptionalDouble price) { + OptionalDouble price, + Optional alias) { this.name = name; this.numberOfLegs = numberOfLegs; this.numberOfTeeth = numberOfTeeth; this.price = price; + this.alias = alias; } public Animal(String name, OptionalInt numberOfLegs) { - this(name, numberOfLegs, null, null); + this(name, numberOfLegs, null, null, null); } public Animal(String name, OptionalLong numberOfTeeth) { - this(name, null, numberOfTeeth, null); + this(name, null, numberOfTeeth, null, null); } public Animal(String name, OptionalDouble price) { - this(name, null, null, price); + this(name, null, null, price, null); + } + public Animal(String name, Optional alias) { + this(name, null, null, null, alias); } public String getName() { @@ -70,6 +77,14 @@ public void setPrice(OptionalDouble price) { this.price = price; } + public Optional getAlias() { + return alias; + } + + public void setAlias(Optional alias) { + this.alias = alias; + } + @Override public boolean equals(Object o) { if (this == o) @@ -80,11 +95,18 @@ public boolean equals(Object o) { return Objects.equals(name, animal.name) && Objects.equals(numberOfLegs, animal.numberOfLegs) && Objects.equals(numberOfTeeth, animal.numberOfTeeth) && - Objects.equals(price, animal.price); + Objects.equals(price, animal.price) && + Objects.equals(alias, animal.alias); } @Override public int hashCode() { - return Objects.hash(name, numberOfLegs, numberOfTeeth, price); + return Objects.hash(name, numberOfLegs, numberOfTeeth, price, alias); + } + + @Override + public String toString() { + return "Animal [name=" + name + ", numberOfLegs=" + numberOfLegs + ", numberOfTeeth=" + numberOfTeeth + + ", price=" + price + ", alias=" + alias + "]"; } } \ No newline at end of file diff --git a/client/tck/src/main/java/tck/graphql/typesafe/OptionalBehavior.java b/client/tck/src/main/java/tck/graphql/typesafe/OptionalBehavior.java index c351ae0bc..7b3625972 100644 --- a/client/tck/src/main/java/tck/graphql/typesafe/OptionalBehavior.java +++ b/client/tck/src/main/java/tck/graphql/typesafe/OptionalBehavior.java @@ -181,7 +181,7 @@ void optionalIntOutputTest() { List listOfAnimalLegs = api.allAnimalLegs(); then(fixture.query()).isEqualTo("query allAnimalLegs { allAnimalLegs {name numberOfLegs" + - " numberOfTeeth price} }"); + " numberOfTeeth price alias} }"); then(listOfAnimalLegs).containsExactly( new Animal("Lion", OptionalInt.of(4)), new Animal("Centipedes", OptionalInt.of(70)), @@ -195,7 +195,7 @@ void optionalLongOutputTest() { AnimalApi api = fixture.build(AnimalApi.class); List listOfAnimalTeeth = api.allAnimalTeeth(); then(fixture.query()).isEqualTo("query allAnimalTeeth { allAnimalTeeth {name numberOfLegs" + - " numberOfTeeth price} }"); + " numberOfTeeth price alias} }"); then(listOfAnimalTeeth).containsExactly( new Animal("Lion", OptionalLong.of(30)), new Animal("Centipedes", OptionalLong.of(0)), @@ -209,7 +209,7 @@ void optionalDoubleOutputTest() { AnimalApi api = fixture.build(AnimalApi.class); List listOfAnimalPrice = api.allAnimalPrice(); then(fixture.query()).isEqualTo("query allAnimalPrice { allAnimalPrice {name numberOfLegs" + - " numberOfTeeth price} }"); + " numberOfTeeth price alias} }"); then(listOfAnimalPrice).containsExactly( new Animal("Lion", OptionalDouble.of(355655.74)), new Animal("Centipedes", OptionalDouble.of(241.62)), @@ -219,17 +219,18 @@ void optionalDoubleOutputTest() { @Test void optionalIntParameterQuery() { fixture.returnsData("'animalsByLegs':[" + - "{'name':'Snake', 'numberOfLegs':0, 'numberOfTeeth':100, 'price':1648.28}]"); + "{'name':'Snake', 'numberOfLegs':0, 'numberOfTeeth':100, 'price':1648.28, 'alias': 'Max'}]"); AnimalApi api = fixture.build(AnimalApi.class); List animals = api.getAnimalsByLegs(OptionalInt.of(0)); then(fixture.query()).isEqualTo("query animalsByLegs($numberOfLegs: Int) { " + - "animalsByLegs(numberOfLegs: $numberOfLegs) {name numberOfLegs numberOfTeeth price} }"); + "animalsByLegs(numberOfLegs: $numberOfLegs) {name numberOfLegs numberOfTeeth price alias} }"); then(fixture.variables()).isEqualTo("{'numberOfLegs':0}"); then(animals).containsExactly( new Animal("Snake", OptionalInt.of(0), OptionalLong.of(100), - OptionalDouble.of(1648.28))); + OptionalDouble.of(1648.28), + Optional.of("Max"))); } @Test @@ -238,36 +239,51 @@ void optionalIntMutationTest() { AnimalApi api = fixture.build(AnimalApi.class); Animal animal = api.newAnimal(new Animal("Pig", OptionalInt.of(4))); then(fixture.query()).isEqualTo("mutation newAnimal($animal: AnimalInput) " + - "{ newAnimal(animal: $animal) {name numberOfLegs numberOfTeeth price} }"); + "{ newAnimal(animal: $animal) {name numberOfLegs numberOfTeeth price alias} }"); then(fixture.variables()).isEqualTo("{'animal':{'name':'Pig','numberOfLegs':" + "4}}"); then(animal).isEqualTo(new Animal("Pig", OptionalInt.of(4))); } + @Test + void optionalStringMutationTest() { + fixture.returnsData("'newAnimal':{'name':'Pig', 'alias':'Joe'}"); + AnimalApi api = fixture.build(AnimalApi.class); + Animal animal = api.newAnimal(new Animal("Pig", Optional.of("Joe"))); + then(fixture.query()).isEqualTo("mutation newAnimal($animal: AnimalInput) " + + "{ newAnimal(animal: $animal) {name numberOfLegs numberOfTeeth price alias} }"); + then(fixture.variables()).isEqualTo("{'animal':{'name':'Pig','alias':" + + "'Joe'}}"); + then(animal).isEqualTo(new Animal("Pig", Optional.of("Joe"))); + } + @Test void optionalLongParameterQuery() { fixture.returnsData("'animalsByTeeth':[" + - "{'name':'Lion', 'numberOfLegs':4, 'numberOfTeeth':30, 'price':330705.0}, " + - "{'name':'Tiger', 'numberOfLegs':4, 'numberOfTeeth':30, 'price':165352.5}, " + - "{'name':'Rhino', 'numberOfLegs':4, 'numberOfTeeth':30, 'price':2215390.3}]"); + "{'name':'Lion', 'numberOfLegs':4, 'numberOfTeeth':30, 'price':330705.0, 'alias': 'Leo'}, " + + "{'name':'Tiger', 'numberOfLegs':4, 'numberOfTeeth':30, 'price':165352.5, 'alias': 'Diego'}, " + + "{'name':'Rhino', 'numberOfLegs':4, 'numberOfTeeth':30, 'price':2215390.3, 'alias': 'Gloria'}]"); AnimalApi api = fixture.build(AnimalApi.class); List animals = api.getAnimalsByTeeth(OptionalLong.of(30)); then(fixture.query()).isEqualTo("query animalsByTeeth($numberOfTeeth: BigInteger) { " + - "animalsByTeeth(numberOfTeeth: $numberOfTeeth) {name numberOfLegs numberOfTeeth price} }"); + "animalsByTeeth(numberOfTeeth: $numberOfTeeth) {name numberOfLegs numberOfTeeth price alias} }"); then(fixture.variables()).isEqualTo("{'numberOfTeeth':30}"); then(animals).containsExactly( new Animal("Lion", OptionalInt.of(4), OptionalLong.of(30), - OptionalDouble.of(330705.0)), + OptionalDouble.of(330705.0), + Optional.of("Leo")), new Animal("Tiger", OptionalInt.of(4), OptionalLong.of(30), - OptionalDouble.of(165352.5)), + OptionalDouble.of(165352.5), + Optional.of("Diego")), new Animal("Rhino", OptionalInt.of(4), OptionalLong.of(30), - OptionalDouble.of(2215390.3))); + OptionalDouble.of(2215390.3), + Optional.of("Gloria"))); } @Test @@ -276,7 +292,7 @@ void optionalLongMutationTest() { AnimalApi api = fixture.build(AnimalApi.class); Animal animal = api.newAnimal(new Animal("Bat", OptionalLong.of(20))); then(fixture.query()).isEqualTo("mutation newAnimal($animal: AnimalInput) " + - "{ newAnimal(animal: $animal) {name numberOfLegs numberOfTeeth price} }"); + "{ newAnimal(animal: $animal) {name numberOfLegs numberOfTeeth price alias} }"); then(fixture.variables()).isEqualTo("{'animal':{'name':'Bat','numberOfTeeth':" + "20}}"); then(animal).isEqualTo(new Animal("Bat", OptionalLong.of(20))); @@ -285,22 +301,24 @@ void optionalLongMutationTest() { @Test void optionalDoubleParameterQuery() { fixture.returnsData("'animalsByPrice':[{'name':'Elephant'," + - " 'numberOfLegs':4, 'numberOfTeeth':26, 'price':2215390.3}," + - " {'name':'Rhino', 'numberOfLegs':4, 'numberOfTeeth':30, 'price':2215390.3}]"); + " 'numberOfLegs':4, 'numberOfTeeth':26, 'price':2215390.3, 'alias': 'Max'}," + + " {'name':'Rhino', 'numberOfLegs':4, 'numberOfTeeth':30, 'price':2215390.3, 'alias': 'Gloria'}]"); AnimalApi api = fixture.build(AnimalApi.class); List animals = api.getAnimalsByPrice(OptionalDouble.of(2215390.3)); then(fixture.query()).isEqualTo("query animalsByPrice($price: Float) { " + - "animalsByPrice(price: $price) {name numberOfLegs numberOfTeeth price} }"); + "animalsByPrice(price: $price) {name numberOfLegs numberOfTeeth price alias} }"); then(fixture.variables()).isEqualTo("{'price':2215390.3}"); then(animals).containsExactly( new Animal("Elephant", OptionalInt.of(4), OptionalLong.of(26), - OptionalDouble.of(2215390.3)), + OptionalDouble.of(2215390.3), + Optional.of("Max")), new Animal("Rhino", OptionalInt.of(4), OptionalLong.of(30), - OptionalDouble.of(2215390.3))); + OptionalDouble.of(2215390.3), + Optional.of("Gloria"))); } @Test @@ -309,7 +327,7 @@ void optionalDoubleMutationTest() { AnimalApi api = fixture.build(AnimalApi.class); Animal animal = api.newAnimal(new Animal("Labrador", OptionalDouble.of(6610.50))); then(fixture.query()).isEqualTo("mutation newAnimal($animal: AnimalInput) " + - "{ newAnimal(animal: $animal) {name numberOfLegs numberOfTeeth price} }"); + "{ newAnimal(animal: $animal) {name numberOfLegs numberOfTeeth price alias} }"); then(fixture.variables()).isEqualTo("{'animal':{'name':'Labrador','price':" + "6610.5}}"); then(animal).isEqualTo(new Animal("Labrador", OptionalDouble.of(6610.50)));