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  }