hedgehog-gen-json-0.1.0: test/Hedgehog/Gen/JSON/Constrained/Internal/InternalSpec.hs
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Hedgehog.Gen.JSON.Constrained.Internal.InternalSpec
( tests
) where
import qualified Data.HashSet as HashSet
import qualified Data.Scientific as Scientific
import qualified Data.Text as Text
import Hedgehog
import qualified Hedgehog.Gen as Gen
import Hedgehog.Gen.JSON.Constrained.Internal
import Hedgehog.Gen.JSON.JSONSchema
import qualified Hedgehog.Range as Range
import Protolude
import Test.Tasty
import Test.Tasty.Hedgehog
import Text.Regex.Posix
prop_genBoundedInteger :: Property
prop_genBoundedInteger =
property $ do
minC <- forAll $ Gen.maybe $ Gen.integral (Range.linear (-500) 500)
maxC <- forAll $ Gen.maybe $ Gen.integral (Range.linear 500 1500)
minExC <- forAll $ Gen.maybe $ Gen.integral (Range.linear (-500) 500)
maxExC <- forAll $ Gen.maybe $ Gen.integral (Range.linear 500 1500)
multC <- forAll $ Gen.maybe $ Gen.integral (Range.linear 1 10)
v <-
forAll $
genBoundedInteger
((NumberConstraintExclusiveMinimum . fromInteger) <$> minExC)
((NumberConstraintMinimum . fromInteger) <$> minC)
((NumberConstraintExclusiveMaximum . fromInteger) <$> maxExC)
((NumberConstraintMaximum . fromInteger) <$> maxC)
((NumberConstraintMultipleOf . fromInteger) <$> multC)
(Range.linear (-5000) 5000)
assert $ maybe True (v >=) minC
assert $ maybe True (v <=) maxC
assert $ maybe True (v >) minExC
assert $ maybe True (v <) maxExC
assert $ maybe True (\m -> v `rem` m == 0) multC
prop_genBoundedReal :: Property
prop_genBoundedReal =
property $ do
minC <- forAll $ Gen.maybe $ Gen.double (Range.linearFrac (-500) 500)
maxC <- forAll $ Gen.maybe $ Gen.double (Range.linearFrac 500 1500)
minExC <- forAll $ Gen.maybe $ Gen.double (Range.linearFrac (-500) 500)
maxExC <- forAll $ Gen.maybe $ Gen.double (Range.linearFrac 500 1500)
v <-
forAll $
genBoundedReal
((NumberConstraintExclusiveMinimum . Scientific.fromFloatDigits) <$> minExC)
((NumberConstraintMinimum . Scientific.fromFloatDigits) <$> minC)
((NumberConstraintExclusiveMaximum . Scientific.fromFloatDigits) <$> maxExC)
((NumberConstraintMaximum . Scientific.fromFloatDigits) <$> maxC)
(Range.linearFrac (-5000) 5000)
assert $ maybe True (v >=) minC
assert $ maybe True (v <=) maxC
assert $ maybe True (v >) minExC
assert $ maybe True (v <) maxExC
prop_genBoundedString :: Property
prop_genBoundedString =
property $ do
minLengthC <- forAll $ Gen.maybe $ Gen.int (Range.linear 0 100)
maxLengthC <- forAll $ Gen.maybe $ Gen.int (Range.linear 100 200)
v <-
forAll $
genBoundedString
((StringConstraintMinLength . fromIntegral) <$> minLengthC)
((StringConstraintMaxLength . fromIntegral) <$> maxLengthC)
(Range.linear 0 500)
assert $ maybe True (\n -> Text.length v >= n) minLengthC
assert $ maybe True (\n -> Text.length v <= n) maxLengthC
prop_genStringFromRegexp :: Property
prop_genStringFromRegexp =
property $ do
let regexp = "[a-zA-Z0-9]{3,9}"
v <- forAll $ genStringFromRegexp regexp
assert $ Text.unpack v =~ Text.unpack regexp
prop_genUniqueItems :: Property
prop_genUniqueItems = property $ do
let gen = Gen.int (Range.linear 0 1000)
generated <- forAll $ genUniqueItems (Range.linear 10 50) gen
assert $ length generated <= 50
assert $ length generated >= 10
(length . HashSet.fromList) generated === length generated
tests :: TestTree
tests =
testGroup
"Constrained.Internal"
[ testProperty "Generates a bounded integer" prop_genBoundedInteger
, testProperty "Generates a bounded real" prop_genBoundedReal
, testProperty "Generates a bounded string" prop_genBoundedString
, testProperty "Generates a string from a regexp" prop_genStringFromRegexp
, testProperty "Generates a list of unique items" prop_genUniqueItems
]