vector_test.cxx 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. //
  2. // vector_test.cpp
  3. // vector
  4. //
  5. // Created by Sam Jaffe on 6/2/18.
  6. //
  7. #include <gmock/gmock.h>
  8. #include "math/vector/vector.hpp"
  9. template <typename T, size_t N> math::vector::vector<T, N> iota() {
  10. math::vector::vector<T, N> rval;
  11. for (size_t i = 0; i < N; ++i)
  12. rval[i] = static_cast<T>(i + 1);
  13. return rval;
  14. }
  15. using vec2i = math::vector::vector<int, 2>;
  16. using vec3 = math::vector::vector<double, 3>;
  17. using vec3i = math::vector::vector<int, 3>;
  18. using vec4i = math::vector::vector<int, 4>;
  19. vec2i iota2i() { return iota<int, 2>(); }
  20. vec3i iota3i() { return iota<int, 3>(); }
  21. TEST(Vector, Equality) {
  22. EXPECT_THAT((iota3i()), vec3i({1, 2, 3}));
  23. EXPECT_THAT((iota3i()), ::testing::Not(vec3i({0, 2, 3})));
  24. }
  25. TEST(Vector, DefaultConstructorIsAllZero) {
  26. EXPECT_THAT(vec3i(), vec3i({0, 0, 0}));
  27. }
  28. TEST(Vector, FillConstructorInsertsAllElements) {
  29. EXPECT_THAT(vec3i(1, math::vector::fill), vec3i({1, 1, 1}));
  30. }
  31. TEST(Vector, ExtensionConstructorAppendsZeros) {
  32. EXPECT_THAT(vec4i(iota3i()), vec4i({1, 2, 3, 0}));
  33. }
  34. TEST(Vector, CanAccessVectorElements) {
  35. math::vector::vector<int, 3> viota = iota3i();
  36. EXPECT_THAT(viota[0], 1);
  37. EXPECT_THAT(viota[1], 2);
  38. EXPECT_THAT(viota[2], 3);
  39. }
  40. TEST(Vector, AccessingOutOfRangeThrows) {
  41. EXPECT_THROW(iota3i().at(3), std::out_of_range);
  42. }
  43. TEST(Vector, CrossProduct2DHasOnlyZElement) {
  44. EXPECT_THAT(vec2i({1, 1}).cross(vec2i({-1, 1})), vec3i({0, 0, 2}));
  45. }
  46. TEST(Vector, CrossProduct3DHasAllElements) {
  47. EXPECT_THAT(vec3i({1, 1, 2}).cross(vec3i({-1, 1, 1})), vec3i({-1, -3, 2}));
  48. }
  49. TEST(Vector, AdditionIsPiecewise) {
  50. EXPECT_THAT((vec2i{{1, 0}} + vec2i{{0, 1}}), vec2i({1, 1}));
  51. }
  52. TEST(Vector, SubtractionIsPiecewise) {
  53. EXPECT_THAT((vec2i{{1, 0}} - vec2i{{0, 1}}), vec2i({1, -1}));
  54. }
  55. TEST(Vector, MultiplicationIsPiecewise) {
  56. EXPECT_THAT((vec2i{{1, 0}} * vec2i({2, 1})), vec2i({2, 0}));
  57. }
  58. TEST(Vector, DivisionIsPiecewise) {
  59. EXPECT_THAT((vec2i{{6, 4}} / vec2i({2, 1})), vec2i({3, 4}));
  60. }
  61. TEST(Vector, DivisionByZeroThrowsException) {
  62. EXPECT_THROW(vec3{} / 0, std::domain_error);
  63. EXPECT_THROW((vec3{{1.0, 1.0, 1.0}} / vec3({1.0, 0.5, 0.0})),
  64. std::domain_error);
  65. }
  66. TEST(Vector, AdditionWithValueType) {
  67. EXPECT_THAT(vec2i({1, 0}) + 1, vec2i({2, 1}));
  68. EXPECT_THAT(1 + iota2i(), vec2i({2, 3}));
  69. }
  70. TEST(Vector, SubtractionWithValueType) {
  71. EXPECT_THAT(4 - iota2i(), vec2i({3, 2}));
  72. EXPECT_THAT(vec2i({1, 0}) - 1, vec2i({0, -1}));
  73. }
  74. TEST(Vector, MultiplicationWithValueType) {
  75. EXPECT_THAT((vec2i{{1, 0}} * 3), vec2i({3, 0}));
  76. EXPECT_THAT(2 * iota2i(), vec2i({2, 4}));
  77. }
  78. TEST(Vector, DivisionWithValueType) {
  79. EXPECT_THAT((vec2i{{6, 4}} / 2), vec2i({3, 2}));
  80. // EXPECT_THAT(4/iota2i(), (vec2i{4,2}));
  81. }
  82. TEST(Vector, OperatorPlusEqualsMutatesValue) {
  83. vec3i vec = iota3i();
  84. EXPECT_THAT(vec += iota3i(), vec3i({2, 4, 6}));
  85. EXPECT_THAT(vec, vec3i({2, 4, 6}));
  86. EXPECT_THAT(vec += 1, vec3i({3, 5, 7}));
  87. EXPECT_THAT(vec, vec3i({3, 5, 7}));
  88. }
  89. TEST(Vector, OperatorMinusEqualsMutatesValue) {
  90. vec3i vec = iota3i();
  91. EXPECT_THAT(vec -= 1, vec3i({0, 1, 2}));
  92. EXPECT_THAT(vec, vec3i({0, 1, 2}));
  93. EXPECT_THAT(vec -= iota3i(), vec3i({-1, -1, -1}));
  94. EXPECT_THAT(vec, vec3i({-1, -1, -1}));
  95. }
  96. TEST(Vector, MultiplicationWorksAcrossTypes) {
  97. EXPECT_THAT(iota3i() * 0.5, vec3({0.5, 1.0, 1.5}));
  98. EXPECT_THAT(0.5 * iota3i(), vec3({0.5, 1.0, 1.5}));
  99. EXPECT_THAT(vec3({2.0, 1.5, -2}) * iota3i(), vec3({2.0, 3.0, -6.0}));
  100. }
  101. TEST(Vector, DivisionWorksAcrossTypes) {
  102. EXPECT_THAT(iota3i() / 0.5, vec3({2.0, 4.0, 6.0}));
  103. EXPECT_THAT(iota3i() / vec3({2.0, 2.5, -2}), vec3({0.5, 0.8, -1.5}));
  104. EXPECT_THAT(vec3({2.0, 2.5, -3}) / iota3i(), vec3({2.0, 1.25, -1.0}));
  105. }
  106. TEST(Vector, Length) {
  107. // EXPECT_THAT(iota3i().lengthSquared(), 14);
  108. EXPECT_THAT(iota3i().magnitude(),
  109. ::testing::DoubleNear(std::sqrt(14),
  110. std::numeric_limits<double>::epsilon()));
  111. }
  112. TEST(Vector, Distance) {
  113. // EXPECT_THAT((iota3i().distanceSquared(vec3i{3, 1, -1})), 21);
  114. EXPECT_THAT((iota3i() - vec3i({3, 1, -1})).magnitude(),
  115. ::testing::DoubleNear(std::sqrt(21),
  116. std::numeric_limits<double>::epsilon()));
  117. }
  118. TEST(Vector, Projection) {
  119. EXPECT_THAT(iota3i().projection(vec3i({3, 1, -1})).magnitude(),
  120. ::testing::DoubleNear(std::sqrt(4.0 / 11.0),
  121. std::numeric_limits<double>::epsilon()));
  122. }
  123. TEST(Vector, DotProductIsSumOfElementProducts) {
  124. EXPECT_THAT(iota3i().dot(vec3i({3, 0, -1})), 0);
  125. }
  126. TEST(Vector, UnitFunctionCreatesNewVectorOverMagnitude) {
  127. double sq = std::sqrt(14);
  128. auto unit = iota3i().unit();
  129. EXPECT_THAT(unit[0], ::testing::DoubleNear(
  130. 1 / sq, std::numeric_limits<double>::epsilon()));
  131. EXPECT_THAT(unit[1], ::testing::DoubleNear(
  132. 2 / sq, std::numeric_limits<double>::epsilon()));
  133. EXPECT_THAT(unit[2], ::testing::DoubleNear(
  134. 3 / sq, std::numeric_limits<double>::epsilon()));
  135. }
  136. TEST(Vector, CanCastEntireVectorThroughConstructor) {
  137. EXPECT_THAT(vec3i(vec3({1.0, 2.3, 3.9})), iota3i());
  138. }
  139. TEST(Vector, SwapExchangesAllValues) {
  140. using std::swap;
  141. vec2i a{{1, 2}};
  142. const vec2i ac = a;
  143. vec2i b{{5, 7}};
  144. const vec2i bc = b;
  145. swap(a, b);
  146. EXPECT_THAT(a, bc);
  147. EXPECT_THAT(b, ac);
  148. }
  149. TEST(Vector, UnaryNegateOperatorNegatesAllElements) {
  150. EXPECT_THAT(-iota3i(), vec3i({-1, -2, -3}));
  151. }
  152. TEST(Vector, AbsoluteValueOfVectorAbsAllElements) {
  153. EXPECT_THAT(iota3i(), abs(-iota3i()));
  154. }
  155. TEST(Vector, MakeVectorAllowsConstuctionFromVariadicComponents) {
  156. EXPECT_TRUE((std::is_same<vec2i, decltype(make_vector(1, 2))>::value));
  157. EXPECT_THAT(iota2i(), make_vector(1, 2));
  158. EXPECT_FALSE((std::is_same<vec2i, decltype(make_vector(1, 2, 3))>::value));
  159. EXPECT_TRUE((std::is_same<vec3i, decltype(make_vector(1, 2, 3))>::value));
  160. EXPECT_THAT(iota3i(), make_vector(1, 2, 3));
  161. }