github.com/yoheimuta/protolint@v0.49.8-0.20240515023657-4ecaebb7575d/internal/addon/rules/proto3FieldsAvoidRequiredRule_test.go (about) 1 package rules_test 2 3 import ( 4 "reflect" 5 "testing" 6 7 "github.com/yoheimuta/go-protoparser/v4/parser" 8 "github.com/yoheimuta/go-protoparser/v4/parser/meta" 9 "github.com/yoheimuta/protolint/internal/addon/rules" 10 "github.com/yoheimuta/protolint/linter/report" 11 "github.com/yoheimuta/protolint/linter/rule" 12 ) 13 14 func TestProto3FieldsAvoidRequiredRule_Apply(t *testing.T) { 15 tests := []struct { 16 name string 17 inputProto *parser.Proto 18 wantFailures []report.Failure 19 }{ 20 { 21 name: "no failures for proto without fields", 22 inputProto: &parser.Proto{ 23 ProtoBody: []parser.Visitee{ 24 &parser.Enum{}, 25 }, 26 }, 27 }, 28 { 29 name: "no failures for proto with not required field names", 30 inputProto: &parser.Proto{ 31 Syntax: &parser.Syntax{ 32 ProtobufVersion: "proto3", 33 }, 34 ProtoBody: []parser.Visitee{ 35 &parser.Service{}, 36 &parser.Message{ 37 MessageBody: []parser.Visitee{ 38 &parser.Field{ 39 FieldName: "song_name", 40 }, 41 &parser.Field{ 42 IsRepeated: true, 43 FieldName: "singer", 44 }, 45 &parser.Field{ 46 IsOptional: true, 47 FieldName: "singer", 48 }, 49 &parser.MapField{ 50 MapName: "song_name2", 51 }, 52 &parser.Oneof{ 53 OneofFields: []*parser.OneofField{ 54 { 55 FieldName: "song_name3", 56 }, 57 }, 58 }, 59 }, 60 }, 61 }, 62 }, 63 }, 64 { 65 name: "no failures for proto with required field names for proto2", 66 inputProto: &parser.Proto{ 67 Syntax: &parser.Syntax{ 68 ProtobufVersion: "proto2", 69 }, 70 ProtoBody: []parser.Visitee{ 71 &parser.Service{}, 72 &parser.Message{ 73 MessageBody: []parser.Visitee{ 74 &parser.Field{ 75 IsRequired: true, 76 FieldName: "song_name", 77 }, 78 &parser.Field{ 79 IsRequired: true, 80 FieldName: "singer", 81 }, 82 }, 83 }, 84 }, 85 }, 86 }, 87 { 88 name: "failures for proto with required field names for proto3", 89 inputProto: &parser.Proto{ 90 Syntax: &parser.Syntax{ 91 ProtobufVersion: "proto3", 92 }, 93 ProtoBody: []parser.Visitee{ 94 &parser.Message{ 95 MessageBody: []parser.Visitee{ 96 &parser.Field{ 97 IsRequired: true, 98 FieldName: "song_Name", 99 Meta: meta.Meta{ 100 Pos: meta.Position{ 101 Filename: "example.proto", 102 Offset: 100, 103 Line: 5, 104 Column: 10, 105 }, 106 }, 107 }, 108 &parser.Field{ 109 IsRequired: true, 110 FieldName: "song.name", 111 Meta: meta.Meta{ 112 Pos: meta.Position{ 113 Filename: "example.proto", 114 Offset: 200, 115 Line: 10, 116 Column: 20, 117 }, 118 }, 119 }, 120 }, 121 }, 122 }, 123 }, 124 wantFailures: []report.Failure{ 125 report.Failuref( 126 meta.Position{ 127 Filename: "example.proto", 128 Offset: 100, 129 Line: 5, 130 Column: 10, 131 }, 132 "PROTO3_FIELDS_AVOID_REQUIRED", 133 `Field "song_Name" should avoid required for proto3`, 134 ), 135 report.Failuref( 136 meta.Position{ 137 Filename: "example.proto", 138 Offset: 200, 139 Line: 10, 140 Column: 20, 141 }, 142 "PROTO3_FIELDS_AVOID_REQUIRED", 143 `Field "song.name" should avoid required for proto3`, 144 ), 145 }, 146 }, 147 } 148 149 for _, test := range tests { 150 test := test 151 t.Run(test.name, func(t *testing.T) { 152 rule := rules.NewProto3FieldsAvoidRequiredRule(rule.SeverityError, false) 153 154 got, err := rule.Apply(test.inputProto) 155 if err != nil { 156 t.Errorf("got err %v, but want nil", err) 157 return 158 } 159 if !reflect.DeepEqual(got, test.wantFailures) { 160 t.Errorf("got %v, but want %v", got, test.wantFailures) 161 } 162 }) 163 } 164 } 165 166 func TestProto3FieldsAvoidRequiredRule_Apply_fix(t *testing.T) { 167 tests := []struct { 168 name string 169 inputFilename string 170 wantFilename string 171 }{ 172 { 173 name: "no fix for a correct proto", 174 inputFilename: "avoid_required.proto", 175 wantFilename: "avoid_required.proto", 176 }, 177 { 178 name: "fix for an incorrect proto", 179 inputFilename: "invalid.proto", 180 wantFilename: "avoid_required.proto", 181 }, 182 } 183 184 for _, test := range tests { 185 test := test 186 t.Run(test.name, func(t *testing.T) { 187 r := rules.NewProto3FieldsAvoidRequiredRule(rule.SeverityError, true) 188 testApplyFix(t, r, test.inputFilename, test.wantFilename) 189 }) 190 } 191 }