TEST(Utf8Normalize, InvalidData)
{
	char o[256] = { 0 };
	size_t os = 255;
	int32_t errors = UTF8_ERR_NONE;

	EXPECT_EQ(0, utf8normalize(nullptr, 7, o, os, UTF8_NORMALIZE_COMPOSE, &errors));
	EXPECT_UTF8EQ("", o);
	EXPECT_ERROREQ(UTF8_ERR_INVALID_DATA, errors);
}
TEST(Utf8Normalize, InvalidFlagAndInvalidData)
{
	char o[256] = { 0 };
	size_t os = 255;
	int32_t errors = UTF8_ERR_NONE;

	EXPECT_EQ(0, utf8normalize(nullptr, 166, o, os, 0x00001B28, &errors));
	EXPECT_UTF8EQ("", o);
	EXPECT_ERROREQ(UTF8_ERR_INVALID_FLAG, errors);
}
TEST_F(Utf8ToLowerTurkish, SingleCapitalLetterINotEnoughSpace)
{
	const char* c = "I";
	const size_t s = 1;
	char b[256] = { 0 };
	int32_t errors = UTF8_ERR_NONE;

	EXPECT_EQ(0, utf8tolower(c, strlen(c), b, s, &errors));
	EXPECT_UTF8EQ("", b);
	EXPECT_ERROREQ(UTF8_ERR_NOT_ENOUGH_SPACE, errors);
}
TEST_F(Utf8ToLowerGreek, SentenceCapitalLetterSigmaNotEnoughSpace)
{
	const char* c = "\xCE\xA3\xCE\x97\xCE\xA3 \xCE\x98\xCE\x9F\xCE\xA4\xCE\xA3";
	const size_t s = 6;
	char b[256] = { 0 };
	int32_t errors = UTF8_ERR_NONE;

	EXPECT_EQ(6, utf8tolower(c, strlen(c), b, s, &errors));
	EXPECT_UTF8EQ("\xCF\x83\xCE\xB7\xCF\x82", b);
	EXPECT_ERROREQ(UTF8_ERR_NOT_ENOUGH_SPACE, errors);
}
TEST_F(Utf8ToLowerGreek, SentenceSmallLetterSigmaNotEnoughSpace)
{
	const char* c = "\xCE\xB5\xCE\xBD\xCE\xB8\xCF\x83 \xCF\x85\xCF\x84";
	const size_t s = 7;
	char b[256] = { 0 };
	int32_t errors = UTF8_ERR_NONE;

	EXPECT_EQ(6, utf8tolower(c, strlen(c), b, s, &errors));
	EXPECT_UTF8EQ("\xCE\xB5\xCE\xBD\xCE\xB8", b);
	EXPECT_ERROREQ(UTF8_ERR_NOT_ENOUGH_SPACE, errors);
}
TEST_F(Utf8ToLowerGreek, WordSmallLetterFinalSigmaNotEnoughSpace)
{
	const char* c = "\xCE\xBF\xCF\x80\xCF\x82";
	const size_t s = 3;
	char b[256] = { 0 };
	int32_t errors = UTF8_ERR_NONE;

	EXPECT_EQ(2, utf8tolower(c, strlen(c), b, s, &errors));
	EXPECT_UTF8EQ("\xCE\xBF", b);
	EXPECT_ERROREQ(UTF8_ERR_NOT_ENOUGH_SPACE, errors);
}
TEST_F(Utf8ToLowerTurkish, SingleSmallLetterDotlessIWithDotAboveNotEnoughSpace)
{
	const char* c = "\xC4\xB1\xCC\x87";
	const size_t s = 1;
	char b[256] = { 0 };
	int32_t errors = UTF8_ERR_NONE;

	EXPECT_EQ(0, utf8tolower(c, strlen(c), b, s, &errors));
	EXPECT_UTF8EQ("", b);
	EXPECT_ERROREQ(UTF8_ERR_NOT_ENOUGH_SPACE, errors);
}
TEST_F(Utf8ToLowerGreek, SentenceSmallLetterFinalSigmaNotEnoughSpace)
{
	const char* c = "\xCE\xB5\xCE\xB6\xCF\x82 \xCE\xBE\xCE\xBE\xCE\xAB\xCE\xAD";
	const size_t s = 5;
	char b[256] = { 0 };
	int32_t errors = UTF8_ERR_NONE;

	EXPECT_EQ(4, utf8tolower(c, strlen(c), b, s, &errors));
	EXPECT_UTF8EQ("\xCE\xB5\xCE\xB6", b);
	EXPECT_ERROREQ(UTF8_ERR_NOT_ENOUGH_SPACE, errors);
}
TEST_F(Utf8ToLowerGreek, SingleSmallLetterSigmaNotEnoughSpace)
{
	const char* c = "\xCF\x83";
	const size_t s = 1;
	char b[256] = { 0 };
	int32_t errors = UTF8_ERR_NONE;

	EXPECT_EQ(0, utf8tolower(c, strlen(c), b, s, &errors));
	EXPECT_UTF8EQ("", b);
	EXPECT_ERROREQ(UTF8_ERR_NOT_ENOUGH_SPACE, errors);
}
TEST_F(Utf8ToLowerGreek, WordCapitalLetterSigmaAtEndNotEnoughSpace)
{
	const char* c = "\xCE\x88\xCE\x93\xCE\xA3";
	const size_t s = 2;
	char b[256] = { 0 };
	int32_t errors = UTF8_ERR_NONE;

	EXPECT_EQ(2, utf8tolower(c, strlen(c), b, s, &errors));
	EXPECT_UTF8EQ("\xCE\xAD", b);
	EXPECT_ERROREQ(UTF8_ERR_NOT_ENOUGH_SPACE, errors);
}
TEST_F(Utf8ToTitleTurkish, SingleSmallLetterDotlessINotEnoughSpace)
{
	const char* c = "\xC4\xB1";
	const size_t s = 0;
	char b[256] = { 0 };
	int32_t errors = UTF8_ERR_NONE;

	EXPECT_EQ(0, utf8totitle(c, strlen(c), b, s, &errors));
	EXPECT_UTF8EQ("", b);
	EXPECT_ERROREQ(UTF8_ERR_NOT_ENOUGH_SPACE, errors);
}
TEST_F(Utf8ToTitleTurkish, SingleCapitalLetterIAndDotAboveNotEnoughSpace)
{
	const char* c = "I\xCC\x87";
	const size_t s = 2;
	char b[256] = { 0 };
	int32_t errors = UTF8_ERR_NONE;

	EXPECT_EQ(1, utf8totitle(c, strlen(c), b, s, &errors));
	EXPECT_UTF8EQ("I", b);
	EXPECT_ERROREQ(UTF8_ERR_NOT_ENOUGH_SPACE, errors);
}
TEST(WideToUtf8, BasicLatin)
{
	wchar_t i[] = { 'c', 'o', 'n', 'n', 'e', 'c', 't' };
	size_t is = sizeof(i);
	char o[256] = { 0 };
	size_t os = 255;
	int32_t errors = UTF8_ERR_NONE;

	EXPECT_EQ(7, widetoutf8(i, is, o, os, &errors));
	EXPECT_UTF8EQ("connect", o);
	EXPECT_ERROREQ(UTF8_ERR_NONE, errors);
}
TEST(WideToUtf8, BasicLatinNotEnoughSpace)
{
	wchar_t i[] = { 'r', 'o', 'c', 'k', 'e', 't' };
	size_t is = sizeof(i);
	char o[256] = { 0 };
	size_t os = 4;
	int32_t errors = UTF8_ERR_NONE;

	EXPECT_EQ(4, widetoutf8(i, is, o, os, &errors));
	EXPECT_UTF8EQ("rock", o);
	EXPECT_ERROREQ(UTF8_ERR_NOT_ENOUGH_SPACE, errors);
}
TEST(WideToUtf8, SurrogatePairNotEnoughSpace)
{
	const wchar_t i[] = { 0xDBFE, 0xDFFE, 0xD818, 0xDCDE };
	size_t is = sizeof(i);
	char o[256] = { 0 };
	size_t os = 3;
	int32_t errors = UTF8_ERR_NONE;

	EXPECT_EQ(0, widetoutf8(i, is, o, os, &errors));
	EXPECT_UTF8EQ("", o);
	EXPECT_ERROREQ(UTF8_ERR_NOT_ENOUGH_SPACE, errors);
}
TEST(WideToUtf8, ErrorsIsReset)
{
	const wchar_t i[] = { 0x0A9A };
	size_t is = sizeof(i);
	char o[256] = { 0 };
	size_t os = 255;
	int32_t errors = 776;

	EXPECT_EQ(3, widetoutf8(i, is, o, os, &errors));
	EXPECT_UTF8EQ("\xE0\xAA\x9A", o);
	EXPECT_ERROREQ(UTF8_ERR_NONE, errors);
}
TEST(WideToUtf8, SurrogatePair)
{
	const wchar_t i[] = { 0xD834, 0xDD1E, 0xDA88, 0xDC10 };
	size_t is = sizeof(i);
	char o[256] = { 0 };
	size_t os = 255;
	int32_t errors = UTF8_ERR_NONE;

	EXPECT_EQ(8, widetoutf8(i, is, o, os, &errors));
	EXPECT_UTF8EQ("\xF0\x9D\x84\x9E\xF2\xB2\x80\x90", o);
	EXPECT_ERROREQ(UTF8_ERR_NONE, errors);
}
TEST_F(Utf8ToLowerGreek, WordCapitalLetterSigma)
{
	// 03BC 03BE 03A3 039F
	// 03BC 03BE 03C3 03BF

	const char* c = "\xCE\xBC\xCE\xBE\xCE\xA3\xCE\x9F";
	const size_t s = 255;
	char b[256] = { 0 };
	int32_t errors = UTF8_ERR_NONE;

	EXPECT_EQ(8, utf8tolower(c, strlen(c), b, s, &errors));
	EXPECT_UTF8EQ("\xCE\xBC\xCE\xBE\xCF\x83\xCE\xBF", b);
	EXPECT_ERROREQ(UTF8_ERR_NONE, errors);
}
TEST_F(Utf8ToLowerGreek, SingleSmallLetterFinalSigma)
{
	// 03C2
	// 03C2

	const char* c = "\xCF\x82";
	const size_t s = 255;
	char b[256] = { 0 };
	int32_t errors = UTF8_ERR_NONE;

	EXPECT_EQ(2, utf8tolower(c, strlen(c), b, s, &errors));
	EXPECT_UTF8EQ("\xCF\x82", b);
	EXPECT_ERROREQ(UTF8_ERR_NONE, errors);
}
TEST_F(Utf8ToLowerGreek, WordSmallLetterSigma)
{
	// 03BB 03BD 03C3 03CD
	// 03BB 03BD 03C3 03CD

	const char* c = "\xCE\xBB\xCE\xBD\xCF\x83\xCF\x8D";
	const size_t s = 255;
	char b[256] = { 0 };
	int32_t errors = UTF8_ERR_NONE;

	EXPECT_EQ(8, utf8tolower(c, strlen(c), b, s, &errors));
	EXPECT_UTF8EQ("\xCE\xBB\xCE\xBD\xCF\x83\xCF\x8D", b);
	EXPECT_ERROREQ(UTF8_ERR_NONE, errors);
}
TEST_F(Utf8ToLowerGreek, SingleCapitalLetterSigma)
{
	// 03A3
	// 03C3

	const char* c = "\xCE\xA3";
	const size_t s = 255;
	char b[256] = { 0 };
	int32_t errors = UTF8_ERR_NONE;

	EXPECT_EQ(2, utf8tolower(c, strlen(c), b, s, &errors));
	EXPECT_UTF8EQ("\xCF\x83", b);
	EXPECT_ERROREQ(UTF8_ERR_NONE, errors);
}
TEST_F(Utf8ToLowerGreek, SentenceCapitalLetterSigma)
{
	// 03A3 0397 03A3 0020 0398 039F 03A4 03A3
	// 03C3 03B7 03C2 0020 03B8 03BF 03C4 03C2

	const char* c = "\xCE\xA3\xCE\x97\xCE\xA3 \xCE\x98\xCE\x9F\xCE\xA4\xCE\xA3";
	const size_t s = 255;
	char b[256] = { 0 };
	int32_t errors = UTF8_ERR_NONE;

	EXPECT_EQ(15, utf8tolower(c, strlen(c), b, s, &errors));
	EXPECT_UTF8EQ("\xCF\x83\xCE\xB7\xCF\x82 \xCE\xB8\xCE\xBF\xCF\x84\xCF\x82", b);
	EXPECT_ERROREQ(UTF8_ERR_NONE, errors);
}
TEST_F(Utf8ToLowerGreek, WordCapitalLetterSigmaAtEnd)
{
	// 0388 0393 03A3
	// 03AD 03B3 03C2

	const char* c = "\xCE\x88\xCE\x93\xCE\xA3";
	const size_t s = 255;
	char b[256] = { 0 };
	int32_t errors = UTF8_ERR_NONE;

	EXPECT_EQ(6, utf8tolower(c, strlen(c), b, s, &errors));
	EXPECT_UTF8EQ("\xCE\xAD\xCE\xB3\xCF\x82", b);
	EXPECT_ERROREQ(UTF8_ERR_NONE, errors);
}
TEST_F(Utf8ToTitleTurkish, SingleSmallLetterIWithDotAbove)
{
	// 0069 0307
	// 0130 0307

	const char* c = "i\xCC\x87";
	const size_t s = 255;
	char b[256] = { 0 };
	int32_t errors = UTF8_ERR_NONE;

	EXPECT_EQ(4, utf8totitle(c, strlen(c), b, s, &errors));
	EXPECT_UTF8EQ("\xC4\xB0\xCC\x87", b);
	EXPECT_ERROREQ(UTF8_ERR_NONE, errors);
}
TEST_F(Utf8ToTitleTurkish, SingleSmallLetterDotlessI)
{
	// 0131
	// 0049

	const char* c = "\xC4\xB1";
	const size_t s = 255;
	char b[256] = { 0 };
	int32_t errors = UTF8_ERR_NONE;

	EXPECT_EQ(1, utf8totitle(c, strlen(c), b, s, &errors));
	EXPECT_UTF8EQ("I", b);
	EXPECT_ERROREQ(UTF8_ERR_NONE, errors);
}
TEST_F(Utf8ToLowerGreek, SentenceSmallLetterSigma)
{
	// 03B5 03BD 03B8 03C3 0020 03C5 03C4
	// 03B5 03BD 03B8 03C3 0020 03C5 03C4

	const char* c = "\xCE\xB5\xCE\xBD\xCE\xB8\xCF\x83 \xCF\x85\xCF\x84";
	const size_t s = 255;
	char b[256] = { 0 };
	int32_t errors = UTF8_ERR_NONE;

	EXPECT_EQ(13, utf8tolower(c, strlen(c), b, s, &errors));
	EXPECT_UTF8EQ("\xCE\xB5\xCE\xBD\xCE\xB8\xCF\x83 \xCF\x85\xCF\x84", b);
	EXPECT_ERROREQ(UTF8_ERR_NONE, errors);
}
TEST_F(Utf8ToTitleTurkish, SingleCapitalLetterIAndDotAbove)
{
	// 0049 0307
	// 0049 0307

	const char* c = "I\xCC\x87";
	const size_t s = 255;
	char b[256] = { 0 };
	int32_t errors = UTF8_ERR_NONE;

	EXPECT_EQ(3, utf8totitle(c, strlen(c), b, s, &errors));
	EXPECT_UTF8EQ("I\xCC\x87", b);
	EXPECT_ERROREQ(UTF8_ERR_NONE, errors);
}
TEST_F(Utf8ToLowerGreek, SentenceSmallLetterFinalSigma)
{
	// 03B5 03B6 03C2 0020 03BE 03BE 03AB 03AD
	// 03B5 03B6 03C2 0020 03BE 03BE 03CB 03AD

	const char* c = "\xCE\xB5\xCE\xB6\xCF\x82 \xCE\xBE\xCE\xBE\xCE\xAB\xCE\xAD";
	const size_t s = 255;
	char b[256] = { 0 };
	int32_t errors = UTF8_ERR_NONE;

	EXPECT_EQ(15, utf8tolower(c, strlen(c), b, s, &errors));
	EXPECT_UTF8EQ("\xCE\xB5\xCE\xB6\xCF\x82 \xCE\xBE\xCE\xBE\xCF\x8B\xCE\xAD", b);
	EXPECT_ERROREQ(UTF8_ERR_NONE, errors);
}
TEST_F(Utf8ToTitleTurkish, SingleCapitalLetterIWithDotAbove)
{
	// 0130
	// 0130

	const char* c = "\xC4\xB0";
	const size_t s = 255;
	char b[256] = { 0 };
	int32_t errors = UTF8_ERR_NONE;

	EXPECT_EQ(2, utf8totitle(c, strlen(c), b, s, &errors));
	EXPECT_UTF8EQ("\xC4\xB0", b);
	EXPECT_ERROREQ(UTF8_ERR_NONE, errors);
}
TEST_F(Utf8ToLowerTurkish, SingleSmallLetterDotlessIWithDotAbove)
{
	// 0131 0307
	// 0131 0307

	const char* c = "\xC4\xB1\xCC\x87";
	const size_t s = 255;
	char b[256] = { 0 };
	int32_t errors = UTF8_ERR_NONE;

	EXPECT_EQ(4, utf8tolower(c, strlen(c), b, s, &errors));
	EXPECT_UTF8EQ("\xC4\xB1\xCC\x87", b);
	EXPECT_ERROREQ(UTF8_ERR_NONE, errors);
}