fix: fixed bugs in RequestDeserializer, and wrote Proptests for it

This commit is contained in:
Yannik Bretschneider 2021-05-28 16:20:40 +02:00
parent da1d72d61a
commit a25231fb3e
2 changed files with 125 additions and 4 deletions

View File

@ -43,7 +43,9 @@ public class RequestDeserializer extends JsonDeserializer<Request> {
.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,

View File

@ -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<GameRequest> 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<CharacterRequest> characterRequests() {
final var characterRequestTypes = List.of(
RequestType.MeleeAttackRequest,
RequestType.RangedAttackRequest,
RequestType.MoveRequest,
RequestType.ExchangeInfinityStoneRequest,
RequestType.UseInfinityStoneRequest);
Arbitrary<RequestType> types = Arbitraries.of(RequestType.class)
.filter(characterRequestTypes::contains);
Arbitrary<IntVector2> positions = Arbitraries.integers()
.greaterOrEqual(0)
.tuple2()
.map(x -> new IntVector2(x.get1(), x.get2()));
Arbitrary<Integer> characterIDNums = Arbitraries.integers()
.between(0, 5);
Arbitrary<EntityType> characterTypes = Arbitraries.of(true, false)
.map(x -> x ? EntityType.P1 : EntityType.P2);
Arbitrary<EntityID> characterIDs = Combinators.combine(characterTypes, characterIDNums)
.as(EntityID::new);
Arbitrary<EntityID> stoneIDs = Arbitraries.integers()
.greaterOrEqual(0)
.map(x -> new EntityID(EntityType.Rocks, x));
Arbitrary<StoneType> stoneTypes = Arbitraries.of(StoneType.class);
Arbitrary<Integer> 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();
});
}
}