diff --git a/graphql_test.go b/graphql_test.go index 3b3efb045fd..5b0e8bb09c8 100644 --- a/graphql_test.go +++ b/graphql_test.go @@ -678,7 +678,15 @@ var tests = []struct { "name": "Droid", "fields": [ { - "name": "appearsIn", + "name": "id", + "args": [], + "type": { + "name": null, + "kind": "NON_NULL" + } + }, + { + "name": "name", "args": [], "type": { "name": null, @@ -697,16 +705,16 @@ var tests = []struct { "name": "friendsConnection", "args": [ { - "name": "after", + "name": "first", "type": { - "name": "ID" + "name": "Int" }, "defaultValue": null }, { - "name": "first", + "name": "after", "type": { - "name": "Int" + "name": "ID" }, "defaultValue": null } @@ -717,15 +725,7 @@ var tests = []struct { } }, { - "name": "id", - "args": [], - "type": { - "name": null, - "kind": "NON_NULL" - } - }, - { - "name": "name", + "name": "appearsIn", "args": [], "type": { "name": null, diff --git a/internal/exec/introspection.go b/internal/exec/introspection.go index 0e801ff10f8..99fc1b8a9d1 100644 --- a/internal/exec/introspection.go +++ b/internal/exec/introspection.go @@ -168,7 +168,7 @@ func (r *schemaResolver) MutationType() *typeResolver { } func (r *schemaResolver) Directives() []*directiveResolver { - panic("TODO") + return nil } type typeResolver struct { @@ -223,23 +223,20 @@ func (r *typeResolver) Description() string { func (r *typeResolver) Fields(args struct{ IncludeDeprecated bool }) []*fieldResolver { var fields map[string]*schema.Field + var fieldOrder []string switch t := r.typ.(type) { case *schema.Object: fields = t.Fields + fieldOrder = t.FieldOrder case *schema.Interface: fields = t.Fields + fieldOrder = t.FieldOrder default: return nil } - var names []string - for name := range fields { - names = append(names, name) - } - sort.Strings(names) - - l := make([]*fieldResolver, len(names)) - for i, name := range names { + l := make([]*fieldResolver, len(fieldOrder)) + for i, name := range fieldOrder { l[i] = &fieldResolver{fields[name]} } return l @@ -278,14 +275,8 @@ func (r *fieldResolver) Description() string { } func (r *fieldResolver) Args() []*inputValueResolver { - var names []string - for name := range r.field.Args { - names = append(names, name) - } - sort.Strings(names) - - l := make([]*inputValueResolver, len(names)) - for i, name := range names { + l := make([]*inputValueResolver, len(r.field.ArgOrder)) + for i, name := range r.field.ArgOrder { l[i] = &inputValueResolver{r.field.Args[name]} } return l @@ -354,7 +345,7 @@ func (r *directiveResolver) Name() string { } func (r *directiveResolver) Description() string { - return "" + panic("TODO") } func (r *directiveResolver) Locations() []string { diff --git a/internal/schema/schema.go b/internal/schema/schema.go index 72db93dbc66..3e339636a45 100644 --- a/internal/schema/schema.go +++ b/internal/schema/schema.go @@ -28,12 +28,14 @@ type Object struct { Name string Implements string Fields map[string]*Field + FieldOrder []string } type Interface struct { Name string ImplementedBy []string Fields map[string]*Field + FieldOrder []string } type Union struct { @@ -47,8 +49,9 @@ type Enum struct { } type InputObject struct { - Name string - InputFields map[string]*InputValue + Name string + InputFields map[string]*InputValue + InputFieldOrder []string } type List struct { @@ -69,9 +72,10 @@ func (List) isType() {} func (NonNull) isType() {} type Field struct { - Name string - Args map[string]*InputValue - Type Type + Name string + Args map[string]*InputValue + ArgOrder []string + Type Type } type InputValue struct { @@ -172,7 +176,7 @@ func parseObjectDecl(l *lexer.Lexer, c *context) *Object { o.Implements = l.ConsumeIdent() } l.ConsumeToken('{') - o.Fields = parseFields(l, c) + o.Fields, o.FieldOrder = parseFields(l, c) l.ConsumeToken('}') return o } @@ -181,7 +185,7 @@ func parseInterfaceDecl(l *lexer.Lexer, c *context) *Interface { i := &Interface{} i.Name = l.ConsumeIdent() l.ConsumeToken('{') - i.Fields = parseFields(l, c) + i.Fields, i.FieldOrder = parseFields(l, c) l.ConsumeToken('}') return i } @@ -207,6 +211,7 @@ func parseInputDecl(l *lexer.Lexer, c *context) *InputObject { for l.Peek() != '}' { v := parseInputValue(l, c) i.InputFields[v.Name] = v + i.InputFieldOrder = append(i.InputFieldOrder, v.Name) } l.ConsumeToken('}') return i @@ -223,8 +228,9 @@ func parseEnumDecl(l *lexer.Lexer, c *context) *Enum { return enum } -func parseFields(l *lexer.Lexer, c *context) map[string]*Field { +func parseFields(l *lexer.Lexer, c *context) (map[string]*Field, []string) { fields := make(map[string]*Field) + var fieldOrder []string for l.Peek() != '}' { f := &Field{} f.Name = l.ConsumeIdent() @@ -234,14 +240,16 @@ func parseFields(l *lexer.Lexer, c *context) map[string]*Field { for l.Peek() != ')' { v := parseInputValue(l, c) f.Args[v.Name] = v + f.ArgOrder = append(f.ArgOrder, v.Name) } l.ConsumeToken(')') } l.ConsumeToken(':') parseType(&f.Type, l, c) fields[f.Name] = f + fieldOrder = append(fieldOrder, f.Name) } - return fields + return fields, fieldOrder } func parseInputValue(l *lexer.Lexer, c *context) *InputValue {