| OLD | NEW |
| 1 # Copyright 2016 The Chromium Authors. All rights reserved. | 1 # Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 import unittest | 5 import unittest |
| 6 | 6 |
| 7 from webkitpy.common.system.executive import Executive, ScriptError | 7 from webkitpy.common.system.executive import Executive, ScriptError |
| 8 from webkitpy.common.system.executive_mock import MockExecutive | 8 from webkitpy.common.system.executive_mock import MockExecutive |
| 9 from webkitpy.common.system.filesystem import FileSystem | 9 from webkitpy.common.system.filesystem import FileSystem |
| 10 from webkitpy.common.system.filesystem_mock import MockFileSystem | 10 from webkitpy.common.system.filesystem_mock import MockFileSystem |
| 11 from webkitpy.common.checkout.git import Git | 11 from webkitpy.common.checkout.git import Git |
| 12 | 12 |
| 13 | 13 |
| 14 class GitTestWithRealFilesystemAndExecutive(unittest.TestCase): | 14 class GitTestWithRealFilesystemAndExecutive(unittest.TestCase): |
| 15 | 15 |
| 16 def setUp(self): | 16 def setUp(self): |
| 17 self.executive = Executive() | 17 self.executive = Executive() |
| 18 self.filesystem = FileSystem() | 18 self.filesystem = FileSystem() |
| 19 self.original_cwd = self.filesystem.getcwd() | 19 self.original_cwd = self.filesystem.getcwd() |
| 20 | 20 |
| 21 # Set up fresh git repository with one commit. | 21 # Set up fresh git repository with one commit. |
| 22 self.untracking_checkout_path = self._mkdtemp(suffix='-git_unittest_untr
acking') | 22 self.untracking_checkout_path = self._mkdtemp(suffix='-git_unittest_untr
acking') |
| 23 self._run(['git', 'init', self.untracking_checkout_path]) | 23 self._run(['git', 'init', self.untracking_checkout_path]) |
| 24 self._chdir(self.untracking_checkout_path) | 24 self._chdir(self.untracking_checkout_path) |
| 25 self._write_text_file('foo_file', 'foo') | 25 self._write_text_file('foo_file', 'foo') |
| 26 self._run(['git', 'add', 'foo_file']) | 26 self._run(['git', 'add', 'foo_file']) |
| 27 self._run(['git', 'commit', '-am', 'dummy commit']) | 27 self._run(['git', 'commit', '-am', 'dummy commit']) |
| 28 self.untracking_scm = Git(cwd=self.untracking_checkout_path, filesystem=
self.filesystem, executive=self.executive) | 28 self.untracking_git = Git(cwd=self.untracking_checkout_path, filesystem=
self.filesystem, executive=self.executive) |
| 29 | 29 |
| 30 # Then set up a second git repo that tracks the first one. | 30 # Then set up a second git repo that tracks the first one. |
| 31 self.tracking_git_checkout_path = self._mkdtemp(suffix='-git_unittest_tr
acking') | 31 self.tracking_git_checkout_path = self._mkdtemp(suffix='-git_unittest_tr
acking') |
| 32 self._run(['git', 'clone', '--quiet', self.untracking_checkout_path, sel
f.tracking_git_checkout_path]) | 32 self._run(['git', 'clone', '--quiet', self.untracking_checkout_path, sel
f.tracking_git_checkout_path]) |
| 33 self._chdir(self.tracking_git_checkout_path) | 33 self._chdir(self.tracking_git_checkout_path) |
| 34 self.tracking_scm = Git(cwd=self.tracking_git_checkout_path, filesystem=
self.filesystem, executive=self.executive) | 34 self.tracking_git = Git(cwd=self.tracking_git_checkout_path, filesystem=
self.filesystem, executive=self.executive) |
| 35 | 35 |
| 36 def tearDown(self): | 36 def tearDown(self): |
| 37 self._chdir(self.original_cwd) | 37 self._chdir(self.original_cwd) |
| 38 self._run(['rm', '-rf', self.tracking_git_checkout_path]) | 38 self._run(['rm', '-rf', self.tracking_git_checkout_path]) |
| 39 self._run(['rm', '-rf', self.untracking_checkout_path]) | 39 self._run(['rm', '-rf', self.untracking_checkout_path]) |
| 40 | 40 |
| 41 def _join(self, *comps): | 41 def _join(self, *comps): |
| 42 return self.filesystem.join(*comps) | 42 return self.filesystem.join(*comps) |
| 43 | 43 |
| 44 def _chdir(self, path): | 44 def _chdir(self, path): |
| (...skipping 24 matching lines...) Expand all Loading... |
| 69 def _make_diff(self, command, *args): | 69 def _make_diff(self, command, *args): |
| 70 # We use this wrapper to disable output decoding. diffs should be treate
d as | 70 # We use this wrapper to disable output decoding. diffs should be treate
d as |
| 71 # binary files since they may include text files of multiple different e
ncodings. | 71 # binary files since they may include text files of multiple different e
ncodings. |
| 72 return self._run([command, 'diff'] + list(args), decode_output=False) | 72 return self._run([command, 'diff'] + list(args), decode_output=False) |
| 73 | 73 |
| 74 def _git_diff(self, *args): | 74 def _git_diff(self, *args): |
| 75 return self._make_diff('git', *args) | 75 return self._make_diff('git', *args) |
| 76 | 76 |
| 77 def test_add_list(self): | 77 def test_add_list(self): |
| 78 self._chdir(self.untracking_checkout_path) | 78 self._chdir(self.untracking_checkout_path) |
| 79 git = self.untracking_scm | 79 git = self.untracking_git |
| 80 self._mkdir('added_dir') | 80 self._mkdir('added_dir') |
| 81 self._write_text_file('added_dir/added_file', 'new stuff') | 81 self._write_text_file('added_dir/added_file', 'new stuff') |
| 82 print self._run(['ls', 'added_dir']) | 82 print self._run(['ls', 'added_dir']) |
| 83 print self._run(['pwd']) | 83 print self._run(['pwd']) |
| 84 print self._run(['cat', 'added_dir/added_file']) | 84 print self._run(['cat', 'added_dir/added_file']) |
| 85 git.add_list(['added_dir/added_file']) | 85 git.add_list(['added_dir/added_file']) |
| 86 self.assertIn('added_dir/added_file', git.added_files()) | 86 self.assertIn('added_dir/added_file', git.added_files()) |
| 87 | 87 |
| 88 def test_delete_recursively(self): | 88 def test_delete_recursively(self): |
| 89 self._chdir(self.untracking_checkout_path) | 89 self._chdir(self.untracking_checkout_path) |
| 90 git = self.untracking_scm | 90 git = self.untracking_git |
| 91 self._mkdir('added_dir') | 91 self._mkdir('added_dir') |
| 92 self._write_text_file('added_dir/added_file', 'new stuff') | 92 self._write_text_file('added_dir/added_file', 'new stuff') |
| 93 git.add_list(['added_dir/added_file']) | 93 git.add_list(['added_dir/added_file']) |
| 94 self.assertIn('added_dir/added_file', git.added_files()) | 94 self.assertIn('added_dir/added_file', git.added_files()) |
| 95 git.delete_list(['added_dir/added_file']) | 95 git.delete_list(['added_dir/added_file']) |
| 96 self.assertNotIn('added_dir', git.added_files()) | 96 self.assertNotIn('added_dir', git.added_files()) |
| 97 | 97 |
| 98 def test_delete_recursively_or_not(self): | 98 def test_delete_recursively_or_not(self): |
| 99 self._chdir(self.untracking_checkout_path) | 99 self._chdir(self.untracking_checkout_path) |
| 100 git = self.untracking_scm | 100 git = self.untracking_git |
| 101 self._mkdir('added_dir') | 101 self._mkdir('added_dir') |
| 102 self._write_text_file('added_dir/added_file', 'new stuff') | 102 self._write_text_file('added_dir/added_file', 'new stuff') |
| 103 self._write_text_file('added_dir/another_added_file', 'more new stuff') | 103 self._write_text_file('added_dir/another_added_file', 'more new stuff') |
| 104 git.add_list(['added_dir/added_file', 'added_dir/another_added_file']) | 104 git.add_list(['added_dir/added_file', 'added_dir/another_added_file']) |
| 105 self.assertIn('added_dir/added_file', git.added_files()) | 105 self.assertIn('added_dir/added_file', git.added_files()) |
| 106 self.assertIn('added_dir/another_added_file', git.added_files()) | 106 self.assertIn('added_dir/another_added_file', git.added_files()) |
| 107 git.delete_list(['added_dir/added_file']) | 107 git.delete_list(['added_dir/added_file']) |
| 108 self.assertIn('added_dir/another_added_file', git.added_files()) | 108 self.assertIn('added_dir/another_added_file', git.added_files()) |
| 109 | 109 |
| 110 def test_exists(self): | 110 def test_exists(self): |
| 111 self._chdir(self.untracking_checkout_path) | 111 self._chdir(self.untracking_checkout_path) |
| 112 git = self.untracking_scm | 112 git = self.untracking_git |
| 113 self._chdir(git.checkout_root) | 113 self._chdir(git.checkout_root) |
| 114 self.assertFalse(git.exists('foo.txt')) | 114 self.assertFalse(git.exists('foo.txt')) |
| 115 self._write_text_file('foo.txt', 'some stuff') | 115 self._write_text_file('foo.txt', 'some stuff') |
| 116 self.assertFalse(git.exists('foo.txt')) | 116 self.assertFalse(git.exists('foo.txt')) |
| 117 git.add_list(['foo.txt']) | 117 git.add_list(['foo.txt']) |
| 118 git.commit_locally_with_message('adding foo') | 118 git.commit_locally_with_message('adding foo') |
| 119 self.assertTrue(git.exists('foo.txt')) | 119 self.assertTrue(git.exists('foo.txt')) |
| 120 git.delete_list(['foo.txt']) | 120 git.delete_list(['foo.txt']) |
| 121 git.commit_locally_with_message('deleting foo') | 121 git.commit_locally_with_message('deleting foo') |
| 122 self.assertFalse(git.exists('foo.txt')) | 122 self.assertFalse(git.exists('foo.txt')) |
| 123 | 123 |
| 124 def test_move(self): | 124 def test_move(self): |
| 125 self._chdir(self.untracking_checkout_path) | 125 self._chdir(self.untracking_checkout_path) |
| 126 git = self.untracking_scm | 126 git = self.untracking_git |
| 127 self._write_text_file('added_file', 'new stuff') | 127 self._write_text_file('added_file', 'new stuff') |
| 128 git.add_list(['added_file']) | 128 git.add_list(['added_file']) |
| 129 git.move('added_file', 'moved_file') | 129 git.move('added_file', 'moved_file') |
| 130 self.assertIn('moved_file', git.added_files()) | 130 self.assertIn('moved_file', git.added_files()) |
| 131 | 131 |
| 132 def test_move_recursive(self): | 132 def test_move_recursive(self): |
| 133 self._chdir(self.untracking_checkout_path) | 133 self._chdir(self.untracking_checkout_path) |
| 134 git = self.untracking_scm | 134 git = self.untracking_git |
| 135 self._mkdir('added_dir') | 135 self._mkdir('added_dir') |
| 136 self._write_text_file('added_dir/added_file', 'new stuff') | 136 self._write_text_file('added_dir/added_file', 'new stuff') |
| 137 self._write_text_file('added_dir/another_added_file', 'more new stuff') | 137 self._write_text_file('added_dir/another_added_file', 'more new stuff') |
| 138 git.add_list(['added_dir']) | 138 git.add_list(['added_dir']) |
| 139 git.move('added_dir', 'moved_dir') | 139 git.move('added_dir', 'moved_dir') |
| 140 self.assertIn('moved_dir/added_file', git.added_files()) | 140 self.assertIn('moved_dir/added_file', git.added_files()) |
| 141 self.assertIn('moved_dir/another_added_file', git.added_files()) | 141 self.assertIn('moved_dir/another_added_file', git.added_files()) |
| 142 | 142 |
| 143 def test_remote_branch_ref(self): | 143 def test_remote_branch_ref(self): |
| 144 # This tests a protected method. pylint: disable=protected-access | 144 # This tests a protected method. pylint: disable=protected-access |
| 145 self.assertEqual(self.tracking_scm._remote_branch_ref(), 'refs/remotes/o
rigin/master') | 145 self.assertEqual(self.tracking_git._remote_branch_ref(), 'refs/remotes/o
rigin/master') |
| 146 self._chdir(self.untracking_checkout_path) | 146 self._chdir(self.untracking_checkout_path) |
| 147 self.assertRaises(ScriptError, self.untracking_scm._remote_branch_ref) | 147 self.assertRaises(ScriptError, self.untracking_git._remote_branch_ref) |
| 148 | 148 |
| 149 def test_create_patch(self): | 149 def test_create_patch(self): |
| 150 self._chdir(self.tracking_git_checkout_path) | 150 self._chdir(self.tracking_git_checkout_path) |
| 151 git = self.tracking_scm | 151 git = self.tracking_git |
| 152 self._write_text_file('test_file_commit1', 'contents') | 152 self._write_text_file('test_file_commit1', 'contents') |
| 153 self._run(['git', 'add', 'test_file_commit1']) | 153 self._run(['git', 'add', 'test_file_commit1']) |
| 154 git.commit_locally_with_message('message') | 154 git.commit_locally_with_message('message') |
| 155 git._patch_order = lambda: '' # pylint: disable=protected-access | 155 git._patch_order = lambda: '' # pylint: disable=protected-access |
| 156 patch = git.create_patch() | 156 patch = git.create_patch() |
| 157 self.assertNotRegexpMatches(patch, r'Subversion Revision:') | 157 self.assertNotRegexpMatches(patch, r'Subversion Revision:') |
| 158 | 158 |
| 159 def test_patches_have_filenames_with_prefixes(self): | 159 def test_patches_have_filenames_with_prefixes(self): |
| 160 self._chdir(self.tracking_git_checkout_path) | 160 self._chdir(self.tracking_git_checkout_path) |
| 161 git = self.tracking_scm | 161 git = self.tracking_git |
| 162 self._write_text_file('test_file_commit1', 'contents') | 162 self._write_text_file('test_file_commit1', 'contents') |
| 163 self._run(['git', 'add', 'test_file_commit1']) | 163 self._run(['git', 'add', 'test_file_commit1']) |
| 164 git.commit_locally_with_message('message') | 164 git.commit_locally_with_message('message') |
| 165 | 165 |
| 166 # Even if diff.noprefix is enabled, create_patch() produces diffs with p
refixes. | 166 # Even if diff.noprefix is enabled, create_patch() produces diffs with p
refixes. |
| 167 self._run(['git', 'config', 'diff.noprefix', 'true']) | 167 self._run(['git', 'config', 'diff.noprefix', 'true']) |
| 168 git._patch_order = lambda: '' # pylint: disable=protected-access | 168 git._patch_order = lambda: '' # pylint: disable=protected-access |
| 169 patch = git.create_patch() | 169 patch = git.create_patch() |
| 170 self.assertRegexpMatches(patch, r'^diff --git a/test_file_commit1 b/test
_file_commit1') | 170 self.assertRegexpMatches(patch, r'^diff --git a/test_file_commit1 b/test
_file_commit1') |
| 171 | 171 |
| 172 def test_rename_files(self): | 172 def test_rename_files(self): |
| 173 self._chdir(self.tracking_git_checkout_path) | 173 self._chdir(self.tracking_git_checkout_path) |
| 174 git = self.tracking_scm | 174 git = self.tracking_git |
| 175 git.move('foo_file', 'bar_file') | 175 git.move('foo_file', 'bar_file') |
| 176 git.commit_locally_with_message('message') | 176 git.commit_locally_with_message('message') |
| 177 | 177 |
| 178 def test_commit_position_from_git_log(self): | 178 def test_commit_position_from_git_log(self): |
| 179 # This tests a protected method. pylint: disable=protected-access | 179 # This tests a protected method. pylint: disable=protected-access |
| 180 git_log = """ | 180 git_log = """ |
| 181 commit 624c3081c0 | 181 commit 624c3081c0 |
| 182 Author: foobarbaz1 <foobarbaz1@chromium.org> | 182 Author: foobarbaz1 <foobarbaz1@chromium.org> |
| 183 Date: Mon Sep 28 19:10:30 2015 -0700 | 183 Date: Mon Sep 28 19:10:30 2015 -0700 |
| 184 | 184 |
| 185 Test foo bar baz qux 123. | 185 Test foo bar baz qux 123. |
| 186 | 186 |
| 187 BUG=000000 | 187 BUG=000000 |
| 188 | 188 |
| 189 Review URL: https://codereview.chromium.org/999999999 | 189 Review URL: https://codereview.chromium.org/999999999 |
| 190 | 190 |
| 191 Cr-Commit-Position: refs/heads/master@{#1234567} | 191 Cr-Commit-Position: refs/heads/master@{#1234567} |
| 192 """ | 192 """ |
| 193 self._chdir(self.tracking_git_checkout_path) | 193 self._chdir(self.tracking_git_checkout_path) |
| 194 git = self.tracking_scm | 194 git = self.tracking_git |
| 195 self.assertEqual(git._commit_position_from_git_log(git_log), 1234567) | 195 self.assertEqual(git._commit_position_from_git_log(git_log), 1234567) |
| 196 | 196 |
| 197 def test_timestamp_of_revision(self): | 197 def test_timestamp_of_revision(self): |
| 198 # This tests a protected method. pylint: disable=protected-access | 198 # This tests a protected method. pylint: disable=protected-access |
| 199 self._chdir(self.tracking_git_checkout_path) | 199 self._chdir(self.tracking_git_checkout_path) |
| 200 git = self.tracking_scm | 200 git = self.tracking_git |
| 201 position_regex = git._commit_position_regex_for_timestamp() | 201 position_regex = git._commit_position_regex_for_timestamp() |
| 202 git.most_recent_log_matching(position_regex, git.checkout_root) | 202 git.most_recent_log_matching(position_regex, git.checkout_root) |
| 203 | 203 |
| 204 | 204 |
| 205 class GitTestWithMock(unittest.TestCase): | 205 class GitTestWithMock(unittest.TestCase): |
| 206 | 206 |
| 207 def make_scm(self): | 207 def make_git(self): |
| 208 git = Git(cwd='.', executive=MockExecutive(), filesystem=MockFileSystem(
)) | 208 git = Git(cwd='.', executive=MockExecutive(), filesystem=MockFileSystem(
)) |
| 209 git.read_git_config = lambda *args, **kw: 'MOCKKEY:MOCKVALUE' | 209 git.read_git_config = lambda *args, **kw: 'MOCKKEY:MOCKVALUE' |
| 210 return git | 210 return git |
| 211 | 211 |
| 212 def _assert_timestamp_of_revision(self, canned_git_output, expected): | 212 def _assert_timestamp_of_revision(self, canned_git_output, expected): |
| 213 git = self.make_scm() | 213 git = self.make_git() |
| 214 git.find_checkout_root = lambda path: '' | 214 git.find_checkout_root = lambda path: '' |
| 215 # Modifying protected method. pylint: disable=protected-access | 215 # Modifying protected method. pylint: disable=protected-access |
| 216 git._run_git = lambda args: canned_git_output | 216 git._run_git = lambda args: canned_git_output |
| 217 self.assertEqual(git.timestamp_of_revision('some-path', '12345'), expect
ed) | 217 self.assertEqual(git.timestamp_of_revision('some-path', '12345'), expect
ed) |
| 218 | 218 |
| 219 def test_timestamp_of_revision_utc(self): | 219 def test_timestamp_of_revision_utc(self): |
| 220 self._assert_timestamp_of_revision('Date: 2013-02-08 08:05:49 +0000', '2
013-02-08T08:05:49Z') | 220 self._assert_timestamp_of_revision('Date: 2013-02-08 08:05:49 +0000', '2
013-02-08T08:05:49Z') |
| 221 | 221 |
| 222 def test_timestamp_of_revision_positive_timezone(self): | 222 def test_timestamp_of_revision_positive_timezone(self): |
| 223 self._assert_timestamp_of_revision('Date: 2013-02-08 01:02:03 +0130', '2
013-02-07T23:32:03Z') | 223 self._assert_timestamp_of_revision('Date: 2013-02-08 01:02:03 +0130', '2
013-02-07T23:32:03Z') |
| 224 | 224 |
| 225 def test_timestamp_of_revision_pacific_timezone(self): | 225 def test_timestamp_of_revision_pacific_timezone(self): |
| 226 self._assert_timestamp_of_revision('Date: 2013-02-08 01:55:21 -0800', '2
013-02-08T09:55:21Z') | 226 self._assert_timestamp_of_revision('Date: 2013-02-08 01:55:21 -0800', '2
013-02-08T09:55:21Z') |
| 227 | 227 |
| 228 def test_unstaged_files(self): | 228 def test_unstaged_files(self): |
| 229 scm = self.make_scm() | 229 git = self.make_git() |
| 230 status_lines = [ | 230 status_lines = [ |
| 231 ' M d/modified.txt', | 231 ' M d/modified.txt', |
| 232 ' D d/deleted.txt', | 232 ' D d/deleted.txt', |
| 233 '?? d/untracked.txt', | 233 '?? d/untracked.txt', |
| 234 'D d/deleted.txt', | 234 'D d/deleted.txt', |
| 235 'M d/modified-staged.txt', | 235 'M d/modified-staged.txt', |
| 236 'A d/added-staged.txt', | 236 'A d/added-staged.txt', |
| 237 ] | 237 ] |
| 238 # pylint: disable=protected-access | 238 # pylint: disable=protected-access |
| 239 scm._run_git = lambda args: '\x00'.join(status_lines) + '\x00' | 239 git._run_git = lambda args: '\x00'.join(status_lines) + '\x00' |
| 240 self.assertEqual( | 240 self.assertEqual( |
| 241 scm.unstaged_changes(), | 241 git.unstaged_changes(), |
| 242 { | 242 { |
| 243 'd/modified.txt': 'M', | 243 'd/modified.txt': 'M', |
| 244 'd/deleted.txt': 'D', | 244 'd/deleted.txt': 'D', |
| 245 'd/untracked.txt': '?', | 245 'd/untracked.txt': '?', |
| 246 }) | 246 }) |
| OLD | NEW |