gitlab.com/Raven-IO/raven-delve@v1.22.4/pkg/proc/evalop/evalop_test.go (about) 1 package evalop 2 3 import ( 4 "go/ast" 5 "go/parser" 6 "go/token" 7 "testing" 8 ) 9 10 func assertNoError(err error, t testing.TB, s string) { 11 t.Helper() 12 if err != nil { 13 t.Fatalf("failed assertion %s: %s\n", s, err) 14 } 15 } 16 17 func TestEvalSwitchExhaustiveness(t *testing.T) { 18 // Checks that the switch statement in (*EvalScope).executeOp of 19 // pkg/proc/eval.go exhaustively covers all implementations of the 20 // evalop.Op interface. 21 22 ops := make(map[string]bool) 23 24 var fset, fset2 token.FileSet 25 f, err := parser.ParseFile(&fset, "ops.go", nil, 0) 26 assertNoError(err, t, "ParseFile") 27 for _, decl := range f.Decls { 28 decl, _ := decl.(*ast.FuncDecl) 29 if decl == nil { 30 continue 31 } 32 if decl.Name.Name != "depthCheck" { 33 continue 34 } 35 ops[decl.Recv.List[0].Type.(*ast.StarExpr).X.(*ast.Ident).Name] = false 36 } 37 38 f, err = parser.ParseFile(&fset2, "../eval.go", nil, 0) 39 assertNoError(err, t, "ParseFile") 40 for _, decl := range f.Decls { 41 decl, _ := decl.(*ast.FuncDecl) 42 if decl == nil { 43 continue 44 } 45 if decl.Name.Name != "executeOp" { 46 continue 47 } 48 ast.Inspect(decl, func(n ast.Node) bool { 49 sw, _ := n.(*ast.TypeSwitchStmt) 50 if sw == nil { 51 return true 52 } 53 54 for _, c := range sw.Body.List { 55 if len(c.(*ast.CaseClause).List) == 0 { 56 // default clause 57 continue 58 } 59 sel := c.(*ast.CaseClause).List[0].(*ast.StarExpr).X.(*ast.SelectorExpr) 60 if sel.X.(*ast.Ident).Name != "evalop" { 61 t.Fatalf("wrong case statement at: %v", fset2.Position(sel.Pos())) 62 } 63 64 ops[sel.Sel.Name] = true 65 } 66 return false 67 }) 68 } 69 70 for op := range ops { 71 if !ops[op] { 72 t.Errorf("evalop.Op %s not used in executeOp", op) 73 } 74 } 75 }