2025-08-03 10:37:17 -07:00
/* Copyright (C) 2025 Wildfire Games.
2023-12-02 16:30:12 -08:00
* This file is part of 0 A . D .
2010-01-09 11:20:14 -08:00
*
2023-12-02 16:30:12 -08:00
* 0 A . D . is free software : you can redistribute it and / or modify
2010-01-09 11:20:14 -08:00
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 2 of the License , or
* ( at your option ) any later version .
*
2023-12-02 16:30:12 -08:00
* 0 A . D . is distributed in the hope that it will be useful ,
2010-01-09 11:20:14 -08:00
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
2023-12-02 16:30:12 -08:00
* along with 0 A . D . If not , see < http : //www.gnu.org/licenses/>.
2010-01-09 11:20:14 -08:00
*/
# include "lib/self_test.h"
2012-03-17 16:03:02 -07:00
# include "ps/CLogger.h"
2025-08-03 10:37:17 -07:00
# include "ps/Errors.h"
2010-01-09 11:20:14 -08:00
# include "ps/XML/Xeromyces.h"
2025-08-03 10:37:17 -07:00
# include "simulation2/system/Component.h"
2010-01-09 11:20:14 -08:00
2024-09-18 09:17:04 -07:00
# include <optional>
2025-08-03 10:37:17 -07:00
# include <string>
2024-09-18 09:17:04 -07:00
2010-01-09 11:20:14 -08:00
class TestParamNode : public CxxTest : : TestSuite
{
2024-09-18 09:17:04 -07:00
std : : optional < CXeromycesEngine > xeromycesEngine ;
2010-01-09 11:20:14 -08:00
public :
void setUp ( )
{
2024-09-18 09:17:04 -07:00
xeromycesEngine . emplace ( ) ;
2010-01-09 11:20:14 -08:00
}
void tearDown ( )
{
2024-09-18 09:17:04 -07:00
xeromycesEngine . reset ( ) ;
2010-01-09 11:20:14 -08:00
}
void test_basic ( )
{
CParamNode node ;
TS_ASSERT_EQUALS ( CParamNode : : LoadXMLString ( node , " <test> <Foo> 1 </Foo><Bar>2<Baz>3</Baz>4</Bar><Qux/></test> " ) , PSRETURN_OK ) ;
2010-02-02 15:01:17 -08:00
TS_ASSERT ( node . GetChild ( " test " ) . IsOk ( ) ) ;
TS_ASSERT ( ! node . GetChild ( " Test " ) . IsOk ( ) ) ;
2021-04-11 02:23:10 -07:00
TS_ASSERT_STR_EQUALS ( node . GetChild ( " test " ) . ToString ( ) , " " ) ;
2010-02-02 15:01:17 -08:00
TS_ASSERT ( node . GetChild ( " test " ) . GetChild ( " Foo " ) . IsOk ( ) ) ;
TS_ASSERT_EQUALS ( node . GetChild ( " test " ) . GetChild ( " Foo " ) . ToInt ( ) , 1 ) ;
2021-04-11 02:23:10 -07:00
TS_ASSERT_STR_EQUALS ( node . GetChild ( " test " ) . GetChild ( " Foo " ) . ToString ( ) , " 1 " ) ;
2010-02-02 15:01:17 -08:00
TS_ASSERT_EQUALS ( node . GetChild ( " test " ) . GetChild ( " Bar " ) . ToInt ( ) , 24 ) ;
2021-04-11 02:23:10 -07:00
TS_ASSERT_STR_EQUALS ( node . GetChild ( " test " ) . GetChild ( " Bar " ) . ToString ( ) , " 24 " ) ;
2010-02-02 15:01:17 -08:00
TS_ASSERT_EQUALS ( node . GetChild ( " test " ) . GetChild ( " Bar " ) . GetChild ( " Baz " ) . ToInt ( ) , 3 ) ;
TS_ASSERT ( node . GetChild ( " test " ) . GetChild ( " Qux " ) . IsOk ( ) ) ;
TS_ASSERT ( ! node . GetChild ( " test " ) . GetChild ( " Qux " ) . GetChild ( " Baz " ) . IsOk ( ) ) ;
2022-12-29 23:34:23 -08:00
TS_ASSERT_STR_EQUALS ( node . GetChild ( " test " ) . ToXMLString ( ) , node . GetOnlyChild ( ) . ToXMLString ( ) ) ;
2010-02-02 15:01:17 -08:00
CParamNode nullOne ( false ) ;
CParamNode nullTwo = nullOne ;
CParamNode nullThree ( nullOne ) ;
TS_ASSERT ( ! nullOne . IsOk ( ) ) ;
TS_ASSERT ( ! nullTwo . IsOk ( ) ) ;
TS_ASSERT ( ! nullThree . IsOk ( ) ) ;
2021-04-11 02:23:10 -07:00
TS_ASSERT_STR_EQUALS ( nullOne . ToString ( ) , " " ) ;
2010-02-02 15:01:17 -08:00
TS_ASSERT ( nullOne . ToInt ( ) = = 0 ) ;
TS_ASSERT ( nullOne . ToFixed ( ) . ToDouble ( ) = = 0 ) ;
2010-01-09 11:20:14 -08:00
}
void test_attrs ( )
{
CParamNode node ;
TS_ASSERT_EQUALS ( CParamNode : : LoadXMLString ( node , " <test x='1' y='2'> <z>3</z> <w a='4'/></test> " ) , PSRETURN_OK ) ;
2010-02-02 15:01:17 -08:00
TS_ASSERT ( node . GetChild ( " test " ) . IsOk ( ) ) ;
TS_ASSERT ( node . GetChild ( " test " ) . GetChild ( " @x " ) . IsOk ( ) ) ;
TS_ASSERT ( node . GetChild ( " test " ) . GetChild ( " @y " ) . IsOk ( ) ) ;
TS_ASSERT ( node . GetChild ( " test " ) . GetChild ( " z " ) . IsOk ( ) ) ;
TS_ASSERT ( node . GetChild ( " test " ) . GetChild ( " w " ) . IsOk ( ) ) ;
TS_ASSERT ( node . GetChild ( " test " ) . GetChild ( " w " ) . GetChild ( " @a " ) . IsOk ( ) ) ;
TS_ASSERT_EQUALS ( node . GetChild ( " test " ) . GetChild ( " @x " ) . ToInt ( ) , 1 ) ;
TS_ASSERT_EQUALS ( node . GetChild ( " test " ) . GetChild ( " @y " ) . ToInt ( ) , 2 ) ;
TS_ASSERT_EQUALS ( node . GetChild ( " test " ) . GetChild ( " z " ) . ToInt ( ) , 3 ) ;
TS_ASSERT_EQUALS ( node . GetChild ( " test " ) . GetChild ( " w " ) . GetChild ( " @a " ) . ToInt ( ) , 4 ) ;
2010-01-09 11:20:14 -08:00
}
2021-04-11 02:23:10 -07:00
void test_ToXMLString ( )
2010-01-09 11:20:14 -08:00
{
CParamNode node ;
TS_ASSERT_EQUALS ( CParamNode : : LoadXMLString ( node , " <test x='1' y='2'> <z>3</z> <w a='4'/></test> " ) , PSRETURN_OK ) ;
2021-04-11 02:23:10 -07:00
TS_ASSERT_STR_EQUALS ( node . ToXMLString ( ) , " <test x= \" 1 \" y= \" 2 \" ><w a= \" 4 \" ></w><z>3</z></test> " ) ;
2010-01-09 11:20:14 -08:00
}
2010-02-12 14:48:16 -08:00
void test_overlay_basic ( )
{
CParamNode node ;
TS_ASSERT_EQUALS ( CParamNode : : LoadXMLString ( node , " <test x='1' y='2'> <a>3</a> <b>4</b> </test> " ) , PSRETURN_OK ) ;
TS_ASSERT_EQUALS ( CParamNode : : LoadXMLString ( node , " <test y='5' z='6'> <b>7</b> <c>8</c> </test> " ) , PSRETURN_OK ) ;
2021-04-11 02:23:10 -07:00
TS_ASSERT_STR_EQUALS ( node . ToXMLString ( ) , " <test x= \" 1 \" y= \" 5 \" z= \" 6 \" ><a>3</a><b>7</b><c>8</c></test> " ) ;
2010-02-12 14:48:16 -08:00
}
void test_overlay_disable ( )
{
CParamNode node ;
TS_ASSERT_EQUALS ( CParamNode : : LoadXMLString ( node , " <test> <a>1</a> <b>2</b> </test> " ) , PSRETURN_OK ) ;
TS_ASSERT_EQUALS ( CParamNode : : LoadXMLString ( node , " <test> <a disable=''/> <c disable=''/> </test> " ) , PSRETURN_OK ) ;
2021-04-11 02:23:10 -07:00
TS_ASSERT_STR_EQUALS ( node . ToXMLString ( ) , " <test><b>2</b></test> " ) ;
2010-02-12 14:48:16 -08:00
}
2010-04-09 11:43:50 -07:00
void test_overlay_replace ( )
{
CParamNode node ;
TS_ASSERT_EQUALS ( CParamNode : : LoadXMLString ( node , " <test> <a x='1'>2<b/></a> <c y='3'/></test> " ) , PSRETURN_OK ) ;
TS_ASSERT_EQUALS ( CParamNode : : LoadXMLString ( node , " <test> <a replace=''><d/></a> <e replace=''/> </test> " ) , PSRETURN_OK ) ;
2021-04-11 02:23:10 -07:00
TS_ASSERT_STR_EQUALS ( node . ToXMLString ( ) , " <test><a><d></d></a><c y= \" 3 \" ></c><e></e></test> " ) ;
2010-04-09 11:43:50 -07:00
}
2010-07-02 18:23:23 -07:00
void test_overlay_tokens ( )
{
CParamNode node ;
2011-07-07 10:05:22 -07:00
TS_ASSERT_EQUALS ( CParamNode : : LoadXMLString ( node , " <test> <a datatype='tokens'>x y</a><b datatype='tokens'>a b \n c \t d</b><c datatype='tokens'>m n</c></test> " ) , PSRETURN_OK ) ;
TS_ASSERT_EQUALS ( CParamNode : : LoadXMLString ( node , " <test> <a datatype='tokens'>-y z w</a><c datatype='tokens' replace=''>n o</c></test> " ) , PSRETURN_OK ) ;
2021-04-11 02:23:10 -07:00
TS_ASSERT_STR_EQUALS ( node . ToXMLString ( ) , " <test><a datatype= \" tokens \" >x z w</a><b datatype= \" tokens \" >a b c d</b><c datatype= \" tokens \" >n o</c></test> " ) ;
2010-07-02 18:23:23 -07:00
}
2012-03-15 15:57:08 -07:00
void test_overlay_remove_nonexistent_token ( )
{
// regression test; this used to cause a crash because of a failure to check whether the token being removed was present
2021-04-11 02:23:10 -07:00
TestLogger logger ;
2012-03-15 15:57:08 -07:00
CParamNode node ;
TS_ASSERT_EQUALS ( CParamNode : : LoadXMLString ( node , " <test> <a datatype='tokens'>-nonexistenttoken X</a></test> " ) , PSRETURN_OK ) ;
2021-04-11 02:23:10 -07:00
TS_ASSERT_STR_EQUALS ( node . ToXMLString ( ) , " <test><a datatype= \" tokens \" >X</a></test> " ) ;
2012-03-15 15:57:08 -07:00
}
void test_overlay_remove_empty_token ( )
{
2021-04-11 02:23:10 -07:00
TestLogger logger ;
2012-03-15 15:57:08 -07:00
CParamNode node ;
TS_ASSERT_EQUALS ( CParamNode : : LoadXMLString ( node , " <test> <a datatype='tokens'> Y - X </a></test> " ) , PSRETURN_OK ) ;
2021-04-11 02:23:10 -07:00
TS_ASSERT_STR_EQUALS ( node . ToXMLString ( ) , " <test><a datatype= \" tokens \" >Y X</a></test> " ) ;
2012-03-15 15:57:08 -07:00
}
2017-03-16 12:56:12 -07:00
void test_overlay_filtered ( )
{
CParamNode node ;
TS_ASSERT_EQUALS ( CParamNode : : LoadXMLString ( node , " <test> <a><b/></a> <c>toberemoved</c> <d><e/></d> </test> " ) , PSRETURN_OK ) ;
TS_ASSERT_EQUALS ( CParamNode : : LoadXMLString ( node , " <test filtered= \" \" > <a/> <d><f/></d> <g/> </test> " ) , PSRETURN_OK ) ;
2021-04-11 02:23:10 -07:00
TS_ASSERT_STR_EQUALS ( node . ToXMLString ( ) , " <test><a><b></b></a><d><e></e><f></f></d><g></g></test> " ) ;
2017-03-16 12:56:12 -07:00
CParamNode node2 ;
TS_ASSERT_EQUALS ( CParamNode : : LoadXMLString ( node2 , " <test> <a><b>b</b><c>c</c><d>d</d><e>e</e></a> <f/> </test> " ) , PSRETURN_OK ) ;
TS_ASSERT_EQUALS ( CParamNode : : LoadXMLString ( node2 , " <test filtered= \" \" > <a filtered= \" \" ><b merge= \" \" /><c>c2</c><d/></a> </test> " ) , PSRETURN_OK ) ;
2021-04-11 02:23:10 -07:00
TS_ASSERT_STR_EQUALS ( node2 . ToXMLString ( ) , " <test><a><b>b</b><c>c2</c><d></d></a></test> " ) ;
2017-03-16 12:56:12 -07:00
}
void test_overlay_merge ( )
{
CParamNode node ;
TS_ASSERT_EQUALS ( CParamNode : : LoadXMLString ( node , " <test> <a><b>foo</b><c>bar</c></a> <x><y><z>foo</z></y></x> </test> " ) , PSRETURN_OK ) ;
TS_ASSERT_EQUALS ( CParamNode : : LoadXMLString ( node , " <test> <a merge= \" \" ><b>test</b><d>baz</d></a> <i merge= \" \" ><j>willnotbeincluded</j></i> <x merge= \" \" ><y merge= \" \" ><v>text</v></y><w>more text</w></x> </test> " ) , PSRETURN_OK ) ;
2021-04-11 02:23:10 -07:00
TS_ASSERT_STR_EQUALS ( node . ToXMLString ( ) , " <test><a><b>test</b><c>bar</c><d>baz</d></a><x><w>more text</w><y><v>text</v><z>foo</z></y></x></test> " ) ;
}
void test_overlay_merge_empty ( )
{
// 'merge' nodes don't change the original value.
CParamNode node ;
TS_ASSERT_EQUALS ( CParamNode : : LoadXMLString ( node , " <test><a>foo</a><c>bar</c></test> " ) , PSRETURN_OK ) ;
TS_ASSERT_EQUALS ( CParamNode : : LoadXMLString ( node , " <test><a merge= \" \" /><b merge= \" \" >skipped</b><c merge= \" \" >replaced</c></test> " ) , PSRETURN_OK ) ;
TS_ASSERT_STR_EQUALS ( node . ToXMLString ( ) , " <test><a>foo</a><c>bar</c></test> " ) ;
2017-03-16 12:56:12 -07:00
}
void test_overlay_filtered_merge ( )
{
CParamNode node ;
TS_ASSERT_EQUALS ( CParamNode : : LoadXMLString ( node , " <test> <a><b/></a> <c><x/></c> <Health><Max>1200</Max></Health> </test> " ) , PSRETURN_OK ) ;
TS_ASSERT_EQUALS ( CParamNode : : LoadXMLString ( node , " <test filtered= \" \" > <c merge= \" \" /> <d>bar</d> <e merge= \" \" /> <Health><Initial>1</Initial></Health> </test> " ) , PSRETURN_OK ) ;
2021-04-11 02:23:10 -07:00
TS_ASSERT_STR_EQUALS ( node . ToXMLString ( ) , " <test><Health><Initial>1</Initial><Max>1200</Max></Health><c><x></x></c><d>bar</d></test> " ) ;
}
void test_overlay_ops ( )
{
CParamNode node ;
TS_ASSERT_EQUALS ( CParamNode : : LoadXMLString ( node , " <test><a>5</a><b>5</b><c>5</c></test> " ) , PSRETURN_OK ) ;
TS_ASSERT_EQUALS ( CParamNode : : LoadXMLString ( node , " <test><a op='add'>5</a><b op='mul'>3</b><c op='mul_round'>0.55</c></test> " ) , PSRETURN_OK ) ;
TS_ASSERT_STR_EQUALS ( node . ToXMLString ( ) , " <test><a>10</a><b>15</b><c>3</c></test> " ) ;
2017-03-16 12:56:12 -07:00
}
2010-01-09 11:20:14 -08:00
void test_types ( )
{
CParamNode node ;
TS_ASSERT_EQUALS ( CParamNode : : LoadXMLString ( node , " <test><n>+010.75</n><t>true</t></test> " ) , PSRETURN_OK ) ;
2010-02-02 15:01:17 -08:00
TS_ASSERT ( node . GetChild ( " test " ) . IsOk ( ) ) ;
TS_ASSERT ( node . GetChild ( " test " ) . GetChild ( " n " ) . IsOk ( ) ) ;
2021-04-11 02:23:10 -07:00
TS_ASSERT_EQUALS ( node . GetChild ( " test " ) . GetChild ( " n " ) . ToString ( ) , " +010.75 " ) ;
2010-02-02 15:01:17 -08:00
TS_ASSERT_EQUALS ( node . GetChild ( " test " ) . GetChild ( " n " ) . ToInt ( ) , 10 ) ;
TS_ASSERT_EQUALS ( node . GetChild ( " test " ) . GetChild ( " n " ) . ToFixed ( ) . ToDouble ( ) , 10.75 ) ;
TS_ASSERT_EQUALS ( node . GetChild ( " test " ) . GetChild ( " n " ) . ToBool ( ) , false ) ;
TS_ASSERT_EQUALS ( node . GetChild ( " test " ) . GetChild ( " t " ) . ToBool ( ) , true ) ;
2010-01-09 11:20:14 -08:00
}
void test_escape ( )
{
2021-04-11 02:23:10 -07:00
TS_ASSERT_STR_EQUALS ( CParamNode : : EscapeXMLString ( " test " ) , " test " ) ;
TS_ASSERT_STR_EQUALS ( CParamNode : : EscapeXMLString ( " x < y << z " ) , " x < y << z " ) ;
TS_ASSERT_STR_EQUALS ( CParamNode : : EscapeXMLString ( " x < y \" &' y > z ]]> " ) , " x < y "&' y > z ]]> " ) ;
TS_ASSERT_STR_EQUALS ( CParamNode : : EscapeXMLString ( " \r \n \t " ) , " 	 " ) ;
2010-01-09 11:20:14 -08:00
}
} ;