@@ -7,6 +7,8 @@ module Test.QuickCheck.Arbitrary
77 , genericCoarbitrary
88 , class ArbitraryGenericSum
99 , arbitraryGenericSum
10+ , class ArbitraryRowList
11+ , arbitraryRecord
1012 ) where
1113
1214import Prelude
@@ -17,6 +19,7 @@ import Control.Monad.Gen.Common as MGC
1719import Data.Char (toCharCode , fromCharCode )
1820import Data.Either (Either (..))
1921import Data.Foldable (foldl )
22+ import Data.Generic.Rep (class Generic , to , from , NoArguments (..), Sum (..), Product (..), Constructor (..), Argument (..), Rec (..), Field (..))
2023import Data.Identity (Identity (..))
2124import Data.Int (toNumber )
2225import Data.Lazy (Lazy , defer , force )
@@ -25,9 +28,13 @@ import Data.List.NonEmpty (NonEmptyList(..))
2528import Data.Maybe (Maybe (..))
2629import Data.Newtype (wrap )
2730import Data.NonEmpty (NonEmpty (..), (:|))
31+ import Data.Record (insert )
2832import Data.String (charCodeAt , fromCharArray , split )
33+ import Data.Symbol (class IsSymbol , SProxy (..))
2934import Data.Tuple (Tuple (..))
30- import Data.Generic.Rep (class Generic , to , from , NoArguments (..), Sum (..), Product (..), Constructor (..), Argument (..), Rec (..), Field (..))
35+
36+ import Type.Prelude (class RowToList )
37+ import Type.Row (kind RowList , class RowLacks , Nil , Cons , RLProxy (..))
3138
3239import Test.QuickCheck.Gen (Gen , elements , listOf , chooseInt , sized , perturbGen , repeatable , arrayOf , oneOf , uniform )
3340
@@ -223,3 +230,31 @@ genericArbitrary = to <$> (arbitrary :: Gen rep)
223230genericCoarbitrary :: forall a rep . Generic a rep => Coarbitrary rep => a -> Gen a -> Gen a
224231genericCoarbitrary x g = to <$> coarbitrary (from x) (from <$> g)
225232
233+ -- | A helper typeclass to implement `Arbitrary` for records.
234+ class ArbitraryRowList
235+ (list :: RowList )
236+ (row :: # Type )
237+ | list -> row where
238+ arbitraryRecord :: RLProxy list -> Gen (Record row )
239+
240+ instance arbitraryRowListNil :: ArbitraryRowList Nil () where
241+ arbitraryRecord _ = pure {}
242+
243+ instance arbitraryRowListCons ::
244+ ( Arbitrary a
245+ , ArbitraryRowList listRest rowRest
246+ , RowLacks key rowRest
247+ , RowCons key a rowRest rowFull
248+ , RowToList rowFull (Cons key a listRest )
249+ , IsSymbol key
250+ ) => ArbitraryRowList (Cons key a listRest ) rowFull where
251+ arbitraryRecord _ = do
252+ value <- arbitrary
253+ previous <- arbitraryRecord (RLProxy :: RLProxy listRest )
254+ pure $ insert (SProxy :: SProxy key ) value previous
255+
256+ instance arbitraryRecordInstance ::
257+ ( RowToList row list
258+ , ArbitraryRowList list row
259+ ) => Arbitrary (Record row ) where
260+ arbitrary = arbitraryRecord (RLProxy :: RLProxy list )
0 commit comments