CLIRepositoryTestCase.java

  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. import static org.junit.Assert.assertEquals;

  45. import java.io.File;
  46. import java.io.IOException;
  47. import java.nio.file.Path;
  48. import java.util.ArrayList;
  49. import java.util.Arrays;
  50. import java.util.List;

  51. import org.eclipse.jgit.junit.JGitTestUtil;
  52. import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase;
  53. import org.eclipse.jgit.pgm.CLIGitCommand;
  54. import org.eclipse.jgit.pgm.CLIGitCommand.Result;
  55. import org.eclipse.jgit.pgm.TextBuiltin.TerminatedByHelpException;
  56. import org.junit.Before;

  57. public class CLIRepositoryTestCase extends LocalDiskRepositoryTestCase {
  58.     /** Test repository, initialized for this test case. */
  59.     protected Repository db;

  60.     @Override
  61.     @Before
  62.     public void setUp() throws Exception {
  63.         super.setUp();
  64.         db = createWorkRepository();
  65.     }

  66.     /**
  67.      * Executes specified git commands (with arguments)
  68.      *
  69.      * @param cmds
  70.      *            each string argument must be a valid git command line, e.g.
  71.      *            "git branch -h"
  72.      * @return command output
  73.      * @throws Exception
  74.      */
  75.     protected String[] executeUnchecked(String... cmds) throws Exception {
  76.         List<String> result = new ArrayList<>(cmds.length);
  77.         for (String cmd : cmds) {
  78.             result.addAll(CLIGitCommand.executeUnchecked(cmd, db));
  79.         }
  80.         return result.toArray(new String[0]);
  81.     }

  82.     /**
  83.      * Executes specified git commands (with arguments), throws exception and
  84.      * stops execution on first command which output contains a 'fatal:' error
  85.      *
  86.      * @param cmds
  87.      *            each string argument must be a valid git command line, e.g.
  88.      *            "git branch -h"
  89.      * @return command output
  90.      * @throws Exception
  91.      */
  92.     protected String[] execute(String... cmds) throws Exception {
  93.         List<String> result = new ArrayList<>(cmds.length);
  94.         for (String cmd : cmds) {
  95.             Result r = CLIGitCommand.executeRaw(cmd, db);
  96.             if (r.ex instanceof TerminatedByHelpException) {
  97.                 result.addAll(r.errLines());
  98.             } else if (r.ex != null) {
  99.                 throw r.ex;
  100.             }
  101.             result.addAll(r.outLines());
  102.         }
  103.         return result.toArray(new String[0]);
  104.     }

  105.     /**
  106.      * @param link
  107.      *            the path of the symbolic link to create
  108.      * @param target
  109.      *            the target of the symbolic link
  110.      * @return the path to the symbolic link
  111.      * @throws Exception
  112.      */
  113.     protected Path writeLink(String link, String target) throws Exception {
  114.         return JGitTestUtil.writeLink(db, link, target);
  115.     }

  116.     protected File writeTrashFile(String name, String data)
  117.             throws IOException {
  118.         return JGitTestUtil.writeTrashFile(db, name, data);
  119.     }

  120.     @Override
  121.     protected String read(File file) throws IOException {
  122.         return JGitTestUtil.read(file);
  123.     }

  124.     protected void deleteTrashFile(String name) throws IOException {
  125.         JGitTestUtil.deleteTrashFile(db, name);
  126.     }

  127.     /**
  128.      * Execute the given commands and print the output to stdout. Use this
  129.      * function instead of the normal {@link #execute(String...)} when preparing
  130.      * a test case: the command is executed and then its output is printed on
  131.      * stdout, thus making it easier to prepare the correct command and expected
  132.      * output for the test case.
  133.      *
  134.      * @param cmds
  135.      *            The commands to execute
  136.      * @return the result of the command, see {@link #execute(String...)}
  137.      * @throws Exception
  138.      */
  139.     protected String[] executeAndPrint(String... cmds) throws Exception {
  140.         String[] lines = execute(cmds);
  141.         for (String line : lines) {
  142.             System.out.println(line);
  143.         }
  144.         return lines;
  145.     }

  146.     /**
  147.      * Execute the given commands and print test code comparing expected and
  148.      * actual output. Use this function instead of the normal
  149.      * {@link #execute(String...)} when preparing a test case: the command is
  150.      * executed and test code is generated using the command output as a
  151.      * template of what is expected. The code generated is printed on stdout and
  152.      * can be pasted in the test case function.
  153.      *
  154.      * @param cmds
  155.      *            The commands to execute
  156.      * @return the result of the command, see {@link #execute(String...)}
  157.      * @throws Exception
  158.      */
  159.     protected String[] executeAndPrintTestCode(String... cmds) throws Exception {
  160.         String[] lines = execute(cmds);
  161.         String cmdString = cmdString(cmds);
  162.         if (lines.length == 0)
  163.             System.out.println("\t\tassertTrue(execute(" + cmdString
  164.                     + ").length == 0);");
  165.         else {
  166.             System.out
  167.                     .println("\t\tassertArrayOfLinesEquals(new String[] { //");
  168.             System.out.print("\t\t\t\t\t\t\"" + escapeJava(lines[0]));
  169.             for (int i=1; i<lines.length; i++) {
  170.                 System.out.println("\", //");
  171.                 System.out.print("\t\t\t\t\t\t\"" + escapeJava(lines[i]));
  172.             }
  173.             System.out.println("\" //");
  174.             System.out.println("\t\t\t\t}, execute(" + cmdString + ")); //");
  175.         }
  176.         return lines;
  177.     }

  178.     protected String cmdString(String... cmds) {
  179.         if (cmds.length == 0)
  180.             return "";
  181.         else if (cmds.length == 1)
  182.             return "\"" + escapeJava(cmds[0]) + "\"";
  183.         else {
  184.             StringBuilder sb = new StringBuilder(cmdString(cmds[0]));
  185.             for (int i=1; i<cmds.length; i++) {
  186.                 sb.append(", ");
  187.                 sb.append(cmdString(cmds[i]));
  188.             }
  189.             return sb.toString();
  190.         }
  191.     }

  192.     protected String escapeJava(String line) {
  193.         // very crude implementation but ok for generating test code
  194.         return line.replaceAll("\"", "\\\\\"") //
  195.                 .replaceAll("\\\\", "\\\\\\")
  196.                 .replaceAll("\t", "\\\\t");
  197.     }

  198.     protected String shellQuote(String s) {
  199.         return "'" + s.replace("'", "'\\''") + "'";
  200.     }

  201.     protected String shellQuote(File f) {
  202.         return "'" + f.getPath().replace("'", "'\\''") + "'";
  203.     }

  204.     protected void assertStringArrayEquals(String expected, String[] actual) {
  205.         // if there is more than one line, ignore last one if empty
  206.         assertEquals(1,
  207.                 actual.length > 1 && actual[actual.length - 1].isEmpty()
  208.                         ? actual.length - 1 : actual.length);
  209.         assertEquals(expected, actual[0]);
  210.     }

  211.     protected void assertArrayOfLinesEquals(String[] expected, String[] actual) {
  212.         assertEquals(toString(expected), toString(actual));
  213.     }

  214.     public static String toString(String... lines) {
  215.         return toString(Arrays.asList(lines));
  216.     }

  217.     public static String toString(List<String> lines) {
  218.         StringBuilder b = new StringBuilder();
  219.         for (String s : lines) {
  220.             // trim indentation, to simplify tests
  221.             s = s.trim();
  222.             if (s != null && !s.isEmpty()) {
  223.                 b.append(s);
  224.                 b.append('\n');
  225.             }
  226.         }
  227.         // delete last line break to allow simpler tests with one line compare
  228.         if (b.length() > 0 && b.charAt(b.length() - 1) == '\n') {
  229.             b.deleteCharAt(b.length() - 1);
  230.         }
  231.         return b.toString();
  232.     }

  233.     public static boolean contains(List<String> lines, String str) {
  234.         for (String s : lines) {
  235.             if (s.contains(str)) {
  236.                 return true;
  237.             }
  238.         }
  239.         return false;
  240.     }
  241. }