Пример #1
0
 def test_modified_changelogs(self):
     scm = Mock()
     scm.checkout_root = "/foo/bar"
     scm.changed_files = lambda git_commit: ["file1", "ChangeLog", "relative/path/ChangeLog"]
     checkout = Checkout(scm)
     expected_changlogs = ["/foo/bar/ChangeLog", "/foo/bar/relative/path/ChangeLog"]
     self.assertEqual(checkout.modified_changelogs(git_commit=None), expected_changlogs)
Пример #2
0
 def test_commit_message_for_this_commit(self):
     checkout = Checkout(None)
     checkout.modified_changelogs = lambda: ["ChangeLog1", "ChangeLog2"]
     output = OutputCapture()
     expected_stderr = "Parsing ChangeLog: ChangeLog1\nParsing ChangeLog: ChangeLog2\n"
     commit_message = output.assert_outputs(self, checkout.commit_message_for_this_commit, expected_stderr=expected_stderr)
     self.assertEqual(commit_message.message(), self.expected_commit_message)
Пример #3
0
 def test_bug_id_for_this_commit(self):
     scm = Mock()
     checkout = Checkout(scm)
     checkout.commit_message_for_this_commit = lambda git_commit, changed_files=None: CommitMessage(
         ChangeLogEntry(_changelog1entry1).contents().splitlines())
     self.assertEqual(checkout.bug_id_for_this_commit(git_commit=None),
                      36629)
Пример #4
0
 def setUp(self):
     SVNTestRepository.setup(self)
     self._setup_git_clone_of_svn_repository()
     os.chdir(self.git_checkout_path)
     self.scm = detect_scm_system(self.git_checkout_path)
     # For historical reasons, we test some checkout code here too.
     self.checkout = Checkout(self.scm)
Пример #5
0
 def test_bug_id_for_revision(self):
     scm = Mock()
     scm.committer_email_for_revision = lambda revision: "*****@*****.**"
     checkout = Checkout(scm)
     checkout.changelog_entries_for_revision = lambda revision: [
         ChangeLogEntry(_changelog1entry1)
     ]
     self.assertEqual(checkout.bug_id_for_revision(4), 36629)
Пример #6
0
 def test_latest_entry_for_changelog_at_revision(self):
     scm = Mock()
     def mock_contents_at_revision(changelog_path, revision):
         self.assertEqual(changelog_path, "foo")
         self.assertEqual(revision, "bar")
         return _changelog1
     scm.contents_at_revision = mock_contents_at_revision
     checkout = Checkout(scm)
     entry = checkout._latest_entry_for_changelog_at_revision("foo", "bar")
     self.assertEqual(entry.contents(), _changelog1entry1)
Пример #7
0
 def test_latest_entry_for_changelog_at_revision(self):
     scm = Mock()
     def mock_contents_at_revision(changelog_path, revision):
         self.assertEqual(changelog_path, "foo")
         self.assertEqual(revision, "bar")
         # contents_at_revision is expected to return a byte array (str)
         # so we encode our unicode ChangeLog down to a utf-8 stream.
         return _changelog1.encode("utf-8")
     scm.contents_at_revision = mock_contents_at_revision
     checkout = Checkout(scm)
     entry = checkout._latest_entry_for_changelog_at_revision("foo", "bar")
     self.assertEqual(entry.contents(), _changelog1entry1)
Пример #8
0
 def test_modified_changelogs(self):
     scm = Mock()
     scm.checkout_root = "/foo/bar"
     scm.changed_files = lambda git_commit: [
         "file1", "ChangeLog", "relative/path/ChangeLog"
     ]
     checkout = Checkout(scm)
     expected_changlogs = [
         "/foo/bar/ChangeLog", "/foo/bar/relative/path/ChangeLog"
     ]
     self.assertEqual(checkout.modified_changelogs(git_commit=None),
                      expected_changlogs)
Пример #9
0
 def test_commit_info_for_revision(self):
     scm = Mock()
     scm.committer_email_for_revision = lambda revision: "*****@*****.**"
     checkout = Checkout(scm)
     checkout.changelog_entries_for_revision = lambda revision: [ChangeLogEntry(_changelog1entry1)]
     commitinfo = checkout.commit_info_for_revision(4)
     self.assertEqual(commitinfo.bug_id(), 36629)
     self.assertEqual(commitinfo.author_name(), "Eric Seidel")
     self.assertEqual(commitinfo.author_email(), "*****@*****.**")
     self.assertEqual(commitinfo.reviewer_text(), None)
     self.assertEqual(commitinfo.reviewer(), None)
     self.assertEqual(commitinfo.committer_email(), "*****@*****.**")
     self.assertEqual(commitinfo.committer(), None)
Пример #10
0
 def test_commit_message_for_this_commit(self):
     checkout = Checkout(None)
     checkout.modified_changelogs = lambda git_commit, changed_files=None: [
         "ChangeLog1", "ChangeLog2"
     ]
     output = OutputCapture()
     expected_stderr = "Parsing ChangeLog: ChangeLog1\nParsing ChangeLog: ChangeLog2\n"
     commit_message = output.assert_outputs(
         self,
         checkout.commit_message_for_this_commit,
         kwargs={"git_commit": None},
         expected_stderr=expected_stderr)
     self.assertEqual(commit_message.message(),
                      self.expected_commit_message)
Пример #11
0
    def test_latest_entry_for_changelog_at_revision(self):
        scm = Mock()

        def mock_contents_at_revision(changelog_path, revision):
            self.assertEqual(changelog_path, "foo")
            self.assertEqual(revision, "bar")
            # contents_at_revision is expected to return a byte array (str)
            # so we encode our unicode ChangeLog down to a utf-8 stream.
            return _changelog1.encode("utf-8")

        scm.contents_at_revision = mock_contents_at_revision
        checkout = Checkout(scm)
        entry = checkout._latest_entry_for_changelog_at_revision("foo", "bar")
        self.assertEqual(entry.contents(), _changelog1entry1)
Пример #12
0
 def setUp(self):
     SVNTestRepository.setup(self)
     self._setup_git_clone_of_svn_repository()
     os.chdir(self.git_checkout_path)
     self.scm = detect_scm_system(self.git_checkout_path)
     # For historical reasons, we test some checkout code here too.
     self.checkout = Checkout(self.scm)
Пример #13
0
 def test_apply_git_patch_force(self):
     scm = detect_scm_system(self.git_checkout_path)
     patch = self._create_patch(_git_diff('HEAD~2..HEAD'))
     self._setup_webkittools_scripts_symlink(scm)
     self.assertRaises(ScriptError,
                       Checkout(scm).apply_patch,
                       patch,
                       force=True)
Пример #14
0
 def test_apply_git_patch(self):
     scm = detect_scm_system(self.git_checkout_path)
     # We carefullly pick a diff which does not have a directory addition
     # as currently svn-apply will error out when trying to remove directories
     # in Git: https://bugs.webkit.org/show_bug.cgi?id=34871
     patch = self._create_patch(_git_diff('HEAD..HEAD^'))
     self._setup_webkittools_scripts_symlink(scm)
     Checkout(scm).apply_patch(patch)
Пример #15
0
 def test_apply_svn_patch_force(self):
     scm = detect_scm_system(self.svn_checkout_path)
     patch = self._create_patch(_svn_diff("-r3:5"))
     self._setup_webkittools_scripts_symlink(scm)
     self.assertRaises(ScriptError,
                       Checkout(scm).apply_patch,
                       patch,
                       force=True)
Пример #16
0
    def setUp(self):
        self.original_dir = os.getcwd()

        SVNTestRepository.setup(self)
        self._setup_git_checkout()
        self.scm = detect_scm_system(self.git_checkout_path)
        # For historical reasons, we test some checkout code here too.
        self.checkout = Checkout(self.scm)
Пример #17
0
    def test_changelog_entries_for_revision(self):
        scm = Mock()
        scm.changed_files_for_revision = lambda revision: [
            'foo/ChangeLog', 'bar/ChangeLog'
        ]
        checkout = Checkout(scm)

        def mock_latest_entry_for_changelog_at_revision(path, revision):
            if path == "foo/ChangeLog":
                return 'foo'
            raise ScriptError()

        checkout._latest_entry_for_changelog_at_revision = mock_latest_entry_for_changelog_at_revision

        # Even though fetching one of the entries failed, the other should succeed.
        entries = checkout.changelog_entries_for_revision(1)
        self.assertEqual(len(entries), 1)
        self.assertEqual(entries[0], 'foo')
Пример #18
0
    def test_suggested_reviewers(self):
        def mock_changelog_entries_for_revision(revision):
            if revision % 2 == 0:
                return [ChangeLogEntry(_changelog1entry1)]
            return [ChangeLogEntry(_changelog1entry2)]

        def mock_revisions_changing_file(path, limit=5):
            if path.endswith("ChangeLog"):
                return [3]
            return [4, 8]

        scm = Mock()
        scm.checkout_root = "/foo/bar"
        scm.changed_files = lambda git_commit: ["file1", "file2", "relative/path/ChangeLog"]
        scm.revisions_changing_file = mock_revisions_changing_file
        checkout = Checkout(scm)
        checkout.changelog_entries_for_revision = mock_changelog_entries_for_revision
        reviewers = checkout.suggested_reviewers(git_commit=None)
        reviewer_names = [reviewer.full_name for reviewer in reviewers]
        self.assertEqual(reviewer_names, [u'Tor Arne Vestb\xf8'])
