| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 """Unit tests for git_cl.py.""" | 6 """Unit tests for git_cl.py.""" |
| 7 | 7 |
| 8 import os | 8 import os |
| 9 import StringIO | 9 import StringIO |
| 10 import stat | 10 import stat |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 def __init__(self, *args, **kwargs): | 23 def __init__(self, *args, **kwargs): |
| 24 self.reviewers = [] | 24 self.reviewers = [] |
| 25 @staticmethod | 25 @staticmethod |
| 26 def should_continue(): | 26 def should_continue(): |
| 27 return True | 27 return True |
| 28 | 28 |
| 29 | 29 |
| 30 class RietveldMock(object): | 30 class RietveldMock(object): |
| 31 def __init__(self, *args, **kwargs): | 31 def __init__(self, *args, **kwargs): |
| 32 pass | 32 pass |
| 33 |
| 33 @staticmethod | 34 @staticmethod |
| 34 def get_description(issue): | 35 def get_description(issue): |
| 35 return 'Issue: %d' % issue | 36 return 'Issue: %d' % issue |
| 36 | 37 |
| 38 @staticmethod |
| 39 def get_issue_properties(_issue, _messages): |
| 40 return { |
| 41 'reviewers': ['joe@chromium.org', 'john@chromium.org'], |
| 42 'messages': [ |
| 43 { |
| 44 'approval': True, |
| 45 'sender': 'john@chromium.org', |
| 46 }, |
| 47 ], |
| 48 } |
| 49 |
| 37 | 50 |
| 38 class WatchlistsMock(object): | 51 class WatchlistsMock(object): |
| 39 def __init__(self, _): | 52 def __init__(self, _): |
| 40 pass | 53 pass |
| 41 @staticmethod | 54 @staticmethod |
| 42 def GetWatchersForPaths(_): | 55 def GetWatchersForPaths(_): |
| 43 return ['joe@example.com'] | 56 return ['joe@example.com'] |
| 44 | 57 |
| 45 | 58 |
| 46 class CodereviewSettingsFileMock(object): | 59 class CodereviewSettingsFileMock(object): |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 264 ((['git', 'show-ref', '--quiet', '--verify', | 277 ((['git', 'show-ref', '--quiet', '--verify', |
| 265 'refs/heads/git-cl-commit'],), | 278 'refs/heads/git-cl-commit'],), |
| 266 (('', None), 0)), | 279 (('', None), 0)), |
| 267 ((['git', 'branch', '-D', 'git-cl-commit'],), ''), | 280 ((['git', 'branch', '-D', 'git-cl-commit'],), ''), |
| 268 ((['git', 'show-ref', '--quiet', '--verify', | 281 ((['git', 'show-ref', '--quiet', '--verify', |
| 269 'refs/heads/git-cl-cherry-pick'],), ''), | 282 'refs/heads/git-cl-cherry-pick'],), ''), |
| 270 ((['git', 'rev-parse', '--show-cdup'],), '\n'), | 283 ((['git', 'rev-parse', '--show-cdup'],), '\n'), |
| 271 ((['git', 'checkout', '-q', '-b', 'git-cl-commit'],), ''), | 284 ((['git', 'checkout', '-q', '-b', 'git-cl-commit'],), ''), |
| 272 ((['git', 'reset', '--soft', 'fake_ancestor_sha'],), ''), | 285 ((['git', 'reset', '--soft', 'fake_ancestor_sha'],), ''), |
| 273 ((['git', 'commit', '-m', | 286 ((['git', 'commit', '-m', |
| 274 'Issue: 12345\n\nReview URL: https://codereview.example.com/12345'],), | 287 'Issue: 12345\n\n' |
| 288 'Review URL: https://codereview.example.com/12345'],), |
| 275 ''), | 289 ''), |
| 276 ((['git', 'svn', 'dcommit', '-C50', '--no-rebase', '--rmdir'],), | 290 ((['git', 'svn', 'dcommit', '-C50', '--no-rebase', '--rmdir'],), |
| 277 (('', None), 0)), | 291 (('', None), 0)), |
| 278 ((['git', 'checkout', '-q', 'working'],), ''), | 292 ((['git', 'checkout', '-q', 'working'],), ''), |
| 279 ((['git', 'branch', '-D', 'git-cl-commit'],), ''), | 293 ((['git', 'branch', '-D', 'git-cl-commit'],), ''), |
| 280 ] | 294 ] |
| 281 | 295 |
| 282 @staticmethod | 296 @staticmethod |
| 283 def _cmd_line(description, args, similarity, find_copies): | 297 def _cmd_line(description, args, similarity, find_copies): |
| 284 """Returns the upload command line passed to upload.RealMain().""" | 298 """Returns the upload command line passed to upload.RealMain().""" |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 327 cmd_line = self._cmd_line(final_description, reviewers, similarity, | 341 cmd_line = self._cmd_line(final_description, reviewers, similarity, |
| 328 find_copies) | 342 find_copies) |
| 329 self.assertEquals(cmd_line, args) | 343 self.assertEquals(cmd_line, args) |
| 330 return 1, 2 | 344 return 1, 2 |
| 331 self.mock(git_cl.upload, 'RealMain', check_upload) | 345 self.mock(git_cl.upload, 'RealMain', check_upload) |
| 332 git_cl.main(['upload'] + upload_args) | 346 git_cl.main(['upload'] + upload_args) |
| 333 | 347 |
| 334 def test_no_reviewer(self): | 348 def test_no_reviewer(self): |
| 335 self._run_reviewer_test( | 349 self._run_reviewer_test( |
| 336 [], | 350 [], |
| 337 'desc\n\nBUG=\n', | 351 'desc\n\nBUG=', |
| 338 '# Blah blah comment.\ndesc\n\nBUG=\n', | 352 '# Blah blah comment.\ndesc\n\nBUG=', |
| 339 'desc\n\nBUG=\n', | 353 'desc\n\nBUG=', |
| 340 []) | 354 []) |
| 341 | 355 |
| 342 def test_keep_similarity(self): | 356 def test_keep_similarity(self): |
| 343 self._run_reviewer_test( | 357 self._run_reviewer_test( |
| 344 ['--similarity', '70'], | 358 ['--similarity', '70'], |
| 345 'desc\n\nBUG=\n', | 359 'desc\n\nBUG=', |
| 346 '# Blah blah comment.\ndesc\n\nBUG=\n', | 360 '# Blah blah comment.\ndesc\n\nBUG=', |
| 347 'desc\n\nBUG=\n', | 361 'desc\n\nBUG=', |
| 348 []) | 362 []) |
| 349 | 363 |
| 350 def test_keep_find_copies(self): | 364 def test_keep_find_copies(self): |
| 351 self._run_reviewer_test( | 365 self._run_reviewer_test( |
| 352 ['--no-find-copies'], | 366 ['--no-find-copies'], |
| 353 'desc\n\nBUG=\n', | 367 'desc\n\nBUG=', |
| 354 '# Blah blah comment.\ndesc\n\nBUG=\n', | 368 '# Blah blah comment.\ndesc\n\nBUG=\n', |
| 355 'desc\n\nBUG=\n', | 369 'desc\n\nBUG=', |
| 356 []) | 370 []) |
| 357 | 371 |
| 358 def test_reviewers_cmd_line(self): | 372 def test_reviewers_cmd_line(self): |
| 359 # Reviewer is passed as-is | 373 # Reviewer is passed as-is |
| 360 description = 'desc\n\nR=foo@example.com\nBUG=\n' | 374 description = 'desc\n\nR=foo@example.com\nBUG=' |
| 361 self._run_reviewer_test( | 375 self._run_reviewer_test( |
| 362 ['-r' 'foo@example.com'], | 376 ['-r' 'foo@example.com'], |
| 363 description, | 377 description, |
| 364 '\n%s\n' % description, | 378 '\n%s\n' % description, |
| 365 description, | 379 description, |
| 366 ['--reviewers', 'foo@example.com']) | 380 ['--reviewers=foo@example.com']) |
| 367 | 381 |
| 368 def test_reviewer_tbr_overriden(self): | 382 def test_reviewer_tbr_overriden(self): |
| 369 # Reviewer is overriden with TBR | 383 # Reviewer is overriden with TBR |
| 370 # Also verifies the regexp work without a trailing LF | 384 # Also verifies the regexp work without a trailing LF |
| 371 description = 'Foo Bar\nTBR=reviewer@example.com\n' | 385 description = 'Foo Bar\n\nTBR=reviewer@example.com' |
| 372 self._run_reviewer_test( | 386 self._run_reviewer_test( |
| 373 ['-r' 'foo@example.com'], | 387 ['-r' 'foo@example.com'], |
| 374 'desc\n\nR=foo@example.com\nBUG=\n', | 388 'desc\n\nR=foo@example.com\nBUG=', |
| 375 description.strip('\n'), | 389 description.strip('\n'), |
| 376 description, | 390 description, |
| 377 ['--reviewers', 'reviewer@example.com']) | 391 ['--reviewers=reviewer@example.com']) |
| 378 | 392 |
| 379 def test_reviewer_multiple(self): | 393 def test_reviewer_multiple(self): |
| 380 # Handles multiple R= or TBR= lines. | 394 # Handles multiple R= or TBR= lines. |
| 381 description = ( | 395 description = ( |
| 382 'Foo Bar\nTBR=reviewer@example.com\nBUG=\nR=another@example.com\n') | 396 'Foo Bar\nTBR=reviewer@example.com\nBUG=\nR=another@example.com') |
| 383 self._run_reviewer_test( | 397 self._run_reviewer_test( |
| 384 [], | 398 [], |
| 385 'desc\n\nBUG=\n', | 399 'desc\n\nBUG=', |
| 386 description, | 400 description, |
| 387 description, | 401 description, |
| 388 ['--reviewers', 'reviewer@example.com,another@example.com']) | 402 ['--reviewers=another@example.com,reviewer@example.com']) |
| 389 | 403 |
| 390 def test_reviewer_send_mail(self): | 404 def test_reviewer_send_mail(self): |
| 391 # --send-mail can be used without -r if R= is used | 405 # --send-mail can be used without -r if R= is used |
| 392 description = 'Foo Bar\nR=reviewer@example.com\n' | 406 description = 'Foo Bar\nR=reviewer@example.com' |
| 393 self._run_reviewer_test( | 407 self._run_reviewer_test( |
| 394 ['--send-mail'], | 408 ['--send-mail'], |
| 395 'desc\n\nBUG=\n', | 409 'desc\n\nBUG=', |
| 396 description.strip('\n'), | 410 description.strip('\n'), |
| 397 description, | 411 description, |
| 398 ['--reviewers', 'reviewer@example.com', '--send_mail']) | 412 ['--reviewers=reviewer@example.com', '--send_mail']) |
| 399 | 413 |
| 400 def test_reviewer_send_mail_no_rev(self): | 414 def test_reviewer_send_mail_no_rev(self): |
| 401 # Fails without a reviewer. | 415 # Fails without a reviewer. |
| 402 class FileMock(object): | 416 class FileMock(object): |
| 403 buf = StringIO.StringIO() | 417 buf = StringIO.StringIO() |
| 404 def write(self, content): | 418 def write(self, content): |
| 405 self.buf.write(content) | 419 self.buf.write(content) |
| 406 | 420 |
| 407 mock = FileMock() | 421 mock = FileMock() |
| 408 try: | 422 try: |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 483 'fake_ancestor_sha..HEAD'],), | 497 'fake_ancestor_sha..HEAD'],), |
| 484 description) | 498 description) |
| 485 ] | 499 ] |
| 486 calls += [ | 500 calls += [ |
| 487 ((['git', 'config', 'rietveld.cc'],), '') | 501 ((['git', 'config', 'rietveld.cc'],), '') |
| 488 ] | 502 ] |
| 489 receive_pack = '--receive-pack=git receive-pack ' | 503 receive_pack = '--receive-pack=git receive-pack ' |
| 490 receive_pack += '--cc=joe@example.com' # from watch list | 504 receive_pack += '--cc=joe@example.com' # from watch list |
| 491 if reviewers: | 505 if reviewers: |
| 492 receive_pack += ' ' | 506 receive_pack += ' ' |
| 493 receive_pack += ' '.join(['--reviewer=' + email for email in reviewers]) | 507 receive_pack += ' '.join( |
| 508 '--reviewer=' + email for email in sorted(reviewers)) |
| 494 receive_pack += '' | 509 receive_pack += '' |
| 495 calls += [ | 510 calls += [ |
| 496 ((['git', 'push', receive_pack, 'origin', 'HEAD:refs/for/master'],), | 511 ((['git', 'push', receive_pack, 'origin', 'HEAD:refs/for/master'],), |
| 497 '') | 512 '') |
| 498 ] | 513 ] |
| 499 return calls | 514 return calls |
| 500 | 515 |
| 501 def _run_gerrit_upload_test( | 516 def _run_gerrit_upload_test( |
| 502 self, | 517 self, |
| 503 upload_args, | 518 upload_args, |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 583 (('CC list:',), ''), | 598 (('CC list:',), ''), |
| 584 ((['git', 'config', 'rietveld.tree-status-url'],), ''), | 599 ((['git', 'config', 'rietveld.tree-status-url'],), ''), |
| 585 (('Tree status URL:',), ''), | 600 (('Tree status URL:',), ''), |
| 586 ((['git', 'config', 'rietveld.viewvc-url'],), ''), | 601 ((['git', 'config', 'rietveld.viewvc-url'],), ''), |
| 587 (('ViewVC URL:',), ''), | 602 (('ViewVC URL:',), ''), |
| 588 # DownloadHooks(True) | 603 # DownloadHooks(True) |
| 589 ((commit_msg_path, os.X_OK,), True), | 604 ((commit_msg_path, os.X_OK,), True), |
| 590 ] | 605 ] |
| 591 git_cl.main(['config']) | 606 git_cl.main(['config']) |
| 592 | 607 |
| 608 def test_update_reviewers(self): |
| 609 data = [ |
| 610 ('foo', '', 'foo'), |
| 611 ('foo', 'a@c', 'foo\n\nR=a@c'), |
| 612 ('foo\nBUG=', 'a@c', 'foo\nBUG=\nR=a@c'), |
| 613 ('foo\nR=xx\nTBR=yy\nR=bar', 'a@c', 'foo\nTBR=a@c'), |
| 614 ] |
| 615 for orig, reviewers, expected in data: |
| 616 obj = git_cl.ChangeDescription(orig) |
| 617 obj.update_reviewers(reviewers) |
| 618 self.assertEqual(expected, obj.description) |
| 619 |
| 593 | 620 |
| 594 if __name__ == '__main__': | 621 if __name__ == '__main__': |
| 622 git_cl.logging.basicConfig( |
| 623 level=git_cl.logging.DEBUG if '-v' in sys.argv else git_cl.logging.ERROR) |
| 595 unittest.main() | 624 unittest.main() |
| OLD | NEW |