Skip to content

Commit 111e0c8

Browse files
committed
Merge pull request #24 from jhgg/known-fragment-names
Implement KnownFragmentNames
2 parents 2087058 + f51a269 commit 111e0c8

File tree

3 files changed

+69
-2
lines changed

3 files changed

+69
-2
lines changed

graphql/core/validation/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ def get_fragment(self, name):
118118
fragments = self._fragments
119119
if fragments is None:
120120
self._fragments = fragments = {}
121-
for statement in self.get_document().definitions:
121+
for statement in self.get_ast().definitions:
122122
if isinstance(statement, FragmentDefinition):
123123
fragments[statement.name.value] = statement
124124
return fragments[name]

graphql/core/validation/rules.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,19 @@ def duplicate_fragment_name_message(field):
167167

168168

169169
class KnownFragmentNames(ValidationRule):
170-
pass
170+
def enter_FragmentSpread(self, node, *args):
171+
fragment_name = node.name.value
172+
try:
173+
self.context.get_fragment(fragment_name)
174+
except KeyError:
175+
return GraphQLError(
176+
self.unknown_fragment_message(fragment_name),
177+
[node.name]
178+
)
179+
180+
@staticmethod
181+
def unknown_fragment_message(fragment_name):
182+
return 'Unknown fragment "{}".'.format(fragment_name)
171183

172184

173185
class NoUnusedFragments(ValidationRule):
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
from graphql.core.language.location import SourceLocation
2+
from graphql.core.validation.rules import KnownFragmentNames
3+
from utils import expect_passes_rule, expect_fails_rule
4+
5+
6+
def undefined_fragment(fragment_name, line, column):
7+
return {
8+
'message': KnownFragmentNames.unknown_fragment_message(fragment_name),
9+
'locations': [SourceLocation(line, column)]
10+
}
11+
12+
13+
def test_known_fragment_names_are_valid():
14+
expect_passes_rule(KnownFragmentNames, '''
15+
{
16+
human(id: 4) {
17+
...HumanFields1
18+
... on Human {
19+
...HumanFields2
20+
}
21+
}
22+
}
23+
fragment HumanFields1 on Human {
24+
name
25+
...HumanFields3
26+
}
27+
fragment HumanFields2 on Human {
28+
name
29+
}
30+
fragment HumanFields3 on Human {
31+
name
32+
}
33+
''')
34+
35+
36+
def test_unknown_fragment_names_are_invalid():
37+
expect_fails_rule(KnownFragmentNames, '''
38+
{
39+
human(id: 4) {
40+
...UnknownFragment1
41+
... on Human {
42+
...UnknownFragment2
43+
}
44+
}
45+
}
46+
fragment HumanFields on Human {
47+
name
48+
...UnknownFragment3
49+
}
50+
''', [
51+
undefined_fragment('UnknownFragment1', 4, 16),
52+
undefined_fragment('UnknownFragment2', 6, 20),
53+
undefined_fragment('UnknownFragment3', 12, 12),
54+
55+
])

0 commit comments

Comments
 (0)