github.com/yoheimuta/protolint@v0.49.8-0.20240515023657-4ecaebb7575d/internal/addon/rules/fieldsHaveCommentRule_test.go (about) 1 package rules_test 2 3 import ( 4 "reflect" 5 "testing" 6 7 "github.com/yoheimuta/go-protoparser/v4/parser/meta" 8 9 "github.com/yoheimuta/go-protoparser/v4/parser" 10 11 "github.com/yoheimuta/protolint/internal/addon/rules" 12 "github.com/yoheimuta/protolint/linter/report" 13 "github.com/yoheimuta/protolint/linter/rule" 14 ) 15 16 func TestFieldsHaveCommentRule_Apply(t *testing.T) { 17 tests := []struct { 18 name string 19 inputProto *parser.Proto 20 inputShouldFollowGolangStyle bool 21 wantFailures []report.Failure 22 }{ 23 { 24 name: "no failures for proto without field", 25 inputProto: &parser.Proto{ 26 ProtoBody: []parser.Visitee{}, 27 }, 28 }, 29 { 30 name: "no failures for proto including valid fields with comments", 31 inputProto: &parser.Proto{ 32 ProtoBody: []parser.Visitee{ 33 &parser.Message{ 34 MessageBody: []parser.Visitee{ 35 &parser.Field{ 36 FieldName: "FieldName", 37 Comments: []*parser.Comment{ 38 { 39 Raw: "// a field name.", 40 }, 41 }, 42 }, 43 &parser.MapField{ 44 MapName: "MapFieldName", 45 Comments: []*parser.Comment{ 46 { 47 Raw: "// a map field name.", 48 }, 49 }, 50 }, 51 &parser.Oneof{ 52 OneofFields: []*parser.OneofField{ 53 { 54 FieldName: "OneofFieldName", 55 Comments: []*parser.Comment{ 56 { 57 Raw: "// a oneof field name.", 58 }, 59 }, 60 }, 61 }, 62 }, 63 &parser.Field{ 64 FieldName: "FieldName", 65 InlineComment: &parser.Comment{ 66 Raw: "// a field name.", 67 }, 68 }, 69 &parser.MapField{ 70 MapName: "MapFieldName", 71 InlineComment: &parser.Comment{ 72 Raw: "// a map field name.", 73 }, 74 }, 75 &parser.Oneof{ 76 OneofFields: []*parser.OneofField{ 77 { 78 FieldName: "OneofFieldName", 79 InlineComment: &parser.Comment{ 80 Raw: "// a oneof field name.", 81 }, 82 }, 83 }, 84 }, 85 }, 86 }, 87 }, 88 }, 89 }, 90 { 91 name: "no failures for proto including valid fields with Golang style comments", 92 inputProto: &parser.Proto{ 93 ProtoBody: []parser.Visitee{ 94 &parser.Message{ 95 MessageBody: []parser.Visitee{ 96 &parser.Field{ 97 FieldName: "FieldName", 98 Comments: []*parser.Comment{ 99 { 100 Raw: "// FieldName is a field name.", 101 }, 102 }, 103 }, 104 &parser.MapField{ 105 MapName: "MapFieldName", 106 Comments: []*parser.Comment{ 107 { 108 Raw: "// MapFieldName is a map field name.", 109 }, 110 }, 111 }, 112 &parser.Oneof{ 113 OneofFields: []*parser.OneofField{ 114 { 115 FieldName: "OneofFieldName", 116 Comments: []*parser.Comment{ 117 { 118 Raw: "// OneofFieldName is a oneof field name.", 119 }, 120 }, 121 }, 122 }, 123 }, 124 }, 125 }, 126 }, 127 }, 128 inputShouldFollowGolangStyle: true, 129 }, 130 { 131 name: "failures for proto with invalid fields", 132 inputProto: &parser.Proto{ 133 ProtoBody: []parser.Visitee{ 134 &parser.Message{ 135 MessageBody: []parser.Visitee{ 136 &parser.Field{ 137 FieldName: "FieldName", 138 Meta: meta.Meta{ 139 Pos: meta.Position{ 140 Filename: "example.proto", 141 Offset: 150, 142 Line: 7, 143 Column: 15, 144 }, 145 }, 146 }, 147 &parser.MapField{ 148 MapName: "MapFieldName", 149 Meta: meta.Meta{ 150 Pos: meta.Position{ 151 Filename: "example.proto", 152 Offset: 200, 153 Line: 14, 154 Column: 30, 155 }, 156 }, 157 }, 158 &parser.Oneof{ 159 OneofFields: []*parser.OneofField{ 160 { 161 FieldName: "OneofFieldName", 162 Meta: meta.Meta{ 163 Pos: meta.Position{ 164 Filename: "example.proto", 165 Offset: 300, 166 Line: 21, 167 Column: 45, 168 }, 169 }, 170 }, 171 }, 172 }, 173 }, 174 }, 175 }, 176 }, 177 wantFailures: []report.Failure{ 178 report.Failuref( 179 meta.Position{ 180 Filename: "example.proto", 181 Offset: 150, 182 Line: 7, 183 Column: 15, 184 }, 185 "FIELDS_HAVE_COMMENT", 186 `Field "FieldName" should have a comment`, 187 ), 188 report.Failuref( 189 meta.Position{ 190 Filename: "example.proto", 191 Offset: 200, 192 Line: 14, 193 Column: 30, 194 }, 195 "FIELDS_HAVE_COMMENT", 196 `Field "MapFieldName" should have a comment`, 197 ), 198 report.Failuref( 199 meta.Position{ 200 Filename: "example.proto", 201 Offset: 300, 202 Line: 21, 203 Column: 45, 204 }, 205 "FIELDS_HAVE_COMMENT", 206 `Field "OneofFieldName" should have a comment`, 207 ), 208 }, 209 }, 210 { 211 name: "failures for proto with invalid fields without Golang style comments", 212 inputProto: &parser.Proto{ 213 ProtoBody: []parser.Visitee{ 214 &parser.Message{ 215 MessageBody: []parser.Visitee{ 216 &parser.Field{ 217 FieldName: "FieldName", 218 Comments: []*parser.Comment{ 219 { 220 Raw: "// a field name.", 221 }, 222 }, 223 Meta: meta.Meta{ 224 Pos: meta.Position{ 225 Filename: "example.proto", 226 Offset: 150, 227 Line: 7, 228 Column: 15, 229 }, 230 }, 231 }, 232 &parser.MapField{ 233 MapName: "MapFieldName", 234 Comments: []*parser.Comment{ 235 { 236 Raw: "// a map field name.", 237 }, 238 }, 239 Meta: meta.Meta{ 240 Pos: meta.Position{ 241 Filename: "example.proto", 242 Offset: 200, 243 Line: 14, 244 Column: 30, 245 }, 246 }, 247 }, 248 &parser.Oneof{ 249 OneofFields: []*parser.OneofField{ 250 { 251 FieldName: "OneofFieldName", 252 Comments: []*parser.Comment{ 253 { 254 Raw: "// a oneof field name.", 255 }, 256 }, 257 Meta: meta.Meta{ 258 Pos: meta.Position{ 259 Filename: "example.proto", 260 Offset: 300, 261 Line: 21, 262 Column: 45, 263 }, 264 }, 265 }, 266 }, 267 }, 268 }, 269 }, 270 }, 271 }, 272 inputShouldFollowGolangStyle: true, 273 wantFailures: []report.Failure{ 274 report.Failuref( 275 meta.Position{ 276 Filename: "example.proto", 277 Offset: 150, 278 Line: 7, 279 Column: 15, 280 }, 281 "FIELDS_HAVE_COMMENT", 282 `Field "FieldName" should have a comment of the form "// FieldName ..."`, 283 ), 284 report.Failuref( 285 meta.Position{ 286 Filename: "example.proto", 287 Offset: 200, 288 Line: 14, 289 Column: 30, 290 }, 291 "FIELDS_HAVE_COMMENT", 292 `Field "MapFieldName" should have a comment of the form "// MapFieldName ..."`, 293 ), 294 report.Failuref( 295 meta.Position{ 296 Filename: "example.proto", 297 Offset: 300, 298 Line: 21, 299 Column: 45, 300 }, 301 "FIELDS_HAVE_COMMENT", 302 `Field "OneofFieldName" should have a comment of the form "// OneofFieldName ..."`, 303 ), 304 }, 305 }, 306 { 307 name: "failures for proto with fields without Golang style comments due to the inline comment", 308 inputProto: &parser.Proto{ 309 ProtoBody: []parser.Visitee{ 310 &parser.Message{ 311 MessageBody: []parser.Visitee{ 312 &parser.Field{ 313 FieldName: "FieldName2", 314 InlineComment: &parser.Comment{ 315 Raw: "// FieldName2 is a field name.", 316 }, 317 }, 318 &parser.MapField{ 319 MapName: "MapFieldName2", 320 InlineComment: &parser.Comment{ 321 Raw: "// MapFieldName2 is a map field name.", 322 }, 323 }, 324 &parser.Oneof{ 325 OneofFields: []*parser.OneofField{ 326 { 327 FieldName: "OneofFieldName2", 328 InlineComment: &parser.Comment{ 329 Raw: "// OneofFieldName2 is a oneof field name.", 330 }, 331 }, 332 }, 333 }, 334 }, 335 }, 336 }, 337 }, 338 inputShouldFollowGolangStyle: true, 339 wantFailures: []report.Failure{ 340 report.Failuref( 341 meta.Position{}, 342 "FIELDS_HAVE_COMMENT", 343 `Field "FieldName2" should have a comment of the form "// FieldName2 ..."`, 344 ), 345 report.Failuref( 346 meta.Position{}, 347 "FIELDS_HAVE_COMMENT", 348 `Field "MapFieldName2" should have a comment of the form "// MapFieldName2 ..."`, 349 ), 350 report.Failuref( 351 meta.Position{}, 352 "FIELDS_HAVE_COMMENT", 353 `Field "OneofFieldName2" should have a comment of the form "// OneofFieldName2 ..."`, 354 ), 355 }, 356 }, 357 } 358 359 for _, test := range tests { 360 test := test 361 t.Run(test.name, func(t *testing.T) { 362 rule := rules.NewFieldsHaveCommentRule(rule.SeverityError, test.inputShouldFollowGolangStyle) 363 364 got, err := rule.Apply(test.inputProto) 365 if err != nil { 366 t.Errorf("got err %v, but want nil", err) 367 return 368 } 369 if !reflect.DeepEqual(got, test.wantFailures) { 370 t.Errorf("got %v, but want %v", got, test.wantFailures) 371 } 372 }) 373 } 374 }