1package jmespath 2 3import ( 4 "encoding/json" 5 "fmt" 6 "io/ioutil" 7 "os" 8 "path/filepath" 9 "testing" 10 11 "github.com/stretchr/testify/assert" 12) 13 14type TestSuite struct { 15 Given interface{} 16 TestCases []TestCase `json:"cases"` 17 Comment string 18} 19type TestCase struct { 20 Comment string 21 Expression string 22 Result interface{} 23 Error string 24} 25 26var whiteListed = []string{ 27 "compliance/basic.json", 28 "compliance/current.json", 29 "compliance/escape.json", 30 "compliance/filters.json", 31 "compliance/functions.json", 32 "compliance/identifiers.json", 33 "compliance/indices.json", 34 "compliance/literal.json", 35 "compliance/multiselect.json", 36 "compliance/ormatch.json", 37 "compliance/pipe.json", 38 "compliance/slice.json", 39 "compliance/syntax.json", 40 "compliance/unicode.json", 41 "compliance/wildcard.json", 42 "compliance/boolean.json", 43} 44 45func allowed(path string) bool { 46 for _, el := range whiteListed { 47 if el == path { 48 return true 49 } 50 } 51 return false 52} 53 54func TestCompliance(t *testing.T) { 55 assert := assert.New(t) 56 57 var complianceFiles []string 58 err := filepath.Walk("compliance", func(path string, _ os.FileInfo, _ error) error { 59 //if strings.HasSuffix(path, ".json") { 60 if allowed(path) { 61 complianceFiles = append(complianceFiles, path) 62 } 63 return nil 64 }) 65 if assert.Nil(err) { 66 for _, filename := range complianceFiles { 67 runComplianceTest(assert, filename) 68 } 69 } 70} 71 72func runComplianceTest(assert *assert.Assertions, filename string) { 73 var testSuites []TestSuite 74 data, err := ioutil.ReadFile(filename) 75 if assert.Nil(err) { 76 err := json.Unmarshal(data, &testSuites) 77 if assert.Nil(err) { 78 for _, testsuite := range testSuites { 79 runTestSuite(assert, testsuite, filename) 80 } 81 } 82 } 83} 84 85func runTestSuite(assert *assert.Assertions, testsuite TestSuite, filename string) { 86 for _, testcase := range testsuite.TestCases { 87 if testcase.Error != "" { 88 // This is a test case that verifies we error out properly. 89 runSyntaxTestCase(assert, testsuite.Given, testcase, filename) 90 } else { 91 runTestCase(assert, testsuite.Given, testcase, filename) 92 } 93 } 94} 95 96func runSyntaxTestCase(assert *assert.Assertions, given interface{}, testcase TestCase, filename string) { 97 // Anything with an .Error means that we expect that JMESPath should return 98 // an error when we try to evaluate the expression. 99 _, err := Search(testcase.Expression, given) 100 assert.NotNil(err, fmt.Sprintf("Expression: %s", testcase.Expression)) 101} 102 103func runTestCase(assert *assert.Assertions, given interface{}, testcase TestCase, filename string) { 104 lexer := NewLexer() 105 var err error 106 _, err = lexer.tokenize(testcase.Expression) 107 if err != nil { 108 errMsg := fmt.Sprintf("(%s) Could not lex expression: %s -- %s", filename, testcase.Expression, err.Error()) 109 assert.Fail(errMsg) 110 return 111 } 112 parser := NewParser() 113 _, err = parser.Parse(testcase.Expression) 114 if err != nil { 115 errMsg := fmt.Sprintf("(%s) Could not parse expression: %s -- %s", filename, testcase.Expression, err.Error()) 116 assert.Fail(errMsg) 117 return 118 } 119 actual, err := Search(testcase.Expression, given) 120 if assert.Nil(err, fmt.Sprintf("Expression: %s", testcase.Expression)) { 121 assert.Equal(testcase.Result, actual, fmt.Sprintf("Expression: %s", testcase.Expression)) 122 } 123} 124