/* Copyright (c) 2005-2006 Ricebridge. All Rights Reserved.
 *
 * This file is available under the terms and conditions of the
 * Ricebridge "Open Source API" policy; Ricebridge grants use of this
 * copyrighted work under the terms of a BSD-style license only. See
 * http://www.opensource.org/licenses/bsd-license.php for more
 * information.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 
 *  - Redistributions of source code must retain the above copyright
 *  notice, this list of conditions and the following disclaimer.
 *
 *  - Redistributions in binary form must reproduce the above
 *  copyright notice, this list of conditions and the following
 *  disclaimer in the documentation and/or other materials provided
 *  with the distribution.
 *
 *  - Neither the name of the Ricebridge nor the names of its
 *  contributors may be used to endorse or promote products derived
 *  from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.  
 */

package com.ricebridge.csvman.test;


import com.ricebridge.csvman.*;
import com.ricebridge.data.Text;


import junit.framework.*;
import junit.textui.*;

import java.util.*;


/** Test cases for CSV format edge cases.
 *    <p>The <b><a href="EdgeCasesTest.java.html">Source Code</a></b> of this Java class 
 *    is available under a <a href="http://www.opensource.org/licenses/bsd-license.php">BSD-style license</a>.</p>
 */
public class EdgeCasesTest extends TestCase {

  // test framework
  
  public EdgeCasesTest( String pName ) {
    super( pName );
  }

  public static TestSuite suite() {
    return new TestSuite( EdgeCasesTest.class );
  }

  public static void main( String[] pArgs ) {
    TestRunner.run( suite() );
  }

  
  // test methods

  public void testEmptyLines() {
    CsvManager cm = new CsvManager();
    assertEquals( "[[a], [], [], [b]]", cm.loadAsListsFromString("a\n\n\nb").toString() );
    assertEquals( "[[a], [], [], [b]]", cm.loadAsListsFromString("a\r\n\r\n\r\nb").toString() );
    cm.getCsvSpec().setIgnoreEmptyLines( true );
    assertEquals( "[[a], [b]]", cm.loadAsListsFromString("a\n\n\nb").toString() );
    assertEquals( "[[a], [b]]", cm.loadAsListsFromString("a\r\n\r\n\r\nb").toString() );
  }


  public void testLastComma() {
    CsvManager cm = new CsvManager();
    assertEquals( "[[, ]]", cm.loadAsListsFromString(",").toString() );
    assertEquals( "[[, 1]]", cm.loadAsListsFromString(",1").toString() );
    assertEquals( "[[1, ]]", cm.loadAsListsFromString("1,").toString() );
    assertEquals( "[[1, ], [1, 2]]", cm.loadAsListsFromString("1,\n1,2").toString() );
    assertEquals( "[[1, 2], [1, ]]", cm.loadAsListsFromString("1,2\n1,").toString() );
    assertEquals( "[[1, 2], [1, ], [1, 2]]", cm.loadAsListsFromString("1,2\n1,\n1,2").toString() );

    cm.getCsvSpec().setMergeSeparators( true );
    assertEquals( "[[, ]]", cm.loadAsListsFromString(",").toString() );
    assertEquals( "[[, 1]]", cm.loadAsListsFromString(",1").toString() );
    assertEquals( "[[1, ]]", cm.loadAsListsFromString("1,").toString() );
    assertEquals( "[[1, ], [1, 2]]", cm.loadAsListsFromString("1,\n1,2").toString() );
    assertEquals( "[[1, 2], [1, ]]", cm.loadAsListsFromString("1,2\n1,").toString() );
    assertEquals( "[[1, 2], [1, ], [1, 2]]", cm.loadAsListsFromString("1,2\n1,\n1,2").toString() );
  }


  public void testQuotedEscapeSep() {
    CsvManager csvManager = new CsvManager();
    csvManager.getCsvSpec().setEncoding("UTF-8"); 
    csvManager.setSeparator(";");
    csvManager.setIgnoreBadLines(true);

    List out = csvManager.loadAsListsFromString("test1;test2;\"test3;test4\";test5");
    assertEquals("[[test1, test2, test3;test4, test5]]", out.toString() );

    out = csvManager.loadAsListsFromString("test1;test2;\"test3\\;test4\";test5");
    assertEquals("[[test1, test2, test3\\;test4, test5]]", out.toString() );

    out = csvManager.loadAsListsFromString("test1;test2;\"test3\\; test4\";test5");
    assertEquals("[[test1, test2, test3\\; test4, test5]]", out.toString() );
  }


