--- /dev/null
+#include <msp/geometry/boundingbox.h>
+#include <msp/strings/format.h>
+#include <msp/test/test.h>
+
+using namespace Msp;
+
+class BoundingBoxTests: public Test::RegisteredTest<BoundingBoxTests>
+{
+private:
+ typedef Geometry::BoundingBox<double, 3> BoundingBox3;
+ typedef LinAl::Vector<double, 3> Vector3;
+public:
+ BoundingBoxTests();
+
+ static const char *get_name() { return "BoundingBox"; }
+
+private:
+ void simple_union();
+ void simple_intersection();
+ void union_with_empty();
+ void intersection_with_empty();
+ void substraction();
+ void special_cases();
+};
+
+namespace Msp {
+namespace LinAl {
+
+void operator<<(LexicalConverter &conv, const Vector<double, 3> &vec)
+{
+ conv.result(format("[%g %g %g]", vec.x, vec.y, vec.z));
+}
+
+} }
+
+BoundingBoxTests::BoundingBoxTests()
+{
+ add(&BoundingBoxTests::simple_union, "Union");
+ add(&BoundingBoxTests::simple_intersection, "Intersection");
+ add(&BoundingBoxTests::union_with_empty, "Union with empty");
+ add(&BoundingBoxTests::intersection_with_empty, "Intersection with empty");
+ add(&BoundingBoxTests::substraction, "Substraction");
+ add(&BoundingBoxTests::special_cases, "Special cases");
+}
+
+void BoundingBoxTests::simple_union()
+{
+ BoundingBox3 bbox1(Vector3(-1, 0, -1), Vector3(1, 2, 1));
+ BoundingBox3 bbox2(Vector3(0, -1, 0), Vector3(2, 1, 2));
+ BoundingBox3 bboxu = bbox1|bbox2;
+ EXPECT_EQUAL(bboxu.get_minimum_point(), Vector3(-1, -1, -1));
+ EXPECT_EQUAL(bboxu.get_maximum_point(), Vector3(2, 2, 2));
+}
+
+void BoundingBoxTests::simple_intersection()
+{
+ BoundingBox3 bbox1(Vector3(-1, 0, -1), Vector3(1, 2, 1));
+ BoundingBox3 bbox2(Vector3(0, -1, 0), Vector3(2, 1, 2));
+ BoundingBox3 bboxi = bbox1&bbox2;
+ EXPECT_EQUAL(bboxi.get_minimum_point(), Vector3(0, 0, 0));
+ EXPECT_EQUAL(bboxi.get_maximum_point(), Vector3(1, 1, 1));
+}
+
+void BoundingBoxTests::union_with_empty()
+{
+ BoundingBox3 bbox(Vector3(-1, -1, -1), Vector3(1, 1, 1));
+ BoundingBox3 bboxu = bbox|BoundingBox3();
+ EXPECT_EQUAL(bboxu.get_minimum_point(), bbox.get_minimum_point());
+ EXPECT_EQUAL(bboxu.get_maximum_point(), bbox.get_maximum_point());
+}
+
+void BoundingBoxTests::intersection_with_empty()
+{
+ BoundingBox3 bbox(Vector3(-1, -1, -1), Vector3(1, 1, 1));
+ BoundingBox3 bboxi = bbox&BoundingBox3();
+ EXPECT(bboxi.is_empty());
+}
+
+void BoundingBoxTests::substraction()
+{
+ BoundingBox3 bbox1(Vector3(-1, -1, -1), Vector3(1, 1, 1));
+ BoundingBox3 bbox2(Vector3(0, -2, -2), Vector3(2, 2, 2));
+ BoundingBox3 bboxs = bbox1&~bbox2;
+ EXPECT_EQUAL(bboxs.get_minimum_point(), Vector3(-1, -1, -1));
+ EXPECT_EQUAL(bboxs.get_maximum_point(), Vector3(0, 1, 1));
+
+ BoundingBox3 bbox3(Vector3(0, 0, -2), Vector3(2, 2, 2));
+ bboxs = bbox1&~bbox3;
+ EXPECT_EQUAL(bboxs.get_minimum_point(), bbox1.get_minimum_point());
+ EXPECT_EQUAL(bboxs.get_maximum_point(), bbox1.get_maximum_point());
+
+ BoundingBox3 bbox4(Vector3(-2, -2, -2), Vector3(2, 2, 2));
+ bboxs = bbox1&~bbox4;
+ EXPECT(bboxs.is_empty());
+
+ bboxs = bbox1&~BoundingBox3();
+ EXPECT_EQUAL(bboxs.get_minimum_point(), bbox1.get_minimum_point());
+ EXPECT_EQUAL(bboxs.get_maximum_point(), bbox1.get_maximum_point());
+}
+
+void BoundingBoxTests::special_cases()
+{
+ BoundingBox3 bbox = BoundingBox3()|BoundingBox3();
+ EXPECT(bbox.is_empty());
+
+ bbox = BoundingBox3()|~BoundingBox3();
+ EXPECT(bbox.is_space());
+
+ bbox = ~BoundingBox3()|BoundingBox3();
+ EXPECT(bbox.is_space());
+
+ bbox = ~BoundingBox3()|~BoundingBox3();
+ EXPECT(bbox.is_space());
+
+ bbox = BoundingBox3()&BoundingBox3();
+ EXPECT(bbox.is_empty());
+
+ bbox = BoundingBox3()&~BoundingBox3();
+ EXPECT(bbox.is_empty());
+
+ bbox = ~BoundingBox3()&BoundingBox3();
+ EXPECT(bbox.is_empty());
+
+ bbox = ~BoundingBox3()&~BoundingBox3();
+ EXPECT(bbox.is_space());
+}