//------------------------------------------------------------------------------
// Lamp : Open source game middleware
// Copyright (C) 2004  Junpei Ohtani ( Email : junpee@users.sourceforge.jp )
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//------------------------------------------------------------------------------

/** @file
 * 文字列テスト実装
 * @author Junpee
 */

#include "Test/stdafx.h"
#include "Core/Primitive/StringTest.h"
#include "Core/Primitive/String.h"

//------------------------------------------------------------------------------
// コンストラクタ
StringTest::StringTest(String name) : TestCase(name), aiu_("aiuあいうaiu\n"){
}
//------------------------------------------------------------------------------
// テストスィートの取得
Test* StringTest::suite(){
	TestSuite* suite = new TestSuite("StringTest");
	suite->addTest(new TestCaller(StringTest, testConstructor));
	suite->addTest(new TestCaller(StringTest, testParse));
	suite->addTest(new TestCaller(StringTest, testAppend));
	suite->addTest(new TestCaller(StringTest, testFormat));
	suite->addTest(new TestCaller(StringTest, testSubstring));
	suite->addTest(new TestCaller(StringTest, testUpperLower));
	suite->addTest(new TestCaller(StringTest, testCompare));
	suite->addTest(new TestCaller(StringTest, testCompareIgnoreCase));
	suite->addTest(new TestCaller(StringTest, testStartsWithEndsWith));
	suite->addTest(new TestCaller(StringTest, testIndex));
	return suite;
}
//------------------------------------------------------------------------------
// コンストラクタテスト
void StringTest::testConstructor(){
	// NULL
	TestEquals(0, null_.getSize());
	TestEquals("", null_);
	TestAssert(null_.isEmpty());
	String constructorNull(null_);
	TestEquals(0, constructorNull.getSize());
	TestEquals(0, constructorNull.getCharacterCount());
	TestEquals("", constructorNull);
	String copyNull;
	copyNull = null_;
	TestEquals(0, copyNull.getSize());
	TestEquals(0, copyNull.getCharacterCount());
	TestEquals("", copyNull);
	String equalNull;
	equalNull = "";
	TestEquals(0, equalNull.getSize());
	TestEquals(0, equalNull.getCharacterCount());
	TestEquals("", equalNull);
	// あいう
	TestAssert(!aiu_.isEmpty());
	TestEquals(13, aiu_.getSize());
	TestEquals(10, aiu_.getCharacterCount());
	TestEquals("aiuあいうaiu\n", aiu_);
	TestEquals('a', aiu_.charAt(0));
	TestEquals('u', aiu_.charAt(11));
	String constructorAiu(aiu_);
	TestEquals(13, constructorAiu.getSize());
	TestEquals(10, constructorAiu.getCharacterCount());
	TestEquals("aiuあいうaiu\n", constructorAiu);
	String copyAiu;
	copyAiu = aiu_;
	TestEquals(13, copyAiu.getSize());
	TestEquals(10, copyAiu.getCharacterCount());
	TestEquals("aiuあいうaiu\n", copyAiu);
	String equalAiu;
	equalAiu = "aiuあいうaiu\n";
	TestEquals(13, equalAiu.getSize());
	TestEquals(10, equalAiu.getCharacterCount());
	TestEquals("aiuあいうaiu\n", equalAiu);
}
//------------------------------------------------------------------------------
// パーステスト
void StringTest::testParse(){
	String target;
	// charテスト
	char charVal;
	target = "あいう";
	TestAssert(!target.parseChar(&charVal));
	target = "127";
	TestAssert(target.parseChar(&charVal));
	TestEquals(127, charVal);
	target = "-128";
	TestAssert(target.parseChar(&charVal));
	TestEquals(-128, charVal);
	target = "128";
	TestAssert(!target.parseChar(&charVal));
	target = "-129";
	TestAssert(!target.parseChar(&charVal));
	// u_charテスト
	u_char uCharVal;
	target = "あいう";
	TestAssert(!target.parseUChar(&uCharVal));
	target = "255";
	TestAssert(target.parseUChar(&uCharVal));
	TestEquals(255, uCharVal);
	target = "0";
	TestAssert(target.parseUChar(&uCharVal));
	TestEquals(0, uCharVal);
	target = "256";
	TestAssert(!target.parseUChar(&uCharVal));
	target = "-1";
	TestAssert(!target.parseUChar(&uCharVal));
	// shortテスト
	short shortVal;
	target = "あいう";
	TestAssert(!target.parseShort(&shortVal));
	target = "32767";
	TestAssert(target.parseShort(&shortVal));
	TestEquals(32767, shortVal);
	target = "-32768";
	TestAssert(target.parseShort(&shortVal));
	TestEquals(-32768, shortVal);
	target = "32768";
	TestAssert(!target.parseShort(&shortVal));
	target = "-32769";
	TestAssert(!target.parseShort(&shortVal));
	// u_shortテスト
	u_short uShortVal;
	target = "あいう";
	TestAssert(!target.parseUShort(&uShortVal));
	target = "65535";
	TestAssert(target.parseUShort(&uShortVal));
	TestEquals(65535, uShortVal);
	target = "0";
	TestAssert(target.parseUShort(&uShortVal));
	TestEquals(0, uShortVal);
	target = "65536";
	TestAssert(!target.parseUShort(&uShortVal));
	target = "-1";
	TestAssert(!target.parseUShort(&uShortVal));
	// intテスト
	int intVal;
	target = "あいう";
	TestAssert(!target.parseInt(&intVal));
	target = "-2147483648";
	TestAssert(target.parseInt(&intVal));
	TestEquals(-2147483647 - 1, intVal);
	target = "2147483647";
	TestAssert(target.parseInt(&intVal));
	TestEquals(2147483647, intVal);
	target = "4294967296";
	TestAssert(target.parseInt(&intVal));
	TestEquals(0, intVal);
	// u_intテスト
	u_int uIntVal;
	target = "あいう";
	TestAssert(!target.parseUInt(&uIntVal));
	target = "0";
	TestAssert(target.parseUInt(&uIntVal));
	TestEquals(0u, uIntVal);
	target = "4294967295";
	TestAssert(target.parseUInt(&uIntVal));
	TestEquals(4294967295, uIntVal);
	target = "-1";
	TestAssert(target.parseUInt(&uIntVal));
	TestEquals(4294967295, uIntVal);
	target = "-2147483648";
	TestAssert(target.parseUInt(&uIntVal));
	TestEquals(2147483648, uIntVal);
	// floatテスト
	float floatVal;
	target = "あいう";
	TestAssert(!target.parseFloat(&floatVal));
	target = "0";
	TestAssert(target.parseFloat(&floatVal));
	TestEquals(0.f, floatVal);
	target = "-1e-5";
	TestAssert(target.parseFloat(&floatVal));
	TestEquals(-0.00001f, floatVal);
	target = "100000.f";
	TestAssert(target.parseFloat(&floatVal));
	TestEquals(100000.f, floatVal);
	// doubleテスト
	double doubleVal;
	target = "あいう";
	TestAssert(!target.parseDouble(&doubleVal));
	target = "0";
	TestAssert(target.parseDouble(&doubleVal));
	TestEquals(0., doubleVal);
	target = "-1e-15";
	TestAssert(target.parseDouble(&doubleVal));
	TestEquals(-0.000000000000001, doubleVal);
	target = "1000000000000000.";
	TestAssert(target.parseDouble(&doubleVal));
	TestEquals(1000000000000000., doubleVal);
}
//------------------------------------------------------------------------------
// 連結テスト
void StringTest::testAppend(){
	String pre, post;
	// 両方空文字列
	pre = post = "";
	pre.append(post);
	TestEquals(0, pre.getSize());
	TestEquals("", pre);
	// pre空文字列
	post = "aあ\n";
	pre.append(post);
	TestEquals(4, pre.getSize());
	TestEquals("aあ\n", pre);
	// 両方通常文字列
	pre.append(post);
	TestEquals(8, pre.getSize());
	TestEquals("aあ\naあ\n", pre);
	// post空文字列
	post = "";
	pre.append(post);
	TestEquals(8, pre.getSize());
	TestEquals("aあ\naあ\n", pre);

	// 空文字列への空文字列足しこみ
	String addString;
	addString.append("");
	TestEquals(0, addString.getSize());
	TestEquals("", addString);
	// 空文字列への足しこみ
	addString.append("aあ\n");
	TestEquals(4, addString.getSize());
	TestEquals("aあ\n", addString);
	// 通常の足しこみ
	addString.append("aあ\n");
	TestEquals(8, addString.getSize());
	TestEquals(6, addString.getCharacterCount());
	TestEquals("aあ\naあ\n", addString);

	// 追加演算子
	String opeString;
	opeString += "a";
	opeString += "\t";
	opeString += String("c");
	opeString += "あ";
	opeString += String("い");
	TestEquals(7, opeString.getSize());
	TestEquals("a\tcあい", opeString);
	opeString = "b" + String("a") + "あ" + "\t";
	TestEquals("baあ\t", opeString);
	opeString = opeString + "";
	TestEquals("baあ\t", opeString);
	opeString = "" + opeString;
	TestEquals("baあ\t", opeString);

}
//------------------------------------------------------------------------------
// フォーマットテスト
void StringTest::testFormat(){
	String format;
	TestEquals(0, format.getSize());
	TestEquals("", format);
	// 空文字列
	format.format("");
	TestEquals("", format);
	// 通常文字列
	format.format("12345678");
	TestEquals("12345678", format);
	// フォーマット文字列
	format.format("%d %.2f %s",
		5, 1.f / 3.f , aiu_.getBytes());
	TestEquals(17, format.getCharacterCount());
	TestEquals("5 0.33 aiuあいうaiu\n", format);
	format.format("%s", "01234567890123456789");
	TestEquals("01234567890123456789", format);
	format.format("%s", "");
	TestEquals("", format);
}
//------------------------------------------------------------------------------
// 部分文字列テスト
void StringTest::testSubstring(){
	// 開始インデックス
	String source("0123456789");
	source = source.getSubstring(0);
	TestEquals(10, source.getSize());
	TestEquals("0123456789", source);
	source = source.getSubstring(5);
	TestEquals(5, source.getSize());
	TestEquals("56789", source);
	source = source.getSubstring(5);
	TestEquals(0, source.getSize());
	TestEquals("", source);
	source = source.getSubstring(0);
	TestEquals(0, source.getSize());
	TestEquals("", source);
	// 開始、終了インデックス
	source = "0123456789";
	source = source.getSubstring(0, 10);
	TestEquals(10, source.getSize());
	TestEquals("0123456789", source);
	source = source.getSubstring(0, 9);
	TestEquals(9, source.getSize());
	TestEquals("012345678", source);
	source = source.getSubstring(0, 1);
	TestEquals(1, source.getSize());
	TestEquals("0", source);
	source = source.getSubstring(1, 1);
	TestEquals(0, source.getSize());
	TestEquals("", source);
	source = "0123456789";
	source = source.getSubstring(9, 10);
	TestEquals(1, source.getSize());
	TestEquals("9", source);
}
//------------------------------------------------------------------------------
// 大文字小文字テスト
void StringTest::testUpperLower(){
	String source(""), destination;
	source = source.getUpperCase();
	TestEquals(0, source.getSize());
	TestEquals("", source);
	source = source.getLowerCase();
	TestEquals(0, source.getSize());
	TestEquals("", source);
	source = "0";
	source = source.getUpperCase();
	TestEquals(1, source.getSize());
	TestEquals("0", source);
	source = source.getLowerCase();
	TestEquals(1, source.getSize());
	TestEquals("0", source);
	source = "aBcDe";
	source = source.getUpperCase();
	TestEquals(5, source.getSize());
	TestEquals("ABCDE", source);
	source = "aBcDe";
	source = source.getLowerCase();
	TestEquals(5, source.getSize());
	TestEquals("abcde", source);
}
//------------------------------------------------------------------------------
// 比較テスト
void StringTest::testCompare(){
	// 辞書式比較テスト
	String a("あ\ta"), b("あ\tb");
	int comp;
	comp = a.compareTo(b);
	TestEquals(-1, comp);
	comp = a.compareTo("あ\tb");
	TestEquals(-1, comp);
	comp = b.compareTo(a);
	TestEquals(1, comp);
	comp = b.compareTo("あ\ta");
	TestEquals(1, comp);
	comp = a.compareTo(a);
	TestEquals(0, comp);
	comp = a.compareTo("あ\ta");
	TestEquals(0, comp);
	// 比較テスト
	TestAssert(!a.equals(b));
	TestAssert(!a.equals("あ\tb"));
	b = "あ\ta";
	TestAssert(a.equals(b));
	TestAssert(a.equals("あ\ta"));
}
//------------------------------------------------------------------------------
// 大文字小文字を無視する比較テスト
void StringTest::testCompareIgnoreCase(){
	// 辞書式比較テスト
	String source("aBcDe0(\tあ"), target("AbCdE0(\tい");
	TestEquals(-1, source.compareToIgnoreCase(target));
	TestEquals(-1, source.compareToIgnoreCase("AbCdE0(\tい"));
	TestEquals(1, target.compareToIgnoreCase(source));
	TestEquals(1, target.compareToIgnoreCase("aBcDe0(\tあ"));
	target = "AbCdE0(\tあ";
	TestEquals(0, target.compareToIgnoreCase(source));
	TestEquals(0, target.compareToIgnoreCase("aBcDe0(\tあ"));
	// 比較テスト
	TestAssert(source.equalsIsIgnoreCase(target));
	TestAssert(source.equalsIsIgnoreCase("aBcDe0(\tあ"));
	target = "AbCdE0(\tい";
	TestAssert(!source.equalsIsIgnoreCase(target));
	TestAssert(!source.equalsIsIgnoreCase("AbCdE0(\tい"));
}
//------------------------------------------------------------------------------
// 開始一致、終了一致テスト
void StringTest::testStartsWithEndsWith(){
	// 開始文字列テスト
	String target("ab"), compare("abc");
	TestAssert(!target.startsWith(compare));
	TestAssert(!target.startsWith("abc"));
	target = "abcd";
	TestAssert(target.startsWith(compare));
	TestAssert(target.startsWith("abc"));
	target = "acbd";
	TestAssert(!target.startsWith(compare));
	TestAssert(!target.startsWith("abc"));
	target = "";
	TestAssert(!target.startsWith(compare));
	TestAssert(!target.startsWith("abc"));
	compare = "";
	TestAssert(target.startsWith(compare));
	TestAssert(target.startsWith(""));
	// 終了文字列テスト
	compare = "abc";
	target = "bc";
	TestAssert(!target.endsWith(compare));
	TestAssert(!target.endsWith("abc"));
	target = "dabc";
	TestAssert(target.endsWith(compare));
	TestAssert(target.endsWith("abc"));
	target = "abcd";
	TestAssert(!target.endsWith(compare));
	TestAssert(!target.endsWith("abc"));
	target = "";
	TestAssert(!target.endsWith(compare));
	TestAssert(!target.endsWith("abc"));
	compare = "";
	TestAssert(target.endsWith(compare));
	TestAssert(target.endsWith(""));
}
//------------------------------------------------------------------------------
// インデックステスト
void StringTest::testIndex(){
	String source("01234567890123456789"),
		target012("012"), target789("789"), targetAiu("あいう"), targetNull("");
	// 最初
	TestEquals(0, source.getIndexOf('0'));
	TestEquals(9, source.getIndexOf('9'));
	TestEquals(-1, source.getIndexOf('a'));
	TestEquals(0, source.getIndexOf("012"));
	TestEquals(7, source.getIndexOf("789"));
	TestEquals(-1, source.getIndexOf("あいう"));
	TestEquals(0, source.getIndexOf(""));
	TestEquals(0, source.getIndexOf(target012));
	TestEquals(7, source.getIndexOf(target789));
	TestEquals(-1, source.getIndexOf(targetAiu));
	TestEquals(0, source.getIndexOf(targetNull));
	// 最後
	TestEquals(10, source.getLastIndexOf('0'));
	TestEquals(19, source.getLastIndexOf('9'));
	TestEquals(-1, source.getLastIndexOf('a'));
	TestEquals(10, source.getLastIndexOf("012"));
	TestEquals(17, source.getLastIndexOf("789"));
	TestEquals(-1, source.getLastIndexOf("あいう"));
	TestEquals(20, source.getLastIndexOf(""));
	TestEquals(10, source.getLastIndexOf(target012));
	TestEquals(17, source.getLastIndexOf(target789));
	TestEquals(-1, source.getLastIndexOf(targetAiu));
	TestEquals(20, source.getLastIndexOf(targetNull));
}
//------------------------------------------------------------------------------
