Skip to content

Commit

Permalink
Add < and > matchers
Browse files Browse the repository at this point in the history
  • Loading branch information
slonopotamus committed Aug 3, 2024
1 parent 11622df commit d8f335e
Show file tree
Hide file tree
Showing 2 changed files with 144 additions and 97 deletions.
6 changes: 5 additions & 1 deletion Source/UEST/Private/UESTTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,13 @@ TEST(UEST, SimpleTest)
const int v2 = 42;
ASSERT_THAT(&v2, Is::Not::Null);

ASSERT_THAT(42, Is::EqualTo(42));
// TODO: Need explicit <int> for now because of clang bug: https://github.com/llvm/llvm-project/issues/73093
ASSERT_THAT(42, Is::EqualTo<int>(42));
ASSERT_THAT(42, Is::Not::EqualTo<int>(43));
ASSERT_THAT(42, Is::LessThan<int>(43));
ASSERT_THAT(42, Is::Not::LessThan<int>(41));
ASSERT_THAT(42, Is::GreaterThan<int>(41));
ASSERT_THAT(42, Is::Not::GreaterThan<int>(43));
}

TEST_CLASS(UEST, SimpleTestClass)
Expand Down
235 changes: 139 additions & 96 deletions Source/UEST/Public/UEST.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,131 +13,176 @@ struct IMatcher
virtual FString Describe() const = 0;
};

namespace Matchers
namespace UEST
{
static constexpr struct Null
namespace Matchers
{
template<typename T>
requires std::is_pointer_v<T> || std::is_null_pointer_v<T>
struct Matcher final : IMatcher<T>
static constexpr struct Null
{
virtual bool Matches(const T& Value) const override
template<typename T>
requires std::is_pointer_v<T> || std::is_null_pointer_v<T>
struct Matcher final : IMatcher<T>
{
virtual bool Matches(const T& Value) const override
{
return Value == nullptr;
}

virtual FString Describe() const override
{
return TEXT("be nullptr");
}
};

template<typename T>
auto operator()() const
{
return Value == nullptr;
return Matcher<T>();
}
} Null;

virtual FString Describe() const override
static constexpr struct True
{
template<typename T>
requires std::same_as<T, bool>
struct Matcher final : IMatcher<T>
{
return TEXT("be nullptr");
virtual bool Matches(const T& Value) const override
{
return Value;
}

virtual FString Describe() const override
{
return TEXT("be true");
}
};

template<typename T>
auto operator()() const
{
return Matcher<T>();
}
};
} True;

template<typename T>
auto operator()() const
static constexpr struct False
{
return Matcher<T>();
}
} Null;
template<typename T>
requires std::same_as<T, bool>
struct Matcher final : IMatcher<T>
{
virtual bool Matches(const T& Value) const override
{
return !Value;
}

virtual FString Describe() const override
{
return TEXT("be false");
}
};

template<typename T>
auto operator()() const
{
return Matcher<T>();
}
} False;

static constexpr struct True
{
template<typename T>
requires std::same_as<T, bool>
struct Matcher final : IMatcher<T>
struct EqualTo final : IMatcher<T>
{
T Expected;

EqualTo(T Expected)
: Expected(Expected)
{
}

virtual bool Matches(const T& Value) const override
{
return Value;
return Value == Expected;
}

virtual FString Describe() const override
{
return TEXT("be true");
return FString::Printf(TEXT("be equal to %s"), *CQTestConvert::ToString(Expected));
}
};

template<typename T>
auto operator()() const
struct LessThan final : IMatcher<T>
{
return Matcher<T>();
}
} True;
T Expected;

LessThan(T Expected)
: Expected(Expected)
{
}

static constexpr struct False
{
template<typename T>
requires std::same_as<T, bool>
struct Matcher final : IMatcher<T>
{
virtual bool Matches(const T& Value) const override
{
return !Value;
return Value < Expected;
}

virtual FString Describe() const override
{
return TEXT("be false");
return FString::Printf(TEXT("be less than %s"), *CQTestConvert::ToString(Expected));
}
};

template<typename T>
auto operator()() const
struct GreaterThan final : IMatcher<T>
{
return Matcher<T>();
}
} False;
T Expected;

