import Test.Hspec import Test.QuickCheck import qualified Data.Memoizer.Commands as Cmd type CmdResults = [(Int,Int)] memoizeCommands :: CmdResults -> Cmd.CmdMemoizer Int Int memoizeCommands = foldl (flip $ uncurry Cmd.storeResult) Cmd.empty firstDiff :: Int -> CmdResults -> Cmd.CmdMemoizer Int Int -> (Int, Cmd.CmdMemoizer Int Int) firstDiff acc [] m = (acc, Cmd.deleteResult m) firstDiff acc ((a,b):q) m = case Cmd.lookup a m of Nothing -> (acc, Cmd.storeResult a b m) Just b' -> if b == b' then firstDiff (acc + 1) q (Cmd.nextCmd m) else (acc,Cmd.storeResult a b m) main :: IO () main = hspec $ do describe "Data.Memoizer.Commands" $ do it "Cannot guess when not memoized" $ property $ \a l-> Cmd.lookup a (memoizeCommands l) `shouldBe` Nothing it "Memoizes first command" $ property $ \a b l -> Cmd.lookup a (Cmd.restart (memoizeCommands ((a,b): l))) `shouldBe` Just b it "Memoizes second command" $ property $ \a b l a' b' -> Cmd.lookup a' (Cmd.nextCmd (Cmd.restart (memoizeCommands ((a,b):(a',b'): l)))) `shouldBe` Just b' it "Finds the first modification" $ property $ \a b a' l1 l2 -> let l = l1 ++ [(a,b)] ++ l2 l' = l1 ++ [(a',b)] ++ l2 in if a == a' then fst (firstDiff 0 l' (Cmd.restart (memoizeCommands l))) `shouldBe` length l' else fst (firstDiff 0 l' (Cmd.restart (memoizeCommands l))) `shouldBe` length l1 it "Do not memoize after first modif" $ property $ \a'' a b a' l1 l2 -> let l = l1 ++ [(a,b)] ++ l2 l' = l1 ++ [(a',b)] ++ l2 in (Cmd.lookup a'' $ snd $ firstDiff 0 l' $ Cmd.restart $ memoizeCommands l) `shouldBe` Nothing