{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
module Gen
( NonEmptyLQ
, ValidationQ (..)
) where
import qualified Data.List.NonEmpty as NE
import Test.SmallCheck.Series (Serial (..), cons1, (\/))
import Test.Tasty.QuickCheck (Arbitrary (arbitrary, shrink), oneof)
import qualified Test.Tasty.QuickCheck as QC
import Valida (Validation (..))
-- | Wrapper around 'Validation' with 'Arbitrary' and 'Serial' instances.
newtype ValidationQ e a = ValidationQ (Validation e a)
deriving (Show)
instance (Arbitrary e, Arbitrary a) => Arbitrary (ValidationQ e a) where
arbitrary = ValidationQ <$> oneof [Failure <$> arbitrary, Success <$> arbitrary]
shrink (ValidationQ (Failure e)) = ValidationQ . Failure <$> shrink e
shrink (ValidationQ (Success a)) = ValidationQ . Success <$> shrink a
instance (Serial m e, Serial m a) => Serial m (ValidationQ e a) where
series = ValidationQ <$> cons1 Failure \/ cons1 Success
-- | Type unifying the separate `NonEmpty` impls on quickcheck and smallcheck.
data NonEmptyLQ a = NonEmptyListQ (QC.NonEmptyList a) | NonEmptyQ (NE.NonEmpty a)
deriving (Show)
instance Arbitrary a => Arbitrary (NonEmptyLQ a) where
arbitrary = NonEmptyListQ <$> arbitrary
shrink (NonEmptyListQ l) = NonEmptyListQ <$> shrink l
shrink _ = error "Should not try to shrink NonEmptyQ"
instance Serial m a => Serial m (NonEmptyLQ a) where
series = cons1 NonEmptyQ
instance Functor NonEmptyLQ where
fmap f (NonEmptyListQ l) = NonEmptyListQ $ f <$> l
fmap f (NonEmptyQ l) = NonEmptyQ $ f <$> l
instance Foldable NonEmptyLQ where
foldMap f (NonEmptyListQ l) = foldMap f $ QC.getNonEmpty l
foldMap f (NonEmptyQ l) = foldMap f l