From fb3fc1d26dea75086d35271c80a54ce236a77606 Mon Sep 17 00:00:00 2001 From: vvakame Date: Wed, 11 Jul 2018 14:55:41 +0900 Subject: [PATCH] Implement KnownFragmentNames validator --- validator/known_fragment_names.go | 20 ++++++++++++++++++++ validator/validate_test.go | 1 + validator/walk.go | 8 ++++++++ 3 files changed, 29 insertions(+) create mode 100644 validator/known_fragment_names.go diff --git a/validator/known_fragment_names.go b/validator/known_fragment_names.go new file mode 100644 index 00000000..39e2bbfb --- /dev/null +++ b/validator/known_fragment_names.go @@ -0,0 +1,20 @@ +package validator + +import ( + "fmt" + + "github.com/vektah/gqlparser" +) + +func init() { + addRule("KnownFragmentNames", func(observers *Events, addError addErrFunc) { + observers.OnFragmentSpread(func(walker *Walker, parentDef *gqlparser.Definition, fragmentDef *gqlparser.FragmentDefinition, fragmentSpread *gqlparser.FragmentSpread) { + if fragmentDef != nil { + return + } + + message := fmt.Sprintf(`Unknown fragment "%s".`, fragmentSpread.Name) + addError(Message(message)) + }) + }) +} diff --git a/validator/validate_test.go b/validator/validate_test.go index c9b2d4a6..58ab783c 100644 --- a/validator/validate_test.go +++ b/validator/validate_test.go @@ -40,6 +40,7 @@ func TestSpec(t *testing.T) { t.Run("FragmentsOnCompositeTypes", runSpec(schemas, deviations, "../spec/validation/FragmentsOnCompositeTypes.yml")) t.Run("KnownArgumentNames", runSpec(schemas, deviations, "../spec/validation/KnownArgumentNames.yml")) t.Run("KnownDirectives", runSpec(schemas, deviations, "../spec/validation/KnownDirectives.yml")) + t.Run("KnownFragmentNames", runSpec(schemas, deviations, "../spec/validation/KnownFragmentNames.yml")) t.Run("LoneAnonymousOperation", runSpec(schemas, deviations, "../spec/validation/LoneAnonymousOperation.yml")) diff --git a/validator/walk.go b/validator/walk.go index 34b1537e..18827099 100644 --- a/validator/walk.go +++ b/validator/walk.go @@ -14,6 +14,7 @@ type Events struct { field []func(walker *Walker, parentDef *gqlparser.Definition, fieldDef *gqlparser.FieldDefinition, field *gqlparser.Field) fragment []func(walker *Walker, parentDef *gqlparser.Definition, fragment *gqlparser.FragmentDefinition) inlineFragment []func(walker *Walker, parentDef *gqlparser.Definition, inlineFragment *gqlparser.InlineFragment) + fragmentSpread []func(walker *Walker, parentDef *gqlparser.Definition, fragmentDef *gqlparser.FragmentDefinition, fragmentSpread *gqlparser.FragmentSpread) directive []func(walker *Walker, parentDef *gqlparser.Definition, directiveDef *gqlparser.DirectiveDefinition, directive *gqlparser.Directive, location gqlparser.DirectiveLocation) directiveList []func(walker *Walker, parentDef *gqlparser.Definition, directives []gqlparser.Directive, location gqlparser.DirectiveLocation) value []func(walker *Walker, value gqlparser.Value) @@ -31,6 +32,9 @@ func (o *Events) OnFragment(f func(walker *Walker, parentDef *gqlparser.Definiti func (o *Events) OnInlineFragment(f func(walker *Walker, parentDef *gqlparser.Definition, inlineFragment *gqlparser.InlineFragment)) { o.inlineFragment = append(o.inlineFragment, f) } +func (o *Events) OnFragmentSpread(f func(walker *Walker, parentDef *gqlparser.Definition, fragmentDef *gqlparser.FragmentDefinition, fragmentSpread *gqlparser.FragmentSpread)) { + o.fragmentSpread = append(o.fragmentSpread, f) +} func (o *Events) OnDirective(f func(walker *Walker, parentDef *gqlparser.Definition, directiveDef *gqlparser.DirectiveDefinition, directive *gqlparser.Directive, location gqlparser.DirectiveLocation)) { o.directive = append(o.directive, f) } @@ -189,6 +193,10 @@ func (w *Walker) walkSelection(parentDef *gqlparser.Definition, it gqlparser.Sel case gqlparser.FragmentSpread: def := w.Document.GetFragment(it.Name) + for _, v := range w.Observers.fragmentSpread { + v(w, parentDef, def, &it) + } + var nextParentDef *gqlparser.Definition if def != nil { nextParentDef = w.Schema.Types[def.TypeCondition.Name()]