postgresql-syntax-0.5.0.2: hspec-test/Helpers/Specs.hs
{-# LANGUAGE AllowAmbiguousTypes #-}
module Helpers.Specs
( itSatisfiesIsAst,
itSatisfiesCanonicalizes,
itSatisfiesRefines,
itSatisfiesExtends,
itSatisfiesArbitrary,
itParses,
itRejects,
itReportsError,
itReportsSourcePosError,
itParsesWithin,
-- * Settings-aware variants
itParsesWith,
itRejectsWith,
)
where
import qualified Data.Text as Text
import qualified Helpers.Expectations as Expectations
import PostgresqlSyntax.Algebra
import PostgresqlSyntax.Settings (Settings)
import Prelude
import Test.Hspec
import Test.Hspec.QuickCheck (prop)
import qualified Test.QuickCheck as Qc
itSatisfiesIsAst :: forall a. (IsAst a, Eq a, Show a, Qc.Arbitrary a) => Spec
itSatisfiesIsAst =
describe "IsAst" $ for_ (isAstProperties @a) (uncurry prop)
itSatisfiesCanonicalizes :: forall a. (Canonicalizes a, Eq a, Show a, Qc.Arbitrary a) => Spec
itSatisfiesCanonicalizes =
describe "Canonicalizes" $ for_ (canonicalizesProperties @a) (uncurry prop)
itSatisfiesRefines :: forall sub sup. (Refines sub sup, IsAst sub, Eq sub, Show sub, Qc.Arbitrary sub) => Spec
itSatisfiesRefines =
describe "Refines" $ for_ (refinesProperties @sub @sup) (uncurry prop)
itSatisfiesExtends :: forall base ext. (Extends base ext, IsAst base, Eq base, Show base, Qc.Arbitrary base) => Spec
itSatisfiesExtends =
describe "Extends" $ for_ (extendedByProperties @base @ext) (uncurry prop)
itSatisfiesArbitrary :: forall a. (IsAst a, Show a, Qc.Arbitrary a) => Spec
itSatisfiesArbitrary =
describe "Arbitrary" $ do
prop "Terminates at size 0" terminatesAtZero
prop "Grows boundedly" growsBounded
where
terminatesAtZero =
Qc.forAll (Qc.resize 0 (Qc.arbitrary @a)) $ \x ->
let sql = toText mempty x
len = Text.length sql
in Qc.counterexample
("rendered " <> show len <> " chars at size 0 (max " <> show zeroSizeMaxLen <> ")" <> "\n" <> Text.unpack sql)
(len <= zeroSizeMaxLen)
where
zeroSizeMaxLen = 500 :: Int
growsBounded =
Qc.forAll (Qc.resize maxGenSize (Qc.arbitrary @a)) $ \x ->
let sql = toText mempty x
len = Text.length sql
in Qc.counterexample
("rendered " <> show len <> " chars at size " <> show maxGenSize <> " (max " <> show maxGenSizeMaxLen <> ")")
(len <= maxGenSizeMaxLen)
where
maxGenSize = 100 :: Int
maxGenSizeMaxLen = 1000000 :: Int
itParses :: forall a. (HasCallStack, IsAst a) => Text -> Spec
itParses sql =
describe (Text.unpack sql) $ do
it "Parses" (Expectations.parsesTo @a sql)
itRejects :: forall a. (HasCallStack, IsAst a, Show a) => Text -> Spec
itRejects sql =
describe (Text.unpack sql) $ do
it "Rejects" (Expectations.rejects @a sql)
itReportsError :: forall a. (HasCallStack, IsAst a) => Text -> String -> Spec
itReportsError sql expected =
describe (Text.unpack sql) $ do
it ("Reports error: " <> expected) (Expectations.reportsError @a sql expected)
-- | Like 'itReportsError' but checks 'PostgresqlSyntax.Algebra.parseWithSourcePosError''s
-- 'Text.Megaparsec.SourcePos'-based errors instead.
itReportsSourcePosError :: forall a. (HasCallStack, IsAst a) => Text -> String -> Spec
itReportsSourcePosError sql expected =
describe (Text.unpack sql) $ do
it ("Reports error: " <> expected) (Expectations.reportsSourcePosError @a sql expected)
itParsesWithin :: forall a. (HasCallStack, IsAst a) => Int -> Text -> Spec
itParsesWithin seconds sql =
describe (Text.unpack sql) $ do
it ("Parses within " <> show seconds <> " seconds") (Expectations.parsesWithin @a seconds sql)
-- | Wraps 'Expectations.parsesToWith' as a standalone 'Spec'.
itParsesWith :: forall a. (HasCallStack, IsAst a) => Settings -> Text -> Spec
itParsesWith settings sql =
describe (Text.unpack sql) $ do
it "Parses" (Expectations.parsesToWith @a settings sql)
-- | Wraps 'Expectations.rejectsWith' as a standalone 'Spec'.
itRejectsWith :: forall a. (HasCallStack, IsAst a, Show a) => Settings -> Text -> Spec
itRejectsWith settings sql =
describe (Text.unpack sql) $ do
it "Rejects" (Expectations.rejectsWith @a settings sql)