{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE CPP #-} import Test.Tasty import qualified Test.Tasty.QuickCheck as QC import Test.QuickCheck import Test.QuickCheck.Function import qualified Data.Vector as V import qualified Data.Vector.Split as V import qualified Data.Vector.Split.Internal as V import qualified Data.List as L import qualified Data.List.Split as L import Data.Char import Debug.Trace main :: IO () main = defaultMain tests tests = testGroup "tests" [ testGroup "basic strategies" [ QC.testProperty "oneOf" prop_oneOf , QC.testProperty "onSublist" prop_onSublist , QC.testProperty "whenElt" prop_whenElt ] , testGroup "strategy transformers" [ QC.testProperty "dropDelims" prop_dropDelims , QC.testProperty "keepDelimsL" prop_keepDelimsL , QC.testProperty "keepDelimsR" prop_keepDelimsR , QC.testProperty "condense" prop_condense , QC.testProperty "dropInitBlank" prop_dropInitBlank , QC.testProperty "dropFinalBlank" prop_dropFinalBlank , QC.testProperty "dropInnerBlank" prop_dropInnerBlank ] , testGroup "other splitting methods" [ QC.testProperty "chunksOf" prop_chunksOf , QC.testProperty "splitPlaces" prop_splitPlaces , QC.testProperty "splitPlacesBlanks" prop_splitPlacesBlanks , QC.testProperty "chop" prop_chop , QC.testProperty "chopGroup" prop_chopGroup #if MIN_VERSION_split(2,3,0) , QC.testProperty "divvy" prop_divvy #endif ] , testGroup "convenience functions" [ QC.testProperty "splitOn" prop_splitOn , QC.testProperty "splitOneOf" prop_splitOneOf , QC.testProperty "splitWhen" prop_splitWhen , QC.testProperty "endBy" prop_endBy , QC.testProperty "endByOneOf" prop_endByOneOf , QC.testProperty "wordsBy" prop_wordsBy , QC.testProperty "linesBy" prop_linesBy ] ] -- small set of elements used for testing newtype Elt = Elt { unElt :: Char } deriving (Eq) type Elements = [Elt] type SomeElements = NonEmptyList Elt instance Show Elt where show (Elt c) = show c instance Arbitrary Elt where arbitrary = elements (map Elt "abcde") instance CoArbitrary Elt where coarbitrary = coarbitrary . ord . unElt instance Function Elt where function = functionMap unElt Elt -- Basic Strategies prop_oneOf :: Elements -> Elements -> Property prop_oneOf d = listVsVec (L.split (L.oneOf d)) (V.split (V.oneOf (V.fromList d))) prop_onSublist :: SomeElements -> Elements -> Property prop_onSublist (NonEmpty d) = listVsVec (L.split (L.onSublist d)) (V.split (V.onSublist (V.fromList d))) prop_whenElt :: Fun Elt Bool -> Elements -> Property prop_whenElt (Fun _ f) = listVsVec (L.split (L.whenElt f)) (V.split (V.whenElt f)) -- Strategy Transformers prop_dropDelims :: SomeElements -> Elements -> Property prop_dropDelims (NonEmpty d) = listVsVec (L.split (L.dropDelims (L.oneOf d))) (V.split (V.dropDelims . V.oneOf (V.fromList d))) prop_keepDelimsL :: SomeElements -> Elements -> Property prop_keepDelimsL (NonEmpty d) = listVsVec (L.split (L.keepDelimsL (L.oneOf d))) (V.split (V.keepDelimsL . V.oneOf (V.fromList d))) prop_keepDelimsR :: SomeElements -> Elements -> Property prop_keepDelimsR (NonEmpty d) = listVsVec (L.split (L.keepDelimsR (L.oneOf d))) (V.split (V.keepDelimsR . V.oneOf (V.fromList d))) prop_condense :: SomeElements -> Elements -> Property prop_condense (NonEmpty d) = listVsVec (L.split (L.condense (L.oneOf d))) (V.split (V.condense . V.oneOf (V.fromList d))) prop_dropInitBlank :: SomeElements -> Elements -> Property prop_dropInitBlank (NonEmpty d) = listVsVec (L.split (L.dropInitBlank (L.oneOf d))) (V.split (V.dropInitBlank . V.oneOf (V.fromList d))) prop_dropFinalBlank :: SomeElements -> Elements -> Property prop_dropFinalBlank (NonEmpty d) = listVsVec (L.split (L.dropFinalBlank (L.oneOf d))) (V.split (V.dropFinalBlank . V.oneOf (V.fromList d))) prop_dropInnerBlank :: SomeElements -> Elements -> Property prop_dropInnerBlank (NonEmpty d) = listVsVec (L.split (L.dropInnerBlanks (L.oneOf d))) (V.split (V.dropInnerBlanks . V.oneOf (V.fromList d))) -- Other Splitting Methods prop_chunksOf :: Positive Int -> [Double] -> Property prop_chunksOf (Positive i) = listVsVec (L.chunksOf i) (V.chunksOf i) prop_splitPlaces :: [Positive Int] -> [Double] -> Property prop_splitPlaces is = listVsVec (L.splitPlaces is') (V.splitPlaces is') where is' = map getPositive is prop_splitPlacesBlanks :: [Positive Int] -> [Double] -> Property prop_splitPlacesBlanks is = listVsVec (L.splitPlacesBlanks is') (V.splitPlacesBlanks is') where is' = map getPositive is prop_chop :: [Double] -> Property prop_chop = listVsVec (L.chop (L.splitAt 10)) (V.chop (V.splitAt 10)) prop_chopGroup :: [Double] -> Property prop_chopGroup = listVsVec (L.chop (\xs -> L.span (== L.head xs) xs)) (V.chop (\xs -> V.span (== V.head xs) xs)) #if MIN_VERSION_split(2,3,0) prop_divvy :: Positive Int -> Positive Int -> [Double] -> Property prop_divvy (Positive n) (Positive m) = listVsVec (L.divvy n m) (V.divvy n m) #endif -- Convenience functions prop_splitOneOf :: SomeElements -> Elements -> Property prop_splitOneOf (NonEmpty ds) = listVsVec (L.splitOneOf ds) (V.splitOneOf (V.fromList ds)) prop_splitOn :: SomeElements -> Elements -> Property prop_splitOn (NonEmpty ds) = listVsVec (L.splitOn ds) (V.splitOn (V.fromList ds)) prop_splitWhen :: Fun Elt Bool -> Elements -> Property prop_splitWhen (Fun _ f) = listVsVec (L.splitWhen f) (V.splitWhen f) prop_endBy :: SomeElements -> Elements -> Property prop_endBy (NonEmpty p) = listVsVec (L.endBy p) (V.endBy (V.fromList p)) prop_endByOneOf :: SomeElements -> Elements -> Property prop_endByOneOf (NonEmpty p) = listVsVec (L.endByOneOf p) (V.endByOneOf (V.fromList p)) prop_wordsBy :: Fun Elt Bool -> Elements -> Property prop_wordsBy (Fun _ f) = listVsVec (L.wordsBy f) (V.wordsBy f) prop_linesBy :: Fun Elt Bool -> Elements -> Property prop_linesBy (Fun _ f) = listVsVec (L.linesBy f) (V.linesBy f) -- | compare a list splitting vs a vector splitting function listVsVec :: (Show a, Eq a) => ([a] -> [[a]]) -> (V.Vector a -> [V.Vector a]) -> [a] -> Property listVsVec a b l = ls === map V.toList vs where v = V.fromList l ls = a l vs = b v