mono-traversable 1.0.15.1 → 1.0.15.2
raw patch · 6 files changed
+523/−514 lines, 6 filesdep −semigroupsdep ~basedep ~transformers
Dependencies removed: semigroups
Dependency ranges changed: base, transformers
Files
- ChangeLog.md +5/−0
- mono-traversable.cabal +4/−11
- src/Data/MonoTraversable.hs +12/−0
- test/Main.hs +502/−0
- test/Spec.hs +0/−502
- test/main.hs +0/−1
ChangeLog.md view
@@ -1,5 +1,10 @@ # ChangeLog for mono-traversable +## 1.0.15.2++* Support transformers 0.6.0.0 [#196](https://github.com/snoyberg/mono-traversable/issues/196)+* Compile with GHC 9 [#193](https://github.com/snoyberg/mono-traversable/pull/193)+ ## 1.0.15.1 * Remove whitespace after `@` in as-patterns for GHC HEAD [#186](https://github.com/snoyberg/mono-traversable/pull/186)
mono-traversable.cabal view
@@ -1,13 +1,11 @@ cabal-version: 1.12 --- This file has been generated from package.yaml by hpack version 0.31.2.+-- This file has been generated from package.yaml by hpack version 0.34.4. -- -- see: https://github.com/sol/hpack------ hash: b2ac08c2845dd12213a3bc3c6e01f805bb98a7693a588b0ae313ceadcb5ca592 name: mono-traversable-version: 1.0.15.1+version: 1.0.15.2 synopsis: Type classes for mapping, folding, and traversing monomorphic containers description: Please see the README at <https://www.stackage.org/package/mono-traversable> category: Data@@ -39,7 +37,7 @@ src ghc-options: -Wall build-depends:- base >=4.10 && <5+ base >=4.13 && <5 , bytestring >=0.9 , containers >=0.5.8 , hashable@@ -49,16 +47,12 @@ , unordered-containers >=0.2 , vector >=0.10 , vector-algorithms >=0.6- if impl(ghc <8.0)- build-depends:- semigroups >=0.10 default-language: Haskell2010 test-suite test type: exitcode-stdio-1.0- main-is: main.hs+ main-is: Main.hs other-modules:- Spec Paths_mono_traversable hs-source-dirs: test@@ -72,7 +66,6 @@ , foldl , hspec , mono-traversable- , semigroups , text , transformers , unordered-containers
src/Data/MonoTraversable.hs view
@@ -72,7 +72,9 @@ import Data.HashMap.Strict (HashMap) import Data.Vector (Vector) import Control.Monad.Trans.Maybe (MaybeT (..))+#if !MIN_VERSION_transformers(0,6,0) import Control.Monad.Trans.List (ListT)+#endif import Control.Monad.Trans.Writer (WriterT) import qualified Control.Monad.Trans.Writer.Strict as Strict (WriterT) import Control.Monad.Trans.State (StateT(..))@@ -128,7 +130,9 @@ type instance Element (Vector a) = a type instance Element (WrappedArrow a b c) = c type instance Element (MaybeT m a) = a+#if !MIN_VERSION_transformers(0,6,0) type instance Element (ListT m a) = a+#endif type instance Element (IdentityT m a) = a type instance Element (WriterT w m a) = a type instance Element (Strict.WriterT w m a) = a@@ -198,7 +202,9 @@ instance MonoFunctor (Arg a b) instance Arrow a => MonoFunctor (WrappedArrow a b c) instance Functor m => MonoFunctor (MaybeT m a)+#if !MIN_VERSION_transformers(0,6,0) instance Functor m => MonoFunctor (ListT m a)+#endif instance Functor m => MonoFunctor (IdentityT m a) instance Functor m => MonoFunctor (WriterT w m a) instance Functor m => MonoFunctor (Strict.WriterT w m a)@@ -801,7 +807,9 @@ instance MonoFoldable (a, b) instance MonoFoldable (Const m a) instance F.Foldable f => MonoFoldable (MaybeT f a)+#if !MIN_VERSION_transformers(0,6,0) instance F.Foldable f => MonoFoldable (ListT f a)+#endif instance F.Foldable f => MonoFoldable (IdentityT f a) instance F.Foldable f => MonoFoldable (WriterT w f a) instance F.Foldable f => MonoFoldable (Strict.WriterT w f a)@@ -1099,7 +1107,9 @@ instance MonoTraversable (a, b) instance MonoTraversable (Const m a) instance Traversable f => MonoTraversable (MaybeT f a)+#if !MIN_VERSION_transformers(0,6,0) instance Traversable f => MonoTraversable (ListT f a)+#endif instance Traversable f => MonoTraversable (IdentityT f a) instance Traversable f => MonoTraversable (WriterT w f a) instance Traversable f => MonoTraversable (Strict.WriterT w f a)@@ -1209,7 +1219,9 @@ instance Monoid a => MonoPointed (a, b) instance Monoid m => MonoPointed (Const m a) instance Monad m => MonoPointed (WrappedMonad m a)+#if !MIN_VERSION_transformers(0,6,0) instance Applicative m => MonoPointed (ListT m a)+#endif instance Applicative m => MonoPointed (IdentityT m a) instance Arrow a => MonoPointed (WrappedArrow a b c) instance (Monoid w, Applicative m) => MonoPointed (WriterT w m a)
+ test/Main.hs view
@@ -0,0 +1,502 @@+{-# LANGUAGE GADTs #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE ViewPatterns #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE PatternSynonyms #-}++module Main where++import Data.MonoTraversable+import Data.Containers+import Data.Sequences+import qualified Data.Sequence as Seq+import qualified Data.NonNull as NN+import Data.Monoid (mempty, mconcat)+import Data.Maybe (fromMaybe)+import qualified Data.List as List++import Test.Hspec+import Test.Hspec.QuickCheck+import Test.HUnit ((@?=))+import Test.QuickCheck hiding (NonEmptyList(..))+import Test.QuickCheck.Function (pattern Fn)+import qualified Test.QuickCheck.Modifiers as QCM++import Data.Text (Text)+import qualified Data.Text as T+import qualified Data.Text.Lazy as TL+import qualified Data.ByteString as S+import qualified Data.ByteString.Lazy as L+import qualified Data.Vector as V+import qualified Data.Vector.Unboxed as U+import qualified Data.Vector.Storable as VS+import qualified Data.List.NonEmpty as NE+import qualified Data.Semigroup as SG+import qualified Data.Map as Map+import qualified Data.IntMap as IntMap+import qualified Data.HashMap.Strict as HashMap+import qualified Data.Set as Set+import qualified Control.Foldl as Foldl++import Control.Arrow (second)+import Control.Applicative+import Control.Monad.Trans.Writer++import Prelude (Bool (..), ($), IO, Eq (..), fromIntegral, Ord (..), String, mod, Int, Integer, show,+ return, asTypeOf, (.), Show, (+), succ, Maybe (..), (*), mod, map, flip, otherwise, (-), div, maybe)+import qualified Prelude++newtype NonEmpty' a = NonEmpty' (NE.NonEmpty a)+ deriving (Show, Eq)+instance Arbitrary a => Arbitrary (NonEmpty' a) where+ arbitrary = NonEmpty' <$> ((NE.:|) <$> arbitrary <*> arbitrary)++-- | Arbitrary newtype for key-value pairs without any duplicate keys+-- and is not empty+newtype DuplPairs k v = DuplPairs { unDupl :: [(k,v)] }+ deriving (Eq, Show)++removeDuplicateKeys :: Ord k => [(k,v)] -> [(k,v)]+removeDuplicateKeys m = go Set.empty m+ where go _ [] = []+ go used ((k,v):xs)+ | k `member` used = go used xs+ | otherwise = (k,v) : go (insertSet k used) xs++instance (Arbitrary k, Arbitrary v, Ord k, Eq v) => Arbitrary (DuplPairs k v) where+ arbitrary = DuplPairs . removeDuplicateKeys <$> arbitrary `suchThat` (/= [])+ shrink (DuplPairs xs) =+ map (DuplPairs . removeDuplicateKeys) $ filter (/= []) $ shrink xs++-- | Arbitrary newtype for small lists whose length is <= 10+--+-- Used for testing 'unionsWith'+newtype SmallList a = SmallList { getSmallList :: [a] }+ deriving (Eq, Show, Ord)++instance (Arbitrary a) => Arbitrary (SmallList a) where+ arbitrary = SmallList <$> arbitrary `suchThat` ((<= 10) . olength)+ shrink (SmallList xs) =+ map SmallList $ filter ((<= 10) . olength) $ shrink xs++-- | Choose a random key from a key-value pair list+indexIn :: (Show k, Testable prop) => [(k,v)] -> (k -> prop) -> Property+indexIn = forAll . elements . map Prelude.fst++-- | Type restricted 'fromList'+fromListAs :: IsSequence a => [Element a] -> a -> a+fromListAs xs _ = fromList xs++-- | Type restricted 'mapFromListAs'+mapFromListAs :: IsMap a => [(ContainerKey a, MapValue a)] -> a -> a+mapFromListAs xs _ = mapFromList xs++main :: IO ()+main = hspec $ do+ describe "onull" $ do+ it "works on empty lists" $ onull [] @?= True+ it "works on non-empty lists" $ onull [()] @?= False+ it "works on empty texts" $ onull ("" :: Text) @?= True+ it "works on non-empty texts" $ onull ("foo" :: Text) @?= False++ describe "osum" $ do+ prop "works on lists" $ \(Small x) (Small y) ->+ y >= x ==> osum [x..y] @?= ((x + y) * (y - x + 1) `div` (2 :: Int))++ describe "oproduct" $ do+ prop "works on lists" $ \(Positive x) (Positive y) ->+ let fact n = oproduct [1..n]+ in (y :: Integer) > (x :: Integer) ==>+ oproduct [x..y] @?= fact y `div` fact (x - 1)++ describe "olength" $ do+ prop "works on lists" $ \(NonNegative i) ->+ olength (replicate i () :: [()]) @?= i+ prop "works on texts" $ \(NonNegative i) ->+ olength (replicate i 'a' :: Text) @?= i+ prop "works on lazy bytestrings" $ \(NonNegative (Small i)) ->+ olength64 (replicate i 6 :: L.ByteString) @?= i++ describe "omap" $ do+ prop "works on lists" $ \xs ->+ omap (+1) xs @?= map (+1) (xs :: [Int])+ prop "works on lazy bytestrings" $ \xs ->+ omap (+1) (fromList xs :: L.ByteString) @?= fromList (map (+1) xs)+ prop "works on texts" $ \xs ->+ omap succ (fromList xs :: Text) @?= fromList (map succ xs)++ describe "oconcatMap" $ do+ prop "works on lists" $ \xs ->+ oconcatMap (: []) xs @?= (xs :: [Int])++ describe "ocompareLength" $ do+ prop "works on lists" $ \(Positive i) j ->+ ocompareLength (replicate i () :: [()]) j @?= compare i j++ describe "groupAll" $ do+ it "works on lists" $ groupAll ("abcabcabc" :: String) @?= ["aaa", "bbb", "ccc"]+ it "works on texts" $ groupAll ("abcabcabc" :: Text) @?= ["aaa", "bbb", "ccc"]++ describe "unsnoc" $ do+ let test name dummy = prop name $ \(QCM.NonEmpty xs) ->+ let seq' = fromListAs xs dummy+ in case unsnoc seq' of+ Just (y, z) -> do+ y SG.<> singleton z @?= seq'+ snoc y z @?= seq'+ otoList (snoc y z) @?= xs+ Nothing -> expectationFailure "unsnoc returned Nothing"+ test "works on lists" ([] :: [Int])+ test "works on texts" ("" :: Text)+ test "works on lazy bytestrings" L.empty++ describe "index" $ do+ let test name dummy = prop name $+ \i' (QCM.NonEmpty xs) ->+ let seq' = fromListAs xs dummy+ mx = index xs (fromIntegral i)+ i = fromIntegral (i' :: Int)+ in do+ mx @?= index seq' i+ case mx of+ Nothing -> return ()+ Just x -> indexEx seq' i @?= x+ test "works on lists" ([] :: [Int])+ test "works on strict texts" ("" :: Text)+ test "works on lazy texts" ("" :: TL.Text)+ test "works on strict bytestrings" S.empty+ test "works on lazy bytestrings" L.empty+ test "works on Vector" (V.singleton (1 :: Int))+ test "works on SVector" (VS.singleton (1 :: Int))+ test "works on UVector" (U.singleton (1 :: Int))+ test "works on Seq" (Seq.fromList [1 :: Int])++ describe "groupAllOn" $ do+ it "works on lists" $+ groupAllOn (`mod` 3) ([1..9] :: [Int]) @?= [[1, 4, 7], [2, 5, 8], [3, 6, 9]]++ describe "breakWord" $ do+ let test x y z = it (show (x, y, z)) $ breakWord (x :: Text) @?= (y, z)+ test "hello world" "hello" "world"+ test "hello world" "hello" "world"+ test "hello\r\nworld" "hello" "world"+ test "hello there world" "hello" "there world"+ test "" "" ""+ test "hello \n\r\t" "hello" ""++ describe "breakLine" $ do+ let test x y z = it (show (x, y, z)) $ breakLine (x :: Text) @?= (y, z)+ test "hello world" "hello world" ""+ test "hello\r\n world" "hello" " world"+ test "hello\n world" "hello" " world"+ test "hello\r world" "hello\r world" ""+ test "hello\r\nworld" "hello" "world"+ test "hello\r\nthere\nworld" "hello" "there\nworld"+ test "hello\n\r\nworld" "hello" "\r\nworld"+ test "" "" ""++ describe "omapM_" $ do+ let test typ dummy = prop typ $ \input ->+ input @?= execWriter (omapM_ (tell . return) (fromListAs input dummy))+ test "works on strict bytestrings" S.empty+ test "works on lazy bytestrings" L.empty+ test "works on strict texts" T.empty+ test "works on lazy texts" TL.empty++ describe "NonNull" $ do+ describe "fromNonEmpty" $ do+ prop "toMinList" $ \(NonEmpty' ne) ->+ (NE.toList ne :: [Int]) @?= NN.toNullable (NN.toMinList ne)+ describe "toNonEmpty" $ do+ it "converts nonnull to nonempty" $ do+ NN.toNonEmpty (NN.impureNonNull [1,2,3]) @?= NE.fromList [1,2,3]++ describe "mapNonNull" $ do+ prop "mapNonNull id == id" $ \x xs ->+ let nonNull = NN.ncons x (xs :: [Int])+ in NN.mapNonNull Prelude.id nonNull @?= nonNull+ prop "mapNonNull (f . g) == mapNonNull f . mapNonNull g" $+ \(Fn (f :: Integer -> String)) (Fn (g :: Int -> Integer)) x xs ->+ let nns = NN.ncons x (xs :: [Int])+ in NN.mapNonNull (f . g) nns @?= NN.mapNonNull f (NN.mapNonNull g nns)++ let -- | Type restricted 'NN.ncons'+ nconsAs :: IsSequence seq => Element seq -> [Element seq] -> seq -> NN.NonNull seq+ nconsAs x xs _ = NN.ncons x (fromList xs)++ test :: (IsSequence typ, Ord (Element typ), Arbitrary (Element typ), Show (Element typ), Show typ, Eq typ, Eq (Element typ))+ => String -> typ -> Spec+ test typ du = describe typ $ do+ prop "head" $ \x xs ->+ NN.head (nconsAs x xs du) @?= x+ prop "tail" $ \x xs ->+ NN.tail (nconsAs x xs du) @?= fromList xs+ prop "last" $ \x xs ->+ NN.last (reverse $ nconsAs x xs du) @?= x+ prop "init" $ \x xs ->+ NN.init (reverse $ nconsAs x xs du) @?= reverse (fromList xs)+ prop "maximum" $ \x xs ->+ NN.maximum (nconsAs x xs du) @?= Prelude.maximum (x:xs)+ prop "maximumBy" $ \x xs ->+ NN.maximumBy compare (nconsAs x xs du) @?= Prelude.maximum (x:xs)+ prop "minimum" $ \x xs ->+ NN.minimum (nconsAs x xs du) @?= Prelude.minimum (x:xs)+ prop "minimumBy" $ \x xs ->+ NN.minimumBy compare (nconsAs x xs du) @?= Prelude.minimum (x:xs)+ prop "ofoldMap1" $ \x xs ->+ SG.getMax (NN.ofoldMap1 SG.Max $ nconsAs x xs du) @?= Prelude.maximum (x:xs)+ prop "ofoldr1" $ \x xs ->+ NN.ofoldr1 Prelude.min (nconsAs x xs du) @?= Prelude.minimum (x:xs)+ prop "ofoldl1'" $ \x xs ->+ NN.ofoldl1' Prelude.min (nconsAs x xs du) @?= Prelude.minimum (x:xs)++ test "Strict ByteString" S.empty+ test "Lazy ByteString" L.empty+ test "Strict Text" T.empty+ test "Lazy Text" TL.empty+ test "Vector" (V.empty :: V.Vector Int)+ test "Unboxed Vector" (U.empty :: U.Vector Int)+ test "Storable Vector" (VS.empty :: VS.Vector Int)+ test "List" ([5 :: Int])++ describe "Containers" $ do+ let test typ dummy xlookup xinsert xdelete = describe typ $ do+ prop "difference" $ \(DuplPairs xs) (DuplPairs ys) ->+ let m1 = mapFromList xs `difference` mapFromList ys+ m2 = mapFromListAs (xs `difference` ys) dummy+ in m1 @?= m2++ prop "lookup" $ \(DuplPairs xs) -> indexIn xs $ \k ->+ let m = mapFromListAs xs dummy+ v1 = lookup k m+ in do+ v1 @?= lookup k xs+ v1 @?= xlookup k m++ prop "insert" $ \(DuplPairs xs) v -> indexIn xs $ \k ->+ let m = mapFromListAs xs dummy+ m1 = insertMap k v m+ in do+ m1 @?= mapFromList (insertMap k v xs)+ m1 @?= xinsert k v m++ prop "delete" $ \(DuplPairs xs) -> indexIn xs $ \k ->+ let m = mapFromListAs xs dummy+ m1 = deleteMap k m+ in do+ m1 @?= mapFromList (deleteMap k xs)+ m1 @?= xdelete k m++ prop "singletonMap" $ \k v ->+ singletonMap k v @?= (mapFromListAs [(k, v)] dummy)++ prop "findWithDefault" $ \(DuplPairs xs) k v ->+ findWithDefault v k (mapFromListAs xs dummy)+ @?= findWithDefault v k xs++ prop "insertWith" $ \(DuplPairs xs) k v ->+ insertWith (+) k v (mapFromListAs xs dummy)+ @?= mapFromList (insertWith (+) k v xs)++ prop "insertWithKey" $ \(DuplPairs xs) k v ->+ let m = mapFromListAs xs dummy+ f x y z = x + y + z+ in insertWithKey f k v m+ @?= mapFromList (insertWithKey f k v xs)++ prop "insertLookupWithKey" $ \(DuplPairs xs) k v ->+ let m = mapFromListAs xs dummy+ f x y z = x + y + z+ in insertLookupWithKey f k v m @?=+ second mapFromList (insertLookupWithKey f k v xs)++ prop "adjustMap" $ \(DuplPairs xs) k ->+ adjustMap succ k (mapFromListAs xs dummy)+ @?= mapFromList (adjustMap succ k xs)++ prop "adjustWithKey" $ \(DuplPairs xs) k ->+ adjustWithKey (+) k (mapFromListAs xs dummy)+ @?= mapFromList (adjustWithKey (+) k xs)++ prop "updateMap" $ \(DuplPairs xs) k ->+ let f i = if i < 0 then Nothing else Just $ i * 2+ in updateMap f k (mapFromListAs xs dummy)+ @?= mapFromList (updateMap f k xs)++ prop "updateWithKey" $ \(DuplPairs xs) k' ->+ let f k i = if i < 0 then Nothing else Just $ i * k+ in updateWithKey f k' (mapFromListAs xs dummy)+ @?= mapFromList (updateWithKey f k' xs)++ prop "updateLookupWithKey" $ \(DuplPairs xs) k' ->+ let f k i = if i < 0 then Nothing else Just $ i * k+ in updateLookupWithKey f k' (mapFromListAs xs dummy)+ @?= second mapFromList (updateLookupWithKey f k' xs)++ prop "alter" $ \(DuplPairs xs) k ->+ let m = mapFromListAs xs dummy+ f Nothing = Just (-1)+ f (Just i) = if i < 0 then Nothing else Just (i * 2)+ in lookup k (alterMap f k m) @?= f (lookup k m)++ prop "unionWith" $ \(DuplPairs xs) (DuplPairs ys) ->+ let m1 = unionWith (+)+ (mapFromListAs xs dummy)+ (mapFromListAs ys dummy)+ m2 = mapFromList (unionWith (+) xs ys)+ in m1 @?= m2++ prop "unionWithKey" $ \(DuplPairs xs) (DuplPairs ys) ->+ let f k x y = k + x + y+ m1 = unionWithKey f+ (mapFromListAs xs dummy)+ (mapFromListAs ys dummy)+ m2 = mapFromList (unionWithKey f xs ys)+ in m1 @?= m2++ prop "unionsWith" $ \(SmallList xss) ->+ let duplXss = map unDupl xss+ ms = map mapFromList duplXss `asTypeOf` [dummy]+ in unionsWith (+) ms+ @?= mapFromList (unionsWith (+) duplXss)++ prop "mapWithKey" $ \(DuplPairs xs) ->+ let m1 = mapWithKey (+) (mapFromList xs) `asTypeOf` dummy+ m2 = mapFromList $ mapWithKey (+) xs+ in m1 @?= m2++ prop "omapKeysWith" $ \(DuplPairs xs) ->+ let f = flip mod 5+ m1 = omapKeysWith (+) f (mapFromList xs) `asTypeOf` dummy+ m2 = mapFromList $ omapKeysWith (+) f xs+ in m1 @?= m2++ test "Data.Map" (Map.empty :: Map.Map Int Int)+ Map.lookup Map.insert Map.delete+ test "Data.IntMap" (IntMap.empty :: IntMap.IntMap Int)+ IntMap.lookup IntMap.insert IntMap.delete+ test "Data.HashMap" (HashMap.empty :: HashMap.HashMap Int Int)+ HashMap.lookup HashMap.insert HashMap.delete++ describe "Foldl Integration" $ do+ prop "vector" $ \xs -> do+#if MIN_VERSION_foldl(1,3,0)+ let x1 = Foldl.fold Foldl.vector (xs :: [Int])+ x2 = Foldl.purely ofoldlUnwrap Foldl.vector xs+#else+ x1 <- Foldl.foldM Foldl.vector (xs :: [Int])+ x2 <- Foldl.impurely ofoldMUnwrap Foldl.vector xs+#endif+ x2 @?= (x1 :: V.Vector Int)+ prop "length" $ \xs -> do+ let x1 = Foldl.fold Foldl.length (xs :: [Int])+ x2 = Foldl.purely ofoldlUnwrap Foldl.length xs+ x2 @?= x1++ describe "Replacing" $ do+ let test typ dummy = describe typ $ do+ prop "replaceElem old new === omap (\\x -> if x == old then new else x)" $+ -- replace random element or any random value with random new value+ \x list new -> forAll (elements (x:list)) $ \old ->+ let seq' = fromListAs list dummy+ in replaceElem old new seq' @?= omap (\x' -> if x' == old then new else x') seq'+#if MIN_VERSION_QuickCheck(2,8,0)+ prop "replaceSeq old new === ointercalate new . splitSeq old" $+ -- replace random subsequence with random new sequence+ \list new -> forAll (sublistOf list) $ \old ->+ let [seq', old', new'] = map (`fromListAs` dummy) [list, old, new]+ in replaceSeq old' new' seq' @?= ointercalate new' (splitSeq old' seq')+ prop "replaceSeq old old === id" $ \list -> forAll (sublistOf list) $ \old ->+ let [seq', old'] = map (`fromListAs` dummy) [list, old]+ in replaceSeq old' old' seq' @?= seq'+#endif+ test "List" ([] :: [Int])+ test "Vector" (V.empty :: V.Vector Int)+ test "Storable Vector" (VS.empty :: VS.Vector Int)+ test "Unboxed Vector" (U.empty :: U.Vector Int)+ test "Strict ByteString" S.empty+ test "Lazy ByteString" L.empty+ test "Strict Text" T.empty+ test "Lazy Text" TL.empty++ describe "Sorting" $ do+ let test typ dummy = describe typ $ do+ prop "sortBy" $ \input -> do+ let f x y = compare y x+ fromList (sortBy f input) @?= sortBy f (fromListAs input dummy)+ prop "sort" $ \input ->+ fromList (sort input) @?= sort (fromListAs input dummy)+ test "List" ([] :: [Int])+ test "Vector" (V.empty :: V.Vector Int)+ test "Storable Vector" (VS.empty :: VS.Vector Int)+ test "Unboxed Vector" (U.empty :: U.Vector Int)+ test "Strict ByteString" S.empty+ test "Lazy ByteString" L.empty+ test "Strict Text" T.empty+ test "Lazy Text" TL.empty++ describe "Intercalate" $ do+ let test typ dummy = describe typ $ do+ prop "intercalate === defaultIntercalate" $ \list lists ->+ let seq' = fromListAs list dummy+ seqs = map (`fromListAs` dummy) lists+ in ointercalate seq' seqs @?= fromList (List.intercalate list lists)+ test "List" ([] :: [Int])+ test "Vector" (V.empty :: V.Vector Int)+ test "Storable Vector" (VS.empty :: VS.Vector Int)+ test "Unboxed Vector" (U.empty :: U.Vector Int)+ test "Strict ByteString" S.empty+ test "Lazy ByteString" L.empty+ test "Strict Text" T.empty+ test "Lazy Text" TL.empty++ describe "Splitting" $ do+ let test typ dummy = describe typ $ do+ let fromList' = (`fromListAs` dummy)+ let fromSepList sep = fromList' . map (fromMaybe sep)+ prop "intercalate sep . splitSeq sep === id" $+ \(fromList' -> sep) ->+ \(mconcat . map (maybe sep fromList') -> xs) ->+ ointercalate sep (splitSeq sep xs) @?= xs+ prop "splitSeq mempty xs === mempty : map singleton (otoList xs)" $+ \input ->+ splitSeq mempty (fromList' input) @?= mempty : map singleton input+ prop "splitSeq _ mempty == [mempty]" $+ \(fromList' -> sep) ->+ splitSeq sep mempty @?= [mempty]+ prop "intercalate (singleton sep) . splitElem sep === id" $+ \sep -> \(fromSepList sep -> xs) ->+ ointercalate (singleton sep) (splitElem sep xs) @?= xs+ prop "length . splitElem sep === succ . length . filter (== sep)" $+ \sep -> \(fromSepList sep -> xs) ->+ olength (splitElem sep xs) @?= olength (filter (== sep) xs) + 1+ prop "splitElem sep (replicate n sep) == replicate (n+1) mempty" $+ \(NonNegative n) sep ->+ splitElem sep (fromList' (replicate n sep)) @?= replicate (n + 1) mempty+ prop "splitElem sep === splitWhen (== sep)" $+ \sep -> \(fromSepList sep -> xs) ->+ splitElem sep xs @?= splitWhen (== sep) xs+ prop "splitElem sep === splitSeq (singleton sep)" $+ \sep -> \(fromSepList sep -> xs) ->+ splitElem sep xs @?= splitSeq (singleton sep) xs+ test "List" ([] :: [Int])+ test "Vector" (V.empty :: V.Vector Int)+ test "Storable Vector" (VS.empty :: VS.Vector Int)+ test "Unboxed Vector" (U.empty :: U.Vector Int)+ test "Strict ByteString" S.empty+ test "Lazy ByteString" L.empty+ test "Strict Text" T.empty+ test "Lazy Text" TL.empty++ describe "Other Issues" $ do+ it "#26 headEx on a list works" $+ headEx (1 : filter Prelude.odd [2,4..]) @?= (1 :: Int)++ it "#31 find doesn't infinitely loop on NonEmpty" $+ find (== "a") ("a" NE.:| ["d","fgf"]) @?= Just ("a" :: String)++ it "#83 head on Seq works correctly" $ do+ headEx (Seq.fromList [1 :: Int,2,3]) @?= (1 :: Int)+ headMay (Seq.fromList [] :: Seq.Seq Int) @?= Nothing
− test/Spec.hs
@@ -1,502 +0,0 @@-{-# LANGUAGE GADTs #-}-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE ViewPatterns #-}-{-# LANGUAGE CPP #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE PatternSynonyms #-}--module Spec where--import Data.MonoTraversable-import Data.Containers-import Data.Sequences-import qualified Data.Sequence as Seq-import qualified Data.NonNull as NN-import Data.Monoid (mempty, mconcat)-import Data.Maybe (fromMaybe)-import qualified Data.List as List--import Test.Hspec-import Test.Hspec.QuickCheck-import Test.HUnit ((@?=))-import Test.QuickCheck hiding (NonEmptyList(..))-import Test.QuickCheck.Function (pattern Fn)-import qualified Test.QuickCheck.Modifiers as QCM--import Data.Text (Text)-import qualified Data.Text as T-import qualified Data.Text.Lazy as TL-import qualified Data.ByteString as S-import qualified Data.ByteString.Lazy as L-import qualified Data.Vector as V-import qualified Data.Vector.Unboxed as U-import qualified Data.Vector.Storable as VS-import qualified Data.List.NonEmpty as NE-import qualified Data.Semigroup as SG-import qualified Data.Map as Map-import qualified Data.IntMap as IntMap-import qualified Data.HashMap.Strict as HashMap-import qualified Data.Set as Set-import qualified Control.Foldl as Foldl--import Control.Arrow (second)-import Control.Applicative-import Control.Monad.Trans.Writer--import Prelude (Bool (..), ($), IO, Eq (..), fromIntegral, Ord (..), String, mod, Int, Integer, show,- return, asTypeOf, (.), Show, (+), succ, Maybe (..), (*), mod, map, flip, otherwise, (-), div, maybe)-import qualified Prelude--newtype NonEmpty' a = NonEmpty' (NE.NonEmpty a)- deriving (Show, Eq)-instance Arbitrary a => Arbitrary (NonEmpty' a) where- arbitrary = NonEmpty' <$> ((NE.:|) <$> arbitrary <*> arbitrary)---- | Arbitrary newtype for key-value pairs without any duplicate keys--- and is not empty-newtype DuplPairs k v = DuplPairs { unDupl :: [(k,v)] }- deriving (Eq, Show)--removeDuplicateKeys :: Ord k => [(k,v)] -> [(k,v)]-removeDuplicateKeys m = go Set.empty m- where go _ [] = []- go used ((k,v):xs)- | k `member` used = go used xs- | otherwise = (k,v) : go (insertSet k used) xs--instance (Arbitrary k, Arbitrary v, Ord k, Eq v) => Arbitrary (DuplPairs k v) where- arbitrary = DuplPairs . removeDuplicateKeys <$> arbitrary `suchThat` (/= [])- shrink (DuplPairs xs) =- map (DuplPairs . removeDuplicateKeys) $ filter (/= []) $ shrink xs---- | Arbitrary newtype for small lists whose length is <= 10------ Used for testing 'unionsWith'-newtype SmallList a = SmallList { getSmallList :: [a] }- deriving (Eq, Show, Ord)--instance (Arbitrary a) => Arbitrary (SmallList a) where- arbitrary = SmallList <$> arbitrary `suchThat` ((<= 10) . olength)- shrink (SmallList xs) =- map SmallList $ filter ((<= 10) . olength) $ shrink xs---- | Choose a random key from a key-value pair list-indexIn :: (Show k, Testable prop) => [(k,v)] -> (k -> prop) -> Property-indexIn = forAll . elements . map Prelude.fst---- | Type restricted 'fromList'-fromListAs :: IsSequence a => [Element a] -> a -> a-fromListAs xs _ = fromList xs---- | Type restricted 'mapFromListAs'-mapFromListAs :: IsMap a => [(ContainerKey a, MapValue a)] -> a -> a-mapFromListAs xs _ = mapFromList xs--main :: IO ()-main = hspec $ do- describe "onull" $ do- it "works on empty lists" $ onull [] @?= True- it "works on non-empty lists" $ onull [()] @?= False- it "works on empty texts" $ onull ("" :: Text) @?= True- it "works on non-empty texts" $ onull ("foo" :: Text) @?= False-- describe "osum" $ do- prop "works on lists" $ \(Small x) (Small y) ->- y >= x ==> osum [x..y] @?= ((x + y) * (y - x + 1) `div` (2 :: Int))-- describe "oproduct" $ do- prop "works on lists" $ \(Positive x) (Positive y) ->- let fact n = oproduct [1..n]- in (y :: Integer) > (x :: Integer) ==>- oproduct [x..y] @?= fact y `div` fact (x - 1)-- describe "olength" $ do- prop "works on lists" $ \(NonNegative i) ->- olength (replicate i () :: [()]) @?= i- prop "works on texts" $ \(NonNegative i) ->- olength (replicate i 'a' :: Text) @?= i- prop "works on lazy bytestrings" $ \(NonNegative (Small i)) ->- olength64 (replicate i 6 :: L.ByteString) @?= i-- describe "omap" $ do- prop "works on lists" $ \xs ->- omap (+1) xs @?= map (+1) (xs :: [Int])- prop "works on lazy bytestrings" $ \xs ->- omap (+1) (fromList xs :: L.ByteString) @?= fromList (map (+1) xs)- prop "works on texts" $ \xs ->- omap succ (fromList xs :: Text) @?= fromList (map succ xs)-- describe "oconcatMap" $ do- prop "works on lists" $ \xs ->- oconcatMap (: []) xs @?= (xs :: [Int])-- describe "ocompareLength" $ do- prop "works on lists" $ \(Positive i) j ->- ocompareLength (replicate i () :: [()]) j @?= compare i j-- describe "groupAll" $ do- it "works on lists" $ groupAll ("abcabcabc" :: String) @?= ["aaa", "bbb", "ccc"]- it "works on texts" $ groupAll ("abcabcabc" :: Text) @?= ["aaa", "bbb", "ccc"]-- describe "unsnoc" $ do- let test name dummy = prop name $ \(QCM.NonEmpty xs) ->- let seq' = fromListAs xs dummy- in case unsnoc seq' of- Just (y, z) -> do- y SG.<> singleton z @?= seq'- snoc y z @?= seq'- otoList (snoc y z) @?= xs- Nothing -> expectationFailure "unsnoc returned Nothing"- test "works on lists" ([] :: [Int])- test "works on texts" ("" :: Text)- test "works on lazy bytestrings" L.empty-- describe "index" $ do- let test name dummy = prop name $- \i' (QCM.NonEmpty xs) ->- let seq' = fromListAs xs dummy- mx = index xs (fromIntegral i)- i = fromIntegral (i' :: Int)- in do- mx @?= index seq' i- case mx of- Nothing -> return ()- Just x -> indexEx seq' i @?= x- test "works on lists" ([] :: [Int])- test "works on strict texts" ("" :: Text)- test "works on lazy texts" ("" :: TL.Text)- test "works on strict bytestrings" S.empty- test "works on lazy bytestrings" L.empty- test "works on Vector" (V.singleton (1 :: Int))- test "works on SVector" (VS.singleton (1 :: Int))- test "works on UVector" (U.singleton (1 :: Int))- test "works on Seq" (Seq.fromList [1 :: Int])-- describe "groupAllOn" $ do- it "works on lists" $- groupAllOn (`mod` 3) ([1..9] :: [Int]) @?= [[1, 4, 7], [2, 5, 8], [3, 6, 9]]-- describe "breakWord" $ do- let test x y z = it (show (x, y, z)) $ breakWord (x :: Text) @?= (y, z)- test "hello world" "hello" "world"- test "hello world" "hello" "world"- test "hello\r\nworld" "hello" "world"- test "hello there world" "hello" "there world"- test "" "" ""- test "hello \n\r\t" "hello" ""-- describe "breakLine" $ do- let test x y z = it (show (x, y, z)) $ breakLine (x :: Text) @?= (y, z)- test "hello world" "hello world" ""- test "hello\r\n world" "hello" " world"- test "hello\n world" "hello" " world"- test "hello\r world" "hello\r world" ""- test "hello\r\nworld" "hello" "world"- test "hello\r\nthere\nworld" "hello" "there\nworld"- test "hello\n\r\nworld" "hello" "\r\nworld"- test "" "" ""-- describe "omapM_" $ do- let test typ dummy = prop typ $ \input ->- input @?= execWriter (omapM_ (tell . return) (fromListAs input dummy))- test "works on strict bytestrings" S.empty- test "works on lazy bytestrings" L.empty- test "works on strict texts" T.empty- test "works on lazy texts" TL.empty-- describe "NonNull" $ do- describe "fromNonEmpty" $ do- prop "toMinList" $ \(NonEmpty' ne) ->- (NE.toList ne :: [Int]) @?= NN.toNullable (NN.toMinList ne)- describe "toNonEmpty" $ do- it "converts nonnull to nonempty" $ do- NN.toNonEmpty (NN.impureNonNull [1,2,3]) @?= NE.fromList [1,2,3]-- describe "mapNonNull" $ do- prop "mapNonNull id == id" $ \x xs ->- let nonNull = NN.ncons x (xs :: [Int])- in NN.mapNonNull Prelude.id nonNull @?= nonNull- prop "mapNonNull (f . g) == mapNonNull f . mapNonNull g" $- \(Fn (f :: Integer -> String)) (Fn (g :: Int -> Integer)) x xs ->- let nns = NN.ncons x (xs :: [Int])- in NN.mapNonNull (f . g) nns @?= NN.mapNonNull f (NN.mapNonNull g nns)-- let -- | Type restricted 'NN.ncons'- nconsAs :: IsSequence seq => Element seq -> [Element seq] -> seq -> NN.NonNull seq- nconsAs x xs _ = NN.ncons x (fromList xs)-- test :: (IsSequence typ, Ord (Element typ), Arbitrary (Element typ), Show (Element typ), Show typ, Eq typ, Eq (Element typ))- => String -> typ -> Spec- test typ du = describe typ $ do- prop "head" $ \x xs ->- NN.head (nconsAs x xs du) @?= x- prop "tail" $ \x xs ->- NN.tail (nconsAs x xs du) @?= fromList xs- prop "last" $ \x xs ->- NN.last (reverse $ nconsAs x xs du) @?= x- prop "init" $ \x xs ->- NN.init (reverse $ nconsAs x xs du) @?= reverse (fromList xs)- prop "maximum" $ \x xs ->- NN.maximum (nconsAs x xs du) @?= Prelude.maximum (x:xs)- prop "maximumBy" $ \x xs ->- NN.maximumBy compare (nconsAs x xs du) @?= Prelude.maximum (x:xs)- prop "minimum" $ \x xs ->- NN.minimum (nconsAs x xs du) @?= Prelude.minimum (x:xs)- prop "minimumBy" $ \x xs ->- NN.minimumBy compare (nconsAs x xs du) @?= Prelude.minimum (x:xs)- prop "ofoldMap1" $ \x xs ->- SG.getMax (NN.ofoldMap1 SG.Max $ nconsAs x xs du) @?= Prelude.maximum (x:xs)- prop "ofoldr1" $ \x xs ->- NN.ofoldr1 Prelude.min (nconsAs x xs du) @?= Prelude.minimum (x:xs)- prop "ofoldl1'" $ \x xs ->- NN.ofoldl1' Prelude.min (nconsAs x xs du) @?= Prelude.minimum (x:xs)-- test "Strict ByteString" S.empty- test "Lazy ByteString" L.empty- test "Strict Text" T.empty- test "Lazy Text" TL.empty- test "Vector" (V.empty :: V.Vector Int)- test "Unboxed Vector" (U.empty :: U.Vector Int)- test "Storable Vector" (VS.empty :: VS.Vector Int)- test "List" ([5 :: Int])-- describe "Containers" $ do- let test typ dummy xlookup xinsert xdelete = describe typ $ do- prop "difference" $ \(DuplPairs xs) (DuplPairs ys) ->- let m1 = mapFromList xs `difference` mapFromList ys- m2 = mapFromListAs (xs `difference` ys) dummy- in m1 @?= m2-- prop "lookup" $ \(DuplPairs xs) -> indexIn xs $ \k ->- let m = mapFromListAs xs dummy- v1 = lookup k m- in do- v1 @?= lookup k xs- v1 @?= xlookup k m-- prop "insert" $ \(DuplPairs xs) v -> indexIn xs $ \k ->- let m = mapFromListAs xs dummy- m1 = insertMap k v m- in do- m1 @?= mapFromList (insertMap k v xs)- m1 @?= xinsert k v m-- prop "delete" $ \(DuplPairs xs) -> indexIn xs $ \k ->- let m = mapFromListAs xs dummy- m1 = deleteMap k m- in do- m1 @?= mapFromList (deleteMap k xs)- m1 @?= xdelete k m-- prop "singletonMap" $ \k v ->- singletonMap k v @?= (mapFromListAs [(k, v)] dummy)-- prop "findWithDefault" $ \(DuplPairs xs) k v ->- findWithDefault v k (mapFromListAs xs dummy)- @?= findWithDefault v k xs-- prop "insertWith" $ \(DuplPairs xs) k v ->- insertWith (+) k v (mapFromListAs xs dummy)- @?= mapFromList (insertWith (+) k v xs)-- prop "insertWithKey" $ \(DuplPairs xs) k v ->- let m = mapFromListAs xs dummy- f x y z = x + y + z- in insertWithKey f k v m- @?= mapFromList (insertWithKey f k v xs)-- prop "insertLookupWithKey" $ \(DuplPairs xs) k v ->- let m = mapFromListAs xs dummy- f x y z = x + y + z- in insertLookupWithKey f k v m @?=- second mapFromList (insertLookupWithKey f k v xs)-- prop "adjustMap" $ \(DuplPairs xs) k ->- adjustMap succ k (mapFromListAs xs dummy)- @?= mapFromList (adjustMap succ k xs)-- prop "adjustWithKey" $ \(DuplPairs xs) k ->- adjustWithKey (+) k (mapFromListAs xs dummy)- @?= mapFromList (adjustWithKey (+) k xs)-- prop "updateMap" $ \(DuplPairs xs) k ->- let f i = if i < 0 then Nothing else Just $ i * 2- in updateMap f k (mapFromListAs xs dummy)- @?= mapFromList (updateMap f k xs)-- prop "updateWithKey" $ \(DuplPairs xs) k' ->- let f k i = if i < 0 then Nothing else Just $ i * k- in updateWithKey f k' (mapFromListAs xs dummy)- @?= mapFromList (updateWithKey f k' xs)-- prop "updateLookupWithKey" $ \(DuplPairs xs) k' ->- let f k i = if i < 0 then Nothing else Just $ i * k- in updateLookupWithKey f k' (mapFromListAs xs dummy)- @?= second mapFromList (updateLookupWithKey f k' xs)-- prop "alter" $ \(DuplPairs xs) k ->- let m = mapFromListAs xs dummy- f Nothing = Just (-1)- f (Just i) = if i < 0 then Nothing else Just (i * 2)- in lookup k (alterMap f k m) @?= f (lookup k m)-- prop "unionWith" $ \(DuplPairs xs) (DuplPairs ys) ->- let m1 = unionWith (+)- (mapFromListAs xs dummy)- (mapFromListAs ys dummy)- m2 = mapFromList (unionWith (+) xs ys)- in m1 @?= m2-- prop "unionWithKey" $ \(DuplPairs xs) (DuplPairs ys) ->- let f k x y = k + x + y- m1 = unionWithKey f- (mapFromListAs xs dummy)- (mapFromListAs ys dummy)- m2 = mapFromList (unionWithKey f xs ys)- in m1 @?= m2-- prop "unionsWith" $ \(SmallList xss) ->- let duplXss = map unDupl xss- ms = map mapFromList duplXss `asTypeOf` [dummy]- in unionsWith (+) ms- @?= mapFromList (unionsWith (+) duplXss)-- prop "mapWithKey" $ \(DuplPairs xs) ->- let m1 = mapWithKey (+) (mapFromList xs) `asTypeOf` dummy- m2 = mapFromList $ mapWithKey (+) xs- in m1 @?= m2-- prop "omapKeysWith" $ \(DuplPairs xs) ->- let f = flip mod 5- m1 = omapKeysWith (+) f (mapFromList xs) `asTypeOf` dummy- m2 = mapFromList $ omapKeysWith (+) f xs- in m1 @?= m2-- test "Data.Map" (Map.empty :: Map.Map Int Int)- Map.lookup Map.insert Map.delete- test "Data.IntMap" (IntMap.empty :: IntMap.IntMap Int)- IntMap.lookup IntMap.insert IntMap.delete- test "Data.HashMap" (HashMap.empty :: HashMap.HashMap Int Int)- HashMap.lookup HashMap.insert HashMap.delete-- describe "Foldl Integration" $ do- prop "vector" $ \xs -> do-#if MIN_VERSION_foldl(1,3,0)- let x1 = Foldl.fold Foldl.vector (xs :: [Int])- x2 = Foldl.purely ofoldlUnwrap Foldl.vector xs-#else- x1 <- Foldl.foldM Foldl.vector (xs :: [Int])- x2 <- Foldl.impurely ofoldMUnwrap Foldl.vector xs-#endif- x2 @?= (x1 :: V.Vector Int)- prop "length" $ \xs -> do- let x1 = Foldl.fold Foldl.length (xs :: [Int])- x2 = Foldl.purely ofoldlUnwrap Foldl.length xs- x2 @?= x1-- describe "Replacing" $ do- let test typ dummy = describe typ $ do- prop "replaceElem old new === omap (\\x -> if x == old then new else x)" $- -- replace random element or any random value with random new value- \x list new -> forAll (elements (x:list)) $ \old ->- let seq' = fromListAs list dummy- in replaceElem old new seq' @?= omap (\x' -> if x' == old then new else x') seq'-#if MIN_VERSION_QuickCheck(2,8,0)- prop "replaceSeq old new === ointercalate new . splitSeq old" $- -- replace random subsequence with random new sequence- \list new -> forAll (sublistOf list) $ \old ->- let [seq', old', new'] = map (`fromListAs` dummy) [list, old, new]- in replaceSeq old' new' seq' @?= ointercalate new' (splitSeq old' seq')- prop "replaceSeq old old === id" $ \list -> forAll (sublistOf list) $ \old ->- let [seq', old'] = map (`fromListAs` dummy) [list, old]- in replaceSeq old' old' seq' @?= seq'-#endif- test "List" ([] :: [Int])- test "Vector" (V.empty :: V.Vector Int)- test "Storable Vector" (VS.empty :: VS.Vector Int)- test "Unboxed Vector" (U.empty :: U.Vector Int)- test "Strict ByteString" S.empty- test "Lazy ByteString" L.empty- test "Strict Text" T.empty- test "Lazy Text" TL.empty-- describe "Sorting" $ do- let test typ dummy = describe typ $ do- prop "sortBy" $ \input -> do- let f x y = compare y x- fromList (sortBy f input) @?= sortBy f (fromListAs input dummy)- prop "sort" $ \input ->- fromList (sort input) @?= sort (fromListAs input dummy)- test "List" ([] :: [Int])- test "Vector" (V.empty :: V.Vector Int)- test "Storable Vector" (VS.empty :: VS.Vector Int)- test "Unboxed Vector" (U.empty :: U.Vector Int)- test "Strict ByteString" S.empty- test "Lazy ByteString" L.empty- test "Strict Text" T.empty- test "Lazy Text" TL.empty-- describe "Intercalate" $ do- let test typ dummy = describe typ $ do- prop "intercalate === defaultIntercalate" $ \list lists ->- let seq' = fromListAs list dummy- seqs = map (`fromListAs` dummy) lists- in ointercalate seq' seqs @?= fromList (List.intercalate list lists)- test "List" ([] :: [Int])- test "Vector" (V.empty :: V.Vector Int)- test "Storable Vector" (VS.empty :: VS.Vector Int)- test "Unboxed Vector" (U.empty :: U.Vector Int)- test "Strict ByteString" S.empty- test "Lazy ByteString" L.empty- test "Strict Text" T.empty- test "Lazy Text" TL.empty-- describe "Splitting" $ do- let test typ dummy = describe typ $ do- let fromList' = (`fromListAs` dummy)- let fromSepList sep = fromList' . map (fromMaybe sep)- prop "intercalate sep . splitSeq sep === id" $- \(fromList' -> sep) ->- \(mconcat . map (maybe sep fromList') -> xs) ->- ointercalate sep (splitSeq sep xs) @?= xs- prop "splitSeq mempty xs === mempty : map singleton (otoList xs)" $- \input ->- splitSeq mempty (fromList' input) @?= mempty : map singleton input- prop "splitSeq _ mempty == [mempty]" $- \(fromList' -> sep) ->- splitSeq sep mempty @?= [mempty]- prop "intercalate (singleton sep) . splitElem sep === id" $- \sep -> \(fromSepList sep -> xs) ->- ointercalate (singleton sep) (splitElem sep xs) @?= xs- prop "length . splitElem sep === succ . length . filter (== sep)" $- \sep -> \(fromSepList sep -> xs) ->- olength (splitElem sep xs) @?= olength (filter (== sep) xs) + 1- prop "splitElem sep (replicate n sep) == replicate (n+1) mempty" $- \(NonNegative n) sep ->- splitElem sep (fromList' (replicate n sep)) @?= replicate (n + 1) mempty- prop "splitElem sep === splitWhen (== sep)" $- \sep -> \(fromSepList sep -> xs) ->- splitElem sep xs @?= splitWhen (== sep) xs- prop "splitElem sep === splitSeq (singleton sep)" $- \sep -> \(fromSepList sep -> xs) ->- splitElem sep xs @?= splitSeq (singleton sep) xs- test "List" ([] :: [Int])- test "Vector" (V.empty :: V.Vector Int)- test "Storable Vector" (VS.empty :: VS.Vector Int)- test "Unboxed Vector" (U.empty :: U.Vector Int)- test "Strict ByteString" S.empty- test "Lazy ByteString" L.empty- test "Strict Text" T.empty- test "Lazy Text" TL.empty-- describe "Other Issues" $ do- it "#26 headEx on a list works" $- headEx (1 : filter Prelude.odd [2,4..]) @?= (1 :: Int)-- it "#31 find doesn't infinitely loop on NonEmpty" $- find (== "a") ("a" NE.:| ["d","fgf"]) @?= Just ("a" :: String)-- it "#83 head on Seq works correctly" $ do- headEx (Seq.fromList [1 :: Int,2,3]) @?= (1 :: Int)- headMay (Seq.fromList [] :: Seq.Seq Int) @?= Nothing
− test/main.hs
@@ -1,1 +0,0 @@-import Spec (main)