Created
November 5, 2019 03:41
-
-
Save saantiaguilera/bd0241a9a4cfd97842f4682abbaa61ac to your computer and use it in GitHub Desktop.
Tennis BrownBag
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.mercadolibre.dojo | |
import org.junit.Assert | |
import org.junit.Before | |
import org.junit.Test | |
class IntegrationTests { | |
lateinit var player1: Player | |
lateinit var player2: Player | |
@Before | |
fun setup() { | |
val (player1, player2) = createPlayers("fulana", "fulano") | |
this.player1 = player1 | |
this.player2 = player2 | |
} | |
fun provideGamePoint(name: String) = Game(name) | |
fun provideFourtyPoint(game: Game) = Fourty(game) | |
fun provideAdvantagePoint(name: String, game: Game) = Advantage(name, game) | |
fun provideDeucePoint(advantage: Advantage, oponentAdvantage: Advantage) = Deuce(advantage, oponentAdvantage) | |
fun provideThirtyPoint(fourty: Fourty, deuceProvider: DeuceProvider) = Thirty(fourty, deuceProvider) | |
fun provideFifteenPoint(thirty: Thirty) = Fifteen(thirty) | |
fun provideZero(fifteen: Fifteen) = Zero(fifteen) | |
private fun createPlayers(name1: String, name2: String): Pair<Player, Player> { | |
val scoreGame1 = provideGamePoint(name1) | |
val scoreFourty1 = provideFourtyPoint(scoreGame1) | |
val scoreAdvantage1 = provideAdvantagePoint(name1, scoreGame1) | |
val scoreGame2 = provideGamePoint(name2) | |
val scoreFourty2 = provideFourtyPoint(scoreGame2) | |
val scoreAdvantage2 = provideAdvantagePoint(name2, scoreGame2) | |
val scoreDeuce1 = provideDeucePoint(scoreAdvantage1, scoreAdvantage2) | |
val scoreDeuce2 = provideDeucePoint(scoreAdvantage2, scoreAdvantage1) | |
val scoreThirty1 = provideThirtyPoint(scoreFourty1) { | |
Pair(scoreDeuce1, scoreDeuce2) | |
} | |
val scoreThirty2 = provideThirtyPoint(scoreFourty2) { | |
Pair(scoreDeuce2, scoreDeuce1) | |
} | |
val scoreFifteen1 = provideFifteenPoint(scoreThirty1) | |
val scoreFifteen2 = provideFifteenPoint(scoreThirty2) | |
val scoreZero1 = provideZero(scoreFifteen1) | |
val scoreZero2 = provideZero(scoreFifteen2) | |
return Pair(Player(scoreZero1), Player(scoreZero2)) | |
} | |
fun getMessageWhen(player1: Player, | |
player2: Player, | |
numberOfScoresPlayer1: Int, | |
numberOfScoresPlayer2: Int): String { | |
repeat(numberOfScoresPlayer1) { | |
player1 scoreAgainst player2 | |
} | |
repeat(numberOfScoresPlayer2) { | |
player2 scoreAgainst player1 | |
} | |
return Logger(player1, player2).getCurrentScore() | |
} | |
@Test | |
fun `test game start`() { | |
Assert.assertEquals("Game Start", getMessageWhen(player1, player2, 0, 0)) | |
} | |
@Test | |
fun `test game 0 - 15`() { | |
Assert.assertEquals("0 - 15", getMessageWhen(player1, player2, 0, 1)) | |
} | |
@Test | |
fun `test game 15 - 0`() { | |
Assert.assertEquals("15 - 0", getMessageWhen(player1, player2, 1, 0)) | |
} | |
@Test | |
fun `test game 30 - 0`() { | |
Assert.assertEquals("30 - 0", getMessageWhen(player1, player2, 2, 0)) | |
} | |
@Test | |
fun `test game 0 - 30`() { | |
Assert.assertEquals("0 - 30", getMessageWhen(player1, player2, 0, 2)) | |
} | |
@Test | |
fun `test game 40 - 0`() { | |
Assert.assertEquals("40 - 0", getMessageWhen(player1, player2, 3, 0)) | |
} | |
@Test | |
fun `test game 0 - 40`() { | |
Assert.assertEquals("0 - 40", getMessageWhen(player1, player2, 0, 3)) | |
} | |
@Test | |
fun `test game wins player 1`() { | |
Assert.assertEquals("Game fulano", getMessageWhen(player1, player2, 0, 4)) | |
} | |
@Test | |
fun `test game wins player 2`() { | |
Assert.assertEquals("Game fulana", getMessageWhen(player1, player2, 4, 0)) | |
} | |
@Test | |
fun `test game 15 - 30`() { | |
Assert.assertEquals("15 - 30", getMessageWhen(player1, player2, 1, 2)) | |
} | |
@Test | |
fun `test game 30 - 15`() { | |
Assert.assertEquals("30 - 15", getMessageWhen(player1, player2, 2, 1)) | |
} | |
@Test | |
fun `test game 40 - 15`() { | |
Assert.assertEquals("40 - 15", getMessageWhen(player1, player2, 3, 1)) | |
} | |
@Test | |
fun `test game 15 - 40`() { | |
Assert.assertEquals("15 - 40", getMessageWhen(player1, player2, 1, 3)) | |
} | |
@Test | |
fun `test game 40 - 30`() { | |
Assert.assertEquals("40 - 30", getMessageWhen(player1, player2, 3, 2)) | |
} | |
@Test | |
fun `test game 30 - 40`() { | |
Assert.assertEquals("30 - 40", getMessageWhen(player1, player2, 2, 3)) | |
} | |
@Test | |
fun `test game 40 - 40 deuce`() { | |
Assert.assertEquals("Deuce", getMessageWhen(player1, player2, 3, 3)) | |
} | |
@Test | |
fun `test game advantage player 1`() { | |
val (player1, player2) = createPlayers("fulano", "fulana") | |
player1 scoreAgainst player2 | |
player1 scoreAgainst player2 | |
player1 scoreAgainst player2 | |
player2 scoreAgainst player1 | |
player2 scoreAgainst player1 | |
player2 scoreAgainst player1 | |
player1 scoreAgainst player2 | |
Assert.assertEquals("Advantage fulano", Logger(player1, player2).getCurrentScore()) | |
} | |
@Test | |
fun `test game advantage player 2`() { | |
val (player1, player2) = createPlayers("fulano", "fulana") | |
player1 scoreAgainst player2 | |
player1 scoreAgainst player2 | |
player1 scoreAgainst player2 | |
player2 scoreAgainst player1 | |
player2 scoreAgainst player1 | |
player2 scoreAgainst player1 | |
player2 scoreAgainst player1 | |
Assert.assertEquals("Advantage fulana", Logger(player1, player2).getCurrentScore()) | |
} | |
@Test | |
fun `test game wins player 1 after advantage`() { | |
val (player1, player2) = createPlayers("fulano", "fulana") | |
player1 scoreAgainst player2 | |
player1 scoreAgainst player2 | |
player1 scoreAgainst player2 | |
player2 scoreAgainst player1 | |
player2 scoreAgainst player1 | |
player2 scoreAgainst player1 | |
player1 scoreAgainst player2 | |
player1 scoreAgainst player2 | |
Assert.assertEquals("Game fulano", Logger(player1, player2).getCurrentScore()) | |
} | |
@Test | |
fun `test game wins player 2 after advantage`() { | |
val (player1, player2) = createPlayers("fulano", "fulana") | |
player1 scoreAgainst player2 | |
player1 scoreAgainst player2 | |
player1 scoreAgainst player2 | |
player2 scoreAgainst player1 | |
player2 scoreAgainst player1 | |
player2 scoreAgainst player1 | |
player2 scoreAgainst player1 | |
player2 scoreAgainst player1 | |
Assert.assertEquals("Game fulana", Logger(player1, player2).getCurrentScore()) | |
} | |
@Test | |
fun `test game deuce after advantage`() { | |
val (player1, player2) = createPlayers("fulano", "fulana") | |
player1 scoreAgainst player2 | |
player1 scoreAgainst player2 | |
player1 scoreAgainst player2 | |
player2 scoreAgainst player1 | |
player2 scoreAgainst player1 | |
player2 scoreAgainst player1 | |
player2 scoreAgainst player1 | |
player1 scoreAgainst player2 | |
Assert.assertEquals("Deuce", Logger(player1, player2).getCurrentScore()) | |
} | |
@Test | |
fun `test game advantage player 1 after deuce`() { | |
val (player1, player2) = createPlayers("fulano", "fulana") | |
player1 scoreAgainst player2 | |
player1 scoreAgainst player2 | |
player1 scoreAgainst player2 | |
player2 scoreAgainst player1 | |
player2 scoreAgainst player1 | |
player2 scoreAgainst player1 | |
player2 scoreAgainst player1 | |
player1 scoreAgainst player2 | |
player1 scoreAgainst player2 | |
Assert.assertEquals("Advantage fulano", Logger(player1, player2).getCurrentScore()) | |
} | |
@Test | |
fun `test game advantage player 2 after deuce`() { | |
val (player1, player2) = createPlayers("fulano", "fulana") | |
player1 scoreAgainst player2 | |
player1 scoreAgainst player2 | |
player1 scoreAgainst player2 | |
player2 scoreAgainst player1 | |
player2 scoreAgainst player1 | |
player2 scoreAgainst player1 | |
player2 scoreAgainst player1 | |
player1 scoreAgainst player2 | |
player2 scoreAgainst player1 | |
Assert.assertEquals("Advantage fulana", Logger(player1, player2).getCurrentScore()) | |
} | |
@Test | |
fun `test game wins player 1 after advantage and deuce`() { | |
val (player1, player2) = createPlayers("fulano", "fulana") | |
player1 scoreAgainst player2 | |
player1 scoreAgainst player2 | |
player1 scoreAgainst player2 | |
player2 scoreAgainst player1 | |
player2 scoreAgainst player1 | |
player2 scoreAgainst player1 | |
player2 scoreAgainst player1 | |
player1 scoreAgainst player2 | |
player1 scoreAgainst player2 | |
player1 scoreAgainst player2 | |
Assert.assertEquals("Game fulano", Logger(player1, player2).getCurrentScore()) | |
} | |
@Test | |
fun `test game wins player 2 after advantage and deuce`() { | |
val (player1, player2) = createPlayers("fulano", "fulana") | |
player1 scoreAgainst player2 | |
player1 scoreAgainst player2 | |
player1 scoreAgainst player2 | |
player2 scoreAgainst player1 | |
player2 scoreAgainst player1 | |
player2 scoreAgainst player1 | |
player2 scoreAgainst player1 | |
player1 scoreAgainst player2 | |
player2 scoreAgainst player1 | |
player2 scoreAgainst player1 | |
Assert.assertEquals("Game fulana", Logger(player1, player2).getCurrentScore()) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.mercadolibre.dojo | |
interface Scorer<S : Scorer<S>> { | |
var score: Score | |
infix fun scoreAgainst(scorer: S) | |
} | |
class Player(initialScore: Score) : Scorer<Player> { | |
override var score: Score = initialScore | |
override infix fun scoreAgainst(scorer: Player) { | |
val (score1, score2) = score.nextPoint(scorer.score) | |
score = score1 | |
scorer.score = score2 | |
} | |
} | |
class Logger<S: Scorer<S>>(private val scorer1: S, | |
private val scorer2: S) { | |
fun getCurrentScore(): String { | |
return scorer1.score.asMessage(scorer2.score) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.mercadolibre.dojo | |
interface Score { | |
fun nextPoint(otherPoint: Score): Pair<Score, Score> | |
fun asMessage(otherPoint: Score): String { | |
return "${toString()} - $otherPoint" | |
} | |
} | |
typealias DeuceProvider = () -> Pair<Deuce, Deuce> | |
data class Zero(val nextPoint: Score) : Score { | |
override fun nextPoint(otherPoint: Score) = Pair(nextPoint, otherPoint) | |
override fun toString() = "0" | |
override fun asMessage(otherPoint: Score): String { | |
if (otherPoint is Zero) { | |
return "Game Start" | |
} | |
return super.asMessage(otherPoint) | |
} | |
} | |
data class Fifteen(val nextPoint: Score) : Score { | |
override fun nextPoint(otherPoint: Score) = Pair(nextPoint, otherPoint) | |
override fun toString() = "15" | |
} | |
data class Thirty(val fourtyPoint: Score, | |
val deuceProvider: DeuceProvider) : Score { | |
override fun nextPoint(otherPoint: Score): Pair<Score, Score> { | |
if (otherPoint::class == fourtyPoint::class) { | |
return deuceProvider() | |
} | |
return Pair(fourtyPoint, otherPoint) | |
} | |
override fun toString() = "30" | |
} | |
data class Fourty(val gamePoint: Score) : Score { | |
override fun toString() = "40" | |
override fun nextPoint(otherPoint: Score): Pair<Score, Score> { | |
return Pair(gamePoint, gamePoint) | |
} | |
} | |
data class Advantage(val name: String, | |
val gamePoint: Score) : Score { | |
override fun asMessage(otherPoint: Score) = "Advantage $name" | |
override fun nextPoint(otherPoint: Score): Pair<Score, Score> { | |
return Pair(gamePoint, gamePoint) | |
} | |
} | |
data class Deuce(val advantagePoint: Score, | |
val oponentAdvantagePoint: Score) : Score { | |
override fun asMessage(otherPoint: Score): String { | |
if (otherPoint is Deuce) { | |
return "Deuce" | |
} | |
return otherPoint.asMessage(this) // Probably he's an advantage. Double-dispatch us | |
} | |
override fun nextPoint(otherPoint: Score): Pair<Score, Score> { | |
if (otherPoint::class == advantagePoint::class) { | |
// Create a deuce for the oponent with inverted values for advantages! | |
return Pair(this, Deuce(oponentAdvantagePoint, advantagePoint)) | |
} | |
return Pair(advantagePoint, otherPoint) | |
} | |
} | |
data class Game(val winner: String) : Score { | |
override fun asMessage(otherPoint: Score) = "Game $winner" | |
override fun nextPoint(otherPoint: Score): Pair<Score, Score> { | |
throw IllegalStateException("Game has already ended.") | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment