test(tgbot): detect open-coded keypad transitions (#6214)

Co-authored-by: n0ctal <293235942+n0ctal@users.noreply.github.com>
This commit is contained in:
n0ctal
2026-08-15 18:27:02 +05:00
committed by GitHub
parent 2217213e9f
commit aecbad3ab1
2 changed files with 49 additions and 7 deletions
+2 -3
View File
@@ -1,8 +1,7 @@
package tgbot
// updateNumericInput applies one key from the shared inline number pad.
// Key -2 clears the value, -1 removes the last decimal digit, and 0..9 append
// a digit. Callers retain their own validation and keyboard labels.
// updateNumericInput applies one number-pad key: -2 clears, -1 backspaces, and 0..9 append.
// Callers retain their own validation and keyboard labels.
func updateNumericInput(value, key int) int {
switch key {
case -2:
@@ -1,7 +1,11 @@
package tgbot
import (
"go/ast"
"go/parser"
"go/token"
"os"
"path/filepath"
"strings"
"testing"
)
@@ -28,11 +32,50 @@ func TestUpdateNumericInput(t *testing.T) {
}
func TestNumericInputTransitionIsUsedByEveryKeypad(t *testing.T) {
source, err := os.ReadFile("tgbot_router.go")
entries, err := os.ReadDir(".")
if err != nil {
t.Fatalf("read tgbot_router.go: %v", err)
t.Fatalf("read tgbot package: %v", err)
}
if got := strings.Count(string(source), "updateNumericInput("); got != 6 {
t.Fatalf("numeric keypad transition call sites = %d, want 6", got)
fset := token.NewFileSet()
for _, entry := range entries {
name := entry.Name()
if entry.IsDir() || filepath.Ext(name) != ".go" || name == "numeric_input.go" || filepath.Ext(strings.TrimSuffix(name, "_test.go")) != ".go" {
continue
}
parsed, err := parser.ParseFile(fset, name, nil, 0)
if err != nil {
t.Fatalf("parse %s: %v", name, err)
}
ast.Inspect(parsed, func(node ast.Node) bool {
switchStmt, ok := node.(*ast.SwitchStmt)
if !ok {
return true
}
hasClear, hasBackspace, hasDefault := false, false, false
for _, stmt := range switchStmt.Body.List {
clause := stmt.(*ast.CaseClause)
if clause.List == nil {
hasDefault = true
}
for _, expr := range clause.List {
hasClear = hasClear || numericKeyLiteral(expr, "2")
hasBackspace = hasBackspace || numericKeyLiteral(expr, "1")
}
}
if hasClear && hasBackspace && hasDefault {
position := fset.Position(switchStmt.Pos())
t.Errorf("open-coded numeric keypad transition at %s; use updateNumericInput", position)
}
return true
})
}
}
func numericKeyLiteral(expr ast.Expr, magnitude string) bool {
unary, ok := expr.(*ast.UnaryExpr)
if !ok || unary.Op != token.SUB {
return false
}
literal, ok := unary.X.(*ast.BasicLit)
return ok && literal.Kind == token.INT && literal.Value == magnitude
}