From a25231fb3e87745707bfde0ab770ec22a840f170 Mon Sep 17 00:00:00 2001 From: Yannik Bretschneider Date: Fri, 28 May 2021 16:20:40 +0200 Subject: [PATCH] fix: fixed bugs in RequestDeserializer, and wrote Proptests for it --- .../json/ingame/RequestDeserializer.java | 4 +- .../json/ingame/RequestDeserializerTest.java | 125 +++++++++++++++++- 2 files changed, 125 insertions(+), 4 deletions(-) diff --git a/src/main/java/uulm/teamname/marvelous/gamelibrary/json/ingame/RequestDeserializer.java b/src/main/java/uulm/teamname/marvelous/gamelibrary/json/ingame/RequestDeserializer.java index 7ad3ca4..3dcccd8 100644 --- a/src/main/java/uulm/teamname/marvelous/gamelibrary/json/ingame/RequestDeserializer.java +++ b/src/main/java/uulm/teamname/marvelous/gamelibrary/json/ingame/RequestDeserializer.java @@ -43,7 +43,9 @@ public class RequestDeserializer extends JsonDeserializer { .withTargetEntity(unwrap(node, "targetEntity", EntityID.class)) .withOriginField(unwrap(node, "originField", IntVector2.class)) .withTargetField(unwrap(node, "targetField", IntVector2.class)) - .withStoneType(unwrap(node, "stoneType", StoneType.class)); + .withStoneType(Optional.ofNullable(unwrap(node, "stoneType", EntityID.class)) + .map(x -> StoneType.valueOf(x.id)) + .orElseGet(() -> null)); switch (requestType) { case DisconnectRequest, diff --git a/src/test/java/uulm/teamname/marvelous/gamelibrary/json/ingame/RequestDeserializerTest.java b/src/test/java/uulm/teamname/marvelous/gamelibrary/json/ingame/RequestDeserializerTest.java index 5e5028a..0f1e624 100644 --- a/src/test/java/uulm/teamname/marvelous/gamelibrary/json/ingame/RequestDeserializerTest.java +++ b/src/test/java/uulm/teamname/marvelous/gamelibrary/json/ingame/RequestDeserializerTest.java @@ -2,12 +2,20 @@ package uulm.teamname.marvelous.gamelibrary.json.ingame; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import net.jqwik.api.*; +import net.jqwik.api.lifecycle.BeforeProperty; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.*; -import uulm.teamname.marvelous.gamelibrary.requests.GameRequest; -import uulm.teamname.marvelous.gamelibrary.requests.Request; -import uulm.teamname.marvelous.gamelibrary.requests.RequestType; + +import uulm.teamname.marvelous.gamelibrary.IntVector2; +import uulm.teamname.marvelous.gamelibrary.entities.EntityID; +import uulm.teamname.marvelous.gamelibrary.entities.EntityType; +import uulm.teamname.marvelous.gamelibrary.entities.StoneType; +import uulm.teamname.marvelous.gamelibrary.requests.*; + +import java.util.List; +import java.util.concurrent.ThreadLocalRandom; public class RequestDeserializerTest { @@ -28,4 +36,115 @@ public class RequestDeserializerTest { assertThat((GameRequest) (mapper.readValue(jsonRepresentingRequest, Request.class))) .isEqualTo(request); } + + @Test + void emptyRequestsThrowException() { + assertThatExceptionOfType(JsonProcessingException.class) + .isThrownBy(() -> mapper.readValue("{}", Request.class)); + } + + @BeforeProperty + void beforeProperty() { + mapper = new ObjectMapper(); + } + + @Property + void gameRequestsGetDeserializedProperly(@ForAll("gameRequests") GameRequest request) throws JsonProcessingException { + var jsonRepresentingRequest = String.format("{ \"requestType\": \"%s\" }", request.type.toString()); + assertThat((GameRequest) mapper.readValue(jsonRepresentingRequest, Request.class)) + .isEqualTo(request); +// System.out.println(request); +// System.out.println(jsonRepresentingRequest); + + } + + @Property + void characterRequestsGetDeserializedProperly(@ForAll("characterRequests") CharacterRequest request) throws JsonProcessingException { + var jsonRepresentingRequest = String.format(""" + { + "requestType": "%s", + "originEntity": {"entityID": "%s", "ID": %d}, + "targetEntity": {"entityID": "%s", "ID": %d}, + "originField": [%d, %d], + "targetField": [%d, %d], + "stoneType": {"entityID": "InfinityStones", "ID": %d}, + "value": %d + } + """, + request.type, + request.originEntity.type, request.originEntity.id, + request.targetEntity.type, request.targetEntity.id, + request.originField.getX(), request.originField.getY(), + request.targetField.getX(), request.targetField.getY(), + request.stoneType.getID(), + request.value); + + assertThat((CharacterRequest) mapper.readValue(jsonRepresentingRequest, Request.class)) + .isEqualTo(request); + } + + + @Provide("gameRequests") + Arbitrary gameRequests() { + final var gameRequestTypes = List.of( + RequestType.PauseStopRequest, + RequestType.PauseStartRequest, + RequestType.EndRoundRequest, + RequestType.DisconnectRequest, + RequestType.Req); + + + return Arbitraries.of(RequestType.class) + .filter(gameRequestTypes::contains) + .map(x -> new RequestBuilder(x).buildGameRequest()); + } + + @Provide("characterRequests") + Arbitrary characterRequests() { + + final var characterRequestTypes = List.of( + RequestType.MeleeAttackRequest, + RequestType.RangedAttackRequest, + RequestType.MoveRequest, + RequestType.ExchangeInfinityStoneRequest, + RequestType.UseInfinityStoneRequest); + + Arbitrary types = Arbitraries.of(RequestType.class) + .filter(characterRequestTypes::contains); + + Arbitrary positions = Arbitraries.integers() + .greaterOrEqual(0) + .tuple2() + .map(x -> new IntVector2(x.get1(), x.get2())); + + Arbitrary characterIDNums = Arbitraries.integers() + .between(0, 5); + + Arbitrary characterTypes = Arbitraries.of(true, false) + .map(x -> x ? EntityType.P1 : EntityType.P2); + + Arbitrary characterIDs = Combinators.combine(characterTypes, characterIDNums) + .as(EntityID::new); + + Arbitrary stoneIDs = Arbitraries.integers() + .greaterOrEqual(0) + .map(x -> new EntityID(EntityType.Rocks, x)); + + Arbitrary stoneTypes = Arbitraries.of(StoneType.class); + + Arbitrary values = Arbitraries.integers(); + + return Combinators.combine(types, positions.tuple2(), characterIDs.tuple2(), stoneIDs, stoneTypes, values) + .as((type, pos, cID, sID, stoneType, val) -> { + return new RequestBuilder(type) + .withOriginField(pos.get1()) + .withTargetField(pos.get2()) + .withOriginEntity(cID.get1()) + .withTargetEntity(ThreadLocalRandom.current().nextBoolean() ? cID.get2() : sID) + .withStoneType(stoneType) + .withValue(val) + .buildCharacterRequest(); + }); + } + }