diff options
Diffstat (limited to 'tests/Test')
| -rw-r--r-- | tests/Test/FragmentSpec.hs | 97 | ||||
| -rw-r--r-- | tests/Test/KitchenSinkSpec.hs | 33 |
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 |