Пример #19
0
    def test_suggested_reviewers(self):
        def mock_changelog_entries_for_revision(revision):
            if revision % 2 == 0:
                return [ChangeLogEntry(_changelog1entry1)]
            return [ChangeLogEntry(_changelog1entry2)]

        def mock_revisions_changing_file(path, limit=5):
            if path.endswith("ChangeLog"):
                return [3]
            return [4, 8]

        scm = Mock()
        scm.checkout_root = "/foo/bar"
        scm.changed_files = lambda git_commit: [
            "file1", "file2", "relative/path/ChangeLog"
        ]
        scm.revisions_changing_file = mock_revisions_changing_file
        checkout = Checkout(scm)
        checkout.changelog_entries_for_revision = mock_changelog_entries_for_revision
        reviewers = checkout.suggested_reviewers(git_commit=None)
        reviewer_names = [reviewer.full_name for reviewer in reviewers]
        self.assertEqual(reviewer_names, [u'Tor Arne Vestb\xf8'])
Пример #20
0
    def test_commit_info_for_revision(self):
        scm = Mock()
        scm.committer_email_for_revision = lambda revision: "*****@*****.**"
        checkout = Checkout(scm)
        checkout.changelog_entries_for_revision = lambda revision: [
            ChangeLogEntry(_changelog1entry1)
        ]
        commitinfo = checkout.commit_info_for_revision(4)
        self.assertEqual(commitinfo.bug_id(), 36629)
        self.assertEqual(commitinfo.author_name(), u"Tor Arne Vestb\u00f8")
        self.assertEqual(commitinfo.author_email(), "*****@*****.**")
        self.assertEqual(commitinfo.reviewer_text(), None)
        self.assertEqual(commitinfo.reviewer(), None)
        self.assertEqual(commitinfo.committer_email(), "*****@*****.**")
        self.assertEqual(commitinfo.committer(), None)

        checkout.changelog_entries_for_revision = lambda revision: []
        self.assertEqual(checkout.commit_info_for_revision(1), None)
