github.com/nya3jp/tast@v0.0.0-20230601000426-85c8e4d83a9b/src/go.chromium.org/tast/core/cmd/tast-lint/internal/check/disallow_testingstate.go (about) 1 // Copyright 2019 The ChromiumOS Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 package check 6 7 import ( 8 "go/ast" 9 "go/token" 10 "strings" 11 ) 12 13 // VerifyTestingStateParam checks if functions in support packages use *testing.State as a parameter. 14 func VerifyTestingStateParam(fs *token.FileSet, f *ast.File) []*Issue { 15 var issues []*Issue 16 17 // Ignore known valid use cases. 18 var allowList = []string{ 19 // Runs code before and after each local test 20 "src/go.chromium.org/tast-tests/cros/local/bundlemain/main.go", 21 // Below files are cases still under considering. 22 "src/go.chromium.org/tast-tests/cros/local/graphics/trace/trace.go", 23 } 24 filepath := fs.Position(f.Package).Filename 25 for _, p := range allowList { 26 if strings.HasSuffix(filepath, p) { 27 return issues 28 } 29 } 30 31 ast.Inspect(f, func(node ast.Node) bool { 32 t := funcType(node) 33 if t == nil { 34 return true 35 } 36 for _, param := range t.Params.List { 37 if toQualifiedName(removeStars(param.Type)) == "testing.State" { 38 issues = append(issues, &Issue{ 39 Pos: fs.Position(param.Type.Pos()), 40 Msg: "'testing.State' should not be used in support packages, except for precondition implementation", 41 Link: "https://chromium.googlesource.com/chromiumos/platform/tast/+/HEAD/docs/writing_tests.md#test-subpackages", 42 }) 43 } 44 } 45 return true 46 }) 47 return issues 48 } 49 50 func funcType(node ast.Node) *ast.FuncType { 51 if fn, ok := node.(*ast.FuncDecl); ok { 52 return fn.Type 53 } 54 if fn, ok := node.(*ast.FuncLit); ok { 55 return fn.Type 56 } 57 return nil 58 } 59 60 // VerifyTestingStateStruct checks if testing.State is stored inside struct types. 61 func VerifyTestingStateStruct(fs *token.FileSet, f *ast.File) []*Issue { 62 var issues []*Issue 63 64 // TODO(crbug.com/1012586): Make below file not use testing.State in struct types. 65 var allowList = []string{ 66 "src/go.chromium.org/tast-tests/cros/local/bundles/cros/platform/memoryuser/mempressure_task.go", 67 } 68 filepath := fs.Position(f.Package).Filename 69 for _, p := range allowList { 70 if strings.HasSuffix(filepath, p) { 71 return issues 72 } 73 } 74 75 ast.Inspect(f, func(node ast.Node) bool { 76 st, ok := node.(*ast.StructType) 77 if !ok { 78 return true 79 } 80 for _, f := range st.Fields.List { 81 if toQualifiedName(removeStars(f.Type)) == "testing.State" { 82 issues = append(issues, &Issue{ 83 Pos: fs.Position(f.Type.Pos()), 84 Msg: "'testing.State' should not be stored inside a struct type", 85 Link: "https://chromium.googlesource.com/chromiumos/platform/tast/+/HEAD/docs/writing_tests.md#test-subpackages", 86 }) 87 } 88 } 89 return true 90 }) 91 return issues 92 } 93 94 // removeStars returns the exression without stars. 95 func removeStars(node ast.Expr) ast.Expr { 96 star, ok := node.(*ast.StarExpr) 97 for ok { 98 node = star.X 99 star, ok = node.(*ast.StarExpr) 100 } 101 return node 102 }