#include <muleunit/test.h>
#include <common/StringFunctions.h>

#include <wx/filename.h>

using namespace muleunit;

DECLARE_SIMPLE(StringFunctions)


///////////////////////////////////////////////////////////
// Tests for the JoinPaths function

TEST(StringFunctions, JoinPaths)
{
	const wxString seps = wxFileName::GetPathSeparators();
	const wxString sep = wxFileName::GetPathSeparator();

	for (size_t i = 0; i < seps.Length(); ++i) {
		const wxString cur_sep = seps.Mid(i, 1);
		
		ASSERT_EQUALS(wxT("a") + sep + wxT("b"), JoinPaths(wxT("a"), wxT("b")));
		ASSERT_EQUALS(wxT("a") + sep + wxT("b"), JoinPaths(wxT("a") + cur_sep, wxT("b")));
		ASSERT_EQUALS(wxT("a") + sep + wxT("b"), JoinPaths(wxT("a"), cur_sep + wxT("b")));
		ASSERT_EQUALS(wxT("a") + sep + wxT("b"), JoinPaths(wxT("a") + cur_sep, cur_sep + wxT("b")));
		ASSERT_EQUALS(wxT("a"), JoinPaths(wxT("a"), wxEmptyString));
		ASSERT_EQUALS(wxT("b"), JoinPaths(wxEmptyString, wxT("b")));
		ASSERT_EQUALS(wxEmptyString, JoinPaths(wxEmptyString, wxEmptyString));
	}
}


///////////////////////////////////////////////////////////
// Tests for the FuzzyStrCmp function

//! Returns the number of items in an array.
#define itemsof(x) (sizeof(x)/sizeof(x[0]))

TEST(StringFunctions, FuzzyStrCmp)
{
	struct FuzzyTest {
		const wxChar* a;
		const wxChar* b;
		int expected;
	};

	FuzzyTest checks[] = {
		{ wxT("a (10)"),	wxT("a (2)"),		 1},
		{ wxT("a (10)"),	wxT("b (2)"),		-1},
		{ wxT("c3 (7)"),	wxT("c3 (12)"),		-1},
		{ wxT("c3 (12)"),	wxT("c3 (7)"),		 1},
		{ wxT("c3 12d"),	wxT("c3 12d"),		 0},
		{ wxT("a (10)  "),	wxT("a (2)  "),		 1},
		{ wxT("a (10)  "),	wxT("b (2)  "),		-1},
		{ wxT("  c3 (7)"),	wxT("  c3 (12)"),	-1},
		{ wxT("  c3 (12)"),	wxT("  c3 (7)"),	 1},
		{ wxT("c3 12d"),	wxT("c3 12d"),		 0},
		{ wxT(""),		wxT(""),		 0},
		{ wxT(""),		wxT("c3 12d"),		-1},
		{ wxT("c3 12d"),	wxT(""),		 1},
		{ wxT(" "),		wxT("c3 12d"),		-1},
		{ wxT("c3 12d"),	wxT(" "),		 1},
		{ wxT("17.10"),		wxT("17.2"),		 1},
		{ wxT("  c3 (a)"),	wxT("  c3 (12)"),	 1},
		{ wxT("  c3 (12)"),	wxT("  c3 (a)"),	-1},
	};

	for (size_t i = 0; i < itemsof(checks); ++i) {
		wxString a = checks[i].a;
		wxString b = checks[i].b;

		ASSERT_EQUALS(checks[i].expected, FuzzyStrCmp(a, b));
	}
}


///////////////////////////////////////////////////////////
// Tests for the CSimpleParser class

DECLARE_SIMPLE(SimpleParser)

	
TEST(SimpleParser, Constructor)
{
	// Empty strings are acceptable and should just return an empty string
	{
		CSimpleTokenizer tkz1(wxEmptyString, wxT('-'));
		ASSERT_EQUALS(wxT(""), tkz1.remaining());
		ASSERT_EQUALS(wxEmptyString, tkz1.next());
		ASSERT_EQUALS(wxT(""), tkz1.remaining());
		ASSERT_EQUALS(wxEmptyString, tkz1.next());
	}

	// String with no tokens should be return immediatly
	{
		CSimpleTokenizer tkz2(wxT(" abc "), wxT('-'));
		ASSERT_EQUALS(wxT(" abc "), tkz2.remaining());
		ASSERT_EQUALS(wxT(" abc "), tkz2.next());
		ASSERT_EQUALS(wxEmptyString, tkz2.next());
		ASSERT_EQUALS(wxEmptyString, tkz2.next());
	}
}


