diff options
author | Joffrey Bion <joffrey.bion@amadeus.com> | 2018-07-09 15:22:53 +0200 |
---|---|---|
committer | Joffrey Bion <joffrey.bion@amadeus.com> | 2018-07-09 15:22:53 +0200 |
commit | f92facc7ccfc9564f7481940c5b23b66a473982f (patch) | |
tree | 00ba42ee9cad92aa7d82336a85b891e02f784869 /game-engine/src/test/kotlin | |
parent | Kotlin mig: Boards package (diff) | |
download | seven-wonders-f92facc7ccfc9564f7481940c5b23b66a473982f.tar.gz seven-wonders-f92facc7ccfc9564f7481940c5b23b66a473982f.tar.bz2 seven-wonders-f92facc7ccfc9564f7481940c5b23b66a473982f.zip |
Kotlin mig: moves package
Diffstat (limited to 'game-engine/src/test/kotlin')
6 files changed, 1173 insertions, 0 deletions
diff --git a/game-engine/src/test/kotlin/org/luxons/sevenwonders/game/moves/BuildWonderMoveTest.kt b/game-engine/src/test/kotlin/org/luxons/sevenwonders/game/moves/BuildWonderMoveTest.kt new file mode 100644 index 00000000..ee461e38 --- /dev/null +++ b/game-engine/src/test/kotlin/org/luxons/sevenwonders/game/moves/BuildWonderMoveTest.kt @@ -0,0 +1,76 @@ +package org.luxons.sevenwonders.game.moves + +import org.junit.Assert.assertEquals +import org.junit.Assert.fail +import org.junit.Test +import org.luxons.sevenwonders.game.Settings +import org.luxons.sevenwonders.game.api.Table +import org.luxons.sevenwonders.game.cards.Card +import org.luxons.sevenwonders.game.test.createMove +import org.luxons.sevenwonders.game.test.sampleCards +import org.luxons.sevenwonders.game.test.testCard +import org.luxons.sevenwonders.game.test.testSettings +import org.luxons.sevenwonders.game.test.testTable + +class BuildWonderMoveTest { + + @Test(expected = InvalidMoveException::class) + fun validate_failsWhenCardNotInHand() { + val table = testTable(3) + val hand = sampleCards(0, 7) + val anotherCard = testCard("Card that is not in the hand") + val move = createMove(0, anotherCard, MoveType.UPGRADE_WONDER) + + move.validate(table, hand) + } + + @Test(expected = InvalidMoveException::class) + fun validate_failsWhenWonderIsCompletelyBuilt() { + val settings = testSettings(3) + val table = testTable(settings) + val hand = sampleCards(0, 7) + + fillPlayerWonderLevels(settings, table, hand) + + // should fail because the wonder is already full + buildOneWonderLevel(settings, table, hand, 4) + } + + private fun fillPlayerWonderLevels(settings: Settings, table: Table, hand: List<Card>) { + try { + val nbLevels = table.getBoard(0).wonder.stages.size + for (i in 0 until nbLevels) { + buildOneWonderLevel(settings, table, hand, i) + } + } catch (e: InvalidMoveException) { + fail("Building wonder levels should not fail before being full") + } + } + + private fun buildOneWonderLevel(settings: Settings, table: Table, hand: List<Card>, cardIndex: Int) { + val card = hand[cardIndex] + val move = createMove(0, card, MoveType.UPGRADE_WONDER) + move.validate(table, hand) + move.place(table, mutableListOf(), settings) + move.activate(table, emptyList(), settings) + } + + @Test + fun place_increasesWonderLevel() { + val settings = testSettings(3) + val table = testTable(settings) + val hand = sampleCards(0, 7) + val cardToUse = hand[0] + val move = createMove(0, cardToUse, MoveType.UPGRADE_WONDER) + move.validate(table, hand) // should not fail + + val initialStage = table.getBoard(0).wonder.nbBuiltStages + + move.place(table, mutableListOf(), settings) + + val newStage = table.getBoard(0).wonder.nbBuiltStages + + // we need to see the level increase before activation so that other players + assertEquals((initialStage + 1).toLong(), newStage.toLong()) + } +} diff --git a/game-engine/src/test/kotlin/org/luxons/sevenwonders/game/resources/BestPriceCalculatorTest.kt b/game-engine/src/test/kotlin/org/luxons/sevenwonders/game/resources/BestPriceCalculatorTest.kt new file mode 100644 index 00000000..f4cf5294 --- /dev/null +++ b/game-engine/src/test/kotlin/org/luxons/sevenwonders/game/resources/BestPriceCalculatorTest.kt @@ -0,0 +1,129 @@ +package org.luxons.sevenwonders.game.resources + +import java.util.Arrays + +import org.junit.Test +import org.luxons.sevenwonders.game.api.Table +import org.luxons.sevenwonders.game.boards.Board +import org.luxons.sevenwonders.game.test.* + +import org.junit.Assert.assertEquals +import org.luxons.sevenwonders.game.resources.Provider.LEFT_PLAYER +import org.luxons.sevenwonders.game.resources.Provider.RIGHT_PLAYER +import org.luxons.sevenwonders.game.resources.ResourceType.CLAY +import org.luxons.sevenwonders.game.resources.ResourceType.GLASS +import org.luxons.sevenwonders.game.resources.ResourceType.ORE +import org.luxons.sevenwonders.game.resources.ResourceType.STONE +import org.luxons.sevenwonders.game.resources.ResourceType.WOOD + +class BestPriceCalculatorTest { + + @Test + fun bestPrice_0forEmptyResources() { + val table = testTable(3) + val resources = Resources() + assertEquals(0, BestPriceCalculator.bestPrice(resources, table, 0).toLong()) + assertEquals(ResourceTransactions(), BestPriceCalculator.bestSolution(resources, table, 0)) + } + + @Test + fun bestPrice_fixedResources_defaultCost() { + val left = testBoard(STONE) + val main = testBoard(STONE) + val right = testBoard(WOOD) + val table = Table(Arrays.asList(main, right, left)) + + val resources = createResources(STONE, STONE) + assertEquals(2, BestPriceCalculator.bestPrice(resources, table, 0).toLong()) + assertEquals(4, BestPriceCalculator.bestPrice(resources, table, 1).toLong()) + assertEquals(2, BestPriceCalculator.bestPrice(resources, table, 2).toLong()) + + val stoneLeftSingle = createTransaction(LEFT_PLAYER, STONE) + val stoneRightSingle = createTransaction(RIGHT_PLAYER, STONE) + + val stoneLeft = createTransactions(stoneLeftSingle) + val stoneRight = createTransactions(stoneRightSingle) + val stoneLeftAndRight = createTransactions(stoneLeftSingle, stoneRightSingle) + + assertEquals(stoneLeft, BestPriceCalculator.bestSolution(resources, table, 0)) + assertEquals(stoneLeftAndRight, BestPriceCalculator.bestSolution(resources, table, 1)) + assertEquals(stoneRight, BestPriceCalculator.bestSolution(resources, table, 2)) + } + + @Test + fun bestPrice_fixedResources_overridenCost() { + val main = testBoard(STONE) + main.tradingRules.setCost(WOOD, RIGHT_PLAYER, 1) + + val left = testBoard(WOOD) + val right = testBoard(WOOD) + val opposite = testBoard(GLASS) + val table = Table(Arrays.asList(main, right, opposite, left)) + + val resources = createResources(WOOD) + assertEquals(1, BestPriceCalculator.bestPrice(resources, table, 0).toLong()) + assertEquals(0, BestPriceCalculator.bestPrice(resources, table, 1).toLong()) + assertEquals(2, BestPriceCalculator.bestPrice(resources, table, 2).toLong()) + assertEquals(0, BestPriceCalculator.bestPrice(resources, table, 3).toLong()) + + val woodLeft = createTransactions(LEFT_PLAYER, WOOD) + val woodRight = createTransactions(RIGHT_PLAYER, WOOD) + assertEquals(woodRight, BestPriceCalculator.bestSolution(resources, table, 0)) + assertEquals(ResourceTransactions(), BestPriceCalculator.bestSolution(resources, table, 1)) + assertEquals(woodLeft, BestPriceCalculator.bestSolution(resources, table, 2)) + assertEquals(ResourceTransactions(), BestPriceCalculator.bestSolution(resources, table, 3)) + } + + @Test + fun bestPrice_mixedResources_overridenCost() { + val left = testBoard(WOOD) + + val main = testBoard(STONE) + main.tradingRules.setCost(WOOD, RIGHT_PLAYER, 1) + + val right = testBoard(ORE) + right.production.addChoice(WOOD, CLAY) + right.publicProduction.addChoice(WOOD, CLAY) + + val table = Table(Arrays.asList(main, right, left)) + + val resources = createResources(WOOD) + assertEquals(1, BestPriceCalculator.bestPrice(resources, table, 0).toLong()) + assertEquals(0, BestPriceCalculator.bestPrice(resources, table, 1).toLong()) + assertEquals(0, BestPriceCalculator.bestPrice(resources, table, 2).toLong()) + + val woodRight = createTransactions(RIGHT_PLAYER, WOOD) + + assertEquals(woodRight, BestPriceCalculator.bestSolution(resources, table, 0)) + assertEquals(ResourceTransactions(), BestPriceCalculator.bestSolution(resources, table, 1)) + assertEquals(ResourceTransactions(), BestPriceCalculator.bestSolution(resources, table, 2)) + } + + @Test + fun bestPrice_chooseCheapest() { + val left = testBoard(WOOD) + + val main = testBoard(WOOD) + main.production.addChoice(CLAY, ORE) + main.tradingRules.setCost(CLAY, RIGHT_PLAYER, 1) + + val right = testBoard(WOOD) + right.production.addFixedResource(ORE, 1) + right.production.addFixedResource(CLAY, 1) + right.publicProduction.addFixedResource(ORE, 1) + right.publicProduction.addFixedResource(CLAY, 1) + + val table = Table(Arrays.asList(main, right, left)) + + val resources = createResources(ORE, CLAY) + assertEquals(1, BestPriceCalculator.bestPrice(resources, table, 0).toLong()) + assertEquals(0, BestPriceCalculator.bestPrice(resources, table, 1).toLong()) + assertEquals(4, BestPriceCalculator.bestPrice(resources, table, 2).toLong()) + + val oreAndClayLeft = createTransactions(LEFT_PLAYER, ORE, CLAY) + val clayRight = createTransactions(RIGHT_PLAYER, CLAY) + assertEquals(clayRight, BestPriceCalculator.bestSolution(resources, table, 0)) + assertEquals(ResourceTransactions(), BestPriceCalculator.bestSolution(resources, table, 1)) + assertEquals(oreAndClayLeft, BestPriceCalculator.bestSolution(resources, table, 2)) + } +} diff --git a/game-engine/src/test/kotlin/org/luxons/sevenwonders/game/resources/ProductionTest.kt b/game-engine/src/test/kotlin/org/luxons/sevenwonders/game/resources/ProductionTest.kt new file mode 100644 index 00000000..27f85c1a --- /dev/null +++ b/game-engine/src/test/kotlin/org/luxons/sevenwonders/game/resources/ProductionTest.kt @@ -0,0 +1,323 @@ +package org.luxons.sevenwonders.game.resources + +import java.util.EnumSet +import java.util.HashSet + +import org.junit.Before +import org.junit.Test + +import org.junit.Assert.assertEquals +import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue + +class ProductionTest { + + private var emptyResources: Resources? = null + + private var resources1Wood: Resources? = null + + private var resources1Stone: Resources? = null + + private var resources1Stone1Wood: Resources? = null + + private var resources2Stones: Resources? = null + + private var resources2Stones3Clay: Resources? = null + + @Before + fun init() { + emptyResources = Resources() + + resources1Wood = Resources() + resources1Wood!!.add(ResourceType.WOOD, 1) + + resources1Stone = Resources() + resources1Stone!!.add(ResourceType.STONE, 1) + + resources1Stone1Wood = Resources() + resources1Stone1Wood!!.add(ResourceType.STONE, 1) + resources1Stone1Wood!!.add(ResourceType.WOOD, 1) + + resources2Stones = Resources() + resources2Stones!!.add(ResourceType.STONE, 2) + + resources2Stones3Clay = Resources() + resources2Stones3Clay!!.add(ResourceType.STONE, 2) + resources2Stones3Clay!!.add(ResourceType.CLAY, 3) + } + + @Test + fun contains_newProductionContainsEmpty() { + val production = Production() + assertTrue(production.contains(emptyResources)) + } + + @Test + fun contains_singleFixedResource_noneAtAll() { + val production = Production() + assertFalse(production.contains(resources2Stones)) + } + + @Test + fun contains_singleFixedResource_notEnough() { + val production = Production() + production.addFixedResource(ResourceType.STONE, 1) + assertFalse(production.contains(resources2Stones)) + } + + @Test + fun contains_singleFixedResource_justEnough() { + val production = Production() + production.addFixedResource(ResourceType.STONE, 2) + assertTrue(production.contains(resources2Stones)) + } + + @Test + fun contains_singleFixedResource_moreThanEnough() { + val production = Production() + production.addFixedResource(ResourceType.STONE, 3) + assertTrue(production.contains(resources2Stones)) + } + + @Test + fun contains_singleFixedResource_moreThanEnough_amongOthers() { + val production = Production() + production.addFixedResource(ResourceType.STONE, 3) + production.addFixedResource(ResourceType.CLAY, 2) + assertTrue(production.contains(resources2Stones)) + } + + @Test + fun contains_multipleFixedResources_notEnoughOfOne() { + val production = Production() + production.addFixedResource(ResourceType.STONE, 3) + production.addFixedResource(ResourceType.CLAY, 1) + assertFalse(production.contains(resources2Stones3Clay)) + } + + @Test + fun contains_multipleFixedResources_notEnoughOfBoth() { + val production = Production() + production.addFixedResource(ResourceType.STONE, 1) + production.addFixedResource(ResourceType.CLAY, 1) + assertFalse(production.contains(resources2Stones3Clay)) + } + + @Test + fun contains_multipleFixedResources_moreThanEnough() { + val production = Production() + production.addFixedResource(ResourceType.STONE, 3) + production.addFixedResource(ResourceType.CLAY, 5) + assertTrue(production.contains(resources2Stones3Clay)) + } + + @Test + fun contains_singleChoice_containsEmpty() { + val production = Production() + production.addChoice(ResourceType.STONE, ResourceType.CLAY) + assertTrue(production.contains(emptyResources)) + } + + @Test + fun contains_singleChoice_enough() { + val production = Production() + production.addChoice(ResourceType.STONE, ResourceType.WOOD) + assertTrue(production.contains(resources1Wood)) + assertTrue(production.contains(resources1Stone)) + } + + @Test + fun contains_multipleChoices_notBoth() { + val production = Production() + production.addChoice(ResourceType.STONE, ResourceType.CLAY) + production.addChoice(ResourceType.STONE, ResourceType.CLAY) + production.addChoice(ResourceType.STONE, ResourceType.CLAY) + assertFalse(production.contains(resources2Stones3Clay)) + } + + @Test + fun contains_multipleChoices_enough() { + val production = Production() + production.addChoice(ResourceType.STONE, ResourceType.ORE) + production.addChoice(ResourceType.STONE, ResourceType.WOOD) + assertTrue(production.contains(resources1Stone1Wood)) + } + + @Test + fun contains_multipleChoices_enoughReverseOrder() { + val production = Production() + production.addChoice(ResourceType.STONE, ResourceType.WOOD) + production.addChoice(ResourceType.STONE, ResourceType.ORE) + assertTrue(production.contains(resources1Stone1Wood)) + } + + @Test + fun contains_multipleChoices_moreThanEnough() { + val production = 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 + fun contains_mixedFixedAndChoice_enough() { + val production = Production() + production.addFixedResource(ResourceType.WOOD, 1) + production.addChoice(ResourceType.STONE, ResourceType.WOOD) + assertTrue(production.contains(resources1Stone1Wood)) + } + + @Test + fun addAll_empty() { + val production = Production() + production.addAll(emptyResources) + assertTrue(production.contains(emptyResources)) + } + + @Test + fun addAll_singleResource() { + val production = Production() + production.addAll(resources1Stone) + assertTrue(production.contains(resources1Stone)) + } + + @Test + fun addAll_multipleResources() { + val production = Production() + production.addAll(resources2Stones3Clay) + assertTrue(production.contains(resources2Stones3Clay)) + } + + @Test + fun addAll_production_multipleFixedResources() { + val production = Production() + production.addAll(resources2Stones3Clay) + + val production2 = Production() + production2.addAll(production) + + assertTrue(production2.contains(resources2Stones3Clay)) + } + + @Test + fun addAll_production_multipleChoices() { + val production = Production() + production.addChoice(ResourceType.STONE, ResourceType.WOOD) + production.addChoice(ResourceType.STONE, ResourceType.ORE) + + val production2 = Production() + production2.addAll(production) + assertTrue(production.contains(resources1Stone1Wood)) + } + + @Test + fun addAll_production_mixedFixedResourcesAndChoices() { + val production = Production() + production.addFixedResource(ResourceType.WOOD, 1) + production.addChoice(ResourceType.STONE, ResourceType.WOOD) + + val production2 = Production() + production2.addAll(production) + + assertTrue(production.contains(resources1Stone1Wood)) + } + + @Test + fun asChoices_empty() { + val production = Production() + assertTrue(production.asChoices().isEmpty()) + } + + @Test + fun asChoices_onlyChoices() { + val production = Production() + production.addChoice(ResourceType.STONE, ResourceType.WOOD) + production.addChoice(ResourceType.STONE, ResourceType.ORE) + production.addChoice(ResourceType.CLAY, ResourceType.LOOM, ResourceType.GLASS) + assertEquals(production.alternativeResources, production.asChoices()) + } + + @Test + fun asChoices_onlyFixed() { + val production = Production() + production.addFixedResource(ResourceType.WOOD, 1) + production.addFixedResource(ResourceType.CLAY, 2) + + val expected = HashSet<Set<ResourceType>>() + expected.add(EnumSet.of(ResourceType.WOOD)) + expected.add(EnumSet.of(ResourceType.CLAY)) + expected.add(EnumSet.of(ResourceType.CLAY)) + + assertEquals(expected, production.asChoices()) + } + + @Test + fun asChoices_mixed() { + val production = Production() + production.addChoice(ResourceType.STONE, ResourceType.ORE) + production.addChoice(ResourceType.CLAY, ResourceType.LOOM, ResourceType.GLASS) + production.addFixedResource(ResourceType.WOOD, 1) + production.addFixedResource(ResourceType.CLAY, 2) + + val expected = HashSet<Set<ResourceType>>() + expected.add(EnumSet.of(ResourceType.STONE, ResourceType.ORE)) + expected.add(EnumSet.of(ResourceType.CLAY, ResourceType.LOOM, ResourceType.GLASS)) + expected.add(EnumSet.of(ResourceType.WOOD)) + expected.add(EnumSet.of(ResourceType.CLAY)) + expected.add(EnumSet.of(ResourceType.CLAY)) + + assertEquals(expected, production.asChoices()) + } + + @Test + fun equals_falseWhenNull() { + val production = Production() + production.addFixedResource(ResourceType.GLASS, 1) + production.addChoice(ResourceType.ORE, ResourceType.WOOD) + + assertFalse(production == null) + } + + @Test + fun equals_falseWhenDifferentClass() { + val production = Production() + production.addFixedResource(ResourceType.GLASS, 1) + val resources = Resources() + resources.add(ResourceType.GLASS, 1) + + assertFalse(production == resources) + } + + @Test + fun equals_trueWhenSame() { + val production = Production() + assertEquals(production, production) + } + + @Test + fun equals_trueWhenSameContent() { + val production1 = Production() + val production2 = Production() + assertTrue(production1 == production2) + production1.addFixedResource(ResourceType.GLASS, 1) + production2.addFixedResource(ResourceType.GLASS, 1) + assertTrue(production1 == production2) + production1.addChoice(ResourceType.ORE, ResourceType.WOOD) + production2.addChoice(ResourceType.ORE, ResourceType.WOOD) + assertTrue(production1 == production2) + } + + @Test + fun hashCode_sameWhenSameContent() { + val production1 = Production() + val production2 = Production() + assertEquals(production1.hashCode().toLong(), production2.hashCode().toLong()) + production1.addFixedResource(ResourceType.GLASS, 1) + production2.addFixedResource(ResourceType.GLASS, 1) + assertEquals(production1.hashCode().toLong(), production2.hashCode().toLong()) + production1.addChoice(ResourceType.ORE, ResourceType.WOOD) + production2.addChoice(ResourceType.ORE, ResourceType.WOOD) + assertEquals(production1.hashCode().toLong(), production2.hashCode().toLong()) + } +} diff --git a/game-engine/src/test/kotlin/org/luxons/sevenwonders/game/resources/ResourceTransactionsTest.kt b/game-engine/src/test/kotlin/org/luxons/sevenwonders/game/resources/ResourceTransactionsTest.kt new file mode 100644 index 00000000..11a03cd4 --- /dev/null +++ b/game-engine/src/test/kotlin/org/luxons/sevenwonders/game/resources/ResourceTransactionsTest.kt @@ -0,0 +1,36 @@ +package org.luxons.sevenwonders.game.resources + +import java.util.ArrayList +import java.util.HashSet + +import org.junit.Test +import org.luxons.sevenwonders.game.test.* + +import org.junit.Assert.assertEquals + +class ResourceTransactionsTest { + + @Test + fun toTransactions() { + val transactionList = ArrayList<ResourceTransaction>() + transactionList.add(createTransaction(Provider.LEFT_PLAYER, ResourceType.WOOD)) + transactionList.add(createTransaction(Provider.LEFT_PLAYER, ResourceType.CLAY)) + transactionList.add(createTransaction(Provider.RIGHT_PLAYER, ResourceType.WOOD)) + + val transactions = ResourceTransactions(transactionList) + + val expectedNormalized = HashSet<ResourceTransaction>() + expectedNormalized.add( + createTransaction(Provider.LEFT_PLAYER, ResourceType.WOOD, ResourceType.CLAY) + ) + expectedNormalized.add(createTransaction(Provider.RIGHT_PLAYER, ResourceType.WOOD)) + + assertEquals(expectedNormalized, HashSet(transactions.toTransactions())) + } + + @Test(expected = IllegalStateException::class) + fun remove_failsIfNoResourceForThatProvider() { + val transactions = ResourceTransactions() + transactions.remove(Provider.LEFT_PLAYER, Resources.of(ResourceType.WOOD)) + } +} diff --git a/game-engine/src/test/kotlin/org/luxons/sevenwonders/game/resources/ResourcesTest.kt b/game-engine/src/test/kotlin/org/luxons/sevenwonders/game/resources/ResourcesTest.kt new file mode 100644 index 00000000..72419fe3 --- /dev/null +++ b/game-engine/src/test/kotlin/org/luxons/sevenwonders/game/resources/ResourcesTest.kt @@ -0,0 +1,482 @@ +package org.luxons.sevenwonders.game.resources + +import org.junit.Assert.* +import org.junit.Rule +import org.junit.Test +import org.junit.rules.ExpectedException +import java.util.NoSuchElementException + +class ResourcesTest { + + @JvmField + @Rule + var thrown = ExpectedException.none() + + @Test + fun init_shouldBeEmpty() { + val resources = Resources() + for (resourceType in ResourceType.values()) { + assertEquals(0, resources.getQuantity(resourceType).toLong()) + } + assertEquals(0, resources.size().toLong()) + assertTrue(resources.isEmpty) + } + + @Test + fun add_zero() { + val resources = Resources() + resources.add(ResourceType.CLAY, 0) + assertEquals(0, resources.getQuantity(ResourceType.CLAY).toLong()) + assertEquals(0, resources.size().toLong()) + assertTrue(resources.isEmpty) + } + + @Test + fun add_simple() { + val resources = Resources() + resources.add(ResourceType.WOOD, 3) + assertEquals(3, resources.getQuantity(ResourceType.WOOD).toLong()) + assertEquals(3, resources.size().toLong()) + assertFalse(resources.isEmpty) + } + + @Test + fun add_multipleCallsStacked() { + val resources = Resources() + resources.add(ResourceType.ORE, 3) + resources.add(ResourceType.ORE, 2) + assertEquals(5, resources.getQuantity(ResourceType.ORE).toLong()) + assertEquals(5, resources.size().toLong()) + assertFalse(resources.isEmpty) + } + + @Test + fun add_interlaced() { + val resources = 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).toLong()) + assertEquals(10, resources.size().toLong()) + assertFalse(resources.isEmpty) + } + + @Test + fun remove_some() { + val resources = Resources() + resources.add(ResourceType.WOOD, 3) + resources.remove(ResourceType.WOOD, 2) + assertEquals(1, resources.getQuantity(ResourceType.WOOD).toLong()) + assertEquals(1, resources.size().toLong()) + assertFalse(resources.isEmpty) + } + + @Test + fun remove_all() { + val resources = Resources() + resources.add(ResourceType.WOOD, 3) + resources.remove(ResourceType.WOOD, 3) + assertEquals(0, resources.getQuantity(ResourceType.WOOD).toLong()) + assertEquals(0, resources.size().toLong()) + assertTrue(resources.isEmpty) + } + + @Test + fun remove_tooMany() { + val resources = Resources() + resources.add(ResourceType.WOOD, 2) + + thrown.expect(NoSuchElementException::class.java) + resources.remove(ResourceType.WOOD, 3) + } + + @Test + fun addAll_empty() { + val resources = Resources() + resources.add(ResourceType.STONE, 1) + resources.add(ResourceType.CLAY, 3) + + val emptyResources = Resources() + + resources.addAll(emptyResources) + assertEquals(1, resources.getQuantity(ResourceType.STONE).toLong()) + assertEquals(3, resources.getQuantity(ResourceType.CLAY).toLong()) + assertEquals(0, resources.getQuantity(ResourceType.ORE).toLong()) + assertEquals(0, resources.getQuantity(ResourceType.GLASS).toLong()) + assertEquals(0, resources.getQuantity(ResourceType.LOOM).toLong()) + assertEquals(4, resources.size().toLong()) + assertFalse(resources.isEmpty) + } + + @Test + fun addAll_zeros() { + val resources = Resources() + resources.add(ResourceType.STONE, 1) + resources.add(ResourceType.CLAY, 3) + + val emptyResources = Resources() + emptyResources.add(ResourceType.STONE, 0) + emptyResources.add(ResourceType.CLAY, 0) + + resources.addAll(emptyResources) + assertEquals(1, resources.getQuantity(ResourceType.STONE).toLong()) + assertEquals(3, resources.getQuantity(ResourceType.CLAY).toLong()) + assertEquals(0, resources.getQuantity(ResourceType.ORE).toLong()) + assertEquals(0, resources.getQuantity(ResourceType.GLASS).toLong()) + assertEquals(0, resources.getQuantity(ResourceType.LOOM).toLong()) + assertEquals(4, resources.size().toLong()) + assertFalse(resources.isEmpty) + } + + @Test + fun addAll_same() { + val resources = Resources() + resources.add(ResourceType.STONE, 1) + resources.add(ResourceType.CLAY, 3) + + val resources2 = Resources() + resources.add(ResourceType.STONE, 2) + resources.add(ResourceType.CLAY, 6) + + resources.addAll(resources2) + assertEquals(3, resources.getQuantity(ResourceType.STONE).toLong()) + assertEquals(9, resources.getQuantity(ResourceType.CLAY).toLong()) + assertEquals(0, resources.getQuantity(ResourceType.ORE).toLong()) + assertEquals(0, resources.getQuantity(ResourceType.GLASS).toLong()) + assertEquals(0, resources.getQuantity(ResourceType.LOOM).toLong()) + assertEquals(12, resources.size().toLong()) + assertFalse(resources.isEmpty) + } + + @Test + fun addAll_overlap() { + val resources = Resources() + resources.add(ResourceType.STONE, 1) + resources.add(ResourceType.CLAY, 3) + + val resources2 = Resources() + resources.add(ResourceType.CLAY, 6) + resources.add(ResourceType.ORE, 4) + + resources.addAll(resources2) + assertEquals(1, resources.getQuantity(ResourceType.STONE).toLong()) + assertEquals(9, resources.getQuantity(ResourceType.CLAY).toLong()) + assertEquals(4, resources.getQuantity(ResourceType.ORE).toLong()) + assertEquals(0, resources.getQuantity(ResourceType.GLASS).toLong()) + assertEquals(0, resources.getQuantity(ResourceType.LOOM).toLong()) + assertEquals(14, resources.size().toLong()) + assertFalse(resources.isEmpty) + } + + @Test + fun contains_emptyContainsEmpty() { + val emptyResources = Resources() + val emptyResources2 = Resources() + assertTrue(emptyResources.contains(emptyResources2)) + } + + @Test + fun contains_singleTypeContainsEmpty() { + val resources = Resources() + resources.add(ResourceType.STONE, 1) + + val emptyResources = Resources() + + assertTrue(resources.contains(emptyResources)) + } + + @Test + fun contains_multipleTypesContainsEmpty() { + val resources = Resources() + resources.add(ResourceType.STONE, 1) + resources.add(ResourceType.CLAY, 3) + + val emptyResources = Resources() + + assertTrue(resources.contains(emptyResources)) + } + + @Test + fun contains_self() { + val resources = Resources() + resources.add(ResourceType.STONE, 1) + resources.add(ResourceType.CLAY, 3) + + assertTrue(resources.contains(resources)) + } + + @Test + fun contains_allOfEachType() { + val resources = Resources() + resources.add(ResourceType.STONE, 1) + resources.add(ResourceType.CLAY, 3) + + val resources2 = Resources() + resources2.add(ResourceType.STONE, 1) + resources2.add(ResourceType.CLAY, 3) + + assertTrue(resources.contains(resources2)) + } + + @Test + fun contains_someOfEachType() { + val resources = Resources() + resources.add(ResourceType.STONE, 2) + resources.add(ResourceType.CLAY, 4) + + val resources2 = Resources() + resources2.add(ResourceType.STONE, 1) + resources2.add(ResourceType.CLAY, 3) + + assertTrue(resources.contains(resources2)) + } + + @Test + fun contains_someOfSomeTypes() { + val resources = Resources() + resources.add(ResourceType.STONE, 2) + resources.add(ResourceType.CLAY, 4) + + val resources2 = Resources() + resources2.add(ResourceType.CLAY, 3) + + assertTrue(resources.contains(resources2)) + } + + @Test + fun contains_allOfSomeTypes() { + val resources = Resources() + resources.add(ResourceType.STONE, 2) + resources.add(ResourceType.CLAY, 4) + + val resources2 = Resources() + resources2.add(ResourceType.CLAY, 4) + + assertTrue(resources.contains(resources2)) + } + + @Test + fun minus_empty() { + val resources = Resources() + resources.add(ResourceType.STONE, 1) + resources.add(ResourceType.CLAY, 3) + + val emptyResources = Resources() + + val diff = resources.minus(emptyResources) + assertEquals(1, diff.getQuantity(ResourceType.STONE).toLong()) + assertEquals(3, diff.getQuantity(ResourceType.CLAY).toLong()) + assertEquals(0, diff.getQuantity(ResourceType.ORE).toLong()) + assertEquals(0, diff.getQuantity(ResourceType.GLASS).toLong()) + assertEquals(0, diff.getQuantity(ResourceType.LOOM).toLong()) + } + + @Test + fun minus_self() { + val resources = Resources() + resources.add(ResourceType.STONE, 1) + resources.add(ResourceType.CLAY, 3) + + val diff = resources.minus(resources) + assertEquals(0, diff.getQuantity(ResourceType.STONE).toLong()) + assertEquals(0, diff.getQuantity(ResourceType.CLAY).toLong()) + assertEquals(0, diff.getQuantity(ResourceType.ORE).toLong()) + assertEquals(0, diff.getQuantity(ResourceType.GLASS).toLong()) + assertEquals(0, diff.getQuantity(ResourceType.LOOM).toLong()) + } + + @Test + fun minus_allOfEachType() { + val resources = Resources() + resources.add(ResourceType.STONE, 1) + resources.add(ResourceType.CLAY, 3) + + val resources2 = Resources() + resources2.add(ResourceType.STONE, 1) + resources2.add(ResourceType.CLAY, 3) + + val diff = resources.minus(resources2) + assertEquals(0, diff.getQuantity(ResourceType.STONE).toLong()) + assertEquals(0, diff.getQuantity(ResourceType.CLAY).toLong()) + assertEquals(0, diff.getQuantity(ResourceType.ORE).toLong()) + assertEquals(0, diff.getQuantity(ResourceType.GLASS).toLong()) + assertEquals(0, diff.getQuantity(ResourceType.LOOM).toLong()) + } + + @Test + fun minus_someOfEachType() { + val resources = Resources() + resources.add(ResourceType.STONE, 2) + resources.add(ResourceType.CLAY, 4) + + val resources2 = Resources() + resources2.add(ResourceType.STONE, 1) + resources2.add(ResourceType.CLAY, 3) + + val diff = resources.minus(resources2) + assertEquals(1, diff.getQuantity(ResourceType.STONE).toLong()) + assertEquals(1, diff.getQuantity(ResourceType.CLAY).toLong()) + assertEquals(0, diff.getQuantity(ResourceType.ORE).toLong()) + assertEquals(0, diff.getQuantity(ResourceType.GLASS).toLong()) + assertEquals(0, diff.getQuantity(ResourceType.LOOM).toLong()) + } + + @Test + fun minus_someOfSomeTypes() { + val resources = Resources() + resources.add(ResourceType.STONE, 2) + resources.add(ResourceType.CLAY, 4) + + val resources2 = Resources() + resources2.add(ResourceType.CLAY, 3) + + val diff = resources.minus(resources2) + assertEquals(2, diff.getQuantity(ResourceType.STONE).toLong()) + assertEquals(1, diff.getQuantity(ResourceType.CLAY).toLong()) + assertEquals(0, diff.getQuantity(ResourceType.ORE).toLong()) + assertEquals(0, diff.getQuantity(ResourceType.GLASS).toLong()) + assertEquals(0, diff.getQuantity(ResourceType.LOOM).toLong()) + } + + @Test + fun minus_allOfSomeTypes() { + val resources = Resources() + resources.add(ResourceType.STONE, 2) + resources.add(ResourceType.CLAY, 4) + + val resources2 = Resources() + resources2.add(ResourceType.CLAY, 4) + + val diff = resources.minus(resources2) + assertEquals(2, diff.getQuantity(ResourceType.STONE).toLong()) + assertEquals(0, diff.getQuantity(ResourceType.CLAY).toLong()) + assertEquals(0, diff.getQuantity(ResourceType.ORE).toLong()) + assertEquals(0, diff.getQuantity(ResourceType.GLASS).toLong()) + assertEquals(0, diff.getQuantity(ResourceType.LOOM).toLong()) + } + + @Test + fun minus_tooMuchOfExistingType() { + val resources = Resources() + resources.add(ResourceType.CLAY, 4) + + val resources2 = Resources() + resources2.add(ResourceType.CLAY, 5) + + val diff = resources.minus(resources2) + assertEquals(0, diff.getQuantity(ResourceType.CLAY).toLong()) + } + + @Test + fun minus_someOfAnAbsentType() { + val resources = Resources() + + val resources2 = Resources() + resources2.add(ResourceType.LOOM, 5) + + val diff = resources.minus(resources2) + assertEquals(0, diff.getQuantity(ResourceType.LOOM).toLong()) + } + + @Test + fun minus_someOfATypeWithZero() { + val resources = Resources() + resources.add(ResourceType.LOOM, 0) + + val resources2 = Resources() + resources2.add(ResourceType.LOOM, 5) + + val diff = resources.minus(resources2) + assertEquals(0, diff.getQuantity(ResourceType.LOOM).toLong()) + } + + @Test + fun isEmpty_noElement() { + val resources = Resources() + assertTrue(resources.isEmpty) + } + + @Test + fun isEmpty_singleZeroElement() { + val resources = Resources() + resources.add(ResourceType.LOOM, 0) + assertTrue(resources.isEmpty) + } + + @Test + fun isEmpty_multipleZeroElements() { + val resources = Resources() + resources.add(ResourceType.WOOD, 0) + resources.add(ResourceType.ORE, 0) + resources.add(ResourceType.LOOM, 0) + assertTrue(resources.isEmpty) + } + + @Test + fun isEmpty_singleElementMoreThanZero() { + val resources = Resources() + resources.add(ResourceType.LOOM, 3) + assertFalse(resources.isEmpty) + } + + @Test + fun isEmpty_mixedZeroAndNonZeroElements() { + val resources = Resources() + resources.add(ResourceType.WOOD, 0) + resources.add(ResourceType.LOOM, 3) + assertFalse(resources.isEmpty) + } + + @Test + fun isEmpty_mixedZeroAndNonZeroElements_reverseOrder() { + val resources = Resources() + resources.add(ResourceType.ORE, 3) + resources.add(ResourceType.PAPYRUS, 0) + assertFalse(resources.isEmpty) + } + + @Test + fun equals_falseWhenNull() { + val resources = Resources() + resources.add(ResourceType.GLASS, 1) + + assertFalse(resources == null) + } + + @Test + fun equals_falseWhenDifferentClass() { + val resources = Resources() + resources.add(ResourceType.GLASS, 1) + val production = Production() + production.addFixedResource(ResourceType.GLASS, 1) + + assertFalse(resources == production) + } + + @Test + fun equals_trueWhenSame() { + val resources = Resources() + assertEquals(resources, resources) + } + + @Test + fun equals_trueWhenSameContent() { + val resources1 = Resources() + val resources2 = Resources() + assertTrue(resources1 == resources2) + resources1.add(ResourceType.GLASS, 1) + resources2.add(ResourceType.GLASS, 1) + assertTrue(resources1 == resources2) + } + + @Test + fun hashCode_sameWhenSameContent() { + val resources1 = Resources() + val resources2 = Resources() + assertEquals(resources1.hashCode().toLong(), resources2.hashCode().toLong()) + resources1.add(ResourceType.GLASS, 1) + resources2.add(ResourceType.GLASS, 1) + assertEquals(resources1.hashCode().toLong(), resources2.hashCode().toLong()) + } +} diff --git a/game-engine/src/test/kotlin/org/luxons/sevenwonders/game/resources/TradingRulesTest.kt b/game-engine/src/test/kotlin/org/luxons/sevenwonders/game/resources/TradingRulesTest.kt new file mode 100644 index 00000000..859c997a --- /dev/null +++ b/game-engine/src/test/kotlin/org/luxons/sevenwonders/game/resources/TradingRulesTest.kt @@ -0,0 +1,127 @@ +package org.luxons.sevenwonders.game.resources + +import java.util.ArrayList + +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.* + +import org.junit.Assert.assertEquals +import org.junit.Assume.assumeTrue + +@RunWith(Theories::class) +class TradingRulesTest { + + @Theory + fun setCost_overridesCost( + defaultCost: Int, overriddenCost: Int, overriddenProvider: Provider, + provider: Provider, type: ResourceType + ) { + assumeTrue(defaultCost != overriddenCost) + assumeTrue(overriddenProvider != provider) + + val rules = TradingRules(defaultCost) + rules.setCost(type, overriddenProvider, overriddenCost) + + assertEquals(overriddenCost.toLong(), rules.getCost(type, overriddenProvider).toLong()) + assertEquals(defaultCost.toLong(), rules.getCost(type, provider).toLong()) + } + + @Theory + fun computeCost_zeroForNoResources(defaultCost: Int) { + val rules = TradingRules(defaultCost) + assertEquals(0, rules.computeCost(ResourceTransactions()).toLong()) + } + + @Theory + fun computeCost_defaultCostWhenNoOverride(defaultCost: Int, provider: Provider, type: ResourceType) { + val rules = TradingRules(defaultCost) + val transactions = createTransactions(provider, type) + assertEquals(defaultCost.toLong(), rules.computeCost(transactions).toLong()) + } + + @Theory + fun computeCost_twiceDefaultFor2Resources(defaultCost: Int, provider: Provider, type: ResourceType) { + val rules = TradingRules(defaultCost) + val transactions = createTransactions(provider, type, type) + assertEquals((2 * defaultCost).toLong(), rules.computeCost(transactions).toLong()) + } + + @Theory + fun computeCost_overriddenCost(defaultCost: Int, overriddenCost: Int, provider: Provider, type: ResourceType) { + val rules = TradingRules(defaultCost) + rules.setCost(type, provider, overriddenCost) + val transactions = createTransactions(provider, type) + assertEquals(overriddenCost.toLong(), rules.computeCost(transactions).toLong()) + } + + @Theory + fun computeCost_defaultCostWhenOverrideOnOtherProviderOrType( + defaultCost: Int, overriddenCost: Int, + overriddenProvider: Provider, + overriddenType: ResourceType, provider: Provider, + type: ResourceType + ) { + assumeTrue(overriddenProvider != provider || overriddenType != type) + val rules = TradingRules(defaultCost) + rules.setCost(overriddenType, overriddenProvider, overriddenCost) + val transactions = createTransactions(provider, type) + assertEquals(defaultCost.toLong(), rules.computeCost(transactions).toLong()) + } + + @Theory + fun computeCost_oneDefaultAndOneOverriddenType( + defaultCost: Int, overriddenCost: Int, + overriddenType: ResourceType, provider: Provider, + type: ResourceType + ) { + assumeTrue(overriddenType != type) + val rules = TradingRules(defaultCost) + rules.setCost(overriddenType, provider, overriddenCost) + val transactions = createTransactions(provider, overriddenType, type) + assertEquals((defaultCost + overriddenCost).toLong(), rules.computeCost(transactions).toLong()) + } + + @Theory + fun computeCost_oneDefaultAndOneOverriddenProvider( + defaultCost: Int, overriddenCost: Int, + overriddenProvider: Provider, provider: Provider, + type: ResourceType + ) { + assumeTrue(overriddenProvider != provider) + val rules = TradingRules(defaultCost) + rules.setCost(type, overriddenProvider, overriddenCost) + + val boughtResources = ArrayList<ResourceTransaction>(2) + boughtResources.add(createTransaction(provider, type)) + boughtResources.add(createTransaction(overriddenProvider, type)) + + assertEquals( + (defaultCost + overriddenCost).toLong(), + rules.computeCost(ResourceTransactions(boughtResources)).toLong() + ) + } + + companion object { + + @JvmStatic + @DataPoints + fun costs(): IntArray { + return intArrayOf(0, 1, 2) + } + + @JvmStatic + @DataPoints + fun providers(): Array<Provider> { + return Provider.values() + } + + @JvmStatic + @DataPoints + fun resourceTypes(): Array<ResourceType> { + return ResourceType.values() + } + } +} |