You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							883 lines
						
					
					
						
							26 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							883 lines
						
					
					
						
							26 KiB
						
					
					
				| 
 | |
| #include "cpptempl.h" | |
|  | |
| #ifdef UNIT_TEST | |
|  | |
| #include <boost/test/unit_test.hpp> | |
|  | |
| #ifndef BOOST_TEST_MODULE | |
| #define BOOST_TEST_MODULE cpptemplTests | |
| #endif | |
|  | |
| #pragma warning( disable : 4996 ) // doesn't like wcstombs | |
|  | |
| #include "unit_testing.h" | |
|  | |
| using namespace std ; | |
| 
 | |
| BOOST_AUTO_TEST_SUITE( TestCppData ) | |
| 
 | |
| 	using namespace cpptempl ; | |
| 	 | |
| 	// DataMap | |
| 	BOOST_AUTO_TEST_CASE(test_DataMap_getvalue) | |
| 	{ | |
| 		data_map items ; | |
| 		data_ptr data(new DataMap(items)) ; | |
| 		BOOST_CHECK_THROW( data->getvalue(), TemplateException ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(test_DataMap_getlist_throws) | |
| 	{ | |
| 		data_map items ; | |
| 		data_ptr data(new DataMap(items)) ; | |
| 
 | |
| 		BOOST_CHECK_THROW( data->getlist(), TemplateException ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(test_DataMap_getitem_throws) | |
| 	{ | |
| 		data_map items ; | |
| 		items[L"key"] = data_ptr(new DataValue(L"foo")) ; | |
| 		data_ptr data(new DataMap(items)) ; | |
| 
 | |
| 		BOOST_CHECK_EQUAL( data->getmap()[L"key"]->getvalue(), L"foo" ) ; | |
| 	} | |
| 	// DataList | |
| 	BOOST_AUTO_TEST_CASE(test_DataList_getvalue) | |
| 	{ | |
| 		data_list items ; | |
| 		data_ptr data(new DataList(items)) ; | |
| 
 | |
| 		BOOST_CHECK_THROW( data->getvalue(), TemplateException ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(test_DataList_getlist_throws) | |
| 	{ | |
| 		data_list items ; | |
| 		items.push_back(make_data(L"bar")) ; | |
| 		data_ptr data(new DataList(items)) ; | |
| 
 | |
| 		BOOST_CHECK_EQUAL( data->getlist().size(), 1u ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(test_DataList_getitem_throws) | |
| 	{ | |
| 		data_list items ; | |
| 		data_ptr data(new DataList(items)) ; | |
| 
 | |
| 		BOOST_CHECK_THROW( data->getmap(), TemplateException ) ; | |
| 	} | |
| 	// DataValue | |
| 	BOOST_AUTO_TEST_CASE(test_DataValue_getvalue) | |
| 	{ | |
| 		data_ptr data(new DataValue(L"foo")) ; | |
| 
 | |
| 		BOOST_CHECK_EQUAL( data->getvalue(), L"foo" ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(test_DataValue_getlist_throws) | |
| 	{ | |
| 		data_ptr data(new DataValue(L"foo")) ; | |
| 
 | |
| 		BOOST_CHECK_THROW( data->getlist(), TemplateException ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(test_DataValue_getitem_throws) | |
| 	{ | |
| 		data_ptr data(new DataValue(L"foo")) ; | |
| 
 | |
| 		BOOST_CHECK_THROW( data->getmap(), TemplateException ) ; | |
| 	} | |
| BOOST_AUTO_TEST_SUITE_END() | |
| 
 | |
| 
 | |
| BOOST_AUTO_TEST_SUITE( TestCppParseVal ) | |
| 
 | |
| 	using namespace cpptempl ; | |
| 	BOOST_AUTO_TEST_CASE(test_quoted) | |
| 	{ | |
| 		data_map data ; | |
| 		data[L"foo"] = make_data(L"bar") ; | |
| 		data_ptr value = parse_val(L"\"foo\"", data) ; | |
| 
 | |
| 		BOOST_CHECK_EQUAL( value->getvalue(), L"foo" ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(test_value) | |
| 	{ | |
| 		data_map data ; | |
| 		data[L"foo"] = make_data(L"bar") ; | |
| 		data_ptr value = parse_val(L"foo", data) ; | |
| 
 | |
| 		BOOST_CHECK_EQUAL( value->getvalue(), L"bar" ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(test_not_found) | |
| 	{ | |
| 		data_map data ; | |
| 		data[L"foo"] = make_data(L"bar") ; | |
| 		data_ptr value = parse_val(L"kettle", data) ; | |
| 
 | |
| 		BOOST_CHECK_EQUAL( value->getvalue(), L"{$kettle}" ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(test_not_found_dotted) | |
| 	{ | |
| 		data_map data ; | |
| 		data[L"foo"] = make_data(L"bar") ; | |
| 		data_ptr value = parse_val(L"kettle.black", data) ; | |
| 
 | |
| 		BOOST_CHECK_EQUAL( value->getvalue(), L"{$kettle.black}" ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(test_my_ax) | |
| 	{ | |
| 		data_map data ; | |
| 		data[L"item"] = make_data(L"my ax") ; | |
| 		BOOST_CHECK_EQUAL( parse_val(L"item", data)->getvalue(), L"my ax" ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(test_list) | |
| 	{ | |
| 		data_map data ; | |
| 		data_list items ; | |
| 		items.push_back(make_data(L"bar")) ; | |
| 		data[L"foo"] = data_ptr(new DataList(items)) ; | |
| 		data_ptr value = parse_val(L"foo", data) ; | |
| 
 | |
| 		BOOST_CHECK_EQUAL( value->getlist().size(), 1u ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(test_dotted) | |
| 	{ | |
| 		data_map data ; | |
| 		data_map subdata ; | |
| 		subdata[L"b"] = data_ptr(new DataValue(L"c")) ; | |
| 		data[L"a"] = data_ptr(new DataMap(subdata)) ; | |
| 		data_ptr value = parse_val(L"a.b", data) ; | |
| 
 | |
| 		BOOST_CHECK_EQUAL( value->getvalue(), L"c" ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(test_double_dotted) | |
| 	{ | |
| 		data_map data ; | |
| 		data_map sub_data ; | |
| 		data_map sub_sub_data ; | |
| 		sub_sub_data[L"c"] = data_ptr(new DataValue(L"d")) ; | |
| 		sub_data[L"b"] = data_ptr(new DataMap(sub_sub_data)) ; | |
| 		data[L"a"] = data_ptr(new DataMap(sub_data)) ; | |
| 		data_ptr value = parse_val(L"a.b.c", data) ; | |
| 
 | |
| 		BOOST_CHECK_EQUAL( value->getvalue(), L"d" ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(test_dotted_to_list) | |
| 	{ | |
| 		data_list friends ; | |
| 		friends.push_back(make_data(L"Bob")) ; | |
| 		data_map person ; | |
| 		person[L"friends"] = make_data(friends) ; | |
| 		data_map data ; | |
| 		data[L"person"] = make_data(person) ; | |
| 		data_ptr value = parse_val(L"person.friends", data) ; | |
| 
 | |
| 		BOOST_CHECK_EQUAL( value->getlist().size(), 1u ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(test_dotted_to_dict_list) | |
| 	{ | |
| 		data_map bob ; | |
| 		bob[L"name"] = make_data(L"Bob") ; | |
| 		data_map betty ; | |
| 		betty[L"name"] = make_data(L"Betty") ; | |
| 		data_list friends ; | |
| 		friends.push_back(make_data(bob)) ; | |
| 		friends.push_back(make_data(betty)) ; | |
| 		data_map person ; | |
| 		person[L"friends"] = make_data(friends) ; | |
| 		data_map data ; | |
| 		data[L"person"] = make_data(person) ; | |
| 		data_ptr value = parse_val(L"person.friends", data) ; | |
| 
 | |
| 		BOOST_CHECK_EQUAL( value->getlist()[0]->getmap()[L"name"]->getvalue(), L"Bob" ) ; | |
| 	} | |
| BOOST_AUTO_TEST_SUITE_END() | |
| 
 | |
| BOOST_AUTO_TEST_SUITE( TestCppToken ) | |
| 
 | |
| 	using namespace cpptempl ; | |
| 
 | |
| 	// TokenVar | |
| 	BOOST_AUTO_TEST_CASE(TestTokenVarType) | |
| 	{ | |
| 		TokenVar token(L"foo") ; | |
| 		BOOST_CHECK_EQUAL( token.gettype(), TOKEN_TYPE_VAR ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(TestTokenVar) | |
| 	{ | |
| 		token_ptr token(new TokenVar(L"foo")) ; | |
| 		data_map data ; | |
| 		data[L"foo"] = make_data(L"bar") ; | |
| 		BOOST_CHECK_EQUAL( gettext(token, data), L"bar" ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(TestTokenVarCantHaveChildren) | |
| 	{ | |
| 		TokenVar token(L"foo") ; | |
| 		token_vector children ; | |
| 		BOOST_CHECK_THROW(token.set_children(children), TemplateException) ; | |
| 	} | |
| 	// TokenText | |
| 	BOOST_AUTO_TEST_CASE(TestTokenTextType) | |
| 	{ | |
| 		TokenText token(L"foo") ; | |
| 		BOOST_CHECK_EQUAL( token.gettype(), TOKEN_TYPE_TEXT ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(TestTokenText) | |
| 	{ | |
| 		token_ptr token(new TokenText(L"foo")) ; | |
| 		data_map data ; | |
| 		data[L"foo"] = make_data(L"bar") ; | |
| 		BOOST_CHECK_EQUAL( gettext(token, data), L"foo" ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(TestTokenTextCantHaveChildrenSet) | |
| 	{ | |
| 		TokenText token(L"foo") ; | |
| 		token_vector children ; | |
| 		BOOST_CHECK_THROW(token.set_children(children), TemplateException) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(TestTokenTextCantHaveChildrenGet) | |
| 	{ | |
| 		TokenText token(L"foo") ; | |
| 		token_vector children ; | |
| 		BOOST_CHECK_THROW(token.get_children(), TemplateException) ; | |
| 	} | |
| 	// TokenFor | |
| 	BOOST_AUTO_TEST_CASE(TestTokenForBadSyntax) | |
| 	{ | |
| 		BOOST_CHECK_THROW(TokenFor token(L"foo"), TemplateException ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(TestTokenForType) | |
| 	{ | |
| 		TokenFor token(L"for item in items") ; | |
| 		BOOST_CHECK_EQUAL( token.gettype(), TOKEN_TYPE_FOR ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(TestTokenForTextEmpty) | |
| 	{ | |
| 		token_ptr token(new TokenFor(L"for item in items")) ; | |
| 		data_map data ; | |
| 		data_list items ; | |
| 		items.push_back(make_data(L"first"));  | |
| 		data[L"items"] = make_data(items) ; | |
| 		BOOST_CHECK_EQUAL( gettext(token, data), L"" ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(TestTokenForTextOneVar) | |
| 	{ | |
| 		token_vector children ; | |
| 		children.push_back(token_ptr(new TokenVar(L"item"))) ; | |
| 		token_ptr token(new TokenFor(L"for item in items")) ; | |
| 		token->set_children(children) ; | |
| 		data_map data ; | |
| 		data_list items ; | |
| 		items.push_back(make_data(L"first "));  | |
| 		items.push_back(make_data(L"second "));  | |
| 		data[L"items"] = make_data(items) ; | |
| 		BOOST_CHECK_EQUAL( gettext(token, data), L"first second " ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(TestTokenForTextOneVarLoop) | |
| 	{ | |
| 		token_vector children ; | |
| 		children.push_back(token_ptr(new TokenVar(L"loop.index"))) ; | |
| 		token_ptr token(new TokenFor(L"for item in items")) ; | |
| 		token->set_children(children) ; | |
| 		data_map data ; | |
| 		data_list items ; | |
| 		items.push_back(make_data(L"first "));  | |
| 		items.push_back(make_data(L"second "));  | |
| 		data[L"items"] = make_data(items) ; | |
| 		BOOST_CHECK_EQUAL( gettext(token, data), L"12" ) ; | |
| 	}	 | |
| 	BOOST_AUTO_TEST_CASE(TestTokenForLoopTextVar) | |
| 	{ | |
| 		token_vector children ; | |
| 		children.push_back(token_ptr(new TokenVar(L"loop.index"))) ; | |
| 		children.push_back(token_ptr(new TokenText(L". "))) ; | |
| 		children.push_back(token_ptr(new TokenVar(L"item"))) ; | |
| 		children.push_back(token_ptr(new TokenText(L" "))) ; | |
| 		token_ptr token(new TokenFor(L"for item in items")) ; | |
| 		token->set_children(children) ; | |
| 		data_map data ; | |
| 		data_list items ; | |
| 		items.push_back(make_data(L"first"));  | |
| 		items.push_back(make_data(L"second"));  | |
| 		data[L"items"] = make_data(items) ; | |
| 		BOOST_CHECK_EQUAL( gettext(token, data), L"1. first 2. second " ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(TestTokenForLoopTextVarDottedKeyAndVal) | |
| 	{ | |
| 		TokenFor token(L"for friend in person.friends") ; | |
| 		BOOST_CHECK_EQUAL( token.m_key, L"person.friends" ) ; | |
| 		BOOST_CHECK_EQUAL( token.m_val, L"friend" ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(TestTokenForLoopTextVarDotted) | |
| 	{ | |
| 		token_vector children ; | |
| 		children.push_back(token_ptr(new TokenVar(L"loop.index"))) ; | |
| 		children.push_back(token_ptr(new TokenText(L". "))) ; | |
| 		children.push_back(token_ptr(new TokenVar(L"friend.name"))) ; | |
| 		children.push_back(token_ptr(new TokenText(L" "))) ; | |
| 		token_ptr token(new TokenFor(L"for friend in person.friends")) ; | |
| 		token->set_children(children) ; | |
| 
 | |
| 		data_map bob ; | |
| 		bob[L"name"] = make_data(L"Bob") ; | |
| 		data_map betty ; | |
| 		betty[L"name"] = make_data(L"Betty") ; | |
| 		data_list friends ; | |
| 		friends.push_back(make_data(bob)) ; | |
| 		friends.push_back(make_data(betty)) ; | |
| 		data_map person ; | |
| 		person[L"friends"] = make_data(friends) ; | |
| 		data_map data ; | |
| 		data[L"person"] = make_data(person) ; | |
| 
 | |
| 		BOOST_CHECK_EQUAL( gettext(token, data), L"1. Bob 2. Betty " ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(TestTokenForTextOneText) | |
| 	{ | |
| 		token_vector children ; | |
| 		children.push_back(token_ptr(new TokenText(L"{--}"))) ; | |
| 		token_ptr token(new TokenFor(L"for item in items")) ; | |
| 		token->set_children(children) ; | |
| 		data_map data ; | |
| 		data_list items ; | |
| 		items.push_back(make_data(L"first "));  | |
| 		items.push_back(make_data(L"second "));  | |
| 		data[L"items"] = make_data(items) ; | |
| 		BOOST_CHECK_EQUAL( gettext(token, data), L"{--}{--}" ) ; | |
| 	} | |
| 
 | |
| 	////////////////////////////////////////////////////////////////////////// | |
| 	// TokenIf | |
| 	////////////////////////////////////////////////////////////////////////// | |
|  | |
| 	BOOST_AUTO_TEST_CASE(TestTokenIfType) | |
| 	{ | |
| 		TokenIf token(L"if items") ; | |
| 		BOOST_CHECK_EQUAL( token.gettype(), TOKEN_TYPE_IF ) ; | |
| 	} | |
| 	// if not empty | |
| 	BOOST_AUTO_TEST_CASE(TestTokenIfTrueText) | |
| 	{ | |
| 		token_vector children ; | |
| 		children.push_back(token_ptr(new TokenText(L"{--}"))) ; | |
| 		token_ptr token(new TokenIf(L"if item")) ; | |
| 		token->set_children(children) ; | |
| 		data_map data ; | |
| 		data[L"item"] = make_data(L"foo") ; | |
| 		BOOST_CHECK_EQUAL( gettext(token, data), L"{--}" ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(TestTokenIfTrueVar) | |
| 	{ | |
| 		token_vector children ; | |
| 		children.push_back(token_ptr(new TokenVar(L"item"))) ; | |
| 		token_ptr token(new TokenIf(L"if item")) ; | |
| 		token->set_children(children) ; | |
| 		data_map data ; | |
| 		data[L"item"] = make_data(L"foo") ; | |
| 		BOOST_CHECK_EQUAL( gettext(token, data), L"foo" ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(TestTokenIfFalse) | |
| 	{ | |
| 		token_vector children ; | |
| 		children.push_back(token_ptr(new TokenText(L"{--}"))) ; | |
| 		token_ptr token(new TokenIf(L"if item")) ; | |
| 		token->set_children(children) ; | |
| 		data_map data ; | |
| 		data[L"item"] = make_data(L"") ; | |
| 		BOOST_CHECK_EQUAL( gettext(token, data), L"") ; | |
| 	} | |
| 
 | |
| 	 | |
| 
 | |
| 	// == | |
| 	BOOST_AUTO_TEST_CASE(TestTokenIfEqualsTrue) | |
| 	{ | |
| 		token_vector children ; | |
| 		children.push_back(token_ptr(new TokenVar(L"item"))) ; | |
| 		token_ptr token(new TokenIf(L"if item == \"foo\"")) ; | |
| 		token->set_children(children) ; | |
| 		data_map data ; | |
| 		data[L"item"] = make_data(L"foo") ; | |
| 		BOOST_CHECK_EQUAL( gettext(token, data), L"foo" ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(TestTokenIfEqualsFalse) | |
| 	{ | |
| 		token_vector children ; | |
| 		children.push_back(token_ptr(new TokenVar(L"item"))) ; | |
| 		token_ptr token(new TokenIf(L"if item == \"bar\"")) ; | |
| 		token->set_children(children) ; | |
| 		data_map data ; | |
| 		data[L"item"] = make_data(L"foo") ; | |
| 		BOOST_CHECK_EQUAL( gettext(token, data), L"" ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(TestTokenIfEqualsTwoVarsTrue) | |
| 	{ | |
| 		token_vector children ; | |
| 		children.push_back(token_ptr(new TokenVar(L"item"))) ; | |
| 		token_ptr token(new TokenIf(L"if item == foo")) ; | |
| 		token->set_children(children) ; | |
| 		data_map data ; | |
| 		data[L"item"] = make_data(L"x") ; | |
| 		data[L"foo"] = make_data(L"x") ; | |
| 		BOOST_CHECK_EQUAL( gettext(token, data), L"x" ) ; | |
| 	} | |
| 
 | |
| 	// != | |
| 	BOOST_AUTO_TEST_CASE(TestTokenIfNotEqualsTrue) | |
| 	{ | |
| 		token_vector children ; | |
| 		children.push_back(token_ptr(new TokenVar(L"item"))) ; | |
| 		token_ptr token(new TokenIf(L"if item != \"foo\"")) ; | |
| 		token->set_children(children) ; | |
| 		data_map data ; | |
| 		data[L"item"] = make_data(L"foo") ; | |
| 		BOOST_CHECK_EQUAL( gettext(token, data), L"" ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(TestTokenIfNotEqualsFalse) | |
| 	{ | |
| 		token_vector children ; | |
| 		children.push_back(token_ptr(new TokenVar(L"item"))) ; | |
| 		token_ptr token(new TokenIf(L"if item != \"bar\"")) ; | |
| 		token->set_children(children) ; | |
| 		data_map data ; | |
| 		data[L"item"] = make_data(L"foo") ; | |
| 		BOOST_CHECK_EQUAL( gettext(token, data), L"foo" ) ; | |
| 	} | |
| 
 | |
| 	// not | |
| 	BOOST_AUTO_TEST_CASE(TestTokenIfNotTrueText) | |
| 	{ | |
| 		token_vector children ; | |
| 		children.push_back(token_ptr(new TokenText(L"{--}"))) ; | |
| 		token_ptr token(new TokenIf(L"if not item")) ; | |
| 		token->set_children(children) ; | |
| 		data_map data ; | |
| 		data[L"item"] = make_data(L"foo") ; | |
| 		BOOST_CHECK_EQUAL( gettext(token, data), L"") ; | |
| 	} | |
| 
 | |
| 	BOOST_AUTO_TEST_CASE(TestTokenIfNotFalseText) | |
| 	{ | |
| 		token_vector children ; | |
| 		children.push_back(token_ptr(new TokenText(L"{--}"))) ; | |
| 		token_ptr token(new TokenIf(L"if not item")) ; | |
| 		token->set_children(children) ; | |
| 		data_map data ; | |
| 		data[L"item"] = make_data(L"") ; | |
| 		BOOST_CHECK_EQUAL( gettext(token, data), L"{--}") ; | |
| 	} | |
| 
 | |
| 	// TokenEnd | |
| 	BOOST_AUTO_TEST_CASE(TestTokenEndFor) | |
| 	{ | |
| 		TokenEnd token(L"endfor") ; | |
| 		BOOST_CHECK_EQUAL( token.gettype(), TOKEN_TYPE_ENDFOR ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(TestTokenEndIf) | |
| 	{ | |
| 		TokenEnd token(L"endif") ; | |
| 		BOOST_CHECK_EQUAL( token.gettype(), TOKEN_TYPE_ENDIF ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(TestTokenEndIfCantHaveChildren) | |
| 	{ | |
| 		TokenEnd token(L"endif") ; | |
| 		token_vector children ; | |
| 		BOOST_CHECK_THROW(token.set_children(children), TemplateException) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(test_throws_on_gettext) | |
| 	{ | |
| 		data_map data ; | |
| 		token_ptr token(new TokenEnd(L"endif")) ; | |
| 
 | |
| 		BOOST_CHECK_THROW(gettext(token, data), TemplateException) ; | |
| 	} | |
| BOOST_AUTO_TEST_SUITE_END() | |
| 
 | |
| BOOST_AUTO_TEST_SUITE( TestCppTokenize ) | |
| 
 | |
| 	using namespace cpptempl ; | |
| 
 | |
| 	BOOST_AUTO_TEST_CASE(test_empty) | |
| 	{ | |
| 		wstring text = L"" ; | |
| 		token_vector tokens ; | |
| 		tokenize(text, tokens) ; | |
| 
 | |
| 		BOOST_CHECK_EQUAL( 0u, tokens.size() ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(test_text_only) | |
| 	{ | |
| 		wstring text = L"blah blah blah" ; | |
| 		token_vector tokens ; | |
| 		tokenize(text, tokens) ; | |
| 		data_map data ; | |
| 
 | |
| 		BOOST_CHECK_EQUAL( 1u, tokens.size() ) ; | |
| 		BOOST_CHECK_EQUAL( gettext(tokens[0], data), L"blah blah blah" ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(test_brackets_no_var) | |
| 	{ | |
| 		wstring text = L"{foo}" ; | |
| 		token_vector tokens ; | |
| 		tokenize(text, tokens) ; | |
| 		data_map data ; | |
| 
 | |
| 		BOOST_CHECK_EQUAL( 2u, tokens.size() ) ; | |
| 		BOOST_CHECK_EQUAL( gettext(tokens[0], data), L"{" ) ; | |
| 		BOOST_CHECK_EQUAL( gettext(tokens[1], data), L"foo}" ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(test_ends_with_bracket) | |
| 	{ | |
| 		wstring text = L"blah blah blah{" ; | |
| 		token_vector tokens ; | |
| 		tokenize(text, tokens) ; | |
| 		data_map data ; | |
| 
 | |
| 		BOOST_CHECK_EQUAL( 2u, tokens.size() ) ; | |
| 		BOOST_CHECK_EQUAL( gettext(tokens[0], data), L"blah blah blah" ) ; | |
| 		BOOST_CHECK_EQUAL( gettext(tokens[1], data), L"{" ) ; | |
| 	} | |
| 	// var | |
| 	BOOST_AUTO_TEST_CASE(test_var) | |
| 	{ | |
| 		wstring text = L"{$foo}" ; | |
| 		token_vector tokens ; | |
| 		tokenize(text, tokens) ; | |
| 		data_map data ; | |
| 		data[L"foo"] = make_data(L"bar") ; | |
| 
 | |
| 		BOOST_CHECK_EQUAL( 1u, tokens.size() ) ; | |
| 		BOOST_CHECK_EQUAL( gettext(tokens[0], data), L"bar" ) ; | |
| 	} | |
| 	// for | |
| 	BOOST_AUTO_TEST_CASE(test_for) | |
| 	{ | |
| 		wstring text = L"{% for item in items %}" ; | |
| 		token_vector tokens ; | |
| 		tokenize(text, tokens) ; | |
| 
 | |
| 		BOOST_CHECK_EQUAL( 1u, tokens.size() ) ; | |
| 		BOOST_CHECK_EQUAL( tokens[0]->gettype(), TOKEN_TYPE_FOR ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(test_for_full) | |
| 	{ | |
| 		wstring text = L"{% for item in items %}{$item}{% endfor %}" ; | |
| 		token_vector tokens ; | |
| 		tokenize(text, tokens) ; | |
| 
 | |
| 		BOOST_CHECK_EQUAL( 3u, tokens.size() ) ; | |
| 		BOOST_CHECK_EQUAL( tokens[0]->gettype(), TOKEN_TYPE_FOR ) ; | |
| 		BOOST_CHECK_EQUAL( tokens[1]->gettype(), TOKEN_TYPE_VAR ) ; | |
| 		BOOST_CHECK_EQUAL( tokens[2]->gettype(), TOKEN_TYPE_ENDFOR ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(test_for_full_with_text) | |
| 	{ | |
| 		wstring text = L"{% for item in items %}*{$item}*{% endfor %}" ; | |
| 		token_vector tokens ; | |
| 		tokenize(text, tokens) ; | |
| 		data_map data ; | |
| 		data[L"item"] = make_data(L"my ax") ; | |
| 
 | |
| 		BOOST_CHECK_EQUAL( 5u, tokens.size() ) ; | |
| 		BOOST_CHECK_EQUAL( tokens[0]->gettype(), TOKEN_TYPE_FOR ) ; | |
| 		BOOST_CHECK_EQUAL( gettext(tokens[1], data), L"*" ) ; | |
| 		BOOST_CHECK_EQUAL( tokens[2]->gettype(), TOKEN_TYPE_VAR ) ; | |
| 		BOOST_CHECK_EQUAL( gettext(tokens[2], data), L"my ax" ) ; | |
| 		BOOST_CHECK_EQUAL( gettext(tokens[3], data), L"*" ) ; | |
| 		BOOST_CHECK_EQUAL( tokens[4]->gettype(), TOKEN_TYPE_ENDFOR ) ; | |
| 	} | |
| 	// if | |
| 	BOOST_AUTO_TEST_CASE(test_if) | |
| 	{ | |
| 		wstring text = L"{% if foo %}" ; | |
| 		token_vector tokens ; | |
| 		tokenize(text, tokens) ; | |
| 
 | |
| 		BOOST_CHECK_EQUAL( 1u, tokens.size() ) ; | |
| 		BOOST_CHECK_EQUAL( tokens[0]->gettype(), TOKEN_TYPE_IF ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(test_if_full) | |
| 	{ | |
| 		wstring text = L"{% if item %}{$item}{% endif %}" ; | |
| 		token_vector tokens ; | |
| 		tokenize(text, tokens) ; | |
| 
 | |
| 		BOOST_CHECK_EQUAL( 3u, tokens.size() ) ; | |
| 		BOOST_CHECK_EQUAL( tokens[0]->gettype(), TOKEN_TYPE_IF ) ; | |
| 		BOOST_CHECK_EQUAL( tokens[1]->gettype(), TOKEN_TYPE_VAR ) ; | |
| 		BOOST_CHECK_EQUAL( tokens[2]->gettype(), TOKEN_TYPE_ENDIF ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(test_if_full_with_text) | |
| 	{ | |
| 		wstring text = L"{% if item %}{{$item}}{% endif %}" ; | |
| 		token_vector tokens ; | |
| 		tokenize(text, tokens) ; | |
| 		data_map data ; | |
| 		data[L"item"] = make_data(L"my ax") ; | |
| 
 | |
| 		BOOST_CHECK_EQUAL( 5u, tokens.size() ) ; | |
| 		BOOST_CHECK_EQUAL( tokens[0]->gettype(), TOKEN_TYPE_IF ) ; | |
| 		BOOST_CHECK_EQUAL( gettext(tokens[1], data), L"{" ) ; | |
| 		BOOST_CHECK_EQUAL( tokens[2]->gettype(), TOKEN_TYPE_VAR ) ; | |
| 		BOOST_CHECK_EQUAL( gettext(tokens[2], data), L"my ax" ) ; | |
| 		BOOST_CHECK_EQUAL( gettext(tokens[3], data), L"}" ) ; | |
| 		BOOST_CHECK_EQUAL( tokens[4]->gettype(), TOKEN_TYPE_ENDIF ) ; | |
| 	} | |
| 
 | |
| BOOST_AUTO_TEST_SUITE_END() | |
| 
 | |
| 
 | |
| BOOST_AUTO_TEST_SUITE( test_parse_tree ) | |
| 
 | |
| 	using namespace cpptempl ; | |
| 
 | |
| 	token_ptr make_tt(wstring text) | |
| 	{ | |
| 		return token_ptr(new TokenText(text)) ; | |
| 	} | |
| 	token_ptr make_for(wstring text) | |
| 	{ | |
| 		return token_ptr(new TokenFor(text)) ; | |
| 	} | |
| 	token_ptr make_if(wstring text) | |
| 	{ | |
| 		return token_ptr(new TokenIf(text)) ; | |
| 	} | |
| 	token_ptr make_endfor() | |
| 	{ | |
| 		return token_ptr(new TokenEnd(L"endfor")) ; | |
| 	} | |
| 	token_ptr make_endif() | |
| 	{ | |
| 		return token_ptr(new TokenEnd(L"endif")) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(test_empty) | |
| 	{ | |
| 		token_vector tokens ; | |
| 		token_vector tree ; | |
| 		parse_tree(tokens, tree) ; | |
| 		BOOST_CHECK_EQUAL( 0u, tree.size() ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(test_one) | |
| 	{ | |
| 		token_vector tokens ; | |
| 		tokens.push_back(make_tt(L"foo")) ; | |
| 		token_vector tree ; | |
| 		parse_tree(tokens, tree) ; | |
| 		BOOST_CHECK_EQUAL( 1u, tree.size() ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(test_for) | |
| 	{ | |
| 		token_vector tokens ; | |
| 		tokens.push_back(make_for(L"for item in items")) ; | |
| 		tokens.push_back(make_tt(L"foo")) ; | |
| 		tokens.push_back(make_endfor()) ; | |
| 		token_vector tree ; | |
| 		parse_tree(tokens, tree) ; | |
| 		BOOST_CHECK_EQUAL( 1u, tree.size() ) ; | |
| 		BOOST_CHECK_EQUAL( 1u, tree[0]->get_children().size()) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(test_if) | |
| 	{ | |
| 		token_vector tokens ; | |
| 		tokens.push_back(make_if(L"if insane")) ; | |
| 		tokens.push_back(make_tt(L"foo")) ; | |
| 		tokens.push_back(make_endif()) ; | |
| 		token_vector tree ; | |
| 		parse_tree(tokens, tree) ; | |
| 		BOOST_CHECK_EQUAL( 1u, tree.size() ) ; | |
| 		BOOST_CHECK_EQUAL( 1u, tree[0]->get_children().size()) ; | |
| 	} | |
| BOOST_AUTO_TEST_SUITE_END() | |
| 
 | |
| BOOST_AUTO_TEST_SUITE(TestCppParse) | |
| 
 | |
| 	using namespace cpptempl ; | |
| 
 | |
| 	BOOST_AUTO_TEST_CASE(test_empty) | |
| 	{ | |
| 		wstring text = L"" ; | |
| 		data_map data ; | |
| 		wstring actual = parse(text, data) ; | |
| 		wstring expected = L"" ; | |
| 		BOOST_CHECK_EQUAL( expected, actual ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(test_no_vars) | |
| 	{ | |
| 		wstring text = L"foo" ; | |
| 		data_map data ; | |
| 		wstring actual = parse(text, data) ; | |
| 		wstring expected = L"foo" ; | |
| 		BOOST_CHECK_EQUAL( expected, actual ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(test_var) | |
| 	{ | |
| 		wstring text = L"{$foo}" ; | |
| 		data_map data ; | |
| 		data[L"foo"] = make_data(L"bar") ; | |
| 		wstring actual = parse(text, data) ; | |
| 		wstring expected = L"bar" ; | |
| 		BOOST_CHECK_EQUAL( expected, actual ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(test_var_surrounded) | |
| 	{ | |
| 		wstring text = L"aaa{$foo}bbb" ; | |
| 		data_map data ; | |
| 		data[L"foo"] = make_data(L"---") ; | |
| 		wstring actual = parse(text, data) ; | |
| 		wstring expected = L"aaa---bbb" ; | |
| 		BOOST_CHECK_EQUAL( expected, actual ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(test_for) | |
| 	{ | |
| 		wstring text = L"{% for item in items %}{$item}{% endfor %}" ; | |
| 		data_map data ; | |
| 		data_list items ; | |
| 		items.push_back(make_data(L"0")) ; | |
| 		items.push_back(make_data(L"1")) ; | |
| 		data[L"items"] = make_data(items) ; | |
| 		wstring actual = parse(text, data) ; | |
| 		wstring expected = L"01" ; | |
| 		BOOST_CHECK_EQUAL( expected, actual ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(test_if_false) | |
| 	{ | |
| 		wstring text = L"{% if item %}{$item}{% endif %}" ; | |
| 		data_map data ; | |
| 		data[L"item"] = make_data(L"") ; | |
| 		wstring actual = parse(text, data) ; | |
| 		wstring expected = L"" ; | |
| 		BOOST_CHECK_EQUAL( expected, actual ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(test_if_true) | |
| 	{ | |
| 		wstring text = L"{% if item %}{$item}{% endif %}" ; | |
| 		data_map data ; | |
| 		data[L"item"] = make_data(L"foo") ; | |
| 		wstring actual = parse(text, data) ; | |
| 		wstring expected = L"foo" ; | |
| 		BOOST_CHECK_EQUAL( expected, actual ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(test_nested_for) | |
| 	{ | |
| 		wstring text = L"{% for item in items %}{% for thing in things %}{$item}{$thing}{% endfor %}{% endfor %}" ; | |
| 		data_map data ; | |
| 		data_list items ; | |
| 		items.push_back(make_data(L"0")) ; | |
| 		items.push_back(make_data(L"1")) ; | |
| 		data[L"items"] = make_data(items) ; | |
| 		data_list things ; | |
| 		things.push_back(make_data(L"a")) ; | |
| 		things.push_back(make_data(L"b")) ; | |
| 		data[L"things"] = make_data(things) ; | |
| 		wstring actual = parse(text, data) ; | |
| 		wstring expected = L"0a0b1a1b" ; | |
| 		BOOST_CHECK_EQUAL( expected, actual ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(test_nested_if_false) | |
| 	{ | |
| 		wstring text = L"{% if item %}{% if thing %}{$item}{$thing}{% endif %}{% endif %}" ; | |
| 		data_map data ; | |
| 		data[L"item"] = make_data(L"aaa") ; | |
| 		data[L"thing"] = make_data(L"") ; | |
| 		wstring actual = parse(text, data) ; | |
| 		wstring expected = L"" ; | |
| 		BOOST_CHECK_EQUAL( expected, actual ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(test_nested_if_true) | |
| 	{ | |
| 		wstring text = L"{% if item %}{% if thing %}{$item}{$thing}{% endif %}{% endif %}" ; | |
| 		data_map data ; | |
| 		data[L"item"] = make_data(L"aaa") ; | |
| 		data[L"thing"] = make_data(L"bbb") ; | |
| 		wstring actual = parse(text, data) ; | |
| 		wstring expected = L"aaabbb" ; | |
| 		BOOST_CHECK_EQUAL( expected, actual ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(test_usage_example) | |
| 	{ | |
| 		wstring text = L"{% if item %}{$item}{% endif %}\n" | |
| 			L"{% if thing %}{$thing}{% endif %}" ; | |
| 		cpptempl::data_map data ; | |
| 		data[L"item"] = cpptempl::make_data(L"aaa") ; | |
| 		data[L"thing"] = cpptempl::make_data(L"bbb") ; | |
| 
 | |
| 		wstring result = cpptempl::parse(text, data) ; | |
| 
 | |
| 		wstring expected = L"aaa\nbbb" ; | |
| 		BOOST_CHECK_EQUAL( result, expected ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(test_syntax_if) | |
| 	{ | |
| 		wstring text = L"{% if person.name == \"Bob\" %}Full name: Robert{% endif %}" ; | |
| 		data_map person ; | |
| 		person[L"name"] = make_data(L"Bob") ; | |
| 		person[L"occupation"] = make_data(L"Plumber") ; | |
| 		data_map data ; | |
| 		data[L"person"] = make_data(person) ; | |
| 
 | |
| 		wstring result = cpptempl::parse(text, data) ; | |
| 
 | |
| 		wstring expected = L"Full name: Robert" ; | |
| 		BOOST_CHECK_EQUAL( result, expected ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(test_syntax_dotted) | |
| 	{ | |
| 		wstring text = L"{% for friend in person.friends %}" | |
| 			L"{$loop.index}. {$friend.name} " | |
| 			L"{% endfor %}" ; | |
| 
 | |
| 		data_map bob ; | |
| 		bob[L"name"] = make_data(L"Bob") ; | |
| 		data_map betty ; | |
| 		betty[L"name"] = make_data(L"Betty") ; | |
| 		data_list friends ; | |
| 		friends.push_back(make_data(bob)) ; | |
| 		friends.push_back(make_data(betty)) ; | |
| 		data_map person ; | |
| 		person[L"friends"] = make_data(friends) ; | |
| 		data_map data ; | |
| 		data[L"person"] = make_data(person) ; | |
| 
 | |
| 		wstring result = cpptempl::parse(text, data) ; | |
| 
 | |
| 		wstring expected = L"1. Bob 2. Betty " ; | |
| 		BOOST_CHECK_EQUAL( result, expected ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(test_example_okinawa) | |
| 	{ | |
| 		// The text template | |
| 		wstring text = L"I heart {$place}!" ; | |
| 		// Data to feed the template engine | |
| 		cpptempl::data_map data ; | |
| 		// {$place} => Okinawa | |
| 		data[L"place"] = cpptempl::make_data(L"Okinawa"); | |
| 		// parse the template with the supplied data dictionary | |
| 		wstring result = cpptempl::parse(text, data) ; | |
| 
 | |
| 		wstring expected = L"I heart Okinawa!" ; | |
| 		BOOST_CHECK_EQUAL( result, expected ) ; | |
| 	} | |
| 	BOOST_AUTO_TEST_CASE(test_example_ul) | |
| 	{ | |
| 		wstring text = L"<h3>Locations</h3><ul>" | |
| 			L"{% for place in places %}" | |
| 			L"<li>{$place}</li>" | |
| 			L"{% endfor %}" | |
| 			L"</ul>" ; | |
| 
 | |
| 		// Create the list of items | |
| 		cpptempl::data_list places; | |
| 		places.push_back(cpptempl::make_data(L"Okinawa")); | |
| 		places.push_back(cpptempl::make_data(L"San Francisco")); | |
| 		// Now set this in the data map | |
| 		cpptempl::data_map data ; | |
| 		data[L"places"] = cpptempl::make_data(places); | |
| 		// parse the template with the supplied data dictionary | |
| 		wstring result = cpptempl::parse(text, data) ; | |
| 		wstring expected = L"<h3>Locations</h3><ul>" | |
| 			L"<li>Okinawa</li>" | |
| 			L"<li>San Francisco</li>" | |
| 			L"</ul>" ; | |
| 		BOOST_CHECK_EQUAL(result, expected) ; | |
| 	} | |
| BOOST_AUTO_TEST_SUITE_END() | |
| 
 | |
| #endif
 |