1
2
3
4
5
6
7
8
9
10 package org.eclipse.jgit.pgm;
11
12 import static org.junit.Assert.assertEquals;
13
14 import java.util.ArrayList;
15 import java.util.Arrays;
16 import java.util.List;
17
18 import org.eclipse.jgit.api.Git;
19 import org.eclipse.jgit.diff.DiffEntry;
20 import org.eclipse.jgit.internal.diffmergetool.CommandLineDiffTool;
21 import org.eclipse.jgit.lib.CLIRepositoryTestCase;
22 import org.eclipse.jgit.pgm.opt.CmdLineParser;
23 import org.eclipse.jgit.pgm.opt.SubcommandHandler;
24 import org.eclipse.jgit.revwalk.RevCommit;
25 import org.eclipse.jgit.treewalk.FileTreeIterator;
26 import org.eclipse.jgit.treewalk.TreeWalk;
27 import org.junit.Before;
28 import org.junit.Test;
29 import org.kohsuke.args4j.Argument;
30
31
32
33
34 public class DiffToolTest extends CLIRepositoryTestCase {
35 public static class GitCliJGitWrapperParser {
36 @Argument(index = 0, metaVar = "metaVar_command", required = true, handler = SubcommandHandler.class)
37 TextBuiltin subcommand;
38
39 @Argument(index = 1, metaVar = "metaVar_arg")
40 List<String> arguments = new ArrayList<>();
41 }
42
43 private String[] runAndCaptureUsingInitRaw(String... args)
44 throws Exception {
45 CLIGitCommand.Result result = new CLIGitCommand.Result();
46
47 GitCliJGitWrapperParser bean = new GitCliJGitWrapperParser();
48 CmdLineParser clp = new CmdLineParser(bean);
49 clp.parseArgument(args);
50
51 TextBuiltin cmd = bean.subcommand;
52 cmd.initRaw(db, null, null, result.out, result.err);
53 cmd.execute(bean.arguments.toArray(new String[bean.arguments.size()]));
54 if (cmd.getOutputWriter() != null) {
55 cmd.getOutputWriter().flush();
56 }
57 if (cmd.getErrorWriter() != null) {
58 cmd.getErrorWriter().flush();
59 }
60 return result.outLines().toArray(new String[0]);
61 }
62
63 private Git git;
64
65 @Override
66 @Before
67 public void setUp() throws Exception {
68 super.setUp();
69 git = new Git(db);
70 git.commit().setMessage("initial commit").call();
71 }
72
73 @Test
74 public void testTool() throws Exception {
75 RevCommit commit = createUnstagedChanges();
76 List<DiffEntry> changes = getRepositoryChanges(commit);
77 String[] expectedOutput = getExpectedDiffToolOutput(changes);
78
79 String[] options = {
80 "--tool",
81 "-t",
82 };
83
84 for (String option : options) {
85 assertArrayOfLinesEquals("Incorrect output for option: " + option,
86 expectedOutput,
87 runAndCaptureUsingInitRaw("difftool", option,
88 "some_tool"));
89 }
90 }
91
92 @Test
93 public void testToolTrustExitCode() throws Exception {
94 RevCommit commit = createUnstagedChanges();
95 List<DiffEntry> changes = getRepositoryChanges(commit);
96 String[] expectedOutput = getExpectedDiffToolOutput(changes);
97
98 String[] options = { "--tool", "-t", };
99
100 for (String option : options) {
101 assertArrayOfLinesEquals("Incorrect output for option: " + option,
102 expectedOutput, runAndCaptureUsingInitRaw("difftool",
103 "--trust-exit-code", option, "some_tool"));
104 }
105 }
106
107 @Test
108 public void testToolNoGuiNoPromptNoTrustExitcode() throws Exception {
109 RevCommit commit = createUnstagedChanges();
110 List<DiffEntry> changes = getRepositoryChanges(commit);
111 String[] expectedOutput = getExpectedDiffToolOutput(changes);
112
113 String[] options = { "--tool", "-t", };
114
115 for (String option : options) {
116 assertArrayOfLinesEquals("Incorrect output for option: " + option,
117 expectedOutput, runAndCaptureUsingInitRaw("difftool",
118 "--no-gui", "--no-prompt", "--no-trust-exit-code",
119 option, "some_tool"));
120 }
121 }
122
123 @Test
124 public void testToolCached() throws Exception {
125 RevCommit commit = createStagedChanges();
126 List<DiffEntry> changes = getRepositoryChanges(commit);
127 String[] expectedOutput = getExpectedDiffToolOutput(changes);
128
129 String[] options = { "--cached", "--staged", };
130
131 for (String option : options) {
132 assertArrayOfLinesEquals("Incorrect output for option: " + option,
133 expectedOutput, runAndCaptureUsingInitRaw("difftool",
134 option, "--tool", "some_tool"));
135 }
136 }
137
138 @Test
139 public void testToolHelp() throws Exception {
140 CommandLineDiffTool[] defaultTools = CommandLineDiffTool.values();
141 List<String> expectedOutput = new ArrayList<>();
142 expectedOutput.add("git difftool --tool=<tool> may be set to one of the following:");
143 for (CommandLineDiffTool defaultTool : defaultTools) {
144 String toolName = defaultTool.name();
145 expectedOutput.add(toolName);
146 }
147 String[] userDefinedToolsHelp = {
148 "user-defined:",
149 "The following tools are valid, but not currently available:",
150 "Some of the tools listed above only work in a windowed",
151 "environment. If run in a terminal-only session, they will fail.",
152 };
153 expectedOutput.addAll(Arrays.asList(userDefinedToolsHelp));
154
155 String option = "--tool-help";
156 assertArrayOfLinesEquals("Incorrect output for option: " + option,
157 expectedOutput.toArray(new String[0]), runAndCaptureUsingInitRaw("difftool", option));
158 }
159
160 private RevCommit createUnstagedChanges() throws Exception {
161 writeTrashFile("a", "Hello world a");
162 writeTrashFile("b", "Hello world b");
163 git.add().addFilepattern(".").call();
164 RevCommit commit = git.commit().setMessage("files a & b").call();
165 writeTrashFile("a", "New Hello world a");
166 writeTrashFile("b", "New Hello world b");
167 return commit;
168 }
169
170 private RevCommit createStagedChanges() throws Exception {
171 RevCommit commit = createUnstagedChanges();
172 git.add().addFilepattern(".").call();
173 return commit;
174 }
175
176 private List<DiffEntry> getRepositoryChanges(RevCommit commit)
177 throws Exception {
178 TreeWalk tw = new TreeWalk(db);
179 tw.addTree(commit.getTree());
180 FileTreeIterator modifiedTree = new FileTreeIterator(db);
181 tw.addTree(modifiedTree);
182 List<DiffEntry> changes = DiffEntry.scan(tw);
183 return changes;
184 }
185
186 private String[] getExpectedDiffToolOutput(List<DiffEntry> changes) {
187 String[] expectedToolOutput = new String[changes.size()];
188 for (int i = 0; i < changes.size(); ++i) {
189 DiffEntry change = changes.get(i);
190 String newPath = change.getNewPath();
191 String oldPath = change.getOldPath();
192 String newIdName = change.getNewId().name();
193 String oldIdName = change.getOldId().name();
194 String expectedLine = "M\t" + newPath + " (" + newIdName + ")"
195 + "\t" + oldPath + " (" + oldIdName + ")";
196 expectedToolOutput[i] = expectedLine;
197 }
198 return expectedToolOutput;
199 }
200
201 private static void assertArrayOfLinesEquals(String failMessage,
202 String[] expected, String[] actual) {
203 assertEquals(failMessage, toString(expected), toString(actual));
204 }
205 }