package com.ricebridge.csvman.test;
import com.ricebridge.csvman.*;
import com.ricebridge.data.Text;
import org.jostraca.util.*;
import junit.framework.*;
import junit.textui.*;
import java.util.*;
import java.io.*;
public class CsvHandlerTest extends TestCase {
public CsvHandlerTest( String pName ) {
super( pName );
}
public static TestSuite suite() {
return new TestSuite( CsvHandlerTest.class );
}
public static void main( String[] pArgs ) {
TestRunner.run( suite() );
}
public void testLifecycle() {
CsvHandler ch = new CsvHandler();
ch.setText( new Text("1,foo,\"a\",bar\n2,baz") );
ch.setCsvSpec( new CsvSpec() );
TestLineListener ln = new TestLineListener();
ch.setLineListener( ln );
ch.load();
assertEquals( "START:LINE1:LINE2:END:", ln.sb.toString() );
}
public void testAddLineReturn() {
CsvHandler ch = new CsvHandler();
ch.setText( new Text( "1,11,111\n"+
"2,22,222\n"+
"bad,line\n"+
"3,33,333\n" ) );
CsvSpec cs = new CsvSpec();
ch.setCsvSpec( cs );
TestLineListener ln = null;
try {
ln = new TestLineListener();
ch.setLineListener( ln );
ch.load();
fail();
}
catch( Exception e ) {
assertEquals( "START:LINE1:LINE2:BAD3:END:", ln.sb.toString() );
assertEquals( 3, ch.getLineCount() );
assertEquals( 1, ch.getBadLineCount() );
assertEquals( "A line was rejected due to invalid data and caused processing to halt. The line was: 'bad,line'.", e.toString() );
assertEquals( 1, ch.getBadLines().size() );
assertEquals( "[[CSV:BadLine:3:bad prefix:SEMANTIC:bad,line]]", ch.getBadLines().toString() );
}
cs.setIgnoreBadLines( true );
ln = new TestLineListener();
ch.setLineListener( ln );
ch.load();
assertEquals( 4, ch.getLineCount() );
assertEquals( 1, ch.getBadLineCount() );
assertEquals( 1, ch.getBadLines().size() );
assertEquals( "[[CSV:BadLine:3:bad prefix:SEMANTIC:bad,line]]", ch.getBadLines().toString() );
assertEquals( "START:LINE1:LINE2:BAD3:LINE4:END:", ln.sb.toString() );
ch.setText( new Text( "1,11,111\n"+
"bad,line1\n"+
"2,22,222\n"+
"bad,line2\n"+
"3,33,333\n" ) );
ln = new TestLineListener();
ch.setLineListener( ln );
ch.load();
assertEquals( 5, ch.getLineCount() );
assertEquals( 2, ch.getBadLineCount() );
assertEquals( 2, ch.getBadLines().size() );
assertEquals( "[[CSV:BadLine:2:bad prefix:SEMANTIC:bad,line1], [CSV:BadLine:4:bad prefix:SEMANTIC:bad,line2]]",
ch.getBadLines().toString() );
}
public void testSaveBadLines() {
ArrayList data = new ArrayList();
data.add( new String[] { "1", "11", "111" } );
data.add( new String[] { "2", "22", "222" } );
data.add( new String[] { "3", "33", "333" } );
String gs
= "1,11,111\n"
+ "2,22,222\n"
+ "3,33,333\n"
;
CsvHandler ch = new CsvHandler();
CsvSpec cs = new CsvSpec();
ch.setCsvSpec( cs );
TestLineProvider lp = null;
String s = null;
ByteArrayOutputStream baos = null;
lp = new TestLineProvider( data );
ch.setLineProvider( lp ); baos = new ByteArrayOutputStream(); ch.setOutputStream( baos );
ch.save();
s = TextUtil.replace( baos.toString(), "\r\n", "\n" );
assertEquals( gs, s );
assertEquals( 3, ch.getLineCount() );
assertEquals( 3, ch.getSavedLines() );
assertEquals( 0, ch.getBadLineCount() );
assertEquals( "[]", ch.getBadLines().toString() );
assertEquals( "SP:HNL:NL:HNL:NL:HNL:NL:HNL:EP:",
lp.sb.toString() );
try {
lp = new TestLineProvider( data );
lp.iFailOnNextLine = 2;
ch.setLineProvider( lp ); baos = new ByteArrayOutputStream(); ch.setOutputStream( baos );
ch.save();
fail();
}
catch( CsvManagerException csvme ) {
assertEquals( "SP:HNL:NL:HNL:NL:FAILNL2:EP:", lp.sb.toString() );
assertTrue( csvme.getBadLine().toString().startsWith("[CSV:BadLine:2:The LineProvider com.ricebridge.csvman.test.CsvHandlerTest$TestLineProvider threw an Exception from method nextLineImpl: java.lang.RuntimeException: nextLine") );
assertTrue( TextUtil.replace(csvme.getBadLine().toString(),"\r\n","\n").endsWith("no data available for bad line, previous line was: [1, 11, 111]]") );
assertEquals( 2, ch.getLineCount() );
assertEquals( 1, ch.getSavedLines() );
assertEquals( 1, ch.getBadLineCount() );
assertEquals( 1, ch.getBadLines().size() );
assertTrue( ch.getBadLines().toString().startsWith("[[CSV:BadLine:2:The LineProvider com.ricebridge.csvman.test.CsvHandlerTest$TestLineProvider threw an Exception from method nextLineImpl: java.lang.RuntimeException: nextLine") );
assertTrue( TextUtil.replace(ch.getBadLines().toString(),"\r\n","\n").endsWith("no data available for bad line, previous line was: [1, 11, 111]]]") );
}
catch( Exception e ) {
e.printStackTrace();
fail();
}
cs.setIgnoreBadLines( true );
lp = new TestLineProvider( data );
lp.iFailOnNextLine = 2;
ch.setLineProvider( lp ); baos = new ByteArrayOutputStream(); ch.setOutputStream( baos );
ch.save();
assertEquals( "SP:HNL:NL:HNL:NL:FAILNL2:HNL:NL:HNL:EP:", lp.sb.toString() );
assertEquals( 3, ch.getLineCount() );
assertEquals( 2, ch.getSavedLines() );
assertEquals( 1, ch.getBadLineCount() );
assertEquals( 1, ch.getBadLines().size() );
assertTrue( ch.getBadLines().toString().startsWith("[[CSV:BadLine:2:The LineProvider com.ricebridge.csvman.test.CsvHandlerTest$TestLineProvider threw an Exception from method nextLineImpl: java.lang.RuntimeException: nextLine") );
assertTrue( TextUtil.replace(ch.getBadLines().toString(),"\r\n","\n").endsWith("no data available for bad line, previous line was: [1, 11, 111]]]") );
cs.setIgnoreBadLines( true );
lp = new TestLineProvider( data );
lp.iFailOnHasNextLine = 1;
ch.setLineProvider( lp ); baos = new ByteArrayOutputStream(); ch.setOutputStream( baos );
ch.save();
assertEquals( "SP:HNL:NL:HNL:FAILHNL1:EP:", lp.sb.toString() );
assertEquals( 2, ch.getLineCount() );
assertEquals( 1, ch.getSavedLines() );
assertEquals( 1, ch.getBadLineCount() );
assertEquals( 1, ch.getBadLines().size() );
assertTrue( ch.getBadLines().toString().startsWith("[[CSV:BadLine:2:The LineProvider com.ricebridge.csvman.test.CsvHandlerTest$TestLineProvider threw an Exception from method hasNextLineImpl: java.lang.RuntimeException: hasNextLine") );
cs.setIgnoreBadLines( true );
lp = new TestLineProvider( data );
lp.iFailOnStartSave = true;
ch.setLineProvider( lp ); baos = new ByteArrayOutputStream(); ch.setOutputStream( baos );
ch.save();
assertEquals( "SP:FAILSS:EP:", lp.sb.toString() );
assertEquals( 0, ch.getLineCount() );
assertEquals( 0, ch.getSavedLines() );
assertEquals( 1, ch.getBadLineCount() );
assertEquals( 1, ch.getBadLines().size() );
cs.setIgnoreBadLines( true );
lp = new TestLineProvider( data );
lp.iFailOnEndSave = true;
ch.setLineProvider( lp ); baos = new ByteArrayOutputStream(); ch.setOutputStream( baos );
ch.save();
assertEquals( "SP:HNL:NL:HNL:NL:HNL:NL:HNL:EP:FAILES:", lp.sb.toString() );
assertEquals( 3, ch.getLineCount() );
assertEquals( 3, ch.getSavedLines() );
assertEquals( 1, ch.getBadLineCount() );
assertEquals( 1, ch.getBadLines().size() );
}
public static final class TestLineListener extends CustomLineListener {
public StringBuffer sb = new StringBuffer();
public StringBuffer data = new StringBuffer();
public void startProcessImpl() {
sb.append("START:");
}
public void endProcessImpl() {
sb.append("END:");
}
public BadLine handleLineImpl( String[] pLine, int pNumFields, long pLineNumber, String pOriginalLine ) {
if( "bad".equals(pLine[0]) ) {
sb.append("BAD"+pLineNumber+":");
return new BadLine( pLineNumber, pOriginalLine, "bad prefix" );
}
sb.append("LINE"+pLineNumber+":");
data.append( Arrays.asList(pLine)+"\n" );
return null;
}
public void handleBadLineImpl( BadLine pBadLine ) throws Exception {
super.handleBadLineImpl( pBadLine );
sb.append("BAD:");
}
}
public static final class TestLineProvider extends CustomLineProvider {
public StringBuffer sb = new StringBuffer();
public boolean iFailOnStartSave = false;
public boolean iFailOnEndSave = false;
public int iFailOnNextLine = -1;
public int iFailOnHasNextLine = -1;
protected List iData = null;
protected long iLineIndex = 0;
public TestLineProvider( List pData ) {
iData = pData;
}
public void startProcessImpl() {
sb.append("SP:");
if( iFailOnStartSave ) { sb.append("FAILSS:"); throw new RuntimeException("startSave"); }
iLineIndex = 0;
}
public void endProcessImpl() {
sb.append("EP:");
if( iFailOnEndSave ) { sb.append("FAILES:"); throw new RuntimeException("endSave"); }
}
public boolean hasNextLineImpl() {
sb.append("HNL:");
if( iLineIndex == iFailOnHasNextLine ) { sb.append("FAILHNL"+iLineIndex+":"); throw new RuntimeException("hasNextLine"); }
return iLineIndex < iData.size();
}
public String[] nextLineImpl() {
sb.append("NL:");
String[] line = (String[]) iData.get( (int) iLineIndex );
iLineIndex++;
if( iLineIndex == iFailOnNextLine ) { sb.append("FAILNL"+iLineIndex+":"); throw new RuntimeException("nextLine"); }
return line;
}
}
}