Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add (Co)Arbitrary instances for Lazy Lists #112

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion src/Test/QuickCheck/Arbitrary.purs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import Data.Identity (Identity(..))
import Data.Int (toNumber)
import Data.Lazy (Lazy, defer, force)
import Data.List (List)
import Data.List.Lazy as Lazy
import Data.List.NonEmpty (NonEmptyList(..))
import Data.Maybe (Maybe(..), fromJust)
import Data.Newtype (wrap)
Expand All @@ -42,7 +43,7 @@ import Partial.Unsafe (unsafePartial)
import Prim.Row as Row
import Prim.RowList as RL
import Record as Record
import Test.QuickCheck.Gen (Gen, arrayOf, chooseInt, elements, listOf, oneOf, perturbGen, repeatable, sized, uniform)
import Test.QuickCheck.Gen (Gen, arrayOf, chooseInt, elements, lazyListOf, listOf, oneOf, perturbGen, repeatable, sized, uniform)
import Type.Data.RowList (RLProxy(..))

-- | The `Arbitrary` class represents those types whose values can be
Expand Down Expand Up @@ -168,6 +169,12 @@ instance arbitraryList :: Arbitrary a => Arbitrary (List a) where
instance coarbList :: Coarbitrary a => Coarbitrary (List a) where
coarbitrary = foldl (\f x -> f <<< coarbitrary x) identity

instance arbitraryLazyList :: Arbitrary a => Arbitrary (Lazy.List a) where
arbitrary = sized \n -> chooseInt zero n >>= flip lazyListOf arbitrary

instance coarbLazyList :: Coarbitrary a => Coarbitrary (Lazy.List a) where
coarbitrary = foldl (\f x -> f <<< coarbitrary x) identity

instance arbitraryIdentity :: Arbitrary a => Arbitrary (Identity a) where
arbitrary = Identity <$> arbitrary

Expand Down
5 changes: 5 additions & 0 deletions src/Test/QuickCheck/Gen.purs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ module Test.QuickCheck.Gen
, frequency
, arrayOf
, arrayOf1
, lazyListOf
, listOf
, vectorOf
, elements
Expand All @@ -43,6 +44,7 @@ import Data.Enum (class BoundedEnum, fromEnum, toEnum)
import Data.Foldable (fold)
import Data.Int (toNumber, floor)
import Data.List (List(..), toUnfoldable)
import Data.List.Lazy as Lazy
import Data.Maybe (fromMaybe, fromJust)
import Data.Monoid.Additive (Additive(..))
import Data.Newtype (unwrap)
Expand Down Expand Up @@ -200,6 +202,9 @@ replicateMRec k gen = tailRecM go (Tuple Nil k)
listOf :: forall a. Int -> Gen a -> Gen (List a)
listOf = replicateMRec

lazyListOf :: forall a. Int -> Gen a -> Gen (Lazy.List a)
lazyListOf n gen = Lazy.fromFoldable <$> listOf n gen

-- | Create a random generator which generates a vector of random values of a specified size.
vectorOf :: forall a. Int -> Gen a -> Gen (Array a)
vectorOf k g = toUnfoldable <$> listOf k g
Expand Down
29 changes: 16 additions & 13 deletions test/Main.purs
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,22 @@ module Test.Main where

import Prelude

import Effect (Effect)
import Effect.Console (log, logShow)
import Effect.Exception (try)
import Control.Monad.Gen.Class as MGen
import Data.Array.Partial (head)
import Data.Either (isLeft)
import Data.Foldable (sum)
import Data.Foldable (class Foldable, sum)
import Data.Generic.Rep (class Generic)
import Data.Generic.Rep.Show (genericShow)
import Data.Tuple (fst)
import Effect (Effect)
import Effect.Console (log, logShow)
import Effect.Exception (try)
import Partial.Unsafe (unsafePartial)
import Random.LCG (mkSeed)
import Test.Assert (assert)
import Test.QuickCheck (class Testable, quickCheck, (/=?), (<=?), (<?), (==?), (>=?), (>?))
import Test.QuickCheck.Arbitrary (arbitrary, genericArbitrary, class Arbitrary)
import Test.QuickCheck.Gen (Gen, vectorOf, randomSample', resize, Size, runGen, sized)
import Random.LCG (mkSeed)
import Test.QuickCheck.Gen (Gen, Size, lazyListOf, listOf, randomSample', resize, runGen, sized, vectorOf)

data Foo a = F0 a | F1 a a | F2 { foo :: a, bar :: Array a }
derive instance genericFoo :: Generic (Foo a) _
Expand Down Expand Up @@ -47,14 +47,16 @@ main = do
assert (testResize (resize))

log "Try with some little Gens first"
logShow =<< go 10
logShow =<< go 100
logShow =<< go 1000
logShow =<< go 10000
logShow =<< go vectorOf 10
logShow =<< go vectorOf 100
logShow =<< go vectorOf 1000
logShow =<< go vectorOf 10000

log "Testing stack safety of Gen"
logShow =<< go 20000
logShow =<< go 100000
logShow =<< go vectorOf 20000
logShow =<< go vectorOf 100000
logShow =<< go listOf 100000
logShow =<< go lazyListOf 100000

log "Generating via Generic"
logShow =<< randomSample' 10 (arbitrary :: Gen (Foo Int))
Expand Down Expand Up @@ -85,7 +87,8 @@ main = do
quickCheckFail $ 4 <=? 3

where
go n = map (sum <<< unsafeHead) $ randomSample' 1 (vectorOf n (arbitrary :: Gen Int))
go :: forall f. Foldable f => (Int -> Gen Int -> Gen (f Int)) -> Int -> Effect Int
go f n = map (sum <<< unsafeHead) $ randomSample' 1 (f n (arbitrary :: Gen Int))

unsafeHead :: forall x. Array x -> x
unsafeHead xs = unsafePartial (head xs)