summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/2geom/tests/testing.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/2geom/tests/testing.h')
-rw-r--r--src/3rdparty/2geom/tests/testing.h186
1 files changed, 186 insertions, 0 deletions
diff --git a/src/3rdparty/2geom/tests/testing.h b/src/3rdparty/2geom/tests/testing.h
new file mode 100644
index 0000000..40a588d
--- /dev/null
+++ b/src/3rdparty/2geom/tests/testing.h
@@ -0,0 +1,186 @@
+#include "gtest/gtest.h"
+#include <vector>
+#include <2geom/coord.h>
+#include <2geom/interval.h>
+#include <2geom/intersection.h>
+
+// streams out a vector
+template <class T>
+std::ostream&
+operator<< (std::ostream &out, const std::vector<T,
+ std::allocator<T> > &v)
+{
+ typedef std::ostream_iterator<T, char,
+ std::char_traits<char> > Iter;
+
+ std::copy (v.begin (), v.end (), Iter (out, " "));
+
+ return out;
+}
+
+template <typename T, unsigned xn>
+std::vector<T> vector_from_array(const T (&x)[xn]) {
+ std::vector<T> v;
+ for(unsigned i = 0; i < xn; i++) {
+ v.push_back(x[i]);
+ }
+ return v;
+}
+
+template <typename T, unsigned xn>
+void expect_array(const T (&x)[xn], std::vector<T> y) {
+ EXPECT_EQ(xn, y.size());
+ for(unsigned i = 0; i < y.size(); i++) {
+ EXPECT_EQ(x[i], y[i]);
+ }
+}
+
+Geom::Interval bound_vector(std::vector<double> const &v) {
+ double low = v[0];
+ double high = v[0];
+ for(double i : v) {
+ low = std::min(i, low);
+ high = std::max(i, high);
+ }
+ return Geom::Interval(low-1, high-1);
+}
+
+
+// Custom assertion formatting predicates
+
+template <typename T>
+::testing::AssertionResult ObjectNear(char const *l_expr,
+ char const *r_expr,
+ char const */*eps_expr*/,
+ T const &l,
+ T const &r,
+ Geom::Coord eps)
+{
+ if (!Geom::are_near(l, r, eps)) {
+ return ::testing::AssertionFailure() << "Objects are not near\n"
+ << "First object: " << l_expr << "\n"
+ << "Value: " << l << "\n"
+ << "Second object: " << r_expr << "\n"
+ << "Value: " << r << "\n"
+ << "Threshold: " << Geom::format_coord_nice(eps) << std::endl;
+ }
+ return ::testing::AssertionSuccess();
+}
+
+template <typename T>
+::testing::AssertionResult ObjectNotNear(char const *l_expr,
+ char const *r_expr,
+ char const */*eps_expr*/,
+ T const &l,
+ T const &r,
+ Geom::Coord eps)
+{
+ if (Geom::are_near(l, r, eps)) {
+ return ::testing::AssertionFailure() << "Objects are near\n"
+ << "First object: " << l_expr << "\n"
+ << "Value: " << l << "\n"
+ << "Second object: " << r_expr << "\n"
+ << "Value: " << r << "\n"
+ << "Threshold: " << Geom::format_coord_nice(eps) << std::endl;
+ }
+ return ::testing::AssertionSuccess();
+}
+
+#define EXPECT_near(a, b, eps) EXPECT_PRED_FORMAT3(ObjectNear, a, b, eps)
+#define EXPECT_not_near(a, b, eps) EXPECT_PRED_FORMAT3(ObjectNotNear, a, b, eps)
+
+
+
+template <typename T>
+::testing::AssertionResult VectorEqual(char const *l_expr,
+ char const *r_expr,
+ std::vector<T> const &l,
+ std::vector<T> const &r)
+{
+ if (l.size() != r.size()) {
+ return ::testing::AssertionFailure() << "Vectors differ in size\n"
+ << l_expr << " has size " << l.size() << "\n"
+ << r_expr << " has size " << r.size() << std::endl;
+ }
+ for (unsigned i = 0; i < l.size(); ++i) {
+ if (!(l[i] == r[i])) {
+ return ::testing::AssertionFailure() << "Vectors differ"
+ << "\nVector: " << l_expr
+ << "\nindex " << i << " contains: " << l[i]
+ << "\nVector:" << r_expr
+ << "\nindex " << i << " contains: " << r[i] << std::endl;
+ }
+ }
+ return ::testing::AssertionSuccess();
+}
+
+template <typename T>
+::testing::AssertionResult VectorNear(char const *l_expr,
+ char const *r_expr,
+ char const */*eps_expr*/,
+ std::vector<T> const &l,
+ std::vector<T> const &r,
+ Geom::Coord eps)
+{
+ if (l.size() != r.size()) {
+ return ::testing::AssertionFailure() << "Vectors differ in size\n"
+ << l_expr << "has size " << l.size() << "\n"
+ << r_expr << "has size " << r.size() << std::endl;
+ }
+ for (unsigned i = 0; i < l.size(); ++i) {
+ if (!Geom::are_near(l[i], r[i], eps)) {
+ return ::testing::AssertionFailure() << "Vectors differ by more than "
+ << Geom::format_coord_nice(eps)
+ << "\nVector: " << l_expr
+ << "\nindex " << i << " contains: " << l[i]
+ << "\nVector:" << r_expr
+ << "\nindex " << i << " contains: " << r[i] << std::endl;
+ }
+ }
+ return ::testing::AssertionSuccess();
+}
+
+#define EXPECT_vector_equal(a, b) EXPECT_PRED_FORMAT2(VectorEqual, a, b)
+#define EXPECT_vector_near(a, b, eps) EXPECT_PRED_FORMAT3(VectorNear, a, b, eps)
+
+
+
+template <typename TA, typename TB>
+::testing::AssertionResult IntersectionsValid(
+ char const *l_expr, char const *r_expr, const char */*xs_expr*/, const char */*eps_expr*/,
+ TA const &shape_a, TB const &shape_b,
+ std::vector<Geom::Intersection<typename Geom::ShapeTraits<TA>::TimeType,
+ typename Geom::ShapeTraits<TB>::TimeType> > const &xs,
+ Geom::Coord eps)
+{
+ std::ostringstream os;
+ bool failed = false;
+
+ for (unsigned i = 0; i < xs.size(); ++i) {
+ Geom::Point pa = shape_a.pointAt(xs[i].first);
+ Geom::Point pb = shape_b.pointAt(xs[i].second);
+ if (!Geom::are_near(pa, xs[i].point(), eps) ||
+ !Geom::are_near(pb, xs[i].point(), eps) ||
+ !Geom::are_near(pb, pa, eps))
+ {
+ os << "Intersection " << i << " does not match\n"
+ << Geom::format_coord_nice(xs[i].first) << " evaluates to " << pa << "\n"
+ << Geom::format_coord_nice(xs[i].second) << " evaluates to " << pb << "\n"
+ << "Reported intersection point is " << xs[i].point() << std::endl;
+ failed = true;
+ }
+ }
+
+ if (failed) {
+ return ::testing::AssertionFailure()
+ << "Intersections do not match\n"
+ << "Shape A: " << l_expr << "\n"
+ << "Shape B: " << r_expr << "\n"
+ << os.str()
+ << "Threshold: " << Geom::format_coord_nice(eps) << std::endl;
+ }
+
+ return ::testing::AssertionSuccess();
+}
+
+#define EXPECT_intersections_valid(a, b, xs, eps) EXPECT_PRED_FORMAT4(IntersectionsValid, a, b, xs, eps)