|
Packit |
2632c6 |
{-# LANGUAGE FlexibleInstances #-}
|
|
Packit |
2632c6 |
{-# LANGUAGE StandaloneDeriving #-}
|
|
Packit |
2632c6 |
module Main where
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
import Data.List.Split.Internals
|
|
Packit |
2632c6 |
import Test.QuickCheck
|
|
Packit |
2632c6 |
import Test.QuickCheck.Function
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
import Control.Monad
|
|
Packit |
2632c6 |
import System.Environment
|
|
Packit |
2632c6 |
import Text.Printf
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
import Data.Char
|
|
Packit |
2632c6 |
import Data.Functor
|
|
Packit |
2632c6 |
import Data.List (genericTake, group, intercalate,
|
|
Packit |
2632c6 |
isInfixOf, isPrefixOf, isSuffixOf,
|
|
Packit |
2632c6 |
tails)
|
|
Packit |
2632c6 |
import Data.Maybe (isJust)
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
newtype Elt = Elt { unElt :: Char }
|
|
Packit |
2632c6 |
deriving (Eq)
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
instance Show Elt where
|
|
Packit |
2632c6 |
show (Elt c) = show c
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
instance Arbitrary Elt where
|
|
Packit |
2632c6 |
arbitrary = elements (map Elt "abcde")
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
instance CoArbitrary Elt where
|
|
Packit |
2632c6 |
coarbitrary = coarbitrary . ord . unElt
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
instance Function Elt where
|
|
Packit |
2632c6 |
function = functionMap unElt Elt
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
deriving instance Show (Splitter Elt)
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
instance Show (Delimiter Elt) where
|
|
Packit |
2632c6 |
show (Delimiter ps) = show (map function ps)
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
instance (Arbitrary a, CoArbitrary a, Function a) => Arbitrary (Delimiter a) where
|
|
Packit |
2632c6 |
arbitrary = (Delimiter . map apply) <$> arbitrary
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
instance Arbitrary a => Arbitrary (Chunk a) where
|
|
Packit |
2632c6 |
arbitrary = oneof [ liftM Text (listOf arbitrary)
|
|
Packit |
2632c6 |
, liftM Delim (listOf arbitrary)
|
|
Packit |
2632c6 |
]
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
instance Arbitrary DelimPolicy where
|
|
Packit |
2632c6 |
arbitrary = elements [Drop, Keep, KeepLeft, KeepRight]
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
instance Arbitrary CondensePolicy where
|
|
Packit |
2632c6 |
arbitrary = elements [Condense, KeepBlankFields]
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
instance Arbitrary EndPolicy where
|
|
Packit |
2632c6 |
arbitrary = elements [DropBlank, KeepBlank]
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
instance (Arbitrary a, CoArbitrary a, Function a) => Arbitrary (Splitter a) where
|
|
Packit |
2632c6 |
arbitrary = liftM5 Splitter arbitrary arbitrary arbitrary arbitrary arbitrary
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
type Delim a = [Fun a Bool]
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
unDelim :: Delim a -> Delimiter a
|
|
Packit |
2632c6 |
unDelim = Delimiter . map apply
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
main :: IO ()
|
|
Packit |
2632c6 |
main = do
|
|
Packit |
2632c6 |
results <- mapM (\(s,t) -> printf "%-40s" s >> t) tests
|
|
Packit |
2632c6 |
when (not . all isSuccess $ results) $ fail "Not all tests passed!"
|
|
Packit |
2632c6 |
where
|
|
Packit |
2632c6 |
isSuccess (Success{}) = True
|
|
Packit |
2632c6 |
isSuccess _ = False
|
|
Packit |
2632c6 |
qc x = quickCheckWithResult (stdArgs { maxSuccess = 200 }) x
|
|
Packit |
2632c6 |
tests = [ ("default/id", qc prop_default_id)
|
|
Packit |
2632c6 |
, ("match/decompose", qc prop_match_decompose)
|
|
Packit |
2632c6 |
, ("match/yields delim", qc prop_match_yields_delim)
|
|
Packit |
2632c6 |
, ("splitInternal/lossless", qc prop_splitInternal_lossless)
|
|
Packit |
2632c6 |
, ("splitInternal/yields delims", qc prop_splitInternal_yields_delims)
|
|
Packit |
2632c6 |
, ("splitInternal/text", qc prop_splitInternal_text_not_delims)
|
|
Packit |
2632c6 |
, ("doCondense/no consec delims", qc prop_doCondense_no_consec_delims)
|
|
Packit |
2632c6 |
, ("insBlanks/no consec delims", qc prop_insBlanks_no_consec_delims)
|
|
Packit |
2632c6 |
, ("insBlanks/fl not delims", qc prop_insBlanks_fl_not_delim)
|
|
Packit |
2632c6 |
, ("mergeL/no delims", qc prop_mergeL_no_delims)
|
|
Packit |
2632c6 |
, ("mergeR/no delims", qc prop_mergeR_no_delims)
|
|
Packit |
2632c6 |
, ("oneOf", qc prop_oneOf)
|
|
Packit |
2632c6 |
, ("oneOf/not text", qc prop_oneOf_not_text)
|
|
Packit |
2632c6 |
, ("onSublist", qc prop_onSublist)
|
|
Packit |
2632c6 |
, ("onSublist/not text", qc prop_onSublist_not_text)
|
|
Packit |
2632c6 |
, ("whenElt", qc prop_whenElt)
|
|
Packit |
2632c6 |
, ("whenElt/not text", qc prop_whenElt_not_text)
|
|
Packit |
2632c6 |
, ("process/dropDelims", qc prop_dropDelims)
|
|
Packit |
2632c6 |
, ("process/keepDelimsL no delims", qc prop_keepDelimsL_no_delims)
|
|
Packit |
2632c6 |
, ("process/keepDelimsR no delims", qc prop_keepDelimsR_no_delims)
|
|
Packit |
2632c6 |
, ("process/keepDelimsL match", qc prop_keepDelimsL_match)
|
|
Packit |
2632c6 |
, ("process/keepDelimsR match", qc prop_keepDelimsR_match)
|
|
Packit |
2632c6 |
, ("condense/no consec delims", qc prop_condense_no_consec_delims)
|
|
Packit |
2632c6 |
, ("condense/all delims", qc prop_condense_all_delims)
|
|
Packit |
2632c6 |
, ("dropInitBlank", qc prop_dropInitBlank)
|
|
Packit |
2632c6 |
, ("dropFinalBlank", qc prop_dropFinalBlank)
|
|
Packit |
2632c6 |
, ("dropBlanks", qc prop_dropBlanks)
|
|
Packit |
2632c6 |
, ("startsWith", qc prop_startsWith)
|
|
Packit |
2632c6 |
, ("startsWithOneOf", qc prop_startsWithOneOf)
|
|
Packit |
2632c6 |
, ("endsWith", qc prop_endsWith)
|
|
Packit |
2632c6 |
, ("endsWithOneOf", qc prop_endsWithOneOf)
|
|
Packit |
2632c6 |
, ("splitOn/right inv", qc prop_splitOn_right_inv)
|
|
Packit |
2632c6 |
, ("splitOn/idem", qc prop_splitOn_intercalate_idem)
|
|
Packit |
2632c6 |
, ("splitOn/empty delim", qc prop_splitOn_empty_delim)
|
|
Packit |
2632c6 |
, ("split/empty delim", qc prop_split_empty_delim_drop)
|
|
Packit |
2632c6 |
, ("chunksOf/lengths", qc prop_chunksOf_all_n)
|
|
Packit |
2632c6 |
, ("chunksOf/last <= n", qc prop_chunksOf_last_less_n)
|
|
Packit |
2632c6 |
, ("chunksOf/preserve", qc prop_chunksOf_preserve)
|
|
Packit |
2632c6 |
, ("splitPlaces/lengths", qc prop_splitPlaces_lengths)
|
|
Packit |
2632c6 |
, ("splitPlaces/last <= n", qc prop_splitPlaces_last_less_n)
|
|
Packit |
2632c6 |
, ("splitPlaces/preserve", qc prop_splitPlaces_preserve)
|
|
Packit |
2632c6 |
, ("splitPlaces/chunksOf", qc prop_splitPlaces_chunksOf)
|
|
Packit |
2632c6 |
, ("splitPlacesB/length", qc prop_splitPlacesB_length)
|
|
Packit |
2632c6 |
, ("splitPlacesB/last <= n", qc prop_splitPlacesB_last_less_n)
|
|
Packit |
2632c6 |
, ("splitPlacesB/preserve", qc prop_splitPlacesB_preserve)
|
|
Packit |
2632c6 |
, ("lines", qc prop_lines)
|
|
Packit |
2632c6 |
, ("wordsBy/words", qc prop_wordsBy_words)
|
|
Packit |
2632c6 |
, ("linesBy/lines", qc prop_linesBy_lines)
|
|
Packit |
2632c6 |
, ("chop/group", qc prop_chop_group)
|
|
Packit |
2632c6 |
, ("chop/words", qc prop_chop_words)
|
|
Packit |
2632c6 |
, ("divvy/evenly", qc prop_divvy_evenly)
|
|
Packit |
2632c6 |
, ("divvy/discard_remainder", qc prop_divvy_discard_remainder)
|
|
Packit |
2632c6 |
, ("divvy/outputlists_allsame_length", qc prop_divvy_outputlists_allsame_length)
|
|
Packit |
2632c6 |
, ("divvy/output_are_sublists", qc prop_divvy_output_are_sublists)
|
|
Packit |
2632c6 |
, ("divvy/heads", qc prop_divvy_heads)
|
|
Packit |
2632c6 |
]
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_default_id :: [Elt] -> Bool
|
|
Packit |
2632c6 |
prop_default_id l = split defaultSplitter l == [l]
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_match_decompose :: Delim Elt -> [Elt] -> Bool
|
|
Packit |
2632c6 |
prop_match_decompose d l = maybe True ((==l) . uncurry (++)) $ matchDelim (unDelim d) l
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
isDelimMatch :: Delim Elt -> [Elt] -> Bool
|
|
Packit |
2632c6 |
isDelimMatch d l = matchDelim (unDelim d) l == Just (l,[])
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_match_yields_delim :: Delim Elt -> [Elt] -> Bool
|
|
Packit |
2632c6 |
prop_match_yields_delim d l =
|
|
Packit |
2632c6 |
case matchDelim (unDelim d) l of
|
|
Packit |
2632c6 |
Nothing -> True
|
|
Packit |
2632c6 |
Just (del,rest) -> isDelimMatch d del
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_splitInternal_lossless :: Delim Elt -> [Elt] -> Bool
|
|
Packit |
2632c6 |
prop_splitInternal_lossless d l = concatMap fromElem (splitInternal (unDelim d) l) == l
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_splitInternal_yields_delims :: Delim Elt -> [Elt] -> Bool
|
|
Packit |
2632c6 |
prop_splitInternal_yields_delims d l =
|
|
Packit |
2632c6 |
all (isDelimMatch d) $ [ del | (Delim del) <- splitInternal d' l ]
|
|
Packit |
2632c6 |
where d' = unDelim d
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_splitInternal_text_not_delims :: Delim Elt -> [Elt] -> Bool
|
|
Packit |
2632c6 |
prop_splitInternal_text_not_delims d l =
|
|
Packit |
2632c6 |
all (not . isDelimMatch d) $ [ ch | (Text ch) <- splitInternal d' l ]
|
|
Packit |
2632c6 |
where d' = unDelim d
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
noConsecDelims :: SplitList Elt -> Bool
|
|
Packit |
2632c6 |
noConsecDelims [] = True
|
|
Packit |
2632c6 |
noConsecDelims [x] = True
|
|
Packit |
2632c6 |
noConsecDelims (Delim _ : Delim _ : _) = False
|
|
Packit |
2632c6 |
noConsecDelims (_ : xs) = noConsecDelims xs
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_doCondense_no_consec_delims :: SplitList Elt -> Bool
|
|
Packit |
2632c6 |
prop_doCondense_no_consec_delims l = noConsecDelims $ doCondense Condense l
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_insBlanks_no_consec_delims :: SplitList Elt -> Bool
|
|
Packit |
2632c6 |
prop_insBlanks_no_consec_delims l = noConsecDelims $ insertBlanks Condense l
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_insBlanks_fl_not_delim :: SplitList Elt -> Bool
|
|
Packit |
2632c6 |
prop_insBlanks_fl_not_delim l =
|
|
Packit |
2632c6 |
case insertBlanks Condense l of
|
|
Packit |
2632c6 |
[] -> True
|
|
Packit |
2632c6 |
xs -> (not . isDelim $ head xs) && (not . isDelim $ last xs)
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_mergeL_no_delims :: SplitList Elt -> Bool
|
|
Packit |
2632c6 |
prop_mergeL_no_delims = all (not . isDelim) . mergeLeft . insertBlanks Condense
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_mergeR_no_delims :: SplitList Elt -> Bool
|
|
Packit |
2632c6 |
prop_mergeR_no_delims = all (not . isDelim) . mergeRight . insertBlanks Condense
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
getDelims :: Splitter Elt -> [Elt] -> [[Elt]]
|
|
Packit |
2632c6 |
getDelims s l = [ d | Delim d <- splitInternal (delimiter s) l ]
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
getTexts :: Splitter Elt -> [Elt] -> [[Elt]]
|
|
Packit |
2632c6 |
getTexts s l = [ c | Text c <- splitInternal (delimiter s) l ]
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_oneOf :: [Elt] -> [Elt] -> Bool
|
|
Packit |
2632c6 |
prop_oneOf elts l = all ((==1) . length) ds && all ((`elem` elts) . head) ds
|
|
Packit |
2632c6 |
where ds = getDelims (oneOf elts) l
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_oneOf_not_text :: [Elt] -> [Elt] -> Bool
|
|
Packit |
2632c6 |
prop_oneOf_not_text elts l = all (not . (`elem` elts)) (concat cs)
|
|
Packit |
2632c6 |
where cs = getTexts (oneOf elts) l
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_onSublist :: [Elt] -> [Elt] -> Bool
|
|
Packit |
2632c6 |
prop_onSublist sub l = all (==sub) $ getDelims (onSublist sub) l
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_onSublist_not_text :: [Elt] -> [Elt] -> Property
|
|
Packit |
2632c6 |
prop_onSublist_not_text sub l =
|
|
Packit |
2632c6 |
(not . null $ sub) ==>
|
|
Packit |
2632c6 |
all (not . isInfixOf sub) $ getTexts (onSublist sub) l
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_whenElt :: (Fun Elt Bool) -> [Elt] -> Bool
|
|
Packit |
2632c6 |
prop_whenElt (Fun _ p) l = all ((==1) . length) ds && all (p . head) ds
|
|
Packit |
2632c6 |
where ds = getDelims (whenElt p) l
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_whenElt_not_text :: (Fun Elt Bool) -> [Elt] -> Bool
|
|
Packit |
2632c6 |
prop_whenElt_not_text (Fun _ p) l = all (not . p) (concat cs)
|
|
Packit |
2632c6 |
where cs = getTexts (whenElt p) l
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
process :: Splitter Elt -> [Elt] -> SplitList Elt
|
|
Packit |
2632c6 |
process s = postProcess s . splitInternal (delimiter s)
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_dropDelims :: Splitter Elt -> [Elt] -> Bool
|
|
Packit |
2632c6 |
prop_dropDelims s l = all (not . isDelim) (process (dropDelims s) l)
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_keepDelimsL_no_delims :: Splitter Elt -> [Elt] -> Bool
|
|
Packit |
2632c6 |
prop_keepDelimsL_no_delims s l = all (not . isDelim) (process (keepDelimsL s) l)
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_keepDelimsL_match :: Splitter Elt -> NonEmptyList Elt -> Bool
|
|
Packit |
2632c6 |
prop_keepDelimsL_match s (NonEmpty l) =
|
|
Packit |
2632c6 |
all (isJust . matchDelim (delimiter s)) [ c | Text c <- tail p ]
|
|
Packit |
2632c6 |
where p = process (keepDelimsL s) l
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_keepDelimsR_no_delims :: Splitter Elt -> [Elt] -> Bool
|
|
Packit |
2632c6 |
prop_keepDelimsR_no_delims s l = all (not . isDelim) (process (keepDelimsR s) l)
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_keepDelimsR_match :: Splitter Elt -> NonEmptyList Elt -> Bool
|
|
Packit |
2632c6 |
prop_keepDelimsR_match s (NonEmpty l) =
|
|
Packit |
2632c6 |
all (any (isJust . matchDelim (delimiter s)) . tails)
|
|
Packit |
2632c6 |
[ c | Text c <- init p ]
|
|
Packit |
2632c6 |
where p = process (keepDelimsR s) l
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_condense_no_consec_delims :: Splitter Elt -> [Elt] -> Bool
|
|
Packit |
2632c6 |
prop_condense_no_consec_delims s l = noConsecDelims $ process (condense s) l
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_condense_all_delims :: Splitter Elt -> [Elt] -> Bool
|
|
Packit |
2632c6 |
prop_condense_all_delims s l = all allDelims p
|
|
Packit |
2632c6 |
where p = [ d | Delim d <- process (condense s) l ]
|
|
Packit |
2632c6 |
allDelims t = all isDelim (splitInternal (delimiter s) t)
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_dropInitBlank :: Splitter Elt -> NonEmptyList Elt -> Bool
|
|
Packit |
2632c6 |
prop_dropInitBlank s (NonEmpty l) = head p /= Text []
|
|
Packit |
2632c6 |
where p = process (dropInitBlank $ s { delimPolicy = Keep } ) l
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_dropFinalBlank :: Splitter Elt -> NonEmptyList Elt -> Bool
|
|
Packit |
2632c6 |
prop_dropFinalBlank s (NonEmpty l) = last p /= Text []
|
|
Packit |
2632c6 |
where p = process (dropFinalBlank $ s { delimPolicy = Keep } ) l
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_dropBlanks :: Splitter Elt -> [Elt] -> Bool
|
|
Packit |
2632c6 |
prop_dropBlanks s = null . filter (== (Text [])) . process (dropBlanks s)
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_startsWith :: [Elt] -> NonEmptyList Elt -> Bool
|
|
Packit |
2632c6 |
prop_startsWith s (NonEmpty l) = all (s `isPrefixOf`) (tail $ split (startsWith s) l)
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_startsWithOneOf :: [Elt] -> NonEmptyList Elt -> Bool
|
|
Packit |
2632c6 |
prop_startsWithOneOf elts (NonEmpty l) = all ((`elem` elts) . head) (tail $ split (startsWithOneOf elts) l)
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_endsWith :: [Elt] -> NonEmptyList Elt -> Bool
|
|
Packit |
2632c6 |
prop_endsWith s (NonEmpty l) = all (s `isSuffixOf`) (init $ split (endsWith s) l)
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_endsWithOneOf :: [Elt] -> NonEmptyList Elt -> Bool
|
|
Packit |
2632c6 |
prop_endsWithOneOf elts (NonEmpty l) = all ((`elem` elts) . last) (init $ split (endsWithOneOf elts) l)
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_splitOn_right_inv :: [Elt] -> [Elt] -> Bool
|
|
Packit |
2632c6 |
prop_splitOn_right_inv x l = intercalate x (splitOn x l) == l
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
{- This property fails: for example,
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
splitOn "dd" (intercalate "dd" ["d",""]) == ["","d"]
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
so it's not enough just to say that the delimiter is not an infix of
|
|
Packit |
2632c6 |
any elements of l!
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_splitOn_left_inv :: [Elt] -> NonEmptyList [Elt] -> Property
|
|
Packit |
2632c6 |
prop_splitOn_left_inv x (NonEmpty ls) = not (any (x `isInfixOf`) ls) ==>
|
|
Packit |
2632c6 |
splitOn x (intercalate x ls) == ls
|
|
Packit |
2632c6 |
-}
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
-- Note, the below property is in fact logically entailed by
|
|
Packit |
2632c6 |
-- prop_splitOn_right_inv, but we keep it here just for kicks.
|
|
Packit |
2632c6 |
prop_splitOn_intercalate_idem :: [Elt] -> [[Elt]] -> Bool
|
|
Packit |
2632c6 |
prop_splitOn_intercalate_idem x ls = f (f ls) == f ls
|
|
Packit |
2632c6 |
where f = splitOn x . intercalate x
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_splitOn_empty_delim :: [Elt] -> Bool
|
|
Packit |
2632c6 |
prop_splitOn_empty_delim ls = splitOn [] ls == [] : map (:[]) ls
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_split_empty_delim_drop :: [Elt] -> Bool
|
|
Packit |
2632c6 |
prop_split_empty_delim_drop ls
|
|
Packit |
2632c6 |
= split (dropDelims . dropBlanks $ onSublist []) ls == map (:[]) ls
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_chunksOf_all_n :: Positive Int -> NonEmptyList Elt -> Bool
|
|
Packit |
2632c6 |
prop_chunksOf_all_n (Positive n) (NonEmpty l) = all ((==n) . length) (init $ chunksOf n l)
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_chunksOf_last_less_n :: Positive Int -> NonEmptyList Elt -> Bool
|
|
Packit |
2632c6 |
prop_chunksOf_last_less_n (Positive n) (NonEmpty l) = (<=n) . length . last $ chunksOf n l
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_chunksOf_preserve :: Positive Int -> [Elt] -> Bool
|
|
Packit |
2632c6 |
prop_chunksOf_preserve (Positive n) l = concat (chunksOf n l) == l
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_splitPlaces_lengths :: [NonNegative Int] -> [Elt] -> Bool
|
|
Packit |
2632c6 |
prop_splitPlaces_lengths ps = and . mInit . zipWith (==) ps' . map length . splitPlaces ps'
|
|
Packit |
2632c6 |
where ps' = map unNN ps
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_splitPlaces_last_less_n :: NonEmptyList (NonNegative Int) -> NonEmptyList Elt -> Bool
|
|
Packit |
2632c6 |
prop_splitPlaces_last_less_n (NonEmpty ps) (NonEmpty l) = (head $ drop (length l' - 1) ps') >= length (last l')
|
|
Packit |
2632c6 |
where l' = splitPlaces ps' l
|
|
Packit |
2632c6 |
ps' = map unNN ps
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_splitPlaces_preserve :: [NonNegative Integer] -> [Elt] -> Bool
|
|
Packit |
2632c6 |
prop_splitPlaces_preserve ps l = concat (splitPlaces ps' l) == genericTake (sum ps') l
|
|
Packit |
2632c6 |
where ps' = map unNN ps
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_splitPlaces_chunksOf :: Positive Int -> [Elt] -> Bool
|
|
Packit |
2632c6 |
prop_splitPlaces_chunksOf (Positive n) l = splitPlaces (repeat n) l == chunksOf n l
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_splitPlacesB_length :: [NonNegative Int] -> [Elt] -> Bool
|
|
Packit |
2632c6 |
prop_splitPlacesB_length ps xs = length ps' == length (splitPlacesBlanks ps' xs)
|
|
Packit |
2632c6 |
where ps' = map unNN ps
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_splitPlacesB_last_less_n :: NonEmptyList (NonNegative Int) -> NonEmptyList Elt -> Bool
|
|
Packit |
2632c6 |
prop_splitPlacesB_last_less_n (NonEmpty ps) (NonEmpty l) = (head $ drop (length l' - 1) ps') >= length (last l')
|
|
Packit |
2632c6 |
where l' = splitPlacesBlanks ps' l
|
|
Packit |
2632c6 |
ps' = map unNN ps
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_splitPlacesB_preserve :: [NonNegative Integer] -> [Elt] -> Bool
|
|
Packit |
2632c6 |
prop_splitPlacesB_preserve ps l = concat (splitPlacesBlanks ps' l) == genericTake (sum ps') l
|
|
Packit |
2632c6 |
where ps' = map unNN ps
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
unNN :: NonNegative a -> a
|
|
Packit |
2632c6 |
unNN (NonNegative x) = x
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
mInit :: [a] -> [a]
|
|
Packit |
2632c6 |
mInit [] = []
|
|
Packit |
2632c6 |
mInit [x] = []
|
|
Packit |
2632c6 |
mInit (x:xs) = x : init xs
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
newtype EltWS = EltWS { unEltWS :: Char }
|
|
Packit |
2632c6 |
deriving (Eq, Show)
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
instance Arbitrary EltWS where
|
|
Packit |
2632c6 |
arbitrary = elements (map EltWS "abcde \n")
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_lines :: [EltWS] -> Bool
|
|
Packit |
2632c6 |
prop_lines s = lines s' == endBy "\n" s'
|
|
Packit |
2632c6 |
where s' = map unEltWS s
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_wordsBy_words :: [EltWS] -> Bool
|
|
Packit |
2632c6 |
prop_wordsBy_words s = words s' == wordsBy isSpace s'
|
|
Packit |
2632c6 |
where s' = map unEltWS s
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_linesBy_lines :: [EltWS] -> Bool
|
|
Packit |
2632c6 |
prop_linesBy_lines s = lines s' == linesBy (=='\n') s'
|
|
Packit |
2632c6 |
where s' = map unEltWS s
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_chop_group :: [Elt] -> Bool
|
|
Packit |
2632c6 |
prop_chop_group s = chop (\xs@(x:_) -> span (==x) xs) s == group s
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_chop_words :: [EltWS] -> Bool
|
|
Packit |
2632c6 |
prop_chop_words s = words s' == (filter (not . null) . chop (span (not . isSpace) . dropWhile isSpace) $ s')
|
|
Packit |
2632c6 |
where s' = map unEltWS s
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_divvy_evenly :: [Elt] -> Positive Int -> Bool
|
|
Packit |
2632c6 |
prop_divvy_evenly elems (Positive n) = concat (divvy n n elems') == elems'
|
|
Packit |
2632c6 |
where
|
|
Packit |
2632c6 |
-- Chop off the smallest possible tail of elems to make the length
|
|
Packit |
2632c6 |
-- evenly divisible by n. This property used to have a
|
|
Packit |
2632c6 |
-- precondition (length elemens `mod` n == 0), but that led to too
|
|
Packit |
2632c6 |
-- many discarded test cases and occasional test suite failures.
|
|
Packit |
2632c6 |
elems' = take ((length elems `div` n) * n) elems
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_divvy_discard_remainder :: [Elt] -> Positive Int -> Bool
|
|
Packit |
2632c6 |
prop_divvy_discard_remainder elems (Positive n) =
|
|
Packit |
2632c6 |
concat (divvy n n elems) == (reverse . drop (length elems `mod` n) . reverse $ elems)
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_divvy_outputlists_allsame_length :: [Elt] -> Positive Int -> Positive Int -> Bool
|
|
Packit |
2632c6 |
prop_divvy_outputlists_allsame_length elems (Positive n) (Positive m) = allSame xs
|
|
Packit |
2632c6 |
where
|
|
Packit |
2632c6 |
allSame :: [Int] -> Bool
|
|
Packit |
2632c6 |
allSame [] = True
|
|
Packit |
2632c6 |
allSame zs = and $ map (== head zs) (tail zs)
|
|
Packit |
2632c6 |
xs = map length (divvy n m elems)
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_divvy_output_are_sublists :: [Elt] -> Positive Int -> Positive Int -> Bool
|
|
Packit |
2632c6 |
prop_divvy_output_are_sublists elems (Positive n) (Positive m) = and $ map (\x -> isInfixOf x elems) xs
|
|
Packit |
2632c6 |
where xs = divvy n m elems
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
takeEvery :: Int -> [a] -> [a]
|
|
Packit |
2632c6 |
takeEvery _ [] = []
|
|
Packit |
2632c6 |
takeEvery n lst = (map head . chunksOf n) $ lst
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
initNth :: Int -> [a] -> [a]
|
|
Packit |
2632c6 |
initNth _ [] = []
|
|
Packit |
2632c6 |
initNth n lst = (reverse . drop n . reverse) $ lst
|
|
Packit |
2632c6 |
|
|
Packit |
2632c6 |
prop_divvy_heads :: [Elt] -> Positive Int -> Positive Int -> Bool
|
|
Packit |
2632c6 |
prop_divvy_heads [] _ _ = True
|
|
Packit |
2632c6 |
prop_divvy_heads elems (Positive n) (Positive m) = hds1 == hds2
|
|
Packit |
2632c6 |
where hds1 = takeEvery m (initNth (n - 1) elems)
|
|
Packit |
2632c6 |
hds2 = map head $ divvy n m elems
|
|
Packit |
2632c6 |
|