def test_added_lines(self): res = create_pull_files(self.two_files_json) diff = Diff(res[0].patch, res[0].filename, res[0].sha) adds = diff.added_lines() self.assertEqual(2, len(adds), 'incorrect addition length') self.assertEqual(set([117, 119]), adds, 'added line numbers are wrong')
def test_has_line_changed__blocks_offset(self): res = Resource.loads(self.block_offset) diff = Diff(res[0]) self.assertTrue(diff.has_line_changed(32)) eq_(26, diff.line_position(23)) eq_(40, diff.line_position(32))
def test_has_line_changed__blocks_offset(self): res = create_pull_files(self.block_offset) diff = Diff(res[0].patch, res[0].filename, res[0].sha) self.assertTrue(diff.has_line_changed(32)) self.assertEqual(26, diff.line_position(23)) self.assertEqual(40, diff.line_position(32))
def test_added_lines(self): res = create_pull_files(self.two_files_json) diff = Diff(res[0].patch, res[0].filename, res[0].sha) adds = diff.added_lines() eq_(2, len(adds), 'incorrect addition length') eq_(set([117, 119]), adds, 'added line numbers are wrong')
def test_has_line_changed__blocks_offset(self): res = create_pull_files(self.block_offset) diff = Diff(res[0]) self.assertTrue(diff.has_line_changed(32)) eq_(26, diff.line_position(23)) eq_(40, diff.line_position(32))
def test_construct_with_hunks_kwarg(self): res = create_pull_files(self.two_files_json)[0] proto = Diff(res.patch, res.filename, res.sha) diff = Diff(None, res.filename, res.sha, hunks=proto.hunks) eq_(len(diff.hunks), len(proto.hunks)) eq_(diff.hunks[0].patch, proto.hunks[0].patch)
def test_has_line_changed__blocks_offset(self): res = create_pull_files(self.block_offset) diff = Diff(res[0].patch, res[0].filename, res[0].sha) self.assertTrue(diff.has_line_changed(32)) eq_(26, diff.line_position(23)) eq_(40, diff.line_position(32))
def test_deleted_lines(self): res = create_pull_files(self.two_files_json) diff = Diff(res[0].patch, res[0].filename, res[0].sha) dels = diff.deleted_lines() eq_(3, len(dels), 'incorrect deleted length') eq_(set([117, 119, 148]), dels, 'deleted line numbers are wrong') overlap = diff.added_lines().intersection(diff.deleted_lines()) eq_(set([117, 119]), overlap)
def test_has_line_changed__not_find_deletes(self): res = Resource.loads(self.two_files_json) diff = Diff(res[0]) self.assertTrue(diff.has_line_changed(117)) # No unchanged lines. self.assertFalse(diff.has_line_changed(118)) self.assertTrue(diff.has_line_changed(119)) # No deleted lines. self.assertFalse(diff.has_line_changed(148))
def test_deleted_lines(self): res = create_pull_files(self.two_files_json) diff = Diff(res[0].patch, res[0].filename, res[0].sha) dels = diff.deleted_lines() self.assertEqual(3, len(dels), 'incorrect deleted length') self.assertEqual(set([117, 119, 148]), dels, 'deleted line numbers are wrong') overlap = diff.added_lines().intersection(diff.deleted_lines()) self.assertEqual(set([117, 119]), overlap)
def test_has_line_changed__not_find_deletes(self): res = create_pull_files(self.two_files_json) diff = Diff(res[0].patch, res[0].filename, res[0].sha) self.assertTrue(diff.has_line_changed(117)) # No unchanged lines. self.assertFalse(diff.has_line_changed(118)) self.assertTrue(diff.has_line_changed(119)) # No deleted lines. self.assertFalse(diff.has_line_changed(147)) self.assertFalse(diff.has_line_changed(148))
def test_hunk_parsing(self): res = create_pull_files(self.two_files_json) diff = Diff(res[0].patch, res[0].filename, res[0].sha) hunks = diff.hunks eq_(2, len(hunks)) expected = set([117, 119]) eq_(expected, hunks[0].added_lines()) eq_(expected, hunks[0].deleted_lines()) eq_(expected, diff.added_lines()) eq_(set([]), hunks[1].added_lines()) eq_(set([148]), hunks[1].deleted_lines()) eq_(set([117, 119, 148]), diff.deleted_lines()) eq_(diff.line_position(117), hunks[0].line_position(117)) eq_(diff.line_position(119), hunks[0].line_position(119))
def test_hunk_parsing(self): res = create_pull_files(self.two_files_json) diff = Diff(res[0].patch, res[0].filename, res[0].sha) hunks = diff.hunks self.assertEqual(2, len(hunks)) expected = set([117, 119]) self.assertEqual(expected, hunks[0].added_lines()) self.assertEqual(expected, hunks[0].deleted_lines()) self.assertEqual(expected, diff.added_lines()) self.assertEqual(set([]), hunks[1].added_lines()) self.assertEqual(set([148]), hunks[1].deleted_lines()) self.assertEqual(set([117, 119, 148]), diff.deleted_lines()) self.assertEqual(diff.line_position(117), hunks[0].line_position(117)) self.assertEqual(diff.line_position(119), hunks[0].line_position(119))
class TestDiff(TestCase): fixture_json = load_fixture('one_file_pull_request.json') two_files_json = load_fixture('two_file_pull_request.json') # Block offset so lines don't match offsets block_offset = load_fixture('pull_request_line_offset.json') def setUp(self): res = Resource.loads(self.fixture_json) self.diff = Diff(res[0]) def test_properties(self): eq_("View/Helper/AssetCompressHelper.php", self.diff.filename) expected = '7f73f381ad3284eeb5a23d3a451b5752c957054c' eq_(expected, self.diff.commit) def test_has_line_changed__no_line(self): self.assertFalse(self.diff.has_line_changed(None)) def test_has_line_changed__added_only(self): # Check start and end of range self.assertTrue(self.diff.has_line_changed(454)) self.assertTrue(self.diff.has_line_changed(464)) def test_has_line_changed__not_find_deletes(self): res = Resource.loads(self.two_files_json) diff = Diff(res[0]) self.assertTrue(diff.has_line_changed(117)) # No unchanged lines. self.assertFalse(diff.has_line_changed(118)) self.assertTrue(diff.has_line_changed(119)) # No deleted lines. self.assertFalse(diff.has_line_changed(148)) def test_has_line_changed__blocks_offset(self): res = Resource.loads(self.block_offset) diff = Diff(res[0]) self.assertTrue(diff.has_line_changed(32)) eq_(26, diff.line_position(23)) eq_(40, diff.line_position(32))
def find_intersecting_diffs(original, fixed): intersection = [] for name in fixed.get_files(): original_diff = original.all_changes(name) if not len(original_diff): log.debug('No matching original diff for %s', name) continue fixed_diff = fixed.all_changes(name)[0] hunks = fixed_diff.intersection(original_diff[0]) intersection.append(Diff(None, name, '00000', hunks=hunks)) return intersection
def test_construct_with_hunks_kwarg(self): proto = parse_diff(self.two_files)[0] diff = Diff(None, proto.filename, None, hunks=proto.hunks) self.assertEqual(len(diff.hunks), len(proto.hunks)) self.assertEqual(diff.hunks[0].patch, proto.hunks[0].patch)
def setUp(self): res = Resource.loads(self.fixture_json) self.diff = Diff(res[0])
def test_construct_with_empty_hunks_kwarg(self): diff = Diff(None, 'test.py', 'abc123', hunks=[]) eq_(0, len(diff.hunks))
def setUp(self): res = create_pull_files(self.fixture_json) self.diff = Diff(res[0])
class TestDiff(TestCase): fixture_json = load_fixture('one_file_pull_request.json') two_files_json = load_fixture('two_file_pull_request.json') # Block offset so lines don't match offsets block_offset = load_fixture('pull_request_line_offset.json') def setUp(self): res = create_pull_files(self.fixture_json) self.diff = Diff(res[0].patch, res[0].filename, res[0].sha) def test_parse_diff__no_input(self): with self.assertRaises(ParseError) as ctx: parse_diff('') self.assertIn('No diff', str(ctx.exception)) def test_parse_diff__headers_removed(self): data = load_fixture('diff/one_file.txt') out = parse_diff(data) assert isinstance(out, DiffCollection) self.assertEqual(1, len(out)) self.assertEqual(['tests/test_diff.py'], out.get_files()) change = out.all_changes('tests/test_diff.py') self.assertEqual(1, len(change)) self.assertEqual('tests/test_diff.py', change[0].filename) self.assertEqual(None, change[0].commit, 'No commit as changes are just a diff') # Make sure git diff headers are not in patch self.assertNotIn('git --diff', change[0].patch) self.assertNotIn('index', change[0].patch) self.assertNotIn('--- a', change[0].patch) self.assertNotIn('+++ b', change[0].patch) self.assertIn('@@', change[0].patch) def test_parse_diff__changed_lines_parsed(self): data = load_fixture('diff/one_file.txt') out = parse_diff(data) assert isinstance(out, DiffCollection) change = out.all_changes('tests/test_diff.py') self.assertEqual(1, len(change)) expected = set([6, 9, 10, 55]) self.assertEqual(expected, change[0].deleted_lines()) def test_parse_diff__multiple_files(self): data = load_fixture('diff/two_files.txt') out = parse_diff(data) self.assertEqual(2, len(out)) self.assertEqual(['lintreview/git.py', 'tests/test_git.py'], out.get_files()) for change in out: assert change.filename, 'has a filename' assert change.commit is None, 'No commit' self.assertNotIn('git --diff', change.patch) self.assertNotIn('index', change.patch) self.assertNotIn('--- a', change.patch) self.assertNotIn('+++ b', change.patch) self.assertIn('@@', change.patch) change = out.all_changes('tests/test_git.py')[0] self.assertEqual({205, 206, 207, 208, 209, 210, 211, 212, 213}, change.added_lines()) def test_parse_diff__bad_input(self): data = """ some dumb stuff """ with self.assertRaises(ParseError) as ctx: parse_diff(data) self.assertIn('Could not parse', str(ctx.exception)) def test_properties(self): self.assertEqual("View/Helper/AssetCompressHelper.php", self.diff.filename) expected = '7f73f381ad3284eeb5a23d3a451b5752c957054c' self.assertEqual(expected, self.diff.commit) def test_patch_property(self): res = create_pull_files(self.two_files_json) diff = Diff(res[0].patch, res[0].filename, res[0].sha) self.assertEqual(res[0].patch, diff.patch) def test_as_diff__one_hunk(self): data = load_fixture('diff/no_intersect_updated.txt') diff = parse_diff(data)[0] # Method results don't include index line. data = re.sub(r'^index.*?\n', '', data, 0, re.M) self.assertEqual(data, diff.as_diff()) def test_as_diff__multi_hunk(self): data = load_fixture('diff/inset_hunks_updated.txt') diff = parse_diff(data)[0] # Method results don't include index line. data = re.sub(r'^index.*?\n', '', data, 0, re.M) self.assertEqual(data, diff.as_diff()) def test_has_line_changed__no_line(self): self.assertFalse(self.diff.has_line_changed(None)) def test_has_line_changed__added_only(self): # Check start and end of range self.assertTrue(self.diff.has_line_changed(454)) self.assertTrue(self.diff.has_line_changed(464)) def test_has_line_changed__not_find_deletes(self): res = create_pull_files(self.two_files_json) diff = Diff(res[0].patch, res[0].filename, res[0].sha) self.assertTrue(diff.has_line_changed(117)) # No unchanged lines. self.assertFalse(diff.has_line_changed(118)) self.assertTrue(diff.has_line_changed(119)) # No deleted lines. self.assertFalse(diff.has_line_changed(147)) self.assertFalse(diff.has_line_changed(148)) def test_has_line_changed__blocks_offset(self): res = create_pull_files(self.block_offset) diff = Diff(res[0].patch, res[0].filename, res[0].sha) self.assertTrue(diff.has_line_changed(32)) self.assertEqual(26, diff.line_position(23)) self.assertEqual(40, diff.line_position(32)) def test_added_lines(self): res = create_pull_files(self.two_files_json) diff = Diff(res[0].patch, res[0].filename, res[0].sha) adds = diff.added_lines() self.assertEqual(2, len(adds), 'incorrect addition length') self.assertEqual(set([117, 119]), adds, 'added line numbers are wrong') def test_deleted_lines(self): res = create_pull_files(self.two_files_json) diff = Diff(res[0].patch, res[0].filename, res[0].sha) dels = diff.deleted_lines() self.assertEqual(3, len(dels), 'incorrect deleted length') self.assertEqual(set([117, 119, 148]), dels, 'deleted line numbers are wrong') overlap = diff.added_lines().intersection(diff.deleted_lines()) self.assertEqual(set([117, 119]), overlap) def test_hunk_parsing(self): res = create_pull_files(self.two_files_json) diff = Diff(res[0].patch, res[0].filename, res[0].sha) hunks = diff.hunks self.assertEqual(2, len(hunks)) expected = set([117, 119]) self.assertEqual(expected, hunks[0].added_lines()) self.assertEqual(expected, hunks[0].deleted_lines()) self.assertEqual(expected, diff.added_lines()) self.assertEqual(set([]), hunks[1].added_lines()) self.assertEqual(set([148]), hunks[1].deleted_lines()) self.assertEqual(set([117, 119, 148]), diff.deleted_lines()) self.assertEqual(diff.line_position(117), hunks[0].line_position(117)) self.assertEqual(diff.line_position(119), hunks[0].line_position(119)) def test_construct_with_hunks_kwarg(self): res = create_pull_files(self.two_files_json)[0] proto = Diff(res.patch, res.filename, res.sha) diff = Diff(None, res.filename, res.sha, hunks=proto.hunks) self.assertEqual(len(diff.hunks), len(proto.hunks)) self.assertEqual(diff.hunks[0].patch, proto.hunks[0].patch) def test_construct_with_empty_hunks_kwarg(self): diff = Diff(None, 'test.py', 'abc123', hunks=[]) self.assertEqual(0, len(diff.hunks)) def test_intersection__simple(self): # These two diffs should fully overlap as # the updated diff hunks touch the original hunks. original = load_fixture('diff/intersecting_hunks_original.txt') updated = load_fixture('diff/intersecting_hunks_updated.txt') original = parse_diff(original)[0] updated = parse_diff(updated)[0] intersecting = updated.intersection(original) self.assertEqual(4, len(updated.hunks)) self.assertEqual(4, len(intersecting)) def test_intersection__no_intersect(self): # Diffs have no overlap as updated appends lines. original = load_fixture('diff/no_intersect_original.txt') updated = load_fixture('diff/no_intersect_updated.txt') original = parse_diff(original)[0] updated = parse_diff(updated)[0] intersecting = updated.intersection(original) self.assertEqual(1, len(updated.hunks)) self.assertEqual(0, len(intersecting)) def test_intersection__inset_hunks(self): # Updated contains two hunks inside original's changes original = load_fixture('diff/inset_hunks_original.txt') updated = load_fixture('diff/inset_hunks_updated.txt') original = parse_diff(original)[0] updated = parse_diff(updated)[0] intersecting = updated.intersection(original) self.assertEqual(2, len(updated.hunks)) self.assertEqual(2, len(intersecting)) def test_intersection__staggered_hunks(self): # Updated contains a big hunk in the middle that pushes # the original section down. The bottom hunk of updated # should overlap original = load_fixture('diff/staggered_original.txt') updated = load_fixture('diff/staggered_updated.txt') original = parse_diff(original)[0] updated = parse_diff(updated)[0] intersecting = updated.intersection(original) self.assertEqual(2, len(updated.hunks)) self.assertEqual(2, len(intersecting)) def test_intersection__adjacent(self): # Updated contains a two hunks that partially overlap # both should be included. original = load_fixture('diff/adjacent_original.txt') updated = load_fixture('diff/adjacent_updated.txt') original = parse_diff(original)[0] updated = parse_diff(updated)[0] intersecting = updated.intersection(original) self.assertEqual(2, len(intersecting))
def setUp(self): res = create_pull_files(self.fixture_json) self.diff = Diff(res[0].patch, res[0].filename, res[0].sha)
def test_patch_property(self): res = create_pull_files(self.two_files_json) diff = Diff(res[0].patch, res[0].filename, res[0].sha) eq_(res[0].patch, diff.patch)
class TestDiff(TestCase): fixture_json = load_fixture('one_file_pull_request.json') two_files_json = load_fixture('two_file_pull_request.json') # Block offset so lines don't match offsets block_offset = load_fixture('pull_request_line_offset.json') def setUp(self): res = create_pull_files(self.fixture_json) self.diff = Diff(res[0].patch, res[0].filename, res[0].sha) def test_properties(self): eq_("View/Helper/AssetCompressHelper.php", self.diff.filename) expected = '7f73f381ad3284eeb5a23d3a451b5752c957054c' eq_(expected, self.diff.commit) def test_patch_property(self): res = create_pull_files(self.two_files_json) diff = Diff(res[0].patch, res[0].filename, res[0].sha) eq_(res[0].patch, diff.patch) def test_as_diff__one_hunk(self): data = load_fixture('diff/no_intersect_updated.txt') diff = parse_diff(data)[0] # Method results don't include index line. data = re.sub(r'^index.*?\n', '', data, 0, re.M) eq_(data, diff.as_diff()) def test_as_diff__multi_hunk(self): data = load_fixture('diff/inset_hunks_updated.txt') diff = parse_diff(data)[0] # Method results don't include index line. data = re.sub(r'^index.*?\n', '', data, 0, re.M) eq_(data, diff.as_diff()) def test_has_line_changed__no_line(self): self.assertFalse(self.diff.has_line_changed(None)) def test_has_line_changed__added_only(self): # Check start and end of range self.assertTrue(self.diff.has_line_changed(454)) self.assertTrue(self.diff.has_line_changed(464)) def test_has_line_changed__not_find_deletes(self): res = create_pull_files(self.two_files_json) diff = Diff(res[0].patch, res[0].filename, res[0].sha) self.assertTrue(diff.has_line_changed(117)) # No unchanged lines. self.assertFalse(diff.has_line_changed(118)) self.assertTrue(diff.has_line_changed(119)) # No deleted lines. self.assertFalse(diff.has_line_changed(147)) self.assertFalse(diff.has_line_changed(148)) def test_has_line_changed__blocks_offset(self): res = create_pull_files(self.block_offset) diff = Diff(res[0].patch, res[0].filename, res[0].sha) self.assertTrue(diff.has_line_changed(32)) eq_(26, diff.line_position(23)) eq_(40, diff.line_position(32)) def test_added_lines(self): res = create_pull_files(self.two_files_json) diff = Diff(res[0].patch, res[0].filename, res[0].sha) adds = diff.added_lines() eq_(2, len(adds), 'incorrect addition length') eq_(set([117, 119]), adds, 'added line numbers are wrong') def test_deleted_lines(self): res = create_pull_files(self.two_files_json) diff = Diff(res[0].patch, res[0].filename, res[0].sha) dels = diff.deleted_lines() eq_(3, len(dels), 'incorrect deleted length') eq_(set([117, 119, 148]), dels, 'deleted line numbers are wrong') overlap = diff.added_lines().intersection(diff.deleted_lines()) eq_(set([117, 119]), overlap) def test_hunk_parsing(self): res = create_pull_files(self.two_files_json) diff = Diff(res[0].patch, res[0].filename, res[0].sha) hunks = diff.hunks eq_(2, len(hunks)) expected = set([117, 119]) eq_(expected, hunks[0].added_lines()) eq_(expected, hunks[0].deleted_lines()) eq_(expected, diff.added_lines()) eq_(set([]), hunks[1].added_lines()) eq_(set([148]), hunks[1].deleted_lines()) eq_(set([117, 119, 148]), diff.deleted_lines()) eq_(diff.line_position(117), hunks[0].line_position(117)) eq_(diff.line_position(119), hunks[0].line_position(119)) def test_construct_with_hunks_kwarg(self): res = create_pull_files(self.two_files_json)[0] proto = Diff(res.patch, res.filename, res.sha) diff = Diff(None, res.filename, res.sha, hunks=proto.hunks) eq_(len(diff.hunks), len(proto.hunks)) eq_(diff.hunks[0].patch, proto.hunks[0].patch) def test_construct_with_empty_hunks_kwarg(self): diff = Diff(None, 'test.py', 'abc123', hunks=[]) eq_(0, len(diff.hunks)) def test_intersection__simple(self): # These two diffs should fully overlap as # the updated diff hunks touch the original hunks. original = load_fixture('diff/intersecting_hunks_original.txt') updated = load_fixture('diff/intersecting_hunks_updated.txt') original = parse_diff(original)[0] updated = parse_diff(updated)[0] intersecting = updated.intersection(original) eq_(4, len(updated.hunks)) eq_(4, len(intersecting)) def test_intersection__no_intersect(self): # Diffs have no overlap as updated appends lines. original = load_fixture('diff/no_intersect_original.txt') updated = load_fixture('diff/no_intersect_updated.txt') original = parse_diff(original)[0] updated = parse_diff(updated)[0] intersecting = updated.intersection(original) eq_(1, len(updated.hunks)) eq_(0, len(intersecting)) def test_intersection__inset_hunks(self): # Updated contains two hunks inside original's changes original = load_fixture('diff/inset_hunks_original.txt') updated = load_fixture('diff/inset_hunks_updated.txt') original = parse_diff(original)[0] updated = parse_diff(updated)[0] intersecting = updated.intersection(original) eq_(2, len(updated.hunks)) eq_(2, len(intersecting)) def test_intersection__staggered_hunks(self): # Updated contains a big hunk in the middle that pushes # the original section down. The bottom hunk of updated # should overlap original = load_fixture('diff/staggered_original.txt') updated = load_fixture('diff/staggered_updated.txt') original = parse_diff(original)[0] updated = parse_diff(updated)[0] intersecting = updated.intersection(original) eq_(2, len(updated.hunks)) eq_(2, len(intersecting)) def test_intersection__adjacent(self): # Updated contains a two hunks that partially overlap # both should be included. original = load_fixture('diff/adjacent_original.txt') updated = load_fixture('diff/adjacent_updated.txt') original = parse_diff(original)[0] updated = parse_diff(updated)[0] intersecting = updated.intersection(original) eq_(2, len(intersecting))