Fail on cyclic fragments, fix #22

This commit is contained in:
Eugen Wissner 2019-11-13 20:40:09 +01:00
parent 31c516927d
commit 115aa02672
2 changed files with 36 additions and 10 deletions

View File

@ -94,17 +94,21 @@ collectFragments = do
_ <- fragmentDefinition nextValue _ <- fragmentDefinition nextValue
collectFragments collectFragments
fragmentDefinition :: Full.FragmentDefinition -> TransformT (NonEmpty Core.Selection) fragmentDefinition ::
Full.FragmentDefinition ->
TransformT (NonEmpty Core.Selection)
fragmentDefinition (Full.FragmentDefinition name _tc _dirs sels) = do fragmentDefinition (Full.FragmentDefinition name _tc _dirs sels) = do
modify deleteFragmentDefinition
selections <- traverse selection sels selections <- traverse selection sels
let newValue = either id pure =<< selections let newValue = either id pure =<< selections
modify $ moveFragment newValue modify $ insertFragment newValue
liftJust newValue liftJust newValue
where where
moveFragment newValue (Replacement fullFragments emptyFragDefs) = deleteFragmentDefinition (Replacement fragments' fragmentDefinitions') =
let newFragments = HashMap.insert name newValue fullFragments Replacement fragments' $ HashMap.delete name fragmentDefinitions'
newDefinitions = HashMap.delete name emptyFragDefs insertFragment newValue (Replacement fragments' fragmentDefinitions') =
in Replacement newFragments newDefinitions let newFragments = HashMap.insert name newValue fragments'
in Replacement newFragments fragmentDefinitions'
field :: Full.Field -> TransformT Core.Field field :: Full.Field -> TransformT Core.Field
field (Full.Field a n args _dirs sels) = do field (Full.Field a n args _dirs sels) = do

View File

@ -10,7 +10,13 @@ import Data.List.NonEmpty (NonEmpty(..))
import Data.Text (Text) import Data.Text (Text)
import Language.GraphQL import Language.GraphQL
import qualified Language.GraphQL.Schema as Schema import qualified Language.GraphQL.Schema as Schema
import Test.Hspec (Spec, describe, it, shouldBe, shouldNotSatisfy) import Test.Hspec ( Spec
, describe
, it
, shouldBe
, shouldSatisfy
, shouldNotSatisfy
)
import Text.RawString.QQ (r) import Text.RawString.QQ (r)
size :: Schema.Resolver IO size :: Schema.Resolver IO
@ -37,6 +43,10 @@ inlineQuery = [r|{
} }
}|] }|]
hasErrors :: Value -> Bool
hasErrors (Object object') = HashMap.member "errors" object'
hasErrors _ = True
spec :: Spec spec :: Spec
spec = describe "Inline fragment executor" $ do spec = describe "Inline fragment executor" $ do
it "chooses the first selection if the type matches" $ do it "chooses the first selection if the type matches" $ do
@ -91,9 +101,7 @@ spec = describe "Inline fragment executor" $ do
}|] }|]
actual <- graphql (size :| []) query actual <- graphql (size :| []) query
let hasErrors (Object object') = HashMap.member "errors" object' actual `shouldNotSatisfy` hasErrors
hasErrors _ = True
in actual `shouldNotSatisfy` hasErrors
it "evaluates nested fragments" $ do it "evaluates nested fragments" $ do
let query = [r| let query = [r|
@ -140,3 +148,17 @@ spec = describe "Inline fragment executor" $ do
] ]
] ]
in actual `shouldBe` expected in actual `shouldBe` expected
it "rejects recursive" $ do
let query = [r|
{
...circumferenceFragment
}
fragment circumferenceFragment on Hat {
...circumferenceFragment
}
|]
actual <- graphql (circumference :| []) query
actual `shouldSatisfy` hasErrors