Пример #21
0
class GitSVNTest(SCMTest):

    def _setup_git_checkout(self):
        self.git_checkout_path = tempfile.mkdtemp(suffix="git_test_checkout")
        # --quiet doesn't make git svn silent, so we use run_silent to redirect output
        run_silent(['git', 'svn', 'clone', '-T', 'trunk', self.svn_repo_url, self.git_checkout_path])
        os.chdir(self.git_checkout_path)

    def _tear_down_git_checkout(self):
        # Change back to a valid directory so that later calls to os.getcwd() do not fail.
        os.chdir(self.original_dir)
        run_command(['rm', '-rf', self.git_checkout_path])

    def setUp(self):
        self.original_dir = os.getcwd()

        SVNTestRepository.setup(self)
        self._setup_git_checkout()
        self.scm = detect_scm_system(self.git_checkout_path)
        # For historical reasons, we test some checkout code here too.
        self.checkout = Checkout(self.scm)

    def tearDown(self):
        SVNTestRepository.tear_down(self)
        self._tear_down_git_checkout()

    def test_detection(self):
        scm = detect_scm_system(self.git_checkout_path)
        self.assertEqual(scm.display_name(), "git")
        self.assertEqual(scm.supports_local_commits(), True)

    def test_read_git_config(self):
        key = 'test.git-config'
        value = 'git-config value'
        run_command(['git', 'config', key, value])
        self.assertEqual(self.scm.read_git_config(key), value)

    def test_local_commits(self):
        test_file = os.path.join(self.git_checkout_path, 'test_file')
        write_into_file_at_path(test_file, 'foo')
        run_command(['git', 'commit', '-a', '-m', 'local commit'])

        self.assertEqual(len(self.scm.local_commits()), 1)

    def test_discard_local_commits(self):
        test_file = os.path.join(self.git_checkout_path, 'test_file')
        write_into_file_at_path(test_file, 'foo')
        run_command(['git', 'commit', '-a', '-m', 'local commit'])

        self.assertEqual(len(self.scm.local_commits()), 1)
        self.scm.discard_local_commits()
        self.assertEqual(len(self.scm.local_commits()), 0)

    def test_delete_branch(self):
        new_branch = 'foo'

        run_command(['git', 'checkout', '-b', new_branch])
        self.assertEqual(run_command(['git', 'symbolic-ref', 'HEAD']).strip(), 'refs/heads/' + new_branch)

        run_command(['git', 'checkout', '-b', 'bar'])
        self.scm.delete_branch(new_branch)

        self.assertFalse(re.search(r'foo', run_command(['git', 'branch'])))

    def test_remote_merge_base(self):
        # Diff to merge-base should include working-copy changes,
        # which the diff to svn_branch.. doesn't.
        test_file = os.path.join(self.git_checkout_path, 'test_file')
        write_into_file_at_path(test_file, 'foo')

        diff_to_common_base = _git_diff(self.scm.remote_branch_ref() + '..')
        diff_to_merge_base = _git_diff(self.scm.remote_merge_base())

        self.assertFalse(re.search(r'foo', diff_to_common_base))
        self.assertTrue(re.search(r'foo', diff_to_merge_base))

    def test_rebase_in_progress(self):
        svn_test_file = os.path.join(self.svn_checkout_path, 'test_file')
        write_into_file_at_path(svn_test_file, "svn_checkout")
        run_command(['svn', 'commit', '--message', 'commit to conflict with git commit'], cwd=self.svn_checkout_path)

        git_test_file = os.path.join(self.git_checkout_path, 'test_file')
        write_into_file_at_path(git_test_file, "git_checkout")
        run_command(['git', 'commit', '-a', '-m', 'commit to be thrown away by rebase abort'])

        # --quiet doesn't make git svn silent, so use run_silent to redirect output
        self.assertRaises(ScriptError, run_silent, ['git', 'svn', '--quiet', 'rebase']) # Will fail due to a conflict leaving us mid-rebase.

        scm = detect_scm_system(self.git_checkout_path)
        self.assertTrue(scm.rebase_in_progress())

        # Make sure our cleanup works.
        scm.clean_working_directory()
        self.assertFalse(scm.rebase_in_progress())

        # Make sure cleanup doesn't throw when no rebase is in progress.
        scm.clean_working_directory()

    def test_commitish_parsing(self):
        scm = detect_scm_system(self.git_checkout_path)
    
        # Multiple revisions are cherry-picked.
        self.assertEqual(len(scm.commit_ids_from_commitish_arguments(['HEAD~2'])), 1)
        self.assertEqual(len(scm.commit_ids_from_commitish_arguments(['HEAD', 'HEAD~2'])), 2)
    
        # ... is an invalid range specifier
        self.assertRaises(ScriptError, scm.commit_ids_from_commitish_arguments, ['trunk...HEAD'])

    def test_commitish_order(self):
        scm = detect_scm_system(self.git_checkout_path)

        commit_range = 'HEAD~3..HEAD'

        actual_commits = scm.commit_ids_from_commitish_arguments([commit_range])
        expected_commits = []
        expected_commits += reversed(run_command(['git', 'rev-list', commit_range]).splitlines())

        self.assertEqual(actual_commits, expected_commits)

    def test_apply_git_patch(self):
        scm = detect_scm_system(self.git_checkout_path)
        # We carefullly pick a diff which does not have a directory addition
        # as currently svn-apply will error out when trying to remove directories
        # in Git: https://bugs.webkit.org/show_bug.cgi?id=34871
        patch = self._create_patch(_git_diff('HEAD..HEAD^'))
        self._setup_webkittools_scripts_symlink(scm)
        Checkout(scm).apply_patch(patch)

    def test_apply_git_patch_force(self):
        scm = detect_scm_system(self.git_checkout_path)
        patch = self._create_patch(_git_diff('HEAD~2..HEAD'))
        self._setup_webkittools_scripts_symlink(scm)
        self.assertRaises(ScriptError, Checkout(scm).apply_patch, patch, force=True)

    def test_commit_text_parsing(self):
        write_into_file_at_path('test_file', 'more test content')
        self.scm.commit_locally_with_message("another test commit")
        commit_text = self.scm.commit_with_message("another test commit")
        self.assertEqual(self.scm.svn_revision_from_commit_text(commit_text), '6')

        self.scm.dryrun = True
        write_into_file_at_path('test_file', 'still more test content')
        self.scm.commit_locally_with_message("yet another test commit")
        commit_text = self.scm.commit_with_message("yet another test commit")
        self.assertEqual(self.scm.svn_revision_from_commit_text(commit_text), '0')

    def _one_local_commit_plus_working_copy_changes(self):
        write_into_file_at_path('test_file_commit1', 'more test content')
        run_command(['git', 'add', 'test_file_commit1'])
        self.scm.commit_locally_with_message("another test commit")

        write_into_file_at_path('test_file_commit2', 'still more test content')
        run_command(['git', 'add', 'test_file_commit2'])

    def test_commit_with_message_working_copy_only(self):
        write_into_file_at_path('test_file_commit1', 'more test content')
        run_command(['git', 'add', 'test_file_commit1'])
        scm = detect_scm_system(self.git_checkout_path)
        commit_text = scm.commit_with_message("yet another test commit")

        self.assertEqual(scm.svn_revision_from_commit_text(commit_text), '6')
        svn_log = run_command(['git', 'svn', 'log', '--limit=1', '--verbose'])
        self.assertTrue(re.search(r'test_file_commit1', svn_log))

    def test_commit_with_message_squashed(self):
        self._one_local_commit_plus_working_copy_changes()
        scm = detect_scm_system(self.git_checkout_path)
        commit_text = scm.commit_with_message("yet another test commit", squash=True)

        self.assertEqual(scm.svn_revision_from_commit_text(commit_text), '6')
        svn_log = run_command(['git', 'svn', 'log', '--limit=1', '--verbose'])
        self.assertTrue(re.search(r'test_file_commit2', svn_log))
        self.assertTrue(re.search(r'test_file_commit1', svn_log))

    def _two_local_commits(self):
        write_into_file_at_path('test_file_commit1', 'more test content')
        run_command(['git', 'add', 'test_file_commit1'])
        self.scm.commit_locally_with_message("another test commit")

        write_into_file_at_path('test_file_commit2', 'still more test content')
        run_command(['git', 'add', 'test_file_commit2'])
        self.scm.commit_locally_with_message("yet another test commit")

    def _three_local_commits(self):
        write_into_file_at_path('test_file_commit0', 'more test content')
        run_command(['git', 'add', 'test_file_commit0'])
        self.scm.commit_locally_with_message("another test commit")
        self._two_local_commits()

    def test_commit_with_message_git_commit(self):
        self._two_local_commits()

        scm = detect_scm_system(self.git_checkout_path)
        commit_text = scm.commit_with_message("another test commit", git_commit="HEAD^")
        self.assertEqual(scm.svn_revision_from_commit_text(commit_text), '6')

        svn_log = run_command(['git', 'svn', 'log', '--limit=1', '--verbose'])
        self.assertTrue(re.search(r'test_file_commit1', svn_log))
        self.assertFalse(re.search(r'test_file_commit2', svn_log))

    def test_commit_with_message_git_commit_range(self):
        self._three_local_commits()

        scm = detect_scm_system(self.git_checkout_path)
        commit_text = scm.commit_with_message("another test commit", git_commit="HEAD~2..HEAD")
        self.assertEqual(scm.svn_revision_from_commit_text(commit_text), '6')

        svn_log = run_command(['git', 'svn', 'log', '--limit=1', '--verbose'])
        self.assertFalse(re.search(r'test_file_commit0', svn_log))
        self.assertTrue(re.search(r'test_file_commit1', svn_log))
        self.assertTrue(re.search(r'test_file_commit2', svn_log))

    def test_commit_with_message_multiple_local_commits(self):
        self._two_local_commits()
        scm = detect_scm_system(self.git_checkout_path)
        self.assertRaises(ScriptError, scm.commit_with_message, ["another test commit"])

    def test_commit_with_message_multiple_local_commits_and_working_copy(self):
        self._two_local_commits()
        write_into_file_at_path('test_file_commit1', 'working copy change')
        scm = detect_scm_system(self.git_checkout_path)
        self.assertRaises(ScriptError, scm.commit_with_message, ["another test commit"])

    def test_commit_with_message_git_commit_and_working_copy(self):
        self._two_local_commits()
        write_into_file_at_path('test_file_commit1', 'working copy change')
        scm = detect_scm_system(self.git_checkout_path)
        self.assertRaises(ScriptError, scm.commit_with_message, ["another test commit", 'git_commit="HEAD^"'])

    def test_commit_with_message_multiple_local_commits_no_squash(self):
        self._two_local_commits()
        scm = detect_scm_system(self.git_checkout_path)
        commit_text = scm.commit_with_message("yet another test commit", squash=False)
        self.assertEqual(scm.svn_revision_from_commit_text(commit_text), '6')

        svn_log = run_command(['git', 'svn', 'log', '--limit=1', '--verbose'])
        self.assertTrue(re.search(r'test_file_commit2', svn_log))
        self.assertFalse(re.search(r'test_file_commit1', svn_log))

        svn_log = run_command(['git', 'svn', 'log', '--limit=2', '--verbose'])
        self.assertTrue(re.search(r'test_file_commit1', svn_log))

    def test_commit_with_message_multiple_local_commits_squash(self):
        self._two_local_commits()
        scm = detect_scm_system(self.git_checkout_path)
        commit_text = scm.commit_with_message("yet another test commit", squash=True)
        self.assertEqual(scm.svn_revision_from_commit_text(commit_text), '6')

        svn_log = run_command(['git', 'svn', 'log', '--limit=1', '--verbose'])
        self.assertTrue(re.search(r'test_file_commit2', svn_log))
        self.assertTrue(re.search(r'test_file_commit1', svn_log))

    def test_commit_with_message_not_synced_squash(self):
        run_command(['git', 'checkout', '-b', 'my-branch', 'trunk~3'])
        self._two_local_commits()
        scm = detect_scm_system(self.git_checkout_path)
        self.assertRaises(ScriptError, scm.commit_with_message, "another test commit", squash=True)

    def test_remote_branch_ref(self):
        self.assertEqual(self.scm.remote_branch_ref(), 'refs/remotes/trunk')

    def test_reverse_diff(self):
        self._shared_test_reverse_diff()

    def test_diff_for_revision(self):
        self._shared_test_diff_for_revision()

    def test_svn_apply_git_patch(self):
        self._shared_test_svn_apply_git_patch()

    def test_create_patch_local_plus_working_copy(self):
        self._one_local_commit_plus_working_copy_changes()
        scm = detect_scm_system(self.git_checkout_path)
        self.assertRaises(ScriptError, scm.create_patch)

    def test_create_patch_multiple_local_commits(self):
        self._two_local_commits()
        scm = detect_scm_system(self.git_checkout_path)
        self.assertRaises(ScriptError, scm.create_patch)

    def test_create_patch_squashed(self):
        self._one_local_commit_plus_working_copy_changes()
        scm = detect_scm_system(self.git_checkout_path)
        patch = scm.create_patch(squash=True)
        self.assertTrue(re.search(r'test_file_commit2', patch))
        self.assertTrue(re.search(r'test_file_commit1', patch))

    def test_create_patch_not_squashed(self):
        self._one_local_commit_plus_working_copy_changes()
        scm = detect_scm_system(self.git_checkout_path)
        patch = scm.create_patch(squash=False)
        self.assertTrue(re.search(r'test_file_commit2', patch))
        self.assertFalse(re.search(r'test_file_commit1', patch))

    def test_create_patch_git_commit(self):
        self._two_local_commits()
        scm = detect_scm_system(self.git_checkout_path)
        patch = scm.create_patch(git_commit="HEAD^")
        self.assertTrue(re.search(r'test_file_commit1', patch))
        self.assertFalse(re.search(r'test_file_commit2', patch))

    def test_create_patch_git_commit_range(self):
        self._three_local_commits()
        scm = detect_scm_system(self.git_checkout_path)
        patch = scm.create_patch(git_commit="HEAD~2..HEAD")
        self.assertFalse(re.search(r'test_file_commit0', patch))
        self.assertTrue(re.search(r'test_file_commit2', patch))
        self.assertTrue(re.search(r'test_file_commit1', patch))

    def test_create_patch_multiple_local_commits_no_squash(self):
        self._two_local_commits()
        scm = detect_scm_system(self.git_checkout_path)
        patch = scm.create_patch(squash=False)
        # FIXME: It's weird that with squash=False, create_patch/changed_files ignores local commits,
        # but commit_with_message commits them.
        self.assertTrue(patch == "")

    def test_create_patch_multiple_local_commits_squash(self):
        self._two_local_commits()
        scm = detect_scm_system(self.git_checkout_path)
        patch = scm.create_patch(squash=True)
        self.assertTrue(re.search(r'test_file_commit2', patch))
        self.assertTrue(re.search(r'test_file_commit1', patch))

    def test_create_patch_not_synced_squash(self):
        run_command(['git', 'checkout', '-b', 'my-branch', 'trunk~3'])
        self._two_local_commits()
        scm = detect_scm_system(self.git_checkout_path)
        self.assertRaises(ScriptError, scm.create_patch, squash=True)

    def test_create_binary_patch(self):
        # Create a git binary patch and check the contents.
        scm = detect_scm_system(self.git_checkout_path)
        test_file_name = 'binary_file'
        test_file_path = os.path.join(self.git_checkout_path, test_file_name)
        file_contents = ''.join(map(chr, range(256)))
        write_into_file_at_path(test_file_path, file_contents, encoding=None)
        run_command(['git', 'add', test_file_name])
        patch = scm.create_patch()
        self.assertTrue(re.search(r'\nliteral 0\n', patch))
        self.assertTrue(re.search(r'\nliteral 256\n', patch))

        # Check if we can apply the created patch.
        run_command(['git', 'rm', '-f', test_file_name])
        self._setup_webkittools_scripts_symlink(scm)
        self.checkout.apply_patch(self._create_patch(patch))
        self.assertEqual(file_contents, read_from_path(test_file_path, encoding=None))

        # Check if we can create a patch from a local commit.
        write_into_file_at_path(test_file_path, file_contents, encoding=None)
        run_command(['git', 'add', test_file_name])
        run_command(['git', 'commit', '-m', 'binary diff'])
        patch_from_local_commit = scm.create_patch('HEAD')
        self.assertTrue(re.search(r'\nliteral 0\n', patch_from_local_commit))
        self.assertTrue(re.search(r'\nliteral 256\n', patch_from_local_commit))

    def test_changed_files_local_plus_working_copy(self):
        self._one_local_commit_plus_working_copy_changes()
        scm = detect_scm_system(self.git_checkout_path)
        self.assertRaises(ScriptError, scm.changed_files)

    def test_changed_files_multiple_local_commits(self):
        self._two_local_commits()
        scm = detect_scm_system(self.git_checkout_path)
        self.assertRaises(ScriptError, scm.changed_files)

    def test_changed_files_squashed(self):
        self._one_local_commit_plus_working_copy_changes()
        scm = detect_scm_system(self.git_checkout_path)
        files = scm.changed_files(squash=True)
        self.assertTrue('test_file_commit2' in files)
        self.assertTrue('test_file_commit1' in files)

    def test_changed_files_not_squashed(self):
        self._one_local_commit_plus_working_copy_changes()
        scm = detect_scm_system(self.git_checkout_path)
        files = scm.changed_files(squash=False)
        self.assertTrue('test_file_commit2' in files)
        self.assertFalse('test_file_commit1' in files)

    def test_changed_files_git_commit(self):
        self._two_local_commits()
        scm = detect_scm_system(self.git_checkout_path)
        files = scm.changed_files(git_commit="HEAD^")
        self.assertTrue('test_file_commit1' in files)
        self.assertFalse('test_file_commit2' in files)

    def test_changed_files_git_commit_range(self):
        self._three_local_commits()
        scm = detect_scm_system(self.git_checkout_path)
        files = scm.changed_files(git_commit="HEAD~2..HEAD")
        self.assertTrue('test_file_commit0' not in files)
        self.assertTrue('test_file_commit1' in files)
        self.assertTrue('test_file_commit2' in files)

    def test_changed_files_multiple_local_commits_no_squash(self):
        self._two_local_commits()
        scm = detect_scm_system(self.git_checkout_path)
        files = scm.changed_files(squash=False)
        # FIXME: It's weird that with squash=False, create_patch/changed_files ignores local commits,
        # but commit_with_message commits them.
        self.assertTrue(len(files) == 0)

    def test_changed_files_multiple_local_commits_squash(self):
        self._two_local_commits()
        scm = detect_scm_system(self.git_checkout_path)
        files = scm.changed_files(squash=True)
        self.assertTrue('test_file_commit2' in files)
        self.assertTrue('test_file_commit1' in files)

    def test_changed_files_not_synced_squash(self):
        run_command(['git', 'checkout', '-b', 'my-branch', 'trunk~3'])
        self._two_local_commits()
        scm = detect_scm_system(self.git_checkout_path)
        self.assertRaises(ScriptError, scm.changed_files, squash=True)

    def test_changed_files(self):
        self._shared_test_changed_files()

    def test_changed_files_for_revision(self):
        self._shared_test_changed_files_for_revision()

    def test_contents_at_revision(self):
        self._shared_test_contents_at_revision()

    def test_added_files(self):
        self._shared_test_added_files()

    def test_committer_email_for_revision(self):
        self._shared_test_committer_email_for_revision()
