The list of contributors in committers.py should be a separate JSON
[WebKit-https.git] / Tools / Scripts / webkitpy / common / config / committers_unittest.py
1 # Copyright (C) 2009 Google Inc. All rights reserved.
2 #
3 # Redistribution and use in source and binary forms, with or without
4 # modification, are permitted provided that the following conditions are
5 # met:
6 #
7 #    * Redistributions of source code must retain the above copyright
8 # notice, this list of conditions and the following disclaimer.
9 #    * Redistributions in binary form must reproduce the above
10 # copyright notice, this list of conditions and the following disclaimer # in the documentation and/or other materials provided with the
11 # distribution.
12 #    * Neither the name of Google Inc. nor the names of its
13 # contributors may be used to endorse or promote products derived from
14 # this software without specific prior written permission.
15 #
16 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 import unittest2 as unittest
29 from webkitpy.common.config.committers import CommitterList, Contributor, Committer, Reviewer
30
31 class CommittersTest(unittest.TestCase):
32     def test_committer_lookup(self):
33         committer = Committer('Test One', 'one@test.com', 'one')
34         reviewer = Reviewer('Test Two', ['two@test.com', 'Two@rad.com', 'so_two@gmail.com'])
35         contributor = Contributor('Test Three', ['Three@test.com'], 'three')
36         contributor_with_two_nicknames = Contributor('Other Four', ['otherfour@webkit.org', 'otherfour@webkit2.org'], ['four', 'otherfour'])
37         contributor_with_same_email_username = Contributor('Yet Another Four', ['otherfour@webkit.com'], ['yetanotherfour'])
38         committer_list = CommitterList(committers=[committer], reviewers=[reviewer],
39             contributors=[contributor, contributor_with_two_nicknames, contributor_with_same_email_username])
40
41         # Test valid committer, reviewer and contributor lookup
42         self.assertEqual(committer_list.committer_by_email('one@test.com'), committer)
43         self.assertEqual(committer_list.reviewer_by_email('two@test.com'), reviewer)
44         self.assertEqual(committer_list.committer_by_email('two@test.com'), reviewer)
45         self.assertEqual(committer_list.committer_by_email('two@rad.com'), reviewer)
46         self.assertEqual(committer_list.reviewer_by_email('so_two@gmail.com'), reviewer)
47         self.assertEqual(committer_list.contributor_by_email('three@test.com'), contributor)
48
49         # Test valid committer, reviewer and contributor lookup
50         self.assertEqual(committer_list.committer_by_name("Test One"), committer)
51         self.assertEqual(committer_list.committer_by_name("Test Two"), reviewer)
52         self.assertIsNone(committer_list.committer_by_name("Test Three"))
53         self.assertEqual(committer_list.contributor_by_name("Test Three"), contributor)
54         self.assertEqual(committer_list.contributor_by_name("test one"), committer)
55         self.assertEqual(committer_list.contributor_by_name("test two"), reviewer)
56         self.assertEqual(committer_list.contributor_by_name("test three"), contributor)
57
58         # Test that the first email is assumed to be the Bugzilla email address (for now)
59         self.assertEqual(committer_list.committer_by_email('two@rad.com').bugzilla_email(), 'two@test.com')
60
61         # Test that a known committer is not returned during reviewer lookup
62         self.assertIsNone(committer_list.reviewer_by_email('one@test.com'))
63         self.assertIsNone(committer_list.reviewer_by_email('three@test.com'))
64         # and likewise that a known contributor is not returned for committer lookup.
65         self.assertIsNone(committer_list.committer_by_email('three@test.com'))
66
67         # Test that unknown email address fail both committer and reviewer lookup
68         self.assertIsNone(committer_list.committer_by_email('bar@bar.com'))
69         self.assertIsNone(committer_list.reviewer_by_email('bar@bar.com'))
70
71         # Test that emails returns a list.
72         self.assertEqual(committer.emails, ['one@test.com'])
73
74         self.assertEqual(committer.irc_nicknames, ['one'])
75         self.assertEqual(committer_list.contributor_by_irc_nickname('one'), committer)
76         self.assertEqual(committer_list.contributor_by_irc_nickname('three'), contributor)
77         self.assertEqual(committer_list.contributor_by_irc_nickname('four'), contributor_with_two_nicknames)
78         self.assertEqual(committer_list.contributor_by_irc_nickname('otherfour'), contributor_with_two_nicknames)
79
80         # Test that the lists returned are are we expect them.
81         self.assertEqual(committer_list.contributors(), [contributor, contributor_with_two_nicknames, contributor_with_same_email_username, committer, reviewer])
82         self.assertEqual(committer_list.committers(), [committer, reviewer])
83         self.assertEqual(committer_list.reviewers(), [reviewer])
84
85         self.assertEqual(committer_list.contributors_by_search_string('test'), [contributor, committer, reviewer])
86         self.assertEqual(committer_list.contributors_by_search_string('rad'), [reviewer])
87         self.assertEqual(committer_list.contributors_by_search_string('Two'), [reviewer])
88         self.assertEqual(committer_list.contributors_by_search_string('otherfour'), [contributor_with_two_nicknames])
89         self.assertEqual(committer_list.contributors_by_search_string('*otherfour*'), [contributor_with_two_nicknames, contributor_with_same_email_username])
90
91         self.assertEqual(committer_list.contributors_by_email_username("one"), [committer])
92         self.assertEqual(committer_list.contributors_by_email_username("four"), [])
93         self.assertEqual(committer_list.contributors_by_email_username("otherfour"), [contributor_with_two_nicknames, contributor_with_same_email_username])
94
95     def _assert_fuzz_match(self, text, name_of_expected_contributor, expected_distance):
96         committers = CommitterList()
97         contributors, distance = committers.contributors_by_fuzzy_match(text)
98         if type(name_of_expected_contributor) is list:
99             expected_names = name_of_expected_contributor
100         else:
101             expected_names = [name_of_expected_contributor] if name_of_expected_contributor else []
102         self.assertEqual(([contributor.full_name for contributor in contributors], distance), (expected_names, expected_distance))
103
104     # Basic testing of the edit distance matching ...
105     def test_contributors_by_fuzzy_match(self):
106         self._assert_fuzz_match('Geoff Garen', 'Geoffrey Garen', 3)
107         self._assert_fuzz_match('Kenneth Christiansen', 'Kenneth Rohde Christiansen', 6)
108         self._assert_fuzz_match('Sam', 'Sam Weinig', 0)
109         self._assert_fuzz_match('me', None, 2)
110
111     # The remaining tests test that certain names are resolved in a specific way.
112     # We break this up into multiple tests so that each is faster and they can
113     # be run in parallel. Unfortunately each test scans the entire committers list,
114     # so these are inherently slow (see https://bugs.webkit.org/show_bug.cgi?id=79179).
115     #
116     # Commented out lines are test cases imported from the bug 26533 yet to pass.
117
118     def integration_test_contributors__none(self):
119         self._assert_fuzz_match('myself', None, 6)
120         self._assert_fuzz_match('others', None, 6)
121         self._assert_fuzz_match('BUILD FIX', None, 9)
122
123     def integration_test_contributors__none_2(self):
124         self._assert_fuzz_match('but Dan Bernstein also reviewed', None, 31)
125         self._assert_fuzz_match('asked thoughtful questions', None, 26)
126         self._assert_fuzz_match('build fix of mac', None, 16)
127
128     def integration_test_contributors__none_3(self):
129         self._assert_fuzz_match('a spell checker', None, 15)
130         self._assert_fuzz_match('nobody, build fix', None, 17)
131         self._assert_fuzz_match('NOBODY (chromium build fix)', None, 27)
132
133     def integration_test_contributors_ada_chan(self):
134         self._assert_fuzz_match('Ada', 'Ada Chan', 0)
135
136     def integration_test_contributors_adele_peterson(self):
137         self._assert_fuzz_match('adele', 'Adele Peterson', 0)
138
139     def integration_test_contributors_adele_peterson(self):
140         # self._assert_fuzz_match('Adam', 'Adam Roben', 0)
141         self._assert_fuzz_match('aroben', 'Adam Roben', 0)
142
143     def integration_test_contributors_alexey_proskuryakov(self):
144         # self._assert_fuzz_match('Alexey', 'Alexey Proskuryakov', 0)
145         self._assert_fuzz_match('ap', 'Alexey Proskuryakov', 0)
146         self._assert_fuzz_match('Alexey P', 'Alexey Proskuryakov', 0)
147
148     def integration_test_contributors_alice_liu(self):
149         # self._assert_fuzz_match('Alice', 'Alice Liu', 0)
150         self._assert_fuzz_match('aliu', 'Alice Liu', 0)
151         self._assert_fuzz_match('Liu', 'Alice Liu', 0)
152
153     def integration_test_contributors_alp_toker(self):
154         self._assert_fuzz_match('Alp', 'Alp Toker', 0)
155
156     def integration_test_contributors_anders_carlsson(self):
157         self._assert_fuzz_match('Anders', 'Anders Carlsson', 0)
158         self._assert_fuzz_match('andersca', 'Anders Carlsson', 0)
159         self._assert_fuzz_match('anders', 'Anders Carlsson', 0)
160         self._assert_fuzz_match('Andersca', 'Anders Carlsson', 0)
161
162     def integration_test_contributors_antti_koivisto(self):
163         self._assert_fuzz_match('Antti "printf" Koivisto', 'Antti Koivisto', 9)
164         self._assert_fuzz_match('Antti', 'Antti Koivisto', 0)
165
166     def integration_test_contributors_beth_dakin(self):
167         self._assert_fuzz_match('Beth', 'Beth Dakin', 0)
168         self._assert_fuzz_match('beth', 'Beth Dakin', 0)
169         self._assert_fuzz_match('bdakin', 'Beth Dakin', 0)
170
171     def integration_test_contributors_brady_eidson(self):
172         self._assert_fuzz_match('Brady', 'Brady Eidson', 0)
173         self._assert_fuzz_match('bradee-oh', 'Brady Eidson', 0)
174         self._assert_fuzz_match('Brady', 'Brady Eidson', 0)
175
176     def integration_test_contributors_cameron_zwarich(self):
177         pass  # self._assert_fuzz_match('Cameron', 'Cameron Zwarich', 0)
178         # self._assert_fuzz_match('cpst', 'Cameron Zwarich', 1)
179
180     def integration_test_contributors_chris_blumenberg(self):
181         # self._assert_fuzz_match('Chris', 'Chris Blumenberg', 0)
182         self._assert_fuzz_match('cblu', 'Chris Blumenberg', 0)
183
184     def integration_test_contributors_dan_bernstein(self):
185         self._assert_fuzz_match('Dan', ['Dan Winship', 'Dan Bernstein'], 0)
186         self._assert_fuzz_match('Dan B', 'Dan Bernstein', 0)
187         # self._assert_fuzz_match('mitz', 'Dan Bernstein', 0)
188         self._assert_fuzz_match('Mitz Pettel', 'Dan Bernstein', 1)
189         self._assert_fuzz_match('Mitzpettel', 'Dan Bernstein', 0)
190         self._assert_fuzz_match('Mitz Pettel RTL', 'Dan Bernstein', 5)
191
192     def integration_test_contributors_dan_bernstein_2(self):
193         self._assert_fuzz_match('Teh Mitzpettel', 'Dan Bernstein', 4)
194         # self._assert_fuzz_match('The Mitz', 'Dan Bernstein', 0)
195         self._assert_fuzz_match('Dr Dan Bernstein', 'Dan Bernstein', 3)
196
197     def integration_test_contributors_darin_adler(self):
198         self._assert_fuzz_match('Darin Adler\'', 'Darin Adler', 1)
199         self._assert_fuzz_match('Darin', 'Darin Adler', 0)  # Thankfully "Fisher" is longer than "Adler"
200         self._assert_fuzz_match('darin', 'Darin Adler', 0)
201
202     def integration_test_contributors_david_harrison(self):
203         self._assert_fuzz_match('Dave Harrison', 'David Harrison', 2)
204         self._assert_fuzz_match('harrison', 'David Harrison', 0)
205         self._assert_fuzz_match('Dr. Harrison', 'David Harrison', 4)
206
207     def integration_test_contributors_david_harrison_2(self):
208         self._assert_fuzz_match('Dave Harrson', 'David Harrison', 3)
209         self._assert_fuzz_match('Dave Harrsion', 'David Harrison', 4)  # Damerau-Levenshtein distance is 3
210
211     def integration_test_contributors_david_hyatt(self):
212         self._assert_fuzz_match('Dave Hyatt', 'David Hyatt', 2)
213         self._assert_fuzz_match('Daddy Hyatt', 'David Hyatt', 3)
214         # self._assert_fuzz_match('Dave', 'David Hyatt', 0)  # 'Dave' could mean harrison.
215         self._assert_fuzz_match('hyatt', 'David Hyatt', 0)
216         # self._assert_fuzz_match('Haytt', 'David Hyatt', 0)  # Works if we had implemented Damerau-Levenshtein distance!
217
218     def integration_test_contributors_david_kilzer(self):
219         self._assert_fuzz_match('Dave Kilzer', 'David Kilzer', 2)
220         self._assert_fuzz_match('David D. Kilzer', 'David Kilzer', 3)
221         self._assert_fuzz_match('ddkilzer', 'David Kilzer', 0)
222
223     def integration_test_contributors_don_melton(self):
224         self._assert_fuzz_match('Don', 'Don Melton', 0)
225         self._assert_fuzz_match('Gramps', 'Don Melton', 0)
226
227     def integration_test_contributors_eric_seidel(self):
228         # self._assert_fuzz_match('eric', 'Eric Seidel', 0)
229         self._assert_fuzz_match('Eric S', 'Eric Seidel', 0)
230         # self._assert_fuzz_match('MacDome', 'Eric Seidel', 0)
231         self._assert_fuzz_match('eseidel', 'Eric Seidel', 0)
232
233     def integration_test_contributors_geoffrey_garen(self):
234         # self._assert_fuzz_match('Geof', 'Geoffrey Garen', 4)
235         # self._assert_fuzz_match('Geoff', 'Geoffrey Garen', 3)
236         self._assert_fuzz_match('Geoff Garen', 'Geoffrey Garen', 3)
237         self._assert_fuzz_match('ggaren', 'Geoffrey Garen', 0)
238         # self._assert_fuzz_match('geoff', 'Geoffrey Garen', 0)
239         self._assert_fuzz_match('Geoffrey', 'Geoffrey Garen', 0)
240         self._assert_fuzz_match('GGaren', 'Geoffrey Garen', 0)
241
242     def integration_test_contributors_greg_bolsinga(self):
243         pass  # self._assert_fuzz_match('Greg', 'Greg Bolsinga', 0)
244
245     def integration_test_contributors_holger_freyther(self):
246         self._assert_fuzz_match('Holger', 'Holger Freyther', 0)
247         self._assert_fuzz_match('Holger Hans Peter Freyther', 'Holger Freyther', 11)
248
249     def integration_test_contributors_jon_sullivan(self):
250         # self._assert_fuzz_match('john', 'John Sullivan', 0)
251         self._assert_fuzz_match('sullivan', 'John Sullivan', 0)
252
253     def integration_test_contributors_jon_honeycutt(self):
254         self._assert_fuzz_match('John Honeycutt', 'Jon Honeycutt', 1)
255         # self._assert_fuzz_match('Jon', 'Jon Honeycutt', 0)
256
257     def integration_test_contributors_jon_honeycutt(self):
258         # self._assert_fuzz_match('justin', 'Justin Garcia', 0)
259         self._assert_fuzz_match('justing', 'Justin Garcia', 0)
260
261     def integration_test_contributors_joseph_pecoraro(self):
262         self._assert_fuzz_match('Joe Pecoraro', 'Joseph Pecoraro', 3)
263
264     def integration_test_contributors_ken_kocienda(self):
265         self._assert_fuzz_match('ken', 'Ken Kocienda', 0)
266         self._assert_fuzz_match('kocienda', 'Ken Kocienda', 0)
267
268     def integration_test_contributors_kenneth_russell(self):
269         self._assert_fuzz_match('Ken Russell', 'Kenneth Russell', 4)
270
271     def integration_test_contributors_kevin_decker(self):
272         self._assert_fuzz_match('kdecker', 'Kevin Decker', 0)
273
274     def integration_test_contributors_kevin_mccullough(self):
275         self._assert_fuzz_match('Kevin M', 'Kevin McCullough', 0)
276         self._assert_fuzz_match('Kevin McCulough', 'Kevin McCullough', 1)
277         self._assert_fuzz_match('mccullough', 'Kevin McCullough', 0)
278
279     def integration_test_contributors_lars_knoll(self):
280         self._assert_fuzz_match('lars', 'Lars Knoll', 0)
281
282     def integration_test_contributors_lars_weintraub(self):
283         self._assert_fuzz_match('levi', 'Levi Weintraub', 0)
284
285     def integration_test_contributors_maciej_stachowiak(self):
286         self._assert_fuzz_match('Maciej', 'Maciej Stachowiak', 0)
287         # self._assert_fuzz_match('mjs', 'Maciej Stachowiak', 0)
288         self._assert_fuzz_match('Maciej S', 'Maciej Stachowiak', 0)
289
290     def integration_test_contributors_mark_rowe(self):
291         # self._assert_fuzz_match('Mark', 'Mark Rowe', 0)
292         self._assert_fuzz_match('bdash', 'Mark Rowe', 0)
293         self._assert_fuzz_match('mrowe', 'Mark Rowe', 0)
294         # self._assert_fuzz_match('Brian Dash', 'Mark Rowe', 0)
295
296     def integration_test_contributors_nikolas_zimmermann(self):
297         # self._assert_fuzz_match('Niko', 'Nikolas Zimmermann', 1)
298         self._assert_fuzz_match('Niko Zimmermann', 'Nikolas Zimmermann', 3)
299         self._assert_fuzz_match('Nikolas', 'Nikolas Zimmermann', 0)
300
301     def integration_test_contributors_oliver_hunt(self):
302         #  self._assert_fuzz_match('Oliver', 'Oliver Hunt', 0)
303         self._assert_fuzz_match('Ollie', 'Oliver Hunt', 1)
304         self._assert_fuzz_match('Olliej', 'Oliver Hunt', 0)
305         self._assert_fuzz_match('Olliej Hunt', 'Oliver Hunt', 3)
306         self._assert_fuzz_match('olliej', 'Oliver Hunt', 0)
307         self._assert_fuzz_match('ollie', 'Oliver Hunt', 1)
308         self._assert_fuzz_match('ollliej', 'Oliver Hunt', 1)
309
310     def integration_test_contributors_oliver_hunt(self):
311         self._assert_fuzz_match('Richard', 'Richard Williamson', 0)
312         self._assert_fuzz_match('rjw', 'Richard Williamson', 0)
313
314     def integration_test_contributors_oliver_hunt(self):
315         self._assert_fuzz_match('Rob', 'Rob Buis', 0)
316         self._assert_fuzz_match('rwlbuis', 'Rob Buis', 0)
317
318     def integration_test_contributors_rniwa(self):
319         self._assert_fuzz_match('rniwa@webkit.org', 'Ryosuke Niwa', 0)
320
321     def disabled_integration_test_contributors_simon_fraser(self):
322         pass  # self._assert_fuzz_match('Simon', 'Simon Fraser', 0)
323
324     def integration_test_contributors_steve_falkenburg(self):
325         self._assert_fuzz_match('Sfalken', 'Steve Falkenburg', 0)
326         # self._assert_fuzz_match('Steve', 'Steve Falkenburg', 0)
327
328     def integration_test_contributors_sam_weinig(self):
329         self._assert_fuzz_match('Sam', 'Sam Weinig', 0)
330         # self._assert_fuzz_match('Weinig Sam', 'weinig', 0)
331         self._assert_fuzz_match('Weinig', 'Sam Weinig', 0)
332         self._assert_fuzz_match('Sam W', 'Sam Weinig', 0)
333         self._assert_fuzz_match('Sammy Weinig', 'Sam Weinig', 2)
334
335     def integration_test_contributors_tim_omernick(self):
336         # self._assert_fuzz_match('timo', 'Tim Omernick', 0)
337         self._assert_fuzz_match('TimO', 'Tim Omernick', 0)
338         # self._assert_fuzz_match('Timo O', 'Tim Omernick', 0)
339         # self._assert_fuzz_match('Tim O.', 'Tim Omernick', 0)
340         self._assert_fuzz_match('Tim O', 'Tim Omernick', 0)
341
342     def integration_test_contributors_timothy_hatcher(self):
343         # self._assert_fuzz_match('Tim', 'Timothy Hatcher', 0)
344         # self._assert_fuzz_match('Tim H', 'Timothy Hatcher', 0)
345         self._assert_fuzz_match('Tim Hatcher', 'Timothy Hatcher', 4)
346         self._assert_fuzz_match('Tim Hatcheri', 'Timothy Hatcher', 5)
347         self._assert_fuzz_match('timothy', 'Timothy Hatcher', 0)
348         self._assert_fuzz_match('thatcher', 'Timothy Hatcher', 1)
349         self._assert_fuzz_match('xenon', 'Timothy Hatcher', 0)
350         self._assert_fuzz_match('Hatcher', 'Timothy Hatcher', 0)
351         # self._assert_fuzz_match('TimH', 'Timothy Hatcher', 0)
352
353     def integration_test_contributors_tor_arne_vestbo(self):
354         self._assert_fuzz_match('Tor Arne', u"Tor Arne Vestb\u00f8", 1)  # Matches IRC nickname
355
356     def integration_test_contributors_vicki_murley(self):
357         self._assert_fuzz_match('Vicki', u"Vicki Murley", 0)
358
359     def integration_test_contributors_zack_rusin(self):
360         self._assert_fuzz_match('Zack', 'Zack Rusin', 0)