mirror of https://github.com/Gnucash/gnucash
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.
179 lines
6.4 KiB
179 lines
6.4 KiB
/********************************************************************\
|
|
* This program is free software; you can redistribute it and/or *
|
|
* modify 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. *
|
|
* *
|
|
* This program is distributed in the hope that it will be useful, *
|
|
* 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*
|
|
* along with this program; if not, contact: *
|
|
* *
|
|
* Free Software Foundation Voice: +1-617-542-5942 *
|
|
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
|
|
* Boston, MA 02110-1301, USA gnu@gnu.org *
|
|
* *
|
|
\********************************************************************/
|
|
#include <config.h>
|
|
|
|
#include <stdlib.h>
|
|
#include "gnc-engine.h"
|
|
|
|
#include "test-engine-stuff.h"
|
|
|
|
#include "test-file-stuff.h"
|
|
#include "sixtp-utils.h"
|
|
#include "sixtp-dom-parsers.h"
|
|
#include "sixtp-dom-generators.h"
|
|
#include "test-stuff.h"
|
|
|
|
#include <optional>
|
|
|
|
#define GNC_V2_STRING "gnc-v2"
|
|
const gchar* gnc_v2_xml_version_string = GNC_V2_STRING;
|
|
|
|
static const char* test_strings[] =
|
|
{
|
|
"FooBar",
|
|
"<Ugly crap>",
|
|
"Something with a & in it",
|
|
"Ugly(*!&@#$NTHOEAUTF\"ntaheu09.h,. \n\t",
|
|
"\n\t\n\t",
|
|
NULL
|
|
};
|
|
|
|
static void
|
|
test_string_converters (void)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; test_strings[i]; ++i)
|
|
{
|
|
const char* mark = test_strings[i];
|
|
xmlNodePtr test_node = text_to_dom_tree ("test-string", mark);
|
|
auto backout = dom_tree_to_text (test_node);
|
|
|
|
do_test_args (
|
|
g_strcmp0 (backout->c_str(), mark) == 0,
|
|
"string converting", __FILE__, __LINE__, "with string %s", mark);
|
|
|
|
xmlFreeNode (test_node);
|
|
}
|
|
}
|
|
|
|
static void
|
|
test_bad_string (void)
|
|
{
|
|
const char* badstr = "foo\abar";
|
|
const char* sanitized = "foo?bar";
|
|
xmlNodePtr test_node = text_to_dom_tree ("test-string", badstr);
|
|
|
|
auto backout = dom_tree_to_text (test_node);
|
|
do_test_args (g_strcmp0 (backout->c_str(), sanitized) == 0,
|
|
"string sanitizing", __FILE__, __LINE__,
|
|
"with string %s", badstr);
|
|
|
|
xmlFreeNode (test_node);
|
|
}
|
|
|
|
template <class T>
|
|
using TestcaseVec = std::vector<std::pair<const char*, std::optional<T>>>;
|
|
|
|
template <class T>
|
|
const TestcaseVec<T> test_cases_common = {
|
|
{ "1" , 1 },
|
|
{ " \t 2 \t\v\n\f\r " , 2 },
|
|
{ " 0 " , 0 },
|
|
{ "123" , 123 },
|
|
{ "123z" , {} },
|
|
{ "a123" , {} },
|
|
{ " 23" , 23 },
|
|
{ "\t23" , 23 },
|
|
{ "44 " , 44 },
|
|
{ "44\t" , 44 },
|
|
{ " 56 " , 56 },
|
|
{ "\t56\t" , 56 },
|
|
{ "1 2" , {} },
|
|
{ "1 2 \t" , {} },
|
|
};
|
|
|
|
const TestcaseVec<gint64> test_cases_gint64 = {
|
|
{ "-44" , -44 },
|
|
{ "9223372036854775807" , 9223372036854775807 }, // maxint64
|
|
{ "9223372036854775808" , {} }, // overflow
|
|
{ "-9223372036854775807" , -9223372036854775807 }, // minint64
|
|
};
|
|
|
|
const TestcaseVec<guint> test_cases_guint = {
|
|
{ "-44" , {} }, // no negative allowed
|
|
{ "4294967295" , 4294967295 }, // max_uint
|
|
{ "4294967296" , {} }, // overflow
|
|
};
|
|
|
|
const TestcaseVec<guint16> test_cases_guint16 = {
|
|
{ "-44" , {} }, // no negative allowed
|
|
{ "65535" , 65535 }, // max_int16
|
|
{ "65536" , {} }, // overflow
|
|
};
|
|
|
|
const TestcaseVec<double> test_cases_double = {
|
|
{ "-3.5" , -3.5 },
|
|
{ ".5" , 0.5 },
|
|
{ "1e10" , 1e10 },
|
|
{ "-1e10" , -1e10 },
|
|
{ "1e-10" , 1e-10 },
|
|
{ "-1e-10" , -1e-10 },
|
|
{ "1.7976931348623158e+308", 1.7976931348623158e+308 }, // max_double
|
|
{ "1.7976931348623159e+308", {} }, // overflow
|
|
};
|
|
|
|
template <typename T>
|
|
static void
|
|
test_string_to_num (const char *func_name, const TestcaseVec<T>& test_cases,
|
|
const std::function<bool(const char*,T*)> &func)
|
|
{
|
|
auto do_test = [&](std::pair<const char*, std::optional<T>> test_pair)
|
|
{
|
|
T num = 0;
|
|
auto [test_str, test_int] = test_pair;
|
|
auto rv = func (test_str, &num);
|
|
// Output for debugging
|
|
// std::cout << "test_str = [" << test_str << "], test_int = ";
|
|
// if (test_int)
|
|
// std::cout << *test_int;
|
|
// else
|
|
// std::cout << "{}";
|
|
// std::cout << ", num = [" << num << "], rv = " << rv << std::endl;
|
|
do_test_args (rv == test_int.has_value(), func_name,
|
|
__FILE__, __LINE__, "with string %s", test_str);
|
|
if (rv)
|
|
do_test_args (num == *test_int, func_name,
|
|
__FILE__, __LINE__, "with string %s", test_str);
|
|
};
|
|
|
|
std::for_each (test_cases_common<T>.begin(), test_cases_common<T>.end(), do_test);
|
|
std::for_each (test_cases.begin(), test_cases.end(), do_test);
|
|
}
|
|
|
|
int
|
|
main (int argc, char** argv)
|
|
{
|
|
qof_log_init ();
|
|
fflush (stdout);
|
|
test_string_converters ();
|
|
test_bad_string ();
|
|
#if __cpp_lib_to_chars >= 201611L
|
|
// because older strtod code is more liberal and parses "123z" as 123.0
|
|
test_string_to_num<double> ("string_to_double", test_cases_double, string_to_double);
|
|
#endif
|
|
test_string_to_num<gint64> ("string_to_gint64", test_cases_gint64, string_to_gint64);
|
|
test_string_to_num<guint16>("string_to_guint16",test_cases_guint16,string_to_guint16);
|
|
test_string_to_num<guint> ("string_to_guint", test_cases_guint, string_to_guint);
|
|
fflush (stdout);
|
|
print_test_results ();
|
|
exit (get_rv ());
|
|
}
|