From 5103e3e4eb9cbf094fb1df1dfa4f469a239bb732 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 4612806e..52f869d8 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("ScalarLeafs", runSpec(schemas, deviations, "../spec/validation/ScalarLeafs.yml")) t.Run("SingleFieldSubscriptions", runSpec(schemas, deviations, "../spec/validation/SingleFieldSubscriptions.yml")) diff --git a/validator/walk.go b/validator/walk.go index 8f52fbe5..32b3f6c1 100644 --- a/validator/walk.go +++ b/validator/walk.go @@ -12,6 +12,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) @@ -29,6 +30,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) } @@ -185,6 +189,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()]