Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(227)

Side by Side Diff: tests/presubmit_unittest.py

Issue 15898005: presubmit: Call 'git diff' once per change instead of once per file (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/depot_tools.git@master
Patch Set: Fix language in git_cl.py Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « presubmit_support.py ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 presubmit_support.py and presubmit_canned_checks.py.""" 6 """Unit tests for presubmit_support.py and presubmit_canned_checks.py."""
7 7
8 # pylint: disable=E1101,E1103 8 # pylint: disable=E1101,E1103
9 9
10 import logging 10 import logging
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
140 # SuperMoxTestBase already mock these but simplify our life. 140 # SuperMoxTestBase already mock these but simplify our life.
141 presubmit.os.path.abspath = MockAbsPath 141 presubmit.os.path.abspath = MockAbsPath
142 presubmit.os.getcwd = self.RootDir 142 presubmit.os.getcwd = self.RootDir
143 presubmit.os.chdir = MockChdir 143 presubmit.os.chdir = MockChdir
144 self.mox.StubOutWithMock(presubmit.scm, 'determine_scm') 144 self.mox.StubOutWithMock(presubmit.scm, 'determine_scm')
145 self.mox.StubOutWithMock(presubmit.scm.SVN, '_CaptureInfo') 145 self.mox.StubOutWithMock(presubmit.scm.SVN, '_CaptureInfo')
146 self.mox.StubOutWithMock(presubmit.scm.SVN, 'GetFileProperty') 146 self.mox.StubOutWithMock(presubmit.scm.SVN, 'GetFileProperty')
147 self.mox.StubOutWithMock(presubmit.gclient_utils, 'FileRead') 147 self.mox.StubOutWithMock(presubmit.gclient_utils, 'FileRead')
148 self.mox.StubOutWithMock(presubmit.gclient_utils, 'FileWrite') 148 self.mox.StubOutWithMock(presubmit.gclient_utils, 'FileWrite')
149 self.mox.StubOutWithMock(presubmit.scm.SVN, 'GenerateDiff') 149 self.mox.StubOutWithMock(presubmit.scm.SVN, 'GenerateDiff')
150 self.mox.StubOutWithMock(presubmit.scm.GIT, 'GenerateDiff')
150 151
151 152
152 class PresubmitUnittest(PresubmitTestsBase): 153 class PresubmitUnittest(PresubmitTestsBase):
153 """General presubmit_support.py tests (excluding InputApi and OutputApi).""" 154 """General presubmit_support.py tests (excluding InputApi and OutputApi)."""
154 155
155 _INHERIT_SETTINGS = 'inherit-review-settings-ok' 156 _INHERIT_SETTINGS = 'inherit-review-settings-ok'
156 157
157 def testMembersChanged(self): 158 def testMembersChanged(self):
158 self.mox.ReplayAll() 159 self.mox.ReplayAll()
159 members = [ 160 members = [
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
378 self.assertEquals(rhs_lines[8][2], 'this is line number 23.1') 379 self.assertEquals(rhs_lines[8][2], 'this is line number 23.1')
379 380
380 self.assertEquals(rhs_lines[12][0].LocalPath(), files[3][1]) 381 self.assertEquals(rhs_lines[12][0].LocalPath(), files[3][1])
381 self.assertEquals(rhs_lines[12][1], 46) 382 self.assertEquals(rhs_lines[12][1], 46)
382 self.assertEquals(rhs_lines[12][2], '') 383 self.assertEquals(rhs_lines[12][2], '')
383 384
384 self.assertEquals(rhs_lines[13][0].LocalPath(), files[3][1]) 385 self.assertEquals(rhs_lines[13][0].LocalPath(), files[3][1])
385 self.assertEquals(rhs_lines[13][1], 49) 386 self.assertEquals(rhs_lines[13][1], 49)
386 self.assertEquals(rhs_lines[13][2], 'this is line number 48.1') 387 self.assertEquals(rhs_lines[13][2], 'this is line number 48.1')
387 388
389 def testGitChange(self):
390 description_lines = ('Hello there',
391 'this is a change',
392 'BUG=123',
393 ' STORY =http://foo/ \t',
394 'and some more regular text \t')
395 unified_diff = [
396 'diff --git binary_a.png binary_a.png',
397 'new file mode 100644',
398 'index 0000000..6fbdd6d',
399 'Binary files /dev/null and binary_a.png differ',
400 'diff --git binary_d.png binary_d.png',
401 'deleted file mode 100644',
402 'index 6fbdd6d..0000000',
403 'Binary files binary_d.png and /dev/null differ',
404 'diff --git binary_md.png binary_md.png',
405 'index 6fbdd6..be3d5d8 100644',
406 'GIT binary patch',
407 'delta 109',
408 'zcmeyihjs5>)(Opwi4&WXB~yyi6N|G`(i5|?i<2_a@)OH5N{Um`D-<SM@g!_^W9;SR',
409 'zO9b*W5{pxTM0slZ=F42indK9U^MTyVQlJ2s%1BMmEKMv1Q^gtS&9nHn&*Ede;|~CU',
410 'CMJxLN',
411 '',
412 'delta 34',
413 'scmV+-0Nww+y#@BX1(1W0gkzIp3}CZh0gVZ>`wGVcgW(Rh;SK@ZPa9GXlK=n!',
414 '',
415 'diff --git binary_m.png binary_m.png',
416 'index 6fbdd6d..be3d5d8 100644',
417 'Binary files binary_m.png and binary_m.png differ',
418 'diff --git boo/blat.cc boo/blat.cc',
419 'new file mode 100644',
420 'index 0000000..37d18ad',
421 '--- boo/blat.cc',
422 '+++ boo/blat.cc',
423 '@@ -0,0 +1,5 @@',
424 '+This is some text',
425 '+which lacks a copyright warning',
426 '+but it is nonetheless interesting',
427 '+and worthy of your attention.',
428 '+Its freshness factor is through the roof.',
429 'diff --git floo/delburt.cc floo/delburt.cc',
430 'deleted file mode 100644',
431 'index e06377a..0000000',
432 '--- floo/delburt.cc',
433 '+++ /dev/null',
434 '@@ -1,14 +0,0 @@',
435 '-This text used to be here',
436 '-but someone, probably you,',
437 '-having consumed the text',
438 '- (absorbed its meaning)',
439 '-decided that it should be made to not exist',
440 '-that others would not read it.',
441 '- (What happened here?',
442 '-was the author incompetent?',
443 '-or is the world today so different from the world',
444 '- the author foresaw',
445 '-and past imaginination',
446 '- amounts to rubble, insignificant,',
447 '-something to be tripped over',
448 '-and frustrated by)',
449 'diff --git foo/TestExpectations foo/TestExpectations',
450 'index c6e12ab..d1c5f23 100644',
451 '--- foo/TestExpectations',
452 '+++ foo/TestExpectations',
453 '@@ -1,12 +1,24 @@',
454 '-Stranger, behold:',
455 '+Strange to behold:',
456 ' This is a text',
457 ' Its contents existed before.',
458 '',
459 '-It is written:',
460 '+Weasel words suggest:',
461 ' its contents shall exist after',
462 ' and its contents',
463 ' with the progress of time',
464 ' will evolve,',
465 '- snaillike,',
466 '+ erratically,',
467 ' into still different texts',
468 '-from this.',
469 '\ No newline at end of file',
470 '+from this.',
471 '+',
472 '+For the most part,',
473 '+I really think unified diffs',
474 '+are elegant: the way you can type',
475 '+diff --git inside/a/text inside/a/text',
476 '+or something silly like',
477 '+@@ -278,6 +278,10 @@',
478 '+and have this not be interpreted',
479 '+as the start of a new file',
480 '+or anything messed up like that,',
481 '+because you parsed the header',
482 '+correctly.',
483 '\ No newline at end of file',
484 '']
485 files = [('A ', 'binary_a.png'),
486 ('D ', 'binary_d.png'),
487 ('M ', 'binary_m.png'),
488 ('M ', 'binary_md.png'), # Binary w/ diff
489 ('A ', 'boo/blat.cc'),
490 ('D ', 'floo/delburt.cc'),
491 ('M ', 'foo/TestExpectations')]
492
493 for op, path in files:
494 full_path = presubmit.os.path.join(self.fake_root_dir, *path.split('/'))
495 if op.startswith('D'):
496 os.path.exists(full_path).AndReturn(False)
497 else:
498 os.path.exists(full_path).AndReturn(False)
499 os.path.isfile(full_path).AndReturn(True)
500
501 presubmit.scm.GIT.GenerateDiff(self.fake_root_dir, files=[], full_move=True
502 ).AndReturn('\n'.join(unified_diff))
503
504 self.mox.ReplayAll()
505
506 change = presubmit.GitChange(
507 'mychange',
508 '\n'.join(description_lines),
509 self.fake_root_dir,
510 files,
511 0,
512 0,
513 None)
514 self.failUnless(change.Name() == 'mychange')
515 self.failUnless(change.DescriptionText() ==
516 'Hello there\nthis is a change\nand some more regular text')
517 self.failUnless(change.FullDescriptionText() ==
518 '\n'.join(description_lines))
519
520 self.failUnless(change.BUG == '123')
521 self.failUnless(change.STORY == 'http://foo/')
522 self.failUnless(change.BLEH == None)
523
524 self.failUnless(len(change.AffectedFiles()) == 7)
525 self.failUnless(len(change.AffectedFiles(include_dirs=True)) == 7)
526 self.failUnless(len(change.AffectedFiles(include_deletes=False)) == 5)
527 self.failUnless(len(change.AffectedFiles(include_dirs=True,
528 include_deletes=False)) == 5)
529
530 # Note that on git, there's no distinction between binary files and text
531 # files; everything that's not a delete is a text file.
532 affected_text_files = change.AffectedTextFiles()
533 self.failUnless(len(affected_text_files) == 5)
534
535 local_paths = change.LocalPaths()
536 expected_paths = [os.path.normpath(f) for op, f in files]
537 self.assertEqual(local_paths, expected_paths)
538
539 try:
540 _ = change.ServerPaths()
541 self.fail("ServerPaths implemented.")
542 except NotImplementedError:
543 pass
544
545 actual_rhs_lines = []
546 for f, linenum, line in change.RightHandSideLines():
547 actual_rhs_lines.append((f.LocalPath(), linenum, line))
548
549 f_blat = os.path.normpath('boo/blat.cc')
550 f_test_expectations = os.path.normpath('foo/TestExpectations')
551 expected_rhs_lines = [
552 (f_blat, 1, 'This is some text'),
553 (f_blat, 2, 'which lacks a copyright warning'),
554 (f_blat, 3, 'but it is nonetheless interesting'),
555 (f_blat, 4, 'and worthy of your attention.'),
556 (f_blat, 5, 'Its freshness factor is through the roof.'),
557 (f_test_expectations, 1, 'Strange to behold:'),
558 (f_test_expectations, 5, 'Weasel words suggest:'),
559 (f_test_expectations, 10, ' erratically,'),
560 (f_test_expectations, 13, 'from this.'),
561 (f_test_expectations, 14, ''),
562 (f_test_expectations, 15, 'For the most part,'),
563 (f_test_expectations, 16, 'I really think unified diffs'),
564 (f_test_expectations, 17, 'are elegant: the way you can type'),
565 (f_test_expectations, 18, 'diff --git inside/a/text inside/a/text'),
566 (f_test_expectations, 19, 'or something silly like'),
567 (f_test_expectations, 20, '@@ -278,6 +278,10 @@'),
568 (f_test_expectations, 21, 'and have this not be interpreted'),
569 (f_test_expectations, 22, 'as the start of a new file'),
570 (f_test_expectations, 23, 'or anything messed up like that,'),
571 (f_test_expectations, 24, 'because you parsed the header'),
572 (f_test_expectations, 25, 'correctly.')]
573
574 self.assertEquals(expected_rhs_lines, actual_rhs_lines)
575
388 def testInvalidChange(self): 576 def testInvalidChange(self):
389 try: 577 try:
390 presubmit.SvnChange( 578 presubmit.SvnChange(
391 'mychange', 579 'mychange',
392 'description', 580 'description',
393 self.fake_root_dir, 581 self.fake_root_dir,
394 ['foo/blat.cc', 'bar'], 582 ['foo/blat.cc', 'bar'],
395 0, 583 0,
396 0, 584 0,
397 None) 585 None)
(...skipping 846 matching lines...) Expand 10 before | Expand all | Expand 10 after
1244 self.mox.ReplayAll() 1432 self.mox.ReplayAll()
1245 1433
1246 change = presubmit.Change( 1434 change = presubmit.Change(
1247 'foo', 'foo', self.fake_root_dir, [('M', 'AA')], 0, 0, None) 1435 'foo', 'foo', self.fake_root_dir, [('M', 'AA')], 0, 0, None)
1248 input_api = presubmit.InputApi( 1436 input_api = presubmit.InputApi(
1249 change, presubmit.os.path.join(self.fake_root_dir, '/p'), False, 1437 change, presubmit.os.path.join(self.fake_root_dir, '/p'), False,
1250 None, False) 1438 None, False)
1251 input_api.ReadFile(path, 'x') 1439 input_api.ReadFile(path, 'x')
1252 1440
1253 def testReadFileAffectedFileDenied(self): 1441 def testReadFileAffectedFileDenied(self):
1254 fileobj = presubmit.AffectedFile('boo', 'M', 'Unrelated') 1442 fileobj = presubmit.AffectedFile('boo', 'M', 'Unrelated',
1443 diff_cache=mox.IsA(presubmit._DiffCache))
1255 self.mox.ReplayAll() 1444 self.mox.ReplayAll()
1256 1445
1257 change = presubmit.Change( 1446 change = presubmit.Change(
1258 'foo', 'foo', self.fake_root_dir, [('M', 'AA')], 0, 0, None) 1447 'foo', 'foo', self.fake_root_dir, [('M', 'AA')], 0, 0, None)
1259 input_api = presubmit.InputApi( 1448 input_api = presubmit.InputApi(
1260 change, presubmit.os.path.join(self.fake_root_dir, '/p'), False, 1449 change, presubmit.os.path.join(self.fake_root_dir, '/p'), False,
1261 None, False) 1450 None, False)
1262 self.assertRaises(IOError, input_api.ReadFile, fileobj, 'x') 1451 self.assertRaises(IOError, input_api.ReadFile, fileobj, 'x')
1263 1452
1264 def testReadFileAffectedFileAccepted(self): 1453 def testReadFileAffectedFileAccepted(self):
1265 fileobj = presubmit.AffectedFile('AA/boo', 'M', self.fake_root_dir) 1454 fileobj = presubmit.AffectedFile('AA/boo', 'M', self.fake_root_dir,
1455 diff_cache=mox.IsA(presubmit._DiffCache))
1266 presubmit.gclient_utils.FileRead(fileobj.AbsoluteLocalPath(), 'x' 1456 presubmit.gclient_utils.FileRead(fileobj.AbsoluteLocalPath(), 'x'
1267 ).AndReturn(None) 1457 ).AndReturn(None)
1268 self.mox.ReplayAll() 1458 self.mox.ReplayAll()
1269 1459
1270 change = presubmit.Change( 1460 change = presubmit.Change(
1271 'foo', 'foo', self.fake_root_dir, [('M', 'AA')], 0, 0, None) 1461 'foo', 'foo', self.fake_root_dir, [('M', 'AA')], 0, 0, None)
1272 input_api = presubmit.InputApi( 1462 input_api = presubmit.InputApi(
1273 change, presubmit.os.path.join(self.fake_root_dir, '/p'), False, 1463 change, presubmit.os.path.join(self.fake_root_dir, '/p'), False,
1274 None, False) 1464 None, False)
1275 input_api.ReadFile(fileobj, 'x') 1465 input_api.ReadFile(fileobj, 'x')
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
1351 self.failUnless(output.should_continue()) 1541 self.failUnless(output.should_continue())
1352 self.failUnless(output.getvalue().count('???')) 1542 self.failUnless(output.getvalue().count('???'))
1353 1543
1354 output_api = presubmit.OutputApi(True) 1544 output_api = presubmit.OutputApi(True)
1355 output = presubmit.PresubmitOutput(input_stream=StringIO.StringIO('\n')) 1545 output = presubmit.PresubmitOutput(input_stream=StringIO.StringIO('\n'))
1356 output_api.PresubmitPromptOrNotify('???').handle(output) 1546 output_api.PresubmitPromptOrNotify('???').handle(output)
1357 output.prompt_yes_no('prompt: ') 1547 output.prompt_yes_no('prompt: ')
1358 self.failIf(output.should_continue()) 1548 self.failIf(output.should_continue())
1359 self.failUnless(output.getvalue().count('???')) 1549 self.failUnless(output.getvalue().count('???'))
1360 1550
1551
1361 class AffectedFileUnittest(PresubmitTestsBase): 1552 class AffectedFileUnittest(PresubmitTestsBase):
1362 def testMembersChanged(self): 1553 def testMembersChanged(self):
1363 self.mox.ReplayAll() 1554 self.mox.ReplayAll()
1364 members = [ 1555 members = [
1365 'AbsoluteLocalPath', 'Action', 'ChangedContents', 'GenerateScmDiff', 1556 'AbsoluteLocalPath', 'Action', 'ChangedContents', 'DIFF_CACHE',
1366 'IsDirectory', 'IsTextFile', 'LocalPath', 'NewContents', 'OldContents', 1557 'GenerateScmDiff', 'IsDirectory', 'IsTextFile', 'LocalPath',
1367 'OldFileTempPath', 'Property', 'ServerPath', 1558 'NewContents', 'Property', 'ServerPath',
1368 ] 1559 ]
1369 # If this test fails, you should add the relevant test. 1560 # If this test fails, you should add the relevant test.
1370 self.compareMembers( 1561 self.compareMembers(
1371 presubmit.AffectedFile('a', 'b', self.fake_root_dir), members) 1562 presubmit.AffectedFile('a', 'b', self.fake_root_dir), members)
1372 self.compareMembers( 1563 self.compareMembers(
1373 presubmit.SvnAffectedFile('a', 'b', self.fake_root_dir), members) 1564 presubmit.SvnAffectedFile('a', 'b', self.fake_root_dir), members)
1565 self.compareMembers(
1566 presubmit.GitAffectedFile('a', 'b', self.fake_root_dir), members)
1374 1567
1375 def testAffectedFile(self): 1568 def testAffectedFile(self):
1376 path = presubmit.os.path.join('foo', 'blat.cc') 1569 path = presubmit.os.path.join('foo', 'blat.cc')
1377 f_path = presubmit.os.path.join(self.fake_root_dir, path) 1570 f_path = presubmit.os.path.join(self.fake_root_dir, path)
1378 presubmit.os.path.exists(f_path).AndReturn(True) 1571 presubmit.os.path.exists(f_path).AndReturn(True)
1379 presubmit.os.path.isdir(f_path).AndReturn(False) 1572 presubmit.os.path.isdir(f_path).AndReturn(False)
1380 presubmit.gclient_utils.FileRead(f_path, 'rU').AndReturn('whatever\ncookie') 1573 presubmit.gclient_utils.FileRead(f_path, 'rU').AndReturn('whatever\ncookie')
1381 presubmit.scm.SVN._CaptureInfo([path], self.fake_root_dir).AndReturn( 1574 presubmit.scm.SVN._CaptureInfo([path], self.fake_root_dir).AndReturn(
1382 {'URL': 'svn:/foo/foo/blat.cc'}) 1575 {'URL': 'svn:/foo/foo/blat.cc'})
1383 self.mox.ReplayAll() 1576 self.mox.ReplayAll()
(...skipping 1147 matching lines...) Expand 10 before | Expand all | Expand 10 after
2531 owners_check=False) 2724 owners_check=False)
2532 self.assertEqual(1, len(results)) 2725 self.assertEqual(1, len(results))
2533 self.assertEqual( 2726 self.assertEqual(
2534 'Found line ending with white spaces in:', results[0]._message) 2727 'Found line ending with white spaces in:', results[0]._message)
2535 self.checkstdout('') 2728 self.checkstdout('')
2536 2729
2537 2730
2538 if __name__ == '__main__': 2731 if __name__ == '__main__':
2539 import unittest 2732 import unittest
2540 unittest.main() 2733 unittest.main()
OLDNEW
« no previous file with comments | « presubmit_support.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698