/**
*
*/
package net.frontlinesms.csv;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.Arrays;
import net.frontlinesms.junit.BaseTestCase;
import org.apache.log4j.Logger;
/**
* Test class for {@link CsvImporter}.
* @author Alex Anderson <alex@frontlinesms.com>
* @author Morgan Belkadi <morgan@frontlinesms.com>
*/
public class CsvImporterTest extends BaseTestCase {
//> CONSTANTS
/** Path to the test resources folder. TODO should probably get these relative to the current {@link ClassLoader}'s path. */
private static final String RESOURCE_PATH = "src/test/resources/net/frontlinesms/csv/";
/** Filters for all tests that should pass */
private static final FilenameFilter PASS_FILENAME_FILTER = new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.endsWith(".pass.csv");
}
};
/** Filters for all tests that should fail */
private static final FilenameFilter FAIL_FILENAME_FILTER = new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.endsWith(".fail.csv");
}
};
//> INSTANCE VARIABLES
/** Logging object */
private final Logger log = Logger.getLogger(this.getClass());
/**
* Get all import test files from /test/net/frontlinesms/csv/import/, and read
* them in. Compare them to test results, which are hard coded here.
* @throws IOException
* @throws CsvParseException
*/
public void testImports_good() throws IOException, CsvParseException {
File importTestsDir = new File(RESOURCE_PATH);
for(File importTestFile : importTestsDir.listFiles(PASS_FILENAME_FILTER)) {
testCsvFile(importTestFile);
}
}
/**
* Get all import test files from /test/net/frontlinesms/csv/import/, and read
* them in. The files should all fail parsing in some way!
* @throws IOException
*/
public void testImports_bad() throws IOException {
File importTestsDir = new File(RESOURCE_PATH);
for(File importTestFile : importTestsDir.listFiles(FAIL_FILENAME_FILTER)) {
try {
testCsvFile(importTestFile);
fail("Expected CsvParseException for file: " + importTestFile.getName());
} catch (CsvParseException ex) {
// Haha, this exception is expected!
log.trace("Testing file: " + importTestFile.getName() + "; got expected exception: " + ex.getMessage());
}
}
}
/**
* @param importTestFile
* @throws FileNotFoundException
* @throws IOException
* @throws CsvParseException
*/
private void testCsvFile(File importTestFile) throws FileNotFoundException,
IOException, CsvParseException {
FileReader reader = new FileReader(importTestFile);
String[][] expectedLines = getExpectedFileContents(importTestFile.getName());
String[] readLine;
int lineIndex = -1;
while((readLine = CsvUtils.readLine(reader)) != null) {
++lineIndex;
log.trace("Readline: " + lineIndex + ": " + toString(readLine));
String[] expectedLine = expectedLines[lineIndex];
assertEquals("Incorrect element count in '" + importTestFile + ":" + lineIndex + "'" +
"\n### READ ###\n" + toString(readLine) +
"\n### EXPECTED ###\n" + toString(expectedLine),
expectedLine.length,
readLine.length);
for (int i = 0; i < expectedLine.length; i++) {
if(!Arrays.deepEquals(readLine, expectedLine)) {
try {
for (int j = 0; j < expectedLine.length; j++) {
String expected = expectedLine[j];
String read = readLine[j];
if(!read.equals(expected)) {
for (int k = 0; k < expected.length(); k++) {
char e = expected.charAt(k);
char r = read.charAt(k);
log.trace("(" + e + ")" + new Integer(e) + " -> ()" + new Integer(r) + "(" + r + ")");
}
}
}
} finally {
fail("Line contents differ in '" + importTestFile + "', read:###\n" + toString(readLine) + "\n###\n" + toString(expectedLine) + "\n###");
}
}
}
}
}
/**
* @param strings
* @return The list of Strings contained in a pair of braces and separated by commas
*/
private static final String toString(String[] strings) {
StringBuilder bob = new StringBuilder();
for(String s : strings) {
if(bob.length() > 0) bob.append(", ");
bob.append(s);
}
return "{" + bob.toString() + "}";
}
/**
* Get the properly imported contents of a test file.
* @param testFileName Filename which should be an integer plus .csv extension, e.g. "1.csv"
* @return
*/
private static final String[][] getExpectedFileContents(String testFileName) {
int testNum = Integer.parseInt(testFileName.substring(0, testFileName.indexOf('.')));
switch(testNum) {
case 0:
return new String[][] {
{"zero", "one", "two", "three", "four"}
};
case 1:
return new String[][] {
{"line 0 cell zero", "cell one", "cell two", "cell three", "cell four"},
{"line 1 cell zero", "cell one", "cell two", "cell three", "cell four"},
{"line 2 cell zero", "cell one", "cell two", "cell three", "cell four"},
{"line 3 cell zero", "cell one", "cell two", "cell three", "cell four"},
{"line 4 cell zero", "cell one", "cell two", "cell three", "cell four"},
{"line 5 cell zero", "cell one", "cell two", "cell three", "cell four"},
{"line 6 cell zero", "cell one", "cell two", "cell three", "cell four"},
{"line 7 cell zero", "cell one", "cell two", "cell three", "cell four"},
{"line 8 cell zero", "cell one", "cell two", "cell three", "cell four"},
{"line 9 cell zero", "cell one", "cell two", "cell three", "cell four"},
{"line 10 cell zero", "cell one", "cell two", "cell three", "cell four","", "last cell was empty", " ", "last cell contained a space", "\t", "last cell contained a tab"},
};
case 2:
return new String[][] {
{
"line 0 cell 0",
"line 0 cell 1",
"line \"0\" cell 2",
"line \"0\"\r\ncell \"3\"",
"\r\n\r\n\r\nline\t0\tcell\t4\""
}
};
case 3:
return new String[][]{
{"Name","Mobile Number","Other Mobile Number","E-mail Address","Current Status","Notes","Group(s)"},
{"Morgan","07691321654","","","Dormant","dangerous","wrecking crew"},
{"Test Number","000","","","Active"},
{"alex","123456789","","","Active"},
{"laura","07788112233","+44123456789","lol@example.com","Active"},
};
case 4:
return new String[][]{
{"Name","Mobile Number","Other Mobile Number","E-mail Address","Current Status","Notes","Group(s)"},
{"Morgan","07691321654","","","Dormant","dangerous","wrecking crew"},
{"Test Number","000","","","Active","",""},
{"alex","123456789","","","Active","",""},
{"laura","07788112233","+44123456789","lol@example.com","Active","",""},
};
default: throw new RuntimeException("Unrecognized test: " + testNum);
}
}
}