2009-10-10 21:36:03 +00:00
# ifndef HEADER_TEST_HPP
# define HEADER_TEST_HPP
2009-10-29 08:11:22 +00:00
# include "../src/pugixml.hpp"
# if (defined(_MSC_VER) && _MSC_VER==1200) || defined(__DMC__)
typedef int intptr_t ;
# endif
2009-10-10 21:58:44 +00:00
# include <string.h>
2009-10-11 06:49:30 +00:00
# include <math.h>
2009-10-28 21:15:05 +00:00
# include <float.h>
2009-10-29 08:11:22 +00:00
# include <setjmp.h>
2009-10-11 10:24:12 +00:00
2009-10-29 21:47:37 +00:00
# if defined(__MWERKS__) || defined(__BORLANDC__)
# include <stdint.h> // intptr_t
# endif
2009-10-29 08:11:22 +00:00
# include <string>
2009-10-10 21:58:44 +00:00
inline bool test_string_equal ( const char * lhs , const char * rhs )
{
return ( ! lhs | | ! rhs ) ? lhs = = rhs : strcmp ( lhs , rhs ) = = 0 ;
}
2009-10-11 06:49:30 +00:00
template < typename Node > inline bool test_node_name_value ( const Node & node , const char * name , const char * value )
{
return test_string_equal ( node . name ( ) , name ) & & test_string_equal ( node . value ( ) , value ) ;
}
2009-10-29 07:17:30 +00:00
struct xml_writer_string : public pugi : : xml_writer
{
std : : string result ;
virtual void write ( const void * data , size_t size )
{
result + = std : : string ( static_cast < const char * > ( data ) , size ) ;
}
} ;
2009-10-12 16:26:18 +00:00
inline bool test_node ( const pugi : : xml_node & node , const char * contents , const char * indent , unsigned int flags )
2009-10-11 10:24:12 +00:00
{
2009-10-29 07:17:30 +00:00
xml_writer_string writer ;
node . print ( writer , indent , flags ) ;
2009-10-11 10:24:12 +00:00
2009-10-29 07:17:30 +00:00
return writer . result = = contents ;
2009-10-11 10:24:12 +00:00
}
2009-10-29 07:17:30 +00:00
# ifndef PUGIXML_NO_XPATH
2009-10-21 19:09:12 +00:00
inline bool test_xpath_string ( const pugi : : xml_node & node , const char * query , const char * expected )
{
pugi : : xpath_query q ( query ) ;
return q . evaluate_string ( node ) = = expected ;
}
inline bool test_xpath_boolean ( const pugi : : xml_node & node , const char * query , bool expected )
{
pugi : : xpath_query q ( query ) ;
return q . evaluate_boolean ( node ) = = expected ;
}
inline bool test_xpath_number ( const pugi : : xml_node & node , const char * query , double expected )
{
pugi : : xpath_query q ( query ) ;
2009-10-27 20:16:08 +00:00
return fabs ( q . evaluate_number ( node ) - expected ) < 1e-16 f ;
2009-10-21 19:09:12 +00:00
}
2009-10-21 20:37:54 +00:00
inline bool test_xpath_number_nan ( const pugi : : xml_node & node , const char * query )
{
pugi : : xpath_query q ( query ) ;
double r = q . evaluate_number ( node ) ;
2009-10-29 21:47:37 +00:00
# if defined(_MSC_VER) || defined(__BORLANDC__)
2009-10-28 21:15:05 +00:00
return _isnan ( r ) ! = 0 ;
# else
2009-10-21 20:37:54 +00:00
return r ! = r ;
2009-10-28 21:15:05 +00:00
# endif
2009-10-21 20:37:54 +00:00
}
2009-10-21 19:09:12 +00:00
inline bool test_xpath_fail_compile ( const char * query )
{
try
{
pugi : : xpath_query q ( query ) ;
return false ;
}
2009-10-27 21:56:49 +00:00
catch ( const pugi : : xpath_exception & )
2009-10-21 19:09:12 +00:00
{
return true ;
}
}
2009-10-29 07:17:30 +00:00
# endif
2009-10-21 19:09:12 +00:00
2009-10-10 21:36:03 +00:00
struct test_runner
{
test_runner ( const char * name )
{
_name = name ;
_next = _tests ;
_tests = this ;
}
virtual ~ test_runner ( ) { }
virtual void run ( ) = 0 ;
const char * _name ;
test_runner * _next ;
static test_runner * _tests ;
2009-10-20 21:36:29 +00:00
static size_t _memory_fail_threshold ;
2009-10-29 08:11:22 +00:00
static jmp_buf _failure ;
2009-10-10 21:36:03 +00:00
} ;
struct dummy_fixture { } ;
# define TEST_FIXTURE(name, fixture) \
struct test_runner_helper_ # # name : fixture \
{ \
void run ( ) ; \
} ; \
static struct test_runner_ # # name : test_runner \
{ \
test_runner_ # # name ( ) : test_runner ( # name ) { } \
\
virtual void run ( ) \
{ \
test_runner_helper_ # # name helper ; \
helper . run ( ) ; \
} \
} test_runner_instance_ # # name ; \
void test_runner_helper_ # # name : : run ( )
# define TEST(name) TEST_FIXTURE(name, dummy_fixture)
2009-10-11 06:49:30 +00:00
# define TEST_XML_FLAGS(name, xml, flags) \
2009-10-10 21:36:03 +00:00
struct test_fixture_ # # name \
{ \
pugi : : xml_document doc ; \
\
test_fixture_ # # name ( ) \
{ \
2009-10-11 06:49:30 +00:00
CHECK ( doc . load ( xml , flags ) ) ; \
2009-10-10 21:36:03 +00:00
} \
2009-10-28 20:08:19 +00:00
\
private : \
test_fixture_ # # name ( const test_fixture_ # # name & ) ; \
test_fixture_ # # name & operator = ( const test_fixture_ # # name & ) ; \
2009-10-10 21:36:03 +00:00
} ; \
\
TEST_FIXTURE ( name , test_fixture_ # # name )
2009-10-11 06:49:30 +00:00
# define TEST_XML(name, xml) TEST_XML_FLAGS(name, xml, pugi::parse_default)
2009-10-28 20:51:13 +00:00
# define CHECK_JOIN(text, file, line) text file #line
# define CHECK_JOIN2(text, file, line) CHECK_JOIN(text, file, line)
2009-10-29 08:11:22 +00:00
# define CHECK_TEXT(condition, text) if (condition) ; else longjmp(test_runner::_failure, (int)(intptr_t)(CHECK_JOIN2(text, " at "__FILE__ ":", __LINE__)))
2009-10-28 20:51:13 +00:00
2009-10-29 21:47:37 +00:00
# if (defined(_MSC_VER) && _MSC_VER == 1200) || defined(__MWERKS__)
# define STR(value) "??" // MSVC 6.0 and CodeWarrior have troubles stringizing stuff with strings w/escaping inside
2009-10-28 20:51:13 +00:00
# else
# define STR(value) #value
# endif
2009-10-12 16:26:18 +00:00
2009-10-28 20:51:13 +00:00
# define CHECK(condition) CHECK_TEXT(condition, STR(condition) " is false")
# define CHECK_STRING(value, expected) CHECK_TEXT(test_string_equal(value, expected), STR(value) " is not equal to " STR(expected))
# define CHECK_DOUBLE(value, expected) CHECK_TEXT(fabs(value - expected) < 1e-6, STR(value) " is not equal to " STR(expected))
# define CHECK_NAME_VALUE(node, name, value) CHECK_TEXT(test_node_name_value(node, name, value), STR(node) " name / value do not match " STR(name) " and " STR(value))
# define CHECK_NODE_EX(node, expected, indent, flags) CHECK_TEXT(test_node(node, expected, indent, flags), STR(node) " contents does not match " STR(expected))
2009-10-12 16:26:18 +00:00
# define CHECK_NODE(node, expected) CHECK_NODE_EX(node, expected, "", pugi::format_raw)
2009-10-10 21:36:03 +00:00
2009-10-29 07:17:30 +00:00
# ifndef PUGIXML_NO_XPATH
2009-10-28 20:51:13 +00:00
# define CHECK_XPATH_STRING(node, query, expected) CHECK_TEXT(test_xpath_string(node, query, expected), STR(query) " does not evaluate to " STR(expected) " in context " STR(node))
# define CHECK_XPATH_BOOLEAN(node, query, expected) CHECK_TEXT(test_xpath_boolean(node, query, expected), STR(query) " does not evaluate to " STR(expected) " in context " STR(node))
# define CHECK_XPATH_NUMBER(node, query, expected) CHECK_TEXT(test_xpath_number(node, query, expected), STR(query) " does not evaluate to " STR(expected) " in context " STR(node))
# define CHECK_XPATH_NUMBER_NAN(node, query) CHECK_TEXT(test_xpath_number_nan(node, query), STR(query) " does not evaluate to NaN in context " STR(node))
# define CHECK_XPATH_FAIL(query) CHECK_TEXT(test_xpath_fail_compile(query), STR(query) " should not compile")
2009-10-29 07:17:30 +00:00
# endif
2009-10-21 19:09:12 +00:00
2009-10-10 21:36:03 +00:00
# endif