module Main where { import Prelude; import Data.Proxy; import Data.Word; import Test.Tasty; import Test.Tasty.HUnit; import Data.Empty; import Data.Searchable; import Data.Countable; import Show; import TypeName; import Three; import Golden; (@/=?) :: (Eq a,Show a) => a -> a -> Assertion; unexpected @/=? actual | unexpected /= actual = return (); _unexpected @/=? actual = assertFailure $ "got unexpected " ++ show actual; prevMaybeNext :: (Countable a,Show a) => Maybe a -> Assertion; prevMaybeNext ma = case countMaybeNext ma of { Just a' -> countPrevious a' @=? ma; Nothing -> return (); }; countableTests' :: (Show a,Countable a) => a -> [TestTree]; countableTests' a = [ testCase "maybeNextDifferent" $ (Just a) @/=? countMaybeNext (Just a), testCase "prevDifferent" $ (Just a) @/=? (countPrevious a), testCase "maybeNextPrev" $ (Just a) @=? countMaybeNext (countPrevious a), testCase "prevMaybeNext" $ prevMaybeNext (Just a) ]; findInNext :: (Countable a) => Int -> a -> TestTree; findInNext n a = testCase "findInNext" $ findInNext' n Nothing where { findInNext' 0 _ = assertFailure "failed"; findInNext' _ (Just x) | x == a = return (); findInNext' n' mx = case countMaybeNext mx of { Nothing -> assertFailure "failed"; mx' -> findInNext' (n' - 1) mx'; }; }; countableTests :: (Show a,Countable a) => a -> [TestTree]; countableTests a = (countableTests' a) ++ [findInNext 1000 a]; nextIsMaybeNext :: (Show a,InfiniteCountable a) => Maybe a -> TestTree; nextIsMaybeNext ma = testCase "nextIsMaybeNext" $ (Just (countNext ma)) @=? (countMaybeNext ma); infiniteCountableTests :: (Show a,InfiniteCountable a) => a -> [TestTree]; infiniteCountableTests a = (countableTests a) ++ [nextIsMaybeNext (Just a)]; checkN :: (Show a,Countable a) => (String -> IO ()) -> Int -> Maybe a -> IO (); checkN _ 0 _ = return (); checkN write n ma = let { ma' = countMaybeNext ma; } in do { prevMaybeNext ma; write (show ma ++ "\n"); case ma' of { Nothing -> return (); _ -> checkN write (n - 1) ma'; }; }; testType :: forall a. (TypeName a,Show a) => (a -> [TestTree]) -> [a] -> TestTree; testType tests vals = testGroup (typeName (Proxy::Proxy a)) $ fmap (\a -> testGroup (show a) (tests a)) vals; -- This is to prevent overlapping Show function instance in Text.Show.Functions, -- which gets imported somehow with lts-5. newtype WrapFunction a b = MkWrapFunction (a -> b) deriving (Eq,Searchable,Countable,TypeName); instance (Show a,Finite a,Show b) => Show (WrapFunction a b) where { show (MkWrapFunction f) = showFunction f; }; instance (Finite a,Finite b) => Finite (WrapFunction a b) where { allValues = fmap MkWrapFunction allValues; assemble wabfx = let foo abx (MkWrapFunction ab) = abx ab; in fmap foo $ assemble (wabfx . MkWrapFunction); }; allTests :: TestTree; allTests = testGroup "countable" [ testType countableTests (allValues :: [()]), testType countableTests (allValues :: [Bool]), testType countableTests ([0,3,255] :: [Word8]), testType countableTests (allValues :: [Maybe ()]), testType countableTests (allValues :: [Maybe Bool]), testType countableTests (allValues :: [Maybe (Maybe Bool)]), testType countableTests ([[],[0],[2],[-1,1],[0,0,0]] :: [[Integer]]), testType countableTests' ([[1,2,1],[-5,17,112]] :: [[Integer]]), testType countableTests ([[],[True,True]] :: [[Bool]]), testType infiniteCountableTests ([0,1,-1,3,-7] :: [Integer]), testType countableTests (allValues :: [WrapFunction Three Three]), testType countableTests (allValues :: [None]), testType countableTests ([[] :: [None]]), testGroup "list" [ goldenVsWriteString "Bool" "test/count.Bool.ref" $ \write -> checkN write 40 (Nothing :: Maybe [Bool ]), goldenVsWriteString "Word8" "test/count.Word8.ref" $ \write -> checkN write 40 (Nothing :: Maybe [Word8 ]), goldenVsWriteString "Integer" "test/count.Integer.ref" $ \write -> checkN write 40 (Nothing :: Maybe [Integer]) ] ]; main :: IO (); main = defaultMain allTests; }