summaryrefslogtreecommitdiff
path: root/backend/src/test
diff options
context:
space:
mode:
authorjbion <joffrey.bion@amadeus.com>2017-01-20 16:11:24 +0100
committerjbion <joffrey.bion@amadeus.com>2017-01-20 16:11:35 +0100
commitb32cdf5c4f5d0b4f31b3bcfa64fe9328ed78d818 (patch)
treebdda009d448cb6b56415d90eae90eceb138318e4 /backend/src/test
parentMerge remote-tracking branch 'origin/feature/front' (diff)
downloadseven-wonders-b32cdf5c4f5d0b4f31b3bcfa64fe9328ed78d818.tar.gz
seven-wonders-b32cdf5c4f5d0b4f31b3bcfa64fe9328ed78d818.tar.bz2
seven-wonders-b32cdf5c4f5d0b4f31b3bcfa64fe9328ed78d818.zip
Move frontend and backend into 2 separate subprojects
Diffstat (limited to 'backend/src/test')
-rw-r--r--backend/src/test/java/org/luxons/sevenwonders/game/LobbyTest.java170
-rw-r--r--backend/src/test/java/org/luxons/sevenwonders/game/api/TableTest.java49
-rw-r--r--backend/src/test/java/org/luxons/sevenwonders/game/boards/BoardTest.java107
-rw-r--r--backend/src/test/java/org/luxons/sevenwonders/game/boards/MilitaryTest.java72
-rw-r--r--backend/src/test/java/org/luxons/sevenwonders/game/boards/RelativeBoardPositionTest.java44
-rw-r--r--backend/src/test/java/org/luxons/sevenwonders/game/boards/ScienceTest.java113
-rw-r--r--backend/src/test/java/org/luxons/sevenwonders/game/cards/CardBackTest.java15
-rw-r--r--backend/src/test/java/org/luxons/sevenwonders/game/cards/CardTest.java106
-rw-r--r--backend/src/test/java/org/luxons/sevenwonders/game/cards/DecksTest.java110
-rw-r--r--backend/src/test/java/org/luxons/sevenwonders/game/cards/HandRotationDirectionTest.java15
-rw-r--r--backend/src/test/java/org/luxons/sevenwonders/game/cards/HandsTest.java141
-rw-r--r--backend/src/test/java/org/luxons/sevenwonders/game/data/GameDefinitionLoaderTest.java16
-rw-r--r--backend/src/test/java/org/luxons/sevenwonders/game/data/GameDefinitionTest.java25
-rw-r--r--backend/src/test/java/org/luxons/sevenwonders/game/data/definitions/WonderSidePickMethodTest.java96
-rw-r--r--backend/src/test/java/org/luxons/sevenwonders/game/data/serializers/NumericEffectSerializerTest.java128
-rw-r--r--backend/src/test/java/org/luxons/sevenwonders/game/data/serializers/ProductionIncreaseSerializerTest.java203
-rw-r--r--backend/src/test/java/org/luxons/sevenwonders/game/data/serializers/ResourceTypeSerializerTest.java50
-rw-r--r--backend/src/test/java/org/luxons/sevenwonders/game/data/serializers/ResourceTypesSerializerTest.java100
-rw-r--r--backend/src/test/java/org/luxons/sevenwonders/game/data/serializers/ResourcesSerializerTest.java107
-rw-r--r--backend/src/test/java/org/luxons/sevenwonders/game/data/serializers/ScienceProgressSerializerTest.java145
-rw-r--r--backend/src/test/java/org/luxons/sevenwonders/game/effects/BonusPerBoardElementTest.java139
-rw-r--r--backend/src/test/java/org/luxons/sevenwonders/game/effects/DiscountTest.java72
-rw-r--r--backend/src/test/java/org/luxons/sevenwonders/game/effects/GoldIncreaseTest.java78
-rw-r--r--backend/src/test/java/org/luxons/sevenwonders/game/effects/MilitaryReinforcementsTest.java79
-rw-r--r--backend/src/test/java/org/luxons/sevenwonders/game/effects/ProductionIncreaseTest.java85
-rw-r--r--backend/src/test/java/org/luxons/sevenwonders/game/effects/RawPointsIncreaseTest.java61
-rw-r--r--backend/src/test/java/org/luxons/sevenwonders/game/effects/ScienceProgressTest.java38
-rw-r--r--backend/src/test/java/org/luxons/sevenwonders/game/effects/SpecialAbilityActivationTest.java94
-rw-r--r--backend/src/test/java/org/luxons/sevenwonders/game/resources/ProductionTest.java271
-rw-r--r--backend/src/test/java/org/luxons/sevenwonders/game/resources/ResourcesTest.java431
-rw-r--r--backend/src/test/java/org/luxons/sevenwonders/game/resources/TradingRulesTest.java96
-rw-r--r--backend/src/test/java/org/luxons/sevenwonders/game/test/TestUtils.java191
-rw-r--r--backend/src/test/java/org/luxons/sevenwonders/repositories/GameRepositoryTest.java61
-rw-r--r--backend/src/test/java/org/luxons/sevenwonders/repositories/LobbyRepositoryTest.java77
-rw-r--r--backend/src/test/java/org/luxons/sevenwonders/repositories/PlayerRepositoryTest.java73
-rw-r--r--backend/src/test/java/org/luxons/sevenwonders/validation/DestinationAccessValidatorTest.java147
36 files changed, 3805 insertions, 0 deletions
diff --git a/backend/src/test/java/org/luxons/sevenwonders/game/LobbyTest.java b/backend/src/test/java/org/luxons/sevenwonders/game/LobbyTest.java
new file mode 100644
index 00000000..4a12592e
--- /dev/null
+++ b/backend/src/test/java/org/luxons/sevenwonders/game/LobbyTest.java
@@ -0,0 +1,170 @@
+package org.luxons.sevenwonders.game;
+
+import java.util.Arrays;
+
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.theories.DataPoints;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+import org.luxons.sevenwonders.game.Lobby.GameAlreadyStartedException;
+import org.luxons.sevenwonders.game.Lobby.PlayerNameAlreadyUsedException;
+import org.luxons.sevenwonders.game.Lobby.PlayerOverflowException;
+import org.luxons.sevenwonders.game.Lobby.PlayerUnderflowException;
+import org.luxons.sevenwonders.game.Lobby.UnknownPlayerException;
+import org.luxons.sevenwonders.game.data.GameDefinition;
+import org.luxons.sevenwonders.game.data.GameDefinitionLoader;
+
+import static org.junit.Assert.*;
+import static org.junit.Assume.*;
+
+@RunWith(Theories.class)
+public class LobbyTest {
+
+ @DataPoints
+ public static int[] nbPlayers() {
+ return new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+ }
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ private static GameDefinition gameDefinition;
+
+ private Player gameOwner;
+
+ private Lobby lobby;
+
+ @BeforeClass
+ public static void loadDefinition() {
+ gameDefinition = new GameDefinitionLoader().getGameDefinition();
+ }
+
+ @Before
+ public void setUp() {
+ gameOwner = new Player("gameowner", "Game owner");
+ lobby = new Lobby(0, "Test Game", gameOwner, gameDefinition);
+ }
+
+ @Test
+ public void testId() {
+ Lobby l = new Lobby(5, "Test Game", gameOwner, gameDefinition);
+ assertEquals(5, l.getId());
+ }
+
+ @Test
+ public void testName() {
+ Lobby l = new Lobby(5, "Test Game", gameOwner, gameDefinition);
+ assertEquals("Test Game", l.getName());
+ }
+
+ @Test
+ public void isOwner_falseWhenNull() {
+ assertFalse(lobby.isOwner(null));
+ }
+
+ @Test
+ public void isOwner_falseWhenEmptyString() {
+ assertFalse(lobby.isOwner(""));
+ }
+
+ @Test
+ public void isOwner_falseWhenGarbageString() {
+ assertFalse(lobby.isOwner("this is garbage"));
+ }
+
+ @Test
+ public void isOwner_trueWhenOwnerUsername() {
+ assertTrue(lobby.isOwner(gameOwner.getUsername()));
+ }
+
+ @Test
+ public void isOwner_falseWhenOtherPlayerName() {
+ Player player = new Player("testuser", "Test User");
+ lobby.addPlayer(player);
+ assertFalse(lobby.isOwner(player.getUsername()));
+ }
+
+ @Test
+ public void addPlayer_success() {
+ Player player = new Player("testuser", "Test User");
+ lobby.addPlayer(player);
+ assertTrue(lobby.containsUser("testuser"));
+ }
+
+ @Test(expected = PlayerNameAlreadyUsedException.class)
+ public void addPlayer_failsOnSameName() {
+ Player player = new Player("testuser", "Test User");
+ Player player2 = new Player("testuser2", "Test User");
+ lobby.addPlayer(player);
+ lobby.addPlayer(player2);
+ }
+
+ @Test(expected = PlayerOverflowException.class)
+ public void addPlayer_playerOverflowWhenTooMany() {
+ // the owner + the max number gives an overflow
+ addPlayers(gameDefinition.getMaxPlayers());
+ }
+
+ @Test(expected = GameAlreadyStartedException.class)
+ public void addPlayer_failWhenGameStarted() {
+ // total with owner is the minimum
+ addPlayers(gameDefinition.getMinPlayers() - 1);
+ lobby.startGame();
+ lobby.addPlayer(new Player("soonerNextTime", "The Late Guy"));
+ }
+
+ private void addPlayers(int nbPlayers) {
+ for (int i = 0; i < nbPlayers; i++) {
+ Player player = new Player("testuser" + i, "Test User " + i);
+ lobby.addPlayer(player);
+ }
+ }
+
+ @Test
+ public void reorderPlayers_failsOnSameName() {
+ Player player1 = new Player("testuser1", "Test User 1");
+ Player player2 = new Player("testuser2", "Test User 2");
+ Player player3 = new Player("testuser3", "Test User 3");
+ lobby.addPlayer(player1);
+ lobby.addPlayer(player2);
+ lobby.addPlayer(player3);
+ lobby.reorderPlayers(Arrays.asList("testuser3", "testuser1", "testuser2"));
+ assertEquals("testuser3", lobby.getPlayers().get(0).getUsername());
+ assertEquals("testuser1", lobby.getPlayers().get(1).getUsername());
+ assertEquals("testuser2", lobby.getPlayers().get(2).getUsername());
+ }
+
+ @Test(expected = UnknownPlayerException.class)
+ public void reorderPlayers_failsOnUnknownPlayer() {
+ Player player1 = new Player("testuser1", "Test User 1");
+ Player player2 = new Player("testuser2", "Test User 2");
+ Player player3 = new Player("testuser3", "Test User 3");
+ lobby.addPlayer(player1);
+ lobby.addPlayer(player2);
+ lobby.addPlayer(player3);
+ lobby.reorderPlayers(Arrays.asList("testuser4", "testuser1", "testuser2"));
+ }
+
+ @Theory
+ public void startGame_failsBelowMinPlayers(int nbPlayers) {
+ assumeTrue(nbPlayers < gameDefinition.getMinPlayers());
+ thrown.expect(PlayerUnderflowException.class);
+ // there is already the owner
+ addPlayers(nbPlayers - 1);
+ lobby.startGame();
+ }
+
+ @Theory
+ public void startGame_succeedsAboveMinPlayers(int nbPlayers) {
+ assumeTrue(nbPlayers >= gameDefinition.getMinPlayers());
+ assumeTrue(nbPlayers < gameDefinition.getMaxPlayers());
+ // there is already the owner
+ addPlayers(nbPlayers - 1);
+ lobby.startGame();
+ }
+} \ No newline at end of file
diff --git a/backend/src/test/java/org/luxons/sevenwonders/game/api/TableTest.java b/backend/src/test/java/org/luxons/sevenwonders/game/api/TableTest.java
new file mode 100644
index 00000000..9ed0af02
--- /dev/null
+++ b/backend/src/test/java/org/luxons/sevenwonders/game/api/TableTest.java
@@ -0,0 +1,49 @@
+package org.luxons.sevenwonders.game.api;
+
+import org.junit.experimental.theories.DataPoints;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+import org.junit.runner.RunWith;
+import org.luxons.sevenwonders.game.boards.RelativeBoardPosition;
+import org.luxons.sevenwonders.game.test.TestUtils;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assume.assumeTrue;
+
+@RunWith(Theories.class)
+public class TableTest {
+
+ @DataPoints
+ public static int[] nbPlayers() {
+ return new int[] {2, 3, 4, 5, 6, 7, 8};
+ }
+
+ @Theory
+ public void getBoard_wrapLeft(int nbPlayers) {
+ assumeTrue(nbPlayers >= 2);
+ Table table = TestUtils.createTable(nbPlayers);
+ int last = nbPlayers - 1;
+ assertEquals(table.getBoard(last), table.getBoard(0, RelativeBoardPosition.LEFT));
+ assertEquals(table.getBoard(0), table.getBoard(0, RelativeBoardPosition.SELF));
+ assertEquals(table.getBoard(1), table.getBoard(0, RelativeBoardPosition.RIGHT));
+ }
+
+ @Theory
+ public void getBoard_wrapRight(int nbPlayers) {
+ assumeTrue(nbPlayers >= 2);
+ Table table = TestUtils.createTable(nbPlayers);
+ int last = nbPlayers - 1;
+ assertEquals(table.getBoard(last - 1), table.getBoard(last, RelativeBoardPosition.LEFT));
+ assertEquals(table.getBoard(last), table.getBoard(last, RelativeBoardPosition.SELF));
+ assertEquals(table.getBoard(0), table.getBoard(last, RelativeBoardPosition.RIGHT));
+ }
+
+ @Theory
+ public void getBoard_noWrap(int nbPlayers) {
+ assumeTrue(nbPlayers >= 3);
+ Table table = TestUtils.createTable(nbPlayers);
+ assertEquals(table.getBoard(0), table.getBoard(1, RelativeBoardPosition.LEFT));
+ assertEquals(table.getBoard(1), table.getBoard(1, RelativeBoardPosition.SELF));
+ assertEquals(table.getBoard(2), table.getBoard(1, RelativeBoardPosition.RIGHT));
+ }
+} \ No newline at end of file
diff --git a/backend/src/test/java/org/luxons/sevenwonders/game/boards/BoardTest.java b/backend/src/test/java/org/luxons/sevenwonders/game/boards/BoardTest.java
new file mode 100644
index 00000000..f9117146
--- /dev/null
+++ b/backend/src/test/java/org/luxons/sevenwonders/game/boards/BoardTest.java
@@ -0,0 +1,107 @@
+package org.luxons.sevenwonders.game.boards;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+import org.junit.Rule;
+import org.junit.experimental.theories.DataPoints;
+import org.junit.experimental.theories.FromDataPoints;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+import org.luxons.sevenwonders.game.Settings;
+import org.luxons.sevenwonders.game.api.CustomizableSettings;
+import org.luxons.sevenwonders.game.boards.Board.InsufficientFundsException;
+import org.luxons.sevenwonders.game.cards.Color;
+import org.luxons.sevenwonders.game.resources.ResourceType;
+import org.luxons.sevenwonders.game.resources.Resources;
+import org.luxons.sevenwonders.game.test.TestUtils;
+
+import static junit.framework.TestCase.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.*;
+
+@RunWith(Theories.class)
+public class BoardTest {
+
+ @DataPoints("gold")
+ public static int[] goldAmounts() {
+ return new int[]{-3, -1, 0, 1, 2, 3};
+ }
+
+ @DataPoints("nbCards")
+ public static int[] nbCards() {
+ return new int[] {0, 1, 2};
+ }
+
+ @DataPoints
+ public static ResourceType[] resourceTypes() {
+ return ResourceType.values();
+ }
+
+ @DataPoints
+ public static Color[] colors() {
+ return Color.values();
+ }
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ @Theory
+ public void initialGold_respectsSettings(@FromDataPoints("gold") int goldAmountInSettings) {
+ CustomizableSettings customSettings = new CustomizableSettings();
+ customSettings.setInitialGold(goldAmountInSettings);
+ Settings settings = new Settings(5, customSettings);
+ Board board = new Board(TestUtils.createWonder(), null, settings);
+ assertEquals(goldAmountInSettings, board.getGold());
+ }
+
+ @Theory
+ public void initialProduction_containsInitialResource(ResourceType type) {
+ Board board = new Board(TestUtils.createWonder(type), null, new Settings(5));
+ Resources resources = TestUtils.createResources(type);
+ assertTrue(board.getProduction().contains(resources));
+ }
+
+ @Theory
+ public void removeGold_successfulWhenNotTooMuch(@FromDataPoints("gold") int initialGold,
+ @FromDataPoints("gold") int goldRemoved) {
+ assumeTrue(goldRemoved >= 0);
+ assumeTrue(initialGold >= goldRemoved);
+ Board board = new Board(TestUtils.createWonder(), null, new Settings(5));
+ board.setGold(initialGold);
+ board.removeGold(goldRemoved);
+ assertEquals(initialGold - goldRemoved, board.getGold());
+ }
+
+ @Theory
+ public void removeGold_failsWhenTooMuch(@FromDataPoints("gold") int initialGold,
+ @FromDataPoints("gold") int goldRemoved) {
+ assumeTrue(goldRemoved >= 0);
+ assumeTrue(initialGold < goldRemoved);
+ thrown.expect(InsufficientFundsException.class);
+ Board board = new Board(TestUtils.createWonder(), null, new Settings(5));
+ board.setGold(initialGold);
+ board.removeGold(goldRemoved);
+ }
+
+ @Theory
+ public void getNbCardsOfColor_properCount_singleColor(ResourceType type, @FromDataPoints("nbCards") int nbCards,
+ @FromDataPoints("nbCards") int nbOtherCards, Color color) {
+ Board board = new Board(TestUtils.createWonder(type), null, new Settings(5));
+ TestUtils.addCards(board, nbCards, nbOtherCards, color);
+ assertEquals(nbCards, board.getNbCardsOfColor(Collections.singletonList(color)));
+ }
+
+ @Theory
+ public void getNbCardsOfColor_properCount_multiColors(ResourceType type, @FromDataPoints("nbCards") int nbCards1,
+ @FromDataPoints("nbCards") int nbCards2, @FromDataPoints("nbCards") int nbOtherCards, Color color1,
+ Color color2) {
+ Board board = new Board(TestUtils.createWonder(type), null, new Settings(5));
+ TestUtils.addCards(board, nbCards1, color1);
+ TestUtils.addCards(board, nbCards2, color2);
+ TestUtils.addCards(board, nbOtherCards, TestUtils.getDifferentColorFrom(color1, color2));
+ assertEquals(nbCards1 + nbCards2, board.getNbCardsOfColor(Arrays.asList(color1, color2)));
+ }
+} \ No newline at end of file
diff --git a/backend/src/test/java/org/luxons/sevenwonders/game/boards/MilitaryTest.java b/backend/src/test/java/org/luxons/sevenwonders/game/boards/MilitaryTest.java
new file mode 100644
index 00000000..7ef253db
--- /dev/null
+++ b/backend/src/test/java/org/luxons/sevenwonders/game/boards/MilitaryTest.java
@@ -0,0 +1,72 @@
+package org.luxons.sevenwonders.game.boards;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Rule;
+import org.junit.experimental.theories.DataPoints;
+import org.junit.experimental.theories.FromDataPoints;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+import org.luxons.sevenwonders.game.Settings;
+import org.luxons.sevenwonders.game.api.CustomizableSettings;
+import org.luxons.sevenwonders.game.boards.Military.UnknownAgeException;
+
+import static org.junit.Assert.*;
+
+@RunWith(Theories.class)
+public class MilitaryTest {
+
+ @DataPoints("points")
+ public static int[] points() {
+ return new int[] {0, 1, 3, 5};
+ }
+
+ @DataPoints("ages")
+ public static int[] ages() {
+ return new int[] {1, 2, 3};
+ }
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ private static Military createMilitary(int age, int nbPointsPerVictory, int nbPointsPerDefeat) {
+ Map<Integer, Integer> wonPointsPerAge = new HashMap<>();
+ wonPointsPerAge.put(age, nbPointsPerVictory);
+
+ CustomizableSettings customSettings = new CustomizableSettings();
+ customSettings.setWonPointsPerVictoryPerAge(wonPointsPerAge);
+ customSettings.setLostPointsPerDefeat(nbPointsPerDefeat);
+
+ Settings settings = new Settings(5, customSettings);
+ return new Military(settings);
+ }
+
+ @Theory
+ public void victory_addsCorrectPoints(@FromDataPoints("ages") int age, @FromDataPoints("points") int
+ nbPointsPerVictory) {
+ Military military = createMilitary(age, nbPointsPerVictory, 0);
+ int initialPoints = military.getTotalPoints();
+
+ military.victory(age);
+ assertEquals(initialPoints + nbPointsPerVictory, military.getTotalPoints());
+ }
+
+ @Theory
+ public void victory_failsIfUnknownAge(@FromDataPoints("points") int nbPointsPerVictory) {
+ Military military = createMilitary(0, nbPointsPerVictory, 0);
+ thrown.expect(UnknownAgeException.class);
+ military.victory(1);
+ }
+
+ @Theory
+ public void defeat_removesCorrectPoints(@FromDataPoints("points") int nbPointsLostPerDefeat) {
+ Military military = createMilitary(0, 0, nbPointsLostPerDefeat);
+ int initialPoints = military.getTotalPoints();
+
+ military.defeat();
+ assertEquals(initialPoints - nbPointsLostPerDefeat, military.getTotalPoints());
+ }
+} \ No newline at end of file
diff --git a/backend/src/test/java/org/luxons/sevenwonders/game/boards/RelativeBoardPositionTest.java b/backend/src/test/java/org/luxons/sevenwonders/game/boards/RelativeBoardPositionTest.java
new file mode 100644
index 00000000..e95a1e37
--- /dev/null
+++ b/backend/src/test/java/org/luxons/sevenwonders/game/boards/RelativeBoardPositionTest.java
@@ -0,0 +1,44 @@
+package org.luxons.sevenwonders.game.boards;
+
+import org.junit.experimental.theories.DataPoints;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+import static org.junit.Assume.*;
+
+@RunWith(Theories.class)
+public class RelativeBoardPositionTest {
+
+ @DataPoints
+ public static int[] nbPlayers() {
+ return new int[] {1, 2, 3, 5, 7, 9};
+ }
+
+ @Theory
+ public void getIndexFrom_wrapLeft(int nbPlayers) {
+ assumeTrue(nbPlayers >= 2);
+ int last = nbPlayers - 1;
+ assertEquals(last, RelativeBoardPosition.LEFT.getIndexFrom(0, nbPlayers));
+ assertEquals(0, RelativeBoardPosition.SELF.getIndexFrom(0, nbPlayers));
+ assertEquals(1, RelativeBoardPosition.RIGHT.getIndexFrom(0, nbPlayers));
+ }
+
+ @Theory
+ public void getIndexFrom_wrapRight(int nbPlayers) {
+ assumeTrue(nbPlayers >= 2);
+ int last = nbPlayers - 1;
+ assertEquals(last - 1, RelativeBoardPosition.LEFT.getIndexFrom(last, nbPlayers));
+ assertEquals(last, RelativeBoardPosition.SELF.getIndexFrom(last, nbPlayers));
+ assertEquals(0, RelativeBoardPosition.RIGHT.getIndexFrom(last, nbPlayers));
+ }
+
+ @Theory
+ public void getIndexFrom_noWrap(int nbPlayers) {
+ assumeTrue(nbPlayers >= 3);
+ assertEquals(0, RelativeBoardPosition.LEFT.getIndexFrom(1, nbPlayers));
+ assertEquals(1, RelativeBoardPosition.SELF.getIndexFrom(1, nbPlayers));
+ assertEquals(2, RelativeBoardPosition.RIGHT.getIndexFrom(1, nbPlayers));
+ }
+} \ No newline at end of file
diff --git a/backend/src/test/java/org/luxons/sevenwonders/game/boards/ScienceTest.java b/backend/src/test/java/org/luxons/sevenwonders/game/boards/ScienceTest.java
new file mode 100644
index 00000000..067a7eff
--- /dev/null
+++ b/backend/src/test/java/org/luxons/sevenwonders/game/boards/ScienceTest.java
@@ -0,0 +1,113 @@
+package org.luxons.sevenwonders.game.boards;
+
+import org.junit.Test;
+import org.junit.experimental.theories.DataPoints;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+import org.junit.runner.RunWith;
+import org.luxons.sevenwonders.game.test.TestUtils;
+
+import static org.junit.Assert.assertEquals;
+
+@RunWith(Theories.class)
+public class ScienceTest {
+
+ @DataPoints
+ public static int[][] quantitiesWithExpectedPoints() {
+ // compasses, wheels, tablets, jokers, expected points
+ return new int[][]{
+ {0, 0, 0, 1, 1},
+ {0, 0, 1, 0, 1},
+ {0, 0, 0, 2, 4},
+ {0, 0, 1, 1, 4},
+ {0, 0, 2, 0, 4},
+ {0, 0, 0, 3, 10},
+ {0, 0, 1, 2, 10},
+ {0, 1, 1, 1, 10},
+ {1, 1, 1, 0, 10},
+ {0, 0, 0, 4, 16},
+ {0, 0, 1, 3, 16},
+ {0, 0, 2, 2, 16},
+ {0, 0, 3, 1, 16},
+ {0, 0, 4, 0, 16}};
+ }
+
+ @DataPoints
+ public static int[] quantitiesDataPoints() {
+ return new int[] {0, 1, 3, 5, 8};
+ }
+
+ @Test
+ public void addAll_empty() {
+ Science initial = TestUtils.createScience(3, 4, 5, 1);
+ Science empty = new Science();
+ initial.addAll(empty);
+ assertEquals(3, initial.getQuantity(ScienceType.COMPASS));
+ assertEquals(4, initial.getQuantity(ScienceType.WHEEL));
+ assertEquals(5, initial.getQuantity(ScienceType.TABLET));
+ assertEquals(1, initial.getJokers());
+ }
+
+ @Test
+ public void addAll_noJoker() {
+ Science initial = TestUtils.createScience(3, 4, 5, 1);
+ Science other = TestUtils.createScience(1, 2, 3, 0);
+ initial.addAll(other);
+ assertEquals(4, initial.getQuantity(ScienceType.COMPASS));
+ assertEquals(6, initial.getQuantity(ScienceType.WHEEL));
+ assertEquals(8, initial.getQuantity(ScienceType.TABLET));
+ assertEquals(1, initial.getJokers());
+ }
+
+ @Test
+ public void addAll_withJokers() {
+ Science initial = TestUtils.createScience(3, 4, 5, 1);
+ Science other = TestUtils.createScience(0, 0, 0, 3);
+ initial.addAll(other);
+ assertEquals(3, initial.getQuantity(ScienceType.COMPASS));
+ assertEquals(4, initial.getQuantity(ScienceType.WHEEL));
+ assertEquals(5, initial.getQuantity(ScienceType.TABLET));
+ assertEquals(4, initial.getJokers());
+ }
+
+ @Test
+ public void addAll_mixed() {
+ Science initial = TestUtils.createScience(3, 4, 5, 1);
+ Science other = TestUtils.createScience(1, 2, 3, 4);
+ initial.addAll(other);
+ assertEquals(4, initial.getQuantity(ScienceType.COMPASS));
+ assertEquals(6, initial.getQuantity(ScienceType.WHEEL));
+ assertEquals(8, initial.getQuantity(ScienceType.TABLET));
+ assertEquals(5, initial.getJokers());
+ }
+
+ @Theory
+ public void computePoints_compassesOnly_noJoker(int compasses) {
+ Science science = TestUtils.createScience(compasses, 0, 0, 0);
+ assertEquals(compasses * compasses, science.computePoints());
+ }
+
+ @Theory
+ public void computePoints_wheelsOnly_noJoker(int wheels) {
+ Science science = TestUtils.createScience(0, wheels, 0, 0);
+ assertEquals(wheels * wheels, science.computePoints());
+ }
+
+ @Theory
+ public void computePoints_tabletsOnly_noJoker(int tablets) {
+ Science science = TestUtils.createScience(0, 0, tablets, 0);
+ assertEquals(tablets * tablets, science.computePoints());
+ }
+
+ @Theory
+ public void computePoints_allSameNoJoker(int eachSymbol) {
+ Science science = TestUtils.createScience(eachSymbol, eachSymbol, eachSymbol, 0);
+ assertEquals(3 * eachSymbol * eachSymbol + 7 * eachSymbol, science.computePoints());
+ }
+
+ @Theory
+ public void computePoints_expectation(int[] expectation) {
+ Science science = TestUtils.createScience(expectation[0], expectation[1], expectation[2], expectation[3]);
+ assertEquals(expectation[4], science.computePoints());
+ }
+} \ No newline at end of file
diff --git a/backend/src/test/java/org/luxons/sevenwonders/game/cards/CardBackTest.java b/backend/src/test/java/org/luxons/sevenwonders/game/cards/CardBackTest.java
new file mode 100644
index 00000000..d105c33f
--- /dev/null
+++ b/backend/src/test/java/org/luxons/sevenwonders/game/cards/CardBackTest.java
@@ -0,0 +1,15 @@
+package org.luxons.sevenwonders.game.cards;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class CardBackTest {
+
+ @Test
+ public void initializedWithImage() throws Exception {
+ String imagePath = "whateverimage.png";
+ CardBack back = new CardBack(imagePath);
+ assertEquals(imagePath, back.getImage());
+ }
+} \ No newline at end of file
diff --git a/backend/src/test/java/org/luxons/sevenwonders/game/cards/CardTest.java b/backend/src/test/java/org/luxons/sevenwonders/game/cards/CardTest.java
new file mode 100644
index 00000000..4a481442
--- /dev/null
+++ b/backend/src/test/java/org/luxons/sevenwonders/game/cards/CardTest.java
@@ -0,0 +1,106 @@
+package org.luxons.sevenwonders.game.cards;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.luxons.sevenwonders.game.Settings;
+import org.luxons.sevenwonders.game.api.Table;
+import org.luxons.sevenwonders.game.boards.Board;
+import org.luxons.sevenwonders.game.effects.Effect;
+import org.luxons.sevenwonders.game.effects.ProductionIncrease;
+import org.luxons.sevenwonders.game.resources.ResourceType;
+import org.luxons.sevenwonders.game.wonders.Wonder;
+
+import static org.junit.Assert.*;
+import static org.luxons.sevenwonders.game.test.TestUtils.*;
+
+public class CardTest {
+
+ private Table table;
+
+ private Card treeFarmCard;
+
+ @Before
+ public void initBoard() {
+ Settings settings = new Settings(5);
+
+ List<Board> boards = new ArrayList<>(3);
+ boards.add(new Board(new Wonder("TestWonder", ResourceType.WOOD), null, settings));
+ boards.add(new Board(new Wonder("TestWonder", ResourceType.STONE), null, settings));
+ boards.add(new Board(new Wonder("TestWonder", ResourceType.PAPYRUS), null, settings));
+ table = new Table(boards);
+
+ Requirements treeFarmRequirements = new Requirements();
+ treeFarmRequirements.setGold(1);
+
+ ProductionIncrease treeFarmEffect = new ProductionIncrease();
+ treeFarmEffect.getProduction().addChoice(ResourceType.WOOD, ResourceType.CLAY);
+
+ List<Effect> effects = Collections.singletonList(treeFarmEffect);
+
+ treeFarmCard = new Card("Tree Farm", Color.BROWN, treeFarmRequirements, effects, "", null, null);
+ }
+
+ @Test
+ public void playCardCostingMoney() {
+ table.getBoard(0).setGold(3);
+ table.getBoard(1).setGold(3);
+ table.getBoard(2).setGold(3);
+ treeFarmCard.applyTo(table, 0, new ArrayList<>());
+ assertEquals(2, table.getBoard(0).getGold());
+ assertEquals(3, table.getBoard(1).getGold());
+ assertEquals(3, table.getBoard(2).getGold());
+ }
+
+ @Test
+ public void equals_falseWhenNull() {
+ Card card = createCard("TestCard");
+ //noinspection ObjectEqualsNull
+ assertFalse(card.equals(null));
+ }
+
+ @Test
+ public void equals_falseWhenDifferentClass() {
+ Card card = createCard("TestCard");
+ Object object = new Object();
+ //noinspection EqualsBetweenInconvertibleTypes
+ assertFalse(card.equals(object));
+ }
+
+ @Test
+ public void equals_trueWhenSame() {
+ Card card = createCard("TestCard");
+ assertEquals(card, card);
+ }
+
+ @Test
+ public void equals_trueWhenSameContent() {
+ Card card1 = createCard("TestCard");
+ Card card2 = createCard("TestCard");
+ assertTrue(card1.equals(card2));
+ }
+
+ @Test
+ public void equals_falseWhenDifferentName() {
+ Card card1 = createCard("TestCard1");
+ Card card2 = createCard("TestCard2");
+ assertFalse(card1.equals(card2));
+ }
+
+ @Test
+ public void hashCode_sameWhenSameContent() {
+ Card card1 = createCard("TestCard");
+ Card card2 = createCard("TestCard");
+ assertEquals(card1.hashCode(), card2.hashCode());
+ }
+
+ @Test
+ public void hashCode_differentWhenDifferentName() {
+ Card card1 = createCard("TestCard1");
+ Card card2 = createCard("TestCard2");
+ assertNotEquals(card1.hashCode(), card2.hashCode());
+ }
+}
diff --git a/backend/src/test/java/org/luxons/sevenwonders/game/cards/DecksTest.java b/backend/src/test/java/org/luxons/sevenwonders/game/cards/DecksTest.java
new file mode 100644
index 00000000..06060f16
--- /dev/null
+++ b/backend/src/test/java/org/luxons/sevenwonders/game/cards/DecksTest.java
@@ -0,0 +1,110 @@
+package org.luxons.sevenwonders.game.cards;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.theories.DataPoints;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+import org.luxons.sevenwonders.game.cards.Decks.CardNotFoundException;
+import org.luxons.sevenwonders.game.test.TestUtils;
+
+import static org.junit.Assert.*;
+import static org.junit.Assume.*;
+
+@RunWith(Theories.class)
+public class DecksTest {
+
+ @DataPoints
+ public static int[] dataPoints() {
+ return new int[] {1, 2, 3, 5, 10};
+ }
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ private static Decks createDecks(int nbAges, int nbCardsPerAge) {
+ Map<Integer, List<Card>> cardsPerAge = new HashMap<>();
+ for (int age = 1; age <= nbAges; age++) {
+ int firstCardNumber = (age - 1) * nbCardsPerAge;
+ cardsPerAge.put(age, TestUtils.createSampleCards(firstCardNumber, nbCardsPerAge));
+ }
+ return new Decks(cardsPerAge);
+ }
+
+ @Test(expected = CardNotFoundException.class)
+ public void getCard_failsOnNullNameWhenDeckIsEmpty() {
+ Decks decks = createDecks(0, 0);
+ decks.getCard(null);
+ }
+
+ @Test(expected = CardNotFoundException.class)
+ public void getCard_failsOnEmptyNameWhenDeckIsEmpty() {
+ Decks decks = createDecks(0, 0);
+ decks.getCard("");
+ }
+
+ @Test(expected = CardNotFoundException.class)
+ public void getCard_failsWhenDeckIsEmpty() {
+ Decks decks = createDecks(0, 0);
+ decks.getCard("Any name");
+ }
+
+ @Test(expected = CardNotFoundException.class)
+ public void getCard_failsWhenCardIsNotFound() {
+ Decks decks = createDecks(3, 20);
+ decks.getCard("Unknown name");
+ }
+
+ @Test
+ public void getCard_succeedsWhenCardIsFound() {
+ Decks decks = createDecks(3, 20);
+ Card card = decks.getCard("Test Card 3");
+ assertEquals("Test Card 3", card.getName());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void deal_failsOnZeroPlayers() {
+ Decks decks = createDecks(3, 20);
+ decks.deal(1, 0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void deal_failsOnMissingAge() {
+ Decks decks = createDecks(2, 0);
+ decks.deal(4, 10);
+ }
+
+ @Theory
+ public void deal_failsWhenTooFewPlayers(int nbPlayers, int nbCards) {
+ assumeTrue(nbCards % nbPlayers != 0);
+ thrown.expect(IllegalArgumentException.class);
+ Decks decks = createDecks(1, nbCards);
+ decks.deal(1, nbPlayers);
+ }
+
+ @Theory
+ public void deal_succeedsOnZeroCards(int nbPlayers) {
+ Decks decks = createDecks(1, 0);
+ Hands hands = decks.deal(1, nbPlayers);
+ for (int i = 0; i < nbPlayers; i++) {
+ assertNotNull(hands.get(i));
+ assertTrue(hands.get(i).isEmpty());
+ }
+ }
+
+ @Theory
+ public void deal_evenDistribution(int nbPlayers, int nbCardsPerPlayer) {
+ int nbCardsPerAge = nbPlayers * nbCardsPerPlayer;
+ Decks decks = createDecks(1, nbCardsPerAge);
+ Hands hands = decks.deal(1, nbPlayers);
+ for (int i = 0; i < nbPlayers; i++) {
+ assertEquals(nbCardsPerPlayer, hands.get(i).size());
+ }
+ }
+} \ No newline at end of file
diff --git a/backend/src/test/java/org/luxons/sevenwonders/game/cards/HandRotationDirectionTest.java b/backend/src/test/java/org/luxons/sevenwonders/game/cards/HandRotationDirectionTest.java
new file mode 100644
index 00000000..6165d158
--- /dev/null
+++ b/backend/src/test/java/org/luxons/sevenwonders/game/cards/HandRotationDirectionTest.java
@@ -0,0 +1,15 @@
+package org.luxons.sevenwonders.game.cards;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class HandRotationDirectionTest {
+
+ @Test
+ public void testAgesDirections() throws Exception {
+ assertEquals(HandRotationDirection.LEFT, HandRotationDirection.forAge(1));
+ assertEquals(HandRotationDirection.RIGHT, HandRotationDirection.forAge(2));
+ assertEquals(HandRotationDirection.LEFT, HandRotationDirection.forAge(3));
+ }
+} \ No newline at end of file
diff --git a/backend/src/test/java/org/luxons/sevenwonders/game/cards/HandsTest.java b/backend/src/test/java/org/luxons/sevenwonders/game/cards/HandsTest.java
new file mode 100644
index 00000000..494b9e4c
--- /dev/null
+++ b/backend/src/test/java/org/luxons/sevenwonders/game/cards/HandsTest.java
@@ -0,0 +1,141 @@
+package org.luxons.sevenwonders.game.cards;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.Test;
+import org.junit.experimental.theories.DataPoints;
+import org.junit.experimental.theories.FromDataPoints;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+import org.junit.runner.RunWith;
+import org.luxons.sevenwonders.game.api.HandCard;
+import org.luxons.sevenwonders.game.api.Table;
+import org.luxons.sevenwonders.game.cards.Hands.PlayerIndexOutOfBoundsException;
+import org.luxons.sevenwonders.game.test.TestUtils;
+
+import static org.junit.Assert.*;
+import static org.junit.Assume.*;
+
+@RunWith(Theories.class)
+public class HandsTest {
+
+ @DataPoints("nbCardsPerPlayer")
+ public static int[] nbCardsPerPlayer() {
+ return new int[] {0, 1, 2, 3, 4, 5, 6, 7};
+ }
+
+ @DataPoints("nbPlayers")
+ public static int[] nbPlayers() {
+ return new int[] {3, 4, 5, 6, 7};
+ }
+
+ private static Hands createHands(int nbPlayers, int nbCardsPerPlayer) {
+ Map<Integer, List<Card>> hands = new HashMap<>();
+ for (int p = 0; p < nbPlayers; p++) {
+ int firstCardNumber = (p - 1) * nbCardsPerPlayer;
+ hands.put(p, TestUtils.createSampleCards(firstCardNumber, nbCardsPerPlayer));
+ }
+ return new Hands(hands, nbPlayers);
+ }
+
+ @Test(expected = PlayerIndexOutOfBoundsException.class)
+ public void get_failsOnMissingPlayer() {
+ Hands hands = createHands(4, 7);
+ hands.get(5);
+ }
+
+ @Test
+ public void get_retrievesCorrectCards() {
+ List<Card> hand0 = TestUtils.createSampleCards(0, 5);
+ List<Card> hand1 = TestUtils.createSampleCards(5, 10);
+ Map<Integer, List<Card>> handsMap = new HashMap<>();
+ handsMap.put(0, hand0);
+ handsMap.put(1, hand1);
+ Hands hands = new Hands(handsMap, 2);
+ assertEquals(hand0, hands.get(0));
+ assertEquals(hand1, hands.get(1));
+ }
+
+ @Theory
+ public void isEmpty_falseWhenAtLeast1_allSame(@FromDataPoints("nbPlayers") int nbPlayers,
+ @FromDataPoints("nbCardsPerPlayer") int nbCardsPerPlayer) {
+ assumeTrue(nbCardsPerPlayer >= 1);
+ Hands hands = createHands(nbPlayers, nbCardsPerPlayer);
+ assertFalse(hands.isEmpty());
+ }
+
+ @Theory
+ public void isEmpty_trueWhenAllEmpty(@FromDataPoints("nbPlayers") int nbPlayers) {
+ Hands hands = createHands(nbPlayers, 0);
+ assertTrue(hands.isEmpty());
+ }
+
+ @Theory
+ public void maxOneCardRemains_falseWhenAtLeast2_allSame(@FromDataPoints("nbPlayers") int nbPlayers,
+ @FromDataPoints("nbCardsPerPlayer") int nbCardsPerPlayer) {
+ assumeTrue(nbCardsPerPlayer >= 2);
+ Hands hands = createHands(nbPlayers, nbCardsPerPlayer);
+ assertFalse(hands.maxOneCardRemains());
+ }
+
+ @Theory
+ public void maxOneCardRemains_trueWhenAtMost1_allSame(@FromDataPoints("nbPlayers") int nbPlayers,
+ @FromDataPoints("nbCardsPerPlayer") int nbCardsPerPlayer) {
+ assumeTrue(nbCardsPerPlayer <= 1);
+ Hands hands = createHands(nbPlayers, nbCardsPerPlayer);
+ assertTrue(hands.maxOneCardRemains());
+ }
+
+ @Theory
+ public void maxOneCardRemains_trueWhenAtMost1_someZero(@FromDataPoints("nbPlayers") int nbPlayers) {
+ Hands hands = createHands(nbPlayers, 1);
+ hands.get(0).remove(0);
+ assertTrue(hands.maxOneCardRemains());
+ }
+
+ @Theory
+ public void gatherAndClear(@FromDataPoints("nbPlayers") int nbPlayers,
+ @FromDataPoints("nbCardsPerPlayer") int nbCardsPerPlayer) {
+ Hands hands = createHands(nbPlayers, nbCardsPerPlayer);
+ List<Card> remainingCards = hands.gatherAndClear();
+ assertEquals(nbPlayers * nbCardsPerPlayer, remainingCards.size());
+ assertTrue(hands.isEmpty());
+ }
+
+ @Test
+ public void rotate_movesOfCorrectOffset_right() {
+ Hands hands = createHands(3, 7);
+ Hands rotated = hands.rotate(HandRotationDirection.RIGHT);
+ assertEquals(rotated.get(1), hands.get(0));
+ assertEquals(rotated.get(2), hands.get(1));
+ assertEquals(rotated.get(0), hands.get(2));
+ }
+
+ @Test
+ public void rotate_movesOfCorrectOffset_left() {
+ Hands hands = createHands(3, 7);
+ Hands rotated = hands.rotate(HandRotationDirection.LEFT);
+ assertEquals(rotated.get(2), hands.get(0));
+ assertEquals(rotated.get(0), hands.get(1));
+ assertEquals(rotated.get(1), hands.get(2));
+ }
+
+ @Test
+ public void createHand_containsAllCards() {
+ List<Card> hand0 = TestUtils.createSampleCards(0, 5);
+ List<Card> hand1 = TestUtils.createSampleCards(5, 10);
+ Map<Integer, List<Card>> handsMap = new HashMap<>();
+ handsMap.put(0, hand0);
+ handsMap.put(1, hand1);
+ Hands hands = new Hands(handsMap, 2);
+
+ Table table = TestUtils.createTable(2);
+ List<HandCard> hand = hands.createHand(table, 0);
+
+ for (HandCard handCard : hand) {
+ assertTrue(hand0.contains(handCard.getCard()));
+ }
+ }
+} \ No newline at end of file
diff --git a/backend/src/test/java/org/luxons/sevenwonders/game/data/GameDefinitionLoaderTest.java b/backend/src/test/java/org/luxons/sevenwonders/game/data/GameDefinitionLoaderTest.java
new file mode 100644
index 00000000..b38afd49
--- /dev/null
+++ b/backend/src/test/java/org/luxons/sevenwonders/game/data/GameDefinitionLoaderTest.java
@@ -0,0 +1,16 @@
+package org.luxons.sevenwonders.game.data;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class GameDefinitionLoaderTest {
+
+ @Test
+ public void successfulLoad() throws Exception {
+ GameDefinitionLoader loader = new GameDefinitionLoader();
+ GameDefinition gameDefinition = loader.getGameDefinition();
+ assertNotNull(gameDefinition);
+ }
+
+} \ No newline at end of file
diff --git a/backend/src/test/java/org/luxons/sevenwonders/game/data/GameDefinitionTest.java b/backend/src/test/java/org/luxons/sevenwonders/game/data/GameDefinitionTest.java
new file mode 100644
index 00000000..5acc09df
--- /dev/null
+++ b/backend/src/test/java/org/luxons/sevenwonders/game/data/GameDefinitionTest.java
@@ -0,0 +1,25 @@
+package org.luxons.sevenwonders.game.data;
+
+import java.util.List;
+
+import org.junit.Test;
+import org.luxons.sevenwonders.game.Game;
+import org.luxons.sevenwonders.game.Player;
+import org.luxons.sevenwonders.game.Settings;
+import org.luxons.sevenwonders.game.api.CustomizableSettings;
+import org.luxons.sevenwonders.game.test.TestUtils;
+
+import static org.junit.Assert.*;
+
+public class GameDefinitionTest {
+
+ @Test
+ public void successfulGameInit() throws Exception {
+ GameDefinition gameDefinition = new GameDefinitionLoader().getGameDefinition();
+ assertNotNull(gameDefinition);
+
+ List<Player> players = TestUtils.createPlayers(7);
+ Game game = gameDefinition.initGame(0, new CustomizableSettings(), players);
+ assertNotNull(game);
+ }
+} \ No newline at end of file
diff --git a/backend/src/test/java/org/luxons/sevenwonders/game/data/definitions/WonderSidePickMethodTest.java b/backend/src/test/java/org/luxons/sevenwonders/game/data/definitions/WonderSidePickMethodTest.java
new file mode 100644
index 00000000..2544ca64
--- /dev/null
+++ b/backend/src/test/java/org/luxons/sevenwonders/game/data/definitions/WonderSidePickMethodTest.java
@@ -0,0 +1,96 @@
+package org.luxons.sevenwonders.game.data.definitions;
+
+import java.util.Random;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.experimental.theories.DataPoints;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.assertEquals;
+
+@RunWith(Theories.class)
+public class WonderSidePickMethodTest {
+
+ @DataPoints
+ public static WonderSide[] sides() {
+ return WonderSide.values();
+ }
+
+ private Random random;
+
+ private Random random2;
+
+ @Before
+ public void setUp() {
+ random = new Random(123); // starts with TRUE
+ random2 = new Random(123456); // starts with FALSE
+ }
+
+ @Test
+ public void pick_allA() {
+ WonderSide side = null;
+ for (int i = 0; i < 10; i++) {
+ side = WonderSidePickMethod.ALL_A.pickSide(random, side);
+ assertEquals(WonderSide.A, side);
+ }
+ }
+
+ @Test
+ public void pick_allB() {
+ WonderSide side = null;
+ for (int i = 0; i < 10; i++) {
+ side = WonderSidePickMethod.ALL_B.pickSide(random, side);
+ assertEquals(WonderSide.B, side);
+ }
+ }
+
+ @Test
+ public void pick_eachRandom() {
+ WonderSide side = WonderSidePickMethod.EACH_RANDOM.pickSide(random, null);
+ assertEquals(WonderSide.A, side);
+ side = WonderSidePickMethod.EACH_RANDOM.pickSide(random, side);
+ assertEquals(WonderSide.B, side);
+ side = WonderSidePickMethod.EACH_RANDOM.pickSide(random, side);
+ assertEquals(WonderSide.A, side);
+ side = WonderSidePickMethod.EACH_RANDOM.pickSide(random, side);
+ assertEquals(WonderSide.B, side);
+ side = WonderSidePickMethod.EACH_RANDOM.pickSide(random, side);
+ assertEquals(WonderSide.B, side);
+ side = WonderSidePickMethod.EACH_RANDOM.pickSide(random, side);
+ assertEquals(WonderSide.A, side);
+ }
+
+ @Test
+ public void pick_eachRandom2() {
+ WonderSide side = WonderSidePickMethod.EACH_RANDOM.pickSide(random2, null);
+ assertEquals(WonderSide.B, side);
+ side = WonderSidePickMethod.EACH_RANDOM.pickSide(random2, side);
+ assertEquals(WonderSide.A, side);
+ side = WonderSidePickMethod.EACH_RANDOM.pickSide(random2, side);
+ assertEquals(WonderSide.A, side);
+ side = WonderSidePickMethod.EACH_RANDOM.pickSide(random2, side);
+ assertEquals(WonderSide.B, side);
+ side = WonderSidePickMethod.EACH_RANDOM.pickSide(random2, side);
+ assertEquals(WonderSide.B, side);
+ side = WonderSidePickMethod.EACH_RANDOM.pickSide(random2, side);
+ assertEquals(WonderSide.B, side);
+ }
+
+ @Theory
+ public void pick_allSameRandom_sameAsFirst(WonderSide firstSide) {
+ WonderSide side = firstSide;
+ for (int i = 0; i < 10; i++) {
+ side = WonderSidePickMethod.SAME_RANDOM_FOR_ALL.pickSide(random, side);
+ assertEquals(firstSide, side);
+ }
+ }
+
+ @Test
+ public void pick_allSameRandom_firstIsRandom() {
+ assertEquals(WonderSide.A, WonderSidePickMethod.SAME_RANDOM_FOR_ALL.pickSide(random, null));
+ assertEquals(WonderSide.B, WonderSidePickMethod.SAME_RANDOM_FOR_ALL.pickSide(random2, null));
+ }
+} \ No newline at end of file
diff --git a/backend/src/test/java/org/luxons/sevenwonders/game/data/serializers/NumericEffectSerializerTest.java b/backend/src/test/java/org/luxons/sevenwonders/game/data/serializers/NumericEffectSerializerTest.java
new file mode 100644
index 00000000..753a26cf
--- /dev/null
+++ b/backend/src/test/java/org/luxons/sevenwonders/game/data/serializers/NumericEffectSerializerTest.java
@@ -0,0 +1,128 @@
+package org.luxons.sevenwonders.game.data.serializers;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.experimental.theories.DataPoints;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+import org.junit.runner.RunWith;
+import org.luxons.sevenwonders.game.effects.GoldIncrease;
+import org.luxons.sevenwonders.game.effects.MilitaryReinforcements;
+import org.luxons.sevenwonders.game.effects.ProductionIncrease;
+import org.luxons.sevenwonders.game.effects.RawPointsIncrease;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import static org.junit.Assert.*;
+
+@RunWith(Theories.class)
+public class NumericEffectSerializerTest {
+
+ @DataPoints
+ public static int[] dataPoints() {
+ return new int[] {-2, -1, 0, 1, 2, 5};
+ }
+
+ private Gson gson;
+
+ @Before
+ public void setUp() {
+ gson = new GsonBuilder().registerTypeAdapter(MilitaryReinforcements.class, new NumericEffectSerializer())
+ .registerTypeAdapter(RawPointsIncrease.class, new NumericEffectSerializer())
+ .registerTypeAdapter(GoldIncrease.class, new NumericEffectSerializer())
+ // ProductionIncrease is not a numeric effect, it is here for negative testing purpose
+ .registerTypeAdapter(ProductionIncrease.class, new NumericEffectSerializer())
+ .create();
+ }
+
+ @Test
+ public void serialize_militaryReinforcements_null() {
+ assertEquals("null", gson.toJson(null, MilitaryReinforcements.class));
+ }
+
+ @Test
+ public void serialize_rawPointsIncrease_null() {
+ assertEquals("null", gson.toJson(null, RawPointsIncrease.class));
+ }
+
+ @Test
+ public void serialize_goldIncrease_null() {
+ assertEquals("null", gson.toJson(null, GoldIncrease.class));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void serialize_failOnUnknownType() {
+ gson.toJson(new ProductionIncrease());
+ }
+
+ @Theory
+ public void serialize_militaryReinforcements(int count) {
+ MilitaryReinforcements reinforcements = new MilitaryReinforcements(count);
+ assertEquals(String.valueOf(count), gson.toJson(reinforcements));
+ }
+
+ @Theory
+ public void serialize_rawPointsIncrease(int count) {
+ RawPointsIncrease points = new RawPointsIncrease(count);
+ assertEquals(String.valueOf(count), gson.toJson(points));
+ }
+
+ @Theory
+ public void serialize_goldIncrease(int count) {
+ GoldIncrease goldIncrease = new GoldIncrease(count);
+ assertEquals(String.valueOf(count), gson.toJson(goldIncrease));
+ }
+
+ @Theory
+ public void deserialize_militaryReinforcements(int count) {
+ MilitaryReinforcements reinforcements = new MilitaryReinforcements(count);
+ assertEquals(reinforcements, gson.fromJson(String.valueOf(count), MilitaryReinforcements.class));
+ }
+
+ @Theory
+ public void deserialize_rawPointsIncrease(int count) {
+ RawPointsIncrease points = new RawPointsIncrease(count);
+ assertEquals(points, gson.fromJson(String.valueOf(count), RawPointsIncrease.class));
+ }
+
+ @Theory
+ public void deserialize_goldIncrease(int count) {
+ GoldIncrease goldIncrease = new GoldIncrease(count);
+ assertEquals(goldIncrease, gson.fromJson(String.valueOf(count), GoldIncrease.class));
+ }
+
+ @Test(expected = NumberFormatException.class)
+ public void deserialize_militaryReinforcements_failOnEmptyString() {
+ gson.fromJson("\"\"", MilitaryReinforcements.class);
+ }
+
+ @Test(expected = NumberFormatException.class)
+ public void deserialize_rawPointsIncrease_failOnEmptyString() {
+ gson.fromJson("\"\"", RawPointsIncrease.class);
+ }
+
+ @Test(expected = NumberFormatException.class)
+ public void deserialize_goldIncrease_failOnEmptyString() {
+ gson.fromJson("\"\"", GoldIncrease.class);
+ }
+
+ @Test(expected = NumberFormatException.class)
+ public void deserialize_militaryReinforcements_failOnNonNumericString() {
+ gson.fromJson("\"abc\"", MilitaryReinforcements.class);
+ }
+
+ @Test(expected = NumberFormatException.class)
+ public void deserialize_rawPointsIncrease_failOnNonNumericString() {
+ gson.fromJson("\"abc\"", RawPointsIncrease.class);
+ }
+
+ @Test(expected = NumberFormatException.class)
+ public void deserialize_goldIncrease_failOnNonNumericString() {
+ gson.fromJson("\"abc\"", GoldIncrease.class);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void deserialize_failOnUnknownType() {
+ gson.fromJson("\"2\"", ProductionIncrease.class);
+ }
+} \ No newline at end of file
diff --git a/backend/src/test/java/org/luxons/sevenwonders/game/data/serializers/ProductionIncreaseSerializerTest.java b/backend/src/test/java/org/luxons/sevenwonders/game/data/serializers/ProductionIncreaseSerializerTest.java
new file mode 100644
index 00000000..17940361
--- /dev/null
+++ b/backend/src/test/java/org/luxons/sevenwonders/game/data/serializers/ProductionIncreaseSerializerTest.java
@@ -0,0 +1,203 @@
+package org.luxons.sevenwonders.game.data.serializers;
+
+import java.lang.reflect.Type;
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.luxons.sevenwonders.game.effects.ProductionIncrease;
+import org.luxons.sevenwonders.game.resources.Production;
+import org.luxons.sevenwonders.game.resources.ResourceType;
+import org.luxons.sevenwonders.game.resources.Resources;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.reflect.TypeToken;
+import static org.junit.Assert.*;
+
+public class ProductionIncreaseSerializerTest {
+
+ private Gson gson;
+
+ @Before
+ public void setUp() {
+ Type resourceTypeList = new TypeToken<List<ResourceType>>() {
+ }.getType();
+ gson = new GsonBuilder().registerTypeAdapter(Resources.class, new ResourcesSerializer())
+ .registerTypeAdapter(ResourceType.class, new ResourceTypeSerializer())
+ .registerTypeAdapter(resourceTypeList, new ResourceTypesSerializer())
+ .registerTypeAdapter(ProductionIncrease.class, new ProductionIncreaseSerializer())
+ .create();
+ }
+
+ private static ProductionIncrease create(int wood, int stone, int clay) {
+ Production production = new Production();
+ if (wood > 0) {
+ production.addFixedResource(ResourceType.WOOD, wood);
+ }
+ if (stone > 0) {
+ production.addFixedResource(ResourceType.STONE, stone);
+ }
+ if (clay > 0) {
+ production.addFixedResource(ResourceType.CLAY, clay);
+ }
+ ProductionIncrease prodIncrease = new ProductionIncrease();
+ prodIncrease.setProduction(production);
+ return prodIncrease;
+ }
+
+ private static ProductionIncrease createChoice(ResourceType... types) {
+ Production production = new Production();
+ production.addChoice(types);
+ ProductionIncrease prodIncrease = new ProductionIncrease();
+ prodIncrease.setProduction(production);
+ return prodIncrease;
+ }
+
+ @Test
+ public void serialize_nullAsNull() {
+ assertEquals("null", gson.toJson(null, ProductionIncrease.class));
+ }
+
+ @Test
+ public void serialize_emptyProdIncreaseAsNull() {
+ ProductionIncrease prodIncrease = new ProductionIncrease();
+ assertEquals("null", gson.toJson(prodIncrease, ProductionIncrease.class));
+ }
+
+ @Test
+ public void serialize_singleType() {
+ ProductionIncrease prodIncrease = create(1, 0, 0);
+ assertEquals("\"W\"", gson.toJson(prodIncrease, ProductionIncrease.class));
+ }
+
+ @Test
+ public void serialize_multipleTimesSameType() {
+ ProductionIncrease prodIncrease = create(3, 0, 0);
+ assertEquals("\"WWW\"", gson.toJson(prodIncrease, ProductionIncrease.class));
+ }
+
+ @Test
+ public void serialize_mixedTypes() {
+ ProductionIncrease prodIncrease = create(1, 1, 1);
+ assertEquals("\"WSC\"", gson.toJson(prodIncrease, ProductionIncrease.class));
+ }
+
+ @Test
+ public void serialize_mixedTypesMultiple() {
+ ProductionIncrease prodIncrease = create(2, 1, 2);
+ assertEquals("\"WWSCC\"", gson.toJson(prodIncrease, ProductionIncrease.class));
+ }
+
+ @Test
+ public void serialize_choice2() {
+ ProductionIncrease prodIncrease = createChoice(ResourceType.WOOD, ResourceType.CLAY);
+ assertEquals("\"W/C\"", gson.toJson(prodIncrease, ProductionIncrease.class));
+ }
+
+ @Test
+ public void serialize_choice3() {
+ ProductionIncrease prodIncrease = createChoice(ResourceType.WOOD, ResourceType.ORE, ResourceType.CLAY);
+ assertEquals("\"W/O/C\"", gson.toJson(prodIncrease, ProductionIncrease.class));
+ }
+
+ @Test
+ public void serialize_choice2_unordered() {
+ ProductionIncrease prodIncrease = createChoice(ResourceType.CLAY, ResourceType.WOOD);
+ assertEquals("\"W/C\"", gson.toJson(prodIncrease, ProductionIncrease.class));
+ }
+
+ @Test
+ public void serialize_choice3_unordered() {
+ ProductionIncrease prodIncrease = createChoice(ResourceType.WOOD, ResourceType.CLAY, ResourceType.ORE);
+ assertEquals("\"W/O/C\"", gson.toJson(prodIncrease, ProductionIncrease.class));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void serialize_failIfMultipleChoices() {
+ ProductionIncrease prodIncrease = createChoice(ResourceType.WOOD, ResourceType.CLAY);
+ prodIncrease.getProduction().addChoice(ResourceType.ORE, ResourceType.GLASS);
+ gson.toJson(prodIncrease, ProductionIncrease.class);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void serialize_failIfMixedFixedAndChoices() {
+ ProductionIncrease prodIncrease = create(1, 0, 0);
+ prodIncrease.getProduction().addChoice(ResourceType.WOOD, ResourceType.CLAY);
+ gson.toJson(prodIncrease, ProductionIncrease.class);
+ }
+
+ @Test
+ public void deserialize_nullFromNull() {
+ assertNull(gson.fromJson("null", ProductionIncrease.class));
+ }
+
+ @Test
+ public void deserialize_emptyList() {
+ ProductionIncrease prodIncrease = new ProductionIncrease();
+ assertEquals(prodIncrease, gson.fromJson("\"\"", ProductionIncrease.class));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void deserialize_failOnGarbageString() {
+ gson.fromJson("\"this is garbage\"", ProductionIncrease.class);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void deserialize_failOnGarbageStringWithSlashes() {
+ gson.fromJson("\"this/is/garbage\"", ProductionIncrease.class);
+ }
+
+ @Test
+ public void deserialize_singleType() {
+ ProductionIncrease prodIncrease = create(1, 0, 0);
+ assertEquals(prodIncrease, gson.fromJson("\"W\"", ProductionIncrease.class));
+ }
+
+ @Test
+ public void deserialize_multipleTimesSameType() {
+ ProductionIncrease prodIncrease = create(3, 0, 0);
+ assertEquals(prodIncrease, gson.fromJson("\"WWW\"", ProductionIncrease.class));
+ }
+
+ @Test
+ public void deserialize_mixedTypes() {
+ ProductionIncrease prodIncrease = create(1, 1, 1);
+ assertEquals(prodIncrease, gson.fromJson("\"WCS\"", ProductionIncrease.class));
+ }
+
+ @Test
+ public void deserialize_mixedTypes_unordered() {
+ ProductionIncrease prodIncrease = create(1, 3, 2);
+ assertEquals(prodIncrease, gson.fromJson("\"SCWCSS\"", ProductionIncrease.class));
+ }
+
+ @Test
+ public void deserialize_choice2() {
+ ProductionIncrease prodIncrease = createChoice(ResourceType.WOOD, ResourceType.CLAY);
+ assertEquals(prodIncrease, gson.fromJson("\"W/C\"", ProductionIncrease.class));
+ }
+
+ @Test
+ public void deserialize_choice3() {
+ ProductionIncrease prodIncrease = createChoice(ResourceType.WOOD, ResourceType.ORE, ResourceType.CLAY);
+ assertEquals(prodIncrease, gson.fromJson("\"W/O/C\"", ProductionIncrease.class));
+ }
+
+ @Test
+ public void deserialize_choice2_unordered() {
+ ProductionIncrease prodIncrease = createChoice(ResourceType.CLAY, ResourceType.WOOD);
+ assertEquals(prodIncrease, gson.fromJson("\"W/C\"", ProductionIncrease.class));
+ }
+
+ @Test
+ public void deserialize_choice3_unordered() {
+ ProductionIncrease prodIncrease = createChoice(ResourceType.WOOD, ResourceType.CLAY, ResourceType.ORE);
+ assertEquals(prodIncrease, gson.fromJson("\"W/O/C\"", ProductionIncrease.class));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void deserialize_failOnMultipleResourcesInChoice() {
+ gson.fromJson("\"W/SS/C\"", ProductionIncrease.class);
+ }
+} \ No newline at end of file
diff --git a/backend/src/test/java/org/luxons/sevenwonders/game/data/serializers/ResourceTypeSerializerTest.java b/backend/src/test/java/org/luxons/sevenwonders/game/data/serializers/ResourceTypeSerializerTest.java
new file mode 100644
index 00000000..86f3f5ab
--- /dev/null
+++ b/backend/src/test/java/org/luxons/sevenwonders/game/data/serializers/ResourceTypeSerializerTest.java
@@ -0,0 +1,50 @@
+package org.luxons.sevenwonders.game.data.serializers;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.luxons.sevenwonders.game.resources.ResourceType;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import static org.junit.Assert.*;
+
+public class ResourceTypeSerializerTest {
+
+ private Gson gson;
+
+ @Before
+ public void setUp() {
+ gson = new GsonBuilder().registerTypeAdapter(ResourceType.class, new ResourceTypeSerializer()).create();
+ }
+
+ @Test
+ public void serialize_useSymbolForEachType() {
+ for (ResourceType type : ResourceType.values()) {
+ String expectedJson = "\"" + type.getSymbol() + "\"";
+ assertEquals(expectedJson, gson.toJson(type));
+ }
+ }
+
+ @Test
+ public void deserialize_useSymbolForEachType() {
+ for (ResourceType type : ResourceType.values()) {
+ String typeInJson = "\"" + type.getSymbol() + "\"";
+ assertEquals(type, gson.fromJson(typeInJson, ResourceType.class));
+ }
+ }
+
+ @Test
+ public void deserialize_nullFromNull() {
+ assertNull(gson.fromJson("null", ResourceType.class));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void deserialize_failsOnEmptyString() {
+ gson.fromJson("\"\"", ResourceType.class);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void deserialize_failsOnGarbageString() {
+ gson.fromJson("\"thisisgarbage\"", ResourceType.class);
+ }
+} \ No newline at end of file
diff --git a/backend/src/test/java/org/luxons/sevenwonders/game/data/serializers/ResourceTypesSerializerTest.java b/backend/src/test/java/org/luxons/sevenwonders/game/data/serializers/ResourceTypesSerializerTest.java
new file mode 100644
index 00000000..4ebbc33f
--- /dev/null
+++ b/backend/src/test/java/org/luxons/sevenwonders/game/data/serializers/ResourceTypesSerializerTest.java
@@ -0,0 +1,100 @@
+package org.luxons.sevenwonders.game.data.serializers;
+
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.luxons.sevenwonders.game.resources.ResourceType;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.reflect.TypeToken;
+import static org.junit.Assert.*;
+
+public class ResourceTypesSerializerTest {
+
+ private Gson gson;
+
+ @Before
+ public void setUp() {
+ gson = new GsonBuilder().registerTypeAdapter(createListTypeToken(), new ResourceTypesSerializer()).create();
+ }
+
+ private static Type createListTypeToken() {
+ return new TypeToken<List<ResourceType>>() {}.getType();
+ }
+
+ @Test
+ public void serialize_null() {
+ assertEquals("null", gson.toJson(null, createListTypeToken()));
+ }
+
+ @Test
+ public void serialize_emptyList() {
+ List<ResourceType> types = new ArrayList<>();
+ assertEquals("\"\"", gson.toJson(types, createListTypeToken()));
+ }
+
+ @Test
+ public void serialize_singleType() {
+ List<ResourceType> types = new ArrayList<>();
+ types.add(ResourceType.WOOD);
+ assertEquals("\"W\"", gson.toJson(types, createListTypeToken()));
+ }
+
+ @Test
+ public void serialize_multipleTimesSameType() {
+ List<ResourceType> types = new ArrayList<>();
+ types.add(ResourceType.WOOD);
+ types.add(ResourceType.WOOD);
+ types.add(ResourceType.WOOD);
+ assertEquals("\"WWW\"", gson.toJson(types, createListTypeToken()));
+ }
+
+ @Test
+ public void serialize_mixedTypes() {
+ List<ResourceType> types = new ArrayList<>();
+ types.add(ResourceType.WOOD);
+ types.add(ResourceType.CLAY);
+ types.add(ResourceType.STONE);
+ assertEquals("\"WCS\"", gson.toJson(types, createListTypeToken()));
+ }
+
+ @Test
+ public void deserialize_null() {
+ assertNull(gson.fromJson("null", createListTypeToken()));
+ }
+
+ @Test
+ public void deserialize_emptyList() {
+ List<ResourceType> types = new ArrayList<>();
+ assertEquals(types, gson.fromJson("\"\"", createListTypeToken()));
+ }
+
+ @Test
+ public void deserialize_singleType() {
+ List<ResourceType> types = new ArrayList<>();
+ types.add(ResourceType.WOOD);
+ assertEquals(types, gson.fromJson("\"W\"", createListTypeToken()));
+ }
+
+ @Test
+ public void deserialize_multipleTimesSameType() {
+ List<ResourceType> types = new ArrayList<>();
+ types.add(ResourceType.WOOD);
+ types.add(ResourceType.WOOD);
+ types.add(ResourceType.WOOD);
+ assertEquals(types, gson.fromJson("\"WWW\"", createListTypeToken()));
+ }
+
+ @Test
+ public void deserialize_mixedTypes() {
+ List<ResourceType> types = new ArrayList<>();
+ types.add(ResourceType.WOOD);
+ types.add(ResourceType.CLAY);
+ types.add(ResourceType.STONE);
+ assertEquals(types, gson.fromJson("\"WCS\"", createListTypeToken()));
+ }
+} \ No newline at end of file
diff --git a/backend/src/test/java/org/luxons/sevenwonders/game/data/serializers/ResourcesSerializerTest.java b/backend/src/test/java/org/luxons/sevenwonders/game/data/serializers/ResourcesSerializerTest.java
new file mode 100644
index 00000000..1fd01337
--- /dev/null
+++ b/backend/src/test/java/org/luxons/sevenwonders/game/data/serializers/ResourcesSerializerTest.java
@@ -0,0 +1,107 @@
+package org.luxons.sevenwonders.game.data.serializers;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.luxons.sevenwonders.game.resources.ResourceType;
+import org.luxons.sevenwonders.game.resources.Resources;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import static org.junit.Assert.*;
+
+public class ResourcesSerializerTest {
+
+ private Gson gson;
+
+ @Before
+ public void setUp() {
+ gson = new GsonBuilder().registerTypeAdapter(Resources.class, new ResourcesSerializer()).create();
+ }
+
+ @Test
+ public void serialize_null() {
+ assertEquals("null", gson.toJson(null, Resources.class));
+ }
+
+ @Test
+ public void serialize_emptyResourcesToNull() {
+ Resources resources = new Resources();
+ assertEquals("null", gson.toJson(resources));
+ }
+
+ @Test
+ public void serialize_singleType() {
+ Resources resources = new Resources();
+ resources.add(ResourceType.WOOD, 1);
+ assertEquals("\"W\"", gson.toJson(resources));
+ }
+
+ @Test
+ public void serialize_multipleTimesSameType() {
+ Resources resources = new Resources();
+ resources.add(ResourceType.WOOD, 3);
+ assertEquals("\"WWW\"", gson.toJson(resources));
+ }
+
+ @Test
+ public void serialize_mixedTypes() {
+ Resources resources = new Resources();
+ resources.add(ResourceType.WOOD, 1);
+ resources.add(ResourceType.STONE, 1);
+ resources.add(ResourceType.CLAY, 1);
+ assertEquals("\"WSC\"", gson.toJson(resources));
+ }
+
+ @Test
+ public void serialize_mixedTypes_unordered() {
+ Resources resources = new Resources();
+ resources.add(ResourceType.CLAY, 1);
+ resources.add(ResourceType.WOOD, 2);
+ resources.add(ResourceType.CLAY, 1);
+ resources.add(ResourceType.STONE, 1);
+ assertEquals("\"WWSCC\"", gson.toJson(resources));
+ }
+
+ @Test
+ public void deserialize_null() {
+ assertNull(gson.fromJson("null", Resources.class));
+ }
+
+ @Test
+ public void deserialize_emptyList() {
+ Resources resources = new Resources();
+ assertEquals(resources, gson.fromJson("\"\"", Resources.class));
+ }
+
+ @Test
+ public void deserialize_singleType() {
+ Resources resources = new Resources();
+ resources.add(ResourceType.WOOD, 1);
+ assertEquals(resources, gson.fromJson("\"W\"", Resources.class));
+ }
+
+ @Test
+ public void deserialize_multipleTimesSameType() {
+ Resources resources = new Resources();
+ resources.add(ResourceType.WOOD, 3);
+ assertEquals(resources, gson.fromJson("\"WWW\"", Resources.class));
+ }
+
+ @Test
+ public void deserialize_mixedTypes() {
+ Resources resources = new Resources();
+ resources.add(ResourceType.WOOD, 1);
+ resources.add(ResourceType.CLAY, 1);
+ resources.add(ResourceType.STONE, 1);
+ assertEquals(resources, gson.fromJson("\"WCS\"", Resources.class));
+ }
+
+ @Test
+ public void deserialize_mixedTypes_unordered() {
+ Resources resources = new Resources();
+ resources.add(ResourceType.WOOD, 1);
+ resources.add(ResourceType.CLAY, 2);
+ resources.add(ResourceType.STONE, 3);
+ assertEquals(resources, gson.fromJson("\"SCWCSS\"", Resources.class));
+ }
+} \ No newline at end of file
diff --git a/backend/src/test/java/org/luxons/sevenwonders/game/data/serializers/ScienceProgressSerializerTest.java b/backend/src/test/java/org/luxons/sevenwonders/game/data/serializers/ScienceProgressSerializerTest.java
new file mode 100644
index 00000000..40088fda
--- /dev/null
+++ b/backend/src/test/java/org/luxons/sevenwonders/game/data/serializers/ScienceProgressSerializerTest.java
@@ -0,0 +1,145 @@
+package org.luxons.sevenwonders.game.data.serializers;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.luxons.sevenwonders.game.boards.ScienceType;
+import org.luxons.sevenwonders.game.effects.ScienceProgress;
+import org.luxons.sevenwonders.game.test.TestUtils;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import static org.junit.Assert.*;
+
+public class ScienceProgressSerializerTest {
+
+ private static final String COMPASS_STR = "\"COMPASS\"";
+
+ private static final String WHEEL_STR = "\"WHEEL\"";
+
+ private static final String TABLET_STR = "\"TABLET\"";
+
+ private static final String JOKER_STR = "\"any\"";
+
+ private Gson gson;
+
+ @Before
+ public void setUp() {
+ gson = new GsonBuilder().registerTypeAdapter(ScienceProgress.class, new ScienceProgressSerializer()).create();
+ }
+
+ @Test
+ public void serialize_emptyToNull() {
+ ScienceProgress progress = TestUtils.createScienceProgress(0, 0, 0, 0);
+ String json = gson.toJson(progress);
+ assertEquals("null", json);
+ }
+
+ @Test
+ public void serialize_oneCompass() {
+ ScienceProgress progress = TestUtils.createScienceProgress(1, 0, 0, 0);
+ String json = gson.toJson(progress);
+ assertEquals(COMPASS_STR, json);
+ }
+
+ @Test
+ public void serialize_oneWheel() {
+ ScienceProgress progress = TestUtils.createScienceProgress(0, 1, 0, 0);
+ String json = gson.toJson(progress);
+ assertEquals(WHEEL_STR, json);
+ }
+
+ @Test
+ public void serialize_oneTablet() {
+ ScienceProgress progress = TestUtils.createScienceProgress(0, 0, 1, 0);
+ String json = gson.toJson(progress);
+ assertEquals(TABLET_STR, json);
+ }
+
+ @Test
+ public void serialize_oneJoker() {
+ ScienceProgress progress = TestUtils.createScienceProgress(0, 0, 0, 1);
+ String json = gson.toJson(progress);
+ assertEquals(JOKER_STR, json);
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void serialize_failOnMultipleCompasses() {
+ ScienceProgress progress = TestUtils.createScienceProgress(2, 0, 0, 0);
+ gson.toJson(progress);
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void serialize_failOnMultipleWheels() {
+ ScienceProgress progress = TestUtils.createScienceProgress(0, 2, 0, 0);
+ gson.toJson(progress);
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void serialize_failOnMultipleTablets() {
+ ScienceProgress progress = TestUtils.createScienceProgress(0, 0, 2, 0);
+ gson.toJson(progress);
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void serialize_failOnMultipleJokers() {
+ ScienceProgress progress = TestUtils.createScienceProgress(0, 0, 0, 2);
+ gson.toJson(progress);
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void serialize_failOnMixedElements() {
+ ScienceProgress progress = TestUtils.createScienceProgress(1, 1, 0, 0);
+ gson.toJson(progress);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void deserialize_failOnEmptyString() {
+ gson.fromJson("\"\"", ScienceProgress.class);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void deserialize_failOnGarbageString() {
+ gson.fromJson("thisisgarbage", ScienceProgress.class);
+ }
+
+ @Test
+ public void deserialize_compass() {
+ ScienceProgress progress = gson.fromJson(COMPASS_STR, ScienceProgress.class);
+ assertNotNull(progress.getScience());
+ assertEquals(1, progress.getScience().getQuantity(ScienceType.COMPASS));
+ assertEquals(0, progress.getScience().getQuantity(ScienceType.WHEEL));
+ assertEquals(0, progress.getScience().getQuantity(ScienceType.TABLET));
+ assertEquals(0, progress.getScience().getJokers());
+ }
+
+ @Test
+ public void deserialize_wheel() {
+ ScienceProgress progress = gson.fromJson(WHEEL_STR, ScienceProgress.class);
+ assertNotNull(progress.getScience());
+ assertEquals(0, progress.getScience().getQuantity(ScienceType.COMPASS));
+ assertEquals(1, progress.getScience().getQuantity(ScienceType.WHEEL));
+ assertEquals(0, progress.getScience().getQuantity(ScienceType.TABLET));
+ assertEquals(0, progress.getScience().getJokers());
+ }
+
+ @Test
+ public void deserialize_tablet() {
+ ScienceProgress progress = gson.fromJson(TABLET_STR, ScienceProgress.class);
+ assertNotNull(progress.getScience());
+ assertEquals(0, progress.getScience().getQuantity(ScienceType.COMPASS));
+ assertEquals(0, progress.getScience().getQuantity(ScienceType.WHEEL));
+ assertEquals(1, progress.getScience().getQuantity(ScienceType.TABLET));
+ assertEquals(0, progress.getScience().getJokers());
+ }
+
+ @Test
+ public void deserialize_joker() {
+ ScienceProgress progress = gson.fromJson(JOKER_STR, ScienceProgress.class);
+ assertNotNull(progress.getScience());
+ assertEquals(0, progress.getScience().getQuantity(ScienceType.COMPASS));
+ assertEquals(0, progress.getScience().getQuantity(ScienceType.WHEEL));
+ assertEquals(0, progress.getScience().getQuantity(ScienceType.TABLET));
+ assertEquals(1, progress.getScience().getJokers());
+ }
+
+} \ No newline at end of file
diff --git a/backend/src/test/java/org/luxons/sevenwonders/game/effects/BonusPerBoardElementTest.java b/backend/src/test/java/org/luxons/sevenwonders/game/effects/BonusPerBoardElementTest.java
new file mode 100644
index 00000000..5f42bc53
--- /dev/null
+++ b/backend/src/test/java/org/luxons/sevenwonders/game/effects/BonusPerBoardElementTest.java
@@ -0,0 +1,139 @@
+package org.luxons.sevenwonders.game.effects;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+import org.junit.Before;
+import org.junit.experimental.theories.DataPoints;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+import org.junit.runner.RunWith;
+import org.luxons.sevenwonders.game.api.Table;
+import org.luxons.sevenwonders.game.boards.Board;
+import org.luxons.sevenwonders.game.boards.BoardElementType;
+import org.luxons.sevenwonders.game.boards.RelativeBoardPosition;
+import org.luxons.sevenwonders.game.cards.CardBack;
+import org.luxons.sevenwonders.game.cards.Color;
+import org.luxons.sevenwonders.game.test.TestUtils;
+
+import static org.junit.Assert.*;
+
+@RunWith(Theories.class)
+public class BonusPerBoardElementTest {
+
+ @DataPoints
+ public static int[] values() {
+ return new int[] {0, 1, 2, 3};
+ }
+
+ @DataPoints
+ public static Color[] colors() {
+ return Color.values();
+ }
+
+ @DataPoints
+ public static RelativeBoardPosition[] positions() {
+ return RelativeBoardPosition.values();
+ }
+
+ private Table table;
+
+ @Before
+ public void setUp() throws Exception {
+ table = TestUtils.createTable(4);
+ }
+
+ private static BonusPerBoardElement createBonus(BoardElementType type, int gold, int points, Color... colors) {
+ BonusPerBoardElement bonus = new BonusPerBoardElement();
+ bonus.setType(type);
+ bonus.setGold(gold);
+ bonus.setPoints(points);
+ bonus.setColors(Arrays.asList(colors));
+ return bonus;
+ }
+
+ @Theory
+ public void computePoints_countsCards(RelativeBoardPosition boardPosition, int nbCards, int nbOtherCards,
+ int points, int gold, Color color) {
+ Board board = table.getBoard(0, boardPosition);
+ TestUtils.addCards(board, nbCards, nbOtherCards, color);
+
+ BonusPerBoardElement bonus = createBonus(BoardElementType.CARD, gold, points, color);
+ bonus.setBoards(Collections.singletonList(boardPosition));
+
+ assertEquals(nbCards * points, bonus.computePoints(table, 0));
+ }
+
+ @Theory
+ public void computePoints_countsDefeatTokens(RelativeBoardPosition boardPosition, int nbDefeatTokens, int points, int gold) {
+ Board board = table.getBoard(0, boardPosition);
+ for (int i = 0; i < nbDefeatTokens; i++) {
+ board.getMilitary().defeat();
+ }
+
+ BonusPerBoardElement bonus = createBonus(BoardElementType.DEFEAT_TOKEN, gold, points);
+ bonus.setBoards(Collections.singletonList(boardPosition));
+
+ assertEquals(nbDefeatTokens * points, bonus.computePoints(table, 0));
+ }
+
+ @Theory
+ public void computePoints_countsWonderStages(RelativeBoardPosition boardPosition, int nbStages, int points, int gold) {
+ Board board = table.getBoard(0, boardPosition);
+ for (int i = 0; i < nbStages; i++) {
+ board.getWonder().buildLevel(new CardBack(""));
+ }
+
+ BonusPerBoardElement bonus = createBonus(BoardElementType.BUILT_WONDER_STAGES, gold, points);
+ bonus.setBoards(Collections.singletonList(boardPosition));
+
+ assertEquals(nbStages * points, bonus.computePoints(table, 0));
+ }
+
+ @Theory
+ public void apply_countsCards(RelativeBoardPosition boardPosition, int nbCards, int nbOtherCards,
+ int points, int gold, Color color) {
+ Board board = table.getBoard(0, boardPosition);
+ TestUtils.addCards(board, nbCards, nbOtherCards, color);
+
+ BonusPerBoardElement bonus = createBonus(BoardElementType.CARD, gold, points, color);
+ bonus.setBoards(Collections.singletonList(boardPosition));
+
+ Board selfBoard = table.getBoard(0);
+ int initialGold = selfBoard.getGold();
+ bonus.apply(table, 0);
+ assertEquals(initialGold + nbCards * gold, selfBoard.getGold());
+ }
+
+ @Theory
+ public void apply_countsDefeatTokens(RelativeBoardPosition boardPosition, int nbDefeatTokens, int points, int gold) {
+ Board board = table.getBoard(0, boardPosition);
+ for (int i = 0; i < nbDefeatTokens; i++) {
+ board.getMilitary().defeat();
+ }
+
+ BonusPerBoardElement bonus = createBonus(BoardElementType.DEFEAT_TOKEN, gold, points);
+ bonus.setBoards(Collections.singletonList(boardPosition));
+
+ Board selfBoard = table.getBoard(0);
+ int initialGold = selfBoard.getGold();
+ bonus.apply(table, 0);
+ assertEquals(initialGold + nbDefeatTokens * gold, selfBoard.getGold());
+ }
+
+ @Theory
+ public void apply_countsWonderStages(RelativeBoardPosition boardPosition, int nbStages, int points, int gold) {
+ Board board = table.getBoard(0, boardPosition);
+ for (int i = 0; i < nbStages; i++) {
+ board.getWonder().buildLevel(new CardBack(""));
+ }
+
+ BonusPerBoardElement bonus = createBonus(BoardElementType.BUILT_WONDER_STAGES, gold, points);
+ bonus.setBoards(Collections.singletonList(boardPosition));
+
+ Board selfBoard = table.getBoard(0);
+ int initialGold = selfBoard.getGold();
+ bonus.apply(table, 0);
+ assertEquals(initialGold + nbStages * gold, selfBoard.getGold());
+ }
+} \ No newline at end of file
diff --git a/backend/src/test/java/org/luxons/sevenwonders/game/effects/DiscountTest.java b/backend/src/test/java/org/luxons/sevenwonders/game/effects/DiscountTest.java
new file mode 100644
index 00000000..cf8ce21d
--- /dev/null
+++ b/backend/src/test/java/org/luxons/sevenwonders/game/effects/DiscountTest.java
@@ -0,0 +1,72 @@
+package org.luxons.sevenwonders.game.effects;
+
+import org.junit.Assume;
+import org.junit.experimental.theories.DataPoints;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+import org.junit.runner.RunWith;
+import org.luxons.sevenwonders.game.boards.Board;
+import org.luxons.sevenwonders.game.resources.BoughtResources;
+import org.luxons.sevenwonders.game.resources.Provider;
+import org.luxons.sevenwonders.game.resources.ResourceType;
+import org.luxons.sevenwonders.game.test.TestUtils;
+
+import static org.junit.Assert.assertEquals;
+
+@RunWith(Theories.class)
+public class DiscountTest {
+
+ @DataPoints
+ public static int[] discountedPrices() {
+ return new int[]{0, 1, 2};
+ }
+
+ @DataPoints
+ public static ResourceType[] resourceTypes() {
+ return ResourceType.values();
+ }
+
+ @DataPoints
+ public static Provider[] providers() {
+ return Provider.values();
+ }
+
+ @Theory
+ public void apply_givesDiscountedPrice(int discountedPrice, ResourceType discountedType, Provider provider) {
+ Board board = TestUtils.createBoard(ResourceType.CLAY, 3);
+ Discount discount = new Discount();
+ discount.setDiscountedPrice(discountedPrice);
+ discount.getProviders().add(provider);
+ discount.getResourceTypes().add(discountedType);
+ discount.apply(board);
+
+ BoughtResources boughtResources = TestUtils.createBoughtResources(provider, discountedType);
+ assertEquals(discountedPrice, board.getTradingRules().computeCost(boughtResources));
+ }
+
+ @Theory
+ public void apply_doesNotAffectOtherResources(int discountedPrice, ResourceType discountedType, Provider provider,
+ ResourceType otherType, Provider otherProvider) {
+ Assume.assumeTrue(otherProvider != provider);
+ Assume.assumeTrue(otherType != discountedType);
+
+ Board board = TestUtils.createBoard(ResourceType.CLAY, 3);
+ Discount discount = new Discount();
+ discount.setDiscountedPrice(discountedPrice);
+ discount.getProviders().add(provider);
+ discount.getResourceTypes().add(discountedType);
+ discount.apply(board);
+
+ // this is the default in the settings used by TestUtils.createBoard()
+ int normalPrice = 2;
+
+ BoughtResources fromOtherType = TestUtils.createBoughtResources(provider, otherType);
+ assertEquals(normalPrice, board.getTradingRules().computeCost(fromOtherType));
+
+ BoughtResources fromOtherProvider = TestUtils.createBoughtResources(otherProvider, discountedType);
+ assertEquals(normalPrice, board.getTradingRules().computeCost(fromOtherProvider));
+
+ BoughtResources fromOtherProviderAndType = TestUtils.createBoughtResources(otherProvider, otherType);
+ assertEquals(normalPrice, board.getTradingRules().computeCost(fromOtherProviderAndType));
+ }
+} \ No newline at end of file
diff --git a/backend/src/test/java/org/luxons/sevenwonders/game/effects/GoldIncreaseTest.java b/backend/src/test/java/org/luxons/sevenwonders/game/effects/GoldIncreaseTest.java
new file mode 100644
index 00000000..e4d4c27f
--- /dev/null
+++ b/backend/src/test/java/org/luxons/sevenwonders/game/effects/GoldIncreaseTest.java
@@ -0,0 +1,78 @@
+package org.luxons.sevenwonders.game.effects;
+
+import org.junit.experimental.theories.DataPoints;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+import org.junit.runner.RunWith;
+import org.luxons.sevenwonders.game.api.Table;
+import org.luxons.sevenwonders.game.boards.Board;
+import org.luxons.sevenwonders.game.resources.ResourceType;
+import org.luxons.sevenwonders.game.test.TestUtils;
+
+import static org.junit.Assert.*;
+
+@RunWith(Theories.class)
+public class GoldIncreaseTest {
+
+ @DataPoints
+ public static int[] goldAmounts() {
+ return new int[]{-5, -1, 0, 1, 2, 5, 10};
+ }
+
+ @DataPoints
+ public static ResourceType[] resourceTypes() {
+ return ResourceType.values();
+ }
+
+ @Theory
+ public void apply_increaseGoldWithRightAmount(int initialAmount, int goldIncreaseAmount, ResourceType type) {
+ Board board = TestUtils.createBoard(type, initialAmount);
+ GoldIncrease goldIncrease = new GoldIncrease(goldIncreaseAmount);
+
+ goldIncrease.apply(board);
+
+ assertEquals(initialAmount + goldIncreaseAmount, board.getGold());
+ }
+
+ @Theory
+ public void computePoints_isAlwaysZero(int gold) {
+ GoldIncrease goldIncrease = new GoldIncrease(gold);
+ Table table = TestUtils.createTable(5);
+ assertEquals(0, goldIncrease.computePoints(table, 0));
+ }
+
+ @Theory
+ public void equals_falseWhenNull(int gold) {
+ GoldIncrease goldIncrease = new GoldIncrease(gold);
+ //noinspection ObjectEqualsNull
+ assertFalse(goldIncrease.equals(null));
+ }
+
+ @Theory
+ public void equals_falseWhenDifferentClass(int gold) {
+ GoldIncrease goldIncrease = new GoldIncrease(gold);
+ MilitaryReinforcements reinforcements = new MilitaryReinforcements(gold);
+ //noinspection EqualsBetweenInconvertibleTypes
+ assertFalse(goldIncrease.equals(reinforcements));
+ }
+
+ @Theory
+ public void equals_trueWhenSame(int gold) {
+ GoldIncrease goldIncrease = new GoldIncrease(gold);
+ assertEquals(goldIncrease, goldIncrease);
+ }
+
+ @Theory
+ public void equals_trueWhenSameContent(int gold) {
+ GoldIncrease goldIncrease1 = new GoldIncrease(gold);
+ GoldIncrease goldIncrease2 = new GoldIncrease(gold);
+ assertTrue(goldIncrease1.equals(goldIncrease2));
+ }
+
+ @Theory
+ public void hashCode_sameWhenSameContent(int gold) {
+ GoldIncrease goldIncrease1 = new GoldIncrease(gold);
+ GoldIncrease goldIncrease2 = new GoldIncrease(gold);
+ assertEquals(goldIncrease1.hashCode(), goldIncrease2.hashCode());
+ }
+} \ No newline at end of file
diff --git a/backend/src/test/java/org/luxons/sevenwonders/game/effects/MilitaryReinforcementsTest.java b/backend/src/test/java/org/luxons/sevenwonders/game/effects/MilitaryReinforcementsTest.java
new file mode 100644
index 00000000..d3c2cc03
--- /dev/null
+++ b/backend/src/test/java/org/luxons/sevenwonders/game/effects/MilitaryReinforcementsTest.java
@@ -0,0 +1,79 @@
+package org.luxons.sevenwonders.game.effects;
+
+import org.junit.experimental.theories.DataPoints;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+import org.junit.runner.RunWith;
+import org.luxons.sevenwonders.game.api.Table;
+import org.luxons.sevenwonders.game.boards.Board;
+import org.luxons.sevenwonders.game.resources.ResourceType;
+import org.luxons.sevenwonders.game.test.TestUtils;
+
+import static org.junit.Assert.*;
+
+@RunWith(Theories.class)
+public class MilitaryReinforcementsTest {
+
+ @DataPoints
+ public static int[] shieldCounts() {
+ return new int[]{0, 1, 2, 3, 5};
+ }
+
+ @DataPoints
+ public static ResourceType[] resourceTypes() {
+ return ResourceType.values();
+ }
+
+ @Theory
+ public void apply_increaseGoldWithRightAmount(int initialShields, int additionalShields, ResourceType type) {
+ Board board = TestUtils.createBoard(type);
+ board.getMilitary().addShields(initialShields);
+
+ MilitaryReinforcements reinforcements = new MilitaryReinforcements(additionalShields);
+ reinforcements.apply(board);
+
+ assertEquals(initialShields + additionalShields, board.getMilitary().getNbShields());
+ }
+
+ @Theory
+ public void computePoints_isAlwaysZero(int shields) {
+ MilitaryReinforcements reinforcements = new MilitaryReinforcements(shields);
+ Table table = TestUtils.createTable(5);
+ assertEquals(0, reinforcements.computePoints(table, 0));
+ }
+
+ @Theory
+ public void equals_falseWhenNull(int shields) {
+ MilitaryReinforcements reinforcements = new MilitaryReinforcements(shields);
+ //noinspection ObjectEqualsNull
+ assertFalse(reinforcements.equals(null));
+ }
+
+ @Theory
+ public void equals_falseWhenDifferentClass(int shields) {
+ MilitaryReinforcements reinforcements = new MilitaryReinforcements(shields);
+ GoldIncrease goldIncrease = new GoldIncrease(shields);
+ //noinspection EqualsBetweenInconvertibleTypes
+ assertFalse(reinforcements.equals(goldIncrease));
+ }
+
+ @Theory
+ public void equals_trueWhenSame(int shields) {
+ MilitaryReinforcements reinforcements = new MilitaryReinforcements(shields);
+ assertEquals(reinforcements, reinforcements);
+ }
+
+ @Theory
+ public void equals_trueWhenSameContent(int shields) {
+ MilitaryReinforcements reinforcements1 = new MilitaryReinforcements(shields);
+ MilitaryReinforcements reinforcements2 = new MilitaryReinforcements(shields);
+ assertTrue(reinforcements1.equals(reinforcements2));
+ }
+
+ @Theory
+ public void hashCode_sameWhenSameContent(int shields) {
+ MilitaryReinforcements reinforcements1 = new MilitaryReinforcements(shields);
+ MilitaryReinforcements reinforcements2 = new MilitaryReinforcements(shields);
+ assertEquals(reinforcements1.hashCode(), reinforcements2.hashCode());
+ }
+} \ No newline at end of file
diff --git a/backend/src/test/java/org/luxons/sevenwonders/game/effects/ProductionIncreaseTest.java b/backend/src/test/java/org/luxons/sevenwonders/game/effects/ProductionIncreaseTest.java
new file mode 100644
index 00000000..6031e112
--- /dev/null
+++ b/backend/src/test/java/org/luxons/sevenwonders/game/effects/ProductionIncreaseTest.java
@@ -0,0 +1,85 @@
+package org.luxons.sevenwonders.game.effects;
+
+import org.junit.experimental.theories.DataPoints;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+import org.junit.runner.RunWith;
+import org.luxons.sevenwonders.game.api.Table;
+import org.luxons.sevenwonders.game.boards.Board;
+import org.luxons.sevenwonders.game.resources.Production;
+import org.luxons.sevenwonders.game.resources.ResourceType;
+import org.luxons.sevenwonders.game.resources.Resources;
+import org.luxons.sevenwonders.game.test.TestUtils;
+
+import static org.junit.Assert.*;
+
+@RunWith(Theories.class)
+public class ProductionIncreaseTest {
+
+ @DataPoints
+ public static ResourceType[] resourceTypes() {
+ return ResourceType.values();
+ }
+
+ private static ProductionIncrease createProductionIncrease(ResourceType... types) {
+ ProductionIncrease effect = new ProductionIncrease();
+ effect.getProduction().addAll(TestUtils.createFixedProduction(types));
+ return effect;
+ }
+
+ @Theory
+ public void apply_boardContainsAddedResourceType(ResourceType initialType, ResourceType addedType, ResourceType extraType) {
+ Board board = TestUtils.createBoard(initialType);
+ ProductionIncrease effect = createProductionIncrease(addedType);
+
+ effect.apply(board);
+
+ Resources resources = TestUtils.createResources(initialType, addedType);
+ assertTrue(board.getProduction().contains(resources));
+
+ Resources moreResources = TestUtils.createResources(initialType, addedType, extraType);
+ assertFalse(board.getProduction().contains(moreResources));
+ }
+
+ @Theory
+ public void computePoints_isAlwaysZero(ResourceType addedType) {
+ ProductionIncrease effect = createProductionIncrease(addedType);
+ Table table = TestUtils.createTable(5);
+ assertEquals(0, effect.computePoints(table, 0));
+ }
+
+ @Theory
+ public void equals_falseWhenNull(ResourceType addedType) {
+ ProductionIncrease effect = createProductionIncrease(addedType);
+ //noinspection ObjectEqualsNull
+ assertFalse(effect.equals(null));
+ }
+
+ @Theory
+ public void equals_falseWhenDifferentClass(ResourceType addedType) {
+ ProductionIncrease effect = createProductionIncrease(addedType);
+ Production production = TestUtils.createFixedProduction(addedType);
+ //noinspection EqualsBetweenInconvertibleTypes
+ assertFalse(effect.equals(production));
+ }
+
+ @Theory
+ public void equals_trueWhenSame(ResourceType addedType) {
+ ProductionIncrease effect = createProductionIncrease(addedType);
+ assertEquals(effect, effect);
+ }
+
+ @Theory
+ public void equals_trueWhenSameContent(ResourceType addedType) {
+ ProductionIncrease effect1 = createProductionIncrease(addedType);
+ ProductionIncrease effect2 = createProductionIncrease(addedType);
+ assertTrue(effect1.equals(effect2));
+ }
+
+ @Theory
+ public void hashCode_sameWhenSameContent(ResourceType addedType) {
+ ProductionIncrease effect1 = createProductionIncrease(addedType);
+ ProductionIncrease effect2 = createProductionIncrease(addedType);
+ assertEquals(effect1.hashCode(), effect2.hashCode());
+ }
+} \ No newline at end of file
diff --git a/backend/src/test/java/org/luxons/sevenwonders/game/effects/RawPointsIncreaseTest.java b/backend/src/test/java/org/luxons/sevenwonders/game/effects/RawPointsIncreaseTest.java
new file mode 100644
index 00000000..a1c8a8de
--- /dev/null
+++ b/backend/src/test/java/org/luxons/sevenwonders/game/effects/RawPointsIncreaseTest.java
@@ -0,0 +1,61 @@
+package org.luxons.sevenwonders.game.effects;
+
+import org.junit.experimental.theories.DataPoints;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+import org.junit.runner.RunWith;
+import org.luxons.sevenwonders.game.api.Table;
+import org.luxons.sevenwonders.game.test.TestUtils;
+
+import static org.junit.Assert.*;
+
+@RunWith(Theories.class)
+public class RawPointsIncreaseTest {
+
+ @DataPoints
+ public static int[] points() {
+ return new int[] {0, 1, 2, 3, 5};
+ }
+
+ @Theory
+ public void computePoints_equalsNbOfPoints(int points) {
+ RawPointsIncrease rawPointsIncrease = new RawPointsIncrease(points);
+ Table table = TestUtils.createTable(5);
+ assertEquals(points, rawPointsIncrease.computePoints(table, 0));
+ }
+
+ @Theory
+ public void equals_falseWhenNull(int points) {
+ RawPointsIncrease rawPointsIncrease = new RawPointsIncrease(points);
+ //noinspection ObjectEqualsNull
+ assertFalse(rawPointsIncrease.equals(null));
+ }
+
+ @Theory
+ public void equals_falseWhenDifferentClass(int points) {
+ RawPointsIncrease rawPointsIncrease = new RawPointsIncrease(points);
+ GoldIncrease goldIncrease = new GoldIncrease(points);
+ //noinspection EqualsBetweenInconvertibleTypes
+ assertFalse(rawPointsIncrease.equals(goldIncrease));
+ }
+
+ @Theory
+ public void equals_trueWhenSame(int points) {
+ RawPointsIncrease rawPointsIncrease = new RawPointsIncrease(points);
+ assertEquals(rawPointsIncrease, rawPointsIncrease);
+ }
+
+ @Theory
+ public void equals_trueWhenSameContent(int points) {
+ RawPointsIncrease rawPointsIncrease1 = new RawPointsIncrease(points);
+ RawPointsIncrease rawPointsIncrease2 = new RawPointsIncrease(points);
+ assertTrue(rawPointsIncrease1.equals(rawPointsIncrease2));
+ }
+
+ @Theory
+ public void hashCode_sameWhenSameContent(int points) {
+ RawPointsIncrease rawPointsIncrease1 = new RawPointsIncrease(points);
+ RawPointsIncrease rawPointsIncrease2 = new RawPointsIncrease(points);
+ assertEquals(rawPointsIncrease1.hashCode(), rawPointsIncrease2.hashCode());
+ }
+} \ No newline at end of file
diff --git a/backend/src/test/java/org/luxons/sevenwonders/game/effects/ScienceProgressTest.java b/backend/src/test/java/org/luxons/sevenwonders/game/effects/ScienceProgressTest.java
new file mode 100644
index 00000000..56289654
--- /dev/null
+++ b/backend/src/test/java/org/luxons/sevenwonders/game/effects/ScienceProgressTest.java
@@ -0,0 +1,38 @@
+package org.luxons.sevenwonders.game.effects;
+
+import org.junit.experimental.theories.DataPoints;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+import org.junit.runner.RunWith;
+import org.luxons.sevenwonders.game.boards.Board;
+import org.luxons.sevenwonders.game.boards.Science;
+import org.luxons.sevenwonders.game.boards.ScienceType;
+import org.luxons.sevenwonders.game.resources.ResourceType;
+import org.luxons.sevenwonders.game.test.TestUtils;
+
+import static org.junit.Assert.*;
+
+@RunWith(Theories.class)
+public class ScienceProgressTest {
+
+ @DataPoints
+ public static int[] elementsCount() {
+ return new int[] {0, 1, 2};
+ }
+
+ @Theory
+ public void apply_initContainsAddedScience(int initCompasses, int initWheels, int initTablets, int initJokers,
+ int compasses, int wheels, int tablets, int jokers) {
+ Board board = TestUtils.createBoard(ResourceType.ORE);
+ Science initialScience = TestUtils.createScience(initCompasses, initWheels, initTablets, initJokers);
+ board.getScience().addAll(initialScience);
+
+ ScienceProgress effect = TestUtils.createScienceProgress(compasses, wheels, tablets, jokers);
+ effect.apply(board);
+
+ assertEquals(initCompasses + compasses, board.getScience().getQuantity(ScienceType.COMPASS));
+ assertEquals(initWheels + wheels, board.getScience().getQuantity(ScienceType.WHEEL));
+ assertEquals(initTablets + tablets, board.getScience().getQuantity(ScienceType.TABLET));
+ assertEquals(initJokers + jokers, board.getScience().getJokers());
+ }
+} \ No newline at end of file
diff --git a/backend/src/test/java/org/luxons/sevenwonders/game/effects/SpecialAbilityActivationTest.java b/backend/src/test/java/org/luxons/sevenwonders/game/effects/SpecialAbilityActivationTest.java
new file mode 100644
index 00000000..b04db127
--- /dev/null
+++ b/backend/src/test/java/org/luxons/sevenwonders/game/effects/SpecialAbilityActivationTest.java
@@ -0,0 +1,94 @@
+package org.luxons.sevenwonders.game.effects;
+
+import java.util.Arrays;
+
+import org.junit.Assume;
+import org.junit.Test;
+import org.junit.experimental.theories.DataPoints;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+import org.junit.runner.RunWith;
+import org.luxons.sevenwonders.game.api.Table;
+import org.luxons.sevenwonders.game.boards.Board;
+import org.luxons.sevenwonders.game.boards.BoardElementType;
+import org.luxons.sevenwonders.game.boards.RelativeBoardPosition;
+import org.luxons.sevenwonders.game.cards.Card;
+import org.luxons.sevenwonders.game.cards.Color;
+import org.luxons.sevenwonders.game.test.TestUtils;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+@RunWith(Theories.class)
+public class SpecialAbilityActivationTest {
+
+ @DataPoints
+ public static SpecialAbility[] abilities() {
+ return SpecialAbility.values();
+ }
+
+ @DataPoints
+ public static RelativeBoardPosition[] neighbours() {
+ return new RelativeBoardPosition[]{RelativeBoardPosition.LEFT, RelativeBoardPosition.RIGHT};
+ }
+
+ @DataPoints
+ public static Card[] guilds() {
+ BonusPerBoardElement bonus = new BonusPerBoardElement();
+ bonus.setType(BoardElementType.CARD);
+ bonus.setColors(Arrays.asList(Color.GREY, Color.BROWN));
+ bonus.setBoards(Arrays.asList(RelativeBoardPosition.LEFT, RelativeBoardPosition.RIGHT));
+ bonus.setPoints(1);
+
+ BonusPerBoardElement bonus2 = new BonusPerBoardElement();
+ bonus2.setType(BoardElementType.BUILT_WONDER_STAGES);
+ bonus2.setBoards(
+ Arrays.asList(RelativeBoardPosition.LEFT, RelativeBoardPosition.SELF, RelativeBoardPosition.RIGHT));
+ bonus2.setPoints(1);
+
+ return new Card[]{TestUtils.createGuildCard(1, bonus), TestUtils.createGuildCard(2, bonus2)};
+ }
+
+ @Theory
+ public void apply_addsAbility(SpecialAbility ability) {
+ SpecialAbilityActivation effect = new SpecialAbilityActivation(ability);
+ Table table = TestUtils.createTable(5);
+
+ effect.apply(table, 0);
+
+ Board board = table.getBoard(0);
+ assertTrue(board.hasSpecial(ability));
+ }
+
+ @Theory
+ public void computePoints_zeroExceptForCopyGuild(SpecialAbility ability) {
+ Assume.assumeTrue(ability != SpecialAbility.COPY_GUILD);
+
+ SpecialAbilityActivation effect = new SpecialAbilityActivation(ability);
+ Table table = TestUtils.createTable(5);
+
+ assertEquals(0, effect.computePoints(table, 0));
+ }
+
+ @Theory
+ public void computePoints_copiedGuild(Card guildCard, RelativeBoardPosition neighbour) {
+ SpecialAbilityActivation effect = new SpecialAbilityActivation(SpecialAbility.COPY_GUILD);
+ Table table = TestUtils.createTable(5);
+
+ Board neighbourBoard = table.getBoard(0, neighbour);
+ neighbourBoard.addCard(guildCard);
+
+ Board board = table.getBoard(0);
+ board.setCopiedGuild(guildCard);
+
+ int directPointsFromGuildCard = guildCard.getEffects().stream().mapToInt(e -> e.computePoints(table, 0)).sum();
+ assertEquals(directPointsFromGuildCard, effect.computePoints(table, 0));
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void computePoints_copyGuild_failWhenNoChosenGuild() {
+ SpecialAbilityActivation effect = new SpecialAbilityActivation(SpecialAbility.COPY_GUILD);
+ Table table = TestUtils.createTable(5);
+ effect.computePoints(table, 0);
+ }
+} \ No newline at end of file
diff --git a/backend/src/test/java/org/luxons/sevenwonders/game/resources/ProductionTest.java b/backend/src/test/java/org/luxons/sevenwonders/game/resources/ProductionTest.java
new file mode 100644
index 00000000..76d2345f
--- /dev/null
+++ b/backend/src/test/java/org/luxons/sevenwonders/game/resources/ProductionTest.java
@@ -0,0 +1,271 @@
+package org.luxons.sevenwonders.game.resources;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class ProductionTest {
+
+ private Resources emptyResources;
+
+ private Resources resources1Wood;
+
+ private Resources resources1Stone;
+
+ private Resources resources1Stone1Wood;
+
+ private Resources resources2Stones;
+
+ private Resources resources2Stones3Clay;
+
+ @Before
+ public void init() {
+ emptyResources = new Resources();
+
+ resources1Wood = new Resources();
+ resources1Wood.add(ResourceType.WOOD, 1);
+
+ resources1Stone = new Resources();
+ resources1Stone.add(ResourceType.STONE, 1);
+
+ resources1Stone1Wood = new Resources();
+ resources1Stone1Wood.add(ResourceType.STONE, 1);
+ resources1Stone1Wood.add(ResourceType.WOOD, 1);
+
+ resources2Stones = new Resources();
+ resources2Stones.add(ResourceType.STONE, 2);
+
+ resources2Stones3Clay = new Resources();
+ resources2Stones3Clay.add(ResourceType.STONE, 2);
+ resources2Stones3Clay.add(ResourceType.CLAY, 3);
+ }
+
+ @Test
+ public void contains_newProductionContainsEmpty() {
+ Production production = new Production();
+ assertTrue(production.contains(emptyResources));
+ }
+
+ @Test
+ public void contains_singleFixedResource_noneAtAll() {
+ Production production = new Production();
+ assertFalse(production.contains(resources2Stones));
+ }
+
+ @Test
+ public void contains_singleFixedResource_notEnough() {
+ Production production = new Production();
+ production.addFixedResource(ResourceType.STONE, 1);
+ assertFalse(production.contains(resources2Stones));
+ }
+
+ @Test
+ public void contains_singleFixedResource_justEnough() {
+ Production production = new Production();
+ production.addFixedResource(ResourceType.STONE, 2);
+ assertTrue(production.contains(resources2Stones));
+ }
+
+ @Test
+ public void contains_singleFixedResource_moreThanEnough() {
+ Production production = new Production();
+ production.addFixedResource(ResourceType.STONE, 3);
+ assertTrue(production.contains(resources2Stones));
+ }
+
+ @Test
+ public void contains_singleFixedResource_moreThanEnough_amongOthers() {
+ Production production = new Production();
+ production.addFixedResource(ResourceType.STONE, 3);
+ production.addFixedResource(ResourceType.CLAY, 2);
+ assertTrue(production.contains(resources2Stones));
+ }
+
+ @Test
+ public void contains_multipleFixedResources_notEnoughOfOne() {
+ Production production = new Production();
+ production.addFixedResource(ResourceType.STONE, 3);
+ production.addFixedResource(ResourceType.CLAY, 1);
+ assertFalse(production.contains(resources2Stones3Clay));
+ }
+
+ @Test
+ public void contains_multipleFixedResources_notEnoughOfBoth() {
+ Production production = new Production();
+ production.addFixedResource(ResourceType.STONE, 1);
+ production.addFixedResource(ResourceType.CLAY, 1);
+ assertFalse(production.contains(resources2Stones3Clay));
+ }
+
+ @Test
+ public void contains_multipleFixedResources_moreThanEnough() {
+ Production production = new Production();
+ production.addFixedResource(ResourceType.STONE, 3);
+ production.addFixedResource(ResourceType.CLAY, 5);
+ assertTrue(production.contains(resources2Stones3Clay));
+ }
+
+ @Test
+ public void contains_singleChoice_containsEmpty() {
+ Production production = new Production();
+ production.addChoice(ResourceType.STONE, ResourceType.CLAY);
+ assertTrue(production.contains(emptyResources));
+ }
+
+ @Test
+ public void contains_singleChoice_enough() {
+ Production production = new Production();
+ production.addChoice(ResourceType.STONE, ResourceType.WOOD);
+ assertTrue(production.contains(resources1Wood));
+ assertTrue(production.contains(resources1Stone));
+ }
+
+ @Test
+ public void contains_multipleChoices_notBoth() {
+ Production production = new Production();
+ production.addChoice(ResourceType.STONE, ResourceType.CLAY);
+ production.addChoice(ResourceType.STONE, ResourceType.CLAY);
+ production.addChoice(ResourceType.STONE, ResourceType.CLAY);
+ assertFalse(production.contains(resources2Stones3Clay));
+ }
+
+ @Test
+ public void contains_multipleChoices_enough() {
+ Production production = new Production();
+ production.addChoice(ResourceType.STONE, ResourceType.ORE);
+ production.addChoice(ResourceType.STONE, ResourceType.WOOD);
+ assertTrue(production.contains(resources1Stone1Wood));
+ }
+
+ @Test
+ public void contains_multipleChoices_enoughReverseOrder() {
+ Production production = new Production();
+ production.addChoice(ResourceType.STONE, ResourceType.WOOD);
+ production.addChoice(ResourceType.STONE, ResourceType.ORE);
+ assertTrue(production.contains(resources1Stone1Wood));
+ }
+
+ @Test
+ public void contains_multipleChoices_moreThanEnough() {
+ Production production = new Production();
+ production.addChoice(ResourceType.LOOM, ResourceType.GLASS, ResourceType.PAPYRUS);
+ production.addChoice(ResourceType.STONE, ResourceType.ORE);
+ production.addChoice(ResourceType.STONE, ResourceType.WOOD);
+ assertTrue(production.contains(resources1Stone1Wood));
+ }
+
+ @Test
+ public void contains_mixedFixedAndChoice_enough() {
+ Production production = new Production();
+ production.addFixedResource(ResourceType.WOOD, 1);
+ production.addChoice(ResourceType.STONE, ResourceType.WOOD);
+ assertTrue(production.contains(resources1Stone1Wood));
+ }
+
+ @Test
+ public void addAll_empty() {
+ Production production = new Production();
+ production.addAll(emptyResources);
+ assertTrue(production.contains(emptyResources));
+ }
+
+ @Test
+ public void addAll_singleResource() {
+ Production production = new Production();
+ production.addAll(resources1Stone);
+ assertTrue(production.contains(resources1Stone));
+ }
+
+ @Test
+ public void addAll_multipleResources() {
+ Production production = new Production();
+ production.addAll(resources2Stones3Clay);
+ assertTrue(production.contains(resources2Stones3Clay));
+ }
+
+ @Test
+ public void addAll_production_multipleFixedResources() {
+ Production production = new Production();
+ production.addAll(resources2Stones3Clay);
+
+ Production production2 = new Production();
+ production2.addAll(production);
+
+ assertTrue(production2.contains(resources2Stones3Clay));
+ }
+
+ @Test
+ public void addAll_production_multipleChoices() {
+ Production production = new Production();
+ production.addChoice(ResourceType.STONE, ResourceType.WOOD);
+ production.addChoice(ResourceType.STONE, ResourceType.ORE);
+
+ Production production2 = new Production();
+ production2.addAll(production);
+ assertTrue(production.contains(resources1Stone1Wood));
+ }
+
+ @Test
+ public void addAll_production_mixedFixedResourcesAndChoices() {
+ Production production = new Production();
+ production.addFixedResource(ResourceType.WOOD, 1);
+ production.addChoice(ResourceType.STONE, ResourceType.WOOD);
+
+ Production production2 = new Production();
+ production2.addAll(production);
+
+ assertTrue(production.contains(resources1Stone1Wood));
+ }
+
+ @Test
+ public void equals_falseWhenNull() {
+ Production production = new Production();
+ production.addFixedResource(ResourceType.GLASS, 1);
+ production.addChoice(ResourceType.ORE, ResourceType.WOOD);
+ //noinspection ObjectEqualsNull
+ assertFalse(production.equals(null));
+ }
+
+ @Test
+ public void equals_falseWhenDifferentClass() {
+ Production production = new Production();
+ production.addFixedResource(ResourceType.GLASS, 1);
+ Resources resources = new Resources();
+ resources.add(ResourceType.GLASS, 1);
+ //noinspection EqualsBetweenInconvertibleTypes
+ assertFalse(production.equals(resources));
+ }
+
+ @Test
+ public void equals_trueWhenSame() {
+ Production production = new Production();
+ assertEquals(production, production);
+ }
+
+ @Test
+ public void equals_trueWhenSameContent() {
+ Production production1 = new Production();
+ Production production2 = new Production();
+ assertTrue(production1.equals(production2));
+ production1.addFixedResource(ResourceType.GLASS, 1);
+ production2.addFixedResource(ResourceType.GLASS, 1);
+ assertTrue(production1.equals(production2));
+ production1.addChoice(ResourceType.ORE, ResourceType.WOOD);
+ production2.addChoice(ResourceType.ORE, ResourceType.WOOD);
+ assertTrue(production1.equals(production2));
+ }
+
+ @Test
+ public void hashCode_sameWhenSameContent() {
+ Production production1 = new Production();
+ Production production2 = new Production();
+ assertEquals(production1.hashCode(), production2.hashCode());
+ production1.addFixedResource(ResourceType.GLASS, 1);
+ production2.addFixedResource(ResourceType.GLASS, 1);
+ assertEquals(production1.hashCode(), production2.hashCode());
+ production1.addChoice(ResourceType.ORE, ResourceType.WOOD);
+ production2.addChoice(ResourceType.ORE, ResourceType.WOOD);
+ assertEquals(production1.hashCode(), production2.hashCode());
+ }
+} \ No newline at end of file
diff --git a/backend/src/test/java/org/luxons/sevenwonders/game/resources/ResourcesTest.java b/backend/src/test/java/org/luxons/sevenwonders/game/resources/ResourcesTest.java
new file mode 100644
index 00000000..674c90e7
--- /dev/null
+++ b/backend/src/test/java/org/luxons/sevenwonders/game/resources/ResourcesTest.java
@@ -0,0 +1,431 @@
+package org.luxons.sevenwonders.game.resources;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class ResourcesTest {
+
+ @Test
+ public void init_shouldBeEmpty() {
+ Resources resources = new Resources();
+ for (ResourceType resourceType : ResourceType.values()) {
+ assertEquals(0, resources.getQuantity(resourceType));
+ }
+ }
+
+ @Test
+ public void add_zero() {
+ Resources resources = new Resources();
+ resources.add(ResourceType.CLAY, 0);
+ assertEquals(0, resources.getQuantity(ResourceType.CLAY));
+ }
+
+ @Test
+ public void add_simple() {
+ Resources resources = new Resources();
+ resources.add(ResourceType.WOOD, 3);
+ assertEquals(3, resources.getQuantity(ResourceType.WOOD));
+ }
+
+ @Test
+ public void add_multipleCallsStacked() {
+ Resources resources = new Resources();
+ resources.add(ResourceType.ORE, 3);
+ resources.add(ResourceType.ORE, 2);
+ assertEquals(5, resources.getQuantity(ResourceType.ORE));
+ }
+
+ @Test
+ public void add_interlaced() {
+ Resources resources = new Resources();
+ resources.add(ResourceType.GLASS, 3);
+ resources.add(ResourceType.STONE, 1);
+ resources.add(ResourceType.WOOD, 4);
+ resources.add(ResourceType.GLASS, 2);
+ assertEquals(5, resources.getQuantity(ResourceType.GLASS));
+ }
+
+ @Test
+ public void addAll_empty() {
+ Resources resources = new Resources();
+ resources.add(ResourceType.STONE, 1);
+ resources.add(ResourceType.CLAY, 3);
+
+ Resources emptyResources = new Resources();
+
+ resources.addAll(emptyResources);
+ assertEquals(1, resources.getQuantity(ResourceType.STONE));
+ assertEquals(3, resources.getQuantity(ResourceType.CLAY));
+ assertEquals(0, resources.getQuantity(ResourceType.ORE));
+ assertEquals(0, resources.getQuantity(ResourceType.GLASS));
+ assertEquals(0, resources.getQuantity(ResourceType.LOOM));
+ }
+
+ @Test
+ public void addAll_zeros() {
+ Resources resources = new Resources();
+ resources.add(ResourceType.STONE, 1);
+ resources.add(ResourceType.CLAY, 3);
+
+ Resources emptyResources = new Resources();
+ emptyResources.add(ResourceType.STONE, 0);
+ emptyResources.add(ResourceType.CLAY, 0);
+
+ resources.addAll(emptyResources);
+ assertEquals(1, resources.getQuantity(ResourceType.STONE));
+ assertEquals(3, resources.getQuantity(ResourceType.CLAY));
+ assertEquals(0, resources.getQuantity(ResourceType.ORE));
+ assertEquals(0, resources.getQuantity(ResourceType.GLASS));
+ assertEquals(0, resources.getQuantity(ResourceType.LOOM));
+ }
+
+ @Test
+ public void addAll_same() {
+ Resources resources = new Resources();
+ resources.add(ResourceType.STONE, 1);
+ resources.add(ResourceType.CLAY, 3);
+
+ Resources resources2 = new Resources();
+ resources.add(ResourceType.STONE, 2);
+ resources.add(ResourceType.CLAY, 6);
+
+ resources.addAll(resources2);
+ assertEquals(3, resources.getQuantity(ResourceType.STONE));
+ assertEquals(9, resources.getQuantity(ResourceType.CLAY));
+ assertEquals(0, resources.getQuantity(ResourceType.ORE));
+ assertEquals(0, resources.getQuantity(ResourceType.GLASS));
+ assertEquals(0, resources.getQuantity(ResourceType.LOOM));
+ }
+
+ @Test
+ public void addAll_overlap() {
+ Resources resources = new Resources();
+ resources.add(ResourceType.STONE, 1);
+ resources.add(ResourceType.CLAY, 3);
+
+ Resources resources2 = new Resources();
+ resources.add(ResourceType.CLAY, 6);
+ resources.add(ResourceType.ORE, 4);
+
+ resources.addAll(resources2);
+ assertEquals(1, resources.getQuantity(ResourceType.STONE));
+ assertEquals(9, resources.getQuantity(ResourceType.CLAY));
+ assertEquals(4, resources.getQuantity(ResourceType.ORE));
+ assertEquals(0, resources.getQuantity(ResourceType.GLASS));
+ assertEquals(0, resources.getQuantity(ResourceType.LOOM));
+ }
+
+ @Test
+ public void contains_emptyContainsEmpty() {
+ Resources emptyResources = new Resources();
+ Resources emptyResources2 = new Resources();
+ assertTrue(emptyResources.contains(emptyResources2));
+ }
+
+ @Test
+ public void contains_singleTypeContainsEmpty() {
+ Resources resources = new Resources();
+ resources.add(ResourceType.STONE, 1);
+
+ Resources emptyResources = new Resources();
+
+ assertTrue(resources.contains(emptyResources));
+ }
+
+ @Test
+ public void contains_multipleTypesContainsEmpty() {
+ Resources resources = new Resources();
+ resources.add(ResourceType.STONE, 1);
+ resources.add(ResourceType.CLAY, 3);
+
+ Resources emptyResources = new Resources();
+
+ assertTrue(resources.contains(emptyResources));
+ }
+
+ @Test
+ public void contains_self() {
+ Resources resources = new Resources();
+ resources.add(ResourceType.STONE, 1);
+ resources.add(ResourceType.CLAY, 3);
+
+ assertTrue(resources.contains(resources));
+ }
+
+ @Test
+ public void contains_allOfEachType() {
+ Resources resources = new Resources();
+ resources.add(ResourceType.STONE, 1);
+ resources.add(ResourceType.CLAY, 3);
+
+ Resources resources2 = new Resources();
+ resources2.add(ResourceType.STONE, 1);
+ resources2.add(ResourceType.CLAY, 3);
+
+ assertTrue(resources.contains(resources2));
+ }
+
+ @Test
+ public void contains_someOfEachType() {
+ Resources resources = new Resources();
+ resources.add(ResourceType.STONE, 2);
+ resources.add(ResourceType.CLAY, 4);
+
+ Resources resources2 = new Resources();
+ resources2.add(ResourceType.STONE, 1);
+ resources2.add(ResourceType.CLAY, 3);
+
+ assertTrue(resources.contains(resources2));
+ }
+
+ @Test
+ public void contains_someOfSomeTypes() {
+ Resources resources = new Resources();
+ resources.add(ResourceType.STONE, 2);
+ resources.add(ResourceType.CLAY, 4);
+
+ Resources resources2 = new Resources();
+ resources2.add(ResourceType.CLAY, 3);
+
+ assertTrue(resources.contains(resources2));
+ }
+
+ @Test
+ public void contains_allOfSomeTypes() {
+ Resources resources = new Resources();
+ resources.add(ResourceType.STONE, 2);
+ resources.add(ResourceType.CLAY, 4);
+
+ Resources resources2 = new Resources();
+ resources2.add(ResourceType.CLAY, 4);
+
+ assertTrue(resources.contains(resources2));
+ }
+
+ @Test
+ public void minus_empty() {
+ Resources resources = new Resources();
+ resources.add(ResourceType.STONE, 1);
+ resources.add(ResourceType.CLAY, 3);
+
+ Resources emptyResources = new Resources();
+
+ Resources diff = resources.minus(emptyResources);
+ assertEquals(1, diff.getQuantity(ResourceType.STONE));
+ assertEquals(3, diff.getQuantity(ResourceType.CLAY));
+ assertEquals(0, diff.getQuantity(ResourceType.ORE));
+ assertEquals(0, diff.getQuantity(ResourceType.GLASS));
+ assertEquals(0, diff.getQuantity(ResourceType.LOOM));
+ }
+
+ @Test
+ public void minus_self() {
+ Resources resources = new Resources();
+ resources.add(ResourceType.STONE, 1);
+ resources.add(ResourceType.CLAY, 3);
+
+ Resources diff = resources.minus(resources);
+ assertEquals(0, diff.getQuantity(ResourceType.STONE));
+ assertEquals(0, diff.getQuantity(ResourceType.CLAY));
+ assertEquals(0, diff.getQuantity(ResourceType.ORE));
+ assertEquals(0, diff.getQuantity(ResourceType.GLASS));
+ assertEquals(0, diff.getQuantity(ResourceType.LOOM));
+ }
+
+ @Test
+ public void minus_allOfEachType() {
+ Resources resources = new Resources();
+ resources.add(ResourceType.STONE, 1);
+ resources.add(ResourceType.CLAY, 3);
+
+ Resources resources2 = new Resources();
+ resources2.add(ResourceType.STONE, 1);
+ resources2.add(ResourceType.CLAY, 3);
+
+ Resources diff = resources.minus(resources2);
+ assertEquals(0, diff.getQuantity(ResourceType.STONE));
+ assertEquals(0, diff.getQuantity(ResourceType.CLAY));
+ assertEquals(0, diff.getQuantity(ResourceType.ORE));
+ assertEquals(0, diff.getQuantity(ResourceType.GLASS));
+ assertEquals(0, diff.getQuantity(ResourceType.LOOM));
+ }
+
+ @Test
+ public void minus_someOfEachType() {
+ Resources resources = new Resources();
+ resources.add(ResourceType.STONE, 2);
+ resources.add(ResourceType.CLAY, 4);
+
+ Resources resources2 = new Resources();
+ resources2.add(ResourceType.STONE, 1);
+ resources2.add(ResourceType.CLAY, 3);
+
+ Resources diff = resources.minus(resources2);
+ assertEquals(1, diff.getQuantity(ResourceType.STONE));
+ assertEquals(1, diff.getQuantity(ResourceType.CLAY));
+ assertEquals(0, diff.getQuantity(ResourceType.ORE));
+ assertEquals(0, diff.getQuantity(ResourceType.GLASS));
+ assertEquals(0, diff.getQuantity(ResourceType.LOOM));
+ }
+
+ @Test
+ public void minus_someOfSomeTypes() {
+ Resources resources = new Resources();
+ resources.add(ResourceType.STONE, 2);
+ resources.add(ResourceType.CLAY, 4);
+
+ Resources resources2 = new Resources();
+ resources2.add(ResourceType.CLAY, 3);
+
+ Resources diff = resources.minus(resources2);
+ assertEquals(2, diff.getQuantity(ResourceType.STONE));
+ assertEquals(1, diff.getQuantity(ResourceType.CLAY));
+ assertEquals(0, diff.getQuantity(ResourceType.ORE));
+ assertEquals(0, diff.getQuantity(ResourceType.GLASS));
+ assertEquals(0, diff.getQuantity(ResourceType.LOOM));
+ }
+
+ @Test
+ public void minus_allOfSomeTypes() {
+ Resources resources = new Resources();
+ resources.add(ResourceType.STONE, 2);
+ resources.add(ResourceType.CLAY, 4);
+
+ Resources resources2 = new Resources();
+ resources2.add(ResourceType.CLAY, 4);
+
+ Resources diff = resources.minus(resources2);
+ assertEquals(2, diff.getQuantity(ResourceType.STONE));
+ assertEquals(0, diff.getQuantity(ResourceType.CLAY));
+ assertEquals(0, diff.getQuantity(ResourceType.ORE));
+ assertEquals(0, diff.getQuantity(ResourceType.GLASS));
+ assertEquals(0, diff.getQuantity(ResourceType.LOOM));
+ }
+
+ @Test
+ public void minus_tooMuchOfExistingType() {
+ Resources resources = new Resources();
+ resources.add(ResourceType.CLAY, 4);
+
+ Resources resources2 = new Resources();
+ resources2.add(ResourceType.CLAY, 5);
+
+ Resources diff = resources.minus(resources2);
+ assertEquals(0, diff.getQuantity(ResourceType.CLAY));
+ }
+
+ @Test
+ public void minus_someOfAnAbsentType() {
+ Resources resources = new Resources();
+
+ Resources resources2 = new Resources();
+ resources2.add(ResourceType.LOOM, 5);
+
+ Resources diff = resources.minus(resources2);
+ assertEquals(0, diff.getQuantity(ResourceType.LOOM));
+ }
+
+ @Test
+ public void minus_someOfATypeWithZero() {
+ Resources resources = new Resources();
+ resources.add(ResourceType.LOOM, 0);
+
+ Resources resources2 = new Resources();
+ resources2.add(ResourceType.LOOM, 5);
+
+ Resources diff = resources.minus(resources2);
+ assertEquals(0, diff.getQuantity(ResourceType.LOOM));
+ }
+
+ @Test
+ public void isEmpty_noElement() {
+ Resources resources = new Resources();
+ assertTrue(resources.isEmpty());
+ }
+
+ @Test
+ public void isEmpty_singleZeroElement() {
+ Resources resources = new Resources();
+ resources.add(ResourceType.LOOM, 0);
+ assertTrue(resources.isEmpty());
+ }
+
+ @Test
+ public void isEmpty_multipleZeroElements() {
+ Resources resources = new Resources();
+ resources.add(ResourceType.WOOD, 0);
+ resources.add(ResourceType.ORE, 0);
+ resources.add(ResourceType.LOOM, 0);
+ assertTrue(resources.isEmpty());
+ }
+
+ @Test
+ public void isEmpty_singleElementMoreThanZero() {
+ Resources resources = new Resources();
+ resources.add(ResourceType.LOOM, 3);
+ assertFalse(resources.isEmpty());
+ }
+
+ @Test
+ public void isEmpty_mixedZeroAndNonZeroElements() {
+ Resources resources = new Resources();
+ resources.add(ResourceType.WOOD, 0);
+ resources.add(ResourceType.LOOM, 3);
+ assertFalse(resources.isEmpty());
+ }
+
+ @Test
+ public void isEmpty_mixedZeroAndNonZeroElements_reverseOrder() {
+ Resources resources = new Resources();
+ resources.add(ResourceType.ORE, 3);
+ resources.add(ResourceType.PAPYRUS, 0);
+ assertFalse(resources.isEmpty());
+ }
+
+ @Test
+ public void equals_falseWhenNull() {
+ Resources resources = new Resources();
+ resources.add(ResourceType.GLASS, 1);
+ //noinspection ObjectEqualsNull
+ assertFalse(resources.equals(null));
+ }
+
+ @Test
+ public void equals_falseWhenDifferentClass() {
+ Resources resources = new Resources();
+ resources.add(ResourceType.GLASS, 1);
+ Production production = new Production();
+ production.addFixedResource(ResourceType.GLASS, 1);
+ //noinspection EqualsBetweenInconvertibleTypes
+ assertFalse(resources.equals(production));
+ }
+
+ @Test
+ public void equals_trueWhenSame() {
+ Resources resources = new Resources();
+ assertEquals(resources, resources);
+ }
+
+ @Test
+ public void equals_trueWhenSameContent() {
+ Resources resources1 = new Resources();
+ Resources resources2 = new Resources();
+ assertTrue(resources1.equals(resources2));
+ resources1.add(ResourceType.GLASS, 1);
+ resources2.add(ResourceType.GLASS, 1);
+ assertTrue(resources1.equals(resources2));
+ }
+
+ @Test
+ public void hashCode_sameWhenSameContent() {
+ Resources resources1 = new Resources();
+ Resources resources2 = new Resources();
+ assertEquals(resources1.hashCode(), resources2.hashCode());
+ resources1.add(ResourceType.GLASS, 1);
+ resources2.add(ResourceType.GLASS, 1);
+ assertEquals(resources1.hashCode(), resources2.hashCode());
+ }
+} \ No newline at end of file
diff --git a/backend/src/test/java/org/luxons/sevenwonders/game/resources/TradingRulesTest.java b/backend/src/test/java/org/luxons/sevenwonders/game/resources/TradingRulesTest.java
new file mode 100644
index 00000000..cd6661dc
--- /dev/null
+++ b/backend/src/test/java/org/luxons/sevenwonders/game/resources/TradingRulesTest.java
@@ -0,0 +1,96 @@
+package org.luxons.sevenwonders.game.resources;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.junit.experimental.theories.DataPoints;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+import org.junit.runner.RunWith;
+import org.luxons.sevenwonders.game.test.TestUtils;
+
+import static org.junit.Assert.*;
+import static org.junit.Assume.*;
+
+@RunWith(Theories.class)
+public class TradingRulesTest {
+
+ @DataPoints
+ public static int[] costs() {
+ return new int[] {0, 1, 2};
+ }
+
+ @DataPoints
+ public static Provider[] providers() {
+ return Provider.values();
+ }
+
+ @DataPoints
+ public static ResourceType[] resourceTypes() {
+ return ResourceType.values();
+ }
+
+ @Theory
+ public void computeCost_zeroForNoResources(int defaultCost) {
+ TradingRules rules = new TradingRules(defaultCost);
+ assertEquals(0, rules.computeCost(new ArrayList<>()));
+ }
+
+ @Theory
+ public void computeCost_defaultCostWhenNoOverride(int defaultCost, Provider provider, ResourceType type) {
+ TradingRules rules = new TradingRules(defaultCost);
+ BoughtResources resources = TestUtils.createBoughtResources(provider, type);
+ assertEquals(defaultCost, rules.computeCost(Collections.singletonList(resources)));
+ }
+
+ @Theory
+ public void computeCost_twiceDefaultFor2Resources(int defaultCost, Provider provider, ResourceType type) {
+ TradingRules rules = new TradingRules(defaultCost);
+ BoughtResources resources = TestUtils.createBoughtResources(provider, type, type);
+ assertEquals(2 * defaultCost, rules.computeCost(Collections.singletonList(resources)));
+ }
+
+ @Theory
+ public void computeCost_overriddenCost(int defaultCost, int overriddenCost, Provider provider, ResourceType type) {
+ TradingRules rules = new TradingRules(defaultCost);
+ rules.setCost(type, provider, overriddenCost);
+ BoughtResources resources = TestUtils.createBoughtResources(provider, type);
+ assertEquals(overriddenCost, rules.computeCost(Collections.singletonList(resources)));
+ }
+
+ @Theory
+ public void computeCost_defaultCostWhenOverrideOnOtherProviderOrType(int defaultCost, int overriddenCost,
+ Provider overriddenProvider, ResourceType overriddenType, Provider provider, ResourceType type) {
+ assumeTrue(overriddenProvider != provider || overriddenType != type);
+ TradingRules rules = new TradingRules(defaultCost);
+ rules.setCost(overriddenType, overriddenProvider, overriddenCost);
+ BoughtResources resources = TestUtils.createBoughtResources(provider, type);
+ assertEquals(defaultCost, rules.computeCost(Collections.singletonList(resources)));
+ }
+
+ @Theory
+ public void computeCost_oneDefaultAndOneOverriddenType(int defaultCost, int overriddenCost,
+ ResourceType overriddenType, Provider provider, ResourceType type) {
+ assumeTrue(overriddenType != type);
+ TradingRules rules = new TradingRules(defaultCost);
+ rules.setCost(overriddenType, provider, overriddenCost);
+ BoughtResources resources = TestUtils.createBoughtResources(provider, overriddenType, type);
+ assertEquals(defaultCost + overriddenCost, rules.computeCost(Collections.singletonList(resources)));
+ }
+
+ @Theory
+ public void computeCost_oneDefaultAndOneOverriddenProvider(int defaultCost, int overriddenCost,
+ Provider overriddenProvider, Provider provider, ResourceType type) {
+ assumeTrue(overriddenProvider != provider);
+ TradingRules rules = new TradingRules(defaultCost);
+ rules.setCost(type, overriddenProvider, overriddenCost);
+
+ List<BoughtResources> boughtResources = new ArrayList<>(2);
+ boughtResources.add(TestUtils.createBoughtResources(provider, type));
+ boughtResources.add(TestUtils.createBoughtResources(overriddenProvider, type));
+
+ assertEquals(defaultCost + overriddenCost, rules.computeCost(boughtResources));
+ }
+
+} \ No newline at end of file
diff --git a/backend/src/test/java/org/luxons/sevenwonders/game/test/TestUtils.java b/backend/src/test/java/org/luxons/sevenwonders/game/test/TestUtils.java
new file mode 100644
index 00000000..b5ddb7b1
--- /dev/null
+++ b/backend/src/test/java/org/luxons/sevenwonders/game/test/TestUtils.java
@@ -0,0 +1,191 @@
+package org.luxons.sevenwonders.game.test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.luxons.sevenwonders.game.Game;
+import org.luxons.sevenwonders.game.Player;
+import org.luxons.sevenwonders.game.Settings;
+import org.luxons.sevenwonders.game.api.CustomizableSettings;
+import org.luxons.sevenwonders.game.api.Table;
+import org.luxons.sevenwonders.game.boards.Board;
+import org.luxons.sevenwonders.game.boards.Science;
+import org.luxons.sevenwonders.game.boards.ScienceType;
+import org.luxons.sevenwonders.game.cards.Card;
+import org.luxons.sevenwonders.game.cards.Color;
+import org.luxons.sevenwonders.game.cards.Decks;
+import org.luxons.sevenwonders.game.cards.Requirements;
+import org.luxons.sevenwonders.game.effects.Effect;
+import org.luxons.sevenwonders.game.effects.ScienceProgress;
+import org.luxons.sevenwonders.game.resources.BoughtResources;
+import org.luxons.sevenwonders.game.resources.Production;
+import org.luxons.sevenwonders.game.resources.Provider;
+import org.luxons.sevenwonders.game.resources.ResourceType;
+import org.luxons.sevenwonders.game.resources.Resources;
+import org.luxons.sevenwonders.game.wonders.Wonder;
+import org.luxons.sevenwonders.game.wonders.WonderStage;
+
+public class TestUtils {
+
+ public static Game createGame(int id, int nbPlayers) {
+ Settings settings = new Settings(nbPlayers, new CustomizableSettings());
+ List<Player> players = TestUtils.createPlayers(nbPlayers);
+ List<Board> boards = TestUtils.createBoards(nbPlayers);
+ List<Card> cards = TestUtils.createSampleCards(0, nbPlayers * 7);
+ Map<Integer, List<Card>> cardsPerAge = new HashMap<>();
+ cardsPerAge.put(1, cards);
+ return new Game(id, settings, players, boards, new Decks(cardsPerAge));
+ }
+
+ public static Table createTable(int nbPlayers) {
+ return new Table(createBoards(nbPlayers));
+ }
+
+ public static List<Board> createBoards(int count) {
+ List<Board> boards = new ArrayList<>(count);
+ for (int i = 0; i < count; i++) {
+ boards.add(createBoard(ResourceType.WOOD));
+ }
+ return boards;
+ }
+
+ public static List<Player> createPlayers(int count) {
+ List<Player> players = new ArrayList<>(count);
+ for (int i = 0; i < count; i++) {
+ String username = "testUser" + i;
+ String displayName = "Test User " + i;
+ Player player = new Player(username, displayName);
+ players.add(player);
+ }
+ return players;
+ }
+
+ public static Board createBoard(ResourceType initialResource) {
+ Settings settings = new Settings(5);
+ Wonder wonder = createWonder(initialResource);
+
+ String username = "testUser" + initialResource.getSymbol();
+ String displayName = "Test User " + initialResource.getSymbol();
+ Player player = new Player(username, displayName);
+
+ return new Board(wonder, player, settings);
+ }
+
+ public static Board createBoard(ResourceType initialResource, ResourceType... production) {
+ Board board = createBoard(initialResource);
+ board.getProduction().addAll(createFixedProduction(production));
+ return board;
+ }
+
+ public static Board createBoard(ResourceType initialResource, int gold, ResourceType... production) {
+ Board board = createBoard(initialResource, production);
+ board.setGold(gold);
+ return board;
+ }
+
+ public static Wonder createWonder() {
+ return createWonder(ResourceType.WOOD);
+ }
+
+ public static Wonder createWonder(ResourceType initialResource) {
+ WonderStage stage1 = new WonderStage();
+ stage1.setRequirements(new Requirements());
+ WonderStage stage2 = new WonderStage();
+ stage1.setRequirements(new Requirements());
+ WonderStage stage3 = new WonderStage();
+ stage1.setRequirements(new Requirements());
+ return new Wonder("Test Wonder " + initialResource.getSymbol(), initialResource, stage1, stage2, stage3);
+ }
+
+ public static Production createFixedProduction(ResourceType... producedTypes) {
+ Production production = new Production();
+ Resources fixedProducedResources = production.getFixedResources();
+ fixedProducedResources.addAll(createResources(producedTypes));
+ return production;
+ }
+
+ public static Resources createResources(ResourceType... types) {
+ Resources resources = new Resources();
+ for (ResourceType producedType : types) {
+ resources.add(producedType, 1);
+ }
+ return resources;
+ }
+
+ public static BoughtResources createBoughtResources(Provider provider, ResourceType... resources) {
+ BoughtResources boughtResources = new BoughtResources();
+ boughtResources.setProvider(provider);
+ boughtResources.setResources(TestUtils.createResources(resources));
+ return boughtResources;
+ }
+
+ public static List<Card> createSampleCards(int fromIndex, int nbCards) {
+ List<Card> sampleCards = new ArrayList<>();
+ for (int i = fromIndex; i < fromIndex + nbCards; i++) {
+ sampleCards.add(createCard(i, Color.BLUE));
+ }
+ return sampleCards;
+ }
+
+ public static Card createCard(String name) {
+ return new Card(name, Color.BLUE, new Requirements(), null, null, null, null);
+ }
+
+ private static Card createCard(int num, Color color) {
+ return new Card("Test Card " + num, color, new Requirements(), null, null, null, null);
+ }
+
+ public static Card createGuildCard(int num, Effect effect) {
+ List<Effect> effects = Collections.singletonList(effect);
+ return new Card("Test Guild " + num, Color.PURPLE, new Requirements(), effects, null, null, null);
+ }
+
+ public static void addCards(Board board, int nbCardsOfColor, int nbOtherCards, Color color) {
+ addCards(board, nbCardsOfColor, color);
+ Color otherColor = getDifferentColorFrom(color);
+ addCards(board, nbOtherCards, otherColor);
+ }
+
+ public static void addCards(Board board, int nbCards, Color color) {
+ for (int i = 0; i < nbCards; i++) {
+ board.addCard(createCard(i, color));
+ }
+ }
+
+ public static Color getDifferentColorFrom(Color... colors) {
+ List<Color> forbiddenColors = Arrays.asList(colors);
+ for (Color color : Color.values()) {
+ if (!forbiddenColors.contains(color)) {
+ return color;
+ }
+ }
+ throw new IllegalArgumentException("All colors are forbidden!");
+ }
+
+ public static ScienceProgress createScienceProgress(int compasses, int wheels, int tablets, int jokers) {
+ ScienceProgress progress = new ScienceProgress();
+ progress.setScience(TestUtils.createScience(compasses, wheels, tablets, jokers));
+ return progress;
+ }
+
+ public static Science createScience(int compasses, int wheels, int tablets, int jokers) {
+ Science science = new Science();
+ if (compasses > 0) {
+ science.add(ScienceType.COMPASS, compasses);
+ }
+ if (wheels > 0) {
+ science.add(ScienceType.WHEEL, wheels);
+ }
+ if (tablets > 0) {
+ science.add(ScienceType.TABLET, tablets);
+ }
+ if (jokers > 0) {
+ science.addJoker(jokers);
+ }
+ return science;
+ }
+}
diff --git a/backend/src/test/java/org/luxons/sevenwonders/repositories/GameRepositoryTest.java b/backend/src/test/java/org/luxons/sevenwonders/repositories/GameRepositoryTest.java
new file mode 100644
index 00000000..5d7d558b
--- /dev/null
+++ b/backend/src/test/java/org/luxons/sevenwonders/repositories/GameRepositoryTest.java
@@ -0,0 +1,61 @@
+package org.luxons.sevenwonders.repositories;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.luxons.sevenwonders.game.Game;
+import org.luxons.sevenwonders.game.test.TestUtils;
+import org.luxons.sevenwonders.repositories.GameRepository.GameAlreadyExistsException;
+import org.luxons.sevenwonders.repositories.GameRepository.GameNotFoundException;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.fail;
+
+public class GameRepositoryTest {
+
+ private GameRepository repository;
+
+ @Before
+ public void setUp() {
+ repository = new GameRepository();
+ }
+
+ @Test(expected = GameAlreadyExistsException.class)
+ public void add_failsOnExistingId() {
+ Game game1 = TestUtils.createGame(0, 5);
+ repository.add(game1);
+ Game game2 = TestUtils.createGame(0, 7);
+ repository.add(game2);
+ }
+
+ @Test(expected = GameNotFoundException.class)
+ public void find_failsOnUnknownId() {
+ repository.find(123);
+ }
+
+ @Test
+ public void find_returnsTheSameObject() {
+ Game game = TestUtils.createGame(0, 5);
+ repository.add(game);
+ assertSame(game, repository.find(0));
+ }
+
+ @Test(expected = GameNotFoundException.class)
+ public void remove_failsOnUnknownId() {
+ repository.remove(123);
+ }
+
+ @Test
+ public void remove_succeeds() {
+ Game game = TestUtils.createGame(0, 5);
+ repository.add(game);
+ assertNotNull(repository.find(0));
+ repository.remove(0);
+ try {
+ repository.find(0);
+ fail(); // the call to find() should have failed
+ } catch (GameNotFoundException e) {
+ // the game has been properly removed
+ }
+ }
+} \ No newline at end of file
diff --git a/backend/src/test/java/org/luxons/sevenwonders/repositories/LobbyRepositoryTest.java b/backend/src/test/java/org/luxons/sevenwonders/repositories/LobbyRepositoryTest.java
new file mode 100644
index 00000000..f5a8d800
--- /dev/null
+++ b/backend/src/test/java/org/luxons/sevenwonders/repositories/LobbyRepositoryTest.java
@@ -0,0 +1,77 @@
+package org.luxons.sevenwonders.repositories;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.luxons.sevenwonders.game.Lobby;
+import org.luxons.sevenwonders.game.Player;
+import org.luxons.sevenwonders.game.data.GameDefinitionLoader;
+import org.luxons.sevenwonders.repositories.LobbyRepository.LobbyNotFoundException;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+public class LobbyRepositoryTest {
+
+ private LobbyRepository repository;
+
+ @Before
+ public void setUp() {
+ repository = new LobbyRepository(new GameDefinitionLoader());
+ }
+
+ @Test
+ public void list_initiallyEmpty() {
+ assertTrue(repository.list().isEmpty());
+ }
+
+ @Test
+ public void list_returnsAllLobbies() {
+ Player owner = new Player("owner", "The Owner");
+ Lobby lobby1 = repository.create("Test Name 1", owner);
+ Lobby lobby2 = repository.create("Test Name 2", owner);
+ assertTrue(repository.list().contains(lobby1));
+ assertTrue(repository.list().contains(lobby2));
+ }
+
+ @Test
+ public void create_withCorrectOwner() {
+ Player owner = new Player("owner", "The Owner");
+ Lobby lobby = repository.create("Test Name", owner);
+ assertTrue(lobby.isOwner(owner.getUsername()));
+ }
+
+ @Test(expected = LobbyNotFoundException.class)
+ public void find_failsOnUnknownId() {
+ repository.find(123);
+ }
+
+ @Test
+ public void find_returnsTheSameObject() {
+ Player owner = new Player("owner", "The Owner");
+ Lobby lobby1 = repository.create("Test Name 1", owner);
+ Lobby lobby2 = repository.create("Test Name 2", owner);
+ assertSame(lobby1, repository.find(lobby1.getId()));
+ assertSame(lobby2, repository.find(lobby2.getId()));
+ }
+
+ @Test(expected = LobbyNotFoundException.class)
+ public void remove_failsOnUnknownId() {
+ repository.remove(123);
+ }
+
+ @Test
+ public void remove_succeeds() {
+ Player owner = new Player("owner", "The Owner");
+ Lobby lobby1 = repository.create("Test Name 1", owner);
+ assertNotNull(repository.find(lobby1.getId()));
+ repository.remove(lobby1.getId());
+ try {
+ repository.find(lobby1.getId());
+ fail(); // the call to find() should have failed
+ } catch (LobbyNotFoundException e) {
+ // the lobby has been properly removed
+ }
+ }
+} \ No newline at end of file
diff --git a/backend/src/test/java/org/luxons/sevenwonders/repositories/PlayerRepositoryTest.java b/backend/src/test/java/org/luxons/sevenwonders/repositories/PlayerRepositoryTest.java
new file mode 100644
index 00000000..d9e07b3f
--- /dev/null
+++ b/backend/src/test/java/org/luxons/sevenwonders/repositories/PlayerRepositoryTest.java
@@ -0,0 +1,73 @@
+package org.luxons.sevenwonders.repositories;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.luxons.sevenwonders.game.Player;
+import org.luxons.sevenwonders.repositories.PlayerRepository.PlayerNotFoundException;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+public class PlayerRepositoryTest {
+
+ private PlayerRepository repository;
+
+ @Before
+ public void setUp() {
+ repository = new PlayerRepository();
+ }
+
+ @Test
+ public void contains_falseIfNoUserAdded() {
+ assertFalse(repository.contains("anyUsername"));
+ }
+
+ @Test
+ public void contains_trueForCreatedPlayer() {
+ repository.createOrUpdate("player1", "Player 1");
+ assertTrue(repository.contains("player1"));
+ }
+
+ @Test
+ public void createOrUpdate_createsProperly() {
+ Player player1 = repository.createOrUpdate("player1", "Player 1");
+ assertEquals("player1", player1.getUsername());
+ assertEquals("Player 1", player1.getDisplayName());
+ }
+
+ @Test
+ public void createOrUpdate_updatesDisplayName() {
+ Player player1 = repository.createOrUpdate("player1", "Player 1");
+ Player player1Updated = repository.createOrUpdate("player1", "Much Better Name");
+ assertSame(player1, player1Updated);
+ assertEquals("Much Better Name", player1Updated.getDisplayName());
+ }
+
+ @Test(expected = PlayerNotFoundException.class)
+ public void find_failsOnUnknownUsername() {
+ repository.find("anyUsername");
+ }
+
+ @Test
+ public void find_returnsTheSameObject() {
+ Player player1 = repository.createOrUpdate("player1", "Player 1");
+ Player player2 = repository.createOrUpdate("player2", "Player 2");
+ assertSame(player1, repository.find("player1"));
+ assertSame(player2, repository.find("player2"));
+ }
+
+ @Test(expected = PlayerNotFoundException.class)
+ public void remove_failsOnUnknownUsername() {
+ repository.remove("anyUsername");
+ }
+
+ @Test
+ public void remove_succeeds() {
+ repository.createOrUpdate("player1", "Player 1");
+ assertTrue(repository.contains("player1"));
+ repository.remove("player1");
+ assertFalse(repository.contains("player1"));
+ }
+} \ No newline at end of file
diff --git a/backend/src/test/java/org/luxons/sevenwonders/validation/DestinationAccessValidatorTest.java b/backend/src/test/java/org/luxons/sevenwonders/validation/DestinationAccessValidatorTest.java
new file mode 100644
index 00000000..1a799ff3
--- /dev/null
+++ b/backend/src/test/java/org/luxons/sevenwonders/validation/DestinationAccessValidatorTest.java
@@ -0,0 +1,147 @@
+package org.luxons.sevenwonders.validation;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.luxons.sevenwonders.game.Game;
+import org.luxons.sevenwonders.game.Lobby;
+import org.luxons.sevenwonders.game.Player;
+import org.luxons.sevenwonders.game.data.GameDefinitionLoader;
+import org.luxons.sevenwonders.repositories.GameRepository;
+import org.luxons.sevenwonders.repositories.GameRepository.GameNotFoundException;
+import org.luxons.sevenwonders.repositories.LobbyRepository;
+import org.luxons.sevenwonders.repositories.LobbyRepository.LobbyNotFoundException;
+
+import static org.junit.Assert.*;
+
+public class DestinationAccessValidatorTest {
+
+ private LobbyRepository lobbyRepository;
+
+ private GameRepository gameRepository;
+
+ private DestinationAccessValidator destinationAccessValidator;
+
+ @Before
+ public void setup() {
+ gameRepository = new GameRepository();
+ lobbyRepository = new LobbyRepository(new GameDefinitionLoader());
+ destinationAccessValidator = new DestinationAccessValidator(lobbyRepository, gameRepository);
+ }
+
+ private Lobby createLobby(String gameName, String ownerUsername, String... otherPlayers) {
+ Player owner = new Player(ownerUsername, ownerUsername);
+ Lobby lobby = lobbyRepository.create(gameName, owner);
+ for (String playerName : otherPlayers) {
+ Player player = new Player(playerName, playerName);
+ lobby.addPlayer(player);
+ }
+ return lobby;
+ }
+
+ private void createGame(String gameName, String ownerUsername, String... otherPlayers) {
+ Lobby lobby = createLobby(gameName, ownerUsername, otherPlayers);
+ Game game = lobby.startGame();
+ gameRepository.add(game);
+ }
+
+ @Test
+ public void validate_failsOnNullUser() {
+ assertFalse(destinationAccessValidator.hasAccess(null, "doesNotMatter"));
+ }
+
+ @Test
+ public void validate_successWhenNoReference() {
+ assertTrue(destinationAccessValidator.hasAccess("", ""));
+ assertTrue(destinationAccessValidator.hasAccess("", "test"));
+ assertTrue(destinationAccessValidator.hasAccess("testUser", "test"));
+ }
+
+ @Test
+ public void validate_successWhenNoRefFollows() {
+ assertTrue(destinationAccessValidator.hasAccess("testUser", "/game/"));
+ assertTrue(destinationAccessValidator.hasAccess("testUser", "/lobby/"));
+ assertTrue(destinationAccessValidator.hasAccess("testUser", "prefix/game/"));
+ assertTrue(destinationAccessValidator.hasAccess("testUser", "prefix/lobby/"));
+ assertTrue(destinationAccessValidator.hasAccess("testUser", "/game//suffix"));
+ assertTrue(destinationAccessValidator.hasAccess("testUser", "/lobby//suffix"));
+ }
+
+ @Test
+ public void validate_successWhenRefIsNotANumber() {
+ assertTrue(destinationAccessValidator.hasAccess("testUser", "/game/notANumber"));
+ assertTrue(destinationAccessValidator.hasAccess("testUser", "/lobby/notANumber"));
+ assertTrue(destinationAccessValidator.hasAccess("testUser", "prefix/game/notANumber"));
+ assertTrue(destinationAccessValidator.hasAccess("testUser", "prefix/lobby/notANumber"));
+ assertTrue(destinationAccessValidator.hasAccess("testUser", "/game/notANumber/suffix"));
+ assertTrue(destinationAccessValidator.hasAccess("testUser", "/lobby/notANumber/suffix"));
+ }
+
+ @Test(expected = LobbyNotFoundException.class)
+ public void validate_failWhenNoLobbyExist() {
+ destinationAccessValidator.hasAccess("", "/lobby/0");
+ }
+
+ @Test(expected = GameNotFoundException.class)
+ public void validate_failWhenNoGameExist() {
+ destinationAccessValidator.hasAccess("", "/game/0");
+ }
+
+ @Test(expected = LobbyNotFoundException.class)
+ public void validate_failWhenReferencedLobbyDoesNotExist() {
+ createLobby("Test Game", "ownerUser1");
+ createLobby("Test Game 2", "ownerUser2");
+ destinationAccessValidator.hasAccess("doesNotMatter", "/lobby/3");
+ }
+
+ @Test(expected = GameNotFoundException.class)
+ public void validate_failWhenReferencedGameDoesNotExist() {
+ createGame("Test Game 1", "user1", "user2", "user3");
+ createGame("Test Game 2", "user4", "user5", "user6");
+ destinationAccessValidator.hasAccess("doesNotMatter", "/game/3");
+ }
+
+ @Test
+ public void validate_failWhenUserIsNotPartOfReferencedLobby() {
+ createLobby("Test Game", "ownerUser");
+ destinationAccessValidator.hasAccess("userNotInLobby", "/lobby/0");
+ }
+
+ @Test
+ public void validate_failWhenUserIsNotPartOfReferencedGame() {
+ createGame("Test Game", "ownerUser", "otherUser1", "otherUser2");
+ destinationAccessValidator.hasAccess("userNotInGame", "/game/0");
+ }
+
+ @Test
+ public void validate_successWhenUserIsOwnerOfReferencedLobby() {
+ createLobby("Test Game 1", "user1");
+ assertTrue(destinationAccessValidator.hasAccess("user1", "/lobby/0"));
+ createLobby("Test Game 2", "user2");
+ assertTrue(destinationAccessValidator.hasAccess("user2", "/lobby/1"));
+ }
+
+ @Test
+ public void validate_successWhenUserIsMemberOfReferencedLobby() {
+ createLobby("Test Game 1", "user1", "user2");
+ assertTrue(destinationAccessValidator.hasAccess("user2", "/lobby/0"));
+ createLobby("Test Game 2", "user3", "user4");
+ assertTrue(destinationAccessValidator.hasAccess("user4", "/lobby/1"));
+ }
+
+ @Test
+ public void validate_successWhenUserIsOwnerOfReferencedGame() {
+ createGame("Test Game 1", "owner1", "user2", "user3");
+ assertTrue(destinationAccessValidator.hasAccess("owner1", "/game/0"));
+ createGame("Test Game 2", "owner4", "user5", "user6");
+ assertTrue(destinationAccessValidator.hasAccess("owner4", "/game/1"));
+ }
+
+ @Test
+ public void validate_successWhenUserIsMemberOfReferencedGame() {
+ createGame("Test Game 1", "owner1", "user2", "user3");
+ assertTrue(destinationAccessValidator.hasAccess("user2", "/game/0"));
+ createGame("Test Game 2", "owner4", "user5", "user6");
+ assertTrue(destinationAccessValidator.hasAccess("user6", "/game/1"));
+ }
+
+} \ No newline at end of file
bgstack15