Пример #22
0
class SVNTest(SCMTest):

    @staticmethod
    def _set_date_and_reviewer(changelog_entry):
        # Joe Cool matches the reviewer set in SCMTest._create_patch
        changelog_entry = changelog_entry.replace('REVIEWER_HERE', 'Joe Cool')
        # svn-apply will update ChangeLog entries with today's date.
        return changelog_entry.replace('DATE_HERE', date.today().isoformat())

    def test_svn_apply(self):
        first_entry = """2009-10-26  Eric Seidel  <*****@*****.**>

        Reviewed by Foo Bar.

        Most awesome change ever.

        * scm_unittest.py:
"""
        intermediate_entry = """2009-10-27  Eric Seidel  <*****@*****.**>

        Reviewed by Baz Bar.

        A more awesomer change yet!

        * scm_unittest.py:
"""
        one_line_overlap_patch = """Index: ChangeLog
===================================================================
--- ChangeLog	(revision 5)
+++ ChangeLog	(working copy)
@@ -1,5 +1,13 @@
 2009-10-26  Eric Seidel  <*****@*****.**>
 
+        Reviewed by NOBODY (OOPS!).
+
+        Second most awesome change ever.
+
+        * scm_unittest.py:
+
+2009-10-26  Eric Seidel  <*****@*****.**>
+
         Reviewed by Foo Bar.
 
         Most awesome change ever.
"""
        one_line_overlap_entry = """DATE_HERE  Eric Seidel  <*****@*****.**>

        Reviewed by REVIEWER_HERE.

        Second most awesome change ever.

        * scm_unittest.py:
"""
        two_line_overlap_patch = """Index: ChangeLog
===================================================================
--- ChangeLog	(revision 5)
+++ ChangeLog	(working copy)
@@ -2,6 +2,14 @@
 
         Reviewed by Foo Bar.
 
+        Second most awesome change ever.
+
+        * scm_unittest.py:
+
+2009-10-26  Eric Seidel  <*****@*****.**>
+
+        Reviewed by Foo Bar.
+
         Most awesome change ever.
 
         * scm_unittest.py:
"""
        two_line_overlap_entry = """DATE_HERE  Eric Seidel  <*****@*****.**>

        Reviewed by Foo Bar.

        Second most awesome change ever.

        * scm_unittest.py:
"""
        write_into_file_at_path('ChangeLog', first_entry)
        run_command(['svn', 'add', 'ChangeLog'])
        run_command(['svn', 'commit', '--quiet', '--message', 'ChangeLog commit'])

        # Patch files were created against just 'first_entry'.
        # Add a second commit to make svn-apply have to apply the patches with fuzz.
        changelog_contents = "%s\n%s" % (intermediate_entry, first_entry)
        write_into_file_at_path('ChangeLog', changelog_contents)
        run_command(['svn', 'commit', '--quiet', '--message', 'Intermediate commit'])

        self._setup_webkittools_scripts_symlink(self.scm)
        self.checkout.apply_patch(self._create_patch(one_line_overlap_patch))
        expected_changelog_contents = "%s\n%s" % (self._set_date_and_reviewer(one_line_overlap_entry), changelog_contents)
        self.assertEquals(read_from_path('ChangeLog'), expected_changelog_contents)

        self.scm.revert_files(['ChangeLog'])
        self.checkout.apply_patch(self._create_patch(two_line_overlap_patch))
        expected_changelog_contents = "%s\n%s" % (self._set_date_and_reviewer(two_line_overlap_entry), changelog_contents)
        self.assertEquals(read_from_path('ChangeLog'), expected_changelog_contents)

    def setUp(self):
        SVNTestRepository.setup(self)
        os.chdir(self.svn_checkout_path)
        self.scm = detect_scm_system(self.svn_checkout_path)
        # For historical reasons, we test some checkout code here too.
        self.checkout = Checkout(self.scm)

    def tearDown(self):
        SVNTestRepository.tear_down(self)

    def test_detect_scm_system_relative_url(self):
        scm = detect_scm_system(".")
        # I wanted to assert that we got the right path, but there was some
        # crazy magic with temp folder names that I couldn't figure out.
        self.assertTrue(scm.checkout_root)

    def test_create_patch_is_full_patch(self):
        test_dir_path = os.path.join(self.svn_checkout_path, "test_dir2")
        os.mkdir(test_dir_path)
        test_file_path = os.path.join(test_dir_path, 'test_file2')
        write_into_file_at_path(test_file_path, 'test content')
        run_command(['svn', 'add', 'test_dir2'])

        # create_patch depends on 'svn-create-patch', so make a dummy version.
        scripts_path = os.path.join(self.svn_checkout_path, 'WebKitTools', 'Scripts')
        os.makedirs(scripts_path)
        create_patch_path = os.path.join(scripts_path, 'svn-create-patch')
        write_into_file_at_path(create_patch_path, '#!/bin/sh\necho $PWD') # We could pass -n to prevent the \n, but not all echo accept -n.
        os.chmod(create_patch_path, stat.S_IXUSR | stat.S_IRUSR)

        # Change into our test directory and run the create_patch command.
        os.chdir(test_dir_path)
        scm = detect_scm_system(test_dir_path)
        self.assertEqual(scm.checkout_root, self.svn_checkout_path) # Sanity check that detection worked right.
        patch_contents = scm.create_patch()
        # Our fake 'svn-create-patch' returns $PWD instead of a patch, check that it was executed from the root of the repo.
        self.assertEqual("%s\n" % os.path.realpath(scm.checkout_root), patch_contents) # Add a \n because echo adds a \n.

    def test_detection(self):
        scm = detect_scm_system(self.svn_checkout_path)
        self.assertEqual(scm.display_name(), "svn")
        self.assertEqual(scm.supports_local_commits(), False)

    def test_apply_small_binary_patch(self):
        patch_contents = """Index: test_file.swf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: test_file.swf
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream


Q1dTBx0AAAB42itg4GlgYJjGwMDDyODMxMDw34GBgQEAJPQDJA==
"""
        expected_contents = base64.b64decode("Q1dTBx0AAAB42itg4GlgYJjGwMDDyODMxMDw34GBgQEAJPQDJA==")
        self._setup_webkittools_scripts_symlink(self.scm)
        patch_file = self._create_patch(patch_contents)
        self.checkout.apply_patch(patch_file)
        actual_contents = read_from_path("test_file.swf", encoding=None)
        self.assertEqual(actual_contents, expected_contents)

    def test_apply_svn_patch(self):
        scm = detect_scm_system(self.svn_checkout_path)
        patch = self._create_patch(_svn_diff("-r5:4"))
        self._setup_webkittools_scripts_symlink(scm)
        Checkout(scm).apply_patch(patch)

    def test_apply_svn_patch_force(self):
        scm = detect_scm_system(self.svn_checkout_path)
        patch = self._create_patch(_svn_diff("-r3:5"))
        self._setup_webkittools_scripts_symlink(scm)
        self.assertRaises(ScriptError, Checkout(scm).apply_patch, patch, force=True)

    def test_commit_logs(self):
        # Commits have dates and usernames in them, so we can't just direct compare.
        self.assertTrue(re.search('fourth commit', self.scm.last_svn_commit_log()))
        self.assertTrue(re.search('second commit', self.scm.svn_commit_log(3)))

    def _shared_test_commit_with_message(self, username=None):
        write_into_file_at_path('test_file', 'more test content')
        commit_text = self.scm.commit_with_message("another test commit", username)
        self.assertEqual(self.scm.svn_revision_from_commit_text(commit_text), '6')

        self.scm.dryrun = True
        write_into_file_at_path('test_file', 'still more test content')
        commit_text = self.scm.commit_with_message("yet another test commit", username)
        self.assertEqual(self.scm.svn_revision_from_commit_text(commit_text), '0')

    def test_commit_text_parsing(self):
        self._shared_test_commit_with_message()

    def test_commit_with_username(self):
        self._shared_test_commit_with_message("*****@*****.**")

    def test_has_authorization_for_realm(self):
        scm = detect_scm_system(self.svn_checkout_path)
        fake_home_dir = tempfile.mkdtemp(suffix="fake_home_dir")
        svn_config_dir_path = os.path.join(fake_home_dir, ".subversion")
        os.mkdir(svn_config_dir_path)
        fake_webkit_auth_file = os.path.join(svn_config_dir_path, "fake_webkit_auth_file")
        write_into_file_at_path(fake_webkit_auth_file, SVN.svn_server_realm)
        self.assertTrue(scm.has_authorization_for_realm(home_directory=fake_home_dir))
        os.remove(fake_webkit_auth_file)
        os.rmdir(svn_config_dir_path)
        os.rmdir(fake_home_dir)

    def test_not_have_authorization_for_realm(self):
        scm = detect_scm_system(self.svn_checkout_path)
        fake_home_dir = tempfile.mkdtemp(suffix="fake_home_dir")
        svn_config_dir_path = os.path.join(fake_home_dir, ".subversion")
        os.mkdir(svn_config_dir_path)
        self.assertFalse(scm.has_authorization_for_realm(home_directory=fake_home_dir))
        os.rmdir(svn_config_dir_path)
        os.rmdir(fake_home_dir)

    def test_reverse_diff(self):
        self._shared_test_reverse_diff()

    def test_diff_for_revision(self):
        self._shared_test_diff_for_revision()

    def test_svn_apply_git_patch(self):
        self._shared_test_svn_apply_git_patch()

    def test_changed_files(self):
        self._shared_test_changed_files()

    def test_changed_files_for_revision(self):
        self._shared_test_changed_files_for_revision()

    def test_added_files(self):
        self._shared_test_added_files()

    def test_contents_at_revision(self):
        self._shared_test_contents_at_revision()

    def test_committer_email_for_revision(self):
        self._shared_test_committer_email_for_revision()