template<typename T>
struct EqualTo final : IMatcher<T>
{
T Expected;
GreaterThan(T Expected)
: Expected(Expected)
{
}

EqualTo(T Expected)
: Expected(Expected)
{
}
virtual bool Matches(const T& Value) const override
{
return Value > Expected;
}

virtual bool Matches(const T& Value) const override
{
return Value == Expected;
}
virtual FString Describe() const override
{
return FString::Printf(TEXT("be greater than %s"), *CQTestConvert::ToString(Expected));
}
};

virtual FString Describe() const override
template<typename T, typename M>
struct Not : IMatcher<T>
{
return FString::Printf(TEXT("be equal to %s"), *CQTestConvert::ToString(Expected));
}
};
M Nested;

template<typename T, typename M>
struct NotMatcher : IMatcher<T>
{
M Nested;
Not() = default;

NotMatcher() = default;
Not(M&& Nested)
: Nested(MoveTemp(Nested))
{}

NotMatcher(M&& Nested)
: Nested(MoveTemp(Nested))
{}

virtual bool Matches(const T& Value) const override
{
return !Nested.Matches(Value);
}
virtual bool Matches(const T& Value) const override
{
return !Nested.Matches(Value);
}

virtual FString Describe() const override
{
return FString::Printf(TEXT("not %s"), *Nested.Describe());
}
};
virtual FString Describe() const override
{
return FString::Printf(TEXT("not %s"), *Nested.Describe());
}
};
}

template <typename T, typename M, typename... P>
template <typename M, typename... P>
// TODO: Add requires
struct PassthroughNot
struct Passthrough
{
NotMatcher<T, M> Matcher;
M Matcher;

explicit PassthroughNot(P... Args)
: Matcher{NotMatcher<T, M>{Args...}}
explicit Passthrough(P... Args)
: Matcher{Args...}
{}

template<typename U>
Expand All @@ -150,26 +195,18 @@ namespace Matchers

namespace Is
{
constexpr const auto& Null = Matchers::Null;
constexpr const auto& True = Matchers::True;
constexpr const auto& False = Matchers::False;
constexpr const auto& Null = UEST::Matchers::Null;
constexpr const auto& True = UEST::Matchers::True;
constexpr const auto& False = UEST::Matchers::False;

template<typename T>
struct EqualTo
{
T Expected;
using EqualTo = UEST::Passthrough<UEST::Matchers::EqualTo<T>, T>;

EqualTo(T Expected)
: Expected(Expected)
{}
template<typename T>
using LessThan = UEST::Passthrough<UEST::Matchers::LessThan<T>, T>;

template<typename U>
requires std::is_convertible_v<T, U>
auto operator()() const
{
return Matchers::EqualTo<T>{Expected};
}
};
template<typename T>
using GreaterThan = UEST::Passthrough<UEST::Matchers::GreaterThan<T>, T>;

namespace Not
{
Expand All @@ -178,7 +215,7 @@ namespace Is
template<typename T>
auto operator()() const
{
return Matchers::NotMatcher<T, Matchers::Null::Matcher<T>>{};
return UEST::Matchers::Not<T, UEST::Matchers::Null::Matcher<T>>{};
}
} Null;

Expand All @@ -187,7 +224,7 @@ namespace Is
template<typename T>
auto operator()() const
{
return Matchers::False::Matcher<T>{};
return UEST::Matchers::False::Matcher<T>{};
}
} True;

Expand All @@ -196,12 +233,18 @@ namespace Is
template<typename T>
auto operator()() const
{
return Matchers::True::Matcher<T>{};
return UEST::Matchers::True::Matcher<T>{};
}
} False;

template<typename T>
using EqualTo = Matchers::PassthroughNot<T, Matchers::EqualTo<T>, T>;
using EqualTo = UEST::Passthrough<UEST::Matchers::Not<T, UEST::Matchers::EqualTo<T>>, T>;

template<typename T>
using LessThan = UEST::Passthrough<UEST::Matchers::Not<T, UEST::Matchers::LessThan<T>>, T>;

template<typename T>
using GreaterThan = UEST::Passthrough<UEST::Matchers::Not<T, UEST::Matchers::GreaterThan<T>>, T>;
}
}

Expand Down

0 comments on commit d8f335e

Please sign in to comment.