/******************************************************************************
 testescape.cc

	A test program for JSubstitute.

	Copyright © 1997 by Dustin Laurence.  All rights reserved.
	
	Base code generated by Codemill v0.1.0

 *****************************************************************************/

#include <JSubstitute.h>
#include <JString.h>
#include <jAssert.h>

/******************************************************************************
 main

 *****************************************************************************/

int
main()
{
	cout << "\nJSubstitute bug check: only errors will be reported, so no news is good news." << endl;

	JString oldString, newString;

	{
		JSubstitute esc;
		esc.IgnoreUnrecognized();

		// A string with an unrecognized escape
		oldString = "\\i\\iabc\\i\\idef\\i\\i";
		newString = oldString;

		// Test "do nothing" default
		esc(&newString);
		if (newString != oldString)
			{
			cout << "    testescape failure at line " << __LINE__ << endl;
			}


		// Test ignore unrecognized
		newString = oldString;
		esc.IgnoreUnrecognized(kFalse);
		esc(&newString);
		if (newString != "iiabciidefii")
			{
			cout << "    testescape failure at line " << __LINE__ << endl;
			}


		// Test a basic table entry
		newString = oldString;
		JString replaceString = "<>";
		esc.SetEscape('i', replaceString);
		esc(&newString);
		if (newString != "<><>abc<><>def<><>")
			{
			cout << "    testescape failure at line " << __LINE__ << endl;
			}


		// Entries should be case-sensitive
		oldString = "\\I\\Iabc\\I\\Idef\\I\\I";
		newString = oldString;
		replaceString = "<wrong>";
		esc.IgnoreUnrecognized();
		esc(&newString);
		if (newString != oldString)
			{
			cout << "    testescape failure at line " << __LINE__ << endl;
			cout << "    newString = \"" << newString << "\", should be \""
			     << oldString << "\"" << endl;
			}


		// Test end-of-string behavior
		oldString = "abcdef\\";
		newString = oldString;
		esc.IgnoreUnrecognized();
		esc(&newString);
		if (newString != "abcdef")
			{
			cout << "    testescape failure at line " << __LINE__ << endl;
			}
		newString = oldString;
		esc.IgnoreUnrecognized(kFalse);
		esc(&newString);
		if (newString != "abcdef")
			{
			cout << "    testescape failure at line " << __LINE__ << endl;
			}


		// Test clearing an entry
		oldString = "abc\\idef";
		newString = oldString;
		esc.ClearEscape('i');
		esc.IgnoreUnrecognized();
		esc(&newString);
		if (newString != oldString)
			{
			cout << "    testescape failure at line " << __LINE__ << endl;
			}
	}

	{
		JSubstitute esc;
		esc.IgnoreUnrecognized();

		// A string with a control-character escape
		oldString = "\\cG\\cGabc\\cG\\cGdef\\cG\\cG";
		newString = oldString;

		// Test a control substitution
		esc.UseControlEscapes();
		esc(&newString);
		if (newString != "\a\aabc\a\adef\a\a")
			{
			cout << "    testescape failure at line " << __LINE__ << endl;
			}


		// But this should fail
		oldString = "\\CG\\CGabc\\CG\\CGdef\\CG\\CG";
		newString = oldString;
		esc(&newString);
		if (newString != oldString)
			{
			cout << "    testescape failure at line " << __LINE__ << endl;
			}


		// So should this
		oldString = "\\cg\\cgabc\\cg\\cgdef\\cg\\cg";
		newString = oldString;
		esc(&newString);
		if (newString != oldString)
			{
			cout << "    testescape failure at line " << __LINE__ << endl;
			}


		// Check the allowed range

		// This one should be disallowed
		oldString = "abc\\c@def";
		newString = oldString;
		esc(&newString);
		if (newString != oldString)
			{
			cout << "    testescape failure at line " << __LINE__ << endl;
			}


		// This one should work
		oldString = "\\cA\\cAabc\\cA\\cAdef\\cA\\cA";
		newString = oldString;
		esc(&newString);
		if (newString != "\01\01abc\01\01def\01\01")
			{
			cout << "    testescape failure at line " << __LINE__ << endl;
			}


		// So should this one
		oldString = "abc\\c_def";
		newString = oldString;
		esc(&newString);
		if (newString != "abc\037def")
			{
			cout << "    testescape failure at line " << __LINE__ << endl;
			cout << "    newString = \"" << newString << "\", should be \""
			     << "abc\037def" << "\"" << endl;
			}


		// But this should fail
		oldString = "abc\\c@`def";
		newString = oldString;
		esc(&newString);
		if (newString != oldString)
			{
			cout << "    testescape failure at line " << __LINE__ << endl;
			}


		// Test end-of-string behavior
		oldString = "abcdef\\c";
		newString = oldString;
		esc.IgnoreUnrecognized();
		esc(&newString);
		if (newString != "abcdef")
			{
			cout << "    testescape failure at line " << __LINE__ << endl;
			}
		newString = oldString;
		esc.IgnoreUnrecognized(kFalse);
		esc(&newString);
		if (newString != "abcdef")
			{
			cout << "    testescape failure at line " << __LINE__ << endl;
			}

		oldString = "abcdef\\cM";
		newString = oldString;
		esc.IgnoreUnrecognized();
		esc(&newString);
		if (newString != "abcdef\r")
			{
			cout << "    testescape failure at line " << __LINE__ << endl;
			}
		newString = oldString;
		esc.IgnoreUnrecognized(kFalse);
		esc(&newString);
		if (newString != "abcdef\r")
			{
			cout << "    testescape failure at line " << __LINE__ << endl;
			}


		// Check ClearAllOrdinary
		oldString = "abc\\cKdef";
		newString = oldString;
		esc.ClearAllEscapes();
		esc.IgnoreUnrecognized();
		esc(&newString);
		if (newString != "abc\vdef")
			{
			cout << "    testescape failure at line " << __LINE__ << endl;
			cout << "    newString = \"" << newString << "\", should be \""
			     << "abc\vdef" << "\"" << endl;
			}


		// Check reset
		oldString = "abc\\cGdef";
		newString = oldString;
		esc.Reset();
		esc.IgnoreUnrecognized();
		esc(&newString);
		if (newString != oldString)
			{
			cout << "    testescape failure at line " << __LINE__ << endl;
			cout << "    newString = \"" << newString << "\", should be \""
			     << oldString << "\"" << endl;
			}
	}

	cout << "Bug check complete.\n" << endl;

	return 0;
}
