github.com/yoheimuta/protolint@v0.49.8-0.20240515023657-4ecaebb7575d/internal/addon/rules/enumFieldNamesPrefixRule_test.go (about) 1 package rules_test 2 3 import ( 4 "reflect" 5 "testing" 6 7 "github.com/yoheimuta/protolint/internal/addon/rules" 8 9 "github.com/yoheimuta/go-protoparser/v4/parser" 10 "github.com/yoheimuta/go-protoparser/v4/parser/meta" 11 "github.com/yoheimuta/protolint/linter/autodisable" 12 "github.com/yoheimuta/protolint/linter/report" 13 "github.com/yoheimuta/protolint/linter/rule" 14 ) 15 16 func TestEnumFieldNamesPrefixRule_Apply(t *testing.T) { 17 tests := []struct { 18 name string 19 inputProto *parser.Proto 20 wantFailures []report.Failure 21 }{ 22 { 23 name: "no failures for proto without enum fields", 24 inputProto: &parser.Proto{ 25 ProtoBody: []parser.Visitee{ 26 &parser.Enum{ 27 EnumName: "FooBar", 28 }, 29 }, 30 }, 31 }, 32 { 33 name: "no failures for proto with valid enum field names", 34 inputProto: &parser.Proto{ 35 ProtoBody: []parser.Visitee{ 36 &parser.Service{}, 37 &parser.Enum{ 38 EnumName: "FooBar", 39 EnumBody: []parser.Visitee{ 40 &parser.EnumField{ 41 Ident: "FOO_BAR_UNSPECIFIED", 42 Number: "0", 43 }, 44 &parser.EnumField{ 45 Ident: "FOO_BAR_FIRST_VALUE", 46 Number: "1", 47 }, 48 &parser.EnumField{ 49 Ident: "FOO_BAR_SECOND_VALUE", 50 Number: "2", 51 }, 52 }, 53 }, 54 }, 55 }, 56 }, 57 { 58 name: "no failures for proto with valid enum field names even when its enum name is snake case", 59 inputProto: &parser.Proto{ 60 ProtoBody: []parser.Visitee{ 61 &parser.Service{}, 62 &parser.Enum{ 63 EnumName: "foo_bar", 64 EnumBody: []parser.Visitee{ 65 &parser.EnumField{ 66 Ident: "FOO_BAR_UNSPECIFIED", 67 Number: "0", 68 }, 69 }, 70 }, 71 }, 72 }, 73 }, 74 { 75 name: "no failures for proto with valid enum field names even when its camel-case string starts with a 2-letter abbreviation", 76 inputProto: &parser.Proto{ 77 ProtoBody: []parser.Visitee{ 78 &parser.Service{}, 79 &parser.Enum{ 80 EnumName: "ITDepartmentRegion", 81 EnumBody: []parser.Visitee{ 82 &parser.EnumField{ 83 Ident: "IT_DEPARTMENT_REGION_UNSPECIFIED", 84 Number: "0", 85 }, 86 }, 87 }, 88 }, 89 }, 90 }, 91 { 92 name: "no failures for proto with valid enum field names even when its camel-case string includes OAuth", 93 inputProto: &parser.Proto{ 94 ProtoBody: []parser.Visitee{ 95 &parser.Service{}, 96 &parser.Enum{ 97 EnumName: "ListAccountPipedriveOAuthsEnabledFilter", 98 EnumBody: []parser.Visitee{ 99 &parser.EnumField{ 100 Ident: "LIST_ACCOUNT_PIPEDRIVE_OAUTHS_ENABLED_FILTER_UNSPECIFIED", 101 Number: "0", 102 }, 103 }, 104 }, 105 }, 106 }, 107 }, 108 { 109 name: "failures for proto with invalid enum field names", 110 inputProto: &parser.Proto{ 111 ProtoBody: []parser.Visitee{ 112 &parser.Enum{ 113 EnumName: "FooBar", 114 EnumBody: []parser.Visitee{ 115 &parser.EnumField{ 116 Ident: "BAR_UNSPECIFIED", 117 Number: "0", 118 Meta: meta.Meta{ 119 Pos: meta.Position{ 120 Filename: "example.proto", 121 Offset: 100, 122 Line: 5, 123 Column: 10, 124 }, 125 }, 126 }, 127 }, 128 }, 129 }, 130 }, 131 wantFailures: []report.Failure{ 132 report.Failuref( 133 meta.Position{ 134 Filename: "example.proto", 135 Offset: 100, 136 Line: 5, 137 Column: 10, 138 }, 139 "ENUM_FIELD_NAMES_PREFIX", 140 `EnumField name "BAR_UNSPECIFIED" should have the prefix "FOO_BAR"`, 141 ), 142 }, 143 }, 144 } 145 146 for _, test := range tests { 147 test := test 148 t.Run(test.name, func(t *testing.T) { 149 rule := rules.NewEnumFieldNamesPrefixRule(rule.SeverityError, false, autodisable.Noop) 150 151 got, err := rule.Apply(test.inputProto) 152 if err != nil { 153 t.Errorf("got err %v, but want nil", err) 154 return 155 } 156 if !reflect.DeepEqual(got, test.wantFailures) { 157 t.Errorf("got %v, but want %v", got, test.wantFailures) 158 } 159 }) 160 } 161 } 162 163 func TestEnumFieldNamesPrefixRule_Apply_fix(t *testing.T) { 164 tests := []struct { 165 name string 166 inputFilename string 167 wantFilename string 168 }{ 169 { 170 name: "no fix for a correct proto", 171 inputFilename: "prefix.proto", 172 wantFilename: "prefix.proto", 173 }, 174 { 175 name: "fix for an incorrect proto", 176 inputFilename: "invalid.proto", 177 wantFilename: "prefix.proto", 178 }, 179 } 180 181 for _, test := range tests { 182 test := test 183 t.Run(test.name, func(t *testing.T) { 184 r := rules.NewEnumFieldNamesPrefixRule(rule.SeverityError, true, autodisable.Noop) 185 testApplyFix(t, r, test.inputFilename, test.wantFilename) 186 }) 187 } 188 } 189 190 func TestEnumFieldNamesPrefixRule_Apply_disable(t *testing.T) { 191 tests := []struct { 192 name string 193 inputFilename string 194 inputPlacementType autodisable.PlacementType 195 wantFilename string 196 }{ 197 { 198 name: "do nothing in case of no violations", 199 inputFilename: "prefix.proto", 200 wantFilename: "prefix.proto", 201 }, 202 { 203 name: "insert disable:next comments", 204 inputFilename: "invalid.proto", 205 inputPlacementType: autodisable.Next, 206 wantFilename: "disable_next.proto", 207 }, 208 { 209 name: "insert disable:this comments", 210 inputFilename: "invalid.proto", 211 inputPlacementType: autodisable.ThisThenNext, 212 wantFilename: "disable_this.proto", 213 }, 214 } 215 216 for _, test := range tests { 217 test := test 218 t.Run(test.name, func(t *testing.T) { 219 r := rules.NewEnumFieldNamesPrefixRule(rule.SeverityError, true, test.inputPlacementType) 220 testApplyFix(t, r, test.inputFilename, test.wantFilename) 221 }) 222 } 223 }