Compare commits

...

3 Commits

5 changed files with 120 additions and 17 deletions

View File

@ -0,0 +1,68 @@
name: Build
on:
push:
pull_request:
branches: [master]
jobs:
audit:
runs-on: alpine
steps:
- name: Set up environment
shell: ash {0}
run: |
apk add --no-cache git bash curl build-base readline-dev openssl-dev zlib-dev libpq-dev gmp-dev
- name: Prepare system
run: |
curl --create-dirs --output-dir \
~/.ghcup/bin https://downloads.haskell.org/~ghcup/0.1.19.5/x86_64-linux-ghcup-0.1.19.5 -o ghcup
chmod +x ~/.ghcup/bin/ghcup
~/.ghcup/bin/ghcup install ghc 9.4.8
~/.ghcup/bin/ghcup install cabal 3.6.2.0
- uses: actions/checkout@v4
- name: Install dependencies
run: |
~/.ghcup/bin/ghcup run --ghc 9.4.8 --cabal 3.6.2.0 -- cabal update
~/.ghcup/bin/ghcup run --ghc 9.4.8 --cabal 3.6.2.0 -- cabal install hlint --constraint="hlint ==3.6.1"
- run: ~/.cabal/bin/hlint -- src tests
test:
runs-on: alpine
steps:
- name: Set up environment
shell: ash {0}
run: |
apk add --no-cache git bash curl build-base readline-dev openssl-dev zlib-dev libpq-dev gmp-dev
- name: Prepare system
run: |
curl --create-dirs --output-dir \
~/.ghcup/bin https://downloads.haskell.org/~ghcup/0.1.19.5/x86_64-linux-ghcup-0.1.19.5 -o ghcup
chmod +x ~/.ghcup/bin/ghcup
~/.ghcup/bin/ghcup install ghc 9.4.8
~/.ghcup/bin/ghcup install cabal 3.6.2.0
- uses: actions/checkout@v4
- name: Install dependencies
run: |
~/.ghcup/bin/ghcup run --ghc 9.4.8 --cabal 3.6.2.0 -- cabal update
~/.ghcup/bin/ghcup run --ghc 9.4.8 --cabal 3.6.2.0 -- cabal build graphql-test
- run: ~/.ghcup/bin/ghcup run --ghc 9.4.8 --cabal 3.6.2.0 -- cabal test --test-show-details=direct
doc:
runs-on: alpine
steps:
- name: Set up environment
shell: ash {0}
run: |
apk add --no-cache git bash curl build-base readline-dev openssl-dev zlib-dev libpq-dev gmp-dev
- name: Prepare system
run: |
curl --create-dirs --output-dir \
~/.ghcup/bin https://downloads.haskell.org/~ghcup/0.1.19.5/x86_64-linux-ghcup-0.1.19.5 -o ghcup
chmod +x ~/.ghcup/bin/ghcup
~/.ghcup/bin/ghcup install ghc 9.4.8
~/.ghcup/bin/ghcup install cabal 3.6.2.0
- uses: actions/checkout@v4
- name: Install dependencies
run: ~/.ghcup/bin/ghcup run --ghc 9.4.8 --cabal 3.6.2.0 -- cabal update
- run: ~/.ghcup/bin/ghcup run --ghc 9.4.8 --cabal 3.6.2.0 -- cabal haddock --enable-documentation

View File

@ -10,6 +10,7 @@ and this project adheres to
### Fixed ### Fixed
- `gql` removes not only leading `\n` but also `\r`. - `gql` removes not only leading `\n` but also `\r`.
- Fix non nullable type string representation in executor error messages. - Fix non nullable type string representation in executor error messages.
- Fix input objects not being coerced to lists.
## [1.2.0.1] - 2023-04-25 ## [1.2.0.1] - 2023-04-25
### Fixed ### Fixed

View File

@ -21,7 +21,7 @@ extra-source-files:
CHANGELOG.md CHANGELOG.md
README.md README.md
tested-with: tested-with:
GHC == 9.2.8, GHC == 9.4.7,
GHC == 9.6.3 GHC == 9.6.3
source-repository head source-repository head

View File