Пример #23
0
 def test_apply_svn_patch(self):
     scm = detect_scm_system(self.svn_checkout_path)
     patch = self._create_patch(_svn_diff("-r5:4"))
     self._setup_webkittools_scripts_symlink(scm)
     Checkout(scm).apply_patch(patch)
Пример #24
0
 def _initialize_scm(self, patch_directories=None):
     self._scm = default_scm(patch_directories)
     self._checkout = Checkout(self.scm())
Пример #25
0
class GitTest(SCMTest):
    def _setup_git_clone_of_svn_repository(self):
        self.git_checkout_path = tempfile.mkdtemp(suffix="git_test_checkout")
        # --quiet doesn't make git svn silent, so we use run_silent to redirect output
        run_silent([
            'git', 'svn', 'clone', '-T', 'trunk', self.svn_repo_url,
            self.git_checkout_path
        ])

    def _tear_down_git_clone_of_svn_repository(self):
        run_command(['rm', '-rf', self.git_checkout_path])

    def setUp(self):
        SVNTestRepository.setup(self)
        self._setup_git_clone_of_svn_repository()
        os.chdir(self.git_checkout_path)
        self.scm = detect_scm_system(self.git_checkout_path)
        # For historical reasons, we test some checkout code here too.
        self.checkout = Checkout(self.scm)

    def tearDown(self):
        SVNTestRepository.tear_down(self)
        self._tear_down_git_clone_of_svn_repository()

    def test_detection(self):
        scm = detect_scm_system(self.git_checkout_path)
        self.assertEqual(scm.display_name(), "git")
        self.assertEqual(scm.supports_local_commits(), True)

    def test_read_git_config(self):
        key = 'test.git-config'
        value = 'git-config value'
        run_command(['git', 'config', key, value])
        self.assertEqual(self.scm.read_git_config(key), value)

    def test_local_commits(self):
        test_file = os.path.join(self.git_checkout_path, 'test_file')
        write_into_file_at_path(test_file, 'foo')
        run_command(['git', 'commit', '-a', '-m', 'local commit'])

        self.assertEqual(len(self.scm.local_commits()), 1)

    def test_discard_local_commits(self):
        test_file = os.path.join(self.git_checkout_path, 'test_file')
        write_into_file_at_path(test_file, 'foo')
        run_command(['git', 'commit', '-a', '-m', 'local commit'])

        self.assertEqual(len(self.scm.local_commits()), 1)
        self.scm.discard_local_commits()
        self.assertEqual(len(self.scm.local_commits()), 0)

    def test_delete_branch(self):
        old_branch = run_command(['git', 'symbolic-ref', 'HEAD']).strip()
        new_branch = 'foo'

        run_command(['git', 'checkout', '-b', new_branch])
        self.assertEqual(
            run_command(['git', 'symbolic-ref', 'HEAD']).strip(),
            'refs/heads/' + new_branch)

        run_command(['git', 'checkout', old_branch])
        self.scm.delete_branch(new_branch)

        self.assertFalse(re.search(r'foo', run_command(['git', 'branch'])))

    def test_svn_merge_base(self):
        # Diff to merge-base should include working-copy changes,
        # which the diff to svn_branch.. doesn't.
        test_file = os.path.join(self.git_checkout_path, 'test_file')
        write_into_file_at_path(test_file, 'foo')

        diff_to_common_base = _git_diff(self.scm.svn_branch_name() + '..')
        diff_to_merge_base = _git_diff(self.scm.svn_merge_base())

        self.assertFalse(re.search(r'foo', diff_to_common_base))
        self.assertTrue(re.search(r'foo', diff_to_merge_base))

    def test_rebase_in_progress(self):
        svn_test_file = os.path.join(self.svn_checkout_path, 'test_file')
        write_into_file_at_path(svn_test_file, "svn_checkout")
        run_command([
            'svn', 'commit', '--message', 'commit to conflict with git commit'
        ],
                    cwd=self.svn_checkout_path)

        git_test_file = os.path.join(self.git_checkout_path, 'test_file')
        write_into_file_at_path(git_test_file, "git_checkout")
        run_command([
            'git', 'commit', '-a', '-m',
            'commit to be thrown away by rebase abort'
        ])

        # --quiet doesn't make git svn silent, so use run_silent to redirect output
        self.assertRaises(
            ScriptError, run_silent,
            ['git', 'svn', '--quiet', 'rebase'
             ])  # Will fail due to a conflict leaving us mid-rebase.

        scm = detect_scm_system(self.git_checkout_path)
        self.assertTrue(scm.rebase_in_progress())

        # Make sure our cleanup works.
        scm.clean_working_directory()
        self.assertFalse(scm.rebase_in_progress())

        # Make sure cleanup doesn't throw when no rebase is in progress.
        scm.clean_working_directory()

    def test_commitish_parsing(self):
        scm = detect_scm_system(self.git_checkout_path)

        # Multiple revisions are cherry-picked.
        self.assertEqual(
            len(scm.commit_ids_from_commitish_arguments(['HEAD~2'])), 1)
        self.assertEqual(
            len(scm.commit_ids_from_commitish_arguments(['HEAD', 'HEAD~2'])),
            2)

        # ... is an invalid range specifier
        self.assertRaises(ScriptError, scm.commit_ids_from_commitish_arguments,
                          ['trunk...HEAD'])

    def test_commitish_order(self):
        scm = detect_scm_system(self.git_checkout_path)

        commit_range = 'HEAD~3..HEAD'

        actual_commits = scm.commit_ids_from_commitish_arguments(
            [commit_range])
        expected_commits = []
        expected_commits += reversed(
            run_command(['git', 'rev-list', commit_range]).splitlines())

        self.assertEqual(actual_commits, expected_commits)

    def test_apply_git_patch(self):
        scm = detect_scm_system(self.git_checkout_path)
        # We carefullly pick a diff which does not have a directory addition
        # as currently svn-apply will error out when trying to remove directories
        # in Git: https://bugs.webkit.org/show_bug.cgi?id=34871
        patch = self._create_patch(_git_diff('HEAD..HEAD^'))
        self._setup_webkittools_scripts_symlink(scm)
        Checkout(scm).apply_patch(patch)

    def test_apply_git_patch_force(self):
        scm = detect_scm_system(self.git_checkout_path)
        patch = self._create_patch(_git_diff('HEAD~2..HEAD'))
        self._setup_webkittools_scripts_symlink(scm)
        self.assertRaises(ScriptError,
                          Checkout(scm).apply_patch,
                          patch,
                          force=True)

    def test_commit_text_parsing(self):
        write_into_file_at_path('test_file', 'more test content')
        self.scm.commit_locally_with_message("another test commit")
        commit_text = self.scm.commit_with_message("another test commit")
        self.assertEqual(self.scm.svn_revision_from_commit_text(commit_text),
                         '6')

        self.scm.dryrun = True
        write_into_file_at_path('test_file', 'still more test content')
        self.scm.commit_locally_with_message("yet another test commit")
        commit_text = self.scm.commit_with_message("yet another test commit")
        self.assertEqual(self.scm.svn_revision_from_commit_text(commit_text),
                         '0')

    def _one_local_commit_plus_working_copy_changes(self):
        write_into_file_at_path('test_file_commit1', 'more test content')
        run_command(['git', 'add', 'test_file_commit1'])
        self.scm.commit_locally_with_message("another test commit")

        write_into_file_at_path('test_file_commit2', 'still more test content')
        run_command(['git', 'add', 'test_file_commit2'])

    def test_commit_with_message_working_copy_only(self):
        write_into_file_at_path('test_file_commit1', 'more test content')
        run_command(['git', 'add', 'test_file_commit1'])
        scm = detect_scm_system(self.git_checkout_path)
        commit_text = scm.commit_with_message("yet another test commit")

        self.assertEqual(scm.svn_revision_from_commit_text(commit_text), '6')
        svn_log = run_command(['git', 'svn', 'log', '--limit=1', '--verbose'])
        self.assertTrue(re.search(r'test_file_commit1', svn_log))

    def test_commit_with_message_squashed(self):
        self._one_local_commit_plus_working_copy_changes()
        scm = detect_scm_system(self.git_checkout_path)
        commit_text = scm.commit_with_message("yet another test commit",
                                              squash=True)

        self.assertEqual(scm.svn_revision_from_commit_text(commit_text), '6')
        svn_log = run_command(['git', 'svn', 'log', '--limit=1', '--verbose'])
        self.assertTrue(re.search(r'test_file_commit2', svn_log))
        self.assertTrue(re.search(r'test_file_commit1', svn_log))

    def _two_local_commits(self):
        write_into_file_at_path('test_file_commit1', 'more test content')
        run_command(['git', 'add', 'test_file_commit1'])
        self.scm.commit_locally_with_message("another test commit")

        write_into_file_at_path('test_file_commit2', 'still more test content')
        run_command(['git', 'add', 'test_file_commit2'])
        self.scm.commit_locally_with_message("yet another test commit")

    def test_commit_with_message_git_commit(self):
        self._two_local_commits()

        scm = detect_scm_system(self.git_checkout_path)
        commit_text = scm.commit_with_message("another test commit",
                                              git_commit="HEAD^")
        self.assertEqual(scm.svn_revision_from_commit_text(commit_text), '6')

        svn_log = run_command(['git', 'svn', 'log', '--limit=1', '--verbose'])
        self.assertTrue(re.search(r'test_file_commit1', svn_log))
        self.assertFalse(re.search(r'test_file_commit2', svn_log))

    def test_commit_with_message_git_commit_range(self):
        self._two_local_commits()

        scm = detect_scm_system(self.git_checkout_path)
        commit_text = scm.commit_with_message("another test commit",
                                              git_commit="HEAD~2..HEAD")
        self.assertEqual(scm.svn_revision_from_commit_text(commit_text), '6')

        svn_log = run_command(['git', 'svn', 'log', '--limit=1', '--verbose'])
        self.assertTrue(re.search(r'test_file_commit1', svn_log))
        self.assertTrue(re.search(r'test_file_commit2', svn_log))

    def test_commit_with_message_multiple_local_commits(self):
        self._two_local_commits()
        scm = detect_scm_system(self.git_checkout_path)
        self.assertRaises(ScriptError, scm.commit_with_message,
                          ["another test commit"])

    def test_commit_with_message_multiple_local_commits_and_working_copy(self):
        self._two_local_commits()
        write_into_file_at_path('test_file_commit1', 'working copy change')
        scm = detect_scm_system(self.git_checkout_path)
        self.assertRaises(ScriptError, scm.commit_with_message,
                          ["another test commit"])

    def test_commit_with_message_git_commit_and_working_copy(self):
        self._two_local_commits()
        write_into_file_at_path('test_file_commit1', 'working copy change')
        scm = detect_scm_system(self.git_checkout_path)
        self.assertRaises(ScriptError, scm.commit_with_message,
                          ["another test commit", 'git_commit="HEAD^"'])

    def test_commit_with_message_multiple_local_commits_no_squash(self):
        self._two_local_commits()
        scm = detect_scm_system(self.git_checkout_path)
        commit_text = scm.commit_with_message("yet another test commit",
                                              squash=False)
        self.assertEqual(scm.svn_revision_from_commit_text(commit_text), '6')

        svn_log = run_command(['git', 'svn', 'log', '--limit=1', '--verbose'])
        self.assertTrue(re.search(r'test_file_commit2', svn_log))
        self.assertFalse(re.search(r'test_file_commit1', svn_log))

        svn_log = run_command(['git', 'svn', 'log', '--limit=2', '--verbose'])
        self.assertTrue(re.search(r'test_file_commit1', svn_log))

    def test_commit_with_message_multiple_local_commits_squash(self):
        self._two_local_commits()
        scm = detect_scm_system(self.git_checkout_path)
        commit_text = scm.commit_with_message("yet another test commit",
                                              squash=True)
        self.assertEqual(scm.svn_revision_from_commit_text(commit_text), '6')

        svn_log = run_command(['git', 'svn', 'log', '--limit=1', '--verbose'])
        self.assertTrue(re.search(r'test_file_commit2', svn_log))
        self.assertTrue(re.search(r'test_file_commit1', svn_log))

    def test_reverse_diff(self):
        self._shared_test_reverse_diff()

    def test_diff_for_revision(self):
        self._shared_test_diff_for_revision()

    def test_svn_apply_git_patch(self):
        self._shared_test_svn_apply_git_patch()

    def test_create_patch_local_plus_working_copy(self):
        self._one_local_commit_plus_working_copy_changes()
        scm = detect_scm_system(self.git_checkout_path)
        self.assertRaises(ScriptError, scm.create_patch)

    def test_create_patch_multiple_local_commits(self):
        self._two_local_commits()
        scm = detect_scm_system(self.git_checkout_path)
        self.assertRaises(ScriptError, scm.create_patch)

    def test_create_patch_squashed(self):
        self._one_local_commit_plus_working_copy_changes()
        scm = detect_scm_system(self.git_checkout_path)
        patch = scm.create_patch(squash=True)
        self.assertTrue(re.search(r'test_file_commit2', patch))
        self.assertTrue(re.search(r'test_file_commit1', patch))

    def test_create_patch_not_squashed(self):
        self._one_local_commit_plus_working_copy_changes()
        scm = detect_scm_system(self.git_checkout_path)
        patch = scm.create_patch(squash=False)
        self.assertTrue(re.search(r'test_file_commit2', patch))
        self.assertFalse(re.search(r'test_file_commit1', patch))

    def test_create_patch_git_commit(self):
        self._two_local_commits()
        scm = detect_scm_system(self.git_checkout_path)
        patch = scm.create_patch(git_commit="HEAD^")
        self.assertTrue(re.search(r'test_file_commit1', patch))
        self.assertFalse(re.search(r'test_file_commit2', patch))

    def test_create_patch_git_commit_range(self):
        self._two_local_commits()
        scm = detect_scm_system(self.git_checkout_path)
        patch = scm.create_patch(git_commit="HEAD~2..HEAD")
        self.assertTrue(re.search(r'test_file_commit2', patch))
        self.assertTrue(re.search(r'test_file_commit1', patch))

    def test_create_patch_multiple_local_commits_no_squash(self):
        self._two_local_commits()
        scm = detect_scm_system(self.git_checkout_path)
        patch = scm.create_patch(squash=False)
        # FIXME: It's weird that with squash=False, create_patch/changed_files ignores local commits,
        # but commit_with_message commits them.
        self.assertTrue(patch == "")

    def test_create_patch_multiple_local_commits_squash(self):
        self._two_local_commits()
        scm = detect_scm_system(self.git_checkout_path)
        patch = scm.create_patch(squash=True)
        self.assertTrue(re.search(r'test_file_commit2', patch))
        self.assertTrue(re.search(r'test_file_commit1', patch))

    def test_create_binary_patch(self):
        # Create a git binary patch and check the contents.
        scm = detect_scm_system(self.git_checkout_path)
        test_file_name = 'binary_file'
        test_file_path = os.path.join(self.git_checkout_path, test_file_name)
        file_contents = ''.join(map(chr, range(256)))
        write_into_file_at_path(test_file_path, file_contents, encoding=None)
        run_command(['git', 'add', test_file_name])
        patch = scm.create_patch()
        self.assertTrue(re.search(r'\nliteral 0\n', patch))
        self.assertTrue(re.search(r'\nliteral 256\n', patch))

        # Check if we can apply the created patch.
        run_command(['git', 'rm', '-f', test_file_name])
        self._setup_webkittools_scripts_symlink(scm)
        self.checkout.apply_patch(self._create_patch(patch))
        self.assertEqual(file_contents,
                         read_from_path(test_file_path, encoding=None))

        # Check if we can create a patch from a local commit.
        write_into_file_at_path(test_file_path, file_contents, encoding=None)
        run_command(['git', 'add', test_file_name])
        run_command(['git', 'commit', '-m', 'binary diff'])
        patch_from_local_commit = scm.create_patch('HEAD')
        self.assertTrue(re.search(r'\nliteral 0\n', patch_from_local_commit))
        self.assertTrue(re.search(r'\nliteral 256\n', patch_from_local_commit))

    def test_changed_files_local_plus_working_copy(self):
        self._one_local_commit_plus_working_copy_changes()
        scm = detect_scm_system(self.git_checkout_path)
        self.assertRaises(ScriptError, scm.changed_files)

    def test_changed_files_multiple_local_commits(self):
        self._two_local_commits()
        scm = detect_scm_system(self.git_checkout_path)
        self.assertRaises(ScriptError, scm.changed_files)

    def test_changed_files_squashed(self):
        self._one_local_commit_plus_working_copy_changes()
        scm = detect_scm_system(self.git_checkout_path)
        files = scm.changed_files(squash=True)
        self.assertTrue('test_file_commit2' in files)
        self.assertTrue('test_file_commit1' in files)

    def test_changed_files_not_squashed(self):
        self._one_local_commit_plus_working_copy_changes()
        scm = detect_scm_system(self.git_checkout_path)
        files = scm.changed_files(squash=False)
        self.assertTrue('test_file_commit2' in files)
        self.assertFalse('test_file_commit1' in files)

    def test_changed_files_git_commit(self):
        self._two_local_commits()
        scm = detect_scm_system(self.git_checkout_path)
        files = scm.changed_files(git_commit="HEAD^")
        self.assertTrue('test_file_commit1' in files)
        self.assertFalse('test_file_commit2' in files)

    def test_changed_files_git_commit_range(self):
        self._two_local_commits()
        scm = detect_scm_system(self.git_checkout_path)
        files = scm.changed_files(git_commit="HEAD~2..HEAD")
        self.assertTrue('test_file_commit1' in files)
        self.assertTrue('test_file_commit2' in files)

    def test_changed_files_multiple_local_commits_no_squash(self):
        self._two_local_commits()
        scm = detect_scm_system(self.git_checkout_path)
        files = scm.changed_files(squash=False)
        # FIXME: It's weird that with squash=False, create_patch/changed_files ignores local commits,
        # but commit_with_message commits them.
        self.assertTrue(len(files) == 0)

    def test_changed_files_multiple_local_commits_squash(self):
        self._two_local_commits()
        scm = detect_scm_system(self.git_checkout_path)
        files = scm.changed_files(squash=True)
        self.assertTrue('test_file_commit2' in files)
        self.assertTrue('test_file_commit1' in files)

    def test_changed_files(self):
        self._shared_test_changed_files()

    def test_changed_files_for_revision(self):
        self._shared_test_changed_files_for_revision()

    def test_contents_at_revision(self):
        self._shared_test_contents_at_revision()

    def test_added_files(self):
        self._shared_test_added_files()

    def test_committer_email_for_revision(self):
        self._shared_test_committer_email_for_revision()
