cloudflare/pint

Public

mirrored from https://github.com/cloudflare/pintAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v0.73.7

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

internal/comments/comments_test.go

782lines · modecode

1package comments_test
2
3import (
4 "fmt"
5 "testing"
6 "time"
7
8 "github.com/cloudflare/pint/internal/comments"
9 "github.com/cloudflare/pint/internal/diags"
10
11 "github.com/stretchr/testify/require"
12)
13
14func TestParse(t *testing.T) {
15 type testCaseT struct {
16 input string
17 output []comments.Comment
18 }
19
20 parseUntil := func(s string) time.Time {
21 until, err := time.Parse(time.RFC3339, s)
22 require.NoError(t, err)
23 return until
24 }
25
26 errUntil := func(s string) error {
27 _, err := time.Parse("2006-01-02", s)
28 require.Error(t, err)
29 return err
30 }
31
32 testCases := []testCaseT{
33 {
34 input: "code\n",
35 },
36 {
37 input: "code # bob\n",
38 },
39 {
40 input: "code # bob\ncode # alice\n",
41 },
42 {
43 input: "# pint bamboozle me this",
44 },
45 {
46 input: "# pint/xxx bamboozle me this",
47 },
48 {
49 input: "# pint bambo[]ozle me this",
50 },
51 {
52 input: "# pint ignore/file \t this file",
53 output: []comments.Comment{
54 {
55 Type: comments.InvalidComment,
56 Value: comments.Invalid{
57 Err: comments.CommentError{
58 Diagnostic: diags.Diagnostic{
59 Message: `This comment is not a valid pint control comment: unexpected comment suffix: "this file"`,
60 Pos: diags.PositionRanges{
61 {
62 Line: 1,
63 FirstColumn: 1,
64 LastColumn: 30,
65 },
66 },
67 FirstColumn: 1,
68 LastColumn: 30,
69 },
70 },
71 },
72 },
73 },
74 },
75 {
76 input: "# pint ignore/file",
77 output: []comments.Comment{
78 {Type: comments.IgnoreFileType},
79 },
80 },
81 {
82 input: "# pint ignore/line this line",
83 output: []comments.Comment{
84 {
85 Type: comments.InvalidComment,
86 Value: comments.Invalid{
87 Err: comments.CommentError{
88 Diagnostic: diags.Diagnostic{
89 Message: `This comment is not a valid pint control comment: unexpected comment suffix: "this line"`,
90 Pos: diags.PositionRanges{
91 {
92 Line: 1,
93 FirstColumn: 1,
94 LastColumn: 28,
95 },
96 },
97 FirstColumn: 1,
98 LastColumn: 28,
99 },
100 },
101 },
102 },
103 },
104 },
105 {
106 input: "# pint ignore/line",
107 output: []comments.Comment{
108 {Type: comments.IgnoreLineType},
109 },
110 },
111 {
112 input: "# pint ignore/begin here",
113 output: []comments.Comment{
114 {
115 Type: comments.InvalidComment,
116 Value: comments.Invalid{
117 Err: comments.CommentError{
118 Diagnostic: diags.Diagnostic{
119 Message: `This comment is not a valid pint control comment: unexpected comment suffix: "here"`,
120 Pos: diags.PositionRanges{
121 {
122 Line: 1,
123 FirstColumn: 1,
124 LastColumn: 24,
125 },
126 },
127 FirstColumn: 1,
128 LastColumn: 24,
129 },
130 },
131 },
132 },
133 },
134 },
135 {
136 input: "# pint ignore/begin",
137 output: []comments.Comment{
138 {Type: comments.IgnoreBeginType},
139 },
140 },
141 {
142 input: "# pint ignore/end here",
143 output: []comments.Comment{
144 {
145 Type: comments.InvalidComment,
146 Value: comments.Invalid{
147 Err: comments.CommentError{
148 Diagnostic: diags.Diagnostic{
149 Message: `This comment is not a valid pint control comment: unexpected comment suffix: "here"`,
150 Pos: diags.PositionRanges{
151 {
152 Line: 1,
153 FirstColumn: 1,
154 LastColumn: 22,
155 },
156 },
157 FirstColumn: 1,
158 LastColumn: 22,
159 },
160 },
161 },
162 },
163 },
164 },
165 {
166 input: "# pint ignore/end",
167 output: []comments.Comment{
168 {Type: comments.IgnoreEndType},
169 },
170 },
171 {
172 input: "# pint ignore/next-line\there",
173 output: []comments.Comment{
174 {
175 Type: comments.InvalidComment,
176 Value: comments.Invalid{
177 Err: comments.CommentError{
178 Diagnostic: diags.Diagnostic{
179 Message: `This comment is not a valid pint control comment: unexpected comment suffix: "here"`,
180 Pos: diags.PositionRanges{
181 {
182 Line: 1,
183 FirstColumn: 1,
184 LastColumn: 30,
185 },
186 },
187 FirstColumn: 1,
188 LastColumn: 30,
189 },
190 },
191 },
192 },
193 },
194 },
195 {
196 input: "# pint ignore/next-line",
197 output: []comments.Comment{
198 {Type: comments.IgnoreNextLineType},
199 },
200 },
201 {
202 input: "# pint file/owner",
203 output: []comments.Comment{
204 {
205 Type: comments.InvalidComment,
206 Value: comments.Invalid{
207 Err: comments.CommentError{
208 Diagnostic: diags.Diagnostic{
209 Message: `This comment is not a valid pint control comment: missing file/owner value`,
210 Pos: diags.PositionRanges{
211 {
212 Line: 1,
213 FirstColumn: 1,
214 LastColumn: 19,
215 },
216 },
217 FirstColumn: 1,
218 LastColumn: 19,
219 },
220 },
221 },
222 },
223 },
224 },
225 {
226 input: "# pint file/owner bob and alice",
227 output: []comments.Comment{
228 {
229 Type: comments.FileOwnerType,
230 Value: comments.Owner{
231 Name: "bob and alice",
232 Line: 1,
233 },
234 },
235 },
236 },
237 {
238 input: "# pint rule/owner",
239 output: []comments.Comment{
240 {
241 Type: comments.InvalidComment,
242 Value: comments.Invalid{
243 Err: comments.CommentError{
244 Diagnostic: diags.Diagnostic{
245 Message: `This comment is not a valid pint control comment: missing rule/owner value`,
246 Pos: diags.PositionRanges{
247 {
248 Line: 1,
249 FirstColumn: 1,
250 LastColumn: 19,
251 },
252 },
253 FirstColumn: 1,
254 LastColumn: 19,
255 },
256 },
257 },
258 },
259 },
260 },
261 {
262 input: "# pint rule/owner bob and alice",
263 output: []comments.Comment{
264 {
265 Type: comments.RuleOwnerType,
266 Value: comments.Owner{
267 Name: "bob and alice",
268 },
269 },
270 },
271 },
272 {
273 input: "# pint file/disable",
274 output: []comments.Comment{
275 {
276 Type: comments.InvalidComment,
277 Value: comments.Invalid{
278 Err: comments.CommentError{
279 Diagnostic: diags.Diagnostic{
280 Message: `This comment is not a valid pint control comment: missing file/disable value`,
281 Pos: diags.PositionRanges{
282 {
283 Line: 1,
284 FirstColumn: 1,
285 LastColumn: 21,
286 },
287 },
288 FirstColumn: 1,
289 LastColumn: 21,
290 },
291 },
292 },
293 },
294 },
295 },
296 {
297 input: `# pint file/disable promql/series(http_errors_total{label="this has spaces"})`,
298 output: []comments.Comment{
299 {
300 Type: comments.FileDisableType,
301 Value: comments.Disable{Match: `promql/series(http_errors_total{label="this has spaces"})`},
302 },
303 },
304 },
305 {
306 input: "# pint disable",
307 output: []comments.Comment{
308 {
309 Type: comments.InvalidComment,
310 Value: comments.Invalid{
311 Err: comments.CommentError{
312 Diagnostic: diags.Diagnostic{
313 Message: `This comment is not a valid pint control comment: missing disable value`,
314 Pos: diags.PositionRanges{
315 {
316 Line: 1,
317 FirstColumn: 1,
318 LastColumn: 16,
319 },
320 },
321 FirstColumn: 1,
322 LastColumn: 16,
323 },
324 },
325 },
326 },
327 },
328 },
329 {
330 input: `# pint disable promql/series(http_errors_total{label="this has spaces"})`,
331 output: []comments.Comment{
332 {
333 Type: comments.DisableType,
334 Value: comments.Disable{Match: `promql/series(http_errors_total{label="this has spaces"})`},
335 },
336 },
337 },
338 {
339 input: `# pint disable promql/series(http_errors_total{label="this has spaces and a # symbol"})`,
340 output: []comments.Comment{
341 {
342 Type: comments.DisableType,
343 Value: comments.Disable{Match: `promql/series(http_errors_total{label="this has spaces and a # symbol"})`},
344 },
345 },
346 },
347 {
348 input: "# pint file/snooze",
349 output: []comments.Comment{
350 {
351 Type: comments.InvalidComment,
352 Value: comments.Invalid{
353 Err: comments.CommentError{
354 Diagnostic: diags.Diagnostic{
355 Message: `This comment is not a valid pint control comment: missing file/snooze value`,
356 Pos: diags.PositionRanges{
357 {
358 Line: 1,
359 FirstColumn: 1,
360 LastColumn: 20,
361 },
362 },
363 FirstColumn: 1,
364 LastColumn: 20,
365 },
366 },
367 },
368 },
369 },
370 },
371 {
372 input: "# pint file/snooze 2023-12-31",
373 output: []comments.Comment{
374 {
375 Type: comments.InvalidComment,
376 Value: comments.Invalid{
377 Err: comments.CommentError{
378 Diagnostic: diags.Diagnostic{
379 Message: `This comment is not a valid pint control comment: invalid snooze comment, expected '$TIME $MATCH' got "2023-12-31"`,
380 Pos: diags.PositionRanges{
381 {
382 Line: 1,
383 FirstColumn: 1,
384 LastColumn: 31,
385 },
386 },
387 FirstColumn: 1,
388 LastColumn: 31,
389 },
390 },
391 },
392 },
393 },
394 },
395 {
396 input: "# pint file/snooze abc",
397 output: []comments.Comment{
398 {
399 Type: comments.InvalidComment,
400 Value: comments.Invalid{
401 Err: comments.CommentError{
402 Diagnostic: diags.Diagnostic{
403 Message: `This comment is not a valid pint control comment: invalid snooze comment, expected '$TIME $MATCH' got "abc"`,
404 Pos: diags.PositionRanges{
405 {
406 Line: 1,
407 FirstColumn: 1,
408 LastColumn: 24,
409 },
410 },
411 FirstColumn: 1,
412 LastColumn: 24,
413 },
414 },
415 },
416 },
417 },
418 },
419 {
420 input: `# pint file/snooze 2023-1231 promql/series(http_errors_total{label="this has spaces"})`,
421 output: []comments.Comment{
422 {
423 Type: comments.InvalidComment,
424 Value: comments.Invalid{Err: comments.CommentError{
425 Diagnostic: diags.Diagnostic{
426 Message: fmt.Sprintf("This comment is not a valid pint control comment: invalid snooze timestamp: %s", errUntil("2023-1231")),
427 Pos: diags.PositionRanges{
428 {
429 Line: 1,
430 FirstColumn: 1,
431 LastColumn: 86,
432 },
433 },
434 FirstColumn: 1,
435 LastColumn: 86,
436 },
437 }},
438 },
439 },
440 },
441 {
442 input: `# pint file/snooze 2023-12-31 promql/series(http_errors_total{label="this has spaces"})`,
443 output: []comments.Comment{
444 {
445 Type: comments.FileSnoozeType,
446 Value: comments.Snooze{
447 Until: parseUntil("2023-12-31T00:00:00Z"),
448 Match: `promql/series(http_errors_total{label="this has spaces"})`,
449 },
450 },
451 },
452 },
453 {
454 input: "# pint snooze",
455 output: []comments.Comment{
456 {
457 Type: comments.InvalidComment,
458 Value: comments.Invalid{
459 Err: comments.CommentError{
460 Diagnostic: diags.Diagnostic{
461 Message: `This comment is not a valid pint control comment: missing snooze value`,
462 Pos: diags.PositionRanges{
463 {
464 Line: 1,
465 FirstColumn: 1,
466 LastColumn: 15,
467 },
468 },
469 FirstColumn: 1,
470 LastColumn: 15,
471 },
472 },
473 },
474 },
475 },
476 },
477 {
478 input: "# pint snooze 2023-12-31",
479 output: []comments.Comment{
480 {
481 Type: comments.InvalidComment,
482 Value: comments.Invalid{
483 Err: comments.CommentError{
484 Diagnostic: diags.Diagnostic{
485 Message: `This comment is not a valid pint control comment: invalid snooze comment, expected '$TIME $MATCH' got "2023-12-31"`,
486 Pos: diags.PositionRanges{
487 {
488 Line: 1,
489 FirstColumn: 1,
490 LastColumn: 26,
491 },
492 },
493 FirstColumn: 1,
494 LastColumn: 26,
495 },
496 },
497 },
498 },
499 },
500 },
501 {
502 input: "# pint snooze abc",
503 output: []comments.Comment{
504 {
505 Type: comments.InvalidComment,
506 Value: comments.Invalid{
507 Err: comments.CommentError{
508 Diagnostic: diags.Diagnostic{
509 Message: `This comment is not a valid pint control comment: invalid snooze comment, expected '$TIME $MATCH' got "abc"`,
510 Pos: diags.PositionRanges{
511 {
512 Line: 1,
513 FirstColumn: 1,
514 LastColumn: 19,
515 },
516 },
517 FirstColumn: 1,
518 LastColumn: 19,
519 },
520 },
521 },
522 },
523 },
524 },
525 {
526 input: `# pint snooze 2023-1231 promql/series(http_errors_total{label="this has spaces"})`,
527 output: []comments.Comment{
528 {
529 Type: comments.InvalidComment,
530 Value: comments.Invalid{Err: comments.CommentError{
531 Diagnostic: diags.Diagnostic{
532 Message: fmt.Sprintf("This comment is not a valid pint control comment: invalid snooze timestamp: %s", errUntil("2023-1231")),
533 Pos: diags.PositionRanges{
534 {
535 Line: 1,
536 FirstColumn: 1,
537 LastColumn: 81,
538 },
539 },
540 FirstColumn: 1,
541 LastColumn: 81,
542 },
543 }},
544 },
545 },
546 },
547 {
548 input: `# pint snooze 2023-12-31 promql/series(http_errors_total{label="this has spaces"})`,
549 output: []comments.Comment{
550 {
551 Type: comments.SnoozeType,
552 Value: comments.Snooze{
553 Until: parseUntil("2023-12-31T00:00:00Z"),
554 Match: `promql/series(http_errors_total{label="this has spaces"})`,
555 },
556 },
557 },
558 },
559 {
560 input: `# pint snooze 2023-12-31 promql/series(http_errors_total{label="this has spaces"})`,
561 output: []comments.Comment{
562 {
563 Type: comments.SnoozeType,
564 Value: comments.Snooze{
565 Until: parseUntil("2023-12-31T00:00:00Z"),
566 Match: `promql/series(http_errors_total{label="this has spaces"})`,
567 },
568 },
569 },
570 },
571 {
572 input: "# pint rule/set",
573 output: []comments.Comment{
574 {
575 Type: comments.InvalidComment,
576 Value: comments.Invalid{
577 Err: comments.CommentError{
578 Diagnostic: diags.Diagnostic{
579 Message: `This comment is not a valid pint control comment: missing rule/set value`,
580 Pos: diags.PositionRanges{
581 {
582 Line: 1,
583 FirstColumn: 1,
584 LastColumn: 17,
585 },
586 },
587 FirstColumn: 1,
588 LastColumn: 17,
589 },
590 },
591 },
592 },
593 },
594 },
595 {
596 input: "# pint rule/set bob and alice",
597 output: []comments.Comment{
598 {
599 Type: comments.RuleSetType,
600 Value: comments.RuleSet{Value: "bob and alice"},
601 },
602 },
603 },
604 {
605 input: "code # pint disable xxx \ncode # alice\n",
606 output: []comments.Comment{
607 {
608 Type: comments.DisableType,
609 Value: comments.Disable{Match: "xxx"},
610 Offset: len("code "),
611 },
612 },
613 },
614 {
615 input: "code # pint disable xxx yyy \n # pint\tfile/owner bob",
616 output: []comments.Comment{
617 {
618 Type: comments.DisableType,
619 Value: comments.Disable{Match: "xxx yyy"},
620 Offset: len("code "),
621 },
622 {
623 Type: comments.FileOwnerType,
624 Value: comments.Owner{
625 Name: "bob",
626 Line: 2,
627 },
628 Offset: 1,
629 },
630 },
631 },
632 {
633 input: "# pint rule/set promql/series(found) min-age foo",
634 output: []comments.Comment{
635 {
636 Type: comments.RuleSetType,
637 Value: comments.RuleSet{Value: "promql/series(found) min-age foo"},
638 },
639 },
640 },
641 {
642 input: "{#- comment #} # pint ignore/line",
643 output: []comments.Comment{
644 {
645 Type: comments.IgnoreLineType,
646 Offset: len("{#- comment #} "),
647 },
648 },
649 },
650 {
651 input: "{# comment #} # pint ignore/line",
652 output: []comments.Comment{
653 {
654 Type: comments.IgnoreLineType,
655 Offset: len("{# comment #} "),
656 },
657 },
658 },
659 {
660 input: "#pint # pint # pint boo # pint ignore/line",
661 output: []comments.Comment{
662 {
663 Type: comments.IgnoreLineType,
664 Offset: len("#pint # pint # pint boo "),
665 },
666 },
667 },
668 {
669 input: "{# comment #} # pint ignore/line # pint ignore/file",
670 output: []comments.Comment{
671 {
672 Type: comments.InvalidComment,
673 Value: comments.Invalid{
674 Err: comments.CommentError{
675 Diagnostic: diags.Diagnostic{
676 Message: `This comment is not a valid pint control comment: unexpected comment suffix: "# pint ignore/file"`,
677 Pos: diags.PositionRanges{
678 {
679 Line: 1,
680 FirstColumn: 15,
681 LastColumn: 51,
682 },
683 },
684 FirstColumn: 1,
685 LastColumn: 51,
686 },
687 },
688 },
689 Offset: 14,
690 },
691 },
692 },
693 {
694 input: "{#- JIRA-12345: foo<->bar example comment ' -#} # pint ignore/line",
695 output: []comments.Comment{
696 {
697 Type: comments.IgnoreLineType,
698 Offset: len("{#- JIRA-12345: foo<->bar example comment ' -#} "),
699 },
700 },
701 },
702 }
703
704 for _, tc := range testCases {
705 t.Run(tc.input, func(t *testing.T) {
706 output := comments.Parse(1, tc.input)
707 require.Equal(t, tc.output, output)
708 })
709 }
710}
711
712func TestCommentValueString(t *testing.T) {
713 type testCaseT struct {
714 comment comments.CommentValue
715 expected string
716 }
717
718 parseUntil := func(s string) time.Time {
719 until, err := time.Parse(time.RFC3339, s)
720 require.NoError(t, err)
721 return until
722 }
723
724 testCases := []testCaseT{
725 {
726 comment: comments.Invalid{Err: comments.CommentError{
727 Diagnostic: diags.Diagnostic{
728 Message: "foo bar",
729 Pos: diags.PositionRanges{
730 {
731 Line: 1,
732 FirstColumn: 1,
733 LastColumn: 100,
734 },
735 },
736 FirstColumn: 1,
737 LastColumn: 100,
738 },
739 }},
740 expected: "foo bar",
741 },
742 {
743 comment: comments.Invalid{Err: comments.CommentError{
744 Diagnostic: diags.Diagnostic{
745 Message: "foo bar",
746 Pos: diags.PositionRanges{
747 {
748 Line: 1,
749 FirstColumn: 1,
750 LastColumn: 100,
751 },
752 },
753 FirstColumn: 1,
754 LastColumn: 100,
755 },
756 }},
757 expected: "foo bar",
758 },
759 {
760 comment: comments.Owner{Name: "bob & alice"},
761 expected: "bob & alice",
762 },
763 {
764 comment: comments.Disable{Match: `promql/series({code="500"})`},
765 expected: `promql/series({code="500"})`,
766 },
767 {
768 comment: comments.RuleSet{Value: "bob & alice"},
769 expected: "bob & alice",
770 },
771 {
772 comment: comments.Snooze{Match: `promql/series({code="500"})`, Until: parseUntil("2023-11-28T00:00:00Z")},
773 expected: `2023-11-28T00:00:00Z promql/series({code="500"})`,
774 },
775 }
776
777 for _, tc := range testCases {
778 t.Run(tc.expected, func(t *testing.T) {
779 require.Equal(t, tc.expected, tc.comment.String())
780 })
781 }
782}