--- /dev/null
+package be.nikiroo.fanfix.test;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+import be.nikiroo.fanfix.Instance;
+import be.nikiroo.fanfix.Main;
+import be.nikiroo.fanfix.output.BasicOutput;
+import be.nikiroo.utils.IOUtils;
+import be.nikiroo.utils.TempFiles;
+import be.nikiroo.utils.TraceHandler;
+import be.nikiroo.utils.test.TestCase;
+import be.nikiroo.utils.test.TestLauncher;
+
+class ConversionTest extends TestLauncher {
+ private TempFiles tempFiles;
+ private File testFile;
+ private File expectedDir;
+ private File resultDir;
+
+ public ConversionTest(String[] args) {
+ super("Conversion", args);
+
+ addTest(new TestCase("Read the test file") {
+ @Override
+ public void test() throws Exception {
+ assertEquals("The test file \"" + testFile
+ + "\" cannot be found", true, testFile.exists());
+ }
+ });
+
+ addTest(new TestCase("Assure directories exist") {
+ @Override
+ public void test() throws Exception {
+ expectedDir.mkdirs();
+ resultDir.mkdirs();
+ assertEquals("The Expected directory \"" + expectedDir
+ + "\" cannot be created", true, expectedDir.exists());
+ assertEquals("The Result directory \"" + resultDir
+ + "\" cannot be created", true, resultDir.exists());
+ }
+ });
+
+ for (BasicOutput.OutputType type : BasicOutput.OutputType.values()) {
+ // NOT for special mode SYSOUT
+ if (!BasicOutput.OutputType.SYSOUT.equals(type)) {
+ addTest(getTestFor(type));
+ }
+ }
+ }
+
+ @Override
+ protected void start() throws Exception {
+ testFile = new File("test/test.story");
+ expectedDir = new File("test/expected/");
+ resultDir = new File("test/result/");
+
+ tempFiles = new TempFiles("Fanfix-ConversionTest");
+ }
+
+ @Override
+ protected void stop() throws Exception {
+ tempFiles.close();
+ }
+
+ private TestCase getTestFor(final BasicOutput.OutputType type) {
+ return new TestCase(type + " output mode") {
+ @Override
+ public void test() throws Exception {
+ File target = generate(this, testFile, resultDir, type);
+ target = new File(target.getAbsolutePath()
+ + type.getDefaultExtension(false));
+
+ // Check conversion:
+ compareFiles(this, expectedDir, resultDir, type);
+
+ // Cross-checks:
+ for (BasicOutput.OutputType type : BasicOutput.OutputType
+ .values()) {
+ // NOT for special mode SYSOUT
+ if (!BasicOutput.OutputType.SYSOUT.equals(type)) {
+ File crossDir = tempFiles.createTempDir("cross-result");
+ generate(this, target, crossDir, type);
+ compareFiles(this, crossDir, resultDir, type);
+ }
+ }
+ }
+ };
+ }
+
+ private File generate(TestCase testCase, File testFile, File resultDir,
+ BasicOutput.OutputType type) throws Exception {
+ final List<String> errors = new ArrayList<String>();
+
+ TraceHandler previousTraceHandler = Instance.getTraceHandler();
+ Instance.setTraceHandler(new TraceHandler(true, true, 0) {
+ @Override
+ public void error(String message) {
+ errors.add(message);
+ }
+
+ @Override
+ public void error(Exception e) {
+ error(" ");
+ for (Throwable t = e; t != null; t = t.getCause()) {
+ error(((t == e) ? "(" : "..caused by: (")
+ + t.getClass().getSimpleName() + ") "
+ + t.getMessage());
+ for (StackTraceElement s : t.getStackTrace()) {
+ error("\t" + s.toString());
+ }
+ }
+ }
+ });
+
+ try {
+ File target = new File(resultDir, type.toString());
+ int code = Main.convert(testFile.getAbsolutePath(),
+ type.toString(), target.getAbsolutePath(), false, null);
+
+ String error = "";
+ for (String err : errors) {
+ if (!error.isEmpty())
+ error += "\n";
+ error += err;
+ }
+ testCase.assertEquals("The conversion returned an error message: "
+ + error, 0, errors.size());
+ if (code != 0) {
+ testCase.fail("The conversion failed with return code: " + code);
+ }
+
+ return target;
+ } finally {
+ Instance.setTraceHandler(previousTraceHandler);
+ }
+ }
+
+ private void compareFiles(TestCase testCase, File expectedDir,
+ File resultDir, final BasicOutput.OutputType typeToCompare)
+ throws Exception {
+
+ FilenameFilter filter = null;
+ if (typeToCompare != null) {
+ filter = new FilenameFilter() {
+ @Override
+ public boolean accept(File dir, String name) {
+ return name.startsWith(typeToCompare.toString());
+ }
+ };
+ }
+
+ List<String> resultFiles = Arrays.asList(resultDir.list(filter));
+ resultFiles.sort(null);
+ List<String> expectedFiles = Arrays.asList(expectedDir.list(filter));
+ expectedFiles.sort(null);
+
+ testCase.assertEquals("The resulting file names are not expected",
+ expectedFiles, resultFiles);
+
+ for (int i = 0; i < resultFiles.size(); i++) {
+ File expected = new File(expectedDir, expectedFiles.get(i));
+ File result = new File(resultDir, resultFiles.get(i));
+
+ testCase.assertEquals(
+ "Type mismatch: expected a "
+ + (expected.isDirectory() ? "directory" : "file")
+ + ", received a "
+ + (result.isDirectory() ? "directory" : "file"),
+ expected.isDirectory(), result.isDirectory());
+
+ if (expected.isDirectory()) {
+ compareFiles(testCase, expected, result, null);
+ continue;
+ }
+
+ if (expected.getName().endsWith(".cbz")
+ || expected.getName().endsWith(".epub")) {
+ File tmpExpected = tempFiles.createTempDir(expected.getName()
+ + "[zip-content]");
+ File tmpResult = tempFiles.createTempDir(result.getName()
+ + "[zip-content]");
+ unzip(expected, tmpExpected);
+ unzip(result, tmpResult);
+ compareFiles(testCase, tmpExpected, tmpResult, null);
+ } else {
+ List<String> expectedLines = Arrays.asList(IOUtils
+ .readSmallFile(expected).split("\n"));
+ List<String> resultLines = Arrays.asList(IOUtils.readSmallFile(
+ result).split("\n"));
+
+ String name = expected.getAbsolutePath();
+ if (name.startsWith(expectedDir.getAbsolutePath())) {
+ name = expectedDir.getName()
+ + name.substring(expectedDir.getAbsolutePath()
+ .length());
+ }
+ for (int j = 0; j < expectedLines.size(); j++) {
+ String expectedLine = expectedLines.get(j);
+ String resultLine = resultLines.get(j);
+ if (name.endsWith(".info")
+ && expectedLine.startsWith("CREATION_DATE=")
+ && resultLine.startsWith("CREATION_DATE=")) {
+ // TODO: check the format?
+ continue;
+ }
+ testCase.assertEquals("Line " + (j + 1)
+ + " is not the same in file " + name, expectedLine,
+ resultLine);
+ }
+ }
+ }
+ }
+
+ private static void unzip(File zipFile, File targetDirectory)
+ throws IOException {
+ if (targetDirectory.exists() && targetDirectory.isFile()) {
+ throw new IOException("Cannot unzip " + zipFile + " into "
+ + targetDirectory + ": it is not a directory");
+ }
+
+ targetDirectory.mkdir();
+ if (!targetDirectory.exists()) {
+ throw new IOException("Cannot create target directory "
+ + targetDirectory);
+ }
+
+ FileInputStream in = new FileInputStream(zipFile);
+ try {
+ ZipInputStream zipStream = new ZipInputStream(in);
+ try {
+ for (ZipEntry entry = zipStream.getNextEntry(); entry != null; entry = zipStream
+ .getNextEntry()) {
+ File file = new File(targetDirectory, entry.getName());
+ if (entry.isDirectory()) {
+ file.mkdirs();
+ } else {
+ IOUtils.write(zipStream, file);
+ }
+ }
+ } finally {
+ zipStream.close();
+ }
+ } finally {
+ in.close();
+ }
+ }
+}