Пример #26
0
class GitTest(SCMTest):

    def _setup_git_clone_of_svn_repository(self):
        self.git_checkout_path = tempfile.mkdtemp(suffix="git_test_checkout")
        # --quiet doesn't make git svn silent, so we use run_silent to redirect output
        run_silent(['git', 'svn', '--quiet', 'clone', self.svn_repo_url, self.git_checkout_path])

    def _tear_down_git_clone_of_svn_repository(self):
        run_command(['rm', '-rf', self.git_checkout_path])

    def setUp(self):
        SVNTestRepository.setup(self)
        self._setup_git_clone_of_svn_repository()
        os.chdir(self.git_checkout_path)
        self.scm = detect_scm_system(self.git_checkout_path)
        # For historical reasons, we test some checkout code here too.
        self.checkout = Checkout(self.scm)

    def tearDown(self):
        SVNTestRepository.tear_down(self)
        self._tear_down_git_clone_of_svn_repository()

    def test_detection(self):
        scm = detect_scm_system(self.git_checkout_path)
        self.assertEqual(scm.display_name(), "git")
        self.assertEqual(scm.supports_local_commits(), True)

    def test_read_git_config(self):
        key = 'test.git-config'
        value = 'git-config value'
        run_command(['git', 'config', key, value])
        self.assertEqual(self.scm.read_git_config(key), value)

    def test_local_commits(self):
        test_file = os.path.join(self.git_checkout_path, 'test_file')
        write_into_file_at_path(test_file, 'foo')
        run_command(['git', 'commit', '-a', '-m', 'local commit'])

        self.assertEqual(len(self.scm.local_commits()), 1)

    def test_discard_local_commits(self):
        test_file = os.path.join(self.git_checkout_path, 'test_file')
        write_into_file_at_path(test_file, 'foo')
        run_command(['git', 'commit', '-a', '-m', 'local commit'])

        self.assertEqual(len(self.scm.local_commits()), 1)
        self.scm.discard_local_commits()
        self.assertEqual(len(self.scm.local_commits()), 0)

    def test_delete_branch(self):
        old_branch = run_command(['git', 'symbolic-ref', 'HEAD']).strip()
        new_branch = 'foo'

        run_command(['git', 'checkout', '-b', new_branch])
        self.assertEqual(run_command(['git', 'symbolic-ref', 'HEAD']).strip(), 'refs/heads/' + new_branch)

        run_command(['git', 'checkout', old_branch])
        self.scm.delete_branch(new_branch)

        self.assertFalse(re.search(r'foo', run_command(['git', 'branch'])))

    def test_svn_merge_base(self):
        # Diff to merge-base should include working-copy changes,
        # which the diff to svn_branch.. doesn't.
        test_file = os.path.join(self.git_checkout_path, 'test_file')
        write_into_file_at_path(test_file, 'foo')

        diff_to_common_base = run_command(['git', 'diff', self.scm.svn_branch_name() + '..'])
        diff_to_merge_base = run_command(['git', 'diff', self.scm.svn_merge_base()])

        self.assertFalse(re.search(r'foo', diff_to_common_base))
        self.assertTrue(re.search(r'foo', diff_to_merge_base))

    def test_rebase_in_progress(self):
        svn_test_file = os.path.join(self.svn_checkout_path, 'test_file')
        write_into_file_at_path(svn_test_file, "svn_checkout")
        run_command(['svn', 'commit', '--message', 'commit to conflict with git commit'], cwd=self.svn_checkout_path)

        git_test_file = os.path.join(self.git_checkout_path, 'test_file')
        write_into_file_at_path(git_test_file, "git_checkout")
        run_command(['git', 'commit', '-a', '-m', 'commit to be thrown away by rebase abort'])

        # --quiet doesn't make git svn silent, so use run_silent to redirect output
        self.assertRaises(ScriptError, run_silent, ['git', 'svn', '--quiet', 'rebase']) # Will fail due to a conflict leaving us mid-rebase.

        scm = detect_scm_system(self.git_checkout_path)
        self.assertTrue(scm.rebase_in_progress())

        # Make sure our cleanup works.
        scm.clean_working_directory()
        self.assertFalse(scm.rebase_in_progress())

        # Make sure cleanup doesn't throw when no rebase is in progress.
        scm.clean_working_directory()

    def test_commitish_parsing(self):
        scm = detect_scm_system(self.git_checkout_path)
    
        # Multiple revisions are cherry-picked.
        self.assertEqual(len(scm.commit_ids_from_commitish_arguments(['HEAD~2'])), 1)
        self.assertEqual(len(scm.commit_ids_from_commitish_arguments(['HEAD', 'HEAD~2'])), 2)
    
        # ... is an invalid range specifier
        self.assertRaises(ScriptError, scm.commit_ids_from_commitish_arguments, ['trunk...HEAD'])

    def test_commitish_order(self):
        scm = detect_scm_system(self.git_checkout_path)

        commit_range = 'HEAD~3..HEAD'

        actual_commits = scm.commit_ids_from_commitish_arguments([commit_range])
        expected_commits = []
        expected_commits += reversed(run_command(['git', 'rev-list', commit_range]).splitlines())

        self.assertEqual(actual_commits, expected_commits)

    def test_apply_git_patch(self):
        scm = detect_scm_system(self.git_checkout_path)
        # We carefullly pick a diff which does not have a directory addition
        # as currently svn-apply will error out when trying to remove directories
        # in Git: https://bugs.webkit.org/show_bug.cgi?id=34871
        patch = self._create_patch(run_command(['git', 'diff', 'HEAD..HEAD^']))
        self._setup_webkittools_scripts_symlink(scm)
        Checkout(scm).apply_patch(patch)

    def test_apply_git_patch_force(self):
        scm = detect_scm_system(self.git_checkout_path)
        patch = self._create_patch(run_command(['git', 'diff', 'HEAD~2..HEAD']))
        self._setup_webkittools_scripts_symlink(scm)
        self.assertRaises(ScriptError, Checkout(scm).apply_patch, patch, force=True)

    def test_commit_text_parsing(self):
        self._shared_test_commit_with_message()

    def test_reverse_diff(self):
        self._shared_test_reverse_diff()

    def test_diff_for_revision(self):
        self._shared_test_diff_for_revision()

    def test_svn_apply_git_patch(self):
        self._shared_test_svn_apply_git_patch()

    def test_create_binary_patch(self):
        # Create a git binary patch and check the contents.
        scm = detect_scm_system(self.git_checkout_path)
        test_file_name = 'binary_file'
        test_file_path = os.path.join(self.git_checkout_path, test_file_name)
        file_contents = ''.join(map(chr, range(256)))
        write_into_file_at_path(test_file_path, file_contents)
        run_command(['git', 'add', test_file_name])
        patch = scm.create_patch()
        self.assertTrue(re.search(r'\nliteral 0\n', patch))
        self.assertTrue(re.search(r'\nliteral 256\n', patch))

        # Check if we can apply the created patch.
        run_command(['git', 'rm', '-f', test_file_name])
        self._setup_webkittools_scripts_symlink(scm)
        self.checkout.apply_patch(self._create_patch(patch))
        self.assertEqual(file_contents, read_from_path(test_file_path))

        # Check if we can create a patch from a local commit.
        write_into_file_at_path(test_file_path, file_contents)
        run_command(['git', 'add', test_file_name])
        run_command(['git', 'commit', '-m', 'binary diff'])
        patch_from_local_commit = scm.create_patch_from_local_commit('HEAD')
        self.assertTrue(re.search(r'\nliteral 0\n', patch_from_local_commit))
        self.assertTrue(re.search(r'\nliteral 256\n', patch_from_local_commit))
        patch_since_local_commit = scm.create_patch_since_local_commit('HEAD^1')
        self.assertTrue(re.search(r'\nliteral 0\n', patch_since_local_commit))
        self.assertTrue(re.search(r'\nliteral 256\n', patch_since_local_commit))
        self.assertEqual(patch_from_local_commit, patch_since_local_commit)

    def test_changed_files(self):
        self._shared_test_changed_files()

    def test_changed_files_for_revision(self):
        self._shared_test_changed_files_for_revision()

    def test_contents_at_revision(self):
        self._shared_test_contents_at_revision()

    def test_added_files(self):
        self._shared_test_added_files()

    def test_committer_email_for_revision(self):
        self._shared_test_committer_email_for_revision()
