Skip to content

Commit 430716e

Browse files
Adam Scarrvektah
authored andcommitted
Implement UniqueFragmentNames validator
1 parent 809908a commit 430716e

4 files changed

Lines changed: 33 additions & 8 deletions

File tree

validator/unique_fragment_names.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package validator
2+
3+
import (
4+
"github.com/vektah/gqlparser"
5+
)
6+
7+
func init() {
8+
fragmentVisitors = append(fragmentVisitors, uniqueFragmentNames)
9+
}
10+
11+
// A GraphQL document is only valid if all defined fragments have unique names.
12+
func uniqueFragmentNames(ctx *vctx, parentDef *gqlparser.Definition, fragment *gqlparser.FragmentDefinition) {
13+
if ctx.seenFragments[fragment.Name] {
14+
ctx.errors = append(ctx.errors, Error(
15+
Rule("UniqueFragmentNames"),
16+
Message(`There can be only one fragment named "%s".`, fragment.Name),
17+
))
18+
}
19+
ctx.seenFragments[fragment.Name] = true
20+
}

validator/validate.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ import (
77

88
func Validate(schema *Schema, doc *QueryDocument) []errors.Validation {
99
ctx := vctx{
10-
schema: schema,
11-
document: doc,
10+
schema: schema,
11+
document: doc,
12+
seenFragments: map[string]bool{},
1213
}
1314

1415
ctx.walk()

validator/validate_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ func TestSpec(t *testing.T) {
4545
t.Run("SingleFieldSubscriptions", runSpec(schemas, deviations, "../spec/validation/SingleFieldSubscriptions.yml"))
4646
t.Run("UniqueArgumentNames", runSpec(schemas, deviations, "../spec/validation/UniqueArgumentNames.yml"))
4747
t.Run("UniqueDirectivesPerLocation", runSpec(schemas, deviations, "../spec/validation/UniqueDirectivesPerLocation.yml"))
48+
t.Run("UniqueFragmentNames", runSpec(schemas, deviations, "../spec/validation/UniqueFragmentNames.yml"))
4849
}
4950

5051
func runSpec(schemas []*gqlparser.Schema, deviations map[string]*Spec, filename string) func(t *testing.T) {

validator/walk.go

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ import (
77
"github.com/vektah/gqlparser/errors"
88
)
99

10-
var operationVisitor []func(vctx *vctx, operation *gqlparser.OperationDefinition)
11-
var fieldVisitors []func(vctx *vctx, parentDef *gqlparser.Definition, fieldDef *gqlparser.FieldDefinition, field *gqlparser.Field)
12-
var fragmentVisitors []func(vctx *vctx, parentDef *gqlparser.Definition, fragment *gqlparser.FragmentDefinition)
13-
var inlineFragmentVisitors []func(vctx *vctx, parentDef *gqlparser.Definition, inlineFragment *gqlparser.InlineFragment)
14-
var directiveVisitors []func(vctx *vctx, parentDef *gqlparser.Definition, directiveDef *gqlparser.DirectiveDefinition, directive *gqlparser.Directive, location gqlparser.DirectiveLocation)
15-
var directiveListVisitors []func(vctx *vctx, parentDef *gqlparser.Definition, directives []gqlparser.Directive, location gqlparser.DirectiveLocation)
10+
var operationVisitor []func(ctx *vctx, operation *gqlparser.OperationDefinition)
11+
var fieldVisitors []func(ctx *vctx, parentDef *gqlparser.Definition, fieldDef *gqlparser.FieldDefinition, field *gqlparser.Field)
12+
var fragmentVisitors []func(ctx *vctx, parentDef *gqlparser.Definition, fragment *gqlparser.FragmentDefinition)
13+
var inlineFragmentVisitors []func(ctx *vctx, parentDef *gqlparser.Definition, inlineFragment *gqlparser.InlineFragment)
14+
var directiveVisitors []func(ctx *vctx, parentDef *gqlparser.Definition, directiveDef *gqlparser.DirectiveDefinition, directive *gqlparser.Directive, location gqlparser.DirectiveLocation)
15+
var directiveListVisitors []func(ctx *vctx, parentDef *gqlparser.Definition, directives []gqlparser.Directive, location gqlparser.DirectiveLocation)
1616

1717
func init() {
1818
//fieldVisitors = append(fieldVisitors, func(vctx *vctx, parentDef *gqlparser.Definition, fieldDef *gqlparser.FieldDefinition, field *gqlparser.Field) {
@@ -24,6 +24,9 @@ type vctx struct {
2424
schema *gqlparser.Schema
2525
document *gqlparser.QueryDocument
2626
errors []errors.Validation
27+
28+
// todo: Move this somewhere better
29+
seenFragments map[string]bool
2730
}
2831

2932
func (c *vctx) walk() {

0 commit comments

Comments
 (0)