Browse Source

Add more tests and helpers.
Failing: contains(line, point) where line.slope = Inf

Sam Jaffe 6 years ago
parent
commit
ab1e50a23e
4 changed files with 50 additions and 30 deletions
  1. 1 0
      math/include/game/math/angle.hpp
  2. 2 0
      math/src/angle.cpp
  3. 37 20
      math/test/common_test.cxx
  4. 10 10
      math/test/shape_test.cxx

+ 1 - 0
math/include/game/math/angle.hpp

@@ -9,6 +9,7 @@
 
 namespace math {
   struct degree {
+    degree(double v);
     double value;
   };
   

+ 2 - 0
math/src/angle.cpp

@@ -10,6 +10,8 @@
 #include <cmath>
 
 namespace math {
+  degree::degree(double v) : value(v) {}
+  
   radian::radian(double v) : value(v) {}
   radian::radian(degree d) : value(d.value / M_2_PI) {}
   radian::operator degree() const { return { value * M_2_PI }; }

+ 37 - 20
math/test/common_test.cxx

@@ -16,36 +16,53 @@
 #include "test_printers.h"
 
 using namespace math::dim2;
+using namespace testing;
 
-struct UnitCircleTest : testing::TestWithParam<point> {};
+template <typename T, typename G>
+decltype(auto) generate(T min, T max, T step, G && generator) {
+  std::vector<decltype(generator(min))> out;
+  for (T val = min; val < max; val += step) {
+    out.emplace_back(generator(val));
+  }
+  return out;
+}
+
+template <typename T> decltype(auto) generate(T min, T max, T step) {
+  auto identity = [](T const & val) { return val; };
+  return generate(min, max, step, identity);
+}
 
-TEST_P(UnitCircleTest, PointExistsInCircle) {
+struct LineTest : TestWithParam<std::tuple<point, int>> {};
+
+TEST_P(LineTest, ExistsOnOriginLine) {
+  point const end = std::get<0>(GetParam());
+  line const ln{{{0, 0}}, end};
+  point const pt = end * std::get<1>(GetParam()) / 100.f;
+  EXPECT_TRUE(math::contains(ln, pt));
+}
+
+std::vector<point> const line_ends{
+  {{1, 1}}, {{0, 1}}, {{1, 0}}
+};
+
+INSTANTIATE_TEST_CASE_P(ContainsPoint, LineTest,
+    Combine(ValuesIn(line_ends), ValuesIn(generate(0, 100, 10))));
+
+struct UnitCircleTest : TestWithParam<point> {};
+
+TEST_P(UnitCircleTest, ExistsInCircle) {
   circle unit{{{0, 0}}, 1};
   EXPECT_TRUE(math::contains(unit, GetParam()));
 }
 
-TEST_P(UnitCircleTest, PointExistsOutsideCircle) {
+TEST_P(UnitCircleTest, OutsideSmallerCircle) {
   circle subunit{{{0, 0}}, 0.9999};
   EXPECT_FALSE(math::contains(subunit, GetParam()));
 }
 
-struct unit_circle_angle {
-  using value_type = point;
-  unit_circle_angle(int degrees) : degs({static_cast<double>(degrees)}) {}
-  point operator*() const {
-    return point(make_vector(math::sin(degs), math::cos(degs)));
-  }
-  unit_circle_angle & operator++() { ++degs.value; return *this; }
-  math::degree degs;
-};
-
-std::vector<point> unit_circle_pts() {
-  std::vector<point> rval;
-  for (math::degree d{0.0}; d.value <= 360; d.value += 5.0) {
-    rval.emplace_back(point(make_vector(math::sin(d), math::cos(d))));
-  }
-  return rval;
+point unit_circle_angle(math::degree degs) {
+  return point(make_vector(math::sin(degs), math::cos(degs)));
 }
 
 INSTANTIATE_TEST_CASE_P(LiesOnEdge, UnitCircleTest,
-                        testing::ValuesIn(unit_circle_pts()));
+    ValuesIn(generate(0.0, 360.0, 5.0, unit_circle_angle)));

+ 10 - 10
math/test/shape_test.cxx

@@ -13,15 +13,16 @@
 #include "test_printers.h"
 
 using namespace math::dim2;
+using namespace testing;
 
-struct FromOriginTest : testing::TestWithParam<line> {};
+struct FromOriginTest : TestWithParam<line> {};
 
 TEST_P(FromOriginTest, IntersectsAtOrigin) {
   line l1 = { GetParam().first, {{0, 0}} };
   line l2 = { {{0, 0}}, GetParam().second };
   
   EXPECT_THAT(math::lines::intersection(l1, l2),
-              testing::Eq(point{{0, 0}}));
+              Eq(point{{0, 0}}));
 }
 
 std::vector<line> const point_pairs{
@@ -40,16 +41,16 @@ std::vector<line> const point_pairs{
 };
 
 INSTANTIATE_TEST_CASE_P(LineIntersection, FromOriginTest,
-                        testing::ValuesIn(point_pairs));
+                        ValuesIn(point_pairs));
 
-struct XUnitTest : testing::TestWithParam<point> {};
+struct XUnitTest : TestWithParam<point> {};
 
 TEST_P(XUnitTest, OrthoOnIntersection) {
   line const ln{{{0, 0}}, {{1, 0}}};
   point const pt = GetParam();
   line const expected{pt, {{pt[0], 0}}};
   EXPECT_THAT(math::lines::orthogonal(ln, pt),
-              testing::Eq(expected));
+              Eq(expected));
 }
 
 std::vector<point> x_orthos{
@@ -58,17 +59,16 @@ std::vector<point> x_orthos{
   {{2, 1}}, {{1, 2}}, {{-2, 1}}, {{-1, 2}}, {{1, -2}}, {{2, -1}}
 };
 
-INSTANTIATE_TEST_CASE_P(LineOrthogonal, XUnitTest,
-                        testing::ValuesIn(x_orthos));
+INSTANTIATE_TEST_CASE_P(LineOrthogonal, XUnitTest, ValuesIn(x_orthos));
 
-struct DiagonalTest : testing::TestWithParam<std::pair<point, float>> {};
+struct DiagonalTest : TestWithParam<std::pair<point, float>> {};
 
 TEST_P(DiagonalTest, OrthoOnIntersection) {
   line const ln{{{0, 0}}, {{1, 1}}};
   point const pt = GetParam().first;
   line const expected{pt, {{GetParam().second, GetParam().second}}};
   EXPECT_THAT(math::lines::orthogonal(ln, pt),
-              testing::Eq(expected));
+              Eq(expected));
 }
 
 std::vector<std::pair<point, float>> diag_orthos{
@@ -81,4 +81,4 @@ std::vector<std::pair<point, float>> diag_orthos{
 };
 
 INSTANTIATE_TEST_CASE_P(LineOrthogonal, DiagonalTest,
-                        testing::ValuesIn(diag_orthos));
+                        ValuesIn(diag_orthos));