From 614dac2f866395654d63ee6e447f4025eb804802 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Wed, 25 Jan 2012 20:53:26 +0400 Subject: [PATCH] GitBranchOperationsTest: local changes overwritten by checkout; smart checkout. --- .../branch/GitBranchOperationsTest.java | 110 ++++++++++++++++-- .../git4idea/tests/git4idea/test/GitExec.java | 18 ++- 2 files changed, 118 insertions(+), 10 deletions(-) diff --git a/plugins/git4idea/tests/git4idea/branch/GitBranchOperationsTest.java b/plugins/git4idea/tests/git4idea/branch/GitBranchOperationsTest.java index 69e5e6c9a3d8..d9b6bc5a21d3 100644 --- a/plugins/git4idea/tests/git4idea/branch/GitBranchOperationsTest.java +++ b/plugins/git4idea/tests/git4idea/branch/GitBranchOperationsTest.java @@ -174,14 +174,14 @@ public class GitBranchOperationsTest extends AbstractVcsTestCase { } @Test - public void checkout_branch_without_problems() throws Exception { + public void checkout_without_problems() throws Exception { prepareBranchForSimpleCheckout(); doCheckout("feature", null); assertNotify(NotificationType.INFORMATION, "Checked out feature"); } @Test - public void checkout_branch_with_unmerged_files_in_first_repo_should_show_notification() throws Exception { + public void checkout_with_unmerged_files_in_first_repo_should_show_notification() throws Exception { prepareBranchForSimpleCheckout(); GitTestScenarioGenerator.prepareUnmergedFiles(myUltimate); doCheckout("feature", null); @@ -189,7 +189,7 @@ public class GitBranchOperationsTest extends AbstractVcsTestCase { } @Test - public void checkout_branch_with_unmerged_file_in_second_repo_should_propose_to_rollback() throws Exception { + public void checkout_with_unmerged_file_in_second_repo_should_propose_to_rollback() throws Exception { prepareBranchForSimpleCheckout(); GitTestScenarioGenerator.prepareUnmergedFiles(myCommunity); doCheckout("feature", null); @@ -219,7 +219,7 @@ public class GitBranchOperationsTest extends AbstractVcsTestCase { } @Test - public void checkout_branch_with_untracked_files_overwritten_by_checkout_in_first_repo_should_show_notification() throws Exception { + public void checkout_with_untracked_files_overwritten_by_checkout_in_first_repo_should_show_notification() throws Exception { prepareUntrackedFilesAndBranchWithSameTrackedFiles(myUltimate); branch(myCommunity, "feature"); branch(myContrib, "feature"); @@ -229,7 +229,7 @@ public class GitBranchOperationsTest extends AbstractVcsTestCase { } @Test - public void checkout_branch_with_untracked_files_overwritten_by_checkout_in_second_repo_should_show_rollback_proposal_with_file_list() throws Exception { + public void checkout_with_untracked_files_overwritten_by_checkout_in_second_repo_should_show_rollback_proposal_with_file_list() throws Exception { prepareUntrackedFilesAndBranchWithSameTrackedFiles(myCommunity); branch(myUltimate, "feature"); branch(myContrib, "feature"); @@ -260,6 +260,97 @@ public class GitBranchOperationsTest extends AbstractVcsTestCase { assertTrue(dialogShown.get()); } + @Test + public void checkout_with_local_changes_overwritten_by_checkout_should_show_smart_checkout_dialog() throws Exception { + prepareLocalChangesAndBranchWithSameModifiedFilesWithoutConflicts(myUltimate); + branch(myCommunity, "feature"); + branch(myContrib, "feature"); + + final AtomicBoolean dialogShown = new AtomicBoolean(); + myDialogManager.registerDialogHandler(GitWouldBeOverwrittenByCheckoutDialog.class, new TestDialogHandler() { + @Override + public int handleDialog(GitWouldBeOverwrittenByCheckoutDialog dialog) { + dialogShown.set(true); + return DialogWrapper.CANCEL_EXIT_CODE; + } + }); + + doCheckout("feature", null); + assertTrue(dialogShown.get()); + } + + @Test + public void agree_to_smart_checkout_should_smart_checkout() throws Exception { + prepareLocalChangesAndBranchWithSameModifiedFilesWithoutConflicts(myUltimate); + prepareLocalChangesAndBranchWithSameModifiedFilesWithoutConflicts(myCommunity); + prepareLocalChangesAndBranchWithSameModifiedFilesWithoutConflicts(myContrib); + myDialogManager.registerDialogHandler(GitWouldBeOverwrittenByCheckoutDialog.class, + new TestDialogHandler() { + @Override + public int handleDialog(GitWouldBeOverwrittenByCheckoutDialog dialog) { + return DialogWrapper.OK_EXIT_CODE; + } + }); + + doCheckout("feature", null); + assertBranch("feature"); + for (GitRepository repository : myRepositories) { + refresh(repository); + assertBranch(repository, "feature"); + assertEquals(read(repository, "local.txt"), "master\ninitial content\nfeature content\n"); + } + } + + @Test + public void deny_to_smart_checkout_in_first_repo_should_show_notification() throws Exception { + prepareLocalChangesAndBranchWithSameModifiedFilesWithoutConflicts(myUltimate); + branch(myCommunity, "feature"); + branch(myContrib, "feature"); + + myDialogManager.registerDialogHandler(GitWouldBeOverwrittenByCheckoutDialog.class, new TestDialogHandler() { + @Override + public int handleDialog(GitWouldBeOverwrittenByCheckoutDialog dialog) { + return DialogWrapper.CANCEL_EXIT_CODE; + } + }); + + doCheckout("feature", null); + assertNotify(NotificationType.ERROR, "Couldn't checkout feature", stripHtmlAndBreaks("Local changes would be overwritten by checkout." + + "Stash or commit them before checking out a branch.")); + assertBranch("master"); + } + + @Test + public void deny_to_smart_checkout_in_second_repo_should_show_rollback_proposal() throws Exception { + prepareLocalChangesAndBranchWithSameModifiedFilesWithoutConflicts(myCommunity); + branch(myUltimate, "feature"); + branch(myContrib, "feature"); + myDialogManager.registerDialogHandler(GitWouldBeOverwrittenByCheckoutDialog.class, new TestDialogHandler() { + @Override + public int handleDialog(GitWouldBeOverwrittenByCheckoutDialog dialog) { + return DialogWrapper.CANCEL_EXIT_CODE; + } + }); + + doCheckout("feature", null); + assertMessage("Couldn't checkout feature", + "Local changes would be overwritten by checkout.
Stash or commit them before checking out a branch.
" + + "However checkout has succeeded for the following repositories:
" + + myUltimate.getPresentableUrl() + + "
You may rollback (checkout back to master) not to let branches diverge.", + "Rollback", "Don't rollback"); + } + + private static void prepareLocalChangesAndBranchWithSameModifiedFilesWithoutConflicts(GitRepository repository) throws IOException { + create(repository, "local.txt", "initial content\n"); + addCommit(repository); + checkout(repository, "-b", "feature"); + edit(repository, "local.txt", "initial content\nfeature content\n"); + addCommit(repository); + checkout(repository, "master"); + edit(repository, "local.txt", "master\ninitial content\n"); + } + private static void prepareUntrackedFilesAndBranchWithSameTrackedFiles(GitRepository repository) throws IOException { checkout(repository, "-b", "feature"); createAddCommit(repository, "untracked.txt"); @@ -422,15 +513,16 @@ public class GitBranchOperationsTest extends AbstractVcsTestCase { private void assertNotify(NotificationType type, @Nullable String title, String content) { Notification notification = myNotificationManager.getLastNotification(); assertNotNull(notification); - assertEquals(stripHtml(notification.getContent()), stripHtml(content)); + assertEquals(stripHtmlAndBreaks(notification.getContent()), stripHtmlAndBreaks(content)); assertEquals(notification.getType(), type); if (title != null) { - assertEquals(stripHtml(notification.getTitle()), stripHtml(title)); + assertEquals(stripHtmlAndBreaks(notification.getTitle()), stripHtmlAndBreaks(title)); } } - private static String stripHtml(String text) { - return StringUtil.stripHtml(text, true); + @NotNull + private static String stripHtmlAndBreaks(@NotNull String text) { + return StringUtil.stripHtml(text, true).replace("\n", ""); } private void assertMessage(String title) { diff --git a/plugins/git4idea/tests/git4idea/test/GitExec.java b/plugins/git4idea/tests/git4idea/test/GitExec.java index 2dab771c7927..cacf79de5907 100644 --- a/plugins/git4idea/tests/git4idea/test/GitExec.java +++ b/plugins/git4idea/tests/git4idea/test/GitExec.java @@ -61,19 +61,35 @@ public class GitExec { } }); } + + @NotNull + public static String read(final @NotNull GitRepository repository, @NotNull String filePath) throws IOException { + final VirtualFile file = repository.getRoot().findFileByRelativePath(filePath); + assert file != null; + return new String(file.contentsToByteArray()); + } public static void add(@NotNull GitRepository repository, @NotNull String filePath) throws IOException { run(repository, "add", filePath); } + public static void add(@NotNull GitRepository repository) throws IOException { + run(repository, "add", "."); + } + public static void commit(@NotNull GitRepository repository) throws IOException { run(repository, "commit", "-m", "message"); } - public static void addCommit(GitRepository repository, String filePath) throws IOException { + public static void addCommit(@NotNull GitRepository repository, @NotNull String filePath) throws IOException { add(repository, filePath); commit(repository); } + + public static void addCommit(@NotNull GitRepository repository) throws IOException { + add(repository); + commit(repository); + } public static void createAddCommit(@NotNull GitRepository repository, @NotNull String filePath) throws IOException { create(repository, filePath);