jsons-to-schema-0.1.0.0: test/JSONSchema/Draft4/QuickCheckTests.hs
module JSONSchema.Draft4.QuickCheckTests where
import Protolude
import qualified Data.Aeson as AE
import JSONSchema.Draft4
import qualified JSONSchema.Draft4 as D4
import JSONSchema.Draft4.SchemaGeneration as JSSC
import JSONSchema.Draft4.SchemaGenerationConfig
import qualified GHC.Base
import Test.Hspec
import Test.Hspec.QuickCheck
import Test.QuickCheck
import Test.QuickCheck.Instances ()
import TestUtils
import JSONSchema.Draft4.QuickCheckInstances
tupleTypedArrayConfig :: SchemaGenerationConfig
tupleTypedArrayConfig =
defaultSchemaGenerationConfig {typeArraysAsTuples = True}
sealedObjectPropertiesConfig :: SchemaGenerationConfig
sealedObjectPropertiesConfig =
defaultSchemaGenerationConfig {sealObjectProperties = True}
explainSchemaCounterexample ::
[AE.Value] -> D4.Schema -> SchemaGenerationConfig -> GHC.Base.String
explainSchemaCounterexample jsons schema config =
"The JSONs " <> foldr (<>) "" (fmap printJsonToString jsons) <>
" do not all validate against their generated schema " <>
printSchemaToString schema <>
" when run with configuration " <>
show config
explainSchemaCommutative ::
D4.Schema -> D4.Schema -> GHC.Base.String
explainSchemaCommutative s1 s2 =
"These schemas could not be united commutatively:" <>
printSchemaToString s1 <>
printSchemaToString s2 <>
"When s1 was unified into s2 the result was \n" <>
printSchemaToString (unifySchemas s1 s2) <>
" but when s2 was unified into s1 the result was\n " <>
printSchemaToString (unifySchemas s2 s1)
explainSchemaSelfUnify ::
D4.Schema -> GHC.Base.String
explainSchemaSelfUnify s =
"This schema did not properly unify with itself:" <>
printSchemaToString s <>
"When it was unified with itself it should have stayed the same but the result instead was \n" <>
printSchemaToString (unifySchemas s s)
testPropUnifyEmptySchemaRightIdentity :: Spec
testPropUnifyEmptySchemaRightIdentity =
prop
"will not change a restricted schema when an empty schema is passed in on the right"
p
where
p :: RestrictedSchema -> Bool
p rs = JSSC.unifySchemas (getSchema rs) emptySchema == getSchema rs
testPropUnifyEmptySchemaLeftIdentity :: Spec
testPropUnifyEmptySchemaLeftIdentity =
prop
"will not change a restricted schema when an empty schema is passed in on the left"
p
where
p :: RestrictedSchema -> Bool
p rs = JSSC.unifySchemas emptySchema (getSchema rs) == getSchema rs
-- Unable yet to generate recursively commutative schemas
testSchemaUnificationCommutative :: Spec
testSchemaUnificationCommutative =
modifyMaxSize (const 1) $
prop "schema unification of a schema with non-const properties is commutative" propUnificationCommutative
where
propUnificationCommutative :: CommutativeSchema -> CommutativeSchema -> Property
propUnificationCommutative r1 r2 =
counterexample (explainSchemaCommutative s1 s2) (unifySchemas s1 s2 == unifySchemas s2 s1)
where
s1 = getCommutativeSchema r1
s2 = getCommutativeSchema r2
-- Unable yet to generate nested schemas without `required`, which must not be empty.
testSchemaUnifiedWithSelfIsSelf :: Spec
testSchemaUnifiedWithSelfIsSelf =
modifyMaxSize (const 1) $
prop "when a schema is unified with itself it does not change" propSelfUnification
where
propSelfUnification :: RestrictedSchema -> Property
propSelfUnification s =
counterexample (explainSchemaSelfUnify rs) (unifySchemas rs rs == rs )
where rs = getSchema s
testJsonToSchemaWithConfigValidatesJson :: Spec
testJsonToSchemaWithConfigValidatesJson =
prop
"will generate a schema that can validate the JSON used to generate the schema with a randomized configuration"
configurer
where
configurer :: SchemaGenerationConfig -> Property
configurer config = sizedJsonProp 7 (p config)
p :: SchemaGenerationConfig -> AE.Value -> Property
p config json =
counterexample
(explainSchemaCounterexample [json] schema config)
(schema `validatesAll` [json])
where
schema = JSSC.jsonToSchemaWithConfig config json
testSchemaUnificationValidatesAllJson :: Spec
testSchemaUnificationValidatesAllJson =
prop
"will generate a schema that validates all the JSON documents unified to produce it"
configurer
where
configurer :: SchemaGenerationConfig -> Property
configurer config = sizedJsonsProp 7 (p config)
p :: SchemaGenerationConfig -> [AE.Value] -> Property
p config jsons =
counterexample
(explainSchemaCounterexample jsons schema config)
(schema `validatesAll` jsons)
where
schema =
fromMaybe
(panic "Could not parse schemas")
(JSSC.jsonsToSchemaWithConfig config jsons)