{-| Module : Game.Werewolf.Test.Engine.Werewolf Copyright : (c) Henry J. Wylde, 2016 License : BSD3 Maintainer : public@hjwylde.com -} module Game.Werewolf.Test.Engine.Werewolf ( -- * Tests allWerewolfEngineTests, ) where import Control.Lens import qualified Data.Map as Map import Data.Maybe import Game.Werewolf import Game.Werewolf.Test.Arbitrary import Game.Werewolf.Test.Util import Test.QuickCheck import Test.Tasty import Test.Tasty.QuickCheck allWerewolfEngineTests :: [TestTree] allWerewolfEngineTests = [ testProperty "check stage skips werewolves' turn when no werewolves" prop_checkStageSkipsWerewolvesTurnWhenNoWerewolves , testProperty "check werewolves' turn advances to witch's turn" prop_checkWerewolvesTurnAdvancesToWitchsTurn , testProperty "check werewolves' turn skips witch's turn when healed and poisoned" prop_checkWerewolvesTurnSkipsWitchsTurnWhenHealedAndPoisoned , testProperty "check werewolves' turn kills one player when consensus" prop_checkWerewolvesTurnKillsOnePlayerWhenConsensus , testProperty "check werewolves' turn kills no one when conflicted" prop_checkWerewolvesTurnKillsNoOneWhenConflicted , testProperty "check werewolves' turn kills no one when target defended" prop_checkWerewolvesTurnKillsNoOneWhenTargetDefended , testProperty "check werewolves' turn resets protect" prop_checkWerewolvesTurnResetsProtect , testProperty "check werewolves' turn resets votes" prop_checkWerewolvesTurnResetsVotes , testProperty "check werewolves' turn does nothing unless all voted" prop_checkWerewolvesTurnDoesNothingUnlessAllVoted ] prop_checkStageSkipsWerewolvesTurnWhenNoWerewolves :: GameWithNoWerewolvesAtProtectorsTurn -> Property prop_checkStageSkipsWerewolvesTurnWhenNoWerewolves (GameWithNoWerewolvesAtProtectorsTurn game) = forAll (arbitraryProtectCommand game) $ \(Blind command) -> do let game' = run_ (apply command) game hasn't (stage . _WerewolvesTurn) game' prop_checkWerewolvesTurnAdvancesToWitchsTurn :: GameWithDevourVotes -> Property prop_checkWerewolvesTurnAdvancesToWitchsTurn (GameWithDevourVotes game) = length (getVoteResult game) == 1 ==> has (stage . _WitchsTurn) (run_ checkStage game) prop_checkWerewolvesTurnSkipsWitchsTurnWhenHealedAndPoisoned :: GameWithDevourVotes -> Bool prop_checkWerewolvesTurnSkipsWitchsTurnWhenHealedAndPoisoned (GameWithDevourVotes game) = hasn't (stage . _WitchsTurn) (run_ checkStage game') where game' = game & healUsed .~ True & poisonUsed .~ True prop_checkWerewolvesTurnKillsOnePlayerWhenConsensus :: GameWithDevourVotes -> Property prop_checkWerewolvesTurnKillsOnePlayerWhenConsensus (GameWithDevourVotes game) = length (getVoteResult game) == 1 ==> has (events . traverse . _DevourEvent) (run_ checkStage game) prop_checkWerewolvesTurnKillsNoOneWhenConflicted :: GameWithDevourVotes -> Property prop_checkWerewolvesTurnKillsNoOneWhenConflicted (GameWithDevourVotes game) = length (getVoteResult game) > 1 ==> hasn't (events . traverse . _DevourEvent) (run_ checkStage game) prop_checkWerewolvesTurnKillsNoOneWhenTargetDefended :: GameWithProtectAndDevourVotes -> Property prop_checkWerewolvesTurnKillsNoOneWhenTargetDefended (GameWithProtectAndDevourVotes game) = length (getVoteResult game) == 1 ==> hasn't (events . traverse . _DevourEvent) (run_ checkStage game') where target = head $ getVoteResult game game' = game & protect .~ Just (target ^. name) prop_checkWerewolvesTurnResetsProtect :: GameWithProtectAndDevourVotes -> Bool prop_checkWerewolvesTurnResetsProtect (GameWithProtectAndDevourVotes game) = isNothing $ run_ checkStage game ^. protect prop_checkWerewolvesTurnResetsVotes :: GameWithDevourVotes -> Bool prop_checkWerewolvesTurnResetsVotes (GameWithDevourVotes game) = Map.null $ run_ checkStage game ^. votes prop_checkWerewolvesTurnDoesNothingUnlessAllVoted :: GameAtWerewolvesTurn -> Property prop_checkWerewolvesTurnDoesNothingUnlessAllVoted (GameAtWerewolvesTurn game) = forAll (runArbitraryCommands n game) $ \game' -> has (stage . _WerewolvesTurn) (run_ checkStage game') where n = length (game ^.. players . werewolves) - 1