summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArseny Kapoulkine <arseny.kapoulkine@gmail.com>2015-03-21 01:05:31 -0700
committerArseny Kapoulkine <arseny.kapoulkine@gmail.com>2015-03-21 01:05:31 -0700
commit250b690a546f296fa480cf61ad796a36b66a78c6 (patch)
tree90003414c3dc1e360aac290d5d968529f3f31f14
parentce974094ace6a33d46d8dcc6ca66a6fcdc014bbd (diff)
tests: Work around fp issues in various runtime libraries
Disable/change some tests for some compilers; use binary float comparison for early MSVC versions.
-rw-r--r--tests/test_dom_modify.cpp65
1 files changed, 54 insertions, 11 deletions
diff --git a/tests/test_dom_modify.cpp b/tests/test_dom_modify.cpp
index 5167358..c06c141 100644
--- a/tests/test_dom_modify.cpp
+++ b/tests/test_dom_modify.cpp
@@ -5,6 +5,10 @@
#include <math.h>
+#ifdef __BORLANDC__
+using std::ldexpf;
+#endif
+
TEST_XML(dom_attr_assign, "<node/>")
{
xml_node node = doc.child(STR("node"));
@@ -101,15 +105,28 @@ TEST_XML(dom_attr_set_value_llong, "<node/>")
}
#endif
-TEST_XML(dom_attr_assign_large_number, "<node attr1='' attr2='' />")
+TEST_XML(dom_attr_assign_large_number_float, "<node attr='' />")
{
xml_node node = doc.child(STR("node"));
- node.attribute(STR("attr1")) = std::numeric_limits<float>::max();
- node.attribute(STR("attr2")) = std::numeric_limits<double>::max();
+ node.attribute(STR("attr")) = std::numeric_limits<float>::max();
- CHECK(test_node(node, STR("<node attr1=\"3.40282347e+038\" attr2=\"1.7976931348623157e+308\" />"), STR(""), pugi::format_raw) ||
- test_node(node, STR("<node attr1=\"3.40282347e+38\" attr2=\"1.7976931348623157e+308\" />"), STR(""), pugi::format_raw));
+ CHECK(test_node(node, STR("<node attr=\"3.40282347e+038\" />"), STR(""), pugi::format_raw) ||
+ test_node(node, STR("<node attr=\"3.40282347e+38\" />"), STR(""), pugi::format_raw));
+}
+
+TEST_XML(dom_attr_assign_large_number_double, "<node attr='' />")
+{
+ xml_node node = doc.child(STR("node"));
+
+ node.attribute(STR("attr")) = std::numeric_limits<double>::max();
+
+ // Borland C does not print double values with enough precision
+#ifdef __BORLANDC__
+ CHECK_NODE(node, STR("<node attr=\"1.7976931348623156e+308\" />"));
+#else
+ CHECK_NODE(node, STR("<node attr=\"1.7976931348623157e+308\" />"));
+#endif
}
TEST_XML(dom_node_set_name, "<node>text</node>")
@@ -1447,6 +1464,17 @@ TEST(dom_node_copy_declaration_empty_name)
CHECK_STRING(decl2.name(), STR(""));
}
+template <typename T> bool fp_equal(T lhs, T rhs)
+{
+ // Several compilers compare float/double values on x87 stack without proper rounding
+ // This causes roundtrip tests to fail, although they correctly preserve the data.
+#if (defined(_MSC_VER) && _MSC_VER < 1400)
+ return memcmp(&lhs, &rhs, sizeof(T)) == 0;
+#else
+ return lhs == rhs;
+#endif
+}
+
TEST(dom_fp_roundtrip_min_max)
{
xml_document doc;
@@ -1454,16 +1482,16 @@ TEST(dom_fp_roundtrip_min_max)
xml_attribute attr = node.append_attribute(STR("attr"));
node.text().set(std::numeric_limits<float>::min());
- CHECK(node.text().as_float() == std::numeric_limits<float>::min());
+ CHECK(fp_equal(node.text().as_float(), std::numeric_limits<float>::min()));
attr.set_value(std::numeric_limits<float>::max());
- CHECK(attr.as_float() == std::numeric_limits<float>::max());
+ CHECK(fp_equal(attr.as_float(), std::numeric_limits<float>::max()));
attr.set_value(std::numeric_limits<double>::min());
- CHECK(attr.as_double() == std::numeric_limits<double>::min());
+ CHECK(fp_equal(attr.as_double(), std::numeric_limits<double>::min()));
node.text().set(std::numeric_limits<double>::max());
- CHECK(node.text().as_double() == std::numeric_limits<double>::max());
+ CHECK(fp_equal(node.text().as_double(), std::numeric_limits<double>::max()));
}
const double fp_roundtrip_base[] =
@@ -1487,11 +1515,13 @@ TEST(dom_fp_roundtrip_float)
float value = ldexpf(static_cast<float>(fp_roundtrip_base[i]), e);
doc.text().set(value);
- CHECK(doc.text().as_float() == value);
+ CHECK(fp_equal(doc.text().as_float(), value));
}
}
}
+// Borland C does not print double values with enough precision
+#ifndef __BORLANDC__
TEST(dom_fp_roundtrip_double)
{
xml_document doc;
@@ -1500,10 +1530,23 @@ TEST(dom_fp_roundtrip_double)
{
for (size_t i = 0; i < sizeof(fp_roundtrip_base) / sizeof(fp_roundtrip_base[0]); ++i)
{
+ #if defined(_MSC_VER) && _MSC_VER < 1400
+ // Not all runtime libraries guarantee roundtripping for denormals
+ if (e == -1021 && fp_roundtrip_base[i] < 0.5)
+ continue;
+ #endif
+
+ #ifdef __DMC__
+ // Digital Mars C does not roundtrip on exactly one combination
+ if (e == -12 && i == 1)
+ continue;
+ #endif
+
double value = ldexp(fp_roundtrip_base[i], e);
doc.text().set(value);
- CHECK(doc.text().as_double() == value);
+ CHECK(fp_equal(doc.text().as_double(), value));
}
}
}
+#endif