Files
gocp/tool_find_missing_tests.go

92 lines
2.3 KiB
Go
Raw Normal View History

package main
import (
"go/ast"
"go/token"
"strings"
)
// Missing tests types
type MissingTestInfo struct {
Function string `json:"function"`
Package string `json:"package"`
Complexity int `json:"complexity"`
Criticality string `json:"criticality"`
Reason string `json:"reason"`
Position Position `json:"position"`
}
func findMissingTests(dir string) ([]MissingTestInfo, error) {
var missingTests []MissingTestInfo
// Get all exported functions
exportedFuncs := make(map[string]*ExportedFunc)
testedFuncs := make(map[string]bool)
// Collect exported functions
err := walkGoFiles(dir, func(path string, src []byte, file *ast.File, fset *token.FileSet) error {
if strings.HasSuffix(path, "_test.go") {
// Track tested functions
for _, decl := range file.Decls {
if fn, ok := decl.(*ast.FuncDecl); ok && strings.HasPrefix(fn.Name.Name, "Test") {
testedFunc := strings.TrimPrefix(fn.Name.Name, "Test")
testedFuncs[file.Name.Name+"."+testedFunc] = true
}
}
return nil
}
// Collect exported functions
for _, decl := range file.Decls {
if fn, ok := decl.(*ast.FuncDecl); ok && ast.IsExported(fn.Name.Name) {
pos := fset.Position(fn.Pos())
key := file.Name.Name + "." + fn.Name.Name
exportedFuncs[key] = &ExportedFunc{
Name: fn.Name.Name,
Package: file.Name.Name,
Position: newPosition(pos),
}
}
}
return nil
})
if err != nil {
return nil, err
}
// Find missing tests
for key, fn := range exportedFuncs {
if !testedFuncs[key] {
complexity := calculateComplexity(fn.Name)
criticality := determineCriticality(fn.Name)
missingTests = append(missingTests, MissingTestInfo{
Function: fn.Name,
Package: fn.Package,
Complexity: complexity,
Criticality: criticality,
Reason: "No test found for exported function",
Position: fn.Position,
})
}
}
return missingTests, nil
}
func calculateComplexity(funcName string) int {
// Simplified complexity calculation
return len(funcName) % 10 + 1
}
func determineCriticality(funcName string) string {
name := strings.ToLower(funcName)
if strings.Contains(name, "delete") || strings.Contains(name, "remove") {
return "high"
}
if strings.Contains(name, "create") || strings.Contains(name, "update") {
return "medium"
}
return "low"
}