spectacle-1.0.0: test/unit-tests/Test/Control/Comonad/Tape.hs
-- |
--
-- @since 0.1.0.0
module Test.Control.Comonad.Tape
( tests,
)
where
import Control.Comonad (duplicate, extract)
import Data.Sequence (Seq)
import Hedgehog (MonadGen, Property, diff, discard, footnote, forAll, property, withTests)
import qualified Hedgehog.Gen as Gen
import qualified Hedgehog.Range as Range
import Test.Tasty (TestTree, testGroup)
import Test.Tasty.Hedgehog (testProperty)
import Control.Comonad.Tape (Tape, shiftl, shiftr, toSeq, viewAt, viewl, viewr)
-- ---------------------------------------------------------------------------------------------------------------------
tests :: TestTree
tests =
testGroup
"Tape"
[ testProperty "Tape.viewl == Tape.viewAt 0" viewlIsAt0
, testProperty "Tape.viewr == Tape.viewAt . length" viewrIsAtN
, testProperty "Tape/Seq isomorphism" isoTapeSeq
, testProperty "extract . duplicate == id" idDuplicateExtract
, testProperty "move n . viewAt i == viewAt (n + i)" idViewMove
, testProperty "shiftl . mover . shiftl == shiftl" invShiftl
, testProperty "mover . shiftl . mover == shiftr" invShiftr
]
linearIntSeq :: MonadGen m => Int -> Int -> m (Seq Int)
linearIntSeq lb ub = Gen.seq (Range.linear lb ub) (Gen.int Range.linearBounded)
viewlIsAt0 :: Property
viewlIsAt0 = withTests 10 $ property do
xs <- forAll (linearIntSeq 0 5)
diff (viewl xs) (==) (viewAt 0 xs)
viewrIsAtN :: Property
viewrIsAtN = withTests 10 $ property do
xs <- forAll (linearIntSeq 0 5)
diff (viewr xs) (==) (viewAt (length xs - 1) xs)
isoTapeSeq :: Property
isoTapeSeq = withTests 10 $ property do
xs <- forAll (linearIntSeq 0 5)
i <- forAll (Gen.int $ Range.constant 0 (length xs))
if null xs
then diff (toSeq <$> viewAt i xs) (==) Nothing
else diff (toSeq <$> viewAt i xs) (==) (Just xs)
idDuplicateExtract :: Property
idDuplicateExtract = withTests 10 $ property do
xs <- forAll (linearIntSeq 0 5)
i <- forAll (Gen.int $ Range.constant 0 (length xs - 1))
case viewAt i xs of
Nothing -> discard
Just tape -> do
diff (extract (duplicate tape)) (==) tape
-- Testing that viewing the tape at some @i@ and moving it @n@ is the same as viewing it at @i - n@.
idViewMove :: Property
idViewMove = property do
xs <- forAll (linearIntSeq 0 10)
let ub = length xs - 1
i <- forAll (Gen.int $ Range.constant 0 ub)
n <- forAll (Gen.int $ Range.constant 0 ub)
footnote ("viewed at: " ++ show i)
footnote ("moved by: " ++ show n)
diff (shiftl n <$> viewAt i xs) (==) (viewAt (i - n) xs)
diff (shiftr n <$> viewAt i xs) (==) (viewAt (i + n) xs)
invShiftl :: Property
invShiftl = isInverse shiftl shiftr
invShiftr :: Property
invShiftr = isInverse shiftr shiftl
isInverse :: (forall a. Int -> Tape a -> Tape a) -> (forall a. Int -> Tape a -> Tape a) -> Property
isInverse to from = property do
xs <- forAll (linearIntSeq 0 10)
let ub = length xs - 1
i <- forAll (Gen.int $ Range.constant 0 ub)
case viewAt i xs of
Nothing -> discard
Just tape -> do
n <- forAll (Gen.int $ Range.constant 0 ub)
diff (to n . from n . to n $ tape) (==) (to n tape)