@@ -13,9 +13,9 @@ import Protolude
13
13
import Data.Aeson (Value (Null ), toJSON , object , (.=) )
14
14
import qualified Data.Map as Map
15
15
import GraphQL (makeSchema , compileQuery , executeQuery , interpretAnonymousQuery , interpretQuery )
16
- import GraphQL.API (Object , Field , Argument , (:>) , Defaultable (.. ), HasAnnotatedInputType (.. ))
16
+ import GraphQL.API (Object , Field , List , Argument , (:>) , Defaultable (.. ), HasAnnotatedInputType (.. ))
17
17
import GraphQL.Internal.Syntax.AST (Variable (.. ))
18
- import GraphQL.Resolver ((:<>) (.. ), Handler )
18
+ import GraphQL.Resolver ((:<>) (.. ), Handler , unionValue )
19
19
import GraphQL.Value (ToValue (.. ), FromValue (.. ), makeName )
20
20
import Test.Tasty (TestTree )
21
21
import Test.Tasty.Hspec (testSpec , describe , it , shouldBe )
@@ -36,6 +36,8 @@ import ExampleSchema
36
36
type QueryRoot = Object " QueryRoot" '[]
37
37
'[ Field " dog" Dog
38
38
, Argument " dog" DogStuff :> Field " describeDog" Text
39
+ , Field " catOrDog" CatOrDog
40
+ , Field " catOrDogList" (List CatOrDog )
39
41
]
40
42
41
43
-- | An object that is passed as an argument. i.e. an input object.
@@ -49,6 +51,25 @@ instance Defaultable DogStuff where
49
51
defaultFor " dog" = pure DogStuff { toy = " shoe" , likesTreats = False }
50
52
defaultFor _ = empty
51
53
54
+ catOrDog :: Handler IO CatOrDog
55
+ catOrDog = do
56
+ name <- pure " MonadicFelix" -- we can do monadic actions
57
+ unionValue @ Cat (catHandler name Nothing 15 )
58
+
59
+ catOrDogList :: Handler IO (List CatOrDog )
60
+ catOrDogList =
61
+ pure [ unionValue @ Cat (catHandler " Felix the Cat" (Just " felix" ) 42 )
62
+ , unionValue @ Cat (catHandler " Henry" Nothing 10 )
63
+ , unionValue @ Dog (viewServerDog mortgage)
64
+ ]
65
+
66
+ catHandler :: Text -> Maybe Text -> Int32 -> Handler IO Cat
67
+ catHandler name nickName meowVolume = pure $
68
+ pure name :<>
69
+ pure (pure <$> nickName) :<>
70
+ pure . const False :<> -- doesn't know any commands
71
+ pure meowVolume
72
+
52
73
-- | Our server's internal representation of a 'Dog'.
53
74
data ServerDog
54
75
= ServerDog
@@ -87,7 +108,7 @@ describeDog (DogStuff toy likesTreats)
87
108
| otherwise = pure $ " their favorite toy is a " <> toy
88
109
89
110
rootHandler :: ServerDog -> Handler IO QueryRoot
90
- rootHandler dog = pure $ viewServerDog dog :<> describeDog
111
+ rootHandler dog = pure $ viewServerDog dog :<> describeDog :<> catOrDog :<> catOrDogList
91
112
92
113
-- | jml has a stuffed black dog called "Mortgage".
93
114
mortgage :: ServerDog
@@ -243,8 +264,6 @@ tests = testSpec "End-to-end tests" $ do
243
264
]
244
265
toJSON (toValue response) `shouldBe` expected
245
266
it " Handles fairly complex queries" $ do
246
- -- TODO: jml would like to put some union checks in here, but we don't
247
- -- have any unions reachable from Dog!
248
267
let query = [r |{
249
268
dog {
250
269
callsign: name
@@ -276,6 +295,41 @@ tests = testSpec "End-to-end tests" $ do
276
295
]
277
296
]
278
297
toJSON (toValue response) `shouldBe` expected
298
+ it " Lets you query union types" $ do
299
+ let query = " { catOrDog { ... on Cat { name meowVolume } ... on Dog { barkVolume } } }"
300
+ response <- interpretAnonymousQuery @ QueryRoot (rootHandler mortgage) query
301
+ let expected =
302
+ object
303
+ [ " data" .= object
304
+ [ " catOrDog" .= object
305
+ [ " name" .= (" MonadicFelix" :: Text )
306
+ , " meowVolume" .= (15 :: Float )
307
+ ]
308
+ ]
309
+ ]
310
+ toJSON (toValue response) `shouldBe` expected
311
+ it " Lets you query lists of union types" $ do
312
+ let query = " { catOrDogList { ... on Cat { name meowVolume } ... on Dog { barkVolume } } }"
313
+ response <- interpretAnonymousQuery @ QueryRoot (rootHandler mortgage) query
314
+ let expected =
315
+ object
316
+ [ " data" .= object
317
+ [ " catOrDogList" .=
318
+ [ object
319
+ [ " name" .= (" Felix the Cat" :: Text )
320
+ , " meowVolume" .= (42 :: Float )
321
+ ]
322
+ , object
323
+ [ " name" .= (" Henry" :: Text )
324
+ , " meowVolume" .= (10 :: Float )
325
+ ]
326
+ , object
327
+ [ " barkVolume" .= (0 :: Float )
328
+ ]
329
+ ]
330
+ ]
331
+ ]
332
+ toJSON (toValue response) `shouldBe` expected
279
333
describe " interpretQuery" $ do
280
334
it " Handles the simplest named query" $ do
281
335
let query = [r |query myQuery {
0 commit comments