Skip to content
This repository was archived by the owner on Apr 1, 2024. It is now read-only.

Commit 6cc243f

Browse files
authored
Merge pull request #17 from Code-Hex/add/tests
add introspection tests
2 parents fff53f6 + c12f709 commit 6cc243f

File tree

9 files changed

+455
-62
lines changed

9 files changed

+455
-62
lines changed

go.mod

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ go 1.16
44

55
require (
66
github.com/99designs/gqlgen v0.13.0
7-
github.com/Code-Hex/gqlparser/v2 v2.1.1-0.20210404043438-758ac252308a
7+
github.com/Code-Hex/gqlparser/v2 v2.1.1-0.20210406023454-534efe0eae8e
88
github.com/agnivade/levenshtein v1.1.0 // indirect
9+
github.com/goccy/go-yaml v1.8.9
910
github.com/google/go-cmp v0.5.5
1011
github.com/machinebox/graphql v0.2.2
1112
github.com/matryer/is v1.4.0 // indirect
@@ -14,4 +15,5 @@ require (
1415
github.com/russross/blackfriday/v2 v2.1.0
1516
github.com/urfave/cli/v2 v2.3.0
1617
github.com/vektah/gqlparser/v2 v2.1.0
18+
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57 // indirect
1719
)

go.sum

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ github.com/99designs/gqlgen v0.13.0/go.mod h1:NV130r6f4tpRWuAI+zsrSdooO/eWUv+Gyy
33
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
44
github.com/Code-Hex/gqlparser/v2 v2.1.1-0.20210404043438-758ac252308a h1:IzMV22Hitzxqb71um5i64jEJTyeUVwemK8JmcQdgpA4=
55
github.com/Code-Hex/gqlparser/v2 v2.1.1-0.20210404043438-758ac252308a/go.mod h1:0sYgRh/Er/ZhHrcKw516TOX4K0ul94vKcBSXAPhLWDc=
6+
github.com/Code-Hex/gqlparser/v2 v2.1.1-0.20210406023454-534efe0eae8e h1:dF5TaS3uw9LA8e75LojnUmnHdhfw1I1ScV9Qy1Stuu8=
7+
github.com/Code-Hex/gqlparser/v2 v2.1.1-0.20210406023454-534efe0eae8e/go.mod h1:0sYgRh/Er/ZhHrcKw516TOX4K0ul94vKcBSXAPhLWDc=
68
github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
79
github.com/agnivade/levenshtein v1.0.3/go.mod h1:4SFRZbbXWLF4MU1T9Qg0pGgH3Pjs+t6ie5efyrwRJXs=
810
github.com/agnivade/levenshtein v1.1.0 h1:n6qGwyHG61v3ABce1rPVZklEYRT8NFpCMrpZdBUbYGM=
@@ -19,7 +21,18 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
1921
github.com/dgryski/trifles v0.0.0-20190318185328-a8d75aae118c/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA=
2022
github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48 h1:fRzb/w+pyskVMQ+UbP35JkH8yB7MYb4q/qhBarqZE6g=
2123
github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA=
24+
github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg=
25+
github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
2226
github.com/go-chi/chi v3.3.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ=
27+
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
28+
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
29+
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
30+
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
31+
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
32+
github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE=
33+
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
34+
github.com/goccy/go-yaml v1.8.9 h1:4AEXg2qx+/w29jXnXpMY6mTckmYu1TMoHteKuMf0HFg=
35+
github.com/goccy/go-yaml v1.8.9/go.mod h1:U/jl18uSupI5rdI2jmuCswEA2htH9eXfferR3KfscvA=
2336
github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
2437
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
2538
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
@@ -30,14 +43,19 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
3043
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
3144
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
3245
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
46+
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
47+
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
3348
github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
3449
github.com/machinebox/graphql v0.2.2 h1:dWKpJligYKhYKO5A2gvNhkJdQMNZeChZYyBbrZkBZfo=
3550
github.com/machinebox/graphql v0.2.2/go.mod h1:F+kbVMHuwrQ5tYgU9JXlnskM8nOaFxCAEolaQybkjWA=
3651
github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE=
3752
github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU=
3853
github.com/matryer/moq v0.0.0-20200106131100-75d0ddfc0007/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ=
3954
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
55+
github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
56+
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
4057
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
58+
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
4159
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
4260
github.com/mattn/go-zglob v0.0.3 h1:6Ry4EYsScDyt5di4OI6xw1bYhOqfE5S33Z1OPy+d+To=
4361
github.com/mattn/go-zglob v0.0.3/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo=
@@ -69,6 +87,8 @@ github.com/vektah/gqlparser/v2 v2.1.0 h1:uiKJ+T5HMGGQM2kRKQ8Pxw8+Zq9qhhZhz/lieYv
6987
github.com/vektah/gqlparser/v2 v2.1.0/go.mod h1:SyUiHgLATUR8BiYURfTirrTcGpcE+4XkV2se04Px1Ms=
7088
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
7189
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
90+
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
91+
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
7292
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
7393
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
7494
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
@@ -78,13 +98,19 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h
7898
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
7999
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
80100
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
101+
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
102+
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57 h1:F5Gozwx4I1xtr/sr/8CFbb57iKi3297KFs0QDbGN60A=
103+
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
81104
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
105+
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
106+
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
82107
golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
83108
golang.org/x/tools v0.0.0-20190515012406-7d7faa4812bd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
84109
golang.org/x/tools v0.0.0-20200114235610-7ae403b6b589/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
85110
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
86-
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
87111
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
112+
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
113+
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
88114
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
89115
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
90116
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

internal/gqlgen/gqlgen.go

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,53 @@ import (
1414
"github.com/Code-Hex/gqldoc/internal/wrapper"
1515
gqlparser "github.com/Code-Hex/gqlparser/v2"
1616
"github.com/Code-Hex/gqlparser/v2/ast"
17+
"github.com/Code-Hex/gqlparser/v2/parser"
18+
"github.com/Code-Hex/gqlparser/v2/validator"
19+
"github.com/pkg/errors"
1720
)
1821

22+
type Params struct {
23+
Schema *ast.Schema
24+
Query string
25+
Variables map[string]interface{}
26+
}
27+
28+
func CreateOperationContext(params Params) (*graphql.OperationContext, error) {
29+
doc, err := parseQuery(params.Schema, params.Query)
30+
if err != nil {
31+
return nil, err
32+
}
33+
operation := doc.Operations.ForName("")
34+
if operation == nil {
35+
return nil, errors.New("operation not found")
36+
}
37+
variables, verr := validator.VariableValues(params.Schema, operation, params.Variables)
38+
if verr != nil {
39+
return nil, errors.WithStack(verr)
40+
}
41+
42+
return &graphql.OperationContext{
43+
RawQuery: params.Query,
44+
Variables: variables,
45+
Doc: doc,
46+
Operation: operation,
47+
}, nil
48+
}
49+
50+
func parseQuery(schema *ast.Schema, query string) (*ast.QueryDocument, error) {
51+
doc, err := parser.ParseQuery(&ast.Source{
52+
Input: query,
53+
})
54+
if err != nil {
55+
return nil, errors.WithStack(err)
56+
}
57+
listErr := validator.Validate(schema, doc)
58+
if len(listErr) != 0 {
59+
return nil, listErr
60+
}
61+
return doc, nil
62+
}
63+
1964
func NewExecutableSchema(filenames ...string) (*ExecutableSchema, error) {
2065
sources := make([]*ast.Source, len(filenames))
2166
for i, filename := range filenames {
@@ -38,10 +83,22 @@ func NewExecutableSchema(filenames ...string) (*ExecutableSchema, error) {
3883
}
3984

4085
type ExecutableSchema struct {
41-
ParsedSchema *ast.Schema
86+
ParsedSchema *ast.Schema
87+
wantReservedTypes bool
4288
}
4389

44-
func (e *ExecutableSchema) Exec(oc *graphql.OperationContext) *bytes.Buffer {
90+
type ExecOption func(es *ExecutableSchema)
91+
92+
func WithReservedTypes(want bool) ExecOption {
93+
return func(es *ExecutableSchema) {
94+
es.wantReservedTypes = want
95+
}
96+
}
97+
98+
func (e *ExecutableSchema) Exec(oc *graphql.OperationContext, opts ...ExecOption) *bytes.Buffer {
99+
for _, opt := range opts {
100+
opt(e)
101+
}
45102
ec := executionContext{oc, e}
46103
data := ec._Query(context.Background(), oc.Operation.SelectionSet)
47104
var buf bytes.Buffer
@@ -55,7 +112,7 @@ type executionContext struct {
55112
}
56113

57114
func (ec *executionContext) introspectSchema() *wrapper.Schema {
58-
return wrapper.WrapSchema(ec.ParsedSchema)
115+
return wrapper.WrapSchema(ec.ParsedSchema, wrapper.WithReservedTypes(ec.wantReservedTypes))
59116
}
60117

61118
func (ec *executionContext) introspectType(name string) *wrapper.Type {
@@ -514,6 +571,8 @@ func (ec *executionContext) ___Schema(ctx context.Context, sel ast.SelectionSet,
514571
if out.Values[i] == gql.Null {
515572
invalids++
516573
}
574+
case "description":
575+
out.Values[i] = gql.MarshalString(obj.Description())
517576
default:
518577
panic("unknown field " + strconv.Quote(field.Name))
519578
}

internal/gqlgen/gqlgen_test.go

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package gqlgen_test
33
import (
44
"context"
55
"encoding/json"
6+
"io/ioutil"
67
"path/filepath"
78
"testing"
89

@@ -11,6 +12,9 @@ import (
1112
"github.com/Code-Hex/gqldoc/internal/gqlgen"
1213
"github.com/Code-Hex/gqldoc/internal/introspection"
1314
"github.com/Code-Hex/gqldoc/loader"
15+
gqlparser "github.com/Code-Hex/gqlparser/v2"
16+
"github.com/Code-Hex/gqlparser/v2/ast"
17+
"github.com/goccy/go-yaml"
1418
"github.com/google/go-cmp/cmp"
1519
"github.com/google/go-cmp/cmp/cmpopts"
1620
"github.com/pkg/errors"
@@ -70,3 +74,89 @@ func LoadSchema(filenames ...string) (*introspection.Root, error) {
7074
}
7175
return &res, nil
7276
}
77+
78+
func TestExec(t *testing.T) {
79+
RunSpec(t, "gqlgen_test.yml", func(t *testing.T, schema, query string) ([]byte, error) {
80+
source := &ast.Source{
81+
Name: "test.gql",
82+
Input: schema,
83+
}
84+
AST, gerr := gqlparser.LoadSchema(source)
85+
if gerr != nil {
86+
return nil, gerr
87+
}
88+
89+
oc, err := gqlgen.CreateOperationContext(
90+
gqlgen.Params{
91+
Schema: AST,
92+
Query: query,
93+
Variables: map[string]interface{}{},
94+
},
95+
)
96+
if err != nil {
97+
return nil, err
98+
}
99+
100+
es := &gqlgen.ExecutableSchema{
101+
ParsedSchema: AST,
102+
}
103+
104+
resp := es.Exec(oc, gqlgen.WithReservedTypes(true))
105+
106+
return resp.Bytes(), nil
107+
})
108+
}
109+
110+
type Features struct {
111+
Tests map[string][]Spec
112+
}
113+
114+
type Spec struct {
115+
Name string
116+
Schema string
117+
Query string
118+
Error error
119+
JSON string
120+
}
121+
122+
func RunSpec(t *testing.T, filename string, f func(t *testing.T, schema, query string) ([]byte, error)) {
123+
b, err := ioutil.ReadFile(filename)
124+
if err != nil {
125+
panic(err)
126+
}
127+
var features Features
128+
err = yaml.Unmarshal(b, &features)
129+
if err != nil {
130+
t.Errorf("unable to load %s: %s", filename, err.Error())
131+
return
132+
}
133+
for name, specs := range features.Tests {
134+
t.Run(name, func(t *testing.T) {
135+
for _, spec := range specs {
136+
t.Run(spec.Name, func(t *testing.T) {
137+
gotJSON, err := f(t, spec.Schema, spec.Query)
138+
if spec.Error != nil {
139+
if diff := cmp.Diff(spec.Error, err); diff != "" {
140+
t.Fatalf("error (-want, +got)\n%s", diff)
141+
}
142+
}
143+
if err != nil {
144+
t.Fatalf("unexpected error: %v", err)
145+
}
146+
if spec.JSON != "" {
147+
var got, want interface{}
148+
if err := json.Unmarshal(gotJSON, &got); err != nil {
149+
t.Fatal(err)
150+
}
151+
if err := json.Unmarshal([]byte(spec.JSON), &want); err != nil {
152+
t.Fatal(err)
153+
}
154+
if diff := cmp.Diff(want, got); diff != "" {
155+
t.Fatalf("json (-want, +got)\n%s", diff)
156+
}
157+
}
158+
})
159+
}
160+
})
161+
}
162+
}

0 commit comments

Comments
 (0)