[git] write test on cherry-pick-without-auto-commit, remove old style cherry-pick tests

This commit is contained in:
Kirill Likhodedov
2013-01-02 17:23:29 +04:00
parent aec119110c
commit ee8fb57a6a
6 changed files with 215 additions and 681 deletions
@@ -0,0 +1,144 @@
Feature: Git Cherry-Pick When Auto-Commit is deselected
Background:
Given disabled auto-commit in the settings
Given new committed files file.txt, a.txt, conflict.txt with initial content
Given branch feature
Given commit f5027a3 on branch feature
"""
fix #1
Author: John Bro
M file.txt "feature changes"
"""
Scenario: Simple cherry-pick
When I cherry-pick the commit f5027a3
Then commit dialog should be shown
And active changelist is 'fix #1 (cherry picked from commit f5027a3)'
Scenario: Simple cherry-pick, agree to commit
When I cherry-pick the commit f5027a3 and commit
Then the last commit is
"""
fix #1
(cherry picked from commit f5027a3)
"""
And success notification is shown 'Cherry-pick successful'
"""
f5027a3 fix #1
"""
And no new changelists are created
Scenario: Simple cherry-pick, cancel commit
When I cherry-pick the commit f5027a3 and don't commit
Then nothing is committed
And active changelist is 'fix #1 (cherry picked from commit f5027a3)'
And no notification is shown
Scenario: Cherry-pick 2 commits
Given commit abc1234 on branch feature
"""
fix #2
M file.txt "more feature changes"
"""
When I cherry-pick commits f5027a3, abc1234 and commit both of them
Then `git log -2` should return
"""
fix #2
(cherry picked from commit abc1234)
-----
fix #1
(cherry picked from commit f5027a3)
"""
And no new changelists are created
Scenario: Cherry-pick 2 commits, cancel committing the second
Given commit abc1234 on branch feature
"""
fix #2
M file.txt "more feature changes"
"""
When I cherry-pick commits f5027a3, abc1234, but commit only the first one
Then the last commit is
"""
fix #1
(cherry picked from commit f5027a3)
"""
And working tree is dirty
And active changelist is 'fix #2 (cherry picked from commit abc1234)'
And warning notification is shown 'Cherry-pick cancelled'
"""
abc1234 fix #2
<hr/>
However cherry-pick succeeded for the following commit:
f5027a3 fix #1
"""
Scenario: Dirty tree, conflicting with the commit
Given file.txt is locally modified:
"""
master content
"""
When I cherry-pick the commit f5027a3
Then nothing is committed
And error notification is shown 'Cherry-pick failed'
"""
f5027a3 fix #1
Your local changes would be overwritten by cherry-pick.
Commit your changes or stash them to proceed.
"""
Scenario: Untracked files, conflicting with cherry-picked commit
Given commit aff6453 on branch feature
"""
add file
A untracked.txt "feature changes"
"""
Given file untracked.txt 'master changes'
When I cherry-pick the commit aff6453
Then no new changelists are created
And error notification is shown 'Cherry-pick failed'
"""
aff6453 add file
Some untracked working tree files would be overwritten by cherry-pick.
Please move, remove or add them before you can cherry-pick. <a href='view'>View them</a>
"""
Scenario: Conflict with cherry-picked commit should show merge dialog
Given commit aff6453 on branch master
"""
master content
M conflict.txt "master version"
"""
Given commit bb6453c on branch feature
"""
feature content
M conflict.txt "feature version"
"""
When I cherry-pick the commit bb6453c
Then merge dialog should be shown
Scenario: Resolve conflict and agree to commit
Given commit aff6453 on branch master
"""
master content
M conflict.txt "master version"
"""
Given commit bb6453c on branch feature
"""
feature content
M conflict.txt "feature version"
"""
When I cherry-pick the commit bb6453c, resolve conflicts and commit
Then the last commit is
"""
feature content
(cherry picked from commit bb6453c)
"""
And success notification is shown 'Cherry-pick successful'
"""
bb6453c feature content
"""
And no new changelists are created
@@ -141,8 +141,13 @@ public class GeneralStepdefs {
git("commit -m 'adding files with initial content'");
}
private static List<String> splitByComma(String listOfFiles) {
return Arrays.asList(listOfFiles.split(", ?"));
public static List<String> splitByComma(String listOfItems) {
return Arrays.asList(listOfItems.split(", ?"));
}
@Given("^branch (.+)$")
public void branch(String branchName) throws Throwable {
git("branch " + branchName);
}
}
@@ -61,7 +61,7 @@ public class GitCherryPickStepdefs {
cherryPick(hash);
}
@When("^I cherry-pick commits (.+) and (.+)$")
@When("^I cherry-pick commits (.+) and (\\w+)$")
public void I_cherry_pick_commits(String severalCommits, String hash2) throws Throwable {
String[] hashes = severalCommits.split(",");
@@ -73,28 +73,6 @@ public class GitCherryPickStepdefs {
cherryPick(allHashes);
}
private static void cherryPick(String... virtualHashes) {
List<GitCommit> commits = new ArrayList<GitCommit>();
for (String virtualHash : virtualHashes) {
commits.add(createMockCommit(virtualHash));
}
new GitCherryPicker(myProject, myGit, myPlatformFacade, mySettings.isAutoCommitOnCherryPick())
.cherryPick(Collections.singletonMap(myRepository, commits));
}
private static GitCommit createMockCommit(String virtualHash) {
CommitDetails realCommit = virtualCommits.getRealCommit(virtualHash);
return mockCommit(realCommit.getHash(), realCommit.getMessage());
}
private static GitCommit mockCommit(String hash, String message) {
AbstractHash ahash = AbstractHash.create(hash);
List<Change> changes = new ArrayList<Change>();
changes.add(new Change(null, new MockContentRevision(new FilePathImpl(new MockVirtualFile("name")), VcsRevisionNumber.NULL)));
return new GitCommit(NullVirtualFile.INSTANCE, ahash, SHAHash.emulate(ahash), "John Smith", null, null, message, message,
null, null, null, null, null, null, null, changes, 0);
}
@When("^I cherry-pick the commit (\\w+) and( don't)? resolve conflicts$")
public void I_cherry_pick_the_commit_and_resolve_conflicts(String hash, String negation) throws Throwable {
if (negation == null) {
@@ -112,16 +90,27 @@ public class GitCherryPickStepdefs {
});
}
private static void commitInFuture() {
private static void commitInFuture(final int times) {
myVcsHelper.registerHandler(new MockVcsHelper.CommitHandler() {
private int myCommitRequests;
@Override
public boolean commit(String commitMessage) {
if (myCommitRequests >= times) {
return false;
}
myCommitRequests++;
git(String.format("commit -am '%s'", commitMessage));
return true;
}
});
}
private static void commitInFuture() {
commitInFuture(Integer.MAX_VALUE);
}
@When("^I cherry-pick the commit (.+), resolve conflicts and( don't)? commit$")
public void I_cherry_pick_the_commit_resolve_conflicts_and_commit(String hash, String negation) throws Throwable {
resolveConflictsInFuture();
@@ -131,6 +120,26 @@ public class GitCherryPickStepdefs {
cherryPick(hash);
}
@When("^I cherry-pick the commit (\\w+) and( don't)? commit$")
public void I_cherry_pick_the_commit_hash_and_commit(String hash, String negation) throws Throwable {
if (negation == null) {
commitInFuture();
}
cherryPick(hash);
}
@When("^I cherry-pick commits (.+) and commit both of them$")
public void I_cherry_pick_commits_and_commit_both_of_them(String listOfHashes) throws Throwable {
commitInFuture();
cherryPick(GeneralStepdefs.splitByComma(listOfHashes));
}
@When("^I cherry-pick commits (.+), but commit only the first one$")
public void I_cherry_pick_commits_but_commit_only_the_first_one(String listOfHashes) throws Throwable {
commitInFuture(1);
cherryPick(GeneralStepdefs.splitByComma(listOfHashes));
}
@Then("^the last commit is$")
public void the_last_commit_is(String message) throws Throwable {
git_log_should_return(1, message);
@@ -172,8 +181,13 @@ public class GitCherryPickStepdefs {
}
@Then("^nothing is committed$")
public void nothing_is_committed() {
assertFalse("Working tree is unexpectedly clean", git("diff").trim().isEmpty());
public void nothing_is_committed() throws Throwable {
working_tree_is_dirty();
}
@And("^working tree is dirty$")
public void working_tree_is_dirty() throws Throwable {
assertFalse("Working tree is unexpectedly clean", git("diff").trim().isEmpty() && git("diff --cached").trim().isEmpty());
}
@Then("^merge dialog should be shown$")
@@ -212,9 +226,30 @@ public class GitCherryPickStepdefs {
assertEquals("Wrong active changelist", name, myChangeListManager.getDefaultChangeList().getName());
}
@Given("^branch (.+)$")
public void branch(String branchName) throws Throwable {
git("branch " + branchName);
private static void cherryPick(List<String> virtualHashes) {
List<GitCommit> commits = new ArrayList<GitCommit>();
for (String virtualHash : virtualHashes) {
commits.add(createMockCommit(virtualHash));
}
new GitCherryPicker(myProject, myGit, myPlatformFacade, mySettings.isAutoCommitOnCherryPick())
.cherryPick(Collections.singletonMap(myRepository, commits));
}
private static void cherryPick(String... virtualHashes) {
cherryPick(Arrays.asList(virtualHashes));
}
private static GitCommit createMockCommit(String virtualHash) {
CommitDetails realCommit = virtualCommits.getRealCommit(virtualHash);
return mockCommit(realCommit.getHash(), realCommit.getMessage());
}
private static GitCommit mockCommit(String hash, String message) {
AbstractHash ahash = AbstractHash.create(hash);
List<Change> changes = new ArrayList<Change>();
changes.add(new Change(null, new MockContentRevision(new FilePathImpl(new MockVirtualFile("name")), VcsRevisionNumber.NULL)));
return new GitCommit(NullVirtualFile.INSTANCE, ahash, SHAHash.emulate(ahash), "John Smith", null, null, message, message,
null, null, null, null, null, null, null, changes, 0);
}
}
@@ -1,252 +0,0 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package git4idea.cherrypick
import com.intellij.notification.NotificationType
import git4idea.history.browser.GitCommit
import org.junit.Before
import org.junit.Test
import static git4idea.test.MockGit.*
import static git4idea.test.MockGit.OperationName.CHERRY_PICK
import static git4idea.test.MockGit.OperationName.GET_UNMERGED_FILES
import static junit.framework.Assert.assertTrue
import git4idea.history.browser.GitCherryPicker
/**
* Cherry-pick of one or multiple commits with "commit at once" option enabled.
*
* @author Kirill Likhodedov
*/
class GitAutoCommittingCherryPickTest extends GitCherryPickTest {
public static final String EMPTY_CHERRY_PICK = """
# On branch master
# Your branch is ahead of 'origin/master' by 11 commits.
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
#\t.idea/
#\tlocal_staged.patch
#\tout/
nothing added to commit but untracked files present (use "git add" to track)
The previous cherry-pick is now empty, possibly due to conflict resolution.
If you wish to commit it anyway, use:
git commit --allow-empty
Otherwise, please use 'git reset'
"""
@Before
void setUp() {
super.setUp()
myCherryPicker = new GitCherryPicker(myProject, myGit, myPlatformFacade, true)
}
@Test
void "clean tree, no conflicts, then commit & notify, no new changelists"() {
GitCommit commit = commit()
myGit.registerOperationExecutors(new SuccessfulCherryPickExecutor(myRepository, commit))
invokeCherryPick(commit)
assertHeadCommit(commit)
assertOnlyDefaultChangelist()
assertNotificationShown("Cherry-pick successful", commitDetails(commit), NotificationType.INFORMATION)
}
@Test
void "dirty tree, conflicting with commit, then show error"() {
myGit.registerOperationExecutors(new SimpleErrorOperationExecutor(CHERRY_PICK, LOCAL_CHANGES_OVERWRITTEN_BY_CHERRY_PICK))
def commit = commit()
invokeCherryPick(commit)
assertNotCherryPicked()
assertOnlyDefaultChangelist()
assertNotificationShown("Cherry-pick failed",
"""
${commitDetails(commit)}<br/>
Your local changes would be overwritten by cherry-pick.<br/>
Commit your changes or stash them to proceed.
""",
NotificationType.ERROR)
}
@Test
void "untracked files, conflicting with commit, then show error"() {
myGit.registerOperationExecutors(new SimpleErrorOperationExecutor(CHERRY_PICK, UNTRACKED_FILES_OVERWRITTEN_BY_CHERRY_PICK))
def commit = commit()
invokeCherryPick(commit)
assertNotCherryPicked()
assertOnlyDefaultChangelist()
assertNotificationShown("Cherry-pick error",
"""
${commitDetails(commit)}<br/>
Some untracked working tree files would be overwritten by cherry-pick.<br/>
Please move, remove or add them before you can cherry-pick. <a href='view'>View them</a>
""",
NotificationType.ERROR)
}
@Test
void "conflict, merge dialog, not all merged, then new & active changelist, notification"() {
prepareConflict()
myGit.registerOperationExecutors(new SimpleSuccessOperationExecutor(GET_UNMERGED_FILES, UNMERGED_FILE))
GitCommit commit = commit()
invokeCherryPick(commit)
assertMergeDialogShown()
assertChangeLists([DEFAULT, newCommitMessage(commit)], newCommitMessage(commit))
assertNotificationShown "Cherry-picked with conflicts",
"""
${commitDetails(commit)}<br/>
Unresolved conflicts remain in the working tree. <a href='resolve'>Resolve them.<a/>
""",
NotificationType.WARNING
}
@Test
void "conflict, merge completed, then commit dialog"() {
prepareConflict()
GitCommit commit = commit()
OKCommitDialogHandler handler = new OKCommitDialogHandler(myRepository)
myVcsHelper.registerHandler(handler)
invokeCherryPick(commit)
assertMergeDialogShown()
assertTrue "Commit dialog was not shown", handler.wasCommitDialogShown()
}
@Test
void "conflict, merge finished, commit succeeded, no new changelists"() {
prepareConflict()
OKCommitDialogHandler handler = new OKCommitDialogHandler(myRepository)
myVcsHelper.registerHandler(handler)
GitCommit commit = commit()
invokeCherryPick(commit)
assertMergeDialogShown()
assertHeadCommit(commit)
assertTrue "Commit dialog was not shown", handler.wasCommitDialogShown()
assertOnlyDefaultChangelist()
}
@Test
void "conflict, merge ok, commit cancelled, then new & active changelist"() {
prepareConflict()
CancelCommitDialogHandler handler = new CancelCommitDialogHandler()
myVcsHelper.registerHandler(handler)
GitCommit commit = commit()
invokeCherryPick(commit)
assertMergeDialogShown()
assertTrue "Commit dialog was not shown", handler.wasCommitDialogShown()
assertChangeLists([DEFAULT, newCommitMessage(commit)], newCommitMessage(commit))
}
@Test
void "2 commits, no problems, then commit all & notify"() {
GitCommit commit1 = commit("First commit to cherry-pick")
GitCommit commit2 = commit("Second commit to cherry-pick")
myGit.registerOperationExecutors(new SuccessfulCherryPickExecutor(myRepository, commit1),
new SuccessfulCherryPickExecutor(myRepository, commit2))
invokeCherryPick([commit1, commit2])
assertLastCommits commit2, commit1
assertNotificationShown("Cherry-pick successful", notificationContent(commit1, commit2), NotificationType.INFORMATION)
}
@Test
void "3 commits, 2nd cherry-pick conflicts with local, then 1st success, 2nd stop & error"() {
GitCommit commit1 = commit("First")
GitCommit commit2 = commit("Second")
GitCommit commit3 = commit("Third")
myGit.registerOperationExecutors(new SuccessfulCherryPickExecutor(myRepository, commit1),
new SimpleErrorOperationExecutor(CHERRY_PICK, LOCAL_CHANGES_OVERWRITTEN_BY_CHERRY_PICK),
new SuccessfulCherryPickExecutor(myRepository, commit3))
invokeCherryPick([commit1, commit2, commit3])
assertHeadCommit(commit1)
assertNotificationShown("Cherry-pick failed",
"""
${commitDetails(commit2)}<br/>
Your local changes would be overwritten by cherry-pick.<br/>
Commit your changes or stash them to proceed.
<hr/>
However cherry-pick succeeded for the following commit:<br/>
${commitDetails(commit1)}
""", NotificationType.ERROR)
}
@Test
void "3 commits, 2nd conflicts with committed, then 1st success, on 2nd show merge dialog"() {
GitCommit commit1 = commit("First")
GitCommit commit2 = commit("Second")
GitCommit commit3 = commit("Third")
myGit.registerOperationExecutors(new SuccessfulCherryPickExecutor(myRepository, commit1))
prepareConflict()
myGit.registerOperationExecutors(new SuccessfulCherryPickExecutor(myRepository, commit3))
OKCommitDialogHandler handler = new OKCommitDialogHandler(myRepository)
myVcsHelper.registerHandler(handler)
invokeCherryPick([commit1, commit2, commit3])
assertMergeDialogShown()
assertTrue "Commit dialog was not shown", handler.wasCommitDialogShown()
assertLastCommits commit3, commit2, commit1
}
// @Test
void "Notify if changes have already been applied"() {
// Inspired by IDEA-73548
myGit.registerOperationExecutors(new SimpleErrorOperationExecutor(CHERRY_PICK, EMPTY_CHERRY_PICK))
GitCommit commit = commit()
invokeCherryPick(commit)
assertNotCherryPicked()
assertNotificationShown("Nothing to cherry-pick", "All changes from ${commitDetails(commit)} have already been applied",
NotificationType.WARNING)
}
// @Test
void "1st successful, 2nd empty (all applied), then compound notification"() {
// Inspired by IDEA-73548
GitCommit commit1 = commit()
GitCommit commit2 = commit()
myGit.registerOperationExecutors(new SuccessfulCherryPickExecutor(myRepository, commit1),
new SimpleErrorOperationExecutor(CHERRY_PICK, EMPTY_CHERRY_PICK))
invokeCherryPick([ commit1, commit2 ])
assertHeadCommit(commit1)
assertNotificationShown("Cherry-picked with problems",
"""Successfully cherry-picked ${commitDetails(commit1)}<br/>
Not cherry-picked ${commitDetails(commit2)} - all changes have already been applied""", NotificationType.WARNING)
}
}
@@ -1,202 +0,0 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package git4idea.cherrypick
import com.intellij.mock.MockVirtualFile
import com.intellij.openapi.vcs.FilePathImpl
import com.intellij.openapi.vcs.changes.Change
import com.intellij.openapi.vcs.changes.ChangeListManager
import com.intellij.openapi.vcs.changes.LocalChangeList
import com.intellij.openapi.vcs.history.VcsRevisionNumber
import com.intellij.testFramework.vcs.MockChangeListManager
import com.intellij.testFramework.vcs.MockContentRevision
import git4idea.history.browser.GitCherryPicker
import git4idea.history.browser.GitCommit
import git4idea.history.browser.SHAHash
import git4idea.history.wholeTree.AbstractHash
import git4idea.test.GitFastTest
import git4idea.test.GitLightRepository
import git4idea.test.MockGit
import com.intellij.dvcs.test.MockVcsHelper
import sun.security.provider.SHA
import static MockGit.OperationName.CHERRY_PICK
import static MockGit.commitMessageForCherryPick
import static junit.framework.Assert.assertEquals
import static junit.framework.Assert.assertTrue
import git4idea.test.TestNotificator
import com.intellij.openapi.vfs.newvfs.impl.NullVirtualFile
/**
* Common parent for all tests on cherry-pick
*
* @author Kirill Likhodedov
*/
class GitCherryPickTest extends GitFastTest {
public static final String DEFAULT = MockChangeListManager.DEFAULT_CHANGE_LIST_NAME;
public static final String UNMERGED_FILE = """
100644 d87b28d6fd6e97620603e64ce70fc2f24535ec28 1\ttest.txt
100644 7b50450f5deb7cce3b5ce92ba866f1af6e58c3c6 2\ttest.txt
100644 a784477cdd0437a84751c52f72b971503deb48cb 3\ttest.txt
"""
public static final String CHERRY_PICK_CONFLICT = """
error: could not apply ec15d8e... message
hint: after resolving the conflicts, mark the corrected paths
hint: with 'git add <paths>' or 'git rm <paths>'
hint: and commit the result with 'git commit'
"""
GitCherryPicker myCherryPicker
GitLightRepository myRepository
GitLightRepository.Commit myInitialCommit
TestNotificator myTestNotificator
static final LOCAL_CHANGES_OVERWRITTEN_BY_CHERRY_PICK =
"""
error: Your local changes to the following files would be overwritten by merge:
\ttest.txt
Please, commit your changes or stash them before you can merge.
Aborting
""";
static final UNTRACKED_FILES_OVERWRITTEN_BY_CHERRY_PICK =
"""
error: The following untracked working tree files would be overwritten by merge:
\tcp.txt
Please move or remove them before you can merge.
Aborting
"""
void setUp() {
super.setUp()
myRepository = new GitLightRepository()
myRepositoryManager.add(myRepository)
myInitialCommit = myRepository.commit("initial")
myTestNotificator = myPlatformFacade.getNotificator(myProject) as TestNotificator;
}
GitCommit commit(String commitMessage = "plain commit") {
AbstractHash hash = AbstractHash.create(Integer.toHexString(new SHA().hashCode()))
List<Change> changes = new ArrayList<Change>();
changes.add(new Change(null, new MockContentRevision(new FilePathImpl(new MockVirtualFile("name")), VcsRevisionNumber.NULL)));
new GitCommit(NullVirtualFile.INSTANCE, hash, SHAHash.emulate(hash), "John Smith", null, null, commitMessage, commitMessage,
null, null, null, null, null, null, null, changes, 0)
}
void assertOnlyDefaultChangelist() {
assertChangeLists( [DEFAULT], DEFAULT)
}
void invokeCherryPick(GitCommit commit) {
invokeCherryPick([commit])
}
void invokeCherryPick(List<GitCommit> commits) {
myCherryPicker.cherryPick(Collections.singletonMap(myRepository, commits))
}
void assertHeadCommit(GitCommit commit) {
assertEquals "Wrong commit at the HEAD", commitMessageForCherryPick(commit), myRepository.head.commitMessage
}
void assertLastCommits(GitCommit... commits) {
GitLightRepository.Commit current = myRepository.head
int level = 0;
for (GitCommit commit : commits) {
assertEquals "Wrong commit at level $level", commitMessageForCherryPick(commit), current.commitMessage
current = current.parent
level++;
}
}
void assertChangeLists(Collection<String> changeLists, String activeChangelist) {
ChangeListManager changeListManager = myPlatformFacade.getChangeListManager(myProject)
List<LocalChangeList> lists = changeListManager.changeLists
Collection<String> listNames = lists.collect { it.name }
assertEquals "Change lists are different", changeLists.toSet(), listNames.toSet()
assertEquals "Wrong active changelist", activeChangelist, changeListManager.defaultChangeList.name
}
String commitDetails(GitCommit commit) {
"${commit.shortHash.toString()} \"${commit.subject}\""
}
String notificationContent(GitCommit... commits) {
commits.collect { commitDetails(it) }.join("<br/>")
}
void assertNotCherryPicked() {
// 1. assert not committed (i.e. git cherry-pick was not performed)
assertNothingCommitted()
// 2. assert working tree not changed (i.e. git cherry-pick -n was not performed either)
assertTrue myPlatformFacade.getChangeListManager(myProject).getAllChanges().isEmpty()
}
void assertNothingCommitted() {
assertEquals(myInitialCommit, myRepository.head)
}
void prepareConflict() {
myGit.registerOperationExecutors(new MockGit.SimpleErrorOperationExecutor(CHERRY_PICK, CHERRY_PICK_CONFLICT),
new MockGit.SimpleSuccessOperationExecutor(MockGit.OperationName.GET_UNMERGED_FILES, UNMERGED_FILE))
}
void assertMergeDialogShown() {
assertTrue "Merge dialog was not shown", myVcsHelper.mergeDialogWasShown()
}
String newCommitMessage(GitCommit commit) {
"${commit.description}\n\n(cherry-picked from ${commit.hash.value})"
}
protected static class OKCommitDialogHandler implements MockVcsHelper.CommitHandler {
private final GitLightRepository myRepository;
boolean myCommitDialogShown
OKCommitDialogHandler(GitLightRepository repository) {
myRepository = repository
}
@Override
boolean commit(String commitMessage) {
myCommitDialogShown = true;
myRepository.commit(commitMessage) // answering OK in the dialog => committing
return true;
}
boolean wasCommitDialogShown() {
myCommitDialogShown
}
}
protected static class CancelCommitDialogHandler implements MockVcsHelper.CommitHandler {
boolean myCommitDialogShown
@Override
boolean commit(String commitMessage) {
myCommitDialogShown = true;
return false;
}
boolean wasCommitDialogShown() {
myCommitDialogShown
}
}
}
@@ -1,196 +0,0 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package git4idea.cherrypick
import com.intellij.notification.NotificationType
import git4idea.history.browser.GitCherryPicker
import git4idea.history.browser.GitCommit
import git4idea.test.GitLightRepository
import git4idea.test.MockGit
import com.intellij.dvcs.test.MockVcsHelper
import org.junit.Before
import org.junit.Test
import static MockGit.OperationName.CHERRY_PICK
import static junit.framework.Assert.*
/**
* Tests for {@link GitCherryPicker}, when the "auto-commit on cherry-pick" option is deselected.
* Most situations are equal or similar, so the majority of cherry pick tests are located in {@link GitAutoCommittingCherryPickTest}.
*
* @author Kirill Likhodedov
*/
class GitNotCommittingCherryPickTest extends GitCherryPickTest {
@Before
void setUp() {
super.setUp()
myCherryPicker = new GitCherryPicker(myProject, myGit, myPlatformFacade, false)
}
@Test
void "clean tree, no conflicts, then show commit dialog, commit on ok"() {
GitCommit commit = commit()
myGit.registerOperationExecutors(new MockGit.SuccessfulCherryPickExecutor(myRepository, commit))
OKCommitDialogHandler handler = new OKCommitDialogHandler(myRepository)
myVcsHelper.registerHandler(handler)
invokeCherryPick(commit)
assertHeadCommit(commit)
assertOnlyDefaultChangelist()
assertTrue "Commit dialog was not shown", handler.wasCommitDialogShown()
// notification is shown from the successful commit, can't check from here
}
@Test
void "cancel in commit dialog shouldn't show a notification"() {
GitCommit commit = commit()
myGit.registerOperationExecutors(new MockGit.SuccessfulCherryPickExecutor(myRepository, commit))
CancelCommitDialogHandler handler = new CancelCommitDialogHandler()
myVcsHelper.registerHandler(handler)
invokeCherryPick(commit)
assertTrue "Commit dialog was not shown", handler.wasCommitDialogShown()
assertNull "Notification should not be shown when cancelling a single commit", myTestNotificator.lastNotification
}
@Test
void "cancel in 2nd commit dialog after successful commit should shown a notification"() {
GitCommit commit1 = commit()
GitCommit commit2 = commit()
myGit.registerOperationExecutors(new MockGit.SimpleSuccessOperationExecutor(CHERRY_PICK, ""),
new MockGit.SimpleSuccessOperationExecutor(CHERRY_PICK, ""))
int dialogNumber = 0;
MockVcsHelper.CommitHandler handler = new MockVcsHelper.CommitHandler() {
boolean commit(String commitMessage) {
dialogNumber++;
// answer OK in the first dialog, Cancel - in the second.
return dialogNumber == 1;
}
}
myVcsHelper.registerHandler(handler)
invokeCherryPick([commit1, commit2])
assertEquals "Commit dialog shown wrong number of times", 2, dialogNumber
assertNotificationShown("Cherry-pick cancelled",
"""
${commitDetails(commit2)}
<hr/>
However cherry-pick succeeded for the following commit:<br/>
${commitDetails(commit1)}
""", NotificationType.WARNING)
}
@Test
void "dirty tree, conflicting with commit, then show error"() {
myGit.registerOperationExecutors(new MockGit.SimpleErrorOperationExecutor(CHERRY_PICK, LOCAL_CHANGES_OVERWRITTEN_BY_CHERRY_PICK))
def commit = commit()
OKCommitDialogHandler handler = new OKCommitDialogHandler(myRepository)
myVcsHelper.registerHandler(handler)
invokeCherryPick(commit)
assertNotCherryPicked()
assertFalse "Commit dialog was shown, but it shouldn't", handler.wasCommitDialogShown()
assertOnlyDefaultChangelist()
assertNotificationShown("Cherry-pick failed",
"""
${commitDetails(commit)}<br/>
Your local changes would be overwritten by cherry-pick.<br/>
Commit your changes or stash them to proceed.
""",
NotificationType.ERROR)
}
@Test
void "conflict, merge ok, commit cancelled, then new & active changelist"() {
prepareConflict()
CancelCommitDialogHandler handler = new CancelCommitDialogHandler()
myVcsHelper.registerHandler(handler)
GitCommit commit = commit()
invokeCherryPick(commit)
assertMergeDialogShown()
assertTrue "Commit dialog was not shown", handler.wasCommitDialogShown()
assertChangeLists([DEFAULT, newCommitMessage(commit)], newCommitMessage(commit))
}
@Test
void "2 simple commits in a row, then 2 commit dialogs in a row"() {
GitCommit commit1 = commit()
GitCommit commit2 = commit()
myGit.registerOperationExecutors(new MockGit.SimpleSuccessOperationExecutor(CHERRY_PICK, ""),
new MockGit.SimpleSuccessOperationExecutor(CHERRY_PICK, ""))
CountingOKCommitHandler handler = new CountingOKCommitHandler(myRepository)
myVcsHelper.registerHandler(handler)
invokeCherryPick([commit1, commit2])
assertOnlyDefaultChangelist()
assertEquals "Commit dialog shown wrong number of times", 2, handler.myCommitDialogs
assertLastCommits(commit2, commit1)
}
@Test
void "3 commits, 2nd conflicts with committed, then 1st success, on 2nd show merge dialog"() {
GitCommit commit1 = commit("First")
GitCommit commit2 = commit("Second")
GitCommit commit3 = commit("Third")
myGit.registerOperationExecutors(new MockGit.SimpleSuccessOperationExecutor(CHERRY_PICK, ""))
prepareConflict()
myGit.registerOperationExecutors(new MockGit.SimpleSuccessOperationExecutor(CHERRY_PICK, ""))
CountingOKCommitHandler handler = new CountingOKCommitHandler(myRepository)
myVcsHelper.registerHandler(handler)
invokeCherryPick([commit1, commit2, commit3])
assertMergeDialogShown()
assertEquals "Commit dialog shown wrong number of times", 3, handler.myCommitDialogs
assertLastCommits commit3, commit2, commit1
}
private static class CountingOKCommitHandler implements MockVcsHelper.CommitHandler {
GitLightRepository myRepository
int myCommitDialogs;
CountingOKCommitHandler(GitLightRepository repository) {
myRepository = repository
}
@Override
boolean commit(String commitMessage) {
myCommitDialogs++
myRepository.commit(commitMessage)
return true;
}
}
}