mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[git] cucumber tests: move from groovy to java, introduce virtual commits, understand commit details syntax
Virtual commits are to be able to specify commit hashes in feature files. Since it's not possible to can't assign a hash to a commit, remember the actual hash after committing and link them together. Make it able to specify commit details in the feature file similar to the way they are written in the log, parse it using CommitDetails, and perform the commit given these specifications.
This commit is contained in:
@@ -76,7 +76,7 @@
|
||||
<orderEntry type="library" scope="TEST" name="Groovy" level="project" />
|
||||
<orderEntry type="module" module-name="dvcs" />
|
||||
<orderEntry type="library" scope="TEST" name="cucumber-jvm" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="cucumber-groovy" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="cucumber-java" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
package git4idea
|
||||
import com.intellij.dvcs.test.MockVirtualFile
|
||||
import com.intellij.notification.Notification
|
||||
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.openapi.vfs.newvfs.impl.NullVirtualFile
|
||||
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.TestNotificator
|
||||
|
||||
import static com.intellij.dvcs.test.Executor.echo
|
||||
import static cucumber.runtime.groovy.EN.*
|
||||
import static git4idea.GitCucumberWorld.*
|
||||
import static git4idea.test.GitExecutor.git
|
||||
import static git4idea.test.GitScenarios.checkout
|
||||
import static junit.framework.Assert.assertEquals
|
||||
/**
|
||||
*
|
||||
* @author Kirill Likhodedov
|
||||
*/
|
||||
|
||||
String remCommit
|
||||
|
||||
Given(~'^(enabled|disabled) auto-commit in the settings$') { String state ->
|
||||
boolean enabled = state.equals("enabled")
|
||||
myPlatformFacade.getSettings(myProject).setAutoCommitOnCherryPick(enabled);
|
||||
}
|
||||
|
||||
Given(~'^branch "([^"]*)" with commit "([^"]*)" by "([^"]*)" modifying (.+):$') { String branch, String commitMessage, String author,
|
||||
String file, String content ->
|
||||
checkout(myRepository, branch)
|
||||
echo(file, content)
|
||||
git("commit -am $commitMessage --author '$author <$author@example.com>'")
|
||||
checkout(myRepository, "master")
|
||||
}
|
||||
|
||||
When(~'^I cherry-pick the commit "(.+)"$') { String msg ->
|
||||
String hash = git("log --grep $msg --pretty=%H --all");
|
||||
remCommit = hash
|
||||
new GitCherryPicker(myProject, myGit, myPlatformFacade, myPlatformFacade.getSettings(myProject).isAutoCommitOnCherryPick())
|
||||
.cherryPick(Collections.singletonMap(myRepository, Collections.singletonList(commit(hash, msg))));
|
||||
}
|
||||
|
||||
private GitCommit commit(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);
|
||||
}
|
||||
|
||||
Then(~'^the last commit is$') { String message ->
|
||||
String actual = git("log -1 --pretty=%B");
|
||||
message = message.replace("#hash", remCommit)
|
||||
assertEquals("Commit doesn't match", message, actual);
|
||||
}
|
||||
|
||||
And(~'^notification "([^"]*)" is shown$') { String title ->
|
||||
assertEquals "Notification title is incorrect", title, lastNotification().title
|
||||
}
|
||||
|
||||
private Notification lastNotification() {
|
||||
(myPlatformFacade.getNotificator(myProject) as TestNotificator).lastNotification
|
||||
}
|
||||
|
||||
And(~'^no new changelists are created$') {->
|
||||
assertOnlyDefaultChangelist()
|
||||
}
|
||||
|
||||
void assertOnlyDefaultChangelist() {
|
||||
String DEFAULT = MockChangeListManager.DEFAULT_CHANGE_LIST_NAME;
|
||||
assertChangeLists( [DEFAULT], DEFAULT)
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
package git4idea
|
||||
import com.intellij.dvcs.test.MockProject
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import git4idea.test.GitTestImpl
|
||||
import git4idea.test.GitTestPlatformFacade
|
||||
|
||||
import static com.intellij.dvcs.test.Executor.cd
|
||||
import static com.intellij.dvcs.test.Executor.mkdir
|
||||
import static com.intellij.dvcs.test.Executor.touch
|
||||
import static cucumber.runtime.groovy.EN.Given
|
||||
import static cucumber.runtime.groovy.Hooks.After
|
||||
import static cucumber.runtime.groovy.Hooks.Before
|
||||
import static git4idea.GitCucumberWorld.*
|
||||
import static git4idea.test.GitExecutor.git
|
||||
import static git4idea.test.GitScenarios.checkout
|
||||
import static git4idea.test.GitTestInitUtil.createRepository
|
||||
|
||||
/**
|
||||
* General step definitions and hooks used by all cucumber tests.
|
||||
*
|
||||
* @author Kirill Likhodedov
|
||||
*/
|
||||
|
||||
Before() {
|
||||
myTestRoot = FileUtil.createTempDirectory("", "").getPath()
|
||||
cd myTestRoot
|
||||
myProjectRoot = mkdir ("project")
|
||||
myProject = new MockProject(myProjectRoot)
|
||||
myPlatformFacade = new GitTestPlatformFacade()
|
||||
myGit = new GitTestImpl()
|
||||
|
||||
cd(myProjectRoot)
|
||||
myRepository = createRepository(myProjectRoot, myPlatformFacade, myProject)
|
||||
}
|
||||
|
||||
After() {
|
||||
FileUtil.delete(new File(myTestRoot))
|
||||
Disposer.dispose(myProject)
|
||||
}
|
||||
|
||||
Given(~'^file (.*) on master:$') { String filename, String content ->
|
||||
checkout(myRepository, "master")
|
||||
touch(filename, content)
|
||||
git("add $filename")
|
||||
git("commit -m 'adding $filename'")
|
||||
}
|
||||
@@ -1,28 +1,37 @@
|
||||
Feature: Git Cherry-Pick When Auto-Commit is selected
|
||||
|
||||
Background:
|
||||
Given enabled auto-commit in the settings
|
||||
Given file file.txt on master:
|
||||
"""
|
||||
first line
|
||||
|
||||
last line (space is to have possibility to avoid conflicts)
|
||||
"""
|
||||
Given branch "feature" with commit "fix_1" by "John Bro" modifying file.txt:
|
||||
"""
|
||||
first line
|
||||
|
||||
last line on branch feature
|
||||
"""
|
||||
Background:
|
||||
Given enabled auto-commit in the settings
|
||||
Given file file.txt "initial" on master
|
||||
And commit f5027a3 on branch feature
|
||||
"""
|
||||
fix #1
|
||||
-----
|
||||
Author: John Bro
|
||||
Changes:
|
||||
M file.txt "feature changes"
|
||||
"""
|
||||
|
||||
Scenario: Simple cherry-pick
|
||||
When I cherry-pick the commit "fix_1"
|
||||
When I cherry-pick the commit f5027a3
|
||||
Then the last commit is
|
||||
"""
|
||||
fix_1
|
||||
(cherry picked from commit #hash)
|
||||
fix #1
|
||||
(cherry picked from commit f5027a3)
|
||||
"""
|
||||
And notification "Cherry-pick successful" is shown
|
||||
And there is notification 'Cherry-pick successful'
|
||||
And no new changelists are created
|
||||
|
||||
Scenario: Dirty tree, conflicting with the commit
|
||||
Given file.txt is locally modified:
|
||||
"""
|
||||
master
|
||||
"""
|
||||
When I cherry-pick the commit f5027a3
|
||||
Then nothing is committed
|
||||
And error notification 'Cherry-pick failed' is shown:
|
||||
"""
|
||||
f5027a3 fix #1
|
||||
error: Your local changes to the following files would be overwritten by merge:
|
||||
"""
|
||||
|
||||
|
||||
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static com.intellij.dvcs.test.Executor.echo;
|
||||
import static com.intellij.dvcs.test.Executor.touch;
|
||||
import static git4idea.GitCucumberWorld.virtualCommits;
|
||||
import static git4idea.test.GitExecutor.git;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Kirill Likhodedov
|
||||
*/
|
||||
public class CommitDetails {
|
||||
|
||||
private String myHash;
|
||||
private String myMessage;
|
||||
private String myAuthor;
|
||||
private Collection<Change> myChanges;
|
||||
|
||||
private static class Change {
|
||||
|
||||
public void apply() {
|
||||
switch (myType) {
|
||||
case MODIFIED:
|
||||
echo(myFile, myContent);
|
||||
break;
|
||||
case ADDED:
|
||||
touch(myFile, myContent);
|
||||
break;
|
||||
case DELETED:
|
||||
throw new UnsupportedOperationException("Not implemented yet");
|
||||
case MOVED:
|
||||
throw new UnsupportedOperationException("Not implemented yet");
|
||||
}
|
||||
}
|
||||
|
||||
enum Type {
|
||||
MODIFIED, ADDED, DELETED, MOVED
|
||||
}
|
||||
|
||||
private final Type myType;
|
||||
private final String myFile;
|
||||
private final String myContent;
|
||||
|
||||
Change(Type type, String filename, String content) {
|
||||
myType = type;
|
||||
myFile = filename;
|
||||
myContent = content;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private enum ParsingStage {
|
||||
MESSAGE,
|
||||
DATA,
|
||||
CHANGES
|
||||
}
|
||||
|
||||
/**
|
||||
* Format:
|
||||
* <pre>
|
||||
commit subject
|
||||
|
||||
and optional description
|
||||
-----
|
||||
Author: John Bro
|
||||
Changes:
|
||||
M file.txt "feature changes"
|
||||
* </pre>
|
||||
*/
|
||||
public static CommitDetails parse(String hash, String details) {
|
||||
CommitDetails commit = new CommitDetails();
|
||||
commit.myHash = hash;
|
||||
|
||||
StringBuilder message = new StringBuilder();
|
||||
Collection<Change> changes = new ArrayList<Change>();
|
||||
ParsingStage stage = ParsingStage.MESSAGE;
|
||||
for (String line : details.split("\n")) {
|
||||
if (line.equals("-----")) {
|
||||
stage = ParsingStage.DATA;
|
||||
continue;
|
||||
}
|
||||
else if (line.equals("Changes:")) {
|
||||
stage = ParsingStage.CHANGES;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (stage == ParsingStage.MESSAGE) {
|
||||
message.append(line);
|
||||
}
|
||||
else if (stage == ParsingStage.CHANGES) {
|
||||
changes.add(parseChange(line));
|
||||
}
|
||||
else if (line.toLowerCase().startsWith("author: ")) {
|
||||
commit.myAuthor = line.substring("author: ".length());
|
||||
}
|
||||
}
|
||||
|
||||
commit.myMessage = message.toString();
|
||||
commit.myChanges = changes;
|
||||
return commit;
|
||||
}
|
||||
|
||||
private static Change parseChange(String change) {
|
||||
int firstSpace = change.indexOf(' ');
|
||||
int secondSpace = change.indexOf(' ', firstSpace + 1);
|
||||
return new Change(parseType(change.substring(0, firstSpace)),
|
||||
change.substring(firstSpace + 1, secondSpace),
|
||||
change.substring(secondSpace + 1));
|
||||
}
|
||||
|
||||
private static Change.Type parseType(String type) {
|
||||
if (type.equals("M")) {
|
||||
return Change.Type.MODIFIED;
|
||||
}
|
||||
else if (type.equals("A")) {
|
||||
return Change.Type.ADDED;
|
||||
}
|
||||
else if (type.equals("D")) {
|
||||
return Change.Type.DELETED;
|
||||
}
|
||||
else if (type.equals("R")) {
|
||||
return Change.Type.MOVED;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return real commit details.
|
||||
*/
|
||||
public CommitDetails apply() {
|
||||
for (Change change : myChanges) {
|
||||
change.apply();
|
||||
}
|
||||
|
||||
String commitOutput = git(String.format("commit -am '%1$s' --author '%2$s <%2$s@example.com>'", myMessage, myAuthor));
|
||||
CommitDetails realCommit = parseHashFromCommitOutput(commitOutput);
|
||||
virtualCommits.register(myHash, realCommit);
|
||||
return realCommit;
|
||||
}
|
||||
|
||||
CommitDetails parseHashFromCommitOutput(String commitOutput) {
|
||||
String line = commitOutput.split("\n")[0];
|
||||
Pattern reg = Pattern.compile("^\\s*\\[.+ ([a-fA-F0-9]+)\\] (.+)$");
|
||||
Matcher matcher = reg.matcher(line);
|
||||
boolean matches = matcher.matches();
|
||||
assert matches;
|
||||
return new CommitDetails().hash(matcher.group(1)).message(matcher.group(2));
|
||||
}
|
||||
|
||||
private CommitDetails hash(String hash) {
|
||||
myHash = hash;
|
||||
return this;
|
||||
}
|
||||
|
||||
private CommitDetails message(String message) {
|
||||
myMessage = message;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getHash() {
|
||||
return myHash;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return myMessage;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package git4idea;/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import com.intellij.dvcs.test.MockProject;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import cucumber.annotation.After;
|
||||
import cucumber.annotation.Before;
|
||||
import cucumber.annotation.en.Given;
|
||||
import git4idea.test.GitTestImpl;
|
||||
import git4idea.test.GitTestPlatformFacade;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import static com.intellij.dvcs.test.Executor.cd;
|
||||
import static com.intellij.dvcs.test.Executor.mkdir;
|
||||
import static git4idea.GitCucumberWorld.*;
|
||||
import static git4idea.test.GitExecutor.git;
|
||||
import static git4idea.test.GitExecutor.touch;
|
||||
import static git4idea.test.GitScenarios.checkout;
|
||||
import static git4idea.test.GitTestInitUtil.createRepository;
|
||||
|
||||
/**
|
||||
* @author Kirill Likhodedov
|
||||
*/
|
||||
public class GeneralStepdefs {
|
||||
|
||||
@Before
|
||||
public void setUpProject() throws IOException {
|
||||
myTestRoot = FileUtil.createTempDirectory("", "").getPath();
|
||||
cd(myTestRoot);
|
||||
myProjectRoot = mkdir("project");
|
||||
myProject = new MockProject(myProjectRoot);
|
||||
myPlatformFacade = new GitTestPlatformFacade();
|
||||
myGit = new GitTestImpl();
|
||||
mySettings = myPlatformFacade.getSettings(myProject);
|
||||
|
||||
cd(myProjectRoot);
|
||||
myRepository = createRepository(myProjectRoot, myPlatformFacade, myProject);
|
||||
|
||||
virtualCommits = new GitTestVirtualCommitsHolder();
|
||||
}
|
||||
|
||||
@After
|
||||
public void cleanup() {
|
||||
FileUtil.delete(new File(myTestRoot));
|
||||
Disposer.dispose(myProject);
|
||||
}
|
||||
|
||||
@Given("^file (.*) \"(.*)\" on master$")
|
||||
public void file_file_txt_on_master(String filename, String content) throws Throwable {
|
||||
checkout(myRepository, "master");
|
||||
touch(filename, content);
|
||||
git("add %s", filename);
|
||||
git("commit -m 'adding %s'", filename);
|
||||
}
|
||||
|
||||
@Given("^commit (.+) on branch (.+)$")
|
||||
public void commit_on_branch_feature(String hash, String branch, String commitDetails) throws Throwable {
|
||||
CommitDetails commit = CommitDetails.parse(hash, commitDetails);
|
||||
checkout(branch);
|
||||
commit.apply();
|
||||
checkout("master");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Collections2;
|
||||
import com.intellij.dvcs.test.MockVirtualFile;
|
||||
import com.intellij.notification.Notification;
|
||||
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.openapi.vfs.newvfs.impl.NullVirtualFile;
|
||||
import com.intellij.testFramework.vcs.MockChangeListManager;
|
||||
import com.intellij.testFramework.vcs.MockContentRevision;
|
||||
import cucumber.annotation.en.And;
|
||||
import cucumber.annotation.en.Given;
|
||||
import cucumber.annotation.en.Then;
|
||||
import cucumber.annotation.en.When;
|
||||
import git4idea.history.browser.GitCherryPicker;
|
||||
import git4idea.history.browser.GitCommit;
|
||||
import git4idea.history.browser.SHAHash;
|
||||
import git4idea.history.wholeTree.AbstractHash;
|
||||
import git4idea.test.TestNotificator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
import static com.intellij.dvcs.test.Executor.echo;
|
||||
import static git4idea.GitCucumberWorld.*;
|
||||
import static git4idea.test.GitExecutor.git;
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
|
||||
/**
|
||||
* @author Kirill Likhodedov
|
||||
*/
|
||||
|
||||
public class GitCherryPickStepdefs {
|
||||
|
||||
@Given("^(enabled|disabled) auto-commit in the settings$")
|
||||
public void auto_commit_in_the_settings(String state) {
|
||||
boolean enabled = state.equals("enabled");
|
||||
myPlatformFacade.getSettings(myProject).setAutoCommitOnCherryPick(enabled);
|
||||
}
|
||||
|
||||
@When("^I cherry-pick the commit (.+)$")
|
||||
public void I_cherry_pick_the_commit(String hash) {
|
||||
CommitDetails realCommit = virtualCommits.getRealCommit(hash);
|
||||
new GitCherryPicker(myProject, myGit, myPlatformFacade, mySettings.isAutoCommitOnCherryPick())
|
||||
.cherryPick(Collections.singletonMap(myRepository, Collections.singletonList(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);
|
||||
}
|
||||
|
||||
@Then("^the last commit is$")
|
||||
public void the_last_commit_is(String message) {
|
||||
String actual = git("log -1 --pretty=%B");
|
||||
message = virtualCommits.replaceVirtualHashes(message);
|
||||
assertEquals("Commit doesn't match", message, trimHash(actual));
|
||||
}
|
||||
|
||||
@And("^there is notification '(.*)'$")
|
||||
public void there_is_notification(String title) {
|
||||
assertEquals("Notification title is incorrect", title, lastNotification().getTitle());
|
||||
}
|
||||
|
||||
private static Notification lastNotification() {
|
||||
return ((TestNotificator)myPlatformFacade.getNotificator(myProject)).getLastNotification();
|
||||
}
|
||||
|
||||
@And("^no new changelists are created$")
|
||||
public void no_new_changelists_are_created() {
|
||||
assertOnlyDefaultChangelist();
|
||||
}
|
||||
|
||||
void assertOnlyDefaultChangelist() {
|
||||
String DEFAULT = MockChangeListManager.DEFAULT_CHANGE_LIST_NAME;
|
||||
assertChangeLists(Collections.singleton(DEFAULT), DEFAULT);
|
||||
}
|
||||
|
||||
void assertChangeLists(Collection<String> changeLists, String activeChangelist) {
|
||||
ChangeListManager changeListManager = myPlatformFacade.getChangeListManager(myProject);
|
||||
List<LocalChangeList> lists = changeListManager.getChangeLists();
|
||||
Collection<String> listNames = Collections2.transform(lists, new Function<LocalChangeList, String>() {
|
||||
@Override
|
||||
public String apply(LocalChangeList input) {
|
||||
return input.getName();
|
||||
}
|
||||
});
|
||||
assertEquals("Change lists are different", new ArrayList<String>(changeLists), new ArrayList<String>(listNames));
|
||||
assertEquals("Wrong active changelist", activeChangelist, changeListManager.getDefaultChangeList().getName());
|
||||
}
|
||||
|
||||
@Given("^(.+) is locally modified:$")
|
||||
public void is_locally_modified(String filename, String content) {
|
||||
echo(filename, content);
|
||||
}
|
||||
|
||||
String trimHash(String commitMessage) {
|
||||
int hashStart = commitMessage.lastIndexOf(' ') + 1;
|
||||
String hash = commitMessage.substring(hashStart);
|
||||
return commitMessage.replace(hash, hash.substring(0, 7)) + ")";
|
||||
}
|
||||
|
||||
@Then("^nothing is committed$")
|
||||
public void nothing_is_committed() {
|
||||
assertFalse("Working tree is unexpectedly clean", git("diff").trim().isEmpty());
|
||||
}
|
||||
|
||||
@And("^error notification '(.+)' is shown:$")
|
||||
public void error_notification_is_shown(String title, String content) {
|
||||
assertEquals("Notification title is incorrect", title, lastNotification().getTitle());
|
||||
assertEquals("Notification content is incorrect", virtualCommits.replaceVirtualHashes(content),
|
||||
convertNotificationHtml(lastNotification().getContent()));
|
||||
}
|
||||
|
||||
private static String convertNotificationHtml(String content) {
|
||||
return content.replaceAll("<br/>", Matcher.quoteReplacement("\n"));
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package git4idea;
|
||||
|
||||
import com.intellij.dvcs.test.MockProject;
|
||||
import git4idea.commands.Git;
|
||||
import git4idea.config.GitVcsSettings;
|
||||
import git4idea.repo.GitRepository;
|
||||
|
||||
/**
|
||||
@@ -18,5 +19,7 @@ public class GitCucumberWorld {
|
||||
public static GitPlatformFacade myPlatformFacade;
|
||||
public static Git myGit;
|
||||
public static GitRepository myRepository;
|
||||
public static GitVcsSettings mySettings;
|
||||
|
||||
public static GitTestVirtualCommitsHolder virtualCommits;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* So called Virtual Commits are used in Cucumber feature files, so that the writer of a test could refer to commits in the natural way:
|
||||
* via hashes. We can't define a hash to the commit when committing to Git, therefore to match these two sets we store them here.
|
||||
*
|
||||
* @author Kirill Likhodedov
|
||||
*/
|
||||
public class GitTestVirtualCommitsHolder {
|
||||
|
||||
// virtual hash -> commit details
|
||||
private Map<String, CommitDetails> commits = new HashMap<String, CommitDetails>();
|
||||
|
||||
void register(String virtualHash, CommitDetails CommitInfo) {
|
||||
commits.put(virtualHash, CommitInfo);
|
||||
}
|
||||
|
||||
CommitDetails getRealCommit(String virtualHash) {
|
||||
return commits.get(virtualHash);
|
||||
}
|
||||
|
||||
String replaceVirtualHashes(String message) {
|
||||
for (Map.Entry<String, CommitDetails> entry : commits.entrySet()) {
|
||||
message = message.replace(entry.getKey(), entry.getValue().getHash());
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -95,10 +95,16 @@ class GitExecutor extends Executor {
|
||||
}
|
||||
|
||||
public static String git(GitRepository repository, String command) {
|
||||
cd repository.root.path
|
||||
if (repository != null) {
|
||||
cd repository.root.path
|
||||
}
|
||||
git command
|
||||
}
|
||||
|
||||
public static String git(String formatString, String... args) {
|
||||
return git(String.format(formatString, args))
|
||||
}
|
||||
|
||||
public static void cd(GitRepository repository) {
|
||||
cd repository.root.path
|
||||
}
|
||||
|
||||
@@ -154,16 +154,17 @@ class GitScenarios {
|
||||
git("commit -m just_a_commit")
|
||||
}
|
||||
|
||||
public static boolean branchExists(GitRepository repo, String branch) {
|
||||
public static boolean branchExists(GitRepository repo = null, String branch) {
|
||||
git(repo, "branch").contains(branch)
|
||||
}
|
||||
|
||||
public static void checkout(GitRepository repository, String branch) {
|
||||
if (branchExists(repository, branch)) {
|
||||
public static void checkout(GitRepository repository = null, String branch) {
|
||||
if (branch.equals("master") || branchExists(repository, branch)) {
|
||||
git("checkout $branch")
|
||||
}
|
||||
else {
|
||||
git("checkout -b $branch")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -32,10 +32,12 @@ import org.jetbrains.annotations.NotNull
|
||||
import org.jetbrains.annotations.Nullable
|
||||
|
||||
import java.lang.reflect.Method
|
||||
import static com.intellij.dvcs.test.Executor.cd;
|
||||
import static GitExecutor.git;
|
||||
|
||||
/**
|
||||
* @author Kirill Likhodedov
|
||||
*/
|
||||
@Mixin(GitExecutor)
|
||||
public class GitTestImpl implements Git {
|
||||
|
||||
@NotNull
|
||||
@@ -197,13 +199,13 @@ public class GitTestImpl implements Git {
|
||||
@NotNull String hash,
|
||||
boolean autoCommit,
|
||||
@NotNull GitLineHandlerListener... listeners) {
|
||||
execute(repository, "cherry-pick -x ${autoCommit ? "" : "-n"} $hash")
|
||||
return execute(repository, "cherry-pick -x ${autoCommit ? "" : "-n"} $hash", listeners);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public GitCommandResult getUnmergedFiles(@NotNull GitRepository repository) {
|
||||
execute(repository, "ls-files --unmerged")
|
||||
return execute(repository, "ls-files --unmerged");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -216,28 +218,41 @@ public class GitTestImpl implements Git {
|
||||
}
|
||||
|
||||
private static GitCommandResult commandResult(String output) {
|
||||
boolean success = !output.split("\n").collect { isError(it) }.contains(true)
|
||||
return new GitCommandResult(success, 0, Collections.emptyList(), Arrays.asList(StringUtil.splitByLines(output)))
|
||||
Collection<String> err = new ArrayList<>();
|
||||
Collection<String> out = new ArrayList<>();
|
||||
for (String line : output.split("\n")) {
|
||||
if (isError(line)) {
|
||||
err.add(line);
|
||||
}
|
||||
else {
|
||||
out.add(line);
|
||||
}
|
||||
}
|
||||
boolean success = err.isEmpty();
|
||||
return new GitCommandResult(success, 0, err, out);
|
||||
}
|
||||
|
||||
private static boolean isError(String s) {
|
||||
// we don't want to make that method public, since it is reused only in the test.
|
||||
Method m = GitImpl.class.getDeclaredMethod("isError", String.class)
|
||||
m.setAccessible(true)
|
||||
return m.invoke(null, s) as boolean
|
||||
Method m = GitImpl.class.getDeclaredMethod("isError", String.class);
|
||||
m.setAccessible(true);
|
||||
return (boolean) m.invoke(null, s);
|
||||
}
|
||||
|
||||
static def feedOutput(String output, GitLineHandlerListener... listeners) {
|
||||
private static void feedOutput(String output, GitLineHandlerListener... listeners) {
|
||||
listeners.each { GitLineHandlerListener listener ->
|
||||
output.split("\n").each { listener.onLineAvailable(it, ProcessOutputTypes.STDERR) }
|
||||
String split = output.split("\n")
|
||||
for (String line : split) {
|
||||
listener.onLineAvailable(line, ProcessOutputTypes.STDERR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def execute(GitRepository repository, String operation, GitLineHandlerListener... listeners) {
|
||||
cd repository.root.path
|
||||
def out = git(operation)
|
||||
feedOutput(out, listeners)
|
||||
commandResult(out)
|
||||
private static GitCommandResult execute(GitRepository repository, String operation, GitLineHandlerListener... listeners) {
|
||||
cd(repository.getRoot().getPath());
|
||||
String out = git(operation);
|
||||
feedOutput(out, listeners);
|
||||
return commandResult(out);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6,6 +6,9 @@ import git4idea.GitPlatformFacade
|
||||
import git4idea.repo.GitRepository
|
||||
import git4idea.repo.GitRepositoryImpl
|
||||
|
||||
import static com.intellij.dvcs.test.Executor.*
|
||||
import static git4idea.test.GitExecutor.*
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Kirill Likhodedov
|
||||
@@ -20,17 +23,17 @@ class GitTestInitUtil {
|
||||
* @param repoRoot
|
||||
*/
|
||||
public static void initRepo(String repoRoot) {
|
||||
com.intellij.dvcs.test.Executor.cd repoRoot
|
||||
git4idea.test.GitExecutor.git("init")
|
||||
cd repoRoot
|
||||
git("init")
|
||||
setupUsername();
|
||||
com.intellij.dvcs.test.Executor.touch("initial.txt")
|
||||
git4idea.test.GitExecutor.git("add initial.txt")
|
||||
git4idea.test.GitExecutor.git("commit -m initial")
|
||||
touch("initial.txt")
|
||||
git("add initial.txt")
|
||||
git("commit -m initial")
|
||||
}
|
||||
|
||||
public static void setupUsername() {
|
||||
git4idea.test.GitExecutor.git("config user.name $USER_NAME")
|
||||
git4idea.test.GitExecutor.git("config user.email $USER_EMAIL")
|
||||
git("config user.name $USER_NAME")
|
||||
git("config user.email $USER_EMAIL")
|
||||
}
|
||||
|
||||
public static GitRepository createRepository(String rootDir, GitPlatformFacade platformFacade, Project project) {
|
||||
|
||||
Reference in New Issue
Block a user