package org.marketcetera.orderloader;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.marketcetera.orderloader.Messages.ERROR_NO_ORDERS;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Pattern;
import org.apache.commons.lang.SystemUtils;
import org.junit.BeforeClass;
import org.junit.Test;
import org.marketcetera.core.LoggerConfiguration;
import org.marketcetera.module.ExpectedFailure;
import org.marketcetera.trade.BrokerID;
import org.marketcetera.trade.Factory;
import org.marketcetera.trade.Order;
import org.marketcetera.util.except.I18NException;
import org.marketcetera.util.log.I18NBoundMessage2P;
import org.marketcetera.util.log.I18NMessage0P;
import org.marketcetera.util.misc.ClassVersion;
import org.marketcetera.util.unicode.SignatureCharset;
/* $License$ */
/**
* Tests {@link OrderParser} & {@link RowProcessor}
*
* @author anshul@marketcetera.com
* @version $Id: OrderParserTest.java 16841 2014-02-20 19:59:04Z colin $
* @since 1.0.0
*/
@ClassVersion("$Id: OrderParserTest.java 16841 2014-02-20 19:59:04Z colin $")
public class OrderParserTest {
@BeforeClass
public static void setupLogger() {
LoggerConfiguration.logSetup();
}
@Test
public void nullRowProcessor() throws Exception {
new ExpectedFailure<NullPointerException>(){
protected void run() throws Exception {
new OrderParser(null);
}
};
}
@Test
public void nullOrderProcessor() throws Exception {
new ExpectedFailure<NullPointerException>(){
protected void run() throws Exception {
new MockRowProcessor(new BrokerID("yyz"), null);
}
};
}
@Test
public void noInput() throws Exception {
MockOrderProcessor orderProcessor = new MockOrderProcessor();
final MockRowProcessor rowProcessor = new MockRowProcessor(null, orderProcessor);
//No lines
new ExpectedFailure<OrderParsingException>(ERROR_NO_ORDERS){
protected void run() throws Exception {
OrderParser parser = new OrderParser(rowProcessor);
parser.parseOrders(new ByteArrayInputStream("".getBytes()));
}
};
//empty lines
new ExpectedFailure<OrderParsingException>(ERROR_NO_ORDERS){
protected void run() throws Exception {
OrderParser parser = new OrderParser(rowProcessor);
parser.parseOrders(new ByteArrayInputStream(arrayToLines("",
" ", " \t").getBytes()));
}
};
//comments only
new ExpectedFailure<OrderParsingException>(ERROR_NO_ORDERS){
protected void run() throws Exception {
OrderParser parser = new OrderParser(rowProcessor);
parser.parseOrders(new ByteArrayInputStream(arrayToLines("# uno",
"#dos", "#tres").getBytes()));
}
};
//stuff
new ExpectedFailure<OrderParsingException>(ERROR_NO_ORDERS){
protected void run() throws Exception {
OrderParser parser = new OrderParser(rowProcessor);
parser.parseOrders(new ByteArrayInputStream(arrayToLines("#",
" ", "# yes", " \t", "#blue").getBytes()));
}
};
}
@Test
public void sampleInput() throws Exception {
//Native encoding
verifySampleInput(new ByteArrayInputStream(arrayToLines(
SAMPLE_INPUT).getBytes()));
//UTF8 encoding
verifySampleInput(new ByteArrayInputStream(SignatureCharset.UTF8_UTF8.
encode(arrayToLines(SAMPLE_INPUT))));
//UTF32 encoding
verifySampleInput(new ByteArrayInputStream(SignatureCharset.
UTF32BE_UTF32BE.encode(arrayToLines(SAMPLE_INPUT))));
}
@Test
public void misMatchedHeaderRow() throws Exception {
MockOrderProcessor orderProcessor = new MockOrderProcessor();
MockRowProcessor rowProcessor = new MockRowProcessor(null, orderProcessor);
OrderParser parser = new OrderParser(rowProcessor);
assertParser(parser, 0, 0, 0);
String failRow = "duck1,duck2,duck4";
parser.parseOrders(new ByteArrayInputStream(arrayToLines(
"head1,head2,head3,head4",
"cow1,cow2,cow3,cow4",
failRow,
"deer1,deer2,deer3,deer4"
).getBytes()));
assertParser(parser, 4, 0, 0);
assertProcessor(rowProcessor, 2, 1);
List<FailedOrderInfo> list = rowProcessor.getFailedOrders();
assertEquals(1, list.size());
FailedOrderInfo info = list.get(0);
assertEquals(3, info.getIndex());
assertArrayEquals(failRow.split(","),info.getRow());
assertEquals(new I18NBoundMessage2P(Messages.HEADER_ROW_MISMATCH,4, 3),
((I18NException) info.getException()).
getI18NBoundMessage());
}
@Test
public void orderProcessorFailure() throws Exception {
MockOrderProcessor orderProcessor = new MockOrderProcessor();
orderProcessor.setFail(true);
MockRowProcessor rowProcessor = new MockRowProcessor(null, orderProcessor);
OrderParser parser = new OrderParser(rowProcessor);
assertParser(parser, 0, 0, 0);
String failRow = "value1,value2,value3";
parser.parseOrders(new ByteArrayInputStream(arrayToLines(
"head1,head2,header",
failRow
).getBytes()));
assertParser(parser, 2, 0, 0);
assertProcessor(rowProcessor, 0, 1);
List<FailedOrderInfo> list = rowProcessor.getFailedOrders();
assertEquals(1, list.size());
FailedOrderInfo info = list.get(0);
assertEquals(2, info.getIndex());
assertArrayEquals(failRow.split(","),info.getRow());
assertTrue(info.getException().toString(),
info.getException() instanceof IllegalArgumentException);
assertEquals(MockOrderProcessor.ORDER_FAILURE_STRING,
info.getException().getMessage());
}
@Test
public void headerProcessingFailure() throws Exception {
MockOrderProcessor orderProcessor = new MockOrderProcessor();
MockRowProcessor rowProcessor = new MockRowProcessor(null, orderProcessor);
rowProcessor.setHeaderFail(true);
final OrderParser parser = new OrderParser(rowProcessor);
assertParser(parser, 0, 0, 0);
new ExpectedFailure<OrderParsingException>(HEADER_FAILURE){
protected void run() throws Exception {
parser.parseOrders(new ByteArrayInputStream(arrayToLines(
"head1,head2,header",
"value1,value2,value3"
).getBytes()));
}
};
}
@Test
public void rowProcessingFailure() throws Exception {
MockOrderProcessor orderProcessor = new MockOrderProcessor();
MockRowProcessor rowProcessor = new MockRowProcessor(null, orderProcessor);
//Set all rows beginning with 'a' to fail.
rowProcessor.setParseFail(Pattern.compile("^a.*"));
OrderParser parser = new OrderParser(rowProcessor);
assertParser(parser, 0, 0, 0);
parser.parseOrders(new ByteArrayInputStream(arrayToLines(
SAMPLE_INPUT).getBytes()));
assertParser(parser, 17, 6, 4);
assertProcessor(rowProcessor, 4, 2);
List<FailedOrderInfo> list = rowProcessor.getFailedOrders();
assertEquals(2, list.size());
FailedOrderInfo info = list.get(0);
assertEquals(7, info.getIndex());
assertArrayEquals(SAMPLE_INPUT[6].split(","),info.getRow());
assertEquals(PARSE_FAILURE,
((OrderParsingException)info.getException()).getI18NBoundMessage());
info = list.get(1);
assertEquals(11, info.getIndex());
assertArrayEquals(SAMPLE_INPUT[10].split(","),info.getRow());
assertEquals(PARSE_FAILURE,
((OrderParsingException)info.getException()).getI18NBoundMessage());
}
private void verifySampleInput(InputStream inInputStream)
throws IOException, OrderParsingException {
MockOrderProcessor orderProcessor = new MockOrderProcessor();
MockRowProcessor rowProcessor = new MockRowProcessor(null, orderProcessor);
OrderParser parser = new OrderParser(rowProcessor);
assertParser(parser, 0, 0, 0);
parser.parseOrders(inInputStream);
assertParser(parser, 17, 6, 4);
assertProcessor(rowProcessor, 6, 0);
//verify headers
assertArrayEquals(SAMPLE_INPUT[3].split(","), rowProcessor.getHeaders());
List<String[]> rows = rowProcessor.getRows();
assertEquals(6, rows.size());
assertArrayEquals(SAMPLE_INPUT[5].split(","), rows.get(0));
assertArrayEquals(SAMPLE_INPUT[6].split(","), rows.get(1));
assertArrayEquals(SAMPLE_INPUT[8].split(","), rows.get(2));
assertArrayEquals(SAMPLE_INPUT[10].split(","), rows.get(3));
assertArrayEquals(SAMPLE_INPUT[11].split(","), rows.get(4));
assertArrayEquals(SAMPLE_INPUT[13].split(","), rows.get(5));
assertEquals(6, orderProcessor.getOrders().size());
}
@Test
public void brokerID() throws Exception {
MockOrderProcessor orderProcessor = new MockOrderProcessor();
MockRowProcessor rowProcessor = new MockRowProcessor(null, orderProcessor);
assertEquals(null, rowProcessor.geBrokerID());
BrokerID brokerID = new BrokerID("SFO");
rowProcessor = new MockRowProcessor(brokerID, orderProcessor);
assertEquals(brokerID, rowProcessor.geBrokerID());
}
public static void assertParser(OrderParser inParser, int inNumLines,
int inNumBlankLines, int inNumComments) {
assertEquals(inNumLines, inParser.getNumLines());
assertEquals(inNumBlankLines, inParser.getNumBlankLines());
assertEquals(inNumComments, inParser.getNumComments());
}
public static void assertProcessor(RowProcessor inProcessor,
int inSuccess, int inFailed) {
assertEquals(inSuccess, inProcessor.getNumSuccess());
assertEquals(inFailed, inProcessor.getNumFailed());
assertEquals(inFailed, inProcessor.getFailedOrders().size());
assertEquals(inFailed + inSuccess, inProcessor.getTotal());
}
private static class MockRowProcessor extends RowProcessor {
protected MockRowProcessor(BrokerID inBrokerID,
OrderProcessor inProcessor) {
super(inProcessor, inBrokerID);
}
protected void setHeaders(String[] inHeaders) throws OrderParsingException {
mHeaders = inHeaders;
if(mHeaderFail) {
throw new OrderParsingException(HEADER_FAILURE);
}
}
protected Order parseOrder(String[] inRow) throws OrderParsingException {
mRows.add(inRow);
if(mParseFail != null) {
if(mParseFail.matcher(inRow[0]).matches()) {
throw new OrderParsingException(PARSE_FAILURE);
}
}
return Factory.getInstance().createOrderSingle();
}
public String[] getHeaders() {
return mHeaders;
}
public List<String[]> getRows() {
return mRows;
}
public void setHeaderFail(boolean inHeaderFail) {
mHeaderFail = inHeaderFail;
}
public void setParseFail(Pattern inParseFail) {
mParseFail = inParseFail;
}
private boolean mHeaderFail = false;
private Pattern mParseFail = null;
private List<String[]> mRows = new LinkedList<String[]>();
private String[] mHeaders;
}
static String arrayToLines(String... inLines) {
StringBuilder builder = new StringBuilder();
for(String line: inLines) {
builder.append(line).append(SystemUtils.LINE_SEPARATOR);
}
return builder.toString();
}
private static final I18NMessage0P PARSE_FAILURE = new I18NMessage0P(
Messages.LOGGER, "parseFailure");
private static final I18NMessage0P HEADER_FAILURE = new I18NMessage0P(
Messages.LOGGER, "headerFailure");
private static final String[] SAMPLE_INPUT = new String[]{
"# comment followed by empty lines",
"",
" ",
"head1,head2,head3,head4",
"",
"value1,value2,value3,value4",
"avalue1,avalue2,avalue3,avalue4",
"# another comment",
"bvalue1,bvalue2,bvalue3,bvalue4",
" ",
"a1value1,a1value2,a1value3,a1value4",
"b1value1,b1value2,b1value3,b1value4",
"# commentary",
"cvalue1,cvalue2,cvalue3,cvalue4",
"# Trailing comment and empty lines",
" ",
""
};
}