blob: 4e973b3e83ec6cc06fb1af4b2787c492316a0c3c [file] [log] [blame]
Kevin Burkef2033b72017-03-27 13:36:47 -06001// Copyright 2017 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package maintner
6
Kevin Burke8f4eb5d2017-04-26 23:04:17 -07007import (
Brad Fitzpatrick0b261d02018-04-15 19:14:59 +00008 "bytes"
Kevin Burke8f4eb5d2017-04-26 23:04:17 -07009 "testing"
10 "time"
11)
Kevin Burkef2033b72017-03-27 13:36:47 -060012
13var statusTests = []struct {
14 msg string
15 want string
16}{
Kevin Burke58ea07d2017-05-02 07:23:31 -070017 {`Create change
Kevin Burkef2033b72017-03-27 13:36:47 -060018
Kevin Burke58ea07d2017-05-02 07:23:31 -070019Uploaded patch set 1.
Kevin Burkef2033b72017-03-27 13:36:47 -060020
Kevin Burke58ea07d2017-05-02 07:23:31 -070021Patch-set: 1 (draft)
22Change-id: I38a08cacc17bcd9587475495111fe98f10d6875c
23Subject: test: test
24Branch: refs/heads/master
25Status: draft
26Topic:
27Commit: fee468c613a70d89f60fb5d683b0f796aabecaac`, "draft"},
28 {`Update patch set 1
Kevin Burkef2033b72017-03-27 13:36:47 -060029
Kevin Burke58ea07d2017-05-02 07:23:31 -070030Change has been successfully cherry-picked as 117ac82c422a11e4dd5f4c14b50bafc1df840481 by Brad Fitzpatrick
Kevin Burkef2033b72017-03-27 13:36:47 -060031
Kevin Burke58ea07d2017-05-02 07:23:31 -070032Patch-set: 1
33Status: merged
34Submission-id: 16401-1446004855021-a20b3823`, "merged"},
35 {`Create patch set 8
Kevin Burkef2033b72017-03-27 13:36:47 -060036
Kevin Burke58ea07d2017-05-02 07:23:31 -070037Uploaded patch set 8: Patch Set 7 was rebased.
Kevin Burkef2033b72017-03-27 13:36:47 -060038
Kevin Burke58ea07d2017-05-02 07:23:31 -070039Patch-set: 8
40Subject: devapp: initial support for App Engine Flex
41Commit: 17839a9f284b473986f235ad2757a2b445d05068
42Tag: autogenerated:gerrit:newPatchSet
Kevin Burke8f4eb5d2017-04-26 23:04:17 -070043Groups: 17839a9f284b473986f235ad2757a2b445d05068`, ""},
Kevin Burkef2033b72017-03-27 13:36:47 -060044}
45
46func TestGetGerritStatus(t *testing.T) {
Kevin Burkef2033b72017-03-27 13:36:47 -060047 for _, tt := range statusTests {
48 gc := &GitCommit{Msg: tt.msg}
Kevin Burke8f4eb5d2017-04-26 23:04:17 -070049 got := getGerritStatus(gc)
Kevin Burkef2033b72017-03-27 13:36:47 -060050 if got != tt.want {
51 t.Errorf("getGerritStatus msg:\n%s\ngot %s, want %s", tt.msg, got, tt.want)
52 }
53 }
54}
Kevin Burked802da82017-04-30 17:22:59 -070055
56var normalizeTests = []struct {
57 in string
58 out string
59}{
60 {"foo", "foo"},
61 {"http://foo", "foo"},
62 {"upspin-review.googlesource.com", "upspin.googlesource.com"},
63 {"go-review.googlesource.com", "go.googlesource.com"},
64}
65
66func TestNormalizeServer(t *testing.T) {
67 for _, tt := range normalizeTests {
68 got := normalizeGerritServer(tt.in)
69 if got != tt.out {
70 t.Errorf("normalizeGerritServer(%q) = %q, want %q", tt.in, got, tt.out)
71 }
72 }
73}
74
75func TestGerritProject(t *testing.T) {
76 var c Corpus
77 c.EnableLeaderMode(new(dummyMutationLogger), "/fake/dir")
78 c.TrackGerrit("go.googlesource.com/build")
79 gp := c.Gerrit().Project("go-review.googlesource.com", "build")
80 if gp == nil {
81 t.Errorf("expected go-review.googlesource.com to return a project, got nil")
82 }
83 gp = c.Gerrit().Project("go-review.googlesource.com", "unknown")
84 if gp != nil {
85 t.Errorf("expected go-review.googlesource.com to return nil, got a project")
86 }
87}
Kevin Burke8f4eb5d2017-04-26 23:04:17 -070088
89var messageTests = []struct {
Brad Fitzpatrick8a704022017-08-07 21:20:33 +000090 in string
91 want string
92 wantNil bool
Kevin Burke8f4eb5d2017-04-26 23:04:17 -070093}{
Brad Fitzpatrick8a704022017-08-07 21:20:33 +000094 {
95 in: `Update patch set 1
Kevin Burke8f4eb5d2017-04-26 23:04:17 -070096
97Patch Set 1: Code-Review+2
98
99Just to confirm, "go test" will consider an empty test file to be passing?
100
101Patch-set: 1
102Reviewer: Quentin Smith <13020@62eb7196-b449-3ce5-99f1-c037f21e1705>
103Label: Code-Review=+2
Brad Fitzpatrick8a704022017-08-07 21:20:33 +0000104`,
105 want: "Patch Set 1: Code-Review+2\n\nJust to confirm, \"go test\" will consider an empty test file to be passing?",
106 },
107 {
108 in: `Create change
Andrew Bonventre2f835b62017-09-20 17:38:08 -0400109
Brad Fitzpatrick8a704022017-08-07 21:20:33 +0000110Uploaded patch set 1: Run-TryBot+1.
111
112Patch-set: 1
113Change-id: I1e0035ffba986c3551479d5742809e43da5e7c73
114Subject: runtime: fall back to small mmaps if we fail to grow reservation
115Branch: refs/heads/master
116Status: new
117Topic:
118Commit: 8776f8d725c001456037e8888a72885d46cd6744
119Tag: autogenerated:gerrit:newPatchSet
120Groups: 8776f8d725c001456037e8888a72885d46cd6744
121Reviewer: Keith Randall <5200@62eb7196-b449-3ce5-99f1-c037f21e1705>
122Reviewer: Rick Hudson <5186@62eb7196-b449-3ce5-99f1-c037f21e1705>
123Reviewer: Austin Clements <5167@62eb7196-b449-3ce5-99f1-c037f21e1705>
Andrew Bonventre2f835b62017-09-20 17:38:08 -0400124Label: Run-TryBot=+1
125Private: false
Brad Fitzpatrick8a704022017-08-07 21:20:33 +0000126Work-in-progress: false
127`,
128 want: "Uploaded patch set 1: Run-TryBot+1.",
129 },
130 {
131 in: `Uploaded patch set 1.
Andrew Bonventre2f835b62017-09-20 17:38:08 -0400132
Brad Fitzpatrick8a704022017-08-07 21:20:33 +0000133Patch-set: 1
134`,
135 wantNil: true,
136 },
137 {
138 in: `Create change
Andrew Bonventre2f835b62017-09-20 17:38:08 -0400139
Brad Fitzpatrick8a704022017-08-07 21:20:33 +0000140Uploaded patch set 1.
Andrew Bonventre2f835b62017-09-20 17:38:08 -0400141
Brad Fitzpatrick8a704022017-08-07 21:20:33 +0000142Patch-set: 1
143Change-id: I3799148a111f1ab6bfee24c9e03e6ebbf9e9595b
144Subject: net: make error messages consistent for invalid ports
145Branch: refs/heads/master
146Commit: 8a7de7048dc194d5e6f761add433b915beebb2e0
147Groups: 8a7de7048dc194d5e6f761add433b915beebb2e0
148`,
149 wantNil: true,
150 },
151 {
152 in: `Create patch set 7
153
Andrew Bonventre2f835b62017-09-20 17:38:08 -0400154Uploaded patch set 7.: Commit message was updated
Brad Fitzpatrick8a704022017-08-07 21:20:33 +0000155
156Patch-set: 7
157Subject: cmd/vet: -lostcancel: check for discarded result of context.WithCancel
158Commit: 5487cc78ea332c7b49d43ef5955211387aca73bb
159Groups: 5487cc78ea332c7b49d43ef5955211387aca73bb
160`,
161 wantNil: true,
162 },
Kevin Burke8f4eb5d2017-04-26 23:04:17 -0700163}
164
165func TestGetGerritMessage(t *testing.T) {
166 var c Corpus
167 c.EnableLeaderMode(new(dummyMutationLogger), "/fake/dir")
168 c.TrackGerrit("go.googlesource.com/build")
169 gp := c.gerrit.projects["go.googlesource.com/build"]
Brad Fitzpatrick8a704022017-08-07 21:20:33 +0000170 for i, tt := range messageTests {
Kevin Burke8f4eb5d2017-04-26 23:04:17 -0700171 gc := &GitCommit{
172 Msg: tt.in,
173 CommitTime: time.Now().UTC(),
174 }
175 msg := gp.getGerritMessage(gc)
Brad Fitzpatrick8a704022017-08-07 21:20:33 +0000176 if msg == nil != tt.wantNil {
177 if tt.wantNil {
Andrew Bonventre2f835b62017-09-20 17:38:08 -0400178 t.Errorf("%d. getGerritMessage returned item; want nil", i)
Brad Fitzpatrick8a704022017-08-07 21:20:33 +0000179 } else {
Andrew Bonventre2f835b62017-09-20 17:38:08 -0400180 t.Errorf("%d. getGerritMessage = nil; want a message", i)
Brad Fitzpatrick8a704022017-08-07 21:20:33 +0000181 }
182 continue
183 }
184 if msg == nil {
185 continue
186 }
Kevin Burke8f4eb5d2017-04-26 23:04:17 -0700187 // just checking these get copied through appropriately
188 if msg.Version != 1 {
Brad Fitzpatrick8a704022017-08-07 21:20:33 +0000189 t.Errorf("%d. getGerritMessage: want Version 1, got %d", i, msg.Version)
Kevin Burke8f4eb5d2017-04-26 23:04:17 -0700190 }
191 if msg.Date.IsZero() {
Brad Fitzpatrick8a704022017-08-07 21:20:33 +0000192 t.Errorf("%d. getGerritMessage: expected Date to be non-zero, got zero", i)
Kevin Burke8f4eb5d2017-04-26 23:04:17 -0700193 }
Brad Fitzpatrick8a704022017-08-07 21:20:33 +0000194 if msg.Message != tt.want {
195 t.Errorf("%d. getGerritMessage = %q; want %q", i, msg.Message, tt.want)
Kevin Burke8f4eb5d2017-04-26 23:04:17 -0700196 }
197 }
198}
Andrew Bonventre6990c342017-07-05 22:24:05 -0400199
Andrew Bonventre5df336c2018-11-08 12:07:56 -0500200func TestOwnerID(t *testing.T) {
Brad Fitzpatrickce9aca42018-04-15 16:43:50 +0000201 cl := &GerritCL{}
Dmitri Shuralyovdcbfa192018-08-03 16:20:39 -0400202 meta := newGerritMeta(
203 &GitCommit{
204 Author: &GitPerson{
205 Str: "Rick Sanchez <137@62eb7196-b449-3ce5-99f1-c037f21e1705>",
Brad Fitzpatrickce9aca42018-04-15 16:43:50 +0000206 },
207 },
Dmitri Shuralyovdcbfa192018-08-03 16:20:39 -0400208 cl,
209 )
210 cl.Meta = meta
211 cl.Metas = []*GerritMeta{meta}
212 cl.Commit = &GitCommit{}
Brad Fitzpatrickce9aca42018-04-15 16:43:50 +0000213
Andrew Bonventre2f835b62017-09-20 17:38:08 -0400214 testCases := []struct {
Andrew Bonventre5df336c2018-11-08 12:07:56 -0500215 cl *GerritCL
216 OwnerID int
Andrew Bonventre2f835b62017-09-20 17:38:08 -0400217 }{
Andrew Bonventre5df336c2018-11-08 12:07:56 -0500218 {&GerritCL{}, -1},
219 {cl, 137},
Andrew Bonventre6990c342017-07-05 22:24:05 -0400220 }
Andrew Bonventre2f835b62017-09-20 17:38:08 -0400221 for _, tc := range testCases {
222 if got := tc.cl.OwnerID(); got != tc.OwnerID {
223 t.Errorf("cl.OwnerID() = %d; want %d", got, tc.OwnerID)
224 }
Andrew Bonventre6990c342017-07-05 22:24:05 -0400225 }
226}
Andrew Bonventree3b7b1d2017-07-18 17:04:23 -0400227
228func TestSubject(t *testing.T) {
Andrew Bonventree3b7b1d2017-07-18 17:04:23 -0400229 testcases := []struct{ msg, subject string }{
230 {"maintner: slurp up all the things", "maintner: slurp up all the things"},
231 {"cmd/go: build stuff\n\nand do other stuff, too.", "cmd/go: build stuff"},
Dmitri Shuralyov77d92a92019-02-05 22:27:47 -0500232 {"cmd/go: build lots\nof stuff\n\nand do other stuff, too.", "cmd/go: build lots of stuff"}, // Subject is separated from body by a blank line.
Dmitri Shuralyov357a85b2019-02-11 01:33:32 -0500233 {"cmd/go: build lots\nof stuff", "cmd/go: build lots of stuff"},
Andrew Bonventree3b7b1d2017-07-18 17:04:23 -0400234 }
235 for _, tc := range testcases {
Dmitri Shuralyov9fbc4182019-02-05 21:37:19 -0500236 cl := &GerritCL{Commit: &GitCommit{Msg: tc.msg}}
Andrew Bonventree3b7b1d2017-07-18 17:04:23 -0400237 if cl.Subject() != tc.subject {
238 t.Errorf("cl.Subject() = %q; want %q", cl.Subject(), tc.subject)
239 }
240 }
241}
Brad Fitzpatrick7d8c8e42017-07-27 14:02:21 +0000242
Dmitri Shuralyov9fbc4182019-02-05 21:37:19 -0500243func TestChangeID(t *testing.T) {
244 testcases := []struct{ msg, changeID string }{
245 {"maintner: slurp up all the things", ""},
246 {"cmd/go: build stuff\n\nChange-Id: I7d3850e6774403c5d4ae15ca94c31c2f46f4ffa3", "I7d3850e6774403c5d4ae15ca94c31c2f46f4ffa3"},
247 }
248 for _, tc := range testcases {
249 cl := &GerritCL{Commit: &GitCommit{Msg: tc.msg}}
250 if cl.ChangeID() != tc.changeID {
251 t.Errorf("cl.ChangeID() = %q; want %q", cl.ChangeID(), tc.changeID)
252 }
253 }
254}
255
Dmitri Shuralyov2e63fd12018-12-10 19:52:01 -0500256func TestLineValueOK(t *testing.T) {
Brad Fitzpatrick7d8c8e42017-07-27 14:02:21 +0000257 tests := []struct {
Brad Fitzpatrick8a704022017-08-07 21:20:33 +0000258 all, prefix, want, wantRest string
Dmitri Shuralyov2e63fd12018-12-10 19:52:01 -0500259 wantOK bool
Brad Fitzpatrick7d8c8e42017-07-27 14:02:21 +0000260 }{
261 {
Brad Fitzpatrick8a704022017-08-07 21:20:33 +0000262 all: "foo: value ",
263 prefix: "foo:",
264 want: "value",
265 wantRest: "",
Dmitri Shuralyov2e63fd12018-12-10 19:52:01 -0500266 wantOK: true,
Brad Fitzpatrick7d8c8e42017-07-27 14:02:21 +0000267 },
268 {
Brad Fitzpatrick8a704022017-08-07 21:20:33 +0000269 all: "foo: value\n",
270 prefix: "foo:",
271 want: "value",
272 wantRest: "",
Dmitri Shuralyov2e63fd12018-12-10 19:52:01 -0500273 wantOK: true,
274 },
275 {
276 all: "foo:\n",
277 prefix: "foo:",
278 want: "",
279 wantRest: "",
280 wantOK: true,
281 },
282 {
283 all: "bar:\n",
284 prefix: "foo:",
285 want: "",
286 wantRest: "",
287 wantOK: false,
Brad Fitzpatrick7d8c8e42017-07-27 14:02:21 +0000288 },
289 {
Brad Fitzpatrick8a704022017-08-07 21:20:33 +0000290 all: "bar: other\nfoo: value\n",
291 prefix: "foo:",
292 want: "value",
293 wantRest: "",
Dmitri Shuralyov2e63fd12018-12-10 19:52:01 -0500294 wantOK: true,
Brad Fitzpatrick7d8c8e42017-07-27 14:02:21 +0000295 },
296 {
Brad Fitzpatrick8a704022017-08-07 21:20:33 +0000297 all: "notfoo: other\nfoo: value\n",
298 prefix: "foo:",
299 want: "value",
300 wantRest: "",
Dmitri Shuralyov2e63fd12018-12-10 19:52:01 -0500301 wantOK: true,
Brad Fitzpatrick8a704022017-08-07 21:20:33 +0000302 },
303 {
304 all: "Foo: bar\nLabel: Vote=+1\nLabel: Vote=+2\n",
305 prefix: "Label: ",
306 want: "Vote=+1",
307 wantRest: "Label: Vote=+2\n",
Dmitri Shuralyov2e63fd12018-12-10 19:52:01 -0500308 wantOK: true,
Brad Fitzpatrick8a704022017-08-07 21:20:33 +0000309 },
310 {
311 all: "Label: Vote=+2\n",
312 prefix: "Label: ",
313 want: "Vote=+2",
314 wantRest: "",
Dmitri Shuralyov2e63fd12018-12-10 19:52:01 -0500315 wantOK: true,
Brad Fitzpatrick7d8c8e42017-07-27 14:02:21 +0000316 },
317 }
318 for _, tt := range tests {
Dmitri Shuralyov2e63fd12018-12-10 19:52:01 -0500319 got, gotRest, gotOK := lineValueOK(tt.all, tt.prefix)
Brad Fitzpatrick7d8c8e42017-07-27 14:02:21 +0000320 if got != tt.want {
Dmitri Shuralyov2e63fd12018-12-10 19:52:01 -0500321 t.Errorf("lineValueOK(%q, %q) returned value %q; want %q", tt.all, tt.prefix, got, tt.want)
Brad Fitzpatrick8a704022017-08-07 21:20:33 +0000322 }
323 if gotRest != tt.wantRest {
Dmitri Shuralyov2e63fd12018-12-10 19:52:01 -0500324 t.Errorf("lineValueOK(%q, %q) returned rest %q; want %q", tt.all, tt.prefix, gotRest, tt.wantRest)
325 }
326 if gotOK != tt.wantOK {
327 t.Errorf("lineValueOK(%q, %q) returned ok %v; want %v", tt.all, tt.prefix, gotOK, tt.wantOK)
Brad Fitzpatrick8a704022017-08-07 21:20:33 +0000328 }
329 }
330}
331
332func TestParseGerritLabelValue(t *testing.T) {
333 tests := []struct {
334 in string
335 wantLabel string
336 wantValue int8
337 wantWhose string
338 }{
339 {"Run-TryBot=+1", "Run-TryBot", 1, ""},
340 {"-Run-TryBot", "-Run-TryBot", 0, ""},
341 {"-TryBot-Result Gobot Gobot <5976@62eb7196-b449-3ce5-99f1-c037f21e1705>", "-TryBot-Result", 0, "5976@62eb7196-b449-3ce5-99f1-c037f21e1705"},
342 {"Run-TryBot=+1 Brad Fitzpatrick <5065@62eb7196-b449-3ce5-99f1-c037f21e1705>", "Run-TryBot", 1, "5065@62eb7196-b449-3ce5-99f1-c037f21e1705"},
343 {"TryBot-Result=-1 Gobot Gobot <5976@62eb7196-b449-3ce5-99f1-c037f21e1705>", "TryBot-Result", -1, "5976@62eb7196-b449-3ce5-99f1-c037f21e1705"},
344 }
345 for _, tt := range tests {
346 label, value, whose := parseGerritLabelValue(tt.in)
347 if label != tt.wantLabel || value != tt.wantValue || whose != tt.wantWhose {
348 t.Errorf("parseGerritLabelValue(%q) = %q, %v, %q; want %q, %v, %q",
349 tt.in,
350 label, value, whose,
351 tt.wantLabel, tt.wantValue, tt.wantWhose)
Brad Fitzpatrick7d8c8e42017-07-27 14:02:21 +0000352 }
353 }
354}
Brad Fitzpatrick0b261d02018-04-15 19:14:59 +0000355
356var hashtagTests = []struct {
357 commit string
358 wantAdd string
359 wantRemove string
360}{
361 {
362 commit: `Update patch set 1
363
364Hashtag removed:foo
365
366Patch-set: 1
367Hashtags:
368Tag: autogenerated:gerrit:setHashtag
369`,
370 wantRemove: "foo",
371 },
372 {
373 commit: `Update patch set 1
374
375Hashtags removed: foo, bar
376
377Patch-set: 1
378Hashtags:
379Tag: autogenerated:gerrit:setHashtag
380`,
381 wantRemove: "foo, bar",
382 },
383 {
384 commit: `Update patch set 1
385
Dmitri Shuralyovdcbfa192018-08-03 16:20:39 -0400386Hashtag added: bar
Brad Fitzpatrick0b261d02018-04-15 19:14:59 +0000387
388Patch-set: 1
389Hashtags:
390Tag: autogenerated:gerrit:setHashtag
391`,
392 wantAdd: "bar",
393 },
394 {
395 commit: `Update patch set 1
396
397Hashtags added: x,y
398
399Patch-set: 1
400Hashtags:
401Tag: autogenerated:gerrit:setHashtag
402`,
403 wantAdd: "x,y",
404 },
405 // No tag:
406 {
407 commit: `Update patch set 1
408
409Hashtags added: x,y
410
411Patch-set: 1
412Hashtags:
413Tag: autogenerated:gerrit:otherTag
414`,
415 },
416}
417
418func TestParseHashtags(t *testing.T) {
419 for i, tt := range hashtagTests {
Brad Fitzpatrickdd351512018-04-16 22:17:01 +0000420 meta := newGerritMeta(&GitCommit{Msg: tt.commit}, nil)
Brad Fitzpatrick0b261d02018-04-15 19:14:59 +0000421 added, removed, ok := meta.HashtagEdits()
422 if ok != (added != "" || removed != "") {
423 t.Errorf("%d. inconsistent return values: %q, %q, %v", i, added, removed, ok)
424 }
425 if string(added) != tt.wantAdd {
426 t.Errorf("%d. added = %q; want %q", i, added, tt.wantAdd)
427 }
428 if string(removed) != tt.wantRemove {
429 t.Errorf("%d. removed = %q; want %q", i, removed, tt.wantRemove)
430 }
431
432 // And an allocation test too:
433 allocs := testing.AllocsPerRun(100, func() {
434 _, _, _ = meta.HashtagEdits()
435 })
436 if allocs > 0 {
437 t.Errorf("%d. allocs = %d; want 0", i, int(allocs))
438 }
439 }
440}
441
442var addedSink, removedSink GerritHashtags
443
444func BenchmarkParseHashtags(b *testing.B) {
445 b.ReportAllocs()
446
447 var metas []*GerritMeta
448 for _, tt := range hashtagTests {
449 metas = append(metas, &GerritMeta{Commit: &GitCommit{Msg: tt.commit}})
450 }
451
452 for i := 0; i < b.N; i++ {
453 for _, meta := range metas {
454 addedSink, removedSink, _ = meta.HashtagEdits()
455 }
456 }
457}
458
459func TestGerritHashtagsContains(t *testing.T) {
460 tests := []struct {
461 set string
462 t string
463 want bool
464 }{
465 {"", "", false},
466 {"x", "", false},
467 {"", "x", false},
468
469 {"foo,bar", "foo", true},
470 {"foo, bar", "foo", true},
471 {" foo, bar", "foo", true},
472 {" foo , bar", "foo", true},
473 {" foo , bar ", "foo", true},
474
475 {"foo,bar", "bar", true},
476 {"foo, bar", "bar", true},
477 {" foo, bar", "bar", true},
478 {" foo , bar", "bar", true},
479 {" foo , bar ", "bar", true},
480
481 {"foo, bar", "fo", false},
482 {"foo, bar", "foo, bar", false},
483 {"foo, bar", "ba", false},
484 }
485 for _, tt := range tests {
486 got := GerritHashtags(tt.set).Contains(tt.t)
487 if got != tt.want {
488 t.Errorf("GerritHashtags(%q).Contains(%q) = %v; want %v", tt.set, tt.t, got, tt.want)
489 }
490 }
491}
492
493func TestGerritHashtagsForeach(t *testing.T) {
494 tests := []struct {
495 set string
496 want string
497 }{
498 {"", ""},
499
500 {"foo", "foo."},
501 {"foo ", "foo."},
502 {" foo", "foo."},
503 {"foo,bar", "foo.bar."},
504 {" foo , bar ", "foo.bar."},
505 }
506 for _, tt := range tests {
507 var buf bytes.Buffer
508 GerritHashtags(tt.set).Foreach(func(t string) {
509 buf.WriteString(t)
510 buf.WriteByte('.')
511 })
512 got := buf.String()
513 if got != tt.want {
514 t.Errorf("For set %q, got %q; want %q", tt.set, got, tt.want)
515 }
516 }
517}
518
519func TestGerritHashtagsMatch(t *testing.T) {
520 tests := []struct {
521 set string
522 want bool // whether "foo" was found
523 wantCalls int
524 }{
525 {"", false, 0},
526 {"foo", true, 1},
527 {"foo, foo", true, 1},
528 {"bar, foo", true, 2},
529 }
530 for _, tt := range tests {
531 calls := 0
532 got := GerritHashtags(tt.set).Match(func(t string) bool {
533 calls++
534 return t == "foo"
535 })
536 if got != tt.want {
537 t.Errorf("For set %q, Match = %v; want %v", tt.set, got, tt.want)
538 }
539 if calls != tt.wantCalls {
540 t.Errorf("For set %q, number of func calls = %v; want %v", tt.set, calls, tt.wantCalls)
541 }
542 }
543}
544
545func TestGerritHashtagsLen(t *testing.T) {
546 tests := []struct {
547 set string
548 want int
549 }{
550 {"", 0},
551 {"foo", 1},
552 {"foo,bar", 2},
553 {"foo, bar", 2},
554 }
555 for _, tt := range tests {
556 got := GerritHashtags(tt.set).Len()
557 if got != tt.want {
558 t.Errorf("For set %q, Len = %v; want %v", tt.set, got, tt.want)
559 }
560 }
561}