  public void testLastCommaNumFields() {
    CsvManager cm = new CsvManager();
    NumFieldLineListener nf = new NumFieldLineListener();

    cm.loadFromString(",",nf);     assertEquals( "1:2:2:,~", nf.log.toString() );
    cm.loadFromString("a",nf);     assertEquals( "1:1:1:a~", nf.log.toString() );     
    cm.loadFromString("a,",nf);    assertEquals( "1:2:2:a,~", nf.log.toString() );     
    cm.loadFromString(",a",nf);    assertEquals( "1:2:2:,a~", nf.log.toString() );     
    cm.loadFromString("a,b",nf);   assertEquals( "1:2:2:a,b~", nf.log.toString() );     
    cm.loadFromString("a,b,",nf);  assertEquals( "1:3:3:a,b,~", nf.log.toString() );     
    cm.loadFromString(",a,b,",nf); assertEquals( "1:4:4:,a,b,~", nf.log.toString() );     

    cm.loadFromString(",\n",nf);      assertEquals( "1:2:2:,~", nf.log.toString() );    
    cm.loadFromString("a\n",nf);      assertEquals( "1:1:1:a~", nf.log.toString() );    
    cm.loadFromString("a,\n",nf);     assertEquals( "1:2:2:a,~", nf.log.toString() );   
    cm.loadFromString(",a\n",nf);     assertEquals( "1:2:2:,a~", nf.log.toString() );   
    cm.loadFromString("a,b\n",nf);    assertEquals( "1:2:2:a,b~", nf.log.toString() );  
    cm.loadFromString("a,b,\n",nf);   assertEquals( "1:3:3:a,b,~", nf.log.toString() ); 
    cm.loadFromString(",a,b,\n",nf);  assertEquals( "1:4:4:,a,b,~", nf.log.toString() );

    cm.loadFromString(",\n,",nf);         assertEquals( "1:2:2:,~2:2:2:,~", nf.log.toString() );    
    cm.loadFromString("a\na",nf);         assertEquals( "1:1:1:a~2:1:1:a~", nf.log.toString() );    
    cm.loadFromString("a,\na,",nf);       assertEquals( "1:2:2:a,~2:2:2:a,~", nf.log.toString() );    
    cm.loadFromString(",a\n,a",nf);       assertEquals( "1:2:2:,a~2:2:2:,a~", nf.log.toString() );    
    cm.loadFromString("a,b\na,b",nf);     assertEquals( "1:2:2:a,b~2:2:2:a,b~", nf.log.toString() );    
    cm.loadFromString("a,b,\na,b,",nf);   assertEquals( "1:3:3:a,b,~2:3:3:a,b,~", nf.log.toString() );    
    cm.loadFromString(",a,b,\n,a,b,",nf); assertEquals( "1:4:4:,a,b,~2:4:4:,a,b,~", nf.log.toString() );    
  }


  public void testDisallowQuotedNewlines() {
    CsvManager csvman  = new CsvManager();
    CsvSpec    csvspec = csvman.getCsvSpec();
    csvspec.setAllowQuotedLineEnds(false);

    try {
      csvman.loadFromString("1,2,3\na,\"b\nb\",c");
      fail();
    }
    catch( CsvManagerException cme ) {
      assertEquals( CsvManagerException.CODE_bad_line, cme.getCode() ); 
      System.out.println( cme.getBadLine() );
    }

    csvspec.setIgnoreBadLines(true);
    List data = csvman.loadAsListsFromString("1,2,3\na,\"b,c\nx,y,a\nA,\"B\nB\",C\n4,5,6" ); //\n\"q\nq\"");
    System.out.println( data );
    System.out.println( csvman.getBadLines() );
    assertEquals( 2, csvman.getBadLineCount() );
  }



  public void testLastLine() throws Exception {
    CsvManager cm = new CsvManager();
    NumFieldLineListener nf = new NumFieldLineListener();
    cm.load( TestUtil.getTextCsvFile("08") ,nf ); assertEquals( "1:1:1:no newline at EOF~2:3:3:a,b,c~", nf.log.toString() );    
  }

  
  
  public void testStartEndLineWithLoader() {
    String csv = "1,a\n2,b\n3,c\n4,d\n5,c";
    CsvSpec cs = new CsvSpec();
    cs.setStartLine(2);
    cs.setEndLine(4);
    CsvManager csvman = new CsvManager(cs);

    assertEquals("[[2, b], [3, c], [4, d]]",csvman.loadAsLists(new Text(csv)).toString());
    
    CsvLoader ldr = csvman.makeLoader(new Text(csv));
    StringBuffer res = new StringBuffer();
    
    ldr.begin();
    while( ldr.hasNext() ) {
      String[] row = ldr.next();
      res.append( Arrays.asList(row));
    }
    ldr.end();
    assertEquals("[2, b][3, c][4, d]",res.toString());
    
    
    cs.setStartLine(2);
    cs.setEndLine(2);
    ldr = csvman.makeLoader(new Text(csv));
    res = new StringBuffer();
    
    ldr.begin();
    while( ldr.hasNext() ) {
      String[] row = ldr.next();
      res.append( Arrays.asList(row));
    }
    ldr.end();
    assertEquals("[2, b]",res.toString());
    
    
  }
  
  
  

  public static class NumFieldLineListener extends CustomLineListener {
    StringBuffer log;
    public void startProcessImpl() throws Exception {
      log = new StringBuffer();
    }
    public BadLine handleLineImpl( String[] pLine, int pNumFields, long pLineNumber, String pOriginalLine ) throws Exception {
      log.append( pLineNumber+":"+pNumFields+":"+pLine.length+":"+pOriginalLine+"~" );
      return null;
    }
  }
}





Syntax Highlighting created using the com.Ostermiller.Syntax package.
Wednesday, June 20 2007 at 22:16