/* ====================================================================
 * Copyright (c) 2003-2006, Martin Hauner
 *                          http://subcommander.tigris.org
 *
 * Subcommander is licensed as described in the file doc/COPYING, which
 * you should have received as part of this distribution.
 * ====================================================================
 */

// tr
#include "LineTokenizerTest.h"
#include "runner/testsupport.h"

#include <cppunit/TestSuite.h>
#include <cppunit/TestCaller.h>

// sc
#include "submerge/LineTokenizer.h"
#include "util/iconvstream.h"

// sys
#include <strstream>



LineTokenizerTest::LineTokenizerTest() : CppUnit::TestCase("LineTokenizerTest")
{
}

LineTokenizerTest::~LineTokenizerTest()
{
}

void LineTokenizerTest::setUp()
{
}

void LineTokenizerTest::tearDown()
{
}


CppUnit::Test *LineTokenizerTest::suite()
{
  CppUnit::TestSuite *newSuite = new CppUnit::TestSuite("LineTokenizerTest");

  newSuite->addTest( NEWTEST(LineTokenizerTest,&LineTokenizerTest::testNoLine) );
  newSuite->addTest( NEWTEST(LineTokenizerTest,&LineTokenizerTest::testEmptyLine) );
  newSuite->addTest( NEWTEST(LineTokenizerTest,&LineTokenizerTest::testEmptyLines) );
  newSuite->addTest( NEWTEST(LineTokenizerTest,&LineTokenizerTest::testSingleLine) );
  newSuite->addTest( NEWTEST(LineTokenizerTest,&LineTokenizerTest::testSingleLineNoFinalLF) );
  newSuite->addTest( NEWTEST(LineTokenizerTest,&LineTokenizerTest::testMultipleLines) );
  newSuite->addTest( NEWTEST(LineTokenizerTest,&LineTokenizerTest::testMultipleLinesNoFinalLF) );

  newSuite->addTest( NEWTEST(LineTokenizerTest,&LineTokenizerTest::testTokenStream) );
  newSuite->addTest( NEWTEST(LineTokenizerTest,&LineTokenizerTest::testTokenStreamError) );
  newSuite->addTest( NEWTEST(LineTokenizerTest,&LineTokenizerTest::testTokenStreamNoFinalLF) );

  newSuite->addTest( NEWTEST(LineTokenizerTest,&LineTokenizerTest::testWriteStream) );

  return newSuite;
}

void LineTokenizerTest::testMultipleLinesNoFinalLF()
{
  char i[] = "b\n b\n b";
  LineTokenizer t( (unsigned char*)i, strlen(i) );

  char*  c;
  size_t s;
  bool   b = t.nextToken( &c, &s );

  CPPUNIT_ASSERT( b );
  CPPUNIT_ASSERT( c == &i[0] );
  CPPUNIT_ASSERT( s == 2 );

  b = t.nextToken( &c, &s );

  CPPUNIT_ASSERT( b );
  CPPUNIT_ASSERT( c == &i[2] );
  CPPUNIT_ASSERT( s == 3 );

  b = t.nextToken( &c, &s );

  CPPUNIT_ASSERT( b );
  CPPUNIT_ASSERT( c == &i[5] );
  CPPUNIT_ASSERT( s == 2 );
}


void LineTokenizerTest::testMultipleLines()
{
  char i[] = "b\n b\n b\n";
  LineTokenizer t( (unsigned char*)i, strlen(i) );

  char*  c;
  size_t s;
  bool   b = t.nextToken( &c, &s );

  CPPUNIT_ASSERT( b );
  CPPUNIT_ASSERT( c == &i[0] );
  CPPUNIT_ASSERT( s == 2 );

  b = t.nextToken( &c, &s );

  CPPUNIT_ASSERT( b );
  CPPUNIT_ASSERT( c == &i[2] );
  CPPUNIT_ASSERT( s == 3 );

  b = t.nextToken( &c, &s );

  CPPUNIT_ASSERT( b );
  CPPUNIT_ASSERT( c == &i[5] );
  CPPUNIT_ASSERT( s == 3 );
}


void LineTokenizerTest::testSingleLineNoFinalLF()
{
  char i[] = "this test runs!";

  LineTokenizer t( (unsigned char*)i, strlen(i) );

  char*  c;
  size_t s;
  bool   b = t.nextToken( &c, &s );

  CPPUNIT_ASSERT( b );
  CPPUNIT_ASSERT( c == &i[0] );
  CPPUNIT_ASSERT( s == strlen(i) );
}


void LineTokenizerTest::testSingleLine()
{
  char i[] = "this test runs!\n";

  LineTokenizer t( (unsigned char*)i, strlen(i) );

  char*  c;
  size_t s;
  bool   b = t.nextToken( &c, &s );

  CPPUNIT_ASSERT( b );
  CPPUNIT_ASSERT( c == &i[0] );
  CPPUNIT_ASSERT( s == strlen(i) );
}


