module Main where import Protolude import Data.Aeson import qualified Data.List.NonEmpty as NE import qualified System.Timeout as TO import Test.Hspec import Test.QuickCheck (property) import qualified JSONSchema.Draft4 as D4 import qualified JSONSchema.Types as JT import qualified Local.Failure import qualified Local.Validation import qualified Local.Reference import Shared -- Examples import qualified AlternateSchema import qualified Simple import qualified TwoStep dir :: FilePath dir = "JSON-Schema-Test-Suite/tests/draft4" supplementDir :: FilePath supplementDir = "test/supplement" main :: IO () main = do -- Language agnostic tests ts <- readSchemaTests dir (\a -> not (isHTTPTest a || skipOptional a)) -- Custom supplements to the language agnostic tests supplementTs <- readSchemaTests supplementDir (\a -> not (isHTTPTest a || skipOptional a)) hspec $ do describe "Examples" exampleTests describe "QuickCheck" quickCheckTests describe "Failure" Local.Failure.spec describe "JSONSchema.Validator.Reference" Local.Reference.spec describe "Supplementary validation tests written in Haskell" Local.Validation.spec describe "Supplementary tests written in JSON (using the record based schema)" (traverse_ (toTest (fmap timeout . validate)) supplementTs) describe "Supplementary tests written in JSON (using the 'Value' based schema)" (traverse_ (toTest (fmap timeout . validateExample)) supplementTs) describe "Language agnostic tests (using the record based schema)" (traverse_ (toTest validate) ts) describe "Language agnostic tests (using the 'Value' based schema)" (traverse_ (toTest validateExample) ts) where timeout :: Expectation -> Expectation timeout f = do res <- TO.timeout 3000000 f case res of Nothing -> expectationFailure "timeout expired" Just a -> pure a validate :: D4.Schema -> SchemaTestCase -> Expectation validate s sc = do res <- D4.fetchHTTPAndValidate (D4.SchemaWithURI s Nothing) (_scData sc) let failures = case res of Right () -> mempty Left (D4.HVData a) -> NE.toList (D4._invalidFailures a) other -> panic ("Local.validate error: " <> show other) assertResult sc failures validateExample :: JT.Schema -> SchemaTestCase -> Expectation validateExample s sc = do res <- AlternateSchema.referencesViaHTTP (D4.SchemaWithURI s Nothing) case res of Left e -> panic ("Local.validateExample error: " <> show e) Right schemaMap -> do let failures = AlternateSchema.validate schemaMap (D4.SchemaWithURI s Nothing) (_scData sc) assertResult sc failures quickCheckTests :: Spec quickCheckTests = it "schemas invert through JSON without change" $ do property invertSchema where invertSchema :: D4.Schema -> Bool invertSchema a = Just a == decode (encode a) exampleTests :: Spec exampleTests = do it "Simple.example compiles successfully" Simple.example it "TwoStep.example compiles successfully" TwoStep.example