mirror of
https://github.com/jezhiggins/arabica
synced 2025-01-17 18:12:04 +01:00
In XPath numbers do not have leading +, so, while '-1.5' converts to -1.5, '+1.5' converts to NaN. Weird and counter-intuitive, but in the spec.
This commit is contained in:
parent
b9a2e6e2f6
commit
db54b7c7bc
2 changed files with 62 additions and 1 deletions
|
@ -413,7 +413,14 @@ template<class string_type, class string_adaptor>
|
||||||
double stringAsNumber(const string_type& str)
|
double stringAsNumber(const string_type& str)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
return boost::lexical_cast<double>(Arabica::text::normalize_whitespace<string_type, string_adaptor>(str));
|
static string_type PLUS = string_adaptor::construct_from_utf8("+");
|
||||||
|
|
||||||
|
string_type n_str = Arabica::text::normalize_whitespace<string_type, string_adaptor>(str);
|
||||||
|
// '+1.5' is not a number according to XPath spec, counter intuitive as that is
|
||||||
|
if(string_adaptor::find(n_str, PLUS) == 0)
|
||||||
|
return NaN;
|
||||||
|
|
||||||
|
return boost::lexical_cast<double>(n_str);
|
||||||
} // try
|
} // try
|
||||||
catch(const boost::bad_lexical_cast&) {
|
catch(const boost::bad_lexical_cast&) {
|
||||||
return NaN;
|
return NaN;
|
||||||
|
|
|
@ -1116,6 +1116,54 @@ public:
|
||||||
assertTrue(isNaN(result.asNumber()));
|
assertTrue(isNaN(result.asNumber()));
|
||||||
} // testNumberFn7
|
} // testNumberFn7
|
||||||
|
|
||||||
|
void testNumberFn8()
|
||||||
|
{
|
||||||
|
using namespace Arabica::XPath;
|
||||||
|
XPathValue<string_type, string_adaptor> result = parser.evaluate_expr(SA::construct_from_utf8("number('-1.5')"), document_);
|
||||||
|
assertValuesEqual(NUMBER, result.type());
|
||||||
|
assertDoublesEqual(-1.5, result.asNumber(), 0.0);
|
||||||
|
} // testNumberFn8
|
||||||
|
|
||||||
|
void testNumberFn9()
|
||||||
|
{
|
||||||
|
using namespace Arabica::XPath;
|
||||||
|
XPathValue<string_type, string_adaptor> result = parser.evaluate_expr(SA::construct_from_utf8("number('+1.5')"), document_);
|
||||||
|
assertValuesEqual(NUMBER, result.type());
|
||||||
|
assertTrue(isNaN(result.asNumber()));
|
||||||
|
} // testNumberFn9
|
||||||
|
|
||||||
|
void testNumberFn10()
|
||||||
|
{
|
||||||
|
using namespace Arabica::XPath;
|
||||||
|
XPathValue<string_type, string_adaptor> result = parser.evaluate_expr(SA::construct_from_utf8("number('-1.5 ')"), document_);
|
||||||
|
assertValuesEqual(NUMBER, result.type());
|
||||||
|
assertDoublesEqual(-1.5, result.asNumber(), 0.0);
|
||||||
|
} // testNumberFn10
|
||||||
|
|
||||||
|
void testNumberFn11()
|
||||||
|
{
|
||||||
|
using namespace Arabica::XPath;
|
||||||
|
XPathValue<string_type, string_adaptor> result = parser.evaluate_expr(SA::construct_from_utf8("number('+1.5')"), document_);
|
||||||
|
assertValuesEqual(NUMBER, result.type());
|
||||||
|
assertTrue(isNaN(result.asNumber()));
|
||||||
|
} // testNumberFn11
|
||||||
|
|
||||||
|
void testNumberFn12()
|
||||||
|
{
|
||||||
|
using namespace Arabica::XPath;
|
||||||
|
XPathValue<string_type, string_adaptor> result = parser.evaluate_expr(SA::construct_from_utf8("number(' -1.5 ')"), document_);
|
||||||
|
assertValuesEqual(NUMBER, result.type());
|
||||||
|
assertDoublesEqual(-1.5, result.asNumber(), 0.0);
|
||||||
|
} // testNumberFn12
|
||||||
|
|
||||||
|
void testNumberFn13()
|
||||||
|
{
|
||||||
|
using namespace Arabica::XPath;
|
||||||
|
XPathValue<string_type, string_adaptor> result = parser.evaluate_expr(SA::construct_from_utf8("number(' +1.5 ')"), document_);
|
||||||
|
assertValuesEqual(NUMBER, result.type());
|
||||||
|
assertTrue(isNaN(result.asNumber()));
|
||||||
|
} // testNumberFn13
|
||||||
|
|
||||||
void testFloorFn1()
|
void testFloorFn1()
|
||||||
{
|
{
|
||||||
using namespace Arabica::XPath;
|
using namespace Arabica::XPath;
|
||||||
|
@ -2575,6 +2623,12 @@ TestSuite* ExecuteTest_suite()
|
||||||
suiteOfTests->addTest(new TestCaller<ExecuteTest<string_type, string_adaptor> >("testNumberFn5", &ExecuteTest<string_type, string_adaptor>::testNumberFn5));
|
suiteOfTests->addTest(new TestCaller<ExecuteTest<string_type, string_adaptor> >("testNumberFn5", &ExecuteTest<string_type, string_adaptor>::testNumberFn5));
|
||||||
suiteOfTests->addTest(new TestCaller<ExecuteTest<string_type, string_adaptor> >("testNumberFn6", &ExecuteTest<string_type, string_adaptor>::testNumberFn6));
|
suiteOfTests->addTest(new TestCaller<ExecuteTest<string_type, string_adaptor> >("testNumberFn6", &ExecuteTest<string_type, string_adaptor>::testNumberFn6));
|
||||||
suiteOfTests->addTest(new TestCaller<ExecuteTest<string_type, string_adaptor> >("testNumberFn7", &ExecuteTest<string_type, string_adaptor>::testNumberFn7));
|
suiteOfTests->addTest(new TestCaller<ExecuteTest<string_type, string_adaptor> >("testNumberFn7", &ExecuteTest<string_type, string_adaptor>::testNumberFn7));
|
||||||
|
suiteOfTests->addTest(new TestCaller<ExecuteTest<string_type, string_adaptor> >("testNumberFn8", &ExecuteTest<string_type, string_adaptor>::testNumberFn8));
|
||||||
|
suiteOfTests->addTest(new TestCaller<ExecuteTest<string_type, string_adaptor> >("testNumberFn9", &ExecuteTest<string_type, string_adaptor>::testNumberFn9));
|
||||||
|
suiteOfTests->addTest(new TestCaller<ExecuteTest<string_type, string_adaptor> >("testNumberFn10", &ExecuteTest<string_type, string_adaptor>::testNumberFn10));
|
||||||
|
suiteOfTests->addTest(new TestCaller<ExecuteTest<string_type, string_adaptor> >("testNumberFn11", &ExecuteTest<string_type, string_adaptor>::testNumberFn11));
|
||||||
|
suiteOfTests->addTest(new TestCaller<ExecuteTest<string_type, string_adaptor> >("testNumberFn12", &ExecuteTest<string_type, string_adaptor>::testNumberFn12));
|
||||||
|
suiteOfTests->addTest(new TestCaller<ExecuteTest<string_type, string_adaptor> >("testNumberFn13", &ExecuteTest<string_type, string_adaptor>::testNumberFn13));
|
||||||
suiteOfTests->addTest(new TestCaller<ExecuteTest<string_type, string_adaptor> >("testFloorFn1", &ExecuteTest<string_type, string_adaptor>::testFloorFn1));
|
suiteOfTests->addTest(new TestCaller<ExecuteTest<string_type, string_adaptor> >("testFloorFn1", &ExecuteTest<string_type, string_adaptor>::testFloorFn1));
|
||||||
suiteOfTests->addTest(new TestCaller<ExecuteTest<string_type, string_adaptor> >("testFloorFn2", &ExecuteTest<string_type, string_adaptor>::testFloorFn2));
|
suiteOfTests->addTest(new TestCaller<ExecuteTest<string_type, string_adaptor> >("testFloorFn2", &ExecuteTest<string_type, string_adaptor>::testFloorFn2));
|
||||||
suiteOfTests->addTest(new TestCaller<ExecuteTest<string_type, string_adaptor> >("testFloorFn3", &ExecuteTest<string_type, string_adaptor>::testFloorFn3));
|
suiteOfTests->addTest(new TestCaller<ExecuteTest<string_type, string_adaptor> >("testFloorFn3", &ExecuteTest<string_type, string_adaptor>::testFloorFn3));
|
||||||
|
|
Loading…
Reference in a new issue