void LineTokenizerTest::testEmptyLines()
{
  char i[] = "\n\n\n";
  LineTokenizer t( (unsigned char*)i, strlen(i) );

  char*  c;
  size_t s;
  bool   b = t.nextToken( &c, &s );

  CPPUNIT_ASSERT( b );
  CPPUNIT_ASSERT( c == &i[0] );
  CPPUNIT_ASSERT( s == 1 );

  b = t.nextToken( &c, &s );

  CPPUNIT_ASSERT( b );
  CPPUNIT_ASSERT( c == &i[1] );
  CPPUNIT_ASSERT( s == 1 );

  b = t.nextToken( &c, &s );

  CPPUNIT_ASSERT( b );
  CPPUNIT_ASSERT( c == &i[2] );
  CPPUNIT_ASSERT( s == 1 );
}


void LineTokenizerTest::testEmptyLine()
{
  char i[] = "\n";

  LineTokenizer t( (unsigned char*)i, strlen(i) );

  char*  c;
  size_t s;
  bool   b = t.nextToken( &c, &s );

  CPPUNIT_ASSERT( b );
  CPPUNIT_ASSERT( c == &i[0] );
  CPPUNIT_ASSERT( s == 1 );
}


void LineTokenizerTest::testNoLine()
{
  LineTokenizer t( 0, 0 );

  char*  c;
  size_t s;
  bool   b = t.nextToken( &c, &s );

  CPPUNIT_ASSERT( !b );
  CPPUNIT_ASSERT( 0 == c );
  CPPUNIT_ASSERT( 0 == s );
}


void LineTokenizerTest::testTokenStreamNoFinalLF()
{
  char sbuf[] = "_1ä2ö3ü4Ä5Ö6Ü7ä8ö9ü0";

  std::strstream s1( sbuf, sizeof(sbuf)-1, std::ios_base::binary|std::ios_base::in );
  iconvistream   s2( s1, "latin1", "utf-8" );

  LineTokenizer2 t( s2 );

  char*  c;
  size_t s;
  bool   b;
  
  b = t.nextToken( &c, &s );
  CPPUNIT_ASSERT( b );
  CPPUNIT_ASSERT( 29 == s );

  b = t.nextToken( &c, &s );
  CPPUNIT_ASSERT( ! b );
  CPPUNIT_ASSERT( 0 == s );
}

void LineTokenizerTest::testTokenStreamError()
{
  char sbuf[] = "error";

  std::strstream s1( sbuf, sizeof(sbuf)-1, std::ios_base::binary|std::ios_base::in );
  iconvistream   s2( s1, "hamwanicht", "utf-8" );

  bool bad = s2.bad();

  CPPUNIT_ASSERT( bad == false );

  //char buf[1024];
  //apr_strerror( s2.getError(), buf, sizeof(buf)-1 );
  const sc::Error* error = s2.getError();
}

void LineTokenizerTest::testTokenStream()
{
  char sbuf[] = "_1ä2ö3ü4Ä5Ö6Ü7ä8ö9ü0\r\n1ä_2ö3ü4Ä5Ö6Ü7ä8ö9ü0\r\n1ä2ö_3ü4Ä5Ö6Ü7ä8ö9ü0";

  std::strstream s1( sbuf, sizeof(sbuf)-1, std::ios_base::binary|std::ios_base::in );
  iconvistream   s2( s1, "latin1", "utf-8" );

  LineTokenizer2 t( s2 );

  char*  c;
  size_t s;
  bool b;
  
  b = t.nextToken( &c, &s );
  CPPUNIT_ASSERT( b );
  CPPUNIT_ASSERT( 31 == s );

  b = t.nextToken( &c, &s );
  CPPUNIT_ASSERT( b );
  CPPUNIT_ASSERT( 31 == s );

  b = t.nextToken( &c, &s );
  CPPUNIT_ASSERT( b );
  CPPUNIT_ASSERT( 29 == s );

  b = t.nextToken( &c, &s );
  CPPUNIT_ASSERT( ! b );
  CPPUNIT_ASSERT( 0 == s );
}

void LineTokenizerTest::testWriteStream()
{
  std::strstream s1;
  iconvostream   s2( s1, "utf-8", "latin1" );

  s2 << "abcdefghijklmnopqrstuvwxyz\n";
  //    "// öÖüÜäÄß"
  s2 << "\x2f\x2f\x20\xc3\xb6\xc3\x96\xc3\xbc\xc3\x9c\xc3\xa4\xc3\x84\xc3\x9f";
  s2.flush();

  std::string s_new( s1.str(), s1.pcount() );
  std::string s_ref = "abcdefghijklmnopqrstuvwxyz\n// öÖüÜäÄß";

  CPPUNIT_ASSERT_EQUAL( s_ref, s_new );
}



syntax highlighted by Code2HTML, v. 0.9.1