def test_parse_diff__bad_input(): data = """ some dumb stuff """ with assert_raises(ParseError) as ctx: parse_diff(data) assert_in('Could not parse', str(ctx.exception))
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_find_intersecting_diffs__no_intersect(self): original = load_fixture('diff/intersecting_hunks_original.txt') updated = load_fixture('diff/adjacent_original.txt') original = parse_diff(original) updated = parse_diff(updated) result = fixers.find_intersecting_diffs(original, updated) self.assertEqual(0, len(result))
def test_parse_diff__bad_input(self): data = """diff --git a/app/models.py b/app/models.py index fa9a814..769886c 100644 --- a/app/models.py +++ b/app/models.py""" with self.assertRaises(ParseError) as ctx: parse_diff(data) self.assertIn('Could not parse', str(ctx.exception))
def test_find_intersecting_diffs__no_intersect(): original = load_fixture('diff/intersecting_hunks_original.txt') updated = load_fixture('diff/adjacent_original.txt') original = parse_diff(original) updated = parse_diff(updated) result = fixers.find_intersecting_diffs(original, updated) eq_(0, len(result))
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 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) self.assertEqual(2, len(updated.hunks)) self.assertEqual(2, 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) 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))
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_find_intersecting_diffs(self): original = load_fixture('diff/intersecting_hunks_original.txt') updated = load_fixture('diff/intersecting_hunks_updated.txt') original = parse_diff(original) updated = parse_diff(updated) result = fixers.find_intersecting_diffs(original, updated) self.assertEqual(1, len(result)) assert isinstance(result[0], Diff) self.assertEqual('model.php', result[0].filename) self.assertEqual('00000', result[0].commit)
def test_find_intersecting_diffs(): original = load_fixture('diff/intersecting_hunks_original.txt') updated = load_fixture('diff/intersecting_hunks_updated.txt') original = parse_diff(original) updated = parse_diff(updated) result = fixers.find_intersecting_diffs(original, updated) eq_(1, len(result)) assert isinstance(result[0], Diff) eq_('model.php', result[0].filename) eq_('00000', result[0].commit)
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__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__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_apply_fixer_diff__calls_execute(self): strategy_factory = Mock() strategy = Mock() strategy_factory.return_value = strategy fixers.add_strategy('mock', strategy_factory) original = load_fixture('diff/intersecting_hunks_original.txt') updated = load_fixture('diff/intersecting_hunks_updated.txt') original = parse_diff(original) updated = parse_diff(updated) context = {'strategy': 'mock'} fixers.apply_fixer_diff(original, updated, context) self.assertEqual(1, strategy.execute.call_count)
def test_apply_fixer_diff__no_intersection(self): strategy_factory = Mock() strategy = Mock() strategy_factory.return_value = strategy fixers.add_strategy('mock', strategy_factory) original = load_fixture('diff/no_intersect_original.txt') updated = load_fixture('diff/no_intersect_updated.txt') original = parse_diff(original) updated = parse_diff(updated) context = {'strategy': 'mock'} fixers.apply_fixer_diff(original, updated, context) self.assertEqual(0, strategy.execute.call_count)
def test_apply_fixer_diff__no_intersection(): strategy_factory = Mock() strategy = Mock() strategy_factory.return_value = strategy fixers.add_strategy('mock', strategy_factory) original = load_fixture('diff/no_intersect_original.txt') updated = load_fixture('diff/no_intersect_updated.txt') original = parse_diff(original) updated = parse_diff(updated) context = {'strategy': 'mock'} fixers.apply_fixer_diff(original, updated, context) eq_(0, strategy.execute.call_count)
def test_first_changed_line(self): assert self.diff.first_changed_line() == 454 data = load_fixture('diff/one_file.txt') out = parse_diff(data) change = out.all_changes('tests/test_diff.py') assert change[0].first_changed_line() == 6
def test_get_files__two_files(self): changes = parse_diff(self.two_files) result = changes.get_files() expected = [ "Console/Command/Task/AssetBuildTask.php", "Test/test_files/View/Parse/single.ctp", ] self.assertEqual(expected, result)
def test_apply_fixer_diff__strategy_execution_fails(): strategy_factory = Mock() strategy = Mock() strategy.execute.side_effect = RuntimeError strategy_factory.return_value = strategy fixers.add_strategy('mock', strategy_factory) original = load_fixture('diff/intersecting_hunks_original.txt') updated = load_fixture('diff/intersecting_hunks_updated.txt') original = parse_diff(original) updated = parse_diff(updated) context = {'strategy': 'mock'} out = fixers.apply_fixer_diff(original, updated, context) eq_(1, strategy.execute.call_count) eq_(out, None, 'No output and no exception')
def test_get_files__two_files__ignore_pattern(self): changes = parse_diff(self.two_files) expected = [ "Console/Command/Task/AssetBuildTask.php", ] ignore = ['Test/**', None, False] result = changes.get_files(ignore_patterns=ignore) self.assertEqual(expected, result)
def test_has_line_changed__single_line(self): filename = 'some.js' changes = parse_diff(self.single_line_add) self.assertTrue(changes.has_line_changed(filename, 1)) self.assertFalse(changes.has_line_changed(filename, 0)) self.assertFalse(changes.has_line_changed(filename, 2))
def test_first_changed_line(self): changes = parse_diff(self.two_files) filename = 'Console/Command/Task/AssetBuildTask.php' assert changes.first_changed_line('not there') is None assert changes.first_changed_line(filename) == 117 filename = "Test/test_files/View/Parse/single.ctp" assert changes.first_changed_line(filename) == 3
def test_find_intersecting_diffs__list(): diff = load_fixture('diff/intersecting_hunks_original.txt') diffs = parse_diff(diff) result = fixers.find_intersecting_diffs(diffs, []) eq_(0, len(result)) result = fixers.find_intersecting_diffs([], diff) eq_(0, len(result))
def test_get_files__ignore_pattern__multiple_wildcard(self): data = load_fixture('diff/multiple_wildcard_pull_request.txt') changes = parse_diff(data) expected = [ "buildpacks/buildpack-ruby/tests/ruby-sinatra/test_web.rb", ] ignore = ['buildpacks/*/tests/*/test.sh'] result = changes.get_files(ignore_patterns=ignore) self.assertEqual(expected, result)
def test_find_intersecting_diffs__list(self): diff = load_fixture('diff/intersecting_hunks_original.txt') diffs = parse_diff(diff) result = fixers.find_intersecting_diffs(diffs, []) self.assertEqual(0, len(result)) result = fixers.find_intersecting_diffs([], diff) self.assertEqual(0, len(result))
def test_deleted_lines(self): diff = parse_diff(self.two_files)[0] 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_parse_diff__changed_lines_parsed(): data = load_fixture('diff/one_file.txt') out = parse_diff(data) assert isinstance(out, DiffCollection) change = out.all_changes('tests/test_diff.py') eq_(1, len(change)) expected = set([6, 9, 10, 55]) eq_(expected, change[0].deleted_lines())
def test_has_line_changed__not_find_deletes(self): diff = parse_diff(self.two_files)[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(147)) self.assertFalse(diff.has_line_changed(148))
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_has_line_changed__two_files(self): changes = parse_diff(self.two_files) filename = 'Console/Command/Task/AssetBuildTask.php' # True for additions self.assertTrue(changes.has_line_changed(filename, 117)) self.assertTrue(changes.has_line_changed(filename, 119)) # Should return false if the line was a deletion self.assertFalse(changes.has_line_changed(filename, 148)) # Should return false for unchanged self.assertFalse(changes.has_line_changed(filename, 145))
def run_fixers(tools, base_path, files): """Run fixer mode of each tool on each file Return a DiffCollection based on the parsed diff from the fixer changes. If no diff is generated an empty list will be returned""" log.info('Running fixers on %d files', len(files)) for tool in tools: if tool.has_fixer(): tool.execute_fixer(files) diff = git.diff(base_path, files) if diff: return parse_diff(diff) return []
def run_fixers(tools, base_path, files): """Run fixer mode of each tool on each file Return a DiffCollection based on the parsed diff from the fixer changes. If no diff is generated an empty list will be returned""" log.info('Running fixers on %d files', len(files)) docker_files = [docker.apply_base(f) for f in files] for tool in tools: if tool.has_fixer(): tool.execute_fixer(docker_files) diff = git.diff(base_path, files) if diff: return parse_diff(diff) return []
def test_hunk_parsing(self): diff = parse_diff(self.two_files)[0] 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_parse_diff__multiple_files(): data = load_fixture('diff/two_files.txt') out = parse_diff(data) eq_(2, len(out)) eq_(['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' assert_not_in('git --diff', change.patch) assert_not_in('index', change.patch) assert_not_in('--- a', change.patch) assert_not_in('+++ b', change.patch) assert_in('@@', change.patch) change = out.all_changes('tests/test_git.py')[0] eq_(set([205, 206, 207, 208, 209, 210, 211, 212, 213]), change.added_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__headers_removed(): data = load_fixture('diff/one_file.txt') out = parse_diff(data) assert isinstance(out, DiffCollection) eq_(1, len(out)) eq_(['tests/test_diff.py'], out.get_files()) change = out.all_changes('tests/test_diff.py') eq_(1, len(change)) eq_('tests/test_diff.py', change[0].filename) eq_(None, change[0].commit, 'No commit as changes are just a diff') # Make sure git diff headers are not in patch assert_not_in('git --diff', change[0].patch) assert_not_in('index', change[0].patch) assert_not_in('--- a', change[0].patch) assert_not_in('+++ b', change[0].patch) assert_in('@@', change[0].patch)
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__no_input(): with assert_raises(ParseError) as ctx: parse_diff('') assert_in('No diff', str(ctx.exception))
def test_parse_diff__no_input(self): with self.assertRaises(ParseError) as ctx: parse_diff('') self.assertIn('No diff', str(ctx.exception))
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_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())