module Data.AMT.Spec ( spec ) where import Data.Foldable (toList) import Test.Hspec import Test.Hspec.QuickCheck (prop) import Test.QuickCheck import qualified Data.AMT as V default (Int) instance Arbitrary a => Arbitrary (V.Vector a) where arbitrary = fmap V.fromList arbitrary unsnoc :: [a] -> Maybe ([a], a) unsnoc [] = Nothing unsnoc ls = Just (init ls, last ls) (!?) :: [a] -> Int -> Maybe a ls !? i | i < 0 || i >= length ls = Nothing | otherwise = Just (ls !! i) spec :: Spec spec = describe "Data.AMT" $ do prop "satisfies `fromList . toList == id`" $ \v -> V.fromList (toList v) === v prop "satisfies `toList . fromList == id`" $ \ls -> toList (V.fromList ls) === ls describe "length" $ do prop "returns the length" $ \ls -> length (V.fromList ls) === length ls it "returns 0 for the empty vector" $ length V.empty `shouldBe` 0 describe "snoc" $ do prop "appends an element to the back" $ \v x -> toList (v V.|> x) === toList v ++ [x] prop "works for the empty vector" $ \x -> V.empty V.|> x `shouldBe` V.singleton x describe "unsnoc" $ do prop "analyzes the back of the vector" $ \v -> V.viewr v === fmap (\(xs, x) -> (V.fromList xs, x)) (unsnoc (toList v)) it "returns Nothing for the empty vector" $ V.viewr V.empty `shouldBe` Nothing describe "take" $ do prop "takes the first n elements" $ \n xs -> V.take n (V.fromList xs) === V.fromList (take n xs) prop "returns the empty vector for non-positive n" $ \(NonPositive n) v -> V.take n v === V.empty prop "does nothing for the empty vector" $ \n -> V.take n V.empty === V.empty describe "lookup" $ do prop "returns the ith element" $ \i v -> V.lookup i v === toList v !? i prop "returns Nothing for negative indices" $ \(Negative i) v -> V.lookup i v === Nothing prop "returns Nothing for the empty vector" $ \i -> V.lookup i V.empty === Nothing