Skip to content

Commit 66aaed7

Browse files
authored
Merge branch 'master' into issue-439
2 parents db6bc15 + bf68c1b commit 66aaed7

File tree

6 files changed

+251
-223
lines changed

6 files changed

+251
-223
lines changed

executor.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ func Execute(p ExecuteParams) (result *Result) {
3636
go func(out chan<- *Result, done <-chan struct{}) {
3737
defer func() {
3838
if err := recover(); err != nil {
39-
result.Errors = append(result.Errors, gqlerrors.FormatError(err.(error)))
39+
result.AppendErrors(gqlerrors.FormatError(err.(error)))
4040
}
4141
select {
4242
case out <- result:
@@ -54,7 +54,7 @@ func Execute(p ExecuteParams) (result *Result) {
5454
})
5555

5656
if err != nil {
57-
result.Errors = append(result.Errors, gqlerrors.FormatError(err))
57+
result.AppendErrors(gqlerrors.FormatError(err))
5858
return
5959
}
6060

@@ -67,7 +67,7 @@ func Execute(p ExecuteParams) (result *Result) {
6767

6868
select {
6969
case <-ctx.Done():
70-
result.Errors = append(result.Errors, gqlerrors.FormatError(ctx.Err()))
70+
result.AppendErrors(gqlerrors.FormatError(ctx.Err()))
7171
case r := <-resultChannel:
7272
result = r
7373
}
@@ -175,15 +175,15 @@ func executeOperation(p executeOperationParams) *Result {
175175
// Extracts the root type of the operation from the schema.
176176
func getOperationRootType(schema Schema, operation ast.Definition) (*Object, error) {
177177
if operation == nil {
178-
return nil, errors.New("Can only execute queries and mutations")
178+
return nil, errors.New("Can only execute queries, mutations and subscription")
179179
}
180180

181181
switch operation.GetOperation() {
182182
case ast.OperationTypeQuery:
183183
return schema.QueryType(), nil
184184
case ast.OperationTypeMutation:
185185
mutationType := schema.MutationType()
186-
if mutationType.PrivateName == "" {
186+
if mutationType == nil || mutationType.PrivateName == "" {
187187
return nil, gqlerrors.NewError(
188188
"Schema is not configured for mutations",
189189
[]ast.Node{operation},
@@ -196,7 +196,7 @@ func getOperationRootType(schema Schema, operation ast.Definition) (*Object, err
196196
return mutationType, nil
197197
case ast.OperationTypeSubscription:
198198
subscriptionType := schema.SubscriptionType()
199-
if subscriptionType.PrivateName == "" {
199+
if subscriptionType == nil || subscriptionType.PrivateName == "" {
200200
return nil, gqlerrors.NewError(
201201
"Schema is not configured for subscriptions",
202202
[]ast.Node{operation},

executor_test.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -899,6 +899,57 @@ func TestThrowsIfUnknownOperationNameIsProvided(t *testing.T) {
899899
t.Fatalf("unexpected result, Diff: %v", testutil.Diff(expectedErrors, result.Errors))
900900
}
901901
}
902+
903+
func TestThrowsIfOperationTypeIsUnsupported(t *testing.T) {
904+
query := `mutation Mut { a } subscription Sub { a }`
905+
operations := []string{"Mut", "Sub"}
906+
907+
expectedErrors := [][]gqlerrors.FormattedError{
908+
{{
909+
Message: `Schema is not configured for mutations`,
910+
Locations: []location.SourceLocation{{Line: 1, Column: 1}},
911+
}},
912+
{{
913+
Message: `Schema is not configured for subscriptions`,
914+
Locations: []location.SourceLocation{{Line: 1, Column: 20}},
915+
}},
916+
}
917+
918+
schema, err := graphql.NewSchema(graphql.SchemaConfig{
919+
Query: graphql.NewObject(graphql.ObjectConfig{
920+
Name: "Query",
921+
Fields: graphql.Fields{
922+
"a": &graphql.Field{
923+
Type: graphql.String,
924+
},
925+
},
926+
}),
927+
})
928+
if err != nil {
929+
t.Fatalf("Error in schema %v", err.Error())
930+
}
931+
932+
// parse query
933+
ast := testutil.TestParse(t, query)
934+
935+
for opIndex, operation := range operations {
936+
expectedErrors := expectedErrors[opIndex]
937+
938+
// execute
939+
ep := graphql.ExecuteParams{
940+
Schema: schema,
941+
AST: ast,
942+
OperationName: operation,
943+
}
944+
result := testutil.TestExecute(t, ep)
945+
if result.Data != nil {
946+
t.Fatalf("wrong result, expected nil result.Data, got %v", result.Data)
947+
}
948+
if !testutil.EqualFormattedErrors(expectedErrors, result.Errors) {
949+
t.Fatalf("unexpected result, Diff: %v", testutil.Diff(expectedErrors, result.Errors))
950+
}
951+
}
952+
}
902953
func TestUsesTheQuerySchemaForQueries(t *testing.T) {
903954

904955
doc := `query Q { a } mutation M { c } subscription S { a }`

language/lexer/lexer.go

Lines changed: 54 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@ import (
1111
"github.com/graphql-go/graphql/language/source"
1212
)
1313

14+
type TokenKind int
15+
1416
const (
15-
EOF = iota + 1
17+
EOF TokenKind = iota + 1
1618
BANG
1719
DOLLAR
1820
PAREN_L
@@ -34,6 +36,33 @@ const (
3436
AMP
3537
)
3638

39+
var tokenDescription = map[TokenKind]string{
40+
EOF: "EOF",
41+
BANG: "!",
42+
DOLLAR: "$",
43+
PAREN_L: "(",
44+
PAREN_R: ")",
45+
SPREAD: "...",
46+
COLON: ":",
47+
EQUALS: "=",
48+
AT: "@",
49+
BRACKET_L: "[",
50+
BRACKET_R: "]",
51+
BRACE_L: "{",
52+
PIPE: "|",
53+
BRACE_R: "}",
54+
NAME: "Name",
55+
INT: "Int",
56+
FLOAT: "Float",
57+
STRING: "String",
58+
BLOCK_STRING: "BlockString",
59+
AMP: "&",
60+
}
61+
62+
func (kind TokenKind) String() string {
63+
return tokenDescription[kind]
64+
}
65+
3766
// NAME -> keyword relationship
3867
const (
3968
FRAGMENT = "fragment"
@@ -51,61 +80,10 @@ const (
5180
DIRECTIVE = "directive"
5281
)
5382

54-
var TokenKind map[int]int
55-
var tokenDescription map[int]string
56-
57-
func init() {
58-
TokenKind = make(map[int]int)
59-
{
60-
TokenKind[EOF] = EOF
61-
TokenKind[BANG] = BANG
62-
TokenKind[DOLLAR] = DOLLAR
63-
TokenKind[PAREN_L] = PAREN_L
64-
TokenKind[PAREN_R] = PAREN_R
65-
TokenKind[SPREAD] = SPREAD
66-
TokenKind[COLON] = COLON
67-
TokenKind[EQUALS] = EQUALS
68-
TokenKind[AT] = AT
69-
TokenKind[BRACKET_L] = BRACKET_L
70-
TokenKind[BRACKET_R] = BRACKET_R
71-
TokenKind[BRACE_L] = BRACE_L
72-
TokenKind[PIPE] = PIPE
73-
TokenKind[BRACE_R] = BRACE_R
74-
TokenKind[NAME] = NAME
75-
TokenKind[INT] = INT
76-
TokenKind[FLOAT] = FLOAT
77-
TokenKind[STRING] = STRING
78-
TokenKind[BLOCK_STRING] = BLOCK_STRING
79-
}
80-
tokenDescription = make(map[int]string)
81-
{
82-
tokenDescription[TokenKind[EOF]] = "EOF"
83-
tokenDescription[TokenKind[BANG]] = "!"
84-
tokenDescription[TokenKind[DOLLAR]] = "$"
85-
tokenDescription[TokenKind[PAREN_L]] = "("
86-
tokenDescription[TokenKind[PAREN_R]] = ")"
87-
tokenDescription[TokenKind[SPREAD]] = "..."
88-
tokenDescription[TokenKind[COLON]] = ":"
89-
tokenDescription[TokenKind[EQUALS]] = "="
90-
tokenDescription[TokenKind[AT]] = "@"
91-
tokenDescription[TokenKind[BRACKET_L]] = "["
92-
tokenDescription[TokenKind[BRACKET_R]] = "]"
93-
tokenDescription[TokenKind[BRACE_L]] = "{"
94-
tokenDescription[TokenKind[PIPE]] = "|"
95-
tokenDescription[TokenKind[BRACE_R]] = "}"
96-
tokenDescription[TokenKind[NAME]] = "Name"
97-
tokenDescription[TokenKind[INT]] = "Int"
98-
tokenDescription[TokenKind[FLOAT]] = "Float"
99-
tokenDescription[TokenKind[STRING]] = "String"
100-
tokenDescription[TokenKind[BLOCK_STRING]] = "BlockString"
101-
tokenDescription[TokenKind[AMP]] = "&"
102-
}
103-
}
104-
10583
// Token is a representation of a lexed Token. Value only appears for non-punctuation
10684
// tokens: NAME, INT, FLOAT, and STRING.
10785
type Token struct {
108-
Kind int
86+
Kind TokenKind
10987
Start int
11088
End int
11189
Value string
@@ -151,7 +129,7 @@ func readName(source *source.Source, position, runePosition int) Token {
151129
break
152130
}
153131
}
154-
return makeToken(TokenKind[NAME], runePosition, endRune, string(body[position:endByte]))
132+
return makeToken(NAME, runePosition, endRune, string(body[position:endByte]))
155133
}
156134

157135
// Reads a number token from the source file, either a float
@@ -207,9 +185,9 @@ func readNumber(s *source.Source, start int, firstCode rune, codeLength int) (To
207185
}
208186
position = p
209187
}
210-
kind := TokenKind[INT]
188+
kind := INT
211189
if isFloat {
212-
kind = TokenKind[FLOAT]
190+
kind = FLOAT
213191
}
214192

215193
return makeToken(kind, start, position, string(body[start:position])), nil
@@ -328,7 +306,7 @@ func readString(s *source.Source, start int) (Token, error) {
328306
stringContent := body[chunkStart:position]
329307
valueBuffer.Write(stringContent)
330308
value := valueBuffer.String()
331-
return makeToken(TokenKind[STRING], start, position+1, value), nil
309+
return makeToken(STRING, start, position+1, value), nil
332310
}
333311

334312
// readBlockString reads a block string token from the source file.
@@ -357,7 +335,7 @@ func readBlockString(s *source.Source, start int) (Token, error) {
357335
stringContent := body[chunkStart:position]
358336
valueBuffer.Write(stringContent)
359337
value := blockStringValue(valueBuffer.String())
360-
return makeToken(TokenKind[BLOCK_STRING], start, position+3, value), nil
338+
return makeToken(BLOCK_STRING, start, position+3, value), nil
361339
}
362340
}
363341

@@ -490,7 +468,7 @@ func char2hex(a rune) int {
490468
return -1
491469
}
492470

493-
func makeToken(kind int, start int, end int, value string) Token {
471+
func makeToken(kind TokenKind, start int, end int, value string) Token {
494472
return Token{Kind: kind, Start: start, End: end, Value: value}
495473
}
496474

@@ -512,7 +490,7 @@ func readToken(s *source.Source, fromPosition int) (Token, error) {
512490
bodyLength := len(body)
513491
position, runePosition := positionAfterWhitespace(body, fromPosition)
514492
if position >= bodyLength {
515-
return makeToken(TokenKind[EOF], position, position, ""), nil
493+
return makeToken(EOF, position, position, ""), nil
516494
}
517495
code, codeLength := runeAt(body, position)
518496

@@ -524,51 +502,51 @@ func readToken(s *source.Source, fromPosition int) (Token, error) {
524502
switch code {
525503
// !
526504
case '!':
527-
return makeToken(TokenKind[BANG], position, position+1, ""), nil
505+
return makeToken(BANG, position, position+1, ""), nil
528506
// $
529507
case '$':
530-
return makeToken(TokenKind[DOLLAR], position, position+1, ""), nil
508+
return makeToken(DOLLAR, position, position+1, ""), nil
531509
// &
532510
case '&':
533-
return makeToken(TokenKind[AMP], position, position+1, ""), nil
511+
return makeToken(AMP, position, position+1, ""), nil
534512
// (
535513
case '(':
536-
return makeToken(TokenKind[PAREN_L], position, position+1, ""), nil
514+
return makeToken(PAREN_L, position, position+1, ""), nil
537515
// )
538516
case ')':
539-
return makeToken(TokenKind[PAREN_R], position, position+1, ""), nil
517+
return makeToken(PAREN_R, position, position+1, ""), nil
540518
// .
541519
case '.':
542520
next1, _ := runeAt(body, position+1)
543521
next2, _ := runeAt(body, position+2)
544522
if next1 == '.' && next2 == '.' {
545-
return makeToken(TokenKind[SPREAD], position, position+3, ""), nil
523+
return makeToken(SPREAD, position, position+3, ""), nil
546524
}
547525
break
548526
// :
549527
case ':':
550-
return makeToken(TokenKind[COLON], position, position+1, ""), nil
528+
return makeToken(COLON, position, position+1, ""), nil
551529
// =
552530
case '=':
553-
return makeToken(TokenKind[EQUALS], position, position+1, ""), nil
531+
return makeToken(EQUALS, position, position+1, ""), nil
554532
// @
555533
case '@':
556-
return makeToken(TokenKind[AT], position, position+1, ""), nil
534+
return makeToken(AT, position, position+1, ""), nil
557535
// [
558536
case '[':
559-
return makeToken(TokenKind[BRACKET_L], position, position+1, ""), nil
537+
return makeToken(BRACKET_L, position, position+1, ""), nil
560538
// ]
561539
case ']':
562-
return makeToken(TokenKind[BRACKET_R], position, position+1, ""), nil
540+
return makeToken(BRACKET_R, position, position+1, ""), nil
563541
// {
564542
case '{':
565-
return makeToken(TokenKind[BRACE_L], position, position+1, ""), nil
543+
return makeToken(BRACE_L, position, position+1, ""), nil
566544
// |
567545
case '|':
568-
return makeToken(TokenKind[PIPE], position, position+1, ""), nil
546+
return makeToken(PIPE, position, position+1, ""), nil
569547
// }
570548
case '}':
571-
return makeToken(TokenKind[BRACE_R], position, position+1, ""), nil
549+
return makeToken(BRACE_R, position, position+1, ""), nil
572550
// A-Z
573551
case 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
574552
'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z':
@@ -672,11 +650,7 @@ func positionAfterWhitespace(body []byte, startPosition int) (position int, rune
672650

673651
func GetTokenDesc(token Token) string {
674652
if token.Value == "" {
675-
return GetTokenKindDesc(token.Kind)
653+
return token.Kind.String()
676654
}
677-
return fmt.Sprintf("%s \"%s\"", GetTokenKindDesc(token.Kind), token.Value)
678-
}
679-
680-
func GetTokenKindDesc(kind int) string {
681-
return tokenDescription[kind]
655+
return fmt.Sprintf("%s \"%s\"", token.Kind.String(), token.Value)
682656
}

0 commit comments

Comments
 (0)