github.com/yoheimuta/protolint@v0.49.8-0.20240515023657-4ecaebb7575d/internal/addon/rules/messagesHaveCommentRule_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 TestMessagesHaveCommentRule_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 message", 25 inputProto: &parser.Proto{ 26 ProtoBody: []parser.Visitee{ 27 &parser.Service{}, 28 }, 29 }, 30 }, 31 { 32 name: "no failures for proto including valid messages with comments", 33 inputProto: &parser.Proto{ 34 ProtoBody: []parser.Visitee{ 35 &parser.Service{}, 36 &parser.Message{ 37 MessageName: "MessageName", 38 Comments: []*parser.Comment{ 39 { 40 Raw: "// a message name.", 41 }, 42 }, 43 }, 44 &parser.Message{ 45 MessageName: "MessageName2", 46 Comments: []*parser.Comment{ 47 { 48 Raw: "// MessageName2 is a message name.", 49 }, 50 }, 51 }, 52 &parser.Message{ 53 MessageName: "MessageName3", 54 InlineComment: &parser.Comment{ 55 Raw: "// a message name.", 56 }, 57 }, 58 &parser.Message{ 59 MessageName: "MessageName4", 60 InlineCommentBehindLeftCurly: &parser.Comment{ 61 Raw: "// a message name.", 62 }, 63 }, 64 }, 65 }, 66 }, 67 { 68 name: "no failures for proto including valid messages with Golang style comments", 69 inputProto: &parser.Proto{ 70 ProtoBody: []parser.Visitee{ 71 &parser.Service{}, 72 &parser.Message{ 73 MessageName: "MessageName", 74 Comments: []*parser.Comment{ 75 { 76 Raw: "// MessageName is a message name.", 77 }, 78 }, 79 }, 80 &parser.Message{ 81 MessageName: "MessageName2", 82 Comments: []*parser.Comment{ 83 { 84 Raw: "// MessageName2 is a message name.", 85 }, 86 }, 87 }, 88 }, 89 }, 90 inputShouldFollowGolangStyle: true, 91 }, 92 { 93 name: "failures for proto with invalid messages", 94 inputProto: &parser.Proto{ 95 ProtoBody: []parser.Visitee{ 96 &parser.Service{}, 97 &parser.Message{ 98 MessageName: "MessageName", 99 MessageBody: []parser.Visitee{ 100 &parser.Message{ 101 MessageName: "MessageName2", 102 Meta: meta.Meta{ 103 Pos: meta.Position{ 104 Filename: "example.proto", 105 Offset: 200, 106 Line: 10, 107 Column: 20, 108 }, 109 }, 110 }, 111 }, 112 Meta: meta.Meta{ 113 Pos: meta.Position{ 114 Filename: "example.proto", 115 Offset: 150, 116 Line: 7, 117 Column: 15, 118 }, 119 }, 120 }, 121 }, 122 }, 123 wantFailures: []report.Failure{ 124 report.Failuref( 125 meta.Position{ 126 Filename: "example.proto", 127 Offset: 150, 128 Line: 7, 129 Column: 15, 130 }, 131 "MESSAGES_HAVE_COMMENT", 132 `Message "MessageName" should have a comment`, 133 ), 134 report.Failuref( 135 meta.Position{ 136 Filename: "example.proto", 137 Offset: 200, 138 Line: 10, 139 Column: 20, 140 }, 141 "MESSAGES_HAVE_COMMENT", 142 `Message "MessageName2" should have a comment`, 143 ), 144 }, 145 }, 146 { 147 name: "failures for proto with invalid messages without Golang style comments", 148 inputProto: &parser.Proto{ 149 ProtoBody: []parser.Visitee{ 150 &parser.Service{}, 151 &parser.Message{ 152 MessageName: "MessageName", 153 MessageBody: []parser.Visitee{ 154 &parser.Message{ 155 MessageName: "MessageName2", 156 Meta: meta.Meta{ 157 Pos: meta.Position{ 158 Filename: "example.proto", 159 Offset: 200, 160 Line: 10, 161 Column: 20, 162 }, 163 }, 164 }, 165 }, 166 Comments: []*parser.Comment{ 167 { 168 Raw: "// a message name.", 169 }, 170 }, 171 Meta: meta.Meta{ 172 Pos: meta.Position{ 173 Filename: "example.proto", 174 Offset: 150, 175 Line: 7, 176 Column: 15, 177 }, 178 }, 179 }, 180 }, 181 }, 182 inputShouldFollowGolangStyle: true, 183 wantFailures: []report.Failure{ 184 report.Failuref( 185 meta.Position{ 186 Filename: "example.proto", 187 Offset: 150, 188 Line: 7, 189 Column: 15, 190 }, 191 "MESSAGES_HAVE_COMMENT", 192 `Message "MessageName" should have a comment of the form "// MessageName ..."`, 193 ), 194 report.Failuref( 195 meta.Position{ 196 Filename: "example.proto", 197 Offset: 200, 198 Line: 10, 199 Column: 20, 200 }, 201 "MESSAGES_HAVE_COMMENT", 202 `Message "MessageName2" should have a comment of the form "// MessageName2 ..."`, 203 ), 204 }, 205 }, 206 { 207 name: "failures for proto with messages without Golang style comments due to the inline comment", 208 inputProto: &parser.Proto{ 209 ProtoBody: []parser.Visitee{ 210 &parser.Service{}, 211 &parser.Message{ 212 MessageName: "MessageName", 213 MessageBody: []parser.Visitee{ 214 &parser.Message{ 215 MessageName: "MessageName2", 216 InlineCommentBehindLeftCurly: &parser.Comment{ 217 Raw: "// MessageName2 is special.", 218 }, 219 }, 220 }, 221 InlineComment: &parser.Comment{ 222 Raw: "// MessageName is special.", 223 }, 224 }, 225 }, 226 }, 227 inputShouldFollowGolangStyle: true, 228 wantFailures: []report.Failure{ 229 report.Failuref( 230 meta.Position{}, 231 "MESSAGES_HAVE_COMMENT", 232 `Message "MessageName" should have a comment of the form "// MessageName ..."`, 233 ), 234 report.Failuref( 235 meta.Position{}, 236 "MESSAGES_HAVE_COMMENT", 237 `Message "MessageName2" should have a comment of the form "// MessageName2 ..."`, 238 ), 239 }, 240 }, 241 } 242 243 for _, test := range tests { 244 test := test 245 t.Run(test.name, func(t *testing.T) { 246 rule := rules.NewMessagesHaveCommentRule(rule.SeverityError, test.inputShouldFollowGolangStyle) 247 248 got, err := rule.Apply(test.inputProto) 249 if err != nil { 250 t.Errorf("got err %v, but want nil", err) 251 return 252 } 253 if !reflect.DeepEqual(got, test.wantFailures) { 254 t.Errorf("got %v, but want %v", got, test.wantFailures) 255 } 256 }) 257 } 258 }