1
0
mirror of https://github.com/mgechev/revive.git synced 2025-11-23 22:04:49 +02:00
Files
revive/rule/var_naming_test.go
Marcin Federowicz 7ba6ad4fcd var-naming: remove regex from code (#1322)
Co-authored-by: ccoVeille <3875889+ccoVeille@users.noreply.github.com>
Co-authored-by: Oleksandr Redko <oleksandr.red+github@gmail.com>
2025-04-25 01:32:03 -07:00

354 lines
9.1 KiB
Go

package rule
import (
"errors"
"reflect"
"testing"
"github.com/mgechev/revive/lint"
)
func TestVarNamingRule_Configure(t *testing.T) {
tests := []struct {
name string
arguments lint.Arguments
wantErr error
wantAllowList []string
wantBlockList []string
wantAllowUpperCaseConst bool
wantSkipPackageNameChecks bool
wantBadPackageNames map[string]struct{}
}{
{
name: "no arguments",
arguments: lint.Arguments{},
wantErr: nil,
wantAllowList: nil,
wantBlockList: nil,
wantAllowUpperCaseConst: false,
wantSkipPackageNameChecks: false,
},
{
name: "valid arguments",
arguments: lint.Arguments{
[]any{"ID"},
[]any{"VM"},
[]any{map[string]any{
"upperCaseConst": true,
"skipPackageNameChecks": true,
"extraBadPackageNames": []string{"helpers", "models"},
}},
},
wantErr: nil,
wantAllowList: []string{"ID"},
wantBlockList: []string{"VM"},
wantAllowUpperCaseConst: true,
wantSkipPackageNameChecks: true,
wantBadPackageNames: map[string]struct{}{"helpers": {}, "models": {}},
},
{
name: "valid lowercased arguments",
arguments: lint.Arguments{
[]any{"ID"},
[]any{"VM"},
[]any{map[string]any{
"uppercaseconst": true,
"skippackagenamechecks": true,
"extrabadpackagenames": []string{"helpers", "models"},
}},
},
wantErr: nil,
wantAllowList: []string{"ID"},
wantBlockList: []string{"VM"},
wantAllowUpperCaseConst: true,
wantSkipPackageNameChecks: true,
wantBadPackageNames: map[string]struct{}{"helpers": {}, "models": {}},
},
{
name: "valid kebab-cased arguments",
arguments: lint.Arguments{
[]any{"ID"},
[]any{"VM"},
[]any{map[string]any{
"upper-case-const": true,
"skip-package-name-checks": true,
"extra-bad-package-names": []string{"helpers", "models"},
}},
},
wantErr: nil,
wantAllowList: []string{"ID"},
wantBlockList: []string{"VM"},
wantAllowUpperCaseConst: true,
wantSkipPackageNameChecks: true,
wantBadPackageNames: map[string]struct{}{"helpers": {}, "models": {}},
},
{
name: "invalid allowlist type",
arguments: lint.Arguments{123},
wantErr: errors.New("invalid argument to the var-naming rule. Expecting a allowlist of type slice with initialisms, got int"),
},
{
name: "invalid allowlist value type",
arguments: lint.Arguments{[]any{123}},
wantErr: errors.New("invalid 123 values of the var-naming rule. Expecting slice of strings but got element of type []interface {}"),
},
{
name: "invalid blocklist type",
arguments: lint.Arguments{[]any{"ID"}, 123},
wantErr: errors.New("invalid argument to the var-naming rule. Expecting a blocklist of type slice with initialisms, got int"),
},
{
name: "invalid third argument type",
arguments: lint.Arguments{[]any{"ID"}, []any{"VM"}, 123},
wantErr: errors.New("invalid third argument to the var-naming rule. Expecting a options of type slice, got int"),
},
{
name: "invalid third argument slice size",
arguments: lint.Arguments{[]any{"ID"}, []any{"VM"}, []any{}},
wantErr: errors.New("invalid third argument to the var-naming rule. Expecting a options of type slice, of len==1, but 0"),
},
{
name: "invalid third argument first element type",
arguments: lint.Arguments{[]any{"ID"}, []any{"VM"}, []any{123}},
wantErr: errors.New("invalid third argument to the var-naming rule. Expecting a options of type slice, of len==1, with map, but int"),
},
{
name: "invalid third argument extraBadPackageNames",
arguments: lint.Arguments{[]any{""}, []any{""}, []any{map[string]any{"extraBadPackageNames": []int{1}}}},
wantErr: errors.New("invalid third argument to the var-naming rule. Expecting extraBadPackageNames of type slice of strings, but []int"),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
var rule VarNamingRule
err := rule.Configure(tt.arguments)
if tt.wantErr != nil {
if err == nil {
t.Errorf("unexpected error: got = nil, want = %v", tt.wantErr)
return
}
if err.Error() != tt.wantErr.Error() {
t.Errorf("unexpected error: got = %v, want = %v", err, tt.wantErr)
}
return
}
if err != nil {
t.Errorf("unexpected error: got = %v, want = nil", err)
}
if rule.allowUpperCaseConst != tt.wantAllowUpperCaseConst {
t.Errorf("unexpected allowUpperCaseConst: got = %v, want %v", rule.allowUpperCaseConst, tt.wantAllowUpperCaseConst)
}
if rule.skipPackageNameChecks != tt.wantSkipPackageNameChecks {
t.Errorf("unexpected skipPackageNameChecks: got = %v, want %v", rule.skipPackageNameChecks, tt.wantSkipPackageNameChecks)
}
if !reflect.DeepEqual(rule.extraBadPackageNames, tt.wantBadPackageNames) {
t.Errorf("unexpected extraBadPackageNames: got = %v, want %v", rule.extraBadPackageNames, tt.wantBadPackageNames)
}
})
}
}
func TestHasUpperCaseLetter(t *testing.T) {
tests := []struct {
varName string
expected bool
}{
{"Exit", true},
{"fmt", false},
{"_SOME_PRIVATE_CONST_2", true},
{"", false},
// Unicode uppercase (non-ASCII)
{"Ä", false}, // Latin capital letter A with diaeresis
{"Ω", false}, // Greek capital letter Omega
{"Д", false}, // Cyrillic capital letter De
// Unicode lowercase/symbols
{"ß", false}, // German sharp s
{"π", false}, // Greek small letter pi
{"💡", false}, // Emoji
{"你", false}, // Chinese character
}
for _, tt := range tests {
t.Run(tt.varName, func(t *testing.T) {
if got := hasUpperCaseLetter(tt.varName); got != tt.expected {
t.Errorf("hasCaps(%s) = %v; want %v", tt.varName, got, tt.expected)
}
})
}
}
func TestIsUpperCaseConst(t *testing.T) {
tests := []struct {
varName string
expected bool
}{
{"SOME_CONST_2", true},
{"__FOO", false},
{"__", false},
{"X509B", true},
{"FOO", true},
{"1FOO", false},
{"_FOO123_BAR456", true},
{"A1_B2_C3", true},
{"A1_b2", false},
{"FOO_", false},
{"foo", false},
{"_", false},
{"", false},
{"FOOBAR", true},
{"FO", true},
{"F_O", true},
{"FOO123", true},
}
for _, tt := range tests {
t.Run(tt.varName, func(t *testing.T) {
if got := isUpperCaseConst(tt.varName); got != tt.expected {
t.Errorf("isUpperCaseConst(%s) = %v; want %v", tt.varName, got, tt.expected)
}
})
}
}
func TestIsUpperUnderscore(t *testing.T) {
tests := []struct {
varName string
expected bool
}{
{"_", false},
{"", false},
{"empty string", false},
{"_404_404", true},
{"FOO_BAR", true},
{"FOOBAR", false},
{"FO", false},
{"F_O", false},
{"_FOOBAR", true},
{"FOOBAR_", true},
{"FOO123", false},
{"FOO_123", true},
}
for _, tt := range tests {
t.Run(tt.varName, func(t *testing.T) {
if got := isUpperUnderscore(tt.varName); got != tt.expected {
t.Errorf("isUpperUnderScore(%s) = %v; want %v", tt.varName, got, tt.expected)
}
})
}
}
func TestIsDigit(t *testing.T) {
tests := []struct {
input rune
expected bool
}{
{'0', true},
{'1', true},
{'2', true},
{'3', true},
{'4', true},
{'5', true},
{'6', true},
{'7', true},
{'8', true},
{'9', true},
{'a', false},
{'Z', false},
{' ', false},
{'!', false},
{'🙂', false}, // Emoji to test unicode
{'٠', false}, // Arabic-Indic 0
{'١', false}, // Arabic-Indic 1
{'२', false}, // Devanagari 2
{'৩', false}, // Bengali 3
{'४', false}, // Devanagari 4
{'௫', false}, // Tamil 5
{'๖', false}, // Thai 6
{'৭', false}, // Bengali 7
{'८', false}, // Devanagari 8
{'९', false}, // Devanagari 9
}
for _, tt := range tests {
result := isDigit(tt.input)
if result != tt.expected {
t.Errorf("isDigit(%q) = %v; want %v", tt.input, result, tt.expected)
}
}
}
func TestIsUpper(t *testing.T) {
t.Run("non letter", func(t *testing.T) {
tests := []rune{
'0',
'5',
' ',
'_',
'!',
'🙂', // Emoji to test unicode
}
for _, r := range tests {
result := isUpper(r)
if result {
t.Errorf("isUpper(%q) = %v; want false", r, result)
}
}
})
t.Run("non ASCII letter", func(t *testing.T) {
tests := []rune{
'Ą',
'Ć',
'你',
'日',
'本',
'語',
'韓',
'中',
'文',
'あ',
'ア',
'한',
}
for _, r := range tests {
result := isUpper(r)
if result {
t.Errorf("isUpper(%q) = %v; want false", r, result)
}
}
})
t.Run("lowercase ASCII letter", func(t *testing.T) {
tests := []rune{
'a',
'b',
}
for _, r := range tests {
result := isUpper(r)
if result {
t.Errorf("isUpper(%q) = %v; want false", r, result)
}
}
})
t.Run("uppercase ASCII letter", func(t *testing.T) {
tests := []rune{
'A',
'B',
'C',
'Z',
}
for _, r := range tests {
result := isUpper(r)
if !result {
t.Errorf("isUpper(%q) = %v; want true", r, result)
}
}
})
}