orville-postgresql-1.1.0.0: test/Test/Expr/ConditionalExpr.hs
module Test.Expr.ConditionalExpr
( conditionalTests
)
where
import qualified Data.ByteString.Char8 as B8
import qualified Data.List.NonEmpty as NE
import GHC.Stack (HasCallStack, withFrozenCallStack)
import qualified Hedgehog as HH
import qualified Orville.PostgreSQL.Expr as Expr
import qualified Orville.PostgreSQL.Raw.RawSql as RawSql
import qualified Orville.PostgreSQL.Raw.SqlValue as SqlValue
import qualified Test.Property as Property
conditionalTests :: Property.Group
conditionalTests =
Property.group
"Expr - Conditional"
[ prop_caseWithNoElse
, prop_caseWithElse
, prop_caseMultipleWhenWithElse
]
prop_caseWithNoElse :: Property.NamedProperty
prop_caseWithNoElse =
let
whenTrueThen1 =
Expr.whenExpr (Expr.literalBooleanExpr True) (Expr.valueExpression $ SqlValue.fromInt32 1)
caseExpr = Expr.caseExpr (pure whenTrueThen1) Nothing
in
Property.singletonNamedProperty "caseExpr with a trivial WHEN and no ELSE generates expected sql." $
assertConditionalEquals
"CASE WHEN TRUE THEN $1 END"
caseExpr
prop_caseWithElse :: Property.NamedProperty
prop_caseWithElse =
let
firstEqualsSecond =
Expr.equals (Expr.valueExpression $ SqlValue.fromInt32 1) (Expr.valueExpression $ SqlValue.fromInt32 1)
whenExpr =
Expr.whenExpr firstEqualsSecond (Expr.valueExpression $ SqlValue.fromInt32 1)
caseExpr = Expr.caseExpr (pure whenExpr) (Just . Expr.valueExpression $ SqlValue.fromInt32 1)
in
Property.singletonNamedProperty "caseExpr with a simple WHEN and simple ELSE generates expected sql." $
assertConditionalEquals
"CASE WHEN ($1) = ($2) THEN $3 ELSE $4 END"
caseExpr
prop_caseMultipleWhenWithElse :: Property.NamedProperty
prop_caseMultipleWhenWithElse =
let
firstVal = Expr.valueExpression $ SqlValue.fromInt32 1
secondVal = Expr.valueExpression $ SqlValue.fromInt32 1
firstGreaterSecond =
Expr.greaterThan firstVal secondVal
firstLessSecond =
Expr.lessThan firstVal secondVal
whenGreaterExpr =
Expr.whenExpr firstGreaterSecond (Expr.valueExpression $ SqlValue.fromInt32 1)
whenLessExpr =
Expr.whenExpr firstLessSecond (Expr.valueExpression $ SqlValue.fromInt32 1)
caseExpr = Expr.caseExpr (whenGreaterExpr NE.:| [whenLessExpr]) (Just . Expr.valueExpression $ SqlValue.fromInt32 1)
in
Property.singletonNamedProperty "caseExpr with a simple WHEN and simple ELSE generates expected sql." $
assertConditionalEquals
"CASE WHEN ($1) > ($2) THEN $3 WHEN ($4) < ($5) THEN $6 ELSE $7 END"
caseExpr
assertConditionalEquals :: (HH.MonadTest m, HasCallStack) => String -> Expr.ValueExpression -> m ()
assertConditionalEquals valueExpressionStr valueExpr =
withFrozenCallStack $
RawSql.toExampleBytes valueExpr HH.=== B8.pack valueExpressionStr