{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS_GHC -Wno-orphans #-}
{-# OPTIONS_GHC -Wno-redundant-constraints #-}

module Data.GenValidity.Persist where

import Data.GenValidity
import Data.GenValidity.Containers
import Data.List.NonEmpty (NonEmpty (..))
import qualified Data.List.NonEmpty as NE
import Data.Validity.Containers
import Data.Validity.Persist ()
import Database.Persist
import Database.Persist.Sql
import Test.QuickCheck

instance ToBackendKey SqlBackend record => GenValid (Key record) where
  genValid :: Gen (Key record)
genValid = forall record.
ToBackendKey SqlBackend record =>
Int64 -> Key record
toSqlKey forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. GenValid a => Gen a
genValid
  shrinkValid :: Key record -> [Key record]
shrinkValid = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall record.
ToBackendKey SqlBackend record =>
Int64 -> Key record
toSqlKey forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. GenValid a => a -> [a]
shrinkValid forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall record.
ToBackendKey SqlBackend record =>
Key record -> Int64
fromSqlKey

instance (GenValid a, ToBackendKey SqlBackend a) => GenValid (Entity a) where
  genValid :: Gen (Entity a)
genValid = forall record. Key record -> record -> Entity record
Entity forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. GenValid a => Gen a
genValid forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. GenValid a => Gen a
genValid
  shrinkValid :: Entity a -> [Entity a]
shrinkValid (Entity Key a
k a
v) = [forall record. Key record -> record -> Entity record
Entity Key a
k' a
v' | (Key a
k', a
v') <- forall a. GenValid a => a -> [a]
shrinkValid (Key a
k, a
v)]

validsWithSeperateIDs ::
  forall a.
  (ToBackendKey SqlBackend a, GenValid a) =>
  Gen [Entity a]
validsWithSeperateIDs :: forall a. (ToBackendKey SqlBackend a, GenValid a) => Gen [Entity a]
validsWithSeperateIDs = forall a.
(PersistEntity a, ToBackendKey SqlBackend a) =>
Gen a -> Gen [Entity a]
genValidsWithSeperateIDs forall a. GenValid a => Gen a
genValid

genValidsWithSeperateIDs ::
  forall a.
  (PersistEntity a, ToBackendKey SqlBackend a) =>
  Gen a ->
  Gen [Entity a]
genValidsWithSeperateIDs :: forall a.
(PersistEntity a, ToBackendKey SqlBackend a) =>
Gen a -> Gen [Entity a]
genValidsWithSeperateIDs Gen a
gen =
  forall a. (Int -> Gen a) -> Gen a
sized forall a b. (a -> b) -> a -> b
$ \Int
n -> do
    [Int]
list <- Int -> Gen [Int]
arbPartition Int
n
    [Int] -> Gen [Entity a]
go [Int]
list
  where
    go :: [Int] -> Gen [Entity a]
    go :: [Int] -> Gen [Entity a]
go [] = forall (f :: * -> *) a. Applicative f => a -> f a
pure []
    go (Int
s : [Int]
ss) = do
      [Entity a]
es <- [Int] -> Gen [Entity a]
go [Int]
ss
      forall a. Int -> Gen a -> Gen a
resize Int
s forall a b. (a -> b) -> a -> b
$ do
        Key a
ei <- forall a. GenValid a => Gen a
genValid forall a. Gen a -> (a -> Bool) -> Gen a
`suchThat` (forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` forall a b. (a -> b) -> [a] -> [b]
map forall record. Entity record -> Key record
entityKey [Entity a]
es)
        a
e <- Gen a
gen
        forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall record. Key record -> record -> Entity record
Entity Key a
ei a
e forall a. a -> [a] -> [a]
: [Entity a]
es

genSeperateIdsForNE ::
  forall a.
  (PersistEntity a, ToBackendKey SqlBackend a, GenValid a) =>
  NonEmpty a ->
  Gen (NonEmpty (Entity a))
genSeperateIdsForNE :: forall a.
(PersistEntity a, ToBackendKey SqlBackend a, GenValid a) =>
NonEmpty a -> Gen (NonEmpty (Entity a))
genSeperateIdsForNE (a
a :| [a]
as) = do
  [Entity a]
es <- forall a.
(ToBackendKey SqlBackend a, GenValid a) =>
[a] -> Gen [Entity a]
genSeperateIdsFor [a]
as
  Key a
i <- forall a. GenValid a => Gen a
genValid forall a. Gen a -> (a -> Bool) -> Gen a
`suchThat` (forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` forall a b. (a -> b) -> [a] -> [b]
map forall record. Entity record -> Key record
entityKey [Entity a]
es)
  forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall record. Key record -> record -> Entity record
Entity Key a
i a
a forall a. a -> [a] -> NonEmpty a
:| [Entity a]
es)

genSeperateIds ::
  forall a.
  (PersistEntity a, ToBackendKey SqlBackend a) =>
  Gen [Key a]
genSeperateIds :: forall a.
(PersistEntity a, ToBackendKey SqlBackend a) =>
Gen [Key a]
genSeperateIds = forall a. Ord a => Gen a -> Gen [a]
genSeperate forall a. GenValid a => Gen a
genValid

genSeperateIdsFor ::
  forall a.
  (ToBackendKey SqlBackend a, GenValid a) =>
  [a] ->
  Gen [Entity a]
genSeperateIdsFor :: forall a.
(ToBackendKey SqlBackend a, GenValid a) =>
[a] -> Gen [Entity a]
genSeperateIdsFor [] = forall (f :: * -> *) a. Applicative f => a -> f a
pure []
genSeperateIdsFor (a
a : [a]
as) = forall a. NonEmpty a -> [a]
NE.toList forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a.
(PersistEntity a, ToBackendKey SqlBackend a, GenValid a) =>
NonEmpty a -> Gen (NonEmpty (Entity a))
genSeperateIdsForNE (a
a forall a. a -> [a] -> NonEmpty a
:| [a]
as)

shrinkValidWithSeperateIds ::
  (PersistEntity a, ToBackendKey SqlBackend a, GenValid a) =>
  [Entity a] ->
  [[Entity a]]
shrinkValidWithSeperateIds :: forall a.
(PersistEntity a, ToBackendKey SqlBackend a, GenValid a) =>
[Entity a] -> [[Entity a]]
shrinkValidWithSeperateIds = forall a. (a -> Bool) -> [a] -> [a]
filter (forall a. Ord a => [a] -> Bool
distinctOrd forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map forall record. Entity record -> Key record
entityKey) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. GenValid a => a -> [a]
shrinkValid