genvalidity-text-1.0.0.0: src/Data/GenValidity/Text.hs
{-# OPTIONS_GHC -fno-warn-orphans #-}
module Data.GenValidity.Text where
import Data.GenValidity
import qualified Data.Text as ST
import qualified Data.Text.Internal.Lazy as LT
import qualified Data.Text.Lazy as LT
import Data.Validity.Text ()
import System.Random as Random
import Test.QuickCheck
import Test.QuickCheck.Gen
import Test.QuickCheck.Random
instance GenValid ST.Text where
genValid = genText
shrinkValid = fmap ST.pack . shrinkValid . ST.unpack
genText :: Gen ST.Text
genText = do
len <- genListLength
MkGen $ \qcgen _ -> ST.unfoldrN len (pure . random) qcgen
genTextBy :: Gen Char -> Gen ST.Text
genTextBy (MkGen charFunc) = do
len <- genListLength
MkGen $ \qcgen size ->
let go :: QCGen -> Maybe (Char, QCGen)
go qcg =
let (qc1, qc2) = Random.split qcg
in Just (charFunc qc1 size, qc2)
in ST.unfoldrN len go qcgen
instance GenValid LT.Text where
genValid =
sized $ \n ->
case n of
0 -> pure LT.Empty
_ -> do
(a, b) <- genSplit n
st <- ST.cons <$> genValid <*> resize a genValid
lt <- resize b genValid
pure $ LT.Chunk st lt
shrinkValid = fmap LT.fromChunks . shrinkValid . LT.toChunks
-- | 'textStartingWith c' generates a 'Text' value that starts with 'c'.
textStartingWith :: Char -> Gen ST.Text
textStartingWith c =
sized $ \n ->
case n of
0 -> pure $ ST.singleton c
1 -> pure $ ST.singleton c
_ -> ST.cons c <$> resize (n - 1) genValid
-- | 'textStartingWith g' generates a 'Text' value that contains a substring generated by 'g'.
textWith :: Gen ST.Text -> Gen ST.Text
textWith gen =
sized $ \n -> do
(b, m, a) <- genSplit3 n
before <- resize b genValid
middle <- resize m gen
after <- resize a genValid
return $ ST.concat [before, middle, after]
-- | 'textStartingWith c' generates a 'Text' value that contains a 'c'.
textWithA :: Char -> Gen ST.Text
textWithA c = textWith $ ST.singleton <$> pure c
-- | 'textWithoutAny c' generates a 'Text' value that does not contain any 'c'.
textWithoutAny :: Char -> Gen ST.Text
textWithoutAny c = textWithoutAnyOf [c]
-- | 'textWithoutAnyOf c' generates a 'Text' value that does not contain any character in 'ls'.
textWithoutAnyOf :: String -> Gen ST.Text
textWithoutAnyOf cs = ST.pack <$> genListOf (genValid `suchThat` (`notElem` cs))
-- | 'textAllCaps' generates a 'Text' value with only upper-case characters.
textAllCaps :: Gen ST.Text
textAllCaps = ST.toUpper <$> genValid
-- | 'genSingleLineText' generates a single-line text, that is without any line separators.
--
-- See 'Data.GenValidity.genNonLineSeparator' and 'Data.Validity.isLineSeparator'
genSingleLineText :: Gen ST.Text
genSingleLineText = genTextBy genNonLineSeparator