Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make it possible to use Optional on payloads #2229

Merged
merged 1 commit into from
Nov 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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());
}

Expand Down Expand Up @@ -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;
}
Expand Down
34 changes: 28 additions & 6 deletions client/tck/src/main/java/tck/graphql/typesafe/Animal.java
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -10,32 +11,38 @@ public class Animal {
private OptionalInt numberOfLegs;
private OptionalLong numberOfTeeth;
private OptionalDouble price;
private Optional<String> alias;

public Animal() {
}

public Animal(String name,
OptionalInt numberOfLegs,
OptionalLong numberOfTeeth,
OptionalDouble price) {
OptionalDouble price,
Optional<String> 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<String> alias) {
this(name, null, null, null, alias);
}

public String getName() {
Expand Down Expand Up @@ -70,6 +77,14 @@ public void setPrice(OptionalDouble price) {
this.price = price;
}

public Optional<String> getAlias() {
return alias;
}

public void setAlias(Optional<String> alias) {
this.alias = alias;
}

@Override
public boolean equals(Object o) {
if (this == o)
Expand All @@ -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 + "]";
}
}
60 changes: 39 additions & 21 deletions client/tck/src/main/java/tck/graphql/typesafe/OptionalBehavior.java
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ void optionalIntOutputTest() {

List<Animal> 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)),
Expand All @@ -195,7 +195,7 @@ void optionalLongOutputTest() {
AnimalApi api = fixture.build(AnimalApi.class);
List<Animal> 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)),
Expand All @@ -209,7 +209,7 @@ void optionalDoubleOutputTest() {
AnimalApi api = fixture.build(AnimalApi.class);
List<Animal> 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)),
Expand All @@ -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<Animal> 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
Expand All @@ -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<Animal> 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
Expand All @@ -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)));
Expand All @@ -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<Animal> 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
Expand All @@ -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)));
Expand Down
Loading