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

add introspection tests #17

Merged
merged 5 commits into from
Apr 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ go 1.16

require (
github.com/99designs/gqlgen v0.13.0
github.com/Code-Hex/gqlparser/v2 v2.1.1-0.20210404043438-758ac252308a
github.com/Code-Hex/gqlparser/v2 v2.1.1-0.20210406023454-534efe0eae8e
github.com/agnivade/levenshtein v1.1.0 // indirect
github.com/goccy/go-yaml v1.8.9
github.com/google/go-cmp v0.5.5
github.com/machinebox/graphql v0.2.2
github.com/matryer/is v1.4.0 // indirect
Expand All @@ -14,4 +15,5 @@ require (
github.com/russross/blackfriday/v2 v2.1.0
github.com/urfave/cli/v2 v2.3.0
github.com/vektah/gqlparser/v2 v2.1.0
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57 // indirect
)
28 changes: 27 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ github.com/99designs/gqlgen v0.13.0/go.mod h1:NV130r6f4tpRWuAI+zsrSdooO/eWUv+Gyy
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/Code-Hex/gqlparser/v2 v2.1.1-0.20210404043438-758ac252308a h1:IzMV22Hitzxqb71um5i64jEJTyeUVwemK8JmcQdgpA4=
github.com/Code-Hex/gqlparser/v2 v2.1.1-0.20210404043438-758ac252308a/go.mod h1:0sYgRh/Er/ZhHrcKw516TOX4K0ul94vKcBSXAPhLWDc=
github.com/Code-Hex/gqlparser/v2 v2.1.1-0.20210406023454-534efe0eae8e h1:dF5TaS3uw9LA8e75LojnUmnHdhfw1I1ScV9Qy1Stuu8=
github.com/Code-Hex/gqlparser/v2 v2.1.1-0.20210406023454-534efe0eae8e/go.mod h1:0sYgRh/Er/ZhHrcKw516TOX4K0ul94vKcBSXAPhLWDc=
github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
github.com/agnivade/levenshtein v1.0.3/go.mod h1:4SFRZbbXWLF4MU1T9Qg0pGgH3Pjs+t6ie5efyrwRJXs=
github.com/agnivade/levenshtein v1.1.0 h1:n6qGwyHG61v3ABce1rPVZklEYRT8NFpCMrpZdBUbYGM=
Expand All @@ -19,7 +21,18 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/dgryski/trifles v0.0.0-20190318185328-a8d75aae118c/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA=
github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48 h1:fRzb/w+pyskVMQ+UbP35JkH8yB7MYb4q/qhBarqZE6g=
github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA=
github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg=
github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
github.com/go-chi/chi v3.3.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ=
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE=
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
github.com/goccy/go-yaml v1.8.9 h1:4AEXg2qx+/w29jXnXpMY6mTckmYu1TMoHteKuMf0HFg=
github.com/goccy/go-yaml v1.8.9/go.mod h1:U/jl18uSupI5rdI2jmuCswEA2htH9eXfferR3KfscvA=
github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
Expand All @@ -30,14 +43,19 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
github.com/machinebox/graphql v0.2.2 h1:dWKpJligYKhYKO5A2gvNhkJdQMNZeChZYyBbrZkBZfo=
github.com/machinebox/graphql v0.2.2/go.mod h1:F+kbVMHuwrQ5tYgU9JXlnskM8nOaFxCAEolaQybkjWA=
github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE=
github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU=
github.com/matryer/moq v0.0.0-20200106131100-75d0ddfc0007/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-zglob v0.0.3 h1:6Ry4EYsScDyt5di4OI6xw1bYhOqfE5S33Z1OPy+d+To=
github.com/mattn/go-zglob v0.0.3/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo=
Expand Down Expand Up @@ -69,6 +87,8 @@ github.com/vektah/gqlparser/v2 v2.1.0 h1:uiKJ+T5HMGGQM2kRKQ8Pxw8+Zq9qhhZhz/lieYv
github.com/vektah/gqlparser/v2 v2.1.0/go.mod h1:SyUiHgLATUR8BiYURfTirrTcGpcE+4XkV2se04Px1Ms=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
Expand All @@ -78,13 +98,19 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57 h1:F5Gozwx4I1xtr/sr/8CFbb57iKi3297KFs0QDbGN60A=
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190515012406-7d7faa4812bd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20200114235610-7ae403b6b589/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
Expand Down
65 changes: 62 additions & 3 deletions internal/gqlgen/gqlgen.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,53 @@ import (
"github.com/Code-Hex/gqldoc/internal/wrapper"
gqlparser "github.com/Code-Hex/gqlparser/v2"
"github.com/Code-Hex/gqlparser/v2/ast"
"github.com/Code-Hex/gqlparser/v2/parser"
"github.com/Code-Hex/gqlparser/v2/validator"
"github.com/pkg/errors"
)

type Params struct {
Schema *ast.Schema
Query string
Variables map[string]interface{}
}

func CreateOperationContext(params Params) (*graphql.OperationContext, error) {
doc, err := parseQuery(params.Schema, params.Query)
if err != nil {
return nil, err
}
operation := doc.Operations.ForName("")
if operation == nil {
return nil, errors.New("operation not found")
}
variables, verr := validator.VariableValues(params.Schema, operation, params.Variables)
if verr != nil {
return nil, errors.WithStack(verr)
}

return &graphql.OperationContext{
RawQuery: params.Query,
Variables: variables,
Doc: doc,
Operation: operation,
}, nil
}

func parseQuery(schema *ast.Schema, query string) (*ast.QueryDocument, error) {
doc, err := parser.ParseQuery(&ast.Source{
Input: query,
})
if err != nil {
return nil, errors.WithStack(err)
}
listErr := validator.Validate(schema, doc)
if len(listErr) != 0 {
return nil, listErr
}
return doc, nil
}

func NewExecutableSchema(filenames ...string) (*ExecutableSchema, error) {
sources := make([]*ast.Source, len(filenames))
for i, filename := range filenames {
Expand All @@ -38,10 +83,22 @@ func NewExecutableSchema(filenames ...string) (*ExecutableSchema, error) {
}

type ExecutableSchema struct {
ParsedSchema *ast.Schema
ParsedSchema *ast.Schema
wantReservedTypes bool
}

func (e *ExecutableSchema) Exec(oc *graphql.OperationContext) *bytes.Buffer {
type ExecOption func(es *ExecutableSchema)

func WithReservedTypes(want bool) ExecOption {
return func(es *ExecutableSchema) {
es.wantReservedTypes = want
}
}

func (e *ExecutableSchema) Exec(oc *graphql.OperationContext, opts ...ExecOption) *bytes.Buffer {
for _, opt := range opts {
opt(e)
}
ec := executionContext{oc, e}
data := ec._Query(context.Background(), oc.Operation.SelectionSet)
var buf bytes.Buffer
Expand All @@ -55,7 +112,7 @@ type executionContext struct {
}

func (ec *executionContext) introspectSchema() *wrapper.Schema {
return wrapper.WrapSchema(ec.ParsedSchema)
return wrapper.WrapSchema(ec.ParsedSchema, wrapper.WithReservedTypes(ec.wantReservedTypes))
}

func (ec *executionContext) introspectType(name string) *wrapper.Type {
Expand Down Expand Up @@ -514,6 +571,8 @@ func (ec *executionContext) ___Schema(ctx context.Context, sel ast.SelectionSet,
if out.Values[i] == gql.Null {
invalids++
}
case "description":
out.Values[i] = gql.MarshalString(obj.Description())
default:
panic("unknown field " + strconv.Quote(field.Name))
}
Expand Down
90 changes: 90 additions & 0 deletions internal/gqlgen/gqlgen_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package gqlgen_test
import (
"context"
"encoding/json"
"io/ioutil"
"path/filepath"
"testing"

Expand All @@ -11,6 +12,9 @@ import (
"github.com/Code-Hex/gqldoc/internal/gqlgen"
"github.com/Code-Hex/gqldoc/internal/introspection"
"github.com/Code-Hex/gqldoc/loader"
gqlparser "github.com/Code-Hex/gqlparser/v2"
"github.com/Code-Hex/gqlparser/v2/ast"
"github.com/goccy/go-yaml"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"github.com/pkg/errors"
Expand Down Expand Up @@ -70,3 +74,89 @@ func LoadSchema(filenames ...string) (*introspection.Root, error) {
}
return &res, nil
}

func TestExec(t *testing.T) {
RunSpec(t, "gqlgen_test.yml", func(t *testing.T, schema, query string) ([]byte, error) {
source := &ast.Source{
Name: "test.gql",
Input: schema,
}
AST, gerr := gqlparser.LoadSchema(source)
if gerr != nil {
return nil, gerr
}

oc, err := gqlgen.CreateOperationContext(
gqlgen.Params{
Schema: AST,
Query: query,
Variables: map[string]interface{}{},
},
)
if err != nil {
return nil, err
}

es := &gqlgen.ExecutableSchema{
ParsedSchema: AST,
}

resp := es.Exec(oc, gqlgen.WithReservedTypes(true))

return resp.Bytes(), nil
})
}

type Features struct {
Tests map[string][]Spec
}

type Spec struct {
Name string
Schema string
Query string
Error error
JSON string
}

func RunSpec(t *testing.T, filename string, f func(t *testing.T, schema, query string) ([]byte, error)) {
b, err := ioutil.ReadFile(filename)
if err != nil {
panic(err)
}
var features Features
err = yaml.Unmarshal(b, &features)
if err != nil {
t.Errorf("unable to load %s: %s", filename, err.Error())
return
}
for name, specs := range features.Tests {
t.Run(name, func(t *testing.T) {
for _, spec := range specs {
t.Run(spec.Name, func(t *testing.T) {
gotJSON, err := f(t, spec.Schema, spec.Query)
if spec.Error != nil {
if diff := cmp.Diff(spec.Error, err); diff != "" {
t.Fatalf("error (-want, +got)\n%s", diff)
}
}
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if spec.JSON != "" {
var got, want interface{}
if err := json.Unmarshal(gotJSON, &got); err != nil {
t.Fatal(err)
}
if err := json.Unmarshal([]byte(spec.JSON), &want); err != nil {
t.Fatal(err)
}
if diff := cmp.Diff(want, got); diff != "" {
t.Fatalf("json (-want, +got)\n%s", diff)
}
}
})
}
})
}
}
Loading