@@ -14,11 +14,17 @@ import Data.JsonSchema
14import Data.Monoid
14import Data.Monoid
15import Data.Text (Text)
15import Data.Text (Text)
16import qualified Data.Text as T
16import qualified Data.Text as T
17+import Data.Vector (Vector)
17import qualified Data.Vector as V
18import qualified Data.Vector as V
18import System.FilePath ((</>))
19import System.FilePath ((</>))
19−import Test.Framework
20+import Test.Framework (Test)
20−import Test.Framework.Providers.HUnit
21+import Test.Framework.Providers.HUnit (testCase)
21−import qualified Test.HUnit as HU
22+import Test.HUnit hiding (Test)
24+isLocal :: String -> Bool
25+isLocal file = (file /= "definitions.json")
26+ && (file /= "ref.json")
27+ && (file /= "refRemote.json")
23data SchemaTest = SchemaTest
29data SchemaTest = SchemaTest
24 { _stDescription :: Text
30 { _stDescription :: Text
@@ -34,7 +40,7 @@ data SchemaTestCase = SchemaTestCase
35instance FromJSON RawSchema where
41instance FromJSON RawSchema where
36 parseJSON = withObject "Schema" $ \o ->
42 parseJSON = withObject "Schema" $ \o ->
37− return $ RawSchema "" o
43+ return RawSchema { _rsURI = "", _rsObject = o }
39instance FromJSON SchemaTest where
45instance FromJSON SchemaTest where
40 parseJSON = withObject "SchemaTest" $ \o -> SchemaTest
46 parseJSON = withObject "SchemaTest" $ \o -> SchemaTest
@@ -42,11 +48,6 @@ instance FromJSON SchemaTest where
42 <*> o .: "schema"
48 <*> o .: "schema"
43 <*> o .: "tests" -- I wish this were "cases"
49 <*> o .: "tests" -- I wish this were "cases"
45−isLocal :: String -> Bool
46−isLocal file = (file /= "definitions.json")
47− && (file /= "ref.json")
48− && (file /= "refRemote.json")
50readSchemaTests :: String -> [String] -> IO [SchemaTest]
51readSchemaTests :: String -> [String] -> IO [SchemaTest]
51readSchemaTests dir jsonFiles = concatMapM fileToCases jsonFiles
52readSchemaTests dir jsonFiles = concatMapM fileToCases jsonFiles
@@ -68,33 +69,37 @@ readSchemaTests dir jsonFiles = concatMapM fileToCases jsonFiles
68 concatMapM f xs = liftM concat (mapM f xs)
69 concatMapM f xs = liftM concat (mapM f xs)
70toTest :: SchemaTest -> Test
71toTest :: SchemaTest -> Test
71−toTest st = testGroup groupName (mkCase <$> _stCases st)
72+toTest st =
74− groupName = T.unpack $ _stDescription st
73+ testCase (T.unpack $ _stDescription st) $ do
74+ assertEqual "schema validity errors" V.empty (isValidSchema . _stSchema $ st)
75+ forM_ (_stCases st) $ \sc -> do
76+ g <- assertRight =<< fetchRefs draft4 (_stSchema st) H.empty
77+ let es = validate (compile draft4 g $ _stSchema st) (_scData sc)
79+ then assertValid sc es
80+ else assertInvalid sc es
76− mkCase :: SchemaTestCase -> Test
82+assertValid :: SchemaTestCase -> Vector ValErr -> Assertion
77− mkCase sc = testCase caseName assertion
83+assertValid sc es =
78− where
84+ unless (V.length es == 0) $ assertFailure $ unlines
85+ [ " Failed to validate data"
79− caseName = T.unpack $ _scDescription sc
86+ , " Description: " <> T.unpack (_scDescription sc)
80− assertion = if _scValid sc
87+ , " Data: " <> show (_scData sc)
81− then assertValid (_stSchema st) (_scData sc)
88+ , " Errors: " <> show es
82− else assertInvalid (_stSchema st) (_scData sc)
89+ ]
84−assertValid, assertInvalid :: RawSchema -> Value -> HU.Assertion
91+assertInvalid :: SchemaTestCase -> Vector ValErr -> Assertion
85−assertValid r v = do
92+assertInvalid sc es =
86− g <- assertRight =<< fetchRefs draft4 r H.empty
87− let es = validate (compile draft4 g r) v
88− unless (V.length es == 0) $ HU.assertFailure (show es)
93+ unless (V.length es > 0) $ assertFailure $ unlines
89−assertInvalid r v = do
94+ [ " Failed to invalidate data"
90− g <- assertRight =<< fetchRefs draft4 r H.empty
95+ , " Description: " <> T.unpack (_scDescription sc)
91− let es = validate (compile draft4 g r) v
96+ , " Data: " <> show (_scData sc)
92− when (V.length es == 0) $ HU.assertFailure "expected a validation error"
97+ ]
94assertRight :: (Show a) => Either a b -> IO b
99assertRight :: (Show a) => Either a b -> IO b
95assertRight a =
100assertRight a =
96 case a of
101 case a of
97− Left e -> HU.assertFailure (show e) >> fail "assertRight failed"
102+ Left e -> assertFailure (show e) >> fail "assertRight failed"
98 Right b -> return b
103 Right b -> return b
100$(deriveFromJSON defaultOptions { fieldLabelModifier = map toLower . drop 3 } ''SchemaTestCase)
105$(deriveFromJSON defaultOptions { fieldLabelModifier = map toLower . drop 3 } ''SchemaTestCase)