1
0

numeric_input_test.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. package tgbot
  2. import (
  3. "go/ast"
  4. "go/parser"
  5. "go/token"
  6. "os"
  7. "path/filepath"
  8. "strings"
  9. "testing"
  10. )
  11. func TestUpdateNumericInput(t *testing.T) {
  12. tests := []struct {
  13. name string
  14. value, key int
  15. want int
  16. }{
  17. {name: "append digit", value: 12, key: 3, want: 123},
  18. {name: "append zero", value: 12, key: 0, want: 120},
  19. {name: "backspace", value: 123, key: -1, want: 12},
  20. {name: "backspace zero", value: 0, key: -1, want: 0},
  21. {name: "clear", value: 123, key: -2, want: 0},
  22. }
  23. for _, tt := range tests {
  24. t.Run(tt.name, func(t *testing.T) {
  25. if got := updateNumericInput(tt.value, tt.key); got != tt.want {
  26. t.Fatalf("updateNumericInput(%d, %d) = %d, want %d", tt.value, tt.key, got, tt.want)
  27. }
  28. })
  29. }
  30. }
  31. func TestNumericInputTransitionIsUsedByEveryKeypad(t *testing.T) {
  32. entries, err := os.ReadDir(".")
  33. if err != nil {
  34. t.Fatalf("read tgbot package: %v", err)
  35. }
  36. fset := token.NewFileSet()
  37. for _, entry := range entries {
  38. name := entry.Name()
  39. if entry.IsDir() || filepath.Ext(name) != ".go" || name == "numeric_input.go" || filepath.Ext(strings.TrimSuffix(name, "_test.go")) != ".go" {
  40. continue
  41. }
  42. parsed, err := parser.ParseFile(fset, name, nil, 0)
  43. if err != nil {
  44. t.Fatalf("parse %s: %v", name, err)
  45. }
  46. ast.Inspect(parsed, func(node ast.Node) bool {
  47. switchStmt, ok := node.(*ast.SwitchStmt)
  48. if !ok {
  49. return true
  50. }
  51. hasClear, hasBackspace, hasDefault := false, false, false
  52. for _, stmt := range switchStmt.Body.List {
  53. clause := stmt.(*ast.CaseClause)
  54. if clause.List == nil {
  55. hasDefault = true
  56. }
  57. for _, expr := range clause.List {
  58. hasClear = hasClear || numericKeyLiteral(expr, "2")
  59. hasBackspace = hasBackspace || numericKeyLiteral(expr, "1")
  60. }
  61. }
  62. if hasClear && hasBackspace && hasDefault {
  63. position := fset.Position(switchStmt.Pos())
  64. t.Errorf("open-coded numeric keypad transition at %s; use updateNumericInput", position)
  65. }
  66. return true
  67. })
  68. }
  69. }
  70. func numericKeyLiteral(expr ast.Expr, magnitude string) bool {
  71. unary, ok := expr.(*ast.UnaryExpr)
  72. if !ok || unary.Op != token.SUB {
  73. return false
  74. }
  75. literal, ok := unary.X.(*ast.BasicLit)
  76. return ok && literal.Kind == token.INT && literal.Value == magnitude
  77. }