001/*
002 * SonarQube, open source software quality management tool.
003 * Copyright (C) 2008-2013 SonarSource
004 * mailto:contact AT sonarsource DOT com
005 *
006 * SonarQube is free software; you can redistribute it and/or
007 * modify it under the terms of the GNU Lesser General Public
008 * License as published by the Free Software Foundation; either
009 * version 3 of the License, or (at your option) any later version.
010 *
011 * SonarQube is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014 * Lesser General Public License for more details.
015 *
016 * You should have received a copy of the GNU Lesser General Public License
017 * along with this program; if not, write to the Free Software Foundation,
018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
019 */
020package org.sonar.test;
021
022import com.google.common.base.Charsets;
023import com.google.common.io.Resources;
024import org.apache.commons.io.FileUtils;
025import org.apache.commons.lang.CharUtils;
026import org.apache.commons.lang.StringUtils;
027import org.custommonkey.xmlunit.Diff;
028import org.custommonkey.xmlunit.XMLUnit;
029import org.sonar.api.utils.SonarException;
030import org.xml.sax.SAXException;
031
032import java.io.File;
033import java.io.IOException;
034import java.net.URL;
035
036import static org.hamcrest.core.Is.is;
037import static org.junit.Assert.assertNotNull;
038import static org.junit.Assert.assertThat;
039import static org.junit.Assert.assertTrue;
040
041/**
042 * Utilities for unit tests
043 * 
044 * @since 2.2
045 */
046public final class TestUtils {
047
048  private TestUtils() {
049  }
050
051  /**
052   * Search for a test resource in the classpath. For example getResource("org/sonar/MyClass/foo.txt");
053   * 
054   * @param path the starting slash is optional
055   * @return the resource. Null if resource not found
056   */
057  public static File getResource(String path) {
058    String resourcePath = path;
059    if (!resourcePath.startsWith("/")) {
060      resourcePath = "/" + resourcePath;
061    }
062    URL url = TestUtils.class.getResource(resourcePath);
063    if (url != null) {
064      return FileUtils.toFile(url);
065    }
066    return null;
067  }
068
069  public static String getResourceContent(String path) {
070    URL url = TestUtils.class.getResource(path);
071    if (url == null) {
072      return null;
073    }
074
075    try {
076      return Resources.toString(url, Charsets.UTF_8);
077    } catch (IOException e) {
078      throw new SonarException("Can not load the resource: " + path, e);
079    }
080  }
081
082  /**
083   * Search for a resource in the classpath. For example calling the method getResource(getClass(), "myTestName/foo.txt") from
084   * the class org.sonar.Foo loads the file $basedir/src/test/resources/org/sonar/Foo/myTestName/foo.txt
085   * 
086   * @return the resource. Null if resource not found
087   */
088  public static File getResource(Class baseClass, String path) {
089    String resourcePath = StringUtils.replaceChars(baseClass.getCanonicalName(), '.', '/');
090    if (!path.startsWith("/")) {
091      resourcePath += "/";
092    }
093    resourcePath += path;
094    return getResource(resourcePath);
095  }
096
097  /**
098   * Shortcut for getTestTempDir(baseClass, testName, true) : cleans the unit test directory
099   */
100  public static File getTestTempDir(Class baseClass, String testName) {
101    return getTestTempDir(baseClass, testName, true);
102  }
103
104  /**
105   * Create a temporary directory for unit tests.
106   * 
107   * @param baseClass the unit test class
108   * @param testName the test name
109   * @param clean remove all the sub-directories and files ?
110   */
111  public static File getTestTempDir(Class baseClass, String testName, boolean clean) {
112    File dir = new File("target/test-tmp/" + baseClass.getCanonicalName() + "/" + testName);
113    if (clean && dir.exists()) {
114      try {
115        FileUtils.deleteDirectory(dir);
116      } catch (IOException e) {
117        throw new SonarException("Can not delete the directory " + dir, e);
118      }
119    }
120    try {
121      FileUtils.forceMkdir(dir);
122    } catch (IOException e) {
123      throw new SonarException("Can not create the directory " + dir, e);
124    }
125    return dir;
126  }
127
128  /**
129   * Checks that a file or a directory is not null and exists.
130   */
131  public static void assertExists(File file) {
132    assertNotNull(file);
133    assertThat(file.exists(), is(true));
134  }
135
136  public static void assertSimilarXml(String expectedXml, String xml) throws Exception {
137    Diff diff = isSimilarXml(expectedXml, xml);
138    String message = "Diff: " + diff.toString() + CharUtils.LF + "XML: " + xml;
139    assertTrue(message, diff.similar());
140  }
141
142  static Diff isSimilarXml(String expectedXml, String xml) throws Exception {
143    XMLUnit.setIgnoreWhitespace(true);
144    return XMLUnit.compareXML(xml, expectedXml);
145  }
146}