Пример #27
0
 def checkout(self):
     if not self._checkout:
         self._checkout = Checkout(self.scm())
     return self._checkout
Пример #28
0
 def test_bug_id_for_revision(self):
     scm = Mock()
     scm.committer_email_for_revision = lambda revision: "*****@*****.**"
     checkout = Checkout(scm)
     checkout.changelog_entries_for_revision = lambda revision: [ChangeLogEntry(_changelog1entry1)]
     self.assertEqual(checkout.bug_id_for_revision(4), 36629)
Пример #29
0
 def test_bug_id_for_this_commit(self):
     scm = Mock()
     checkout = Checkout(scm)
     checkout.commit_message_for_this_commit = lambda git_commit, changed_files=None: CommitMessage(ChangeLogEntry(_changelog1entry1).contents().splitlines())
     self.assertEqual(checkout.bug_id_for_this_commit(git_commit=None), 36629)
Пример #30
0
class SVNTest(SCMTest):
    @staticmethod
    def _set_date_and_reviewer(changelog_entry):
        # Joe Cool matches the reviewer set in SCMTest._create_patch
        changelog_entry = changelog_entry.replace('REVIEWER_HERE', 'Joe Cool')
        # svn-apply will update ChangeLog entries with today's date.
        return changelog_entry.replace('DATE_HERE', date.today().isoformat())

    def test_svn_apply(self):
        first_entry = """2009-10-26  Eric Seidel  <*****@*****.**>

        Reviewed by Foo Bar.

        Most awesome change ever.

        * scm_unittest.py:
"""
        intermediate_entry = """2009-10-27  Eric Seidel  <*****@*****.**>

        Reviewed by Baz Bar.

        A more awesomer change yet!

        * scm_unittest.py:
"""
        one_line_overlap_patch = """Index: ChangeLog
===================================================================
--- ChangeLog	(revision 5)
+++ ChangeLog	(working copy)
@@ -1,5 +1,13 @@
 2009-10-26  Eric Seidel  <*****@*****.**>
 
+        Reviewed by NOBODY (OOPS!).
+
+        Second most awesome change ever.
+
+        * scm_unittest.py:
+
+2009-10-26  Eric Seidel  <*****@*****.**>
+
         Reviewed by Foo Bar.
 
         Most awesome change ever.
"""
        one_line_overlap_entry = """DATE_HERE  Eric Seidel  <*****@*****.**>

        Reviewed by REVIEWER_HERE.

        Second most awesome change ever.

        * scm_unittest.py:
"""
        two_line_overlap_patch = """Index: ChangeLog
===================================================================
--- ChangeLog	(revision 5)
+++ ChangeLog	(working copy)
@@ -2,6 +2,14 @@
 
         Reviewed by Foo Bar.
 
+        Second most awesome change ever.
+
+        * scm_unittest.py:
+
+2009-10-26  Eric Seidel  <*****@*****.**>
+
+        Reviewed by Foo Bar.
+
         Most awesome change ever.
 
         * scm_unittest.py:
"""
        two_line_overlap_entry = """DATE_HERE  Eric Seidel  <*****@*****.**>

        Reviewed by Foo Bar.

        Second most awesome change ever.

        * scm_unittest.py:
"""
        write_into_file_at_path('ChangeLog', first_entry)
        run_command(['svn', 'add', 'ChangeLog'])
        run_command(
            ['svn', 'commit', '--quiet', '--message', 'ChangeLog commit'])

        # Patch files were created against just 'first_entry'.
        # Add a second commit to make svn-apply have to apply the patches with fuzz.
        changelog_contents = "%s\n%s" % (intermediate_entry, first_entry)
        write_into_file_at_path('ChangeLog', changelog_contents)
        run_command(
            ['svn', 'commit', '--quiet', '--message', 'Intermediate commit'])

        self._setup_webkittools_scripts_symlink(self.scm)
        self.checkout.apply_patch(self._create_patch(one_line_overlap_patch))
        expected_changelog_contents = "%s\n%s" % (self._set_date_and_reviewer(
            one_line_overlap_entry), changelog_contents)
        self.assertEquals(read_from_path('ChangeLog'),
                          expected_changelog_contents)

        self.scm.revert_files(['ChangeLog'])
        self.checkout.apply_patch(self._create_patch(two_line_overlap_patch))
        expected_changelog_contents = "%s\n%s" % (self._set_date_and_reviewer(
            two_line_overlap_entry), changelog_contents)
        self.assertEquals(read_from_path('ChangeLog'),
                          expected_changelog_contents)

    def setUp(self):
        SVNTestRepository.setup(self)
        os.chdir(self.svn_checkout_path)
        self.scm = detect_scm_system(self.svn_checkout_path)
        # For historical reasons, we test some checkout code here too.
        self.checkout = Checkout(self.scm)

    def tearDown(self):
        SVNTestRepository.tear_down(self)

    def test_detect_scm_system_relative_url(self):
        scm = detect_scm_system(".")
        # I wanted to assert that we got the right path, but there was some
        # crazy magic with temp folder names that I couldn't figure out.
        self.assertTrue(scm.checkout_root)

    def test_create_patch_is_full_patch(self):
        test_dir_path = os.path.join(self.svn_checkout_path, "test_dir2")
        os.mkdir(test_dir_path)
        test_file_path = os.path.join(test_dir_path, 'test_file2')
        write_into_file_at_path(test_file_path, 'test content')
        run_command(['svn', 'add', 'test_dir2'])

        # create_patch depends on 'svn-create-patch', so make a dummy version.
        scripts_path = os.path.join(self.svn_checkout_path, 'WebKitTools',
                                    'Scripts')
        os.makedirs(scripts_path)
        create_patch_path = os.path.join(scripts_path, 'svn-create-patch')
        write_into_file_at_path(
            create_patch_path, '#!/bin/sh\necho $PWD'
        )  # We could pass -n to prevent the \n, but not all echo accept -n.
        os.chmod(create_patch_path, stat.S_IXUSR | stat.S_IRUSR)

        # Change into our test directory and run the create_patch command.
        os.chdir(test_dir_path)
        scm = detect_scm_system(test_dir_path)
        self.assertEqual(scm.checkout_root, self.svn_checkout_path
                         )  # Sanity check that detection worked right.
        patch_contents = scm.create_patch()
        # Our fake 'svn-create-patch' returns $PWD instead of a patch, check that it was executed from the root of the repo.
        self.assertEqual("%s\n" % os.path.realpath(scm.checkout_root),
                         patch_contents)  # Add a \n because echo adds a \n.

    def test_detection(self):
        scm = detect_scm_system(self.svn_checkout_path)
        self.assertEqual(scm.display_name(), "svn")
        self.assertEqual(scm.supports_local_commits(), False)

    def test_apply_small_binary_patch(self):
        patch_contents = """Index: test_file.swf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: test_file.swf
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream


Q1dTBx0AAAB42itg4GlgYJjGwMDDyODMxMDw34GBgQEAJPQDJA==
"""
        expected_contents = base64.b64decode(
            "Q1dTBx0AAAB42itg4GlgYJjGwMDDyODMxMDw34GBgQEAJPQDJA==")
        self._setup_webkittools_scripts_symlink(self.scm)
        patch_file = self._create_patch(patch_contents)
        self.checkout.apply_patch(patch_file)
        actual_contents = read_from_path("test_file.swf", encoding=None)
        self.assertEqual(actual_contents, expected_contents)

    def test_apply_svn_patch(self):
        scm = detect_scm_system(self.svn_checkout_path)
        patch = self._create_patch(_svn_diff("-r5:4"))
        self._setup_webkittools_scripts_symlink(scm)
        Checkout(scm).apply_patch(patch)

    def test_apply_svn_patch_force(self):
        scm = detect_scm_system(self.svn_checkout_path)
        patch = self._create_patch(_svn_diff("-r3:5"))
        self._setup_webkittools_scripts_symlink(scm)
        self.assertRaises(ScriptError,
                          Checkout(scm).apply_patch,
                          patch,
                          force=True)

    def test_commit_logs(self):
        # Commits have dates and usernames in them, so we can't just direct compare.
        self.assertTrue(
            re.search('fourth commit', self.scm.last_svn_commit_log()))
        self.assertTrue(re.search('second commit', self.scm.svn_commit_log(3)))

    def _shared_test_commit_with_message(self, username=None):
        write_into_file_at_path('test_file', 'more test content')
        commit_text = self.scm.commit_with_message("another test commit",
                                                   username)
        self.assertEqual(self.scm.svn_revision_from_commit_text(commit_text),
                         '6')

        self.scm.dryrun = True
        write_into_file_at_path('test_file', 'still more test content')
        commit_text = self.scm.commit_with_message("yet another test commit",
                                                   username)
        self.assertEqual(self.scm.svn_revision_from_commit_text(commit_text),
                         '0')

    def test_commit_text_parsing(self):
        self._shared_test_commit_with_message()

    def test_commit_with_username(self):
        self._shared_test_commit_with_message("*****@*****.**")

    def test_has_authorization_for_realm(self):
        scm = detect_scm_system(self.svn_checkout_path)
        fake_home_dir = tempfile.mkdtemp(suffix="fake_home_dir")
        svn_config_dir_path = os.path.join(fake_home_dir, ".subversion")
        os.mkdir(svn_config_dir_path)
        fake_webkit_auth_file = os.path.join(svn_config_dir_path,
                                             "fake_webkit_auth_file")
        write_into_file_at_path(fake_webkit_auth_file, SVN.svn_server_realm)
        self.assertTrue(
            scm.has_authorization_for_realm(home_directory=fake_home_dir))
        os.remove(fake_webkit_auth_file)
        os.rmdir(svn_config_dir_path)
        os.rmdir(fake_home_dir)

    def test_not_have_authorization_for_realm(self):
        scm = detect_scm_system(self.svn_checkout_path)
        fake_home_dir = tempfile.mkdtemp(suffix="fake_home_dir")
        svn_config_dir_path = os.path.join(fake_home_dir, ".subversion")
        os.mkdir(svn_config_dir_path)
        self.assertFalse(
            scm.has_authorization_for_realm(home_directory=fake_home_dir))
        os.rmdir(svn_config_dir_path)
        os.rmdir(fake_home_dir)

    def test_reverse_diff(self):
        self._shared_test_reverse_diff()

    def test_diff_for_revision(self):
        self._shared_test_diff_for_revision()

    def test_svn_apply_git_patch(self):
        self._shared_test_svn_apply_git_patch()

    def test_changed_files(self):
        self._shared_test_changed_files()

    def test_changed_files_for_revision(self):
        self._shared_test_changed_files_for_revision()

    def test_added_files(self):
        self._shared_test_added_files()

    def test_contents_at_revision(self):
        self._shared_test_contents_at_revision()

    def test_committer_email_for_revision(self):
        self._shared_test_committer_email_for_revision()