X-Git-Url: http://git.nikiroo.be/?p=fanfix.git;a=blobdiff_plain;f=src%2Fbe%2Fnikiroo%2Futils%2Ftest%2FTestCase.java;fp=src%2Fbe%2Fnikiroo%2Futils%2Ftest%2FTestCase.java;h=fe7b9af5e141d5f750be96b5c692b51484158f4f;hp=0000000000000000000000000000000000000000;hb=d46b7b96f94e88a776bcd2dfd756549ffb300cc9;hpb=c9994f27667bc421bcd448d39e55774fddf5c431 diff --git a/src/be/nikiroo/utils/test/TestCase.java b/src/be/nikiroo/utils/test/TestCase.java new file mode 100644 index 0000000..fe7b9af --- /dev/null +++ b/src/be/nikiroo/utils/test/TestCase.java @@ -0,0 +1,535 @@ +package be.nikiroo.utils.test; + +import java.io.File; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import be.nikiroo.utils.IOUtils; + +/** + * A {@link TestCase} that can be run with {@link TestLauncher}. + * + * @author niki + */ +abstract public class TestCase { + /** + * The type of {@link Exception} used to signal a failed assertion or a + * force-fail. + * + * @author niki + */ + class AssertException extends Exception { + private static final long serialVersionUID = 1L; + + public AssertException(String reason, Exception source) { + super(reason, source); + } + + public AssertException(String reason) { + super(reason); + } + } + + private String name; + + /** + * Create a new {@link TestCase}. + * + * @param name + * the test name + */ + public TestCase(String name) { + this.name = name; + } + + /** + * This constructor can be used if you require a no-param constructor. In + * this case, you are allowed to set the name manually via + * {@link TestCase#setName}. + */ + protected TestCase() { + this("no name"); + } + + /** + * Setup the test (called before the test is run). + * + * @throws Exception + * in case of error + */ + public void setUp() throws Exception { + } + + /** + * Tear-down the test (called when the test has been ran). + * + * @throws Exception + * in case of error + */ + public void tearDown() throws Exception { + } + + /** + * The test name. + * + * @return the name + */ + public String getName() { + return name; + } + + /** + * The test name. + * + * @param name + * the new name (internal use only) + * + * @return this (so we can chain and so we can initialize it in a member + * variable if this is an anonymous inner class) + */ + protected TestCase setName(String name) { + this.name = name; + return this; + } + + /** + * Actually do the test. + * + * @throws Exception + * in case of error + */ + abstract public void test() throws Exception; + + /** + * Force a failure. + * + * @throws AssertException + * every time + */ + public void fail() throws AssertException { + fail(null); + } + + /** + * Force a failure. + * + * @param reason + * the failure reason + * + * @throws AssertException + * every time + */ + public void fail(String reason) throws AssertException { + fail(reason, null); + } + + /** + * Force a failure. + * + * @param reason + * the failure reason + * @param e + * the exception that caused the failure (can be NULL) + * + * @throws AssertException + * every time + */ + public void fail(String reason, Exception e) throws AssertException { + throw new AssertException("Failed!" + // + reason != null ? "\n" + reason : "", e); + } + + /** + * Check that 2 {@link Object}s are equals. + * + * @param expected + * the expected value + * @param actual + * the actual value + * + * @throws AssertException + * in case they differ + */ + public void assertEquals(Object expected, Object actual) + throws AssertException { + assertEquals(null, expected, actual); + } + + /** + * Check that 2 {@link Object}s are equals. + * + * @param errorMessage + * the error message to display if they differ + * @param expected + * the expected value + * @param actual + * the actual value + * + * @throws AssertException + * in case they differ + */ + public void assertEquals(String errorMessage, Object expected, Object actual) + throws AssertException { + if ((expected == null && actual != null) + || (expected != null && !expected.equals(actual))) { + if (errorMessage == null) { + throw new AssertException(generateAssertMessage(expected, + actual)); + } + + throw new AssertException(errorMessage, new AssertException( + generateAssertMessage(expected, actual))); + } + } + + /** + * Check that 2 longs are equals. + * + * @param expected + * the expected value + * @param actual + * the actual value + * + * @throws AssertException + * in case they differ + */ + public void assertEquals(long expected, long actual) throws AssertException { + assertEquals(Long.valueOf(expected), Long.valueOf(actual)); + } + + /** + * Check that 2 longs are equals. + * + * @param errorMessage + * the error message to display if they differ + * @param expected + * the expected value + * @param actual + * the actual value + * + * @throws AssertException + * in case they differ + */ + public void assertEquals(String errorMessage, long expected, long actual) + throws AssertException { + assertEquals(errorMessage, Long.valueOf(expected), Long.valueOf(actual)); + } + + /** + * Check that 2 booleans are equals. + * + * @param expected + * the expected value + * @param actual + * the actual value + * + * @throws AssertException + * in case they differ + */ + public void assertEquals(boolean expected, boolean actual) + throws AssertException { + assertEquals(Boolean.valueOf(expected), Boolean.valueOf(actual)); + } + + /** + * Check that 2 booleans are equals. + * + * @param errorMessage + * the error message to display if they differ + * @param expected + * the expected value + * @param actual + * the actual value + * + * @throws AssertException + * in case they differ + */ + public void assertEquals(String errorMessage, boolean expected, + boolean actual) throws AssertException { + assertEquals(errorMessage, Boolean.valueOf(expected), + Boolean.valueOf(actual)); + } + + /** + * Check that 2 doubles are equals. + * + * @param expected + * the expected value + * @param actual + * the actual value + * + * @throws AssertException + * in case they differ + */ + public void assertEquals(double expected, double actual) + throws AssertException { + assertEquals(Double.valueOf(expected), Double.valueOf(actual)); + } + + /** + * Check that 2 doubles are equals. + * + * @param errorMessage + * the error message to display if they differ + * @param expected + * the expected value + * @param actual + * the actual value + * + * @throws AssertException + * in case they differ + */ + public void assertEquals(String errorMessage, double expected, double actual) + throws AssertException { + assertEquals(errorMessage, Double.valueOf(expected), + Double.valueOf(actual)); + } + + /** + * Check that 2 {@link List}s are equals. + * + * @param errorMessage + * the error message to display if they differ + * @param expected + * the expected value + * @param actual + * the actual value + * + * @throws AssertException + * in case they differ + */ + public void assertEquals(List expected, List actual) + throws AssertException { + assertEquals("Assertion failed", expected, actual); + } + + /** + * Check that 2 {@link List}s are equals. + * + * @param errorMessage + * the error message to display if they differ + * @param expected + * the expected value + * @param actual + * the actual value + * + * @throws AssertException + * in case they differ + */ + public void assertEquals(String errorMessage, List expected, + List actual) throws AssertException { + + if (expected.size() != actual.size()) { + assertEquals(errorMessage + ": not same number of items", + list(expected), list(actual)); + } + + int size = expected.size(); + for (int i = 0; i < size; i++) { + assertEquals(errorMessage + ": item " + i + + " (0-based) is not correct", expected.get(i), + actual.get(i)); + } + } + + /** + * Check that 2 {@link File}s are equals, by doing a line-by-line + * comparison. + * + * @param expected + * the expected value + * @param actual + * the actual value + * @param errorMessage + * the error message to display if they differ + * + * @throws AssertException + * in case they differ + */ + public void assertEquals(File expected, File actual) throws AssertException { + assertEquals(generateAssertMessage(expected, actual), expected, actual); + } + + /** + * Check that 2 {@link File}s are equals, by doing a line-by-line + * comparison. + * + * @param errorMessage + * the error message to display if they differ + * @param expected + * the expected value + * @param actual + * the actual value + * + * @throws AssertException + * in case they differ + */ + public void assertEquals(String errorMessage, File expected, File actual) + throws AssertException { + assertEquals(errorMessage, expected, actual, null); + } + + /** + * Check that 2 {@link File}s are equals, by doing a line-by-line + * comparison. + * + * @param errorMessage + * the error message to display if they differ + * @param expected + * the expected value + * @param actual + * the actual value + * @param skipCompare + * skip the lines starting with some values for the given files + * (relative path from base directory in recursive mode) + * + * @throws AssertException + * in case they differ + */ + public void assertEquals(String errorMessage, File expected, File actual, + Map> skipCompare) throws AssertException { + assertEquals(errorMessage, expected, actual, skipCompare, null); + } + + private void assertEquals(String errorMessage, File expected, File actual, + Map> skipCompare, String removeFromName) + throws AssertException { + + if (expected.isDirectory() || actual.isDirectory()) { + assertEquals(errorMessage + ": type mismatch: expected a " + + (expected.isDirectory() ? "directory" : "file") + + ", received a " + + (actual.isDirectory() ? "directory" : "file"), + expected.isDirectory(), actual.isDirectory()); + + List expectedFiles = Arrays.asList(expected.list()); + Collections.sort(expectedFiles); + List actualFiles = Arrays.asList(actual.list()); + Collections.sort(actualFiles); + + assertEquals(errorMessage, expectedFiles, actualFiles); + for (int i = 0; i < actualFiles.size(); i++) { + File expectedFile = new File(expected, expectedFiles.get(i)); + File actualFile = new File(actual, actualFiles.get(i)); + + assertEquals(errorMessage, expectedFile, actualFile, + skipCompare, expected.getAbsolutePath()); + } + } else { + try { + List expectedLines = Arrays.asList(IOUtils + .readSmallFile(expected).split("\n")); + List resultLines = Arrays.asList(IOUtils.readSmallFile( + actual).split("\n")); + + String name = expected.getAbsolutePath(); + if (removeFromName != null && name.startsWith(removeFromName)) { + name = expected.getName() + + name.substring(removeFromName.length()); + } + + assertEquals(errorMessage + ": " + name + + ": the number of lines is not the same", + expectedLines.size(), resultLines.size()); + + for (int j = 0; j < expectedLines.size(); j++) { + String expectedLine = expectedLines.get(j); + String resultLine = resultLines.get(j); + + boolean skip = false; + if (skipCompare != null) { + for (Entry> skipThose : skipCompare + .entrySet()) { + for (String skipStart : skipThose.getValue()) { + if (name.endsWith(skipThose.getKey()) + && expectedLine.startsWith(skipStart) + && resultLine.startsWith(skipStart)) { + skip = true; + } + } + } + } + + if (skip) { + continue; + } + + assertEquals(errorMessage + ": line " + (j + 1) + + " is not the same in file " + name, expectedLine, + resultLine); + } + } catch (Exception e) { + throw new AssertException(errorMessage, e); + } + } + } + + /** + * Check that given {@link Object} is not NULL. + * + * @param errorMessage + * the error message to display if it is NULL + * @param actual + * the actual value + * + * @throws AssertException + * in case they differ + */ + public void assertNotNull(String errorMessage, Object actual) + throws AssertException { + if (actual == null) { + String defaultReason = String.format("" // + + "Assertion failed!%n" // + + "Object should not have been NULL"); + + if (errorMessage == null) { + throw new AssertException(defaultReason); + } + + throw new AssertException(errorMessage, new AssertException( + defaultReason)); + } + } + + /** + * Generate the default assert message for 2 different values that were + * supposed to be equals. + * + * @param expected + * the expected value + * @param actual + * the actual value + * + * @return the message + */ + public static String generateAssertMessage(Object expected, Object actual) { + return String.format("" // + + "Assertion failed!%n" // + + "Expected value: [%s]%n" // + + "Actual value: [%s]", expected, actual); + } + + private static String list(List items) { + StringBuilder builder = new StringBuilder(); + for (Object item : items) { + if (builder.length() == 0) { + builder.append(items.size() + " item(s): "); + } else { + builder.append(", "); + } + + builder.append("" + item); + + if (builder.length() > 60) { + builder.setLength(57); + builder.append("..."); + break; + } + } + + return builder.toString(); + } +}