LambdaHack-0.10.3.0: test/SessionUIUnitTests.hs
module SessionUIUnitTests (macroTests) where
import Prelude ()
import Game.LambdaHack.Core.Prelude
import qualified Data.Map.Strict as M
import Test.Tasty
import Test.Tasty.HUnit
import Test.Tasty.QuickCheck
import qualified Game.LambdaHack.Client.UI.Content.Input as IC
import qualified Game.LambdaHack.Client.UI.HumanCmd as HumanCmd
import qualified Game.LambdaHack.Client.UI.Key as K
import Game.LambdaHack.Client.UI.SessionUI
import qualified Client.UI.Content.Input as Content.Input
import SessionUIMock
-- Run @test -p "In-game" --quickcheck-verbose@ to verify that quickcheck
-- properties are not too often satisfied voidly.
macroTests :: TestTree
macroTests = testGroup "macroTests" $
let coinput = IC.makeData Nothing Content.Input.standardKeysAndMouse
stringToKeyMacro = KeyMacro . map (K.mkKM . (: []))
listToKeyMacro = KeyMacro . map K.mkKM
bindInput l input =
let ltriple = M.fromList $ map (\(k, ks) ->
(K.mkKM k, ([], "", HumanCmd.Macro $ map (: []) ks))) l
in input {IC.bcmdMap = M.union ltriple $ IC.bcmdMap input}
in [ testCase "Macro 1 from PR#192 description" $
fst <$> unwindMacros coinput (stringToKeyMacro "'j''j'")
@?= [ [ (Right "", "'j''j'", "") ]
, [ (Left "", "j''j'", "") ]
, [ (Left "j", "''j'", "j") ]
, [ (Right "j", "'j'", "j") ]
, [ (Left "", "j'", "j") ]
, [ (Left "j", "'", "j") ]
, [ (Right "j", "", "j") ]
]
, testCase "Macro 1 from Issue#189 description" $
snd (last (unwindMacros (bindInput [ ("a", "'bc'V")
, ("c", "'aaa'V") ] coinput)
(stringToKeyMacro "a")))
@?= "Macro looped"
, testCase "Macro 2 from Issue#189 description" $
snd (last (unwindMacros (bindInput [("a", "'x'")] coinput)
(stringToKeyMacro "'a'")))
@?= "x"
, testCase "Macro 3 from Issue#189 description" $
snd (last (unwindMacros coinput
(stringToKeyMacro "'x''x'")))
@?= "xx"
, testCase "Macro 4 from Issue#189 description" $
snd (last (unwindMacros coinput
(stringToKeyMacro "'x''x'V")))
@?= "xxx"
, testCase "Macro 5 from Issue#189 description" $
snd (last (unwindMacros coinput
(stringToKeyMacro "x'x'V")))
@?= "xxx"
, testCase "Macro test 10" $
snd (last (unwindMacros coinput
(stringToKeyMacro "x'y'V")))
@?= "xyy"
, testCase "Macro test 11" $
snd (last (unwindMacros coinput
(stringToKeyMacro "'x''y'V")))
@?= "xyy"
, testCase "Macro test 12" $
snd (last (unwindMacros coinput
(listToKeyMacro ["x", "C-V"])))
@?= "x"
, testCase "Macro test 13" $
snd (last (unwindMacros coinput
(listToKeyMacro ["'", "x", "'", "C-V"])))
@?= "xxxxxxxxxxxxxxxxxxxxxxxxxx"
, testCase "Macro test 14" $
snd (last (unwindMacros coinput
(listToKeyMacro ["'", "x", "'", "y", "C-V"])))
@?= "xyxxxxxxxxxxxxxxxxxxxxxxxxx"
, testCase "Macro test 15" $
snd (last (unwindMacros (bindInput [("a", "x")] coinput)
(stringToKeyMacro "'a'V")))
@?= "xx"
, testCase "Macro test 16" $
snd (last (unwindMacros (bindInput [("a", "'x'")] coinput)
(stringToKeyMacro "'a'V")))
@?= "xx"
, testCase "Macro test 17" $
snd (last (unwindMacros (bindInput [("a", "'x'V")] coinput)
(stringToKeyMacro "a")))
@?= "xx"
, testCase "Macro test 18" $
snd (last (unwindMacros (bindInput [("a", "'x'V")] coinput)
(stringToKeyMacro "'a'")))
@?= "xx"
, testCase "Macro test 19" $
snd (last (unwindMacros (bindInput [("a", "'x'V")] coinput)
(stringToKeyMacro "'a'V")))
@?= "xxxx"
, testCase "Macro test 20" $
snd (last (unwindMacros (bindInput [ ("a", "'bz'V")
, ("c", "'aaa'V") ] coinput)
(stringToKeyMacro "c")))
@?= "bzbzbzbzbzbzbzbzbzbzbzbz"
, testCase "RepeatLast test 10" $
snd (last (unwindMacros coinput
(stringToKeyMacro "x'y'v")))
@?= "xyy"
, testCase "RepeatLast test 11" $
snd (last (unwindMacros coinput
(stringToKeyMacro "'x'yv")))
@?= "xyy"
, testCase "RepeatLast test 12" $
snd (last (unwindMacros coinput
(listToKeyMacro ["v", "C-v"])))
@?= ""
, testCase "RepeatLast test 13" $
snd (last (unwindMacros coinput
(listToKeyMacro ["'", "x", "'", "C-v"])))
@?= "xxxxxxxxxxxxxxxxxxxxxxxxxx"
, testCase "RepeatLast test 14" $
snd (last (unwindMacros coinput
(listToKeyMacro ["'", "x", "'", "V", "C-v"])))
@?= "xxxxxxxxxxxxxxxxxxxxxxxxxxx"
, testCase "RepeatLast test 15" $
snd (last (unwindMacros (bindInput [("a", "x")] coinput)
(stringToKeyMacro "av")))
@?= "xx"
, testCase "RepeatLast test 16" $
snd (last (unwindMacros (bindInput [("a", "'x'")] coinput)
(stringToKeyMacro "'a'v")))
@?= "xx"
, testCase "RepeatLast test 17" $
snd (last (unwindMacros (bindInput [("a", "'x'v")] coinput)
(stringToKeyMacro "a")))
@?= "xx"
, testCase "RepeatLast test 18" $
snd (last (unwindMacros (bindInput [("a", "'x'v")] coinput)
(stringToKeyMacro "'a'")))
@?= "xx"
, testCase "RepeatLast test 19" $
snd (last (unwindMacros (bindInput [("a", "'x'v")] coinput)
(stringToKeyMacro "'a'v")))
@?= "xxxx"
, testCase "RepeatLast test 20" $
snd (last (unwindMacros (bindInput [ ("a", "'bz'v")
, ("c", "'aaa'v") ] coinput)
(stringToKeyMacro "c")))
@?= "bzzbzzbzzbzz"
, testCase "RepeatLast test 21" $
snd (last (unwindMacros (bindInput [("a", "'x'V")] coinput)
(stringToKeyMacro "'a'v")))
@?= "xxxx"
, testCase "RepeatLast test 22" $
snd (last (unwindMacros (bindInput [("a", "'xy'V")] coinput)
(stringToKeyMacro "'aa'v")))
@?= "xyxyxyxyxyxy"
, testCase "RepeatLast test 23" $
snd (last (unwindMacros (bindInput [("a", "'xy'v")] coinput)
(stringToKeyMacro "'aa'V")))
@?= "xyyxyyxyyxyy"
, testCase "RepeatLast test 24" $
snd (last (unwindMacros (bindInput [("a", "'xy'vv")] coinput)
(stringToKeyMacro "'aa'vv")))
@?= "xyyyxyyyxyyyxyyy"
, testCase "RepeatLast test 25" $
snd (last (unwindMacros (bindInput [("a", "'xyv'v")] coinput)
(stringToKeyMacro "'a'a'vv'")))
@?= "xyyyxyyyxyyyxyyy"
, testCase "RepeatLast test 26" $
snd (last (unwindMacros (bindInput [ ("a", "'xy'v")
, ("b", "'za'v")
, ("c", "'ab'v") ] coinput)
(stringToKeyMacro "'c'v")))
@?= "xyyzxyyxyyzxyyxyyxyyzxyyxyyzxyyxyy"
, testCase "RepeatLast test 27" $
snd (last (unwindMacros (bindInput [ ("a", "'xy'V")
, ("b", "'za'v")
, ("c", "'ab'v") ] coinput)
(stringToKeyMacro "'c'v")))
@?= "xyxyzxyxyxyxyzxyxyxyxyxyxyzxyxyxyxyzxyxyxyxy"
, testCase "RepeatLast test 28" $
snd (last (unwindMacros (bindInput [ ("a", "'xy'v")
, ("b", "'za'V")
, ("c", "'ab'v") ] coinput)
(stringToKeyMacro "'c'v")))
@?= "xyyzxyyzxyyzxyyzxyyxyyzxyyzxyyzxyyzxyy"
, testCase "RepeatLast test 29" $
snd (last (unwindMacros (bindInput [ ("a", "'xy'v")
, ("b", "'za'V")
, ("c", "'ab'V") ] coinput)
(stringToKeyMacro "'c'v")))
@?= "xyyzxyyzxyyxyyzxyyzxyyxyyzxyyzxyyxyyzxyyzxyy"
, testCase "RepeatLast test 30" $
snd (last (unwindMacros (bindInput [ ("a", "'xy'v")
, ("b", "'za'V")
, ("c", "'ab'V") ] coinput)
(stringToKeyMacro "'c'V")))
@?= "xyyzxyyzxyyxyyzxyyzxyyxyyzxyyzxyyxyyzxyyzxyy"
, testCase "RepeatLast test 31" $
snd (last (unwindMacros (bindInput [ ("a", "'xy'v")
, ("b", "'za'v")
, ("c", "'ab'V") ] coinput)
(stringToKeyMacro "'c'V")))
@?= "xyyzxyyxyyxyyzxyyxyyxyyzxyyxyyxyyzxyyxyy"
, testCase "RepeatLast test 32" $
snd (last (unwindMacros (bindInput [ ("a", "'xy'v")
, ("b", "'za'v") ] coinput)
(stringToKeyMacro "'ab'vv")))
@?= "xyyzxyyxyyzxyyxyyzxyyxyy"
, testCase "RepeatLast test 33" $
snd (last (unwindMacros (bindInput [ ("a", "'xy'V") ] coinput)
(stringToKeyMacro "a'za'vvv")))
@?= "xyxyzxyxyxyxyxyxyxyxy"
, testCase "RepeatLast test 34" $
snd (last (unwindMacros (bindInput [ ("a", "'xy'v")
, ("c", "a'za'Vv") ] coinput)
(stringToKeyMacro "'c'v")))
@?= "xyyzxyyzxyyzxyyxyyzxyyzxyyzxyy"
, testCase "RepeatLast test 35" $
snd (last (unwindMacros (bindInput [ ("a", "'xy'v")
, ("b", "'za'V") ] coinput)
(stringToKeyMacro "'ab'Vv")))
@?= "xyyzxyyzxyyxyyzxyyzxyyxyyzxyyzxyy"
, testCase "RepeatLast test 36" $
snd (last (unwindMacros (bindInput [ ("a", "'xy'v")
, ("b", "za'za'") ] coinput)
(stringToKeyMacro "'ab'V'ab'V")))
@?= "xyyzxyyzxyyxyyzxyyzxyyxyyzxyyzxyyxyyzxyyzxyy"
, testCase "RepeatLast test 37" $
snd (last (unwindMacros (bindInput [ ("b", "z'xy'vv")
, ("c", "'xyvb'V") ] coinput)
(stringToKeyMacro "'c'V")))
@?= "xyyzxyyyxyyzxyyyxyyzxyyyxyyzxyyy"
, testCase "RepeatLast test 38" $
snd (last (unwindMacros coinput (stringToKeyMacro "'xv'V")))
@?= "xxxx"
, testCase "RepeatLast test 39" $
fst <$> unwindMacros coinput (stringToKeyMacro "'xv'V")
@?= [[(Right "", "'xv'V", "")],
[(Left "", "xv'V", "")],
[(Left "x", "v'V", "x")],
[(Left "x", "x'V", "x")],
[(Left "xx", "'V", "x")],
[(Right "xx", "V", "x")],
[(Right "", "xx", ""), (Right "xx", "", "V")],
[(Right "", "x", "x"), (Right "xx", "", "V")],
[(Right "xx", "", "V")]]
, testCase "RepeatLast test 40" $
snd (last (unwindMacros coinput (stringToKeyMacro "'xy'Vv")))
@?= "xyxyxy"
, testCase
"RepeatLast test 41; named macros not referentially transparent" $
snd (last (unwindMacros (bindInput [("a", "'xy'V")] coinput)
(stringToKeyMacro "av")))
@?= "xyxyxyxy" -- because @a@ repeated; good!
, testCase "RepeatLast test 42" $
snd (last (unwindMacros (bindInput [("a", "xy")] coinput)
(stringToKeyMacro "'a'Vv")))
@?= "xyxyxy" -- because @V@ repeated; good!
, testCase "RepeatLast test 43" $
snd (last (unwindMacros coinput (stringToKeyMacro "'xyV'V")))
@?= "xyxy"
, testCase "RepeatLast test 44" $
snd (last (unwindMacros coinput (stringToKeyMacro "'xyV'v")))
@?= "xyxy"
, testCase "RepeatLast test 45" $
snd (last (unwindMacros (bindInput [("a", "xyV")] coinput)
(stringToKeyMacro "'a'V")))
@?= "xyxy"
, testCase "RepeatLast test 46" $
snd (last (unwindMacros (bindInput [("a", "xyV")] coinput)
(stringToKeyMacro "'a'v")))
@?= "xyxy"
, testProperty "In-game macro and equivalent predefined macro agree" $
forAll (listOf (elements "`ABvV")) $
\macro ->
let bindings = bindInput [("a", macro)] coinput
inGameResult =
snd (last (unwindMacros coinput
(stringToKeyMacro macro)))
in inGameResult
=== snd (last (unwindMacros bindings
(stringToKeyMacro "a")))
.&&. inGameResult =/= "Macro looped" -- may not loop
, testProperty "In-game and predefined with limited minimal bindings" $
forAll (listOf (elements "````''''ABCABCABCABCvVvVvVa")) $ -- may loop
\macro ->
let bindings = bindInput [("a", macro)] coinput
in snd (last (unwindMacros bindings
(stringToKeyMacro macro)))
=== snd (last (unwindMacros bindings
(stringToKeyMacro "a")))
, testProperty "In-game and predefined with limited multiple bindings" $
forAll (listOf (elements "```ABCDvVabccc")) $
\macro ->
-- The macros may still loop due to mutual recursion,
-- even though direct recursion is ruled out by filtering.
let macroA = filter (/= 'a') macro
macroB = filter (/= 'b') $ take 5 $ reverse macro
bindings = bindInput [ ("a", macroA)
, ("b", macroB)
, ("c", "A'B''CD'") ]
coinput
in snd (last (unwindMacros bindings
(stringToKeyMacro macroA)))
=== snd (last (unwindMacros bindings
(stringToKeyMacro "a")))
]