{-# LANGUAGE LambdaCase #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE TypeApplications #-} {-# LANGUAGE OverloadedLists #-} {-# LANGUAGE OverloadedStrings #-} module JsonSchemaSpec (spec, main) where import Data.Aeson as J import Data.Maybe import Data.Proxy import Data.ByteString.Lazy as B import Data.Schematic import Data.Vinyl import JSONSchema.Draft4 as D4 import Test.Hspec type ArraySchema = 'SchemaArray '[ 'AEq 1] ('SchemaNumber '[ 'NGt 10]) type ArrayField = '("foo", ArraySchema) type FieldsSchema = '[ ArrayField, '("bar", 'SchemaOptional ('SchemaText '[ 'TEnum '["foo", "bar"]]))] type SchemaExample = 'SchemaObject FieldsSchema exampleData :: JsonRepr SchemaExample exampleData = withRepr @SchemaExample $ field @"foo" [ReprNumber 13] :& field @"bar" (pure (ReprText "foo")) :& RNil type SchemaArrayExample = 'SchemaObject '[ '("a1", 'SchemaArray '[ 'AGt 1 ] ('SchemaNumber '[])) , '("a2", 'SchemaArray '[ 'AGe 1 ] ('SchemaNumber '[])) , '("a3", 'SchemaArray '[ 'ALt 1 ] ('SchemaNumber '[])) , '("a4", 'SchemaArray '[ 'ALe 1 ] ('SchemaNumber '[])) ] type SchemaNumberExample = 'SchemaObject '[ '("n1", 'SchemaNumber '[ 'NGt 1 ]) , '("n2", 'SchemaNumber '[ 'NGe 1 ]) , '("n3", 'SchemaNumber '[ 'NLt 1 ]) , '("n4", 'SchemaNumber '[ 'NLe 1 ]) ] type SchemaTextExample = 'SchemaObject '[ '("t1", 'SchemaText '[ 'TGt 1 ]) , '("t2", 'SchemaText '[ 'TGe 1 ]) , '("t3", 'SchemaText '[ 'TLt 1 ]) , '("t4", 'SchemaText '[ 'TLe 1 ]) ] spec :: Spec spec = do it "validates simple schema" $ do let schema = D4.SchemaWithURI (fromJust $ toJsonSchema (Proxy @SchemaExample)) Nothing fetchHTTPAndValidate schema (toJSON exampleData) >>= \case Left _ -> fail "failed to validate test example" Right _ -> pure () it "validates schema with arrays" $ do let schema = D4.SchemaWithURI (fromJust $ toJsonSchema (Proxy @SchemaArrayExample)) Nothing obj = withRepr @SchemaArrayExample $ field @"a1" [ReprNumber 13, ReprNumber 13] :& field @"a2" [ReprNumber 13] :& field @"a3" [] :& field @"a4" [ReprNumber 13] :& RNil fetchHTTPAndValidate schema (toJSON obj) >>= \case Left e -> fail "failed to validate test example" Right _ -> pure () it "validates schema with numbers" $ do let schema = D4.SchemaWithURI (fromJust $ toJsonSchema (Proxy @SchemaNumberExample)) Nothing obj = withRepr @SchemaNumberExample $ field @"n1" 1.1 :& field @"n2" 1 :& field @"n3" 0.9 :& field @"n4" 1.0 :& RNil fetchHTTPAndValidate schema (toJSON obj) >>= \case Left e -> fail "failed to validate test example" Right _ -> pure () it "validates schema with strings" $ do let schema = D4.SchemaWithURI (fromJust $ toJsonSchema (Proxy @SchemaTextExample)) Nothing obj = withRepr @SchemaTextExample $ field @"t1" "11" :& field @"t2" "1" :& field @"t3" "" :& field @"t4" "1" :& RNil fetchHTTPAndValidate schema (toJSON obj) >>= \case Left e -> fail "failed to validate test example" Right _ -> pure () main :: IO () main = hspec spec