wordify-0.7.0.0: test/Tests/Internationalisation/SpanishExtraRuleTest.hs
module Tests.Internationalisation.SpanishExtraRuleTest where
import qualified System.FilePath as F
import Wordify.Rules.WordifyError (WordifyError)
import Wordify.Rules.Dictionary (Dictionary, makeDictionary)
import Wordify.Rules.LetterBag (LetterBag, bagFromTiles)
import Wordify.Rules.Tile (Tile(..))
import Wordify.Rules.Game (Game, makeGame)
import Wordify.Rules.Player (makePlayer)
import Test.HUnit (Assertion, assertBool, assertEqual, Assertable)
import Test.HUnit.Base (assertFailure)
import Wordify.Rules.Move (GameTransition(..), Move (..), makeMove, newGame)
import qualified Data.Map as M
import Wordify.Rules.Pos (rightPositions, starPos, abovePositions, right, belowPositions, above, below)
import Wordify.Rules.Extra.SpanishExtraRule (spanishGameExtraRules)
import Wordify.Rules.Extra.ExtraRule (applyExtraRules, RuleExecutionError (..))
import Control.Error (isLeft)
import Control.Error.Util (isRight)
import Data.Either (fromRight)
import Wordify.Rules.Extra.ExtraRule (RuleApplicationResult(..), RuleApplicationsResult(..))
import Data.Maybe (fromJust)
import qualified Control.Arrow as A
testSpanishDictionary :: IO (Either WordifyError Dictionary)
testSpanishDictionary = makeDictionary $ "Config" ++ [F.pathSeparator] ++ "spanishSet" ++ [F.pathSeparator] ++ "dictionary.txt"
testSpanishLetterBag :: IO LetterBag
testSpanishLetterBag = bagFromTiles tiles
where
tiles = [Letter "CH" 5, Letter "U" 1,Letter "C" 3,Letter "U" 1,Letter "H" 4,Letter "A" 1,Letter "A" 1,Letter "E" 1,Letter "D" 2,
Letter "C" 3,Letter "E" 1,Letter "I" 1,Letter "A" 1,Letter "E" 1,Letter "C" 3,Letter "N" 1,
Letter "E" 1,Letter "A" 1,Letter "D" 2,Letter "D" 2,Letter "RR" 8,Letter "D" 2,Letter "N" 1,
Letter "P" 3,Letter "T" 1,Letter "O" 1,Letter "A" 1,Letter "S" 1,Letter "D" 2,Letter "S" 1,
Letter "E" 1,Letter "R" 1,Letter "I" 1,Letter "I" 1,Letter "A" 1,Letter "N" 1,Letter "A" 1,
Letter "T" 1,Letter "Ñ" 8,Letter "E" 1,Letter "S" 1,Letter "O" 1,Letter "T" 1,Letter "L" 1,
Letter "O" 1,Letter "LL" 8,Letter "I" 1,Letter "N" 1,Letter "S" 1,Letter "P" 3,Letter "E" 1,
Letter "B" 3,Letter "B" 3,Letter "E" 1,Letter "A" 1,Letter "A" 1,Letter "C" 3,Letter "Z" 10,Letter "E" 1,
Letter "U" 1,Letter "E" 1,Letter "E" 1,Letter "R" 1,Letter "M" 3,Letter "O" 1,Letter "L" 1,Letter "U" 1,
Letter "R" 1,Letter "S" 1,Letter "A" 1,Letter "I" 1,Letter "I" 1,
Letter "L" 1,Letter "G" 2,Letter "O" 1,Letter "A" 1,Letter "R" 1,Letter "T" 1,Letter "J" 8,
Letter "O" 1,Letter "F" 4,Blank Nothing,Letter "Y" 4,Letter "N" 1,Letter "L" 1,Letter "O" 1,
Letter "X" 8,Letter "E" 1,Letter "O" 1,Letter "R" 1,Letter "M" 3,Letter "S" 1,Letter "G" 2,Letter "U" 1,
Letter "H" 4,Letter "V" 4,Letter "A" 1,Letter "Q" 5,Letter "O" 1,Blank Nothing]
testGame :: IO (Either WordifyError Game)
testGame = do
letterBag <- testSpanishLetterBag
dictionaryResult <- testSpanishDictionary
case dictionaryResult of
Left err -> return $ Left err
Right dict -> pure $ setupGame letterBag dict
where
setupGame :: LetterBag -> Dictionary -> Either WordifyError Game
setupGame bag dict = makeGame (player1, player2, Nothing) bag dict
where
player1 = makePlayer "player 1"
player2 = makePlayer "player 2"
testCannotPlayCandHOnOwn :: Assertion
testCannotPlayCandHOnOwn = do
gameResult <- testGame
case gameResult of
Left err -> assertFailure $ "Failed to set up game: " ++ show err
Right game -> do
let positions = rightPositions starPos 4
let tiles = [Letter "C" 3, Letter "H" 4, Letter "A" 1]
let moveMap = M.fromList $ zip positions tiles
let move = PlaceTiles moveMap
let result = makeMove game move
case result of
Left err -> assertFailure $ "Initial game transition failed before applying extra rules: " ++ show err
Right moveTransition@MoveTransition {} -> do
let result = applyExtraRules moveTransition spanishGameExtraRules
assertBool "Expected rule to fail " (isLeft result)
case result of
Left (RuleExecutionError code description) -> do
assertEqual "Expected InvalidConsecutiveTiles as error code" "InvalidConsecutiveTiles" code
assertEqual "Expected correct error description" "Cannot place C and H consecutively" description
otherwise -> return ()
Right _ -> assertFailure "Unexpected move transition type"
testCanPlayCHtile :: Assertion
testCanPlayCHtile = do
gameResult <- testGame
case gameResult of
Left err -> assertFailure $ "Failed to set up game: " ++ show err
Right game -> do
let positions = rightPositions starPos 4
let tiles = [Letter "CH" 5, Letter "A" 1]
let moveMap = M.fromList $ zip positions tiles
let move = PlaceTiles moveMap
let playerTwoMovePositions = reverse (drop 1 (fromJust (flip belowPositions 4 <$> right starPos)))
let playerTwoMoveLetters = [Letter "C" 3, Letter "A" 1, Letter "D" 2]
let moveMap = M.fromList $ zip playerTwoMovePositions playerTwoMoveLetters
let move2 = PlaceTiles moveMap
let result = makeMove game move
case result of
Left err -> assertFailure $ "Initial game transition failed before applying extra rules: " ++ show err
Right moveTransition@MoveTransition {} -> do
let result = applyExtraRules moveTransition spanishGameExtraRules
assertBool "Expected rule to pass validation " (isRight result)
let Right (RuleApplicationsResult gameTransition _) = result
let secondMove = makeMove (newGame gameTransition) move2
case secondMove of
Left err -> assertFailure $ "Expected second move success. Error was " ++ show err
Right _ -> do
let result2 = applyExtraRules moveTransition spanishGameExtraRules
assertBool "Expected rule to pass validation " (isRight result2)
Right _ -> assertFailure "Unexpected move transition type"
testCannotPlayCNextToExistingH :: Assertion
testCannotPlayCNextToExistingH = do
gameResult <- testGame
case gameResult of
Left err -> assertFailure $ "Failed to set up game: " ++ show err
Right game -> do
let positions = rightPositions starPos 2
let tiles = [Letter "H" 4, Letter "A" 1]
let moveMap = M.fromList $ zip positions tiles
let move = PlaceTiles moveMap
let result = A.left show (makeMove game move)
let validated = result >>= A.left show <$> flip applyExtraRules spanishGameExtraRules
assertBool "Should pass extra rule in first move" (isRight validated)
let positionsMove2 = [above starPos, below starPos]
let placedLettersMove2 = [Letter "C" 3, Letter "A" 1]
let moveMap2 = M.fromList $ zip positionsMove2 placedLettersMove2
let move2 = PlaceTiles moveMap
let result2 = A.left show (makeMove game move2)
assertBool "Move should succeed prior to extra rule" (isRight result2)
let validated = result2 >>= A.left show <$> flip applyExtraRules spanishGameExtraRules
assertBool "Should not pass extra validation on second move" (isRight validated)
case validated of
Left description -> assertEqual "Description should be as expected" "Cannot place C and H consecutively" description
Right _ -> return ()