@ -664,11 +664,26 @@ variableUsageDifference difference errorMessage = OperationDefinitionRule $ \cas
= filterSelections' selections = filterSelections' selections
>>= lift . mapReaderT (<> mapDirectives directives') . pure >>= lift . mapReaderT (<> mapDirectives directives') . pure
findDirectiveVariables (Full.Directive _ arguments _) = mapArguments arguments findDirectiveVariables (Full.Directive _ arguments _) = mapArguments arguments
mapArguments = Seq.fromList . mapMaybe findArgumentVariables
mapArguments = Seq.fromList . (>>= findArgumentVariables)
mapDirectives = foldMap findDirectiveVariables mapDirectives = foldMap findDirectiveVariables
findArgumentVariables (Full.Argument _ Full.Node{ node = Full.Variable value', ..} _) =
Just (value', [location]) findArgumentVariables (Full.Argument _ Full.Node{node = value, ..} _) =
findArgumentVariables _ = Nothing findValueVariables location value
findValueVariables location (Full.Variable value') = [(value', [location])]
findValueVariables location (Full.List values) =
values
>>= (\(Full.Node{node = value}) -> findValueVariables location value)
findValueVariables _ (Full.Object fields) =
fields
>>= ( \( Full.ObjectField
{ location = location
, value = Full.Node{node = value}
}
) -> findValueVariables location value
)
findValueVariables _ _ = []
makeError operationName (variableName, locations') = Error makeError operationName (variableName, locations') = Error
{ message = errorMessage operationName variableName { message = errorMessage operationName variableName
, locations = locations' , locations = locations'

View File

@ -69,6 +69,7 @@ queryType = Out.ObjectType "Query" Nothing []
, ("throwing", ValueResolver throwingField throwingResolver) , ("throwing", ValueResolver throwingField throwingResolver)
, ("count", ValueResolver countField countResolver) , ("count", ValueResolver countField countResolver)
, ("sequence", ValueResolver sequenceField sequenceResolver) , ("sequence", ValueResolver sequenceField sequenceResolver)
, ("withInputObject", ValueResolver withInputObjectField withInputObjectResolver)
] ]
where where
philosopherField = philosopherField =
@ -89,6 +90,17 @@ queryType = Out.ObjectType "Query" Nothing []
let fieldType = Out.ListType $ Out.NonNullScalarType int let fieldType = Out.ListType $ Out.NonNullScalarType int
in Out.Field Nothing fieldType HashMap.empty in Out.Field Nothing fieldType HashMap.empty
sequenceResolver = pure intSequence sequenceResolver = pure intSequence
withInputObjectResolver = pure $ Type.Int 0
withInputObjectField =
Out.Field Nothing (Out.NonNullScalarType int) $ HashMap.fromList
[("values", In.Argument Nothing withInputObjectArgumentType Nothing)]
withInputObjectArgumentType = In.NonNullListType
$ In.NonNullInputObjectType inputObjectType
inputObjectType :: In.InputObjectType
inputObjectType = In.InputObjectType "InputObject" Nothing $
HashMap.singleton "name" $
In.InputField Nothing (In.NonNullScalarType int) Nothing
intSequence :: Value intSequence :: Value
intSequence = Type.List [Type.Int 1, Type.Int 2, Type.Int 3] intSequence = Type.List [Type.Int 1, Type.Int 2, Type.Int 3]
@ -328,18 +340,6 @@ spec =
sourceQuery = "{ philosopher { majorWork { title } } }" sourceQuery = "{ philosopher { majorWork { title } } }"
in sourceQuery `shouldResolveTo` expected in sourceQuery `shouldResolveTo` expected
it "gives location information for invalid scalar arguments" $
let data'' = Object $ HashMap.singleton "philosopher" Null
executionErrors = pure $ Error
{ message =
"Argument \"id\" has invalid type. Expected type ID, found: True."
, locations = [Location 1 15]
, path = [Segment "philosopher"]
}
expected = Response data'' executionErrors
sourceQuery = "{ philosopher(id: true) { lastName } }"
in sourceQuery `shouldResolveTo` expected
it "gives location information for failed result coercion" $ it "gives location information for failed result coercion" $
let data'' = Object $ HashMap.singleton "philosopher" Null let data'' = Object $ HashMap.singleton "philosopher" Null
executionErrors = pure $ Error executionErrors = pure $ Error
@ -389,6 +389,25 @@ spec =
sourceQuery = "{ sequence }" sourceQuery = "{ sequence }"
in sourceQuery `shouldResolveTo` expected in sourceQuery `shouldResolveTo` expected
context "Arguments" $ do
it "gives location information for invalid scalar arguments" $
let data'' = Object $ HashMap.singleton "philosopher" Null
executionErrors = pure $ Error
{ message =
"Argument \"id\" has invalid type. Expected type ID, found: True."
, locations = [Location 1 15]
, path = [Segment "philosopher"]
}
expected = Response data'' executionErrors
sourceQuery = "{ philosopher(id: true) { lastName } }"
in sourceQuery `shouldResolveTo` expected
it "puts an object in a list if needed" $
let data'' = Object $ HashMap.singleton "withInputObject" $ Type.Int 0
expected = Response data'' mempty
sourceQuery = "{ withInputObject(values: { name: 0 }) }"
in sourceQuery `shouldResolveTo` expected
context "queryError" $ do context "queryError" $ do
let namedQuery name = "query " <> name <> " { philosopher(id: \"1\") { interest } }" let namedQuery name = "query " <> name <> " { philosopher(id: \"1\") { interest } }"
twoQueries = namedQuery "A" <> " " <> namedQuery "B" twoQueries = namedQuery "A" <> " " <> namedQuery "B"