Skip to content

Commit 08d2f56

Browse files
Antoine Vandecrèmeteto
Antoine Vandecrème
authored andcommitted
Fix anyOf schema validation
1 parent 970ee64 commit 08d2f56

File tree

2 files changed

+24
-7
lines changed

2 files changed

+24
-7
lines changed

src/Data/OpenApi/Internal/Schema/Validation.hs

+5-2
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,14 @@ import Prelude ()
2828
import Prelude.Compat
2929

3030
import Control.Applicative
31-
import Control.Lens hiding (allOf)
31+
import Control.Lens hiding (allOf, anyOf)
3232
import Control.Monad (forM, forM_, when)
3333

3434
import Data.Aeson hiding (Result)
3535
#if MIN_VERSION_aeson(2,0,0)
3636
import qualified Data.Aeson.KeyMap as KeyMap
3737
#endif
38-
import Data.Foldable (for_, sequenceA_,
38+
import Data.Foldable (asum, for_, sequenceA_,
3939
traverse_)
4040
#if !MIN_VERSION_aeson(2,0,0)
4141
import Data.HashMap.Strict (HashMap)
@@ -490,6 +490,9 @@ validateSchemaType val = withSchema $ \sch ->
490490
0 -> invalid $ "Value not valid under any of 'oneOf' schemas: " ++ show val
491491
1 -> valid
492492
_ -> invalid $ "Value matches more than one of 'oneOf' schemas: " ++ show val
493+
(view anyOf -> Just variants) -> do
494+
(asum $ (\var -> validateWithSchemaRef var val) <$> variants)
495+
<|> (invalid $ "Value not valid under any of 'anyOf' schemas: " ++ show val)
493496
(view allOf -> Just variants) -> do
494497
-- Default semantics for Validation Monad will abort when at least one
495498
-- variant does not match.

test/Data/OpenApi/Schema/ValidationSpec.hs

+19-5
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ spec = do
9292
prop "(Int, String, Double)" $ shouldValidate (Proxy :: Proxy (Int, String, Double))
9393
prop "(Int, String, Double, [Int])" $ shouldValidate (Proxy :: Proxy (Int, String, Double, [Int]))
9494
prop "(Int, String, Double, [Int], Int)" $ shouldValidate (Proxy :: Proxy (Int, String, Double, [Int], Int))
95+
prop "(String, Paint)" $ shouldValidate (Proxy :: Proxy (String, Paint))
9596
prop "Person" $ shouldValidate (Proxy :: Proxy Person)
9697
prop "Color" $ shouldValidate (Proxy :: Proxy Color)
9798
prop "Paint" $ shouldValidate (Proxy :: Proxy Paint)
@@ -109,6 +110,8 @@ spec = do
109110
prop "invalidPaintToJSON" $ shouldNotValidate invalidPaintToJSON
110111
prop "invalidLightToJSON" $ shouldNotValidate invalidLightToJSON
111112
prop "invalidButtonImagesToJSON" $ shouldNotValidate invalidButtonImagesToJSON
113+
prop "invalidStringPersonToJSON" $ shouldNotValidate $ \(s :: String, p) ->
114+
toJSON (s, toInvalidPersonJSON p)
112115

113116
main :: IO ()
114117
main = hspec spec
@@ -128,12 +131,23 @@ instance ToSchema Person
128131
instance Arbitrary Person where
129132
arbitrary = Person <$> arbitrary <*> arbitrary <*> arbitrary
130133

134+
data InvalidPersonJSON = InvalidPersonJSON
135+
{ invalidName :: String
136+
, invalidPhone :: Integer
137+
, invalidEmail :: Maybe String
138+
} deriving (Show, Generic)
139+
140+
instance ToJSON InvalidPersonJSON
141+
142+
toInvalidPersonJSON :: Person -> InvalidPersonJSON
143+
toInvalidPersonJSON Person{..} = InvalidPersonJSON
144+
{ invalidName = name
145+
, invalidPhone = phone
146+
, invalidEmail = email
147+
}
148+
131149
invalidPersonToJSON :: Person -> Value
132-
invalidPersonToJSON Person{..} = object
133-
[ stringToKey "personName" .= toJSON name
134-
, stringToKey "personPhone" .= toJSON phone
135-
, stringToKey "personEmail" .= toJSON email
136-
]
150+
invalidPersonToJSON = toJSON . toInvalidPersonJSON
137151

138152
-- ========================================================================
139153
-- Color (enum)

0 commit comments

Comments
 (0)