...

Source file src/github.com/vektah/gqlparser/parser/testrunner/runner.go

Documentation: github.com/vektah/gqlparser/parser/testrunner

     1  package testrunner
     2  
     3  import (
     4  	"io/ioutil"
     5  	"strconv"
     6  	"strings"
     7  	"testing"
     8  
     9  	"github.com/andreyvit/diff"
    10  	"github.com/vektah/gqlparser/gqlerror"
    11  	"gopkg.in/yaml.v2"
    12  )
    13  
    14  type Features map[string][]Spec
    15  
    16  type Spec struct {
    17  	Name   string
    18  	Input  string
    19  	Error  *gqlerror.Error
    20  	Tokens []Token
    21  	AST    string
    22  }
    23  
    24  type Token struct {
    25  	Kind   string
    26  	Value  string
    27  	Start  int
    28  	End    int
    29  	Line   int
    30  	Column int
    31  	Src    string
    32  }
    33  
    34  func (t Token) String() string {
    35  	return t.Kind + " " + strconv.Quote(t.Value)
    36  }
    37  
    38  func Test(t *testing.T, filename string, f func(t *testing.T, input string) Spec) {
    39  	b, err := ioutil.ReadFile(filename)
    40  	if err != nil {
    41  		panic(err)
    42  	}
    43  	var tests Features
    44  	err = yaml.Unmarshal(b, &tests)
    45  	if err != nil {
    46  		t.Errorf("unable to load %s: %s", filename, err.Error())
    47  		return
    48  	}
    49  
    50  	for name, specs := range tests {
    51  		t.Run(name, func(t *testing.T) {
    52  			for _, spec := range specs {
    53  				t.Run(spec.Name, func(t *testing.T) {
    54  					result := f(t, spec.Input)
    55  
    56  					if spec.Error == nil {
    57  						if result.Error != nil {
    58  							t.Errorf("unexpected error %s", result.Error.Message)
    59  						}
    60  					} else if result.Error == nil {
    61  						t.Errorf("expected error but got none")
    62  					} else {
    63  						if result.Error.Message != spec.Error.Message {
    64  							t.Errorf("wrong error returned\nexpected: %s\ngot:      %s", spec.Error.Message, result.Error.Message)
    65  						}
    66  
    67  						if result.Error.Locations[0].Column != spec.Error.Locations[0].Column || result.Error.Locations[0].Line != spec.Error.Locations[0].Line {
    68  							t.Errorf(
    69  								"wrong error location:\nexpected: line %d column %d\ngot:      line %d column %d",
    70  								spec.Error.Locations[0].Line,
    71  								spec.Error.Locations[0].Column,
    72  								result.Error.Locations[0].Line,
    73  								result.Error.Locations[0].Column,
    74  							)
    75  						}
    76  					}
    77  
    78  					if len(spec.Tokens) != len(result.Tokens) {
    79  						var tokensStr []string
    80  						for _, t := range result.Tokens {
    81  							tokensStr = append(tokensStr, t.String())
    82  						}
    83  						t.Errorf("token count mismatch, got: \n%s", strings.Join(tokensStr, "\n"))
    84  					} else {
    85  						for i, tok := range result.Tokens {
    86  							expected := spec.Tokens[i]
    87  
    88  							if !strings.EqualFold(strings.Replace(expected.Kind, "_", "", -1), tok.Kind) {
    89  								t.Errorf("token[%d].kind should be %s, was %s", i, expected.Kind, tok.Kind)
    90  							}
    91  							if expected.Value != "undefined" && expected.Value != tok.Value {
    92  								t.Errorf("token[%d].value incorrect\nexpected: %s\ngot:      %s", i, strconv.Quote(expected.Value), strconv.Quote(tok.Value))
    93  							}
    94  							if expected.Start != 0 && expected.Start != tok.Start {
    95  								t.Errorf("token[%d].start should be %d, was %d", i, expected.Start, tok.Start)
    96  							}
    97  							if expected.End != 0 && expected.End != tok.End {
    98  								t.Errorf("token[%d].end should be %d, was %d", i, expected.End, tok.End)
    99  							}
   100  							if expected.Line != 0 && expected.Line != tok.Line {
   101  								t.Errorf("token[%d].line should be %d, was %d", i, expected.Line, tok.Line)
   102  							}
   103  							if expected.Column != 0 && expected.Column != tok.Column {
   104  								t.Errorf("token[%d].column should be %d, was %d", i, expected.Column, tok.Column)
   105  							}
   106  							if tok.Src != "spec" {
   107  								t.Errorf("token[%d].source.name should be spec, was %s", i, strconv.Quote(tok.Src))
   108  							}
   109  						}
   110  					}
   111  
   112  					spec.AST = strings.TrimSpace(spec.AST)
   113  					result.AST = strings.TrimSpace(result.AST)
   114  
   115  					if spec.AST != "" && spec.AST != result.AST {
   116  						diff := diff.LineDiff(spec.AST, result.AST)
   117  						if diff != "" {
   118  							t.Errorf("AST mismatch:\n%s", diff)
   119  						}
   120  					}
   121  
   122  					if t.Failed() {
   123  						t.Logf("input: %s", strconv.Quote(spec.Input))
   124  						if result.Error != nil {
   125  							t.Logf("error: %s", result.Error.Message)
   126  						}
   127  						t.Log("tokens: ")
   128  						for _, tok := range result.Tokens {
   129  							t.Logf("  - %s", tok.String())
   130  						}
   131  						t.Logf("  - <EOF>")
   132  					}
   133  				})
   134  			}
   135  		})
   136  	}
   137  
   138  }
   139  

View as plain text