Unit tests for Vector2 extensions
Also adds ApproxVec and ApproxDeg types for more readable comparison of approximate vectors/angles.
This commit is contained in:
parent
70eeba5067
commit
2eef193c0e
@ -4,7 +4,12 @@
|
|||||||
|
|
||||||
#include <doctest.h>
|
#include <doctest.h>
|
||||||
|
|
||||||
// Use sf::Vector2i for tests. Test coverage is given, as there are no template specializations.
|
using namespace sf::Literals;
|
||||||
|
using doctest::Approx;
|
||||||
|
|
||||||
|
// Use sf::Vector2i for tests (except for float vector algebra).
|
||||||
|
// Test coverage is given, as there are no template specializations.
|
||||||
|
|
||||||
|
|
||||||
TEST_CASE("sf::Vector2 class template - [system]")
|
TEST_CASE("sf::Vector2 class template - [system]")
|
||||||
{
|
{
|
||||||
@ -184,11 +189,97 @@ TEST_CASE("sf::Vector2 class template - [system]")
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SUBCASE("Length and normalization")
|
||||||
|
{
|
||||||
|
sf::Vector2f v(2.4f, 3.0f);
|
||||||
|
|
||||||
|
CHECK(v.length() == Approx(3.84187));
|
||||||
|
CHECK(v.lengthSq() == Approx(14.7599650969));
|
||||||
|
CHECK(v.normalized() == ApproxVec(0.624695, 0.780869));
|
||||||
|
|
||||||
|
sf::Vector2f w(-0.7f, -2.2f);
|
||||||
|
|
||||||
|
CHECK(w.length() == Approx(2.30868));
|
||||||
|
CHECK(w.lengthSq() == Approx(5.3300033));
|
||||||
|
CHECK(w.normalized() == ApproxVec(-0.303204, -0.952926));
|
||||||
|
}
|
||||||
|
|
||||||
|
SUBCASE("Rotations and angles")
|
||||||
|
{
|
||||||
|
sf::Vector2f v(2.4f, 3.0f);
|
||||||
|
|
||||||
|
CHECK(v.angle() == ApproxDeg(51.3402));
|
||||||
|
CHECK(sf::Vector2f::UnitX.angleTo(v) == ApproxDeg(51.3402));
|
||||||
|
CHECK(sf::Vector2f::UnitY.angleTo(v) == ApproxDeg(-38.6598));
|
||||||
|
|
||||||
|
sf::Vector2f w(-0.7f, -2.2f);
|
||||||
|
|
||||||
|
CHECK(w.angle() == ApproxDeg(-107.65));
|
||||||
|
CHECK(sf::Vector2f::UnitX.angleTo(w) == ApproxDeg(-107.65));
|
||||||
|
CHECK(sf::Vector2f::UnitY.angleTo(w) == ApproxDeg(162.35));
|
||||||
|
|
||||||
|
CHECK(v.angleTo(w) == ApproxDeg(-158.9902));
|
||||||
|
CHECK(w.angleTo(v) == ApproxDeg(158.9902));
|
||||||
|
|
||||||
|
float ratio = w.length() / v.length();
|
||||||
|
CHECK(v.rotatedBy(-158.9902_deg) * ratio == ApproxVec(w));
|
||||||
|
CHECK(w.rotatedBy(158.9902_deg) / ratio == ApproxVec(v));
|
||||||
|
|
||||||
|
CHECK(v.perpendicular() == sf::Vector2f(-3.0f, 2.4f));
|
||||||
|
CHECK(v.perpendicular().perpendicular().perpendicular().perpendicular() == v);
|
||||||
|
|
||||||
|
CHECK(v.rotatedBy(90_deg) == ApproxVec(-3.0, 2.4));
|
||||||
|
CHECK(v.rotatedBy(27.14_deg) == ApproxVec(0.767248, 3.76448));
|
||||||
|
CHECK(v.rotatedBy(-36.11_deg) == ApproxVec(3.70694, 1.00925));
|
||||||
|
}
|
||||||
|
|
||||||
|
SUBCASE("Products and quotients")
|
||||||
|
{
|
||||||
|
sf::Vector2f v(2.4f, 3.0f);
|
||||||
|
sf::Vector2f w(-0.7f, -2.2f);
|
||||||
|
|
||||||
|
CHECK(v.dot(w) == Approx(-8.28));
|
||||||
|
CHECK(w.dot(v) == Approx(-8.28));
|
||||||
|
|
||||||
|
CHECK(v.cross(w) == Approx(-3.18));
|
||||||
|
CHECK(w.cross(v) == Approx(+3.18));
|
||||||
|
|
||||||
|
CHECK(v.cwiseMul(w) == ApproxVec(-1.68, -6.6));
|
||||||
|
CHECK(w.cwiseMul(v) == ApproxVec(-1.68, -6.6));
|
||||||
|
CHECK(v.cwiseDiv(w) == ApproxVec(-3.428571, -1.363636));
|
||||||
|
CHECK(w.cwiseDiv(v) == ApproxVec(-0.291666, -0.733333));
|
||||||
|
}
|
||||||
|
|
||||||
|
SUBCASE("Projection")
|
||||||
|
{
|
||||||
|
sf::Vector2f v(2.4f, 3.0f);
|
||||||
|
sf::Vector2f w(-0.7f, -2.2f);
|
||||||
|
|
||||||
|
CHECK(v.projectedOnto(w) == ApproxVec(1.087430, 3.417636));
|
||||||
|
CHECK(v.projectedOnto(w) == ApproxVec(-1.55347f * w));
|
||||||
|
|
||||||
|
CHECK(w.projectedOnto(v) == ApproxVec(-1.346342, -1.682927));
|
||||||
|
CHECK(w.projectedOnto(v) == ApproxVec(-0.560976f * v));
|
||||||
|
|
||||||
|
CHECK(v.projectedOnto(sf::Vector2f::UnitX) == ApproxVec(2.4, 0.0));
|
||||||
|
CHECK(v.projectedOnto(sf::Vector2f::UnitY) == ApproxVec(0.0, 3.0));
|
||||||
|
}
|
||||||
|
|
||||||
SUBCASE("Constexpr support")
|
SUBCASE("Constexpr support")
|
||||||
{
|
{
|
||||||
constexpr sf::Vector2i vector(1, 2);
|
constexpr sf::Vector2i v(1, 2);
|
||||||
static_assert(vector.x == 1);
|
constexpr sf::Vector2i w(2, -3);
|
||||||
static_assert(vector.y == 2);
|
|
||||||
static_assert(vector + sf::Vector2i(2, 1) == sf::Vector2i(3, 3));
|
static_assert(v.x == 1);
|
||||||
|
static_assert(v.y == 2);
|
||||||
|
static_assert(v + w == sf::Vector2i(3, -1));
|
||||||
|
|
||||||
|
static_assert(v.lengthSq() == 5);
|
||||||
|
static_assert(v.perpendicular() == sf::Vector2i(-2, 1));
|
||||||
|
|
||||||
|
static_assert(v.dot(w) == -4);
|
||||||
|
static_assert(v.cross(w) == -7);
|
||||||
|
static_assert(v.cwiseMul(w) == sf::Vector2i(2, -6));
|
||||||
|
static_assert(w.cwiseDiv(v) == sf::Vector2i(2, -1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include <SFML/System/String.hpp>
|
#include <SFML/System/String.hpp>
|
||||||
#include <SFML/System/Time.hpp>
|
#include <SFML/System/Time.hpp>
|
||||||
|
|
||||||
|
#include <doctest.h> // for Approx
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
@ -34,6 +35,28 @@ namespace sf
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool operator==(const sf::Vector2f& lhs, const ApproxVec& rhs)
|
||||||
|
{
|
||||||
|
return (lhs - rhs.vector).length() == doctest::Approx(0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const sf::Angle& lhs, const ApproxDeg& rhs)
|
||||||
|
{
|
||||||
|
return lhs.asDegrees() == doctest::Approx(rhs.degrees);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream& operator <<(std::ostream& os, const ApproxVec& approx)
|
||||||
|
{
|
||||||
|
os << approx.vector;
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream& operator <<(std::ostream& os, const ApproxDeg& approx)
|
||||||
|
{
|
||||||
|
os << sf::degrees(approx.degrees);
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
namespace sf::Testing
|
namespace sf::Testing
|
||||||
{
|
{
|
||||||
static std::string getTemporaryFilePath()
|
static std::string getTemporaryFilePath()
|
||||||
|
@ -39,6 +39,33 @@ namespace sf
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Utilities for approximate equality
|
||||||
|
struct ApproxVec
|
||||||
|
{
|
||||||
|
ApproxVec(double x, double y)
|
||||||
|
: vector(static_cast<float>(x), static_cast<float>(y)) {}
|
||||||
|
|
||||||
|
explicit ApproxVec(const sf::Vector2f& v)
|
||||||
|
: vector(v) {}
|
||||||
|
|
||||||
|
sf::Vector2f vector;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Utilities for approximate equality
|
||||||
|
struct ApproxDeg
|
||||||
|
{
|
||||||
|
ApproxDeg(double degrees)
|
||||||
|
: degrees(static_cast<float>(degrees)) {}
|
||||||
|
|
||||||
|
float degrees;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool operator==(const sf::Vector2f& lhs, const ApproxVec& rhs);
|
||||||
|
bool operator==(const sf::Angle& lhs, const ApproxDeg& rhs);
|
||||||
|
|
||||||
|
std::ostream& operator <<(std::ostream& os, const ApproxVec& approx);
|
||||||
|
std::ostream& operator <<(std::ostream& os, const ApproxDeg& approx);
|
||||||
|
|
||||||
namespace sf::Testing
|
namespace sf::Testing
|
||||||
{
|
{
|
||||||
class TemporaryFile
|
class TemporaryFile
|
||||||
|
Loading…
Reference in New Issue
Block a user