// // vector_test.cpp // vector // // Created by Sam Jaffe on 6/2/18. // #include #include "vector.hpp" template math::vector::vector iota() { math::vector::vector rval; for (size_t i = 0; i < N; ++i) rval[i] = static_cast(i+1); return rval; } using vec2i = math::vector::vector; using vec3 = math::vector::vector; using vec3i = math::vector::vector; using vec4i = math::vector::vector; vec2i iota2i() { return iota(); } vec3i iota3i() { return iota(); } TEST(Vector, Equality) { EXPECT_THAT((iota3i()), (vec3i{{1, 2, 3}})); EXPECT_THAT((iota3i()), ::testing::Not(vec3i{{0, 2, 3}})); } TEST(Vector, DefaultConstructorIsAllZero) { EXPECT_THAT(vec3i(), (vec3i{{0,0,0}})); } TEST(Vector, FillConstructorInsertsAllElements) { EXPECT_THAT(vec3i(1, math::vector::fill), vec3i({1, 1, 1})); } TEST(Vector, ExtensionConstructorAppendsZeros) { EXPECT_THAT(vec4i(iota3i()), (vec4i{{1,2,3,0}})); } TEST(Vector, CanAccessVectorElements) { math::vector::vector viota = iota3i(); EXPECT_THAT(viota[0], 1); EXPECT_THAT(viota[1], 2); EXPECT_THAT(viota[2], 3); } TEST(Vector, AccessingOutOfRangeThrows) { EXPECT_THROW(iota3i().at(3), std::out_of_range); } TEST(Vector, CrossProduct2DHasOnlyZElement) { EXPECT_THAT((vec2i{{1,1}}.cross(vec2i{{-1,1}})), (vec3i{{0,0,2}})); } TEST(Vector, CrossProduct3DHasAllElements) { EXPECT_THAT((vec3i{{1,1,2}}.cross(vec3i{{-1,1,1}})), (vec3i{{-1,-3,2}})); } TEST(Vector, AdditionIsPiecewise) { EXPECT_THAT((vec2i{{1,0}} + vec2i{{0,1}}), (vec2i{{1,1}})); } TEST(Vector, SubtractionIsPiecewise) { EXPECT_THAT((vec2i{{1,0}} - vec2i{{0,1}}), (vec2i{{1,-1}})); } TEST(Vector, MultiplicationIsPiecewise) { EXPECT_THAT((vec2i{{1,0}}*(vec2i{{2,1}})), (vec2i{{2,0}})); } TEST(Vector, DivisionIsPiecewise) { EXPECT_THAT((vec2i{{6,4}}/(vec2i{{2,1}})), (vec2i{{3,4}})); } TEST(Vector, DivisionByZeroThrowsException) { EXPECT_THROW(vec3{} / 0, std::domain_error); EXPECT_THROW((vec3{{1.0, 1.0, 1.0}}/(vec3{{1.0, 0.5, 0.0}})), std::domain_error); } // TEST(Vector, AdditionWithValueType) { // EXPECT_THAT((vec2i{1,0} + 1), (vec2i{2,1})) // EXPECT_THAT(1+iota2i(), (vec2i{2,3})); // } // // TEST(Vector, SubtractionWithValueType) { // EXPECT_THAT(4-iota2i(), (vec2i{3,2})); // EXPECT_THAT((vec2i{1,0} - 1), (vec2i{0,-1})) // } TEST(Vector, MultiplicationWithValueType) { EXPECT_THAT((vec2i{{1,0}} * 3), (vec2i{{3,0}})); EXPECT_THAT(2*iota2i(), (vec2i{{2,4}})); } TEST(Vector, DivisionWithValueType) { EXPECT_THAT((vec2i{{6,4}} / 2), (vec2i{{3,2}})); // EXPECT_THAT(4/iota2i(), (vec2i{4,2})); } TEST(Vector, Length) { // EXPECT_THAT(iota3i().lengthSquared(), 14); EXPECT_THAT(iota3i().magnitude(), ::testing::DoubleNear(std::sqrt(14), 0.00001)); } TEST(Vector, Distance) { // EXPECT_THAT((iota3i().distanceSquared(vec3i{3, 1, -1})), 21); EXPECT_THAT((iota3i() - vec3i{{3, 1, -1}}).magnitude(), ::testing::DoubleNear(std::sqrt(21), 0.00001)); } TEST(Vector, Projection) { EXPECT_THAT((iota3i().projection(vec3i{{3, 1, -1}})).magnitude(), ::testing::DoubleNear(std::sqrt(4.0/11.0), 0.00001)); } TEST(Vector, DotProductIsSumOfElementProducts) { EXPECT_THAT((iota3i().dot(vec3i{{3, 0, -1}})), 0); } TEST(Vector, UnitFunctionCreatesNewVectorOverMagnitude) { double sq = std::sqrt(14); auto unit = iota3i().unit(); EXPECT_THAT(unit[0], ::testing::DoubleNear(1/sq, 0.00001)); EXPECT_THAT(unit[1], ::testing::DoubleNear(2/sq, 0.00001)); EXPECT_THAT(unit[2], ::testing::DoubleNear(3/sq, 0.00001)); } TEST(Vector, CanCastEntireVectorThroughConstructor) { EXPECT_THAT((vec3i(vec3{{1.0, 2.3, 3.9}})), iota3i()); } TEST(Vector, SwapExchangesAllValues) { using std::swap; vec2i a{{1, 2}}; const vec2i ac = a; vec2i b{{5, 7}}; const vec2i bc = b; swap(a, b); EXPECT_THAT(a, bc); EXPECT_THAT(b, ac); } TEST(Vector, UnaryNegateOperatorNegatesAllElements) { EXPECT_THAT(-iota3i(), (vec3i{{-1,-2,-3}})); } TEST(Vector, AbsoluteValueOfVectorAbsAllElements) { EXPECT_THAT(iota3i(), abs(-iota3i())); } TEST(Vector, MakeVectorAllowsConstuctionFromVariadicComponents) { EXPECT_TRUE((std::is_same::value)); EXPECT_THAT(iota2i(), make_vector(1, 2)); EXPECT_FALSE((std::is_same::value)); EXPECT_TRUE((std::is_same::value)); EXPECT_THAT(iota3i(), make_vector(1, 2, 3)); }