Skip to content

Commit

Permalink
Merge pull request #146 from evo-company/add-checks-for-nonexistent-f…
Browse files Browse the repository at this point in the history
…ragment

Raise TypeError for nonexistent fragment. Add basic isort config
  • Loading branch information
kindermax authored Dec 21, 2023
2 parents 930cd8c + edcd7a8 commit 64fd267
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 28 deletions.
4 changes: 1 addition & 3 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@ jobs:
draft: false
prerelease: ${{ steps.check_version.outputs.PRERELEASE }}
- name: Set up PDM
uses: pdm-project/setup-pdm@v3
with:
python-version: "3.7"
run: pip install pdm==2.10.4
- name: Publish package distributions to PyPI
run: pdm publish -u "__token__" -P ${{ secrets.TWINE_PASSWORD }}
4 changes: 1 addition & 3 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@ jobs:
with:
python-version: ${{ matrix.python-version }}
- name: Set up PDM
uses: pdm-project/setup-pdm@v3
with:
python-version: ${{ matrix.python-version }}
run: pip install pdm==2.10.4
- name: Install dependencies
run: |
pdm sync -d -G test -G dev
Expand Down
28 changes: 10 additions & 18 deletions hiku/readers/graphql.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,14 @@
from collections import defaultdict

from typing import (
Optional,
Dict,
Iterator,
Tuple,
Union,
List,
cast,
Any,
Set,
)
from typing import Any, cast, Dict, Iterator, List, Optional, Set, Tuple, Union

from graphql.language import ast
from graphql.language.parser import parse

from hiku.utils import ImmutableDict

from ..directives import (
Cached,
Directive,
)
from ..directives import Cached, Directive
from ..operation import Operation, OperationType
from ..query import FieldOrLink, Fragment, Node, Field, Link, merge
from ..query import Field, FieldOrLink, Fragment, Link, merge, Node


def parse_query(src: str) -> ast.DocumentNode:
Expand Down Expand Up @@ -93,7 +80,7 @@ def get(
try:
return self._operations[self._operation_name]
except KeyError:
raise ValueError(
raise TypeError(
"Undefined operation name: {!r}".format(
self._operation_name
)
Expand Down Expand Up @@ -257,6 +244,9 @@ def _collect_fields(
type_name = item.type_condition.name.value
selection_set = item.selection_set
elif isinstance(item, ast.FragmentSpreadNode):
if item.name.value not in fragments_map:
raise TypeError(f'Undefined fragment: "{item.name.value}"')

fragment = fragments_map[item.name.value]
type_name = fragment.type_condition.name.value
selection_set = fragment.selection_set
Expand Down Expand Up @@ -376,6 +366,8 @@ def __init__(
self.pending_fragments: Set[str] = set()

def transform_fragment(self, name: str) -> List[Union[Field, Link]]:
if name not in self.fragments_map:
raise TypeError(f'Undefined fragment: "{name}"')
return self.visit(self.fragments_map[name])

def visit_operation_definition(
Expand Down
5 changes: 5 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -251,3 +251,8 @@ ignore_missing_imports = true
[tool.black]
line-length = 80
target-version = ['py37']

[tool.isort]
py_version = "37"
profile = "black"
line_length = 80
39 changes: 35 additions & 4 deletions tests/test_read_graphql.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import pytest

from graphql.language import ast
from graphql.language.parser import parse

from hiku.query import Fragment, Node, Field, Link
from hiku.readers.graphql import read, OperationGetter
from hiku.readers.graphql import read_operation, OperationType
from hiku.query import Field, Fragment, Link, Node
from hiku.readers.graphql import (
OperationGetter,
OperationType,
read,
read_operation,
)


def check_read(source, query, variables=None):
Expand Down Expand Up @@ -283,6 +286,34 @@ def test_reference_cycle_in_fragments():
err.match('Cyclic fragment usage: "Pakol"')


def test_non_existent_fragment_root():
with pytest.raises(TypeError) as err:
read(
"""
query Pelota {
sinope
...Pakol
}
"""
)
err.match('Undefined fragment: "Pakol"')


def test_non_existent_fragment():
with pytest.raises(TypeError) as err:
read(
"""
query Pelota {
sinope
pins {
...Splosh
}
}
"""
)
err.match('Undefined fragment: "Splosh"')


def test_duplicated_fragment_names():
with pytest.raises(TypeError) as err:
read(
Expand Down

0 comments on commit 64fd267

Please sign in to comment.