TEST(SimpleParser, EmptyTokens)
{
	{
		CSimpleTokenizer tkz1(wxT(" a"), wxT(' '));
		ASSERT_EQUALS(wxT(" a"), tkz1.remaining());
		ASSERT_EQUALS(0u, tkz1.tokenCount());
		
		ASSERT_EQUALS(wxEmptyString, tkz1.next());
		ASSERT_EQUALS(wxT("a"), tkz1.remaining());
		ASSERT_EQUALS(1u, tkz1.tokenCount());
		
		ASSERT_EQUALS(wxT("a"), tkz1.next());
		ASSERT_EQUALS(wxT(""), tkz1.remaining());
		ASSERT_EQUALS(1u, tkz1.tokenCount());
		
		ASSERT_EQUALS(wxEmptyString, tkz1.next());
		ASSERT_EQUALS(wxT(""), tkz1.remaining());
		ASSERT_EQUALS(1u, tkz1.tokenCount());
	}
	
	{	
		CSimpleTokenizer tkz2(wxT("c "), wxT(' '));
		ASSERT_EQUALS(wxT("c "), tkz2.remaining());
		ASSERT_EQUALS(0u, tkz2.tokenCount());
		
		ASSERT_EQUALS(wxT("c"), tkz2.next());
		ASSERT_EQUALS(wxT(""), tkz2.remaining());
		ASSERT_EQUALS(1u, tkz2.tokenCount());
		
		ASSERT_EQUALS(wxEmptyString, tkz2.next());
		ASSERT_EQUALS(wxT(""), tkz2.remaining());
		ASSERT_EQUALS(1u, tkz2.tokenCount());
		
		ASSERT_EQUALS(wxEmptyString, tkz2.next());
		ASSERT_EQUALS(wxT(""), tkz2.remaining());
		ASSERT_EQUALS(1u, tkz2.tokenCount());
	}

	{
		CSimpleTokenizer tkz3(wxT(" a c "), wxT(' '));
		ASSERT_EQUALS(wxT(" a c "), tkz3.remaining());
		ASSERT_EQUALS(0u, tkz3.tokenCount());

		ASSERT_EQUALS(wxEmptyString, tkz3.next());
		ASSERT_EQUALS(wxT("a c "), tkz3.remaining());
		ASSERT_EQUALS(1u, tkz3.tokenCount());

		ASSERT_EQUALS(wxT("a"), tkz3.next());
		ASSERT_EQUALS(wxT("c "), tkz3.remaining());
		ASSERT_EQUALS(2u, tkz3.tokenCount());

		ASSERT_EQUALS(wxT("c"), tkz3.next());
		ASSERT_EQUALS(wxT(""), tkz3.remaining());
		ASSERT_EQUALS(3u, tkz3.tokenCount());

		ASSERT_EQUALS(wxEmptyString, tkz3.next());
		ASSERT_EQUALS(wxT(""), tkz3.remaining());
		ASSERT_EQUALS(3u, tkz3.tokenCount());

		ASSERT_EQUALS(wxEmptyString, tkz3.next());
		ASSERT_EQUALS(wxT(""), tkz3.remaining());
		ASSERT_EQUALS(3u, tkz3.tokenCount());
	}
}


TEST(SimpleParser, NormalTokens)
{
	CSimpleTokenizer tkz(wxT("a c"), wxT(' '));
	ASSERT_EQUALS(wxT("a c"), tkz.remaining());
	ASSERT_EQUALS(0u, tkz.tokenCount());
	
	ASSERT_EQUALS(wxT("a"), tkz.next());
	ASSERT_EQUALS(wxT("c"), tkz.remaining());
	ASSERT_EQUALS(1u, tkz.tokenCount());
	
	ASSERT_EQUALS(wxT("c"), tkz.next());
	ASSERT_EQUALS(wxT(""), tkz.remaining());
	ASSERT_EQUALS(1u, tkz.tokenCount());
	
	ASSERT_EQUALS(wxEmptyString, tkz.next());
	ASSERT_EQUALS(wxT(""), tkz.remaining());
	ASSERT_EQUALS(1u, tkz.tokenCount());
	
	ASSERT_EQUALS(wxEmptyString, tkz.next());
	ASSERT_EQUALS(wxT(""), tkz.remaining());
	ASSERT_EQUALS(1u, tkz.tokenCount());
}

