aboutsummaryrefslogtreecommitdiff
path: root/tests/Test
diff options
context:
space:
mode:
Diffstat (limited to 'tests/Test')
-rw-r--r--tests/Test/FragmentSpec.hs97
-rw-r--r--tests/Test/KitchenSinkSpec.hs33
2 files changed, 110 insertions, 20 deletions
diff --git a/tests/Test/FragmentSpec.hs b/tests/Test/FragmentSpec.hs
new file mode 100644
index 0000000..7b2bb92
--- /dev/null
+++ b/tests/Test/FragmentSpec.hs
@@ -0,0 +1,97 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE QuasiQuotes #-}
+module Test.FragmentSpec
+ ( spec
+ ) where
+
+import Data.Aeson (Value(..), object, (.=))
+import qualified Data.HashMap.Strict as HashMap
+import Data.List.NonEmpty (NonEmpty(..))
+import Data.Text (Text)
+import Language.GraphQL
+import qualified Language.GraphQL.Schema as Schema
+import Test.Hspec (Spec, describe, it, shouldBe, shouldNotSatisfy)
+import Text.RawString.QQ (r)
+
+size :: Schema.Resolver IO
+size = Schema.scalar "size" $ return ("L" :: Text)
+
+circumference :: Schema.Resolver IO
+circumference = Schema.scalar "circumference" $ return (60 :: Int)
+
+garment :: Text -> Schema.Resolver IO
+garment typeName = Schema.object "garment" $ return
+ [ if typeName == "Hat" then circumference else size
+ , Schema.scalar "__typename" $ return typeName
+ ]
+
+inlineQuery :: Text
+inlineQuery = [r|{
+ garment {
+ ... on Hat {
+ circumference
+ }
+ ... on Shirt {
+ size
+ }
+ }
+}|]
+
+spec :: Spec
+spec = describe "Inline fragment executor" $ do
+ it "chooses the first selection if the type matches" $ do
+ actual <- graphql (garment "Hat" :| []) inlineQuery
+ let expected = object
+ [ "data" .= object
+ [ "garment" .= object
+ [ "circumference" .= (60 :: Int)
+ ]
+ ]
+ ]
+ in actual `shouldBe` expected
+
+ it "chooses the last selection if the type matches" $ do
+ actual <- graphql (garment "Shirt" :| []) inlineQuery
+ let expected = object
+ [ "data" .= object
+ [ "garment" .= object
+ [ "size" .= ("L" :: Text)
+ ]
+ ]
+ ]
+ 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
+
+ it "evaluates fragments on Query" $ do
+ let query = [r|{
+ ... {
+ size
+ }
+ }|]
+
+ actual <- graphql (size :| []) query
+ actual `shouldNotSatisfy` hasErrors
+ where
+ hasErrors (Object object') = HashMap.member "errors" object'
+ hasErrors _ = True
diff --git a/tests/Test/KitchenSinkSpec.hs b/tests/Test/KitchenSinkSpec.hs
index ae3c2c4..674f85b 100644
--- a/tests/Test/KitchenSinkSpec.hs
+++ b/tests/Test/KitchenSinkSpec.hs
@@ -6,19 +6,13 @@ module Test.KitchenSinkSpec
import qualified Data.Text.IO as Text.IO
import qualified Data.Text.Lazy.IO as Text.Lazy.IO
+import qualified Data.Text.Lazy as Lazy (Text)
import qualified Language.GraphQL.Encoder as Encoder
import qualified Language.GraphQL.Parser as Parser
import Paths_graphql (getDataFileName)
-import Test.Hspec ( Spec
- , describe
- , it
- )
-import Test.Hspec.Expectations ( expectationFailure
- , shouldBe
- )
-import Text.Megaparsec ( errorBundlePretty
- , parse
- )
+import Test.Hspec (Spec, describe, it)
+import Test.Hspec.Megaparsec (parseSatisfies)
+import Text.Megaparsec (parse)
import Text.RawString.QQ (r)
spec :: Spec
@@ -26,17 +20,12 @@ spec = describe "Kitchen Sink" $ do
it "minifies the query" $ do
dataFileName <- getDataFileName "tests/data/kitchen-sink.graphql"
minFileName <- getDataFileName "tests/data/kitchen-sink.min.graphql"
- actual <- Text.IO.readFile dataFileName
expected <- Text.Lazy.IO.readFile minFileName
- either
- (expectationFailure . errorBundlePretty)
- (flip shouldBe expected . Encoder.document Encoder.minified)
- $ parse Parser.document dataFileName actual
+ shouldNormalize Encoder.minified dataFileName expected
it "pretty prints the query" $ do
dataFileName <- getDataFileName "tests/data/kitchen-sink.graphql"
- actual <- Text.IO.readFile dataFileName
let expected = [r|query queryName($foo: ComplexType, $site: Site = MOBILE) {
whoever123is: node(id: [123, 456]) {
id
@@ -70,7 +59,11 @@ fragment frag on Friend {
}
|]
- either
- (expectationFailure . errorBundlePretty)
- (flip shouldBe expected . Encoder.document Encoder.pretty)
- $ parse Parser.document dataFileName actual
+ shouldNormalize Encoder.pretty dataFileName expected
+
+shouldNormalize :: Encoder.Formatter -> FilePath -> Lazy.Text -> IO ()
+shouldNormalize formatter dataFileName expected = do
+ actual <- Text.IO.readFile dataFileName
+ parse Parser.document dataFileName actual `parseSatisfies` condition
+ where
+ condition = (expected ==) . Encoder.document formatter