def test_diff_with_change_in_type(self): output = StringProcessAdapter(fixture('diff_change_in_type')) diffs = Diff._index_from_patch_format(self.rorepo, output) self._assert_diff_format(diffs) self.assertEqual(2, len(diffs)) diff = diffs[0] self.assertIsNotNone(diff.deleted_file) self.assertEqual(diff.a_path, 'this') self.assertEqual(diff.b_path, 'this') assert isinstance(str(diff), str) diff = diffs[1] self.assertEqual(diff.a_path, None) self.assertEqual(diff.b_path, 'this') self.assertIsNotNone(diff.new_file) assert isinstance(str(diff), str) output = StringProcessAdapter( to_raw(fixture('diff_change_in_type_raw'))) diffs = Diff._index_from_raw_format(self.rorepo, output) self.assertEqual(len(diffs), 1) diff = diffs[0] self.assertEqual(diff.rename_from, None) self.assertEqual(diff.rename_to, None) self.assertEqual(diff.change_type, 'T') self.assertEqual(len(list(diffs.iter_change_type('T'))), 1)
def test_diff_with_rename(self): output = StringProcessAdapter(fixture('diff_rename')) diffs = Diff._index_from_patch_format(self.rorepo, output) self._assert_diff_format(diffs) self.assertEqual(1, len(diffs)) diff = diffs[0] self.assertTrue(diff.renamed_file) self.assertTrue(diff.renamed) self.assertEqual(diff.rename_from, 'Jérôme') self.assertEqual(diff.rename_to, 'müller') self.assertEqual(diff.raw_rename_from, b'J\xc3\xa9r\xc3\xb4me') self.assertEqual(diff.raw_rename_to, b'm\xc3\xbcller') assert isinstance(str(diff), str) output = StringProcessAdapter(to_raw(fixture('diff_rename_raw'))) diffs = Diff._index_from_raw_format(self.rorepo, output) self.assertEqual(len(diffs), 1) diff = diffs[0] self.assertIsNotNone(diff.renamed_file) self.assertIsNotNone(diff.renamed) self.assertEqual(diff.rename_from, 'this') self.assertEqual(diff.rename_to, 'that') self.assertEqual(diff.change_type, 'R') self.assertEqual(diff.score, 100) self.assertEqual(len(list(diffs.iter_change_type('R'))), 1)
def test_list_from_string_new_mode(self): output = StringProcessAdapter(fixture('diff_new_mode')) diffs = Diff._index_from_patch_format(self.rorepo, output) self._assert_diff_format(diffs) self.assertEqual(1, len(diffs)) self.assertEqual(8, len(diffs[0].diff.splitlines()))
def test_diff_unsafe_paths(self): output = StringProcessAdapter(fixture('diff_patch_unsafe_paths')) res = Diff._index_from_patch_format(None, output) # The "Additions" self.assertEqual(res[0].b_path, 'path/ starting with a space') self.assertEqual(res[1].b_path, 'path/"with-quotes"') self.assertEqual(res[2].b_path, "path/'with-single-quotes'") self.assertEqual(res[3].b_path, 'path/ending in a space ') self.assertEqual(res[4].b_path, 'path/with\ttab') self.assertEqual(res[5].b_path, 'path/with\nnewline') self.assertEqual(res[6].b_path, 'path/with spaces') self.assertEqual(res[7].b_path, 'path/with-question-mark?') self.assertEqual(res[8].b_path, 'path/¯\\_(ツ)_|¯') self.assertEqual(res[9].b_path, 'path/💩.txt') self.assertEqual(res[9].b_rawpath, b'path/\xf0\x9f\x92\xa9.txt') self.assertEqual(res[10].b_path, 'path/�-invalid-unicode-path.txt') self.assertEqual(res[10].b_rawpath, b'path/\x80-invalid-unicode-path.txt') # The "Moves" # NOTE: The path prefixes a/ and b/ here are legit! We're actually # verifying that it's not "a/a/" that shows up, see the fixture data. self.assertEqual(res[11].a_path, 'a/with spaces') # NOTE: path a/ here legit! self.assertEqual(res[11].b_path, 'b/with some spaces') # NOTE: path b/ here legit! self.assertEqual(res[12].a_path, 'a/ending in a space ') self.assertEqual(res[12].b_path, 'b/ending with space ') self.assertEqual(res[13].a_path, 'a/"with-quotes"') self.assertEqual(res[13].b_path, 'b/"with even more quotes"')
def test_diff_patch_format(self): # test all of the 'old' format diffs for completness - it should at least # be able to deal with it fixtures = ("diff_2", "diff_2f", "diff_f", "diff_i", "diff_mode_only", "diff_new_mode", "diff_numstat", "diff_p", "diff_rename", "diff_tree_numstat_root", "diff_patch_unsafe_paths") for fixture_name in fixtures: diff_proc = StringProcessAdapter(fixture(fixture_name)) Diff._index_from_patch_format(self.rorepo, diff_proc)
def test_binary_diff(self, case): method, file_name = case res = method(None, StringProcessAdapter(fixture(file_name))) self.assertEqual(len(res), 1) self.assertEqual(len(list(res.iter_change_type('M'))), 1) if res[0].diff: self.assertEqual(res[0].diff, b"Binary files a/rps and b/rps differ\n", "in patch mode, we get a diff text") self.assertIsNotNone(str(res[0]), "This call should just work")
def test_diff_of_modified_files_not_added_to_the_index(self): output = StringProcessAdapter( to_raw(fixture('diff_abbrev-40_full-index_M_raw_no-color'))) diffs = Diff._index_from_raw_format(self.rorepo, output) self.assertEqual(len(diffs), 1, 'one modification') self.assertEqual(len(list(diffs.iter_change_type('M'))), 1, 'one modification') self.assertEqual(diffs[0].change_type, 'M') self.assertIsNone(diffs[0].b_blob, )
def test_diff_index(self): output = StringProcessAdapter(fixture('diff_index_patch')) res = Diff._index_from_patch_format(None, output) self.assertEqual(len(res), 6) for dr in res: self.assertTrue(dr.diff.startswith(b'@@'), dr) self.assertIsNotNone( str(dr), "Diff to string conversion should be possible") # end for each diff dr = res[3] assert dr.diff.endswith(b"+Binary files a/rps and b/rps differ\n")
def test_diff_with_copied_file(self): output = StringProcessAdapter(fixture('diff_copied_mode')) diffs = Diff._index_from_patch_format(self.rorepo, output) self._assert_diff_format(diffs) self.assertEqual(1, len(diffs)) diff = diffs[0] self.assertTrue(diff.copied_file) self.assertTrue(diff.a_path, 'test1.txt') self.assertTrue(diff.b_path, 'test2.txt') assert isinstance(str(diff), str) output = StringProcessAdapter(to_raw(fixture('diff_copied_mode_raw'))) diffs = Diff._index_from_raw_format(self.rorepo, output) self.assertEqual(len(diffs), 1) diff = diffs[0] self.assertEqual(diff.change_type, 'C') self.assertEqual(diff.score, 100) self.assertEqual(diff.a_path, 'test1.txt') self.assertEqual(diff.b_path, 'test2.txt') self.assertEqual(len(list(diffs.iter_change_type('C'))), 1)
def test_rev_list_bisect_all(self): """ 'git rev-list --bisect-all' returns additional information in the commit header. This test ensures that we properly parse it. """ revs = self.rorepo.git.rev_list( '933d23bf95a5bd1624fbcdf328d904e1fa173474', first_parent=True, bisect_all=True) commits = Commit._iter_from_process_or_stream( self.rorepo, StringProcessAdapter(revs.encode('ascii'))) expected_ids = ('7156cece3c49544abb6bf7a0c218eb36646fad6d', '1f66cfbbce58b4b552b041707a12d437cc5f400a', '33ebe7acec14b25c5f84f35a664803fcab2f7781', '933d23bf95a5bd1624fbcdf328d904e1fa173474') for sha1, commit in zip(expected_ids, commits): self.assertEqual(sha1, commit.hexsha)
def test_diff_with_spaces(self): data = StringProcessAdapter(fixture('diff_file_with_spaces')) diff_index = Diff._index_from_patch_format(self.rorepo, data) self.assertIsNone(diff_index[0].a_path, repr(diff_index[0].a_path)) self.assertEqual(diff_index[0].b_path, 'file with spaces', repr(diff_index[0].b_path))
def test_diff_index_raw_format(self): output = StringProcessAdapter(fixture('diff_index_raw')) res = Diff._index_from_raw_format(None, output) self.assertIsNotNone(res[0].deleted_file) self.assertIsNone(res[0].b_path, )