{- |
Module : Test.SDP.Linear
Copyright : (c) Andrey Mulik 2019
License : BSD-style
Maintainer : work.a.mulik@gmail.com
Portability : non-portable (requires non-portable modules)
@Test.SDP.Linear@ provides basic test suite for 'Linear' class.
-}
module Test.SDP.Linear
(
-- * Default Linear test
TestLinear, TestLinear1, TestLinear2, linearTest,
-- ** Particular tests
deconstructionLinearTest, constructionLinearTest, basicLinearTest,
replicateTest, reverseTest, concatTest
)
where
import Prelude ()
import SDP.SafePrelude
import SDP.Linear
default ()
--------------------------------------------------------------------------------
-- | 'TestLinear' is service type synonym for more comfortable quickCheck using.
type TestLinear l e = Int -> e -> l -> Bool
-- | 'TestLinear1' is service type synonym for more comfortable quickCheck using.
type TestLinear1 f e = Int -> e -> f e -> Bool
-- | 'TestLinear2' is service type synonym for more comfortable quickCheck using.
type TestLinear2 f i e = Int -> e -> f i e -> Bool
--------------------------------------------------------------------------------
{- |
'basicLinearTest' checks relations of 'isNull', 'lzero', 'single' and
'fromList'.
-}
basicLinearTest :: (Linear l e, Eq l) => e -> l -> Bool
basicLinearTest e line = and
[
isNull ( lzero `asTypeOf` line),
isNull (fromList [] `asTypeOf` line),
single e == (fromList [e] `asTypeOf` line),
not $ isNull ( single e `asTypeOf` line),
fromList (listL line) == line
]
{- |
'deconstructionLinearTest' checks relations of 'isNull', 'head', 'last',
'init' and 'tail'.
-}
deconstructionLinearTest :: (Linear l e, Eq e) => l -> Bool
deconstructionLinearTest line = and
[
isNull line || head line == head (listL line),
isNull line || last line == last (listL line),
isNull line || listL (init line) == init (listL line),
isNull line || listL (tail line) == tail (listL line)
]
{- |
'constructionLinearTest' checks relations of 'toHead', 'toLast' and
'fromList'.
-}
constructionLinearTest :: (Linear l e, Eq l) => e -> l -> Bool
constructionLinearTest e line = and
[
toHead e line == fromList (e : listL line),
toLast line e == fromList (listL line ++ [e]),
not . isNull $ toHead e line,
not . isNull $ toLast line e
]
-- | 'reverseTest' checks rules of 'reverse', 'listL' and 'listR'.
reverseTest :: (Linear l e, Eq e) => l -> Bool
reverseTest line = and
[
reverse (listL line) == listL (reverse line),
reverse (listL line) == listR line
]
-- | 'replicateTest' checks rules of 'replicate'.
replicateTest :: (Linear l e, Eq l, Bordered l i) => Int -> e -> l -> Bool
replicateTest n e line = and
[
line' == fromList (replicate n e),
n < 0 || sizeOf line' == n,
not $ n > 0 && isNull line'
]
where
line' = (replicate n e) `asTypeOf` line
-- | 'concatTest' checks rules of ('++') and 'concat'.
concatTest :: (Linear l e, Eq e, Eq l) => l -> Bool
concatTest line = and
[
listL line ++ listR line == listL (line ++ reverse line),
Z ++ line == line,
line ++ Z == line,
concat [line, reverse line] == fromList (concat [listL line, listR line]),
concat [line, reverse line] == line ++ reverse line
]
-- | 'linearTest' is complex test, that includes all ther tests.
linearTest :: (Linear l e, Eq e, Eq l, Bordered l i) => Int -> e -> l -> Bool
linearTest n e line = and
[
basicLinearTest e line,
deconstructionLinearTest line,
constructionLinearTest e line,
replicateTest n e line,
reverseTest line,
concatTest line
]