Example #1
0
func Graphql(p GraphqlParams, resultChannel chan *types.GraphQLResult) {
	source := source.NewSource(&source.Source{
		Body: p.RequestString,
		Name: "GraphQL request",
	})
	AST, err := parser.Parse(parser.ParseParams{Source: source})
	if err != nil {
		result := types.GraphQLResult{
			Errors: graphqlerrors.FormatErrors(err),
		}
		resultChannel <- &result
		return
	}
	validationResult := validator.ValidateDocument(p.Schema, AST)

	if !validationResult.IsValid {
		result := types.GraphQLResult{
			Errors: validationResult.Errors,
		}
		resultChannel <- &result
		return
	} else {
		ep := executor.ExecuteParams{
			Schema:        p.Schema,
			Root:          p.RootObject,
			AST:           AST,
			Ctx:           p.Ctx,
			OperationName: p.OperationName,
			Args:          p.VariableValues,
		}
		executor.Execute(ep, resultChannel)
		return
	}
}
Example #2
0
func TestLexRerportsUsefulInformationForDashesInNames(t *testing.T) {
	q := "a-b"
	lexer := Lex(source.NewSource(q, ""))
	firstToken, err := lexer(0)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	firstTokenExpected := Token{
		Kind:  TokenKind[NAME],
		Start: 0,
		End:   1,
		Value: "a",
	}
	if !reflect.DeepEqual(firstToken, firstTokenExpected) {
		t.Fatalf("unexpected token, expected: %v, got: %v", firstTokenExpected, firstToken)
	}
	errExpected := `Syntax Error GraphQL (1:3) Invalid number, expected digit but got: "b".

1: a-b
     ^
`
	token, err := lexer(0)
	if err == nil {
		t.Fatalf("unexpected nil error: %v", err)
	}
	if err.Error() != errExpected {
		t.Fatalf("unexpected error, token:%v\nexpected:\n%v\n\ngot:\n%v", token, errExpected, err.Error())
	}
}
func TestParseProvidesUsefulErrorsWhenUsingSource(t *testing.T) {
	test := errorMessageTest{
		source.NewSource(&source.Source{Body: "query", Name: "MyQuery.graphql"}),
		`Syntax Error MyQuery.graphql (1:6) Expected Name, found EOF`,
		false,
	}
	testGraphQLErrorMessage(t, test)
}
Example #4
0
func TestErrorsRespectWhitespace(t *testing.T) {
	body := `

    ?

`
	source := source.NewSource(body, "")
	_, err := Lex(source)(0)
	expected := "Syntax Error GraphQL (3:5) Unexpected character \"?\".\n\n2: \n3:     ?\n       ^\n4: \n"
	if err == nil {
		t.Fatalf("unexpected nil error\nexpected:\n%v\n\ngot:\n%v", expected, err)
	}
	if err.Error() != expected {
		t.Fatalf("unexpected error.\nexpected:\n%v\n\ngot:\n%v", expected, err.Error())
	}
}
Example #5
0
func Parse(p ParseParams) (*ast.Document, error) {
	var sourceObj *source.Source
	switch p.Source.(type) {
	case *source.Source:
		sourceObj = p.Source.(*source.Source)
	default:
		s, _ := p.Source.(string)
		sourceObj = source.NewSource(s, "")
	}
	parser, err := makeParser(sourceObj, p.Options)
	if err != nil {
		return nil, err
	}
	doc, err := parseDocument(parser)
	if err != nil {
		return nil, err
	}
	return doc, nil
}
Example #6
0
// TODO: test and expose parseValue as a public
func parseValue(p ParseParams) (ast.Value, error) {
	var value ast.Value
	var sourceObj *source.Source
	switch p.Source.(type) {
	case *source.Source:
		sourceObj = p.Source.(*source.Source)
	default:
		s, _ := p.Source.(string)
		sourceObj = source.NewSource(s, "")
	}
	parser, err := makeParser(sourceObj, p.Options)
	if err != nil {
		return value, err
	}
	value, err = parseValueLiteral(parser, false)
	if err != nil {
		return value, err
	}
	return value, nil
}
Example #7
0
func TestLexReportsUsefulUnknownCharacterError(t *testing.T) {
	tests := []Test{
		Test{
			Body: "..",
			Expected: `Syntax Error GraphQL (1:1) Unexpected character ".".

1: ..
   ^
`,
		},
		Test{
			Body: "?",
			Expected: `Syntax Error GraphQL (1:1) Unexpected character "?".

1: ?
   ^
`,
		},
		Test{
			Body: "\u203B",
			Expected: `Syntax Error GraphQL (1:1) Unexpected character "※".

1: ※
   ^
`,
		},
	}
	for _, test := range tests {
		_, err := Lex(source.NewSource(test.Body, ""))(0)
		if err == nil {
			t.Fatalf("unexpected nil error\nexpected:\n%v\n\ngot:\n%v", test.Expected, err)
		}
		if err.Error() != test.Expected {
			t.Fatalf("unexpected error.\nexpected:\n%v\n\ngot:\n%v", test.Expected, err.Error())
		}
	}
}
Example #8
0
func TestLexesPunctuation(t *testing.T) {
	tests := []Test{
		Test{
			Body: "!",
			Expected: Token{
				Kind:  TokenKind[BANG],
				Start: 0,
				End:   1,
				Value: "",
			},
		},
		Test{
			Body: "$",
			Expected: Token{
				Kind:  TokenKind[DOLLAR],
				Start: 0,
				End:   1,
				Value: "",
			},
		},
		Test{
			Body: "(",
			Expected: Token{
				Kind:  TokenKind[PAREN_L],
				Start: 0,
				End:   1,
				Value: "",
			},
		},
		Test{
			Body: ")",
			Expected: Token{
				Kind:  TokenKind[PAREN_R],
				Start: 0,
				End:   1,
				Value: "",
			},
		},
		Test{
			Body: "...",
			Expected: Token{
				Kind:  TokenKind[SPREAD],
				Start: 0,
				End:   3,
				Value: "",
			},
		},
		Test{
			Body: ":",
			Expected: Token{
				Kind:  TokenKind[COLON],
				Start: 0,
				End:   1,
				Value: "",
			},
		},
		Test{
			Body: "=",
			Expected: Token{
				Kind:  TokenKind[EQUALS],
				Start: 0,
				End:   1,
				Value: "",
			},
		},
		Test{
			Body: "@",
			Expected: Token{
				Kind:  TokenKind[AT],
				Start: 0,
				End:   1,
				Value: "",
			},
		},
		Test{
			Body: "[",
			Expected: Token{
				Kind:  TokenKind[BRACKET_L],
				Start: 0,
				End:   1,
				Value: "",
			},
		},
		Test{
			Body: "]",
			Expected: Token{
				Kind:  TokenKind[BRACKET_R],
				Start: 0,
				End:   1,
				Value: "",
			},
		},
		Test{
			Body: "{",
			Expected: Token{
				Kind:  TokenKind[BRACE_L],
				Start: 0,
				End:   1,
				Value: "",
			},
		},
		Test{
			Body: "|",
			Expected: Token{
				Kind:  TokenKind[PIPE],
				Start: 0,
				End:   1,
				Value: "",
			},
		},
		Test{
			Body: "}",
			Expected: Token{
				Kind:  TokenKind[BRACE_R],
				Start: 0,
				End:   1,
				Value: "",
			},
		},
	}
	for _, test := range tests {
		token, err := Lex(source.NewSource(test.Body, ""))(0)
		if err != nil {
			t.Fatalf("unexpected error :%v, test: %v", err, test)
		}
		if !reflect.DeepEqual(token, test.Expected) {
			t.Fatalf("unexpected token, expected: %v, got: %v, test: %v", test.Expected, token, test)
		}
	}
}
Example #9
0
func TestLexReportsUsefulNumbeErrors(t *testing.T) {
	tests := []Test{
		Test{
			Body: "00",
			Expected: `Syntax Error GraphQL (1:2) Invalid number, unexpected digit after 0: "0".

1: 00
    ^
`,
		},
		Test{
			Body: "+1",
			Expected: `Syntax Error GraphQL (1:1) Unexpected character "+".

1: +1
   ^
`,
		},
		Test{
			Body: "1.",
			Expected: `Syntax Error GraphQL (1:3) Invalid number, expected digit but got: EOF.

1: 1.
     ^
`,
		},
		Test{
			Body: ".123",
			Expected: `Syntax Error GraphQL (1:1) Unexpected character ".".

1: .123
   ^
`,
		},
		Test{
			Body: "1.A",
			Expected: `Syntax Error GraphQL (1:3) Invalid number, expected digit but got: "A".

1: 1.A
     ^
`,
		},
		Test{
			Body: "-A",
			Expected: `Syntax Error GraphQL (1:2) Invalid number, expected digit but got: "A".

1: -A
    ^
`,
		},
		Test{
			Body: "1.0e",
			Expected: `Syntax Error GraphQL (1:5) Invalid number, expected digit but got: EOF.

1: 1.0e
       ^
`,
		},
		Test{
			Body: "1.0eA",
			Expected: `Syntax Error GraphQL (1:5) Invalid number, expected digit but got: "A".

1: 1.0eA
       ^
`,
		},
	}
	for _, test := range tests {
		_, err := Lex(source.NewSource(test.Body, ""))(0)
		if err == nil {
			t.Fatalf("unexpected nil error\nexpected:\n%v\n\ngot:\n%v", test.Expected, err)
		}
		if err.Error() != test.Expected {
			t.Fatalf("unexpected error.\nexpected:\n%v\n\ngot:\n%v", test.Expected, err.Error())
		}
	}
}
Example #10
0
func TestLexesNumbers(t *testing.T) {
	tests := []Test{
		Test{
			Body: "4",
			Expected: Token{
				Kind:  TokenKind[INT],
				Start: 0,
				End:   1,
				Value: "4",
			},
		},
		Test{
			Body: "4.123",
			Expected: Token{
				Kind:  TokenKind[FLOAT],
				Start: 0,
				End:   5,
				Value: "4.123",
			},
		},
		Test{
			Body: "-4",
			Expected: Token{
				Kind:  TokenKind[INT],
				Start: 0,
				End:   2,
				Value: "-4",
			},
		},
		Test{
			Body: "9",
			Expected: Token{
				Kind:  TokenKind[INT],
				Start: 0,
				End:   1,
				Value: "9",
			},
		},
		Test{
			Body: "0",
			Expected: Token{
				Kind:  TokenKind[INT],
				Start: 0,
				End:   1,
				Value: "0",
			},
		},
		Test{
			Body: "-4.123",
			Expected: Token{
				Kind:  TokenKind[FLOAT],
				Start: 0,
				End:   6,
				Value: "-4.123",
			},
		},
		Test{
			Body: "0.123",
			Expected: Token{
				Kind:  TokenKind[FLOAT],
				Start: 0,
				End:   5,
				Value: "0.123",
			},
		},
		Test{
			Body: "123e4",
			Expected: Token{
				Kind:  TokenKind[FLOAT],
				Start: 0,
				End:   5,
				Value: "123e4",
			},
		},
		Test{
			Body: "123E4",
			Expected: Token{
				Kind:  TokenKind[FLOAT],
				Start: 0,
				End:   5,
				Value: "123E4",
			},
		},
		Test{
			Body: "123e-4",
			Expected: Token{
				Kind:  TokenKind[FLOAT],
				Start: 0,
				End:   6,
				Value: "123e-4",
			},
		},
		Test{
			Body: "123e+4",
			Expected: Token{
				Kind:  TokenKind[FLOAT],
				Start: 0,
				End:   6,
				Value: "123e+4",
			},
		},
		Test{
			Body: "-1.123e4",
			Expected: Token{
				Kind:  TokenKind[FLOAT],
				Start: 0,
				End:   8,
				Value: "-1.123e4",
			},
		},
		Test{
			Body: "-1.123E4",
			Expected: Token{
				Kind:  TokenKind[FLOAT],
				Start: 0,
				End:   8,
				Value: "-1.123E4",
			},
		},
		Test{
			Body: "-1.123e-4",
			Expected: Token{
				Kind:  TokenKind[FLOAT],
				Start: 0,
				End:   9,
				Value: "-1.123e-4",
			},
		},
		Test{
			Body: "-1.123e+4",
			Expected: Token{
				Kind:  TokenKind[FLOAT],
				Start: 0,
				End:   9,
				Value: "-1.123e+4",
			},
		},
		Test{
			Body: "-1.123e4567",
			Expected: Token{
				Kind:  TokenKind[FLOAT],
				Start: 0,
				End:   11,
				Value: "-1.123e4567",
			},
		},
	}
	for _, test := range tests {
		token, err := Lex(source.NewSource(test.Body, ""))(0)
		if err != nil {
			t.Fatalf("unexpected error: %v, test: %s", err, test)
		}
		if !reflect.DeepEqual(token, test.Expected) {
			t.Fatalf("unexpected token, expected: %v, got: %v, test: %v", test.Expected, token, test)
		}
	}
}
Example #11
0
func TestLexReportsUsefulStringErrors(t *testing.T) {
	tests := []Test{
		Test{
			Body: "\"no end quote",
			Expected: `Syntax Error GraphQL (1:14) Unterminated string.

1: "no end quote
                ^
`,
		},
		Test{
			Body: "\"multi\nline\"",
			Expected: `Syntax Error GraphQL (1:7) Unterminated string.

1: "multi
         ^
2: line"
`,
		},
		Test{
			Body: "\"multi\rline\"",
			Expected: `Syntax Error GraphQL (1:7) Unterminated string.

1: "multi
         ^
2: line"
`,
		},
		Test{
			Body: "\"multi\u2028line\"",
			Expected: `Syntax Error GraphQL (1:7) Unterminated string.

1: "multi
         ^
2: line"
`,
		},
		Test{
			Body: "\"multi\u2029line\"",
			Expected: `Syntax Error GraphQL (1:7) Unterminated string.

1: "multi
         ^
2: line"
`,
		},
		Test{
			Body: "\"bad \\z esc\"",
			Expected: `Syntax Error GraphQL (1:7) Bad character escape sequence.

1: "bad \z esc"
         ^
`,
		},
		Test{
			Body: "\"bad \\x esc\"",
			Expected: `Syntax Error GraphQL (1:7) Bad character escape sequence.

1: "bad \x esc"
         ^
`,
		},
		Test{
			Body: "\"bad \\u1 esc\"",
			Expected: `Syntax Error GraphQL (1:7) Bad character escape sequence.

1: "bad \u1 esc"
         ^
`,
		},
		Test{
			Body: "\"bad \\u0XX1 esc\"",
			Expected: `Syntax Error GraphQL (1:7) Bad character escape sequence.

1: "bad \u0XX1 esc"
         ^
`,
		},
		Test{
			Body: "\"bad \\uXXXX esc\"",
			Expected: `Syntax Error GraphQL (1:7) Bad character escape sequence.

1: "bad \uXXXX esc"
         ^
`,
		},
		Test{
			Body: "\"bad \\uFXXX esc\"",
			Expected: `Syntax Error GraphQL (1:7) Bad character escape sequence.

1: "bad \uFXXX esc"
         ^
`,
		},
		Test{
			Body: "\"bad \\uXXXF esc\"",
			Expected: `Syntax Error GraphQL (1:7) Bad character escape sequence.

1: "bad \uXXXF esc"
         ^
`,
		},
	}
	for _, test := range tests {
		_, err := Lex(source.NewSource(test.Body, ""))(0)
		if err == nil {
			t.Fatalf("unexpected nil error\nexpected:\n%v\n\ngot:\n%v", test.Expected, err)
		}
		if err.Error() != test.Expected {
			t.Fatalf("unexpected error.\nexpected:\n%v\n\ngot:\n%v", test.Expected, err.Error())
		}
	}
}
func TestParseCreatesAst(t *testing.T) {
	body := `{
  node(id: 4) {
    id,
    name
  }
}
`
	source := source.NewSource(&source.Source{Body: body})
	document, err := Parse(
		ParseParams{
			Source: source,
			Options: ParseOptions{
				NoSource: true,
			},
		},
	)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	oDef := ast.OperationDefinition{
		Kind: "OperationDefinition",
		Loc: &ast.Location{
			Start: 0, End: 40,
		},
		Operation:  "query",
		Directives: []*ast.Directive{},
		SelectionSet: &ast.SelectionSet{
			Kind: "SelectionSet",
			Loc: &ast.Location{
				Start: 0, End: 40,
			},
			Selections: []ast.Selection{
				&ast.Field{
					Kind: "Field",
					Loc: &ast.Location{
						Start: 4, End: 38,
					},
					Name: &ast.Name{
						Kind: "Name",
						Loc: &ast.Location{
							Start: 4, End: 8,
						},
						Value: "node",
					},
					Arguments: []*ast.Argument{
						{
							Kind: "Argument",
							Name: &ast.Name{
								Kind: "Name",
								Loc: &ast.Location{
									Start: 9, End: 11,
								},
								Value: "id",
							},
							Value: &ast.IntValue{
								Kind: "IntValue",
								Loc: &ast.Location{
									Start: 13, End: 14,
								},
								Value: "4",
							},
							Loc: &ast.Location{
								Start: 9, End: 14,
							},
						},
					},
					Directives: []*ast.Directive{},
					SelectionSet: &ast.SelectionSet{
						Kind: "SelectionSet",
						Loc: &ast.Location{
							Start: 16, End: 38,
						},
						Selections: []ast.Selection{
							&ast.Field{
								Kind: "Field",
								Loc: &ast.Location{
									Start: 22, End: 24,
								},
								Name: &ast.Name{
									Kind: "Name",
									Loc: &ast.Location{
										Start: 22, End: 24,
									},
									Value: "id",
								},
								Arguments:    []*ast.Argument{},
								Directives:   []*ast.Directive{},
								SelectionSet: nil,
							},
							&ast.Field{
								Kind: "Field",
								Loc: &ast.Location{
									Start: 30, End: 34,
								},
								Name: &ast.Name{
									Kind: "Name",
									Loc: &ast.Location{
										Start: 30, End: 34,
									},
									Value: "name",
								},
								Arguments:    []*ast.Argument{},
								Directives:   []*ast.Directive{},
								SelectionSet: nil,
							},
						},
					},
				},
			},
		},
	}
	expectedDocument := ast.NewDocument(&ast.Document{
		Loc: &ast.Location{
			Start: 0, End: 41,
		},
		Definitions: []ast.Node{&oDef},
	})
	if !reflect.DeepEqual(document, expectedDocument) {
		t.Fatalf("unexpected document, expected: %v, got: %v", expectedDocument, document)
	}

}