Skip to content

Commit

Permalink
validation: NoFragmentCycles
Browse files Browse the repository at this point in the history
  • Loading branch information
neelance committed May 23, 2017
1 parent 3aaaf02 commit c2135f3
Show file tree
Hide file tree
Showing 4 changed files with 392 additions and 23 deletions.
3 changes: 3 additions & 0 deletions internal/query/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ type InlineFragment struct {
type FragmentSpread struct {
Name lexer.Ident
Directives common.DirectiveList
Loc errors.Location
}

func (Field) isSelection() {}
Expand Down Expand Up @@ -212,6 +213,7 @@ func parseField(l *lexer.Lexer) *Field {
}

func parseSpread(l *lexer.Lexer) Selection {
loc := l.Location()
l.ConsumeToken('.')
l.ConsumeToken('.')
l.ConsumeToken('.')
Expand All @@ -222,6 +224,7 @@ func parseSpread(l *lexer.Lexer) Selection {
if ident.Name != "on" {
fs := &FragmentSpread{
Name: ident,
Loc: loc,
}
fs.Directives = common.ParseDirectives(l)
return fs
Expand Down
2 changes: 1 addition & 1 deletion internal/tests/testdata/export.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ require('./src/validation/__tests__/KnownDirectives-test');
require('./src/validation/__tests__/KnownFragmentNames-test');
require('./src/validation/__tests__/KnownTypeNames-test');
require('./src/validation/__tests__/LoneAnonymousOperation-test');
// require('./src/validation/__tests__/NoFragmentCycles-test');
require('./src/validation/__tests__/NoFragmentCycles-test');
// require('./src/validation/__tests__/NoUndefinedVariables-test');
require('./src/validation/__tests__/NoUnusedFragments-test');
// require('./src/validation/__tests__/NoUnusedVariables-test');
Expand Down
307 changes: 307 additions & 0 deletions internal/tests/testdata/tests.json
Original file line number Diff line number Diff line change
Expand Up @@ -1649,6 +1649,313 @@
}
]
},
{
"name": "Validate: No circular fragment spreads/single reference is valid",
"rule": "NoFragmentCycles",
"query": "\n fragment fragA on Dog { ...fragB }\n fragment fragB on Dog { name }\n ",
"errors": []
},
{
"name": "Validate: No circular fragment spreads/spreading twice is not circular",
"rule": "NoFragmentCycles",
"query": "\n fragment fragA on Dog { ...fragB, ...fragB }\n fragment fragB on Dog { name }\n ",
"errors": []
},
{
"name": "Validate: No circular fragment spreads/spreading twice indirectly is not circular",
"rule": "NoFragmentCycles",
"query": "\n fragment fragA on Dog { ...fragB, ...fragC }\n fragment fragB on Dog { ...fragC }\n fragment fragC on Dog { name }\n ",
"errors": []
},
{
"name": "Validate: No circular fragment spreads/double spread within abstract types",
"rule": "NoFragmentCycles",
"query": "\n fragment nameFragment on Pet {\n ... on Dog { name }\n ... on Cat { name }\n }\n\n fragment spreadsInAnon on Pet {\n ... on Dog { ...nameFragment }\n ... on Cat { ...nameFragment }\n }\n ",
"errors": []
},
{
"name": "Validate: No circular fragment spreads/does not false positive on unknown fragment",
"rule": "NoFragmentCycles",
"query": "\n fragment nameFragment on Pet {\n ...UnknownFragment\n }\n ",
"errors": []
},
{
"name": "Validate: No circular fragment spreads/spreading recursively within field fails",
"rule": "NoFragmentCycles",
"query": "\n fragment fragA on Human { relatives { ...fragA } },\n ",
"errors": [
{
"message": "Cannot spread fragment \"fragA\" within itself.",
"locations": [
{
"line": 2,
"column": 45
}
]
}
]
},
{
"name": "Validate: No circular fragment spreads/no spreading itself directly",
"rule": "NoFragmentCycles",
"query": "\n fragment fragA on Dog { ...fragA }\n ",
"errors": [
{
"message": "Cannot spread fragment \"fragA\" within itself.",
"locations": [
{
"line": 2,
"column": 31
}
]
}
]
},
{
"name": "Validate: No circular fragment spreads/no spreading itself directly within inline fragment",
"rule": "NoFragmentCycles",
"query": "\n fragment fragA on Pet {\n ... on Dog {\n ...fragA\n }\n }\n ",
"errors": [
{
"message": "Cannot spread fragment \"fragA\" within itself.",
"locations": [
{
"line": 4,
"column": 11
}
]
}
]
},
{
"name": "Validate: No circular fragment spreads/no spreading itself indirectly",
"rule": "NoFragmentCycles",
"query": "\n fragment fragA on Dog { ...fragB }\n fragment fragB on Dog { ...fragA }\n ",
"errors": [
{
"message": "Cannot spread fragment \"fragA\" within itself via fragB.",
"locations": [
{
"line": 2,
"column": 31
},
{
"line": 3,
"column": 31
}
]
}
]
},
{
"name": "Validate: No circular fragment spreads/no spreading itself indirectly reports opposite order",
"rule": "NoFragmentCycles",
"query": "\n fragment fragB on Dog { ...fragA }\n fragment fragA on Dog { ...fragB }\n ",
"errors": [
{
"message": "Cannot spread fragment \"fragB\" within itself via fragA.",
"locations": [
{
"line": 2,
"column": 31
},
{
"line": 3,
"column": 31
}
]
}
]
},
{
"name": "Validate: No circular fragment spreads/no spreading itself indirectly within inline fragment",
"rule": "NoFragmentCycles",
"query": "\n fragment fragA on Pet {\n ... on Dog {\n ...fragB\n }\n }\n fragment fragB on Pet {\n ... on Dog {\n ...fragA\n }\n }\n ",
"errors": [
{
"message": "Cannot spread fragment \"fragA\" within itself via fragB.",
"locations": [
{
"line": 4,
"column": 11
},
{
"line": 9,
"column": 11
}
]
}
]
},
{
"name": "Validate: No circular fragment spreads/no spreading itself deeply",
"rule": "NoFragmentCycles",
"query": "\n fragment fragA on Dog { ...fragB }\n fragment fragB on Dog { ...fragC }\n fragment fragC on Dog { ...fragO }\n fragment fragX on Dog { ...fragY }\n fragment fragY on Dog { ...fragZ }\n fragment fragZ on Dog { ...fragO }\n fragment fragO on Dog { ...fragP }\n fragment fragP on Dog { ...fragA, ...fragX }\n ",
"errors": [
{
"message": "Cannot spread fragment \"fragA\" within itself via fragB, fragC, fragO, fragP.",
"locations": [
{
"line": 2,
"column": 31
},
{
"line": 3,
"column": 31
},
{
"line": 4,
"column": 31
},
{
"line": 8,
"column": 31
},
{
"line": 9,
"column": 31
}
]
},
{
"message": "Cannot spread fragment \"fragO\" within itself via fragP, fragX, fragY, fragZ.",
"locations": [
{
"line": 8,
"column": 31
},
{
"line": 9,
"column": 41
},
{
"line": 5,
"column": 31
},
{
"line": 6,
"column": 31
},
{
"line": 7,
"column": 31
}
]
}
]
},
{
"name": "Validate: No circular fragment spreads/no spreading itself deeply two paths",
"rule": "NoFragmentCycles",
"query": "\n fragment fragA on Dog { ...fragB, ...fragC }\n fragment fragB on Dog { ...fragA }\n fragment fragC on Dog { ...fragA }\n ",
"errors": [
{
"message": "Cannot spread fragment \"fragA\" within itself via fragB.",
"locations": [
{
"line": 2,
"column": 31
},
{
"line": 3,
"column": 31
}
]
},
{
"message": "Cannot spread fragment \"fragA\" within itself via fragC.",
"locations": [
{
"line": 2,
"column": 41
},
{
"line": 4,
"column": 31
}
]
}
]
},
{
"name": "Validate: No circular fragment spreads/no spreading itself deeply two paths -- alt traverse order",
"rule": "NoFragmentCycles",
"query": "\n fragment fragA on Dog { ...fragC }\n fragment fragB on Dog { ...fragC }\n fragment fragC on Dog { ...fragA, ...fragB }\n ",
"errors": [
{
"message": "Cannot spread fragment \"fragA\" within itself via fragC.",
"locations": [
{
"line": 2,
"column": 31
},
{
"line": 4,
"column": 31
}
]
},
{
"message": "Cannot spread fragment \"fragC\" within itself via fragB.",
"locations": [
{
"line": 4,
"column": 41
},
{
"line": 3,
"column": 31
}
]
}
]
},
{
"name": "Validate: No circular fragment spreads/no spreading itself deeply and immediately",
"rule": "NoFragmentCycles",
"query": "\n fragment fragA on Dog { ...fragB }\n fragment fragB on Dog { ...fragB, ...fragC }\n fragment fragC on Dog { ...fragA, ...fragB }\n ",
"errors": [
{
"message": "Cannot spread fragment \"fragB\" within itself.",
"locations": [
{
"line": 3,
"column": 31
}
]
},
{
"message": "Cannot spread fragment \"fragA\" within itself via fragB, fragC.",
"locations": [
{
"line": 2,
"column": 31
},
{
"line": 3,
"column": 41
},
{
"line": 4,
"column": 31
}
]
},
{
"message": "Cannot spread fragment \"fragB\" within itself via fragC.",
"locations": [
{
"line": 3,
"column": 41
},
{
"line": 4,
"column": 41
}
]
}
]
},
{
"name": "Validate: No unused fragments/all fragment names are used",
"rule": "NoUnusedFragments",
Expand Down
Loading

0 comments on commit c2135f3

Please sign in to comment.