#include "uitoolkit/UIPageMarkup.h"
#include "unittest/TestSuite.h"

static void testInit(void) {
	UIPageMarkup * markupPtr = UIPageMarkup_create(STR_NULL, NULL);
	TestCase_assertPointerNonNULL(markupPtr);
	TestCase_assertSizeEqual(markupPtr->textData.length, 0);
	TestCase_assertUIntEqual(markupPtr->stringCount, 0);
	TestCase_assertUIntEqual(markupPtr->colorCount, 0);
	UIPageMarkup_dispose(markupPtr);
	
	UIPageMarkup markup;
	UIPageMarkup_init(&markup, STR_NULL, NULL);
	TestCase_assertSizeEqual(markup.textData.length, 0);
	TestCase_assertUIntEqual(markup.stringCount, 0);
	TestCase_assertUIntEqual(markup.colorCount, 0);
	UIPageMarkup_disposeContents(&markup);
}

#define assertStringStructEqualRaw(value, expected_value) \
	if ((value).length != (expected_value).length || memcmp((value).bytes, (expected_value).bytes, (value).length)) { \
		char expectedStringEscaped[(expected_value).length * 4 + 1], actualStringEscaped[(value).length * 4 + 1]; \
		TestCase_escapeStringForTerminal(expectedStringEscaped, (const char *) (expected_value).bytes, (expected_value).length); \
		TestCase_escapeStringForTerminal(actualStringEscaped, (const char *) (value).bytes, (value).length); \
		char expectedByteString[(expected_value).length * 3], actualByteString[(value).length * 3]; \
		TestCase_formatByteString(expectedByteString, (const uint8_t *) (expected_value).bytes, (expected_value).length); \
		TestCase_formatByteString(actualByteString, (const uint8_t *) (value).bytes, (value).length); \
		(*g_unitTestFailureCallback)(__FILE__, __FUNCTION__, __LINE__, "Nonmatching strings. Expected (length " SIZE_T_FORMAT "):\n      \"%s\"\n      %s\n    Actual (length " SIZE_T_FORMAT "):\n      \"%s\"\n      %s", (expected_value).length, expectedStringEscaped, expectedByteString, (value).length, actualStringEscaped, actualByteString); \
	} else { \
		g_unitTestSuccessfulAssertCount++; \
	}

static void testParse(void) {
	UIPageMarkup markup;
	bool success = UIPageMarkup_init(&markup, STRL("Basic text"), NULL);
	TestCase_assertBoolTrue(success);
	TestCase_assertStringStructEqual(markup.textData, STRL("Basic text"));
	TestCase_assertUIntEqual(markup.stringCount, 0);
	TestCase_assertUIntEqual(markup.colorCount, 0);
	UIPageMarkup_disposeContents(&markup);
	
	success = UIPageMarkup_init(&markup, STRL("\\\\Escape\\[\\]"), NULL);
	TestCase_assertBoolTrue(success);
	TestCase_assertStringStructEqual(markup.textData, STRL("\\Escape[]"));
	TestCase_assertUIntEqual(markup.stringCount, 0);
	TestCase_assertUIntEqual(markup.colorCount, 0);
	UIPageMarkup_disposeContents(&markup);
	
	success = UIPageMarkup_init(&markup, STRL("a[i]b[/i]c"), NULL);
	TestCase_assertBoolTrue(success);
	assertStringStructEqualRaw(markup.textData, STRL("a\x1B\x00""b\x1B\x01""c"));
	TestCase_assertUIntEqual(markup.stringCount, 0);
	TestCase_assertUIntEqual(markup.colorCount, 0);
	UIPageMarkup_disposeContents(&markup);
	
	success = UIPageMarkup_init(&markup, STRL("a[b]b[/b]c"), NULL);
	TestCase_assertBoolTrue(success);
	assertStringStructEqualRaw(markup.textData, STRL("a\x1B\x11""b\x1B\x12""c"));
	TestCase_assertUIntEqual(markup.stringCount, 0);
	TestCase_assertUIntEqual(markup.colorCount, 0);
	UIPageMarkup_disposeContents(&markup);
	
	success = UIPageMarkup_init(&markup, STRL("a[u]b[/u]c"), NULL);
	TestCase_assertBoolTrue(success);
	assertStringStructEqualRaw(markup.textData, STRL("a\x1B\x13""b\x1B\x14""c"));
	TestCase_assertUIntEqual(markup.stringCount, 0);
	TestCase_assertUIntEqual(markup.colorCount, 0);
	UIPageMarkup_disposeContents(&markup);
	
	success = UIPageMarkup_init(&markup, STRL("1 [align=left] 2 [align=center] 3 [align=right]"), NULL);
	TestCase_assertBoolTrue(success);
	assertStringStructEqualRaw(markup.textData, STRL("1 \x1B\x04 2 \x1B\x05 3 \x1B\x06"));
	TestCase_assertUIntEqual(markup.stringCount, 0);
	TestCase_assertUIntEqual(markup.colorCount, 0);
	UIPageMarkup_disposeContents(&markup);
	
	success = UIPageMarkup_init(&markup, STRL("1 [valign=bottom] 2 [valign=center] 3 [valign=top]"), NULL);
	TestCase_assertBoolTrue(success);
	assertStringStructEqualRaw(markup.textData, STRL("1 \x1B\x07 2 \x1B\x08 3 \x1B\x09"));
	TestCase_assertUIntEqual(markup.stringCount, 0);
	TestCase_assertUIntEqual(markup.colorCount, 0);
	UIPageMarkup_disposeContents(&markup);
	
	success = UIPageMarkup_init(&markup, STRL("a[list][*]1[*]2[list=1]j[*]2a[/list]j[/list]b"), NULL);
	TestCase_assertBoolTrue(success);
	assertStringStructEqualRaw(markup.textData, STRL("a\x1B\x0A\x1B\x0D""1\x1B\x0D""2\x1B\x0Bj\x1B\x0D""2a\x1B\x0Cj\x1B\x0C""b"));
	TestCase_assertUIntEqual(markup.stringCount, 0);
	TestCase_assertUIntEqual(markup.colorCount, 0);
	UIPageMarkup_disposeContents(&markup);
	
	success = UIPageMarkup_init(&markup, STRL("[color=FF0000]red[/color] [color=00FFFF7F]cyan[/color]"), NULL);
	TestCase_assertBoolTrue(success);
	assertStringStructEqualRaw(markup.textData, STRL("\x1B\x60\x00\x00red\x1B\x0E \x1B\x60\x01\x00""cyan\x1B\x0E"));
	TestCase_assertUIntEqual(markup.stringCount, 0);
	TestCase_assertUIntEqual(markup.colorCount, 2);
	TestCase_assertPointerNonNULL(markup.colors);
	TestCase_assertUIntEqual(markup.colors[0].red, 0xFF);
	TestCase_assertUIntEqual(markup.colors[0].green, 0x00);
	TestCase_assertUIntEqual(markup.colors[0].blue, 0x00);
	TestCase_assertUIntEqual(markup.colors[0].alpha, 0xFF);
	TestCase_assertUIntEqual(markup.colors[1].red, 0x00);
	TestCase_assertUIntEqual(markup.colors[1].green, 0xFF);
	TestCase_assertUIntEqual(markup.colors[1].blue, 0xFF);
	TestCase_assertUIntEqual(markup.colors[1].alpha, 0x7F);
	UIPageMarkup_disposeContents(&markup);
	
	success = UIPageMarkup_init(&markup, STRL("A [font=ab]1[/font] [font=c\\[d\\]e]2[/font] B"), NULL);
	TestCase_assertBoolTrue(success);
	assertStringStructEqualRaw(markup.textData, STRL("A \x1B\x61\x00\x00""1\x1B\x0F \x1B\x61\x01\x00""2\x1B\x0F B"));
	TestCase_assertUIntEqual(markup.stringCount, 2);
	TestCase_assertUIntEqual(markup.colorCount, 0);
	TestCase_assertPointerNonNULL(markup.strings);
	TestCase_assertStringStructEqual(markup.strings[0], STRL("ab"));
	TestCase_assertStringStructEqual(markup.strings[1], STRL("c[d]e"));
	UIPageMarkup_disposeContents(&markup);
	
	success = UIPageMarkup_init(&markup, STRL("A [link=AB]1[/link] [link=C\\[D\\]E]2[/link] B"), NULL);
	TestCase_assertBoolTrue(success);
	assertStringStructEqualRaw(markup.textData, STRL("A \x1B\x62\x00\x00""1\x1B\x10 \x1B\x62\x01\x00""2\x1B\x10 B"));
	TestCase_assertUIntEqual(markup.stringCount, 2);
	TestCase_assertUIntEqual(markup.colorCount, 0);
	TestCase_assertPointerNonNULL(markup.strings);
	TestCase_assertStringStructEqual(markup.strings[0], STRL("AB"));
	TestCase_assertStringStructEqual(markup.strings[1], STRL("C[D]E"));
	UIPageMarkup_disposeContents(&markup);
	
	success = UIPageMarkup_init(&markup, STRL("A [img=12] 1 [img=3\\[4\\]5] B"), NULL);
	TestCase_assertBoolTrue(success);
	assertStringStructEqualRaw(markup.textData, STRL("A \x1B\x63\x00\x00 1 \x1B\x63\x01\x00 B"));
	TestCase_assertUIntEqual(markup.stringCount, 2);
	TestCase_assertUIntEqual(markup.colorCount, 0);
	TestCase_assertPointerNonNULL(markup.strings);
	TestCase_assertStringStructEqual(markup.strings[0], STRL("12"));
	TestCase_assertStringStructEqual(markup.strings[1], STRL("3[4]5"));
	UIPageMarkup_disposeContents(&markup);
}

static void testParseErrors(void) {
	UIPageMarkup markup;
	UIPageMarkup_error error;
	bool success = UIPageMarkup_init(&markup, STRL("[font=[i]"), &error);
	TestCase_assertBoolFalse(success);
	TestCase_assertEnumEqual(error.code, UIPageMarkup_error_openBracketInsideTag);
	TestCase_assertSizeEqual(error.charIndex, 6);
	TestCase_assertUIntEqual(error.lineIndex, 0);
	TestCase_assertUIntEqual(error.lineCharIndex, 6);
	
	success = UIPageMarkup_init(&markup, STRL("[font=\\[i]"), &error);
	TestCase_assertBoolTrue(success);
	assertStringStructEqualRaw(markup.textData, STRL("\x1B\x61\x00\x00"));
	TestCase_assertUIntEqual(markup.stringCount, 1);
	TestCase_assertUIntEqual(markup.colorCount, 0);
	TestCase_assertPointerNonNULL(markup.strings);
	TestCase_assertStringStructEqual(markup.strings[0], STRL("[i"));
	UIPageMarkup_disposeContents(&markup);
	
	success = UIPageMarkup_init(&markup, STRL("[font=i]]"), &error);
	TestCase_assertBoolFalse(success);
	TestCase_assertEnumEqual(error.code, UIPageMarkup_error_closeBracketOutsideTag);
	TestCase_assertSizeEqual(error.charIndex, 8);
	TestCase_assertUIntEqual(error.lineIndex, 0);
	TestCase_assertUIntEqual(error.lineCharIndex, 8);
	
	success = UIPageMarkup_init(&markup, STRL("[font=i\\]]"), &error);
	TestCase_assertBoolTrue(success);
	assertStringStructEqualRaw(markup.textData, STRL("\x1B\x61\x00\x00"));
	TestCase_assertUIntEqual(markup.stringCount, 1);
	TestCase_assertUIntEqual(markup.colorCount, 0);
	TestCase_assertPointerNonNULL(markup.strings);
	TestCase_assertStringStructEqual(markup.strings[0], STRL("i]"));
	UIPageMarkup_disposeContents(&markup);
	
	success = UIPageMarkup_init(&markup, STRL("aa\nb\\"), &error);
	TestCase_assertBoolFalse(success);
	TestCase_assertEnumEqual(error.code, UIPageMarkup_error_trailingBackslash);
	TestCase_assertSizeEqual(error.charIndex, 4);
	TestCase_assertUIntEqual(error.lineIndex, 1);
	TestCase_assertUIntEqual(error.lineCharIndex, 2);
	
	success = UIPageMarkup_init(&markup, STRL("[invalid]tag"), &error);
	TestCase_assertBoolFalse(success);
	TestCase_assertEnumEqual(error.code, UIPageMarkup_error_unrecognizedTag);
	TestCase_assertSizeEqual(error.charIndex, 8);
	TestCase_assertUIntEqual(error.lineIndex, 0);
	TestCase_assertUIntEqual(error.lineCharIndex, 8);
	
	success = UIPageMarkup_init(&markup, STRL("[align=invalid]"), &error);
	TestCase_assertBoolFalse(success);
	TestCase_assertEnumEqual(error.code, UIPageMarkup_error_valueInvalid);
	TestCase_assertSizeEqual(error.charIndex, 14);
	TestCase_assertUIntEqual(error.lineIndex, 0);
	TestCase_assertUIntEqual(error.lineCharIndex, 14);
	
	success = UIPageMarkup_init(&markup, STRL("[valign=invalid]"), &error);
	TestCase_assertBoolFalse(success);
	TestCase_assertEnumEqual(error.code, UIPageMarkup_error_valueInvalid);
	TestCase_assertSizeEqual(error.charIndex, 15);
	TestCase_assertUIntEqual(error.lineIndex, 0);
	TestCase_assertUIntEqual(error.lineCharIndex, 15);
	
	success = UIPageMarkup_init(&markup, STRL("[color=a]"), &error);
	TestCase_assertBoolFalse(success);
	TestCase_assertEnumEqual(error.code, UIPageMarkup_error_valueInvalid);
	TestCase_assertSizeEqual(error.charIndex, 8);
	TestCase_assertUIntEqual(error.lineIndex, 0);
	TestCase_assertUIntEqual(error.lineCharIndex, 8);
	
	success = UIPageMarkup_init(&markup, STRL("[color=ZZZZZZ]"), &error);
	TestCase_assertBoolFalse(success);
	TestCase_assertEnumEqual(error.code, UIPageMarkup_error_valueInvalid);
	TestCase_assertSizeEqual(error.charIndex, 13);
	TestCase_assertUIntEqual(error.lineIndex, 0);
	TestCase_assertUIntEqual(error.lineCharIndex, 13);
	
	success = UIPageMarkup_init(&markup, STRL("[color=000000000]"), &error);
	TestCase_assertBoolFalse(success);
	TestCase_assertEnumEqual(error.code, UIPageMarkup_error_valueInvalid);
	TestCase_assertSizeEqual(error.charIndex, 16);
	TestCase_assertUIntEqual(error.lineIndex, 0);
	TestCase_assertUIntEqual(error.lineCharIndex, 16);
	
	success = UIPageMarkup_init(&markup, STRL("a[]b"), &error);
	TestCase_assertBoolFalse(success);
	TestCase_assertEnumEqual(error.code, UIPageMarkup_error_unrecognizedTag);
	TestCase_assertSizeEqual(error.charIndex, 2);
	TestCase_assertUIntEqual(error.lineIndex, 0);
	TestCase_assertUIntEqual(error.lineCharIndex, 2);
	
	success = UIPageMarkup_init(&markup, STRL("[color]"), &error);
	TestCase_assertBoolFalse(success);
	TestCase_assertEnumEqual(error.code, UIPageMarkup_error_valueMissing);
	TestCase_assertSizeEqual(error.charIndex, 6);
	TestCase_assertUIntEqual(error.lineIndex, 0);
	TestCase_assertUIntEqual(error.lineCharIndex, 6);
	
	success = UIPageMarkup_init(&markup, STRL("[align]"), &error);
	TestCase_assertBoolFalse(success);
	TestCase_assertEnumEqual(error.code, UIPageMarkup_error_valueMissing);
	TestCase_assertSizeEqual(error.charIndex, 6);
	TestCase_assertUIntEqual(error.lineIndex, 0);
	TestCase_assertUIntEqual(error.lineCharIndex, 6);
	
	success = UIPageMarkup_init(&markup, STRL("[valign]"), &error);
	TestCase_assertBoolFalse(success);
	TestCase_assertEnumEqual(error.code, UIPageMarkup_error_valueMissing);
	TestCase_assertSizeEqual(error.charIndex, 7);
	TestCase_assertUIntEqual(error.lineIndex, 0);
	TestCase_assertUIntEqual(error.lineCharIndex, 7);
	
	success = UIPageMarkup_init(&markup, STRL("[font]"), &error);
	TestCase_assertBoolFalse(success);
	TestCase_assertEnumEqual(error.code, UIPageMarkup_error_valueMissing);
	TestCase_assertSizeEqual(error.charIndex, 5);
	TestCase_assertUIntEqual(error.lineIndex, 0);
	TestCase_assertUIntEqual(error.lineCharIndex, 5);
	
	success = UIPageMarkup_init(&markup, STRL("[link]"), &error);
	TestCase_assertBoolFalse(success);
	TestCase_assertEnumEqual(error.code, UIPageMarkup_error_valueMissing);
	TestCase_assertSizeEqual(error.charIndex, 5);
	TestCase_assertUIntEqual(error.lineIndex, 0);
	TestCase_assertUIntEqual(error.lineCharIndex, 5);
	
	success = UIPageMarkup_init(&markup, STRL("[img]"), &error);
	TestCase_assertBoolFalse(success);
	TestCase_assertEnumEqual(error.code, UIPageMarkup_error_valueMissing);
	TestCase_assertSizeEqual(error.charIndex, 4);
	TestCase_assertUIntEqual(error.lineIndex, 0);
	TestCase_assertUIntEqual(error.lineCharIndex, 4);
	
	success = UIPageMarkup_init(&markup, STRL("[i"), &error);
	TestCase_assertBoolFalse(success);
	TestCase_assertEnumEqual(error.code, UIPageMarkup_error_unterminatedTag);
	TestCase_assertSizeEqual(error.charIndex, 2);
	TestCase_assertUIntEqual(error.lineIndex, 0);
	TestCase_assertUIntEqual(error.lineCharIndex, 2);
	
	success = UIPageMarkup_init(&markup, STRL("[i-]a\nb"), &error);
	TestCase_assertBoolFalse(success);
	TestCase_assertEnumEqual(error.code, UIPageMarkup_error_minusNotAtEndOfLine);
	TestCase_assertSizeEqual(error.charIndex, 5);
	TestCase_assertUIntEqual(error.lineIndex, 0);
	TestCase_assertUIntEqual(error.lineCharIndex, 5);
	
	success = UIPageMarkup_init(&markup, STRL("a\eb"), &error);
	TestCase_assertBoolFalse(success);
	TestCase_assertEnumEqual(error.code, UIPageMarkup_error_escapeInString);
	TestCase_assertSizeEqual(error.charIndex, 1);
	TestCase_assertUIntEqual(error.lineIndex, 0);
	TestCase_assertUIntEqual(error.lineCharIndex, 1);
}

static void testDuplicateValuesCoalesced(void) {
	UIPageMarkup markup;
	bool success = UIPageMarkup_init(&markup, STRL("[color=FF0000][color=00FFFF][color=FF0000]"), NULL);
	TestCase_assertBoolTrue(success);
	assertStringStructEqualRaw(markup.textData, STRL("\x1B\x60\x00\x00\x1B\x60\x01\x00\x1B\x60\x00\x00"));
	TestCase_assertUIntEqual(markup.stringCount, 0);
	TestCase_assertUIntEqual(markup.colorCount, 2);
	TestCase_assertPointerNonNULL(markup.colors);
	TestCase_assertUIntEqual(markup.colors[0].red, 0xFF);
	TestCase_assertUIntEqual(markup.colors[0].green, 0x00);
	TestCase_assertUIntEqual(markup.colors[0].blue, 0x00);
	TestCase_assertUIntEqual(markup.colors[0].alpha, 0xFF);
	TestCase_assertUIntEqual(markup.colors[1].red, 0x00);
	TestCase_assertUIntEqual(markup.colors[1].green, 0xFF);
	TestCase_assertUIntEqual(markup.colors[1].blue, 0xFF);
	TestCase_assertUIntEqual(markup.colors[1].alpha, 0xFF);
	UIPageMarkup_disposeContents(&markup);
	
	success = UIPageMarkup_init(&markup, STRL("[color=11223344][color=112233FF][color=112233]"), NULL);
	TestCase_assertBoolTrue(success);
	assertStringStructEqualRaw(markup.textData, STRL("\x1B\x60\x00\x00\x1B\x60\x01\x00\x1B\x60\x01\x00"));
	TestCase_assertUIntEqual(markup.stringCount, 0);
	TestCase_assertUIntEqual(markup.colorCount, 2);
	TestCase_assertPointerNonNULL(markup.colors);
	TestCase_assertUIntEqual(markup.colors[0].red, 0x11);
	TestCase_assertUIntEqual(markup.colors[0].green, 0x22);
	TestCase_assertUIntEqual(markup.colors[0].blue, 0x33);
	TestCase_assertUIntEqual(markup.colors[0].alpha, 0x44);
	TestCase_assertUIntEqual(markup.colors[1].red, 0x11);
	TestCase_assertUIntEqual(markup.colors[1].green, 0x22);
	TestCase_assertUIntEqual(markup.colors[1].blue, 0x33);
	TestCase_assertUIntEqual(markup.colors[1].alpha, 0xFF);
	UIPageMarkup_disposeContents(&markup);
	
	success = UIPageMarkup_init(&markup, STRL("[font=ab][font=ab][font=cd]"), NULL);
	TestCase_assertBoolTrue(success);
	assertStringStructEqualRaw(markup.textData, STRL("\x1B\x61\x00\x00\x1B\x61\x00\x00\x1B\x61\x01\x00"));
	TestCase_assertUIntEqual(markup.stringCount, 2);
	TestCase_assertUIntEqual(markup.colorCount, 0);
	TestCase_assertPointerNonNULL(markup.strings);
	TestCase_assertStringStructEqual(markup.strings[0], STRL("ab"));
	TestCase_assertStringStructEqual(markup.strings[1], STRL("cd"));
	UIPageMarkup_disposeContents(&markup);
	
	success = UIPageMarkup_init(&markup, STRL("[link=AB][link=CD][link=AB]"), NULL);
	TestCase_assertBoolTrue(success);
	assertStringStructEqualRaw(markup.textData, STRL("\x1B\x62\x00\x00\x1B\x62\x01\x00\x1B\x62\x00\x00"));
	TestCase_assertUIntEqual(markup.stringCount, 2);
	TestCase_assertUIntEqual(markup.colorCount, 0);
	TestCase_assertPointerNonNULL(markup.strings);
	TestCase_assertStringStructEqual(markup.strings[0], STRL("AB"));
	TestCase_assertStringStructEqual(markup.strings[1], STRL("CD"));
	UIPageMarkup_disposeContents(&markup);
	
	success = UIPageMarkup_init(&markup, STRL("[img=12][img=3\\]][img=3\\]]"), NULL);
	TestCase_assertBoolTrue(success);
	assertStringStructEqualRaw(markup.textData, STRL("\x1B\x63\x00\x00\x1B\x63\x01\x00\x1B\x63\x01\x00"));
	TestCase_assertUIntEqual(markup.stringCount, 2);
	TestCase_assertUIntEqual(markup.colorCount, 0);
	TestCase_assertPointerNonNULL(markup.strings);
	TestCase_assertStringStructEqual(markup.strings[0], STRL("12"));
	TestCase_assertStringStructEqual(markup.strings[1], STRL("3]"));
	UIPageMarkup_disposeContents(&markup);
}

static void testLineMinimization(void) {
	UIPageMarkup markup;
	bool success = UIPageMarkup_init(&markup, STRL("a\n[img=a]\nb"), NULL);
	TestCase_assertBoolTrue(success);
	assertStringStructEqualRaw(markup.textData, STRL("a\n\x1B\x63\x00\x00\nb"));
	TestCase_assertUIntEqual(markup.stringCount, 1);
	TestCase_assertUIntEqual(markup.colorCount, 0);
	TestCase_assertPointerNonNULL(markup.strings);
	TestCase_assertStringStructEqual(markup.strings[0], STRL("a"));
	UIPageMarkup_disposeContents(&markup);
	
	success = UIPageMarkup_init(&markup, STRL("a\n[img=a-]\nb"), NULL);
	TestCase_assertBoolTrue(success);
	assertStringStructEqualRaw(markup.textData, STRL("a\n\x1B\x63\x00\x00""b"));
	TestCase_assertUIntEqual(markup.stringCount, 1);
	TestCase_assertUIntEqual(markup.colorCount, 0);
	TestCase_assertPointerNonNULL(markup.strings);
	TestCase_assertStringStructEqual(markup.strings[0], STRL("a"));
	UIPageMarkup_disposeContents(&markup);
	
	success = UIPageMarkup_init(&markup, STRL("a\n[img=a\\-]\nb"), NULL);
	TestCase_assertBoolTrue(success);
	assertStringStructEqualRaw(markup.textData, STRL("a\n\x1B\x63\x00\x00\nb"));
	TestCase_assertUIntEqual(markup.stringCount, 1);
	TestCase_assertUIntEqual(markup.colorCount, 0);
	TestCase_assertPointerNonNULL(markup.strings);
	TestCase_assertStringStructEqual(markup.strings[0], STRL("a-"));
	UIPageMarkup_disposeContents(&markup);
	
	success = UIPageMarkup_init(&markup, STRL("a\n[img=a-b]\nb"), NULL);
	TestCase_assertBoolTrue(success);
	assertStringStructEqualRaw(markup.textData, STRL("a\n\x1B\x63\x00\x00\nb"));
	TestCase_assertUIntEqual(markup.stringCount, 1);
	TestCase_assertUIntEqual(markup.colorCount, 0);
	TestCase_assertPointerNonNULL(markup.strings);
	TestCase_assertStringStructEqual(markup.strings[0], STRL("a-b"));
	UIPageMarkup_disposeContents(&markup);
	
	success = UIPageMarkup_init(&markup, STRL("[i]\nI\n[/i]\nN"), NULL);
	TestCase_assertBoolTrue(success);
	assertStringStructEqualRaw(markup.textData, STRL("\x1B\x00\nI\n\x1B\x01\nN"));
	TestCase_assertUIntEqual(markup.stringCount, 0);
	TestCase_assertUIntEqual(markup.colorCount, 0);
	UIPageMarkup_disposeContents(&markup);
	
	success = UIPageMarkup_init(&markup, STRL("[i-]\nI\n[/i-]\nN"), NULL);
	TestCase_assertBoolTrue(success);
	assertStringStructEqualRaw(markup.textData, STRL("\x1B\x00I\n\x1B\x01N"));
	TestCase_assertUIntEqual(markup.stringCount, 0);
	TestCase_assertUIntEqual(markup.colorCount, 0);
	UIPageMarkup_disposeContents(&markup);
	
	success = UIPageMarkup_init(&markup, STRL("[list-]\n[*]x\n[/list-]\ny"), NULL);
	TestCase_assertBoolTrue(success);
	assertStringStructEqualRaw(markup.textData, STRL("\x1B\x0A\x1B\x0Dx\n\x1B\x0Cy"));
	TestCase_assertUIntEqual(markup.stringCount, 0);
	TestCase_assertUIntEqual(markup.colorCount, 0);
	UIPageMarkup_disposeContents(&markup);
	
	success = UIPageMarkup_init(&markup, STRL("[list-]\n[*]x\n[/list-]"), NULL);
	TestCase_assertBoolTrue(success);
	assertStringStructEqualRaw(markup.textData, STRL("\x1B\x0A\x1B\x0Dx\x1B\x0C"));
	TestCase_assertUIntEqual(markup.stringCount, 0);
	TestCase_assertUIntEqual(markup.colorCount, 0);
	UIPageMarkup_disposeContents(&markup);
}

static void testSpacesStrippedFromListItems(void) {
	UIPageMarkup markup;
	bool success = UIPageMarkup_init(&markup, STRL("[list]\n[*]item 1\n  [*]item 2\n[/list]"), NULL);
	TestCase_assertBoolTrue(success);
	assertStringStructEqualRaw(markup.textData, STRL("\x1B\x0A\n\x1B\x0Ditem 1\n\x1B\x0Ditem 2\n\x1B\x0C"));
	TestCase_assertUIntEqual(markup.stringCount, 0);
	TestCase_assertUIntEqual(markup.colorCount, 0);
	UIPageMarkup_disposeContents(&markup);
	
	success = UIPageMarkup_init(&markup, STRL("[list]\n [*]item 1\n\t \t[*]item 2\n[/list]"), NULL);
	TestCase_assertBoolTrue(success);
	assertStringStructEqualRaw(markup.textData, STRL("\x1B\x0A\n\x1B\x0Ditem 1\n\x1B\x0Ditem 2\n\x1B\x0C"));
	TestCase_assertUIntEqual(markup.stringCount, 0);
	TestCase_assertUIntEqual(markup.colorCount, 0);
	UIPageMarkup_disposeContents(&markup);
}

TEST_SUITE(UIPageMarkupTest,
           testInit,
           testParse,
           testParseErrors,
           testDuplicateValuesCoalesced,
           testLineMinimization,
           testSpacesStrippedFromListItems)
