/* ====================================================================
 * 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.
 * ====================================================================
 */

#include "TextModelTest.h"

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

// sc
#include "sublib/TextModelImpl.h"
#include "sublib/Cursor.h"
#include "sublib/Line.h"
#include "util/String.h"


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

TextModelTest::~TextModelTest()
{
}

void TextModelTest::setUp()
{
  sc::String text("test");

  _text = new TextModelImpl( text );
}

void TextModelTest::tearDown()
{
  delete _text;
}


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

  newSuite->addTest(new CppUnit::TestCaller<TextModelTest>("testSingleCharAdd",&TextModelTest::testSingleCharAdd) );
  newSuite->addTest(new CppUnit::TestCaller<TextModelTest>("testEmptyDelLeft",&TextModelTest::testEmptyDelLeft) );
  newSuite->addTest(new CppUnit::TestCaller<TextModelTest>("testEmptyDelRight",&TextModelTest::testEmptyDelRight) );
  newSuite->addTest(new CppUnit::TestCaller<TextModelTest>("testAddReturn",&TextModelTest::testAddReturn) );
  newSuite->addTest(new CppUnit::TestCaller<TextModelTest>("testAddMultiLineLE",&TextModelTest::testAddMultiLineLE) );
  newSuite->addTest(new CppUnit::TestCaller<TextModelTest>("testAddMultiLine",&TextModelTest::testAddMultiLine) );
  newSuite->addTest(new CppUnit::TestCaller<TextModelTest>("testCalcNearestCursorPos",&TextModelTest::testCalcNearestCursorPos) );

  return newSuite;
}

void TextModelTest::testSingleCharAdd()
{
  Cursor null(0,0);

  Cursor c1 = _text->getCursor();
  Cursor c2 = _text->getCursor2();
  CPPUNIT_ASSERT( c1.equalPos(null) );
  CPPUNIT_ASSERT( c2.equalPos(null) );

  _text->addText( sc::String("1") );

  Cursor pos(0,1);

  c1 = _text->getCursor();
  c2 = _text->getCursor2();
  CPPUNIT_ASSERT( c1.equalPos(pos) );
  CPPUNIT_ASSERT( c2.equalPos(pos) );
}

void TextModelTest::testEmptyDelLeft()
{
  Cursor null(0,0);

  _text->removeTextLeft();
  _text->undo();

  Cursor c1 = _text->getCursor();
  Cursor c2 = _text->getCursor2();
  CPPUNIT_ASSERT( c1.equalPos(null) );
  CPPUNIT_ASSERT( c2.equalPos(null) );
}

void TextModelTest::testEmptyDelRight()
{
  Cursor null(0,0);

  _text->removeTextRight();
  _text->undo();

  Cursor c1 = _text->getCursor();
  Cursor c2 = _text->getCursor2();
  CPPUNIT_ASSERT( c1.equalPos(null) );
  CPPUNIT_ASSERT( c2.equalPos(null) );
}

void TextModelTest::testAddReturn()
{
  _text->addText( sc::String("\n") );

  {
    CPPUNIT_ASSERT( 2 == _text->getLineCnt() );

    const Line& res = _text->getLine(0);
    CPPUNIT_ASSERT_EQUAL( sc::String("\n"), res.getLine() );

    const Line& res2 = _text->getLine(1);
    CPPUNIT_ASSERT_EQUAL( Line::getEmpty().getLine(), res2.getLine() );
  }

  _text->undo();

  {
    CPPUNIT_ASSERT( 1 == _text->getLineCnt() );

    const Line& res = _text->getLine(0);
    CPPUNIT_ASSERT_EQUAL( Line::getEmpty().getLine(), res.getLine() );
  }
}

void TextModelTest::testAddMultiLineLE()
{
  _text->addText( sc::String("line1\nline2\n") );

  CPPUNIT_ASSERT( 3 == _text->getLineCnt() );

  _text->undo();

  CPPUNIT_ASSERT( 1 == _text->getLineCnt() );
}

void TextModelTest::testAddMultiLine()
{
  _text->addText( sc::String("line1\nline2") );

  CPPUNIT_ASSERT( 2 == _text->getLineCnt() );

  _text->undo();

  CPPUNIT_ASSERT( 1 == _text->getLineCnt() );
}

void TextModelTest::testCalcNearestCursorPos()
{
  Cursor in(10,0);
  Cursor out = _text->calcNearestCursorPos(in);
  CPPUNIT_ASSERT( out.equalPos(Cursor(-1,0)) );

  _text->addText( sc::String("line1\nline2") );
  out = _text->calcNearestCursorPos(in);
  CPPUNIT_ASSERT( out.equalPos(Cursor(1,0)) );
}


syntax highlighted by Code2HTML, v. 0.9.1