View Javadoc
1   /*
2    * Copyright (C) 2012, IBM Corporation and others.
3    * and other copyright owners as documented in the project's IP log.
4    *
5    * This program and the accompanying materials are made available
6    * under the terms of the Eclipse Distribution License v1.0 which
7    * accompanies this distribution, is reproduced below, and is
8    * available at http://www.eclipse.org/org/documents/edl-v10.php
9    *
10   * All rights reserved.
11   *
12   * Redistribution and use in source and binary forms, with or
13   * without modification, are permitted provided that the following
14   * conditions are met:
15   *
16   * - Redistributions of source code must retain the above copyright
17   *   notice, this list of conditions and the following disclaimer.
18   *
19   * - Redistributions in binary form must reproduce the above
20   *   copyright notice, this list of conditions and the following
21   *   disclaimer in the documentation and/or other materials provided
22   *   with the distribution.
23   *
24   * - Neither the name of the Eclipse Foundation, Inc. nor the
25   *   names of its contributors may be used to endorse or promote
26   *   products derived from this software without specific prior
27   *   written permission.
28   *
29   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
30   * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
31   * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
32   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
34   * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
36   * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
38   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
41   * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42   */
43  package org.eclipse.jgit.lib;
44  
45  import static org.junit.Assert.assertEquals;
46  
47  import java.io.File;
48  import java.io.IOException;
49  import java.nio.file.Path;
50  import java.util.ArrayList;
51  import java.util.Arrays;
52  import java.util.List;
53  
54  import org.eclipse.jgit.junit.JGitTestUtil;
55  import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase;
56  import org.eclipse.jgit.pgm.CLIGitCommand;
57  import org.eclipse.jgit.pgm.CLIGitCommand.Result;
58  import org.eclipse.jgit.pgm.TextBuiltin.TerminatedByHelpException;
59  import org.junit.Before;
60  
61  public class CLIRepositoryTestCase extends LocalDiskRepositoryTestCase {
62  	/** Test repository, initialized for this test case. */
63  	protected Repository db;
64  
65  	/** Working directory of {@link #db}. */
66  	protected File trash;
67  
68  	@Override
69  	@Before
70  	public void setUp() throws Exception {
71  		super.setUp();
72  		db = createWorkRepository();
73  		trash = db.getWorkTree();
74  	}
75  
76  	/**
77  	 * Executes specified git commands (with arguments)
78  	 *
79  	 * @param cmds
80  	 *            each string argument must be a valid git command line, e.g.
81  	 *            "git branch -h"
82  	 * @return command output
83  	 * @throws Exception
84  	 */
85  	protected String[] executeUnchecked(String... cmds) throws Exception {
86  		List<String> result = new ArrayList<String>(cmds.length);
87  		for (String cmd : cmds) {
88  			result.addAll(CLIGitCommand.executeUnchecked(cmd, db));
89  		}
90  		return result.toArray(new String[0]);
91  	}
92  
93  	/**
94  	 * Executes specified git commands (with arguments), throws exception and
95  	 * stops execution on first command which output contains a 'fatal:' error
96  	 *
97  	 * @param cmds
98  	 *            each string argument must be a valid git command line, e.g.
99  	 *            "git branch -h"
100 	 * @return command output
101 	 * @throws Exception
102 	 */
103 	protected String[] execute(String... cmds) throws Exception {
104 		List<String> result = new ArrayList<String>(cmds.length);
105 		for (String cmd : cmds) {
106 			Result r = CLIGitCommand.executeRaw(cmd, db);
107 			if (r.ex instanceof TerminatedByHelpException) {
108 				result.addAll(r.errLines());
109 			} else if (r.ex != null) {
110 				throw r.ex;
111 			}
112 			result.addAll(r.outLines());
113 		}
114 		return result.toArray(new String[0]);
115 	}
116 
117 	/**
118 	 * @param link
119 	 *            the path of the symbolic link to create
120 	 * @param target
121 	 *            the target of the symbolic link
122 	 * @return the path to the symbolic link
123 	 * @throws Exception
124 	 */
125 	protected Path writeLink(String link, String target) throws Exception {
126 		return JGitTestUtil.writeLink(db, link, target);
127 	}
128 
129 	protected File writeTrashFile(final String name, final String data)
130 			throws IOException {
131 		return JGitTestUtil.writeTrashFile(db, name, data);
132 	}
133 
134 	protected String read(final File file) throws IOException {
135 		return JGitTestUtil.read(file);
136 	}
137 
138 	protected void deleteTrashFile(final String name) throws IOException {
139 		JGitTestUtil.deleteTrashFile(db, name);
140 	}
141 
142 	/**
143 	 * Execute the given commands and print the output to stdout. Use this
144 	 * function instead of the normal {@link #execute(String...)} when preparing
145 	 * a test case: the command is executed and then its output is printed on
146 	 * stdout, thus making it easier to prepare the correct command and expected
147 	 * output for the test case.
148 	 *
149 	 * @param cmds
150 	 *            The commands to execute
151 	 * @return the result of the command, see {@link #execute(String...)}
152 	 * @throws Exception
153 	 */
154 	protected String[] executeAndPrint(String... cmds) throws Exception {
155 		String[] lines = execute(cmds);
156 		for (String line : lines) {
157 			System.out.println(line);
158 		}
159 		return lines;
160 	}
161 
162 	/**
163 	 * Execute the given commands and print test code comparing expected and
164 	 * actual output. Use this function instead of the normal
165 	 * {@link #execute(String...)} when preparing a test case: the command is
166 	 * executed and test code is generated using the command output as a
167 	 * template of what is expected. The code generated is printed on stdout and
168 	 * can be pasted in the test case function.
169 	 *
170 	 * @param cmds
171 	 *            The commands to execute
172 	 * @return the result of the command, see {@link #execute(String...)}
173 	 * @throws Exception
174 	 */
175 	protected String[] executeAndPrintTestCode(String... cmds) throws Exception {
176 		String[] lines = execute(cmds);
177 		String cmdString = cmdString(cmds);
178 		if (lines.length == 0)
179 			System.out.println("\t\tassertTrue(execute(" + cmdString
180 					+ ").length == 0);");
181 		else {
182 			System.out
183 					.println("\t\tassertArrayOfLinesEquals(new String[] { //");
184 			System.out.print("\t\t\t\t\t\t\"" + escapeJava(lines[0]));
185 			for (int i=1; i<lines.length; i++) {
186 				System.out.println("\", //");
187 				System.out.print("\t\t\t\t\t\t\"" + escapeJava(lines[i]));
188 			}
189 			System.out.println("\" //");
190 			System.out.println("\t\t\t\t}, execute(" + cmdString + ")); //");
191 		}
192 		return lines;
193 	}
194 
195 	protected String cmdString(String... cmds) {
196 		if (cmds.length == 0)
197 			return "";
198 		else if (cmds.length == 1)
199 			return "\"" + escapeJava(cmds[0]) + "\"";
200 		else {
201 			StringBuilder sb = new StringBuilder(cmdString(cmds[0]));
202 			for (int i=1; i<cmds.length; i++) {
203 				sb.append(", ");
204 				sb.append(cmdString(cmds[i]));
205 			}
206 			return sb.toString();
207 		}
208 	}
209 
210 	protected String escapeJava(String line) {
211 		// very crude implementation but ok for generating test code
212 		return line.replaceAll("\"", "\\\\\"") //
213 				.replaceAll("\\\\", "\\\\\\")
214 				.replaceAll("\t", "\\\\t");
215 	}
216 
217 	protected void assertStringArrayEquals(String expected, String[] actual) {
218 		// if there is more than one line, ignore last one if empty
219 		assertEquals(1,
220 				actual.length > 1 && actual[actual.length - 1].equals("")
221 						? actual.length - 1 : actual.length);
222 		assertEquals(expected, actual[0]);
223 	}
224 
225 	protected void assertArrayOfLinesEquals(String[] expected, String[] actual) {
226 		assertEquals(toString(expected), toString(actual));
227 	}
228 
229 	public static String toString(String... lines) {
230 		return toString(Arrays.asList(lines));
231 	}
232 
233 	public static String toString(List<String> lines) {
234 		StringBuilder b = new StringBuilder();
235 		for (String s : lines) {
236 			// trim indentation, to simplify tests
237 			s = s.trim();
238 			if (s != null && !s.isEmpty()) {
239 				b.append(s);
240 				b.append('\n');
241 			}
242 		}
243 		// delete last line break to allow simpler tests with one line compare
244 		if (b.length() > 0 && b.charAt(b.length() - 1) == '\n') {
245 			b.deleteCharAt(b.length() - 1);
246 		}
247 		return b.toString();
248 	}
249 
250 	public static boolean contains(List<String> lines, String str) {
251 		for (String s : lines) {
252 			if (s.contains(str)) {
253 				return true;
254 			}
255 		}
256 		return false;
257 	}
258 }