Inline fragments without type

Fixes #11.
This commit is contained in:
Eugen Wissner 2019-10-11 23:28:55 +02:00
parent 856efc5d25
commit 37254c8c95
4 changed files with 37 additions and 14 deletions

View File

@ -12,6 +12,7 @@ All notable changes to this project will be documented in this file.
### Added ### Added
- Module documentation. - Module documentation.
- Inline fragment support.
## [0.5.0.1] - 2019-09-10 ## [0.5.0.1] - 2019-09-10
### Added ### Added

View File

@ -66,20 +66,21 @@ selection
-> Fragmenter -> Fragmenter
-> Full.Selection -> Full.Selection
-> Either [Core.Selection] Core.Selection -> Either [Core.Selection] Core.Selection
selection subs fr (Full.SelectionField fld) = selection subs fr (Full.SelectionField fld)
Right $ Core.SelectionField $ field subs fr fld = Right $ Core.SelectionField $ field subs fr fld
selection _ fr (Full.SelectionFragmentSpread (Full.FragmentSpread n _dirs)) = selection _ fr (Full.SelectionFragmentSpread (Full.FragmentSpread name _))
Left $ Core.SelectionField <$> fr n = Left $ Core.SelectionField <$> fr name
selection subs fr (Full.SelectionInlineFragment fragment) selection subs fr (Full.SelectionInlineFragment fragment)
| (Full.InlineFragment (Just typeCondition) _ selectionSet) <- fragment | (Full.InlineFragment (Just typeCondition) _ selectionSet) <- fragment
= Right $ Core.SelectionFragment $ Core.Fragment typeCondition $ node selectionSet = Right
| otherwise = error "Inline fragments not supported yet" $ Core.SelectionFragment
$ Core.Fragment typeCondition
$ NonEmpty.fromList
$ appendSelection selectionSet
| (Full.InlineFragment Nothing _ selectionSet) <- fragment
= Left $ appendSelection selectionSet
where where
node selections appendSelection = foldr (either (++) (:) . selection subs fr) []
= NonEmpty.fromList
$ foldr (appendSelection . selection subs fr) [] selections
appendSelection (Left x) acc = x ++ acc
appendSelection (Right x) acc = x : acc
-- * Fragment replacement -- * Fragment replacement
@ -96,14 +97,13 @@ defrag subs (Full.DefinitionFragment fragDef) =
fragmentDefinition :: Schema.Subs -> Full.FragmentDefinition -> Fragmenter fragmentDefinition :: Schema.Subs -> Full.FragmentDefinition -> Fragmenter
fragmentDefinition subs (Full.FragmentDefinition name _tc _dirs sels) name' fragmentDefinition subs (Full.FragmentDefinition name _tc _dirs sels) name'
-- TODO: Support fragments within fragments. Fold instead of map.
| name == name' = selection' <$> do | name == name' = selection' <$> do
selections <- NonEmpty.toList $ selection subs mempty <$> sels selections <- NonEmpty.toList $ selection subs mempty <$> sels
either id pure selections either id pure selections
| otherwise = empty | otherwise = empty
where where
selection' (Core.SelectionField field') = field' selection' (Core.SelectionField field') = field'
selection' _ = error "Inline fragments not supported yet" selection' _ = error "Fragments within fragments are not supported yet"
field :: Schema.Subs -> Fragmenter -> Full.Field -> Core.Field field :: Schema.Subs -> Fragmenter -> Full.Field -> Core.Field
field subs fr (Full.Field a n args _dirs sels) = field subs fr (Full.Field a n args _dirs sels) =

View File

@ -1,4 +1,4 @@
resolver: lts-14.7 resolver: lts-14.8
packages: packages:
- . - .

View File

@ -59,3 +59,25 @@ spec = describe "Inline fragment executor" $ do
] ]
] ]
in actual `shouldBe` expected in actual `shouldBe` expected
it "embeds inline fragments without type" $ do
let query = [r|{
garment {
circumference
... {
size
}
}
}|]
resolvers = Schema.object "garment" $ return [circumference, size]
actual <- graphql (resolvers :| []) query
let expected = object
[ "data" .= object
[ "garment" .= object
[ "circumference" .= (60 :: Int)
, "size" .= ("L" :: Text)
]
]
]
in actual `shouldBe` expected