rel8-1.7.0.0: tests/Rel8/Generic/Rel8able/Test.hs
{-# language ScopedTypeVariables #-}
{-# language DataKinds #-}
{-# language DeriveAnyClass #-}
{-# language DeriveGeneric #-}
{-# language DerivingStrategies #-}
{-# language DuplicateRecordFields #-}
{-# language FlexibleInstances #-}
{-# language MultiParamTypeClasses #-}
{-# language OverloadedStrings #-}
{-# language StandaloneDeriving #-}
{-# language StandaloneKindSignatures #-}
{-# language TypeApplications #-}
{-# language TypeFamilies #-}
{-# language TypeOperators #-}
{-# language RecordWildCards #-}
{-# language UndecidableInstances #-}
{-# options_ghc -O0 #-}
module Rel8.Generic.Rel8able.Test
( module Rel8.Generic.Rel8able.Test
)
where
-- aeson
import Data.Aeson ( Value(..) )
import qualified Data.Aeson as Aeson
import qualified Data.Aeson.KeyMap as Aeson
-- base
import Data.Fixed ( Fixed ( MkFixed ), E2 )
import Data.Int ( Int16, Int32, Int64 )
import Data.Functor.Identity ( Identity(..) )
import qualified Data.List.NonEmpty as NonEmpty
import GHC.Generics ( Generic )
import Prelude
import Control.Applicative ( liftA3 )
-- bytestring
import Data.ByteString ( ByteString )
import qualified Data.ByteString.Lazy as LB
-- case-insensitive
import Data.CaseInsensitive ( CI )
import qualified Data.CaseInsensitive as CI
-- containers
import qualified Data.Map as Map
-- hedgehog
import qualified Hedgehog
import qualified Hedgehog.Gen as Gen
import qualified Hedgehog.Range as Range
-- rel8
import Rel8
-- scientific
import Data.Scientific ( Scientific, fromFloatDigits )
-- time
import Data.Time.Calendar (Day)
import Data.Time.Clock (UTCTime(..), secondsToDiffTime, secondsToNominalDiffTime)
import Data.Time.LocalTime
( CalendarDiffTime (CalendarDiffTime)
, LocalTime(..)
, TimeOfDay(..)
)
-- text
import Data.Text ( Text )
import qualified Data.Text.Lazy as LT
-- these
import Data.These
-- uuid
import Data.UUID ( UUID )
import qualified Data.UUID as UUID
-- vector
import Data.Vector ( Vector )
import qualified Data.Vector as Vector
makeSchema :: forall f. Rel8able f => QualifiedName -> TableSchema (f Name)
makeSchema name = TableSchema
{ name = name
, columns = namesFromLabels @(f Name)
}
data TableDuplicate f = TableDuplicate
{ foo :: TablePair f
, bar :: TablePair f
}
deriving stock Generic
deriving anyclass Rel8able
tableDuplicate :: TableSchema (TableDuplicate Name)
tableDuplicate = TableSchema
{ name = "tableDuplicate"
, columns = namesFromLabelsWith NonEmpty.last
}
data TableTest f = TableTest
{ foo :: Column f Bool
, bar :: Column f (Maybe Bool)
}
deriving stock Generic
deriving anyclass Rel8able
deriving stock instance f ~ Result => Show (TableTest f)
deriving stock instance f ~ Result => Eq (TableTest f)
deriving stock instance f ~ Result => Ord (TableTest f)
tableTest :: TableSchema (TableTest Name)
tableTest = makeSchema "tableTest"
genTableTest :: Hedgehog.MonadGen m => m (TableTest Result)
genTableTest = TableTest <$> Gen.bool <*> Gen.maybe Gen.bool
data TablePair f = TablePair
{ foo :: Column f Bool
, bars :: (Column f Text, Column f Text)
}
deriving stock Generic
deriving anyclass Rel8able
deriving stock instance f ~ Result => Show (TablePair f)
deriving stock instance f ~ Result => Eq (TablePair f)
deriving stock instance f ~ Result => Ord (TablePair f)
tablePair :: TableSchema (TablePair Name)
tablePair = makeSchema "tablePair"
genTablePair :: Hedgehog.MonadGen m => m (TablePair Result)
genTablePair = TablePair
<$> Gen.bool
<*> liftA2 (,) (Gen.text (Range.linear 0 10) Gen.alphaNum) (Gen.text (Range.linear 0 10) Gen.alphaNum)
data TableMaybe f = TableMaybe
{ foo :: Column f [Maybe Bool]
, bars :: HMaybe f (TablePair f, TablePair f)
}
deriving stock Generic
deriving anyclass Rel8able
deriving stock instance f ~ Result => Show (TableMaybe f)
deriving stock instance f ~ Result => Eq (TableMaybe f)
deriving stock instance f ~ Result => Ord (TableMaybe f)
tableMaybe :: TableSchema (TableMaybe Name)
tableMaybe = makeSchema "tableMaybe"
genTableMaybe :: Hedgehog.MonadGen m => m (TableMaybe Result)
genTableMaybe = TableMaybe
<$> Gen.list (Range.linear 0 10) (Gen.maybe Gen.bool)
<*> Gen.maybe (liftA2 (,) genTablePair genTablePair)
data TableEither f = TableEither
{ foo :: Column f Bool
, bars :: HEither f (HMaybe f (TablePair f, TablePair f)) (Column f Char)
}
deriving stock Generic
deriving anyclass Rel8able
deriving stock instance f ~ Result => Show (TableEither f)
deriving stock instance f ~ Result => Eq (TableEither f)
deriving stock instance f ~ Result => Ord (TableEither f)
tableEither :: TableSchema (TableEither Name)
tableEither = makeSchema "tableEither"
genTableEither :: Hedgehog.MonadGen m => m (TableEither Result)
genTableEither = TableEither
<$> Gen.bool
<*> Gen.either (Gen.maybe $ liftA2 (,) genTablePair genTablePair) Gen.alphaNum
data TableThese f = TableThese
{ foo :: Column f Bool
, bars :: HThese f (TableMaybe f) (TableEither f)
}
deriving stock Generic
deriving anyclass Rel8able
deriving stock instance f ~ Result => Show (TableThese f)
deriving stock instance f ~ Result => Eq (TableThese f)
deriving stock instance f ~ Result => Ord (TableThese f)
tableThese :: TableSchema (TableThese Name)
tableThese = makeSchema "tableThese"
genTableThese :: Hedgehog.MonadGen m => m (TableThese Result)
genTableThese = TableThese
<$> Gen.bool
<*> Gen.choice
[ This <$> genTableMaybe
, That <$> genTableEither
, These <$> genTableMaybe <*> genTableEither
]
data TableList f = TableList
{ foo :: Column f Bool
, bars :: HList f (TableThese f)
}
deriving stock Generic
deriving anyclass Rel8able
deriving stock instance f ~ Result => Show (TableList f)
deriving stock instance f ~ Result => Eq (TableList f)
deriving stock instance f ~ Result => Ord (TableList f)
tableList :: TableSchema (TableList Name)
tableList = makeSchema "tableList"
genTableList :: Hedgehog.MonadGen m => m (TableList Result)
genTableList = TableList
<$> Gen.bool
<*> Gen.list (Range.linear 0 10) genTableThese
data TableNonEmpty f = TableNonEmpty
{ foo :: Column f Bool
, bars :: HNonEmpty f (TableList f, TableMaybe f)
}
deriving stock Generic
deriving anyclass Rel8able
deriving stock instance f ~ Result => Show (TableNonEmpty f)
deriving stock instance f ~ Result => Eq (TableNonEmpty f)
deriving stock instance f ~ Result => Ord (TableNonEmpty f)
tableNonEmpty :: TableSchema (TableNonEmpty Name)
tableNonEmpty = makeSchema "tableNonEmpty"
genTableNonEmpty :: Hedgehog.MonadGen m => m (TableNonEmpty Result)
genTableNonEmpty = TableNonEmpty
<$> Gen.bool
<*> Gen.nonEmpty (Range.linear 0 10) (liftA2 (,) genTableList genTableMaybe)
data TableNest f = TableNest
{ foo :: Column f Bool
, bars :: HList f (HMaybe f (TablePair f))
}
deriving stock Generic
deriving anyclass Rel8able
deriving stock instance f ~ Result => Show (TableNest f)
deriving stock instance f ~ Result => Eq (TableNest f)
deriving stock instance f ~ Result => Ord (TableNest f)
tableNest :: TableSchema (TableNest Name)
tableNest = makeSchema "tableNest"
genTableNest :: Hedgehog.MonadGen m => m (TableNest Result)
genTableNest = TableNest
<$> Gen.bool
<*> Gen.list (Range.linear 0 10) (Gen.maybe genTablePair)
data S3Object = S3Object
{ bucketName :: Text
, objectKey :: Text
}
deriving stock (Generic, Show, Eq, Ord)
instance x ~ HKD S3Object Expr => ToExprs x S3Object
data HKDSum = HKDSumA Text | HKDSumB Bool Char | HKDSumC
deriving stock (Generic, Show, Eq, Ord)
instance x ~ HKD HKDSum Expr => ToExprs x HKDSum
genHKDSum :: Hedgehog.MonadGen m => m HKDSum
genHKDSum = Gen.choice
[ HKDSumA <$> Gen.text (Range.linear 0 10) Gen.alpha
, HKDSumB <$> Gen.bool <*> Gen.alpha
, pure HKDSumC
]
data HKDTest f = HKDTest
{ s3Object :: Lift f S3Object
, hkdSum :: Lift f HKDSum
}
deriving stock Generic
deriving anyclass Rel8able
deriving stock instance f ~ Result => Show (HKDTest f)
deriving stock instance f ~ Result => Eq (HKDTest f)
deriving stock instance f ~ Result => Ord (HKDTest f)
genHKDTest :: Hedgehog.MonadGen m => m (HKDTest Result)
genHKDTest = HKDTest
<$> liftA2 S3Object (Gen.text (Range.linear 0 10) Gen.alpha) (Gen.text (Range.linear 0 10) Gen.alpha)
<*> genHKDSum
data NonRecord f = NonRecord
(Column f Bool)
(Column f Char)
(Column f Char)
(Column f Char)
(Column f Char)
(Column f Char)
(Column f Char)
(Column f Char)
(Column f Char)
(Column f Char)
deriving stock Generic
deriving anyclass Rel8able
deriving stock instance f ~ Result => Show (NonRecord f)
deriving stock instance f ~ Result => Eq (NonRecord f)
deriving stock instance f ~ Result => Ord (NonRecord f)
nonRecord :: TableSchema (NonRecord Name)
nonRecord = makeSchema "nonRecord"
genNonRecord :: Hedgehog.MonadGen m => m (NonRecord Result)
genNonRecord = NonRecord
<$> Gen.bool
<*> Gen.alpha
<*> Gen.alpha
<*> Gen.alpha
<*> Gen.alpha
<*> Gen.alpha
<*> Gen.alpha
<*> Gen.alpha
<*> Gen.alpha
<*> Gen.alpha
data TableSum f
= TableSumA (Column f Bool) (Column f Text)
| TableSumB
| TableSumC (Column f Text)
deriving stock Generic
deriving stock instance f ~ Result => Show (TableSum f)
deriving stock instance f ~ Result => Eq (TableSum f)
deriving stock instance f ~ Result => Ord (TableSum f)
genTableSum :: Hedgehog.MonadGen m => m (HADT Result TableSum)
genTableSum = Gen.choice
[ TableSumA <$> Gen.bool <*> Gen.text (Range.linear 0 10) Gen.alpha
, pure TableSumB
, TableSumC <$> Gen.text (Range.linear 0 10) Gen.alpha
]
data BarbieSum f
= BarbieSumA (f Bool) (f Text)
| BarbieSumB
| BarbieSumC (f Text)
deriving stock Generic
deriving stock instance f ~ Result => Show (BarbieSum f)
deriving stock instance f ~ Result => Eq (BarbieSum f)
deriving stock instance f ~ Result => Ord (BarbieSum f)
genBarbieSum :: Hedgehog.MonadGen m => m (BarbieSum Result)
genBarbieSum = Gen.choice
[ BarbieSumA <$> fmap Identity Gen.bool <*> fmap Identity (Gen.text (Range.linear 0 10) Gen.alpha)
, pure BarbieSumB
, BarbieSumC <$> fmap Identity (Gen.text (Range.linear 0 10) Gen.alpha)
]
data TableProduct f = TableProduct
{ sum :: HADT f BarbieSum
, list :: TableList f
, foos :: HList f (HADT f TableSum, Lift f HKDSum, HKDTest f)
}
deriving stock Generic
deriving anyclass Rel8able
deriving stock instance f ~ Result => Show (TableProduct f)
deriving stock instance f ~ Result => Eq (TableProduct f)
deriving stock instance f ~ Result => Ord (TableProduct f)
tableProduct :: TableSchema (TableProduct Name)
tableProduct = makeSchema "tableProduct"
genTableProduct :: Hedgehog.MonadGen m => m (TableProduct Result)
genTableProduct = TableProduct
<$> genBarbieSum
<*> genTableList
<*> Gen.list (Range.linear 0 10) (liftA3 (,,) genTableSum genHKDSum genHKDTest)
-- tableProduct :: TableProduct Name
-- tableProduct = makeSchema "tableProduct"
-- genTableProduct :: Hedgehog.MonadGen m => m (TableProduct Result)
-- genTableProduct = TableProduct
-- <$> Gen.choice
-- [ BarbieSumA <$> Gen.bool <*> Gen.text (Range.linear 0 10) Gen.alpha
-- , BarbieSumB
-- , BarbieSumC <$> Gen.text (Range.linear 0 10) Gen.alpha
-- ]
-- <*> genTableList
-- <*> Gen.list (Range.linear 0 10) (liftA3 (,,) genTableSum)
data TableTestB f = TableTestB
{ foo :: f Bool
, bar :: f (Maybe Bool)
}
deriving stock Generic
deriving anyclass Rel8able
data NestedTableTestB f = NestedTableTestB
{ foo :: f Bool
, bar :: f (Maybe Bool)
, baz :: Column f Char
, nest :: TableTestB f
}
deriving stock Generic
deriving anyclass Rel8able
newtype IdRecord a f = IdRecord { recordId :: Column f a }
deriving stock Generic
instance DBType a => Rel8able (IdRecord a)
type Nest :: KRel8able -> KRel8able -> KRel8able
data Nest t u f = Nest
{ foo :: t f
, bar :: u f
}
deriving stock Generic
deriving anyclass Rel8able
data TableType f = TableType
{ bool :: Column f Bool
, char :: Column f Char
, int16 :: Column f Int16
, int32 :: Column f Int32
, int64 :: Column f Int64
, float :: Column f Float
, double :: Column f Double
, scientific :: Column f Scientific
, fixed :: Column f (Fixed E2)
, utctime :: Column f UTCTime
, day :: Column f Day
, localtime :: Column f LocalTime
, timeofday :: Column f TimeOfDay
, calendardifftime :: Column f CalendarDiffTime
, text :: Column f Text
, lazytext :: Column f LT.Text
, citext :: Column f (CI Text)
, cilazytext :: Column f (CI LT.Text)
, bytestring :: Column f ByteString
, lazybytestring :: Column f LB.ByteString
, uuid :: Column f UUID
, value :: Column f Value
} deriving stock (Generic)
deriving anyclass instance Rel8able TableType
deriving stock instance f ~ Result => Show (TableType f)
deriving stock instance f ~ Result => Eq (TableType f)
-- deriving stock instance f ~ Result => Ord (TableType f)
tableType :: TableSchema (TableType Name)
tableType = makeSchema "tableType"
badTableType :: TableSchema (TableProduct Name)
badTableType = makeSchema "tableType"
genTableType :: Hedgehog.MonadGen m => m (TableType Result)
genTableType = do
bool <- Gen.bool
char <- Gen.alpha
int16 <- Gen.int16 range
int32 <- Gen.int32 range
int64 <- Gen.int64 range
float <- Gen.float linearFrac
double <- Gen.double linearFrac
scientific <- fromFloatDigits <$> Gen.realFloat linearFrac
utctime <- UTCTime <$> (toEnum <$> Gen.integral range) <*> fmap secondsToDiffTime (Gen.integral range)
day <- toEnum <$> Gen.integral range
localtime <- LocalTime <$> (toEnum <$> Gen.integral range) <*> timeOfDay
timeofday <- timeOfDay
text <- Gen.text range Gen.alpha
lazytext <- LT.fromStrict <$> Gen.text range Gen.alpha
citext <- CI.mk <$> Gen.text range Gen.alpha
cilazytext <- CI.mk <$> LT.fromStrict <$> Gen.text range Gen.alpha
bytestring <- Gen.bytes range
lazybytestring <- LB.fromStrict <$> Gen.bytes range
uuid <- UUID.fromWords <$> Gen.word32 range <*> Gen.word32 range <*> Gen.word32 range <*> Gen.word32 range
fixed <- MkFixed <$> Gen.integral range
value <- Gen.choice
[ Object <$> Aeson.fromMapText <$> Map.fromList <$> Gen.list range (liftA2 (,) (Gen.text range Gen.alpha) (pure Null))
, Array <$> Vector.fromList <$> Gen.list range (pure Null)
, String <$> Gen.text range Gen.alpha
, Number <$> fromFloatDigits <$> Gen.realFloat linearFrac
, Bool <$> Gen.bool
, pure Null
]
calendardifftime <- CalendarDiffTime <$> Gen.integral range <*> (secondsToNominalDiffTime <$> Gen.realFrac_ linearFrac)
pure TableType {..}
where
timeOfDay :: Hedgehog.MonadGen m => m TimeOfDay
timeOfDay = TimeOfDay <$> Gen.integral range <*> Gen.integral range <*> Gen.realFrac_ linearFrac
range :: Integral a => Range.Range a
range = Range.linear 0 10
linearFrac :: (Fractional a, Ord a) => Range.Range a
linearFrac = Range.linearFrac 0 10
data TableNumeric f = TableNumeric
{ foo :: Column f (Fixed E2)
} deriving stock (Generic)
deriving anyclass instance Rel8able TableNumeric
deriving stock instance f ~ Result => Show (TableNumeric f)
deriving stock instance f ~ Result => Eq (TableNumeric f)
tableNumeric :: TableSchema (TableNumeric Name)
tableNumeric = makeSchema "tableNumeric"
data TableChar f = TableChar
{ foo :: Column f Char
} deriving stock (Generic)
deriving anyclass instance Rel8able TableChar
deriving stock instance f ~ Result => Show (TableChar f)
deriving stock instance f ~ Result => Eq (TableChar f)
tableChar :: TableSchema (TableChar Name)
tableChar = makeSchema "tableChar"