All Downloads are FREE. Search and download functionalities are using the official Maven repository.

fm.last.commons.test.LastAssertions Maven / Gradle / Ivy

There is a newer version: 7.0.2
Show newest version
/*
 * Copyright 2012 Last.fm
 *
 *  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 fm.last.commons.test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;

import javax.sql.DataSource;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.junit.Assert;
import org.junit.ComparisonFailure;

import fm.last.commons.lang.units.JedecByteUnit;

/**
 * Additional test assertions that provide Last.fm specific functionality or additional functionality not found in
 * JUnit.
 */
public final class LastAssertions {

  /**
   * Last.fm standard is to name all unit tests with the name of the original database and then this suffix.
   */
  public static final String TEST_DB_SUFFIX = "_unittest";

  private LastAssertions() {
  }

  /**
   * Asserts that the database that the passed DataSource has been configured to use is a unit test database.
   * 
   * @param dataSource Configured DataSource.
   * @throws SQLException If an error occurs connecting to the database to retrieve the database name.
   */
  public static void assertTestDatabase(DataSource dataSource) throws SQLException {
    Connection connection = null;
    String dbName = null;
    try {
      connection = dataSource.getConnection();
      dbName = connection.getCatalog();
    } finally {
      if (connection != null) {
        connection.close();
      }
    }
    if (!dbName.endsWith(TEST_DB_SUFFIX)) {
      throw new IllegalArgumentException("Database provided was " + dbName
          + " but tests must run against a database who's name ends with " + TEST_DB_SUFFIX);
    }
  }

  /**
   * Asserts that the *contents* of the passed files are equal.
   * 
   * @param file1 File to compare.
   * @param file2 File to compare.
   * @throws IOException If an error occurs comparing the file contents.
   */
  public static void assertFileEquals(File file1, File file2) throws IOException {
    assertFileEquals(null, file1, file2);
  }

  /**
   * Asserts that the *contents* of the passed files are equal.
   * 
   * @param message Failure message.
   * @param expectedFile File containing expected data.
   * @param actualFile File to compare.
   * @throws IOException If an error occurs comparing the file contents.
   */
  public static void assertFileEquals(String message, File expectedFile, File actualFile) throws IOException {
    assertFileEquals(message, expectedFile, null, actualFile, null);
  }

  /**
   * Asserts that the *contents* of the passed files are equal.
   * 
   * @param message Failure message.
   * @param expectedFile File containing expected data.
   * @param expectedFileEncoding Encoding of expected file.
   * @param actualFile File to compare.
   * @param actualFileEncoding Encoding of actual file.
   * @throws IOException If an error occurs comparing the file contents.
   */
  public static void assertFileEquals(String message, File expectedFile, Charset expectedFileEncoding, File actualFile,
      Charset actualFileEncoding) throws IOException {
    boolean equal = true;

    long expectedFileLength = expectedFile.length();
    long actualFileLength = actualFile.length();
    if (expectedFileLength != actualFileLength) {
      equal = false;
    } else {
      equal = fileBytesEqual(expectedFile, actualFile);
    }
    if (!equal) {

      if (message == null) {
        message = "";
      }
      if (Math.max(expectedFileLength, actualFileLength) < JedecByteUnit.MEGABYTES.toBytes(1)) {
        expectedFileEncoding = resolveToDefault(expectedFileEncoding);
        actualFileEncoding = resolveToDefault(actualFileEncoding);
        throw new ComparisonFailure(message, FileUtils.readFileToString(expectedFile, expectedFileEncoding),
            FileUtils.readFileToString(actualFile, actualFileEncoding));
      } else {
        Assert.fail(expectedFile + " not equal to " + actualFile);
      }

    }
  }

  private static boolean fileBytesEqual(File expectedFile, File actualFile) throws IOException {
    InputStream expected = null;
    InputStream actual = null;
    try {
      expected = new BufferedInputStream(new FileInputStream(expectedFile));
      actual = new BufferedInputStream(new FileInputStream(actualFile));
      int readExpected;
      int readActual;
      do {
        readActual = actual.read();
        readExpected = expected.read();
        if (readActual != readExpected) {
          return false;
        }
      } while (readExpected != -1 && readActual != -1);
    } finally {
      IOUtils.closeQuietly(expected);
      IOUtils.closeQuietly(actual);
    }
    return true;
  }

  private static Charset resolveToDefault(Charset charset) {
    if (charset == null) {
      return Charset.defaultCharset();
    }
    return charset;
  }

  /**
   * Asserts that the *contents* of the passed files are not equal.
   * 
   * @param expectedFile File containing expected data.
   * @param actualFile File to compare.
   * @throws IOException If an error occurs comparing the file contents.
   */
  public static void assertFilesNotEqual(File expectedFile, File actualFile) throws IOException {
    assertFilesNotEqual(null, expectedFile, actualFile);
  }

  /**
   * Asserts that the *contents* of the passed files are not equal.
   * 
   * @param message Failure message.
   * @param file1 File to compare.
   * @param file2 File to compare.
   * @throws IOException If an error occurs comparing the file contents.
   */
  public static void assertFilesNotEqual(String message, File file1, File file2) throws IOException {
    boolean equalsFailed = false;
    try {
      assertFileEquals(file1, file2);
    } catch (AssertionError e) {
      equalsFailed = true;
    }
    if (!equalsFailed) {
      fail(message);
    }
  }

  /**
   * Assert that all Objects in the passed array match the expected value.
   * 
   * @param expectedValue Expected value.
   * @param values Array of Objects to compare.
   */
  public static void assertValues(String expectedValue, Object[] values) {
    for (Object value : values) {
      Assert.assertEquals(expectedValue, value);
    }
  }

  /**
   * Asserts that the contents of the files are equivalent - i.e. the same lines but not necessarily in the same order.
   * This allows you to compare files with contents that might be sorted differently. The default Charset is used for
   * reading the files.
   * 
   * @param expected File containing expected data.
   * @param actual File to compare.
   * @throws IOException If an error occurs comparing the file contents.
   */
  public static void assertFilesEquivalent(File expected, File actual) throws IOException {
    assertFilesEquivalent(expected, null, actual, null);
  }

  /**
   * Asserts that the contents of the files are equivalent - i.e. the same lines but not necessarily in the same order.
   * This allows you to compare files with contents that might be sorted differently.
   * 
   * @param expected File containing expected data.
   * @param expectedFileEncoding Encoding of expected file.
   * @param actual File to compare.
   * @param actualFileEncoding Encoding of actual file.
   * @throws IOException If an error occurs comparing the file contents.
   */
  public static void assertFilesEquivalent(File expected, Charset expectedFileEncoding, File actual,
      Charset actualFileEncoding) throws IOException {
    expectedFileEncoding = resolveToDefault(expectedFileEncoding);
    actualFileEncoding = resolveToDefault(actualFileEncoding);
    List expectedLines = FileUtils.readLines(expected, expectedFileEncoding);
    List actualLines = FileUtils.readLines(actual, actualFileEncoding);
    int expectedLineCount = expectedLines.size();
    int actualLineCount = actualLines.size();
    Collection difference;
    if (expectedLineCount >= actualLineCount) {
      difference = CollectionUtils.subtract(expectedLines, actualLines);
    } else {
      difference = CollectionUtils.subtract(actualLines, expectedLines);
    }
    assertEquals("Unexpected difference: " + difference, 0, difference.size());
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy