From a14fbd90dbc2ba7b0dfd922f9ab9d111f4d1b1ec Mon Sep 17 00:00:00 2001 From: Redstone1024 <2824517378@qq.com> Date: Fri, 20 Dec 2024 15:35:44 +0800 Subject: [PATCH] test(range): add test for range library --- .../Source/Private/Testing/Range.cpp | 471 ++++++++++++++++++ .../Source/Public/Testing/Testing.h | 1 + 2 files changed, 472 insertions(+) create mode 100644 Redcraft.Utility/Source/Private/Testing/Range.cpp diff --git a/Redcraft.Utility/Source/Private/Testing/Range.cpp b/Redcraft.Utility/Source/Private/Testing/Range.cpp new file mode 100644 index 0000000..953e30c --- /dev/null +++ b/Redcraft.Utility/Source/Private/Testing/Range.cpp @@ -0,0 +1,471 @@ +#include "Testing/Testing.h" + +#include "Range/Range.h" +#include "Containers/Array.h" +#include "Containers/List.h" +#include "Miscellaneous/AssertionMacros.h" + +NAMESPACE_REDCRAFT_BEGIN +NAMESPACE_MODULE_BEGIN(Redcraft) +NAMESPACE_MODULE_BEGIN(Utility) + +NAMESPACE_BEGIN(Testing) + +NAMESPACE_PRIVATE_BEGIN + +void TestConversion() +{ + { + const TArray Arr = { 1, 2, 3, 4, 5 }; + const TList List = { 1, 2, 3, 4, 5 }; + + const TArray Brr = Range::View(List.Begin(), List.End()) | Range::To>(); + const TList Mist = Range::View(Arr.Begin(), Arr.End()) | Range::To>(); + + always_check(Arr == Brr); + always_check(List == Mist); + } + + { + const TArray Arr = { 1, 2, 3, 4, 5 }; + const TList List = { 1, 2, 3, 4, 5 }; + + const TArray Brr = Range::View(List.Begin(), List.End()) | Range::To(); + const TList Mist = Range::View(Arr.Begin(), Arr.End()) | Range::To(); + + always_check(Arr == Brr); + always_check(List == Mist); + } +} + +void TestFactory() +{ + { + const TArray Arr = { }; + const TArray Brr = Range::Empty | Range::To>(); + + always_check(Arr == Brr); + } + + { + const TArray Arr = { 1 }; + const TArray Brr = Range::Single(1) | Range::To>(); + + always_check(Arr == Brr); + } + + { + const TArray Arr = { 0, 1, 2, 3, 4 }; + const TArray Brr = Range::Iota(0, 5) | Range::To>(); + + always_check(Arr == Brr); + } + + { + auto View = Range::Iota(0, 5); + + always_check(View.Num() == 5); + always_check(!View.IsEmpty()); + always_check(!!View); + + always_check(View.Front() == 0); + + auto First = View.Begin(); + auto Last = View.End(); + + auto ConstFirst = AsConst(View).Begin(); + auto ConstLast = AsConst(View).End(); + + always_check(First == ConstFirst); + always_check(Last == ConstLast ); + + ConstFirst = First; + ConstLast = Last; + + auto Iter = ConstFirst; + auto Jter = ConstLast; + + ++Iter; + + always_check(*Iter++ == 1); + } + + { + auto View = Range::Iota(0); + + always_check(!View.IsEmpty()); + always_check(!!View); + + always_check(View.Front() == 0); + + auto First = View.Begin(); + auto Last = View.End(); + + auto ConstFirst = AsConst(View).Begin(); + auto ConstLast = AsConst(View).End(); + + always_check(First == ConstFirst); + + ConstFirst = First; + ConstLast = Last; + + auto Iter = ConstFirst; + auto Jter = ConstLast; + + ++Iter; + + always_check(*Iter++ == 1); + } + + { + const TArray Arr = { 0, 0, 0, 0, 0 }; + const TArray Brr = Range::Repeat(0, 5) | Range::To>(); + + always_check(Arr == Brr); + } + + { + auto View = Range::Repeat(0, 8); + + always_check(View.Num() == 8); + always_check(!View.IsEmpty()); + always_check(!!View); + + always_check(View.Front() == 0); + always_check(View.Back() == 0); + + auto First = View.Begin(); + auto Last = View.End(); + + auto ConstFirst = AsConst(View).Begin(); + auto ConstLast = AsConst(View).End(); + + always_check(First == ConstFirst); + always_check(Last == ConstLast ); + + always_check(ConstLast - First == 8); + + ConstFirst = First; + ConstLast = Last; + + auto Iter = ConstFirst; + auto Jter = ConstLast; + + ++Iter; + --Jter; + + always_check(*Iter++ == 0); + always_check(*Jter-- == 0); + + Iter += 2; + Jter -= 2; + + always_check(Iter[-1] == 0); + always_check(Jter[ 1] == 0); + + Iter = Iter - 2; + Jter = Jter + 2; + + always_check(*Iter == 0); + always_check(*Jter == 0); + + Iter = 2 + Iter; + Jter = Jter - 2; + + always_check(Iter - Jter == 0); + } + + { + auto View = Range::Repeat(0); + + always_check(!View.IsEmpty()); + always_check(!!View); + + always_check(View.Front() == 0); + + auto First = View.Begin(); + auto Last = View.End(); + + auto ConstFirst = AsConst(View).Begin(); + auto ConstLast = AsConst(View).End(); + + always_check(First == ConstFirst); + + ConstFirst = First; + ConstLast = Last; + + auto Iter = ConstFirst; + auto Jter = ConstFirst + 8; + + ++Iter; + --Jter; + + always_check(*Iter++ == 0); + always_check(*Jter-- == 0); + + Iter += 2; + Jter -= 2; + + always_check(Iter[-1] == 0); + always_check(Jter[ 1] == 0); + + Iter = Iter - 2; + Jter = Jter + 2; + + always_check(*Iter == 0); + always_check(*Jter == 0); + + Iter = 2 + Iter; + Jter = Jter - 2; + + always_check(Iter - Jter == 0); + } +} + +void TestAllView() +{ + TArray Arr = { 0, 1, 2, 3, 4 }; + + TArray Brr = Range::All(Arr) | Range::To>(); + + always_check(Arr == Brr); + + auto View = Range::All(MoveTemp(Arr)); + + Arr.Reset(); + + TArray Crr = View | Range::To>(); + + always_check(Brr == Crr); +} + +void TestMoveView() +{ + { + struct FTracker + { + FTracker() = default; + FTracker(const FTracker&) { always_check_no_entry(); } + FTracker(FTracker&&) = default; + ~FTracker() = default; + FTracker& operator=(const FTracker&) { always_check_no_entry(); } + FTracker& operator=(FTracker&&) = default; + }; + + FTracker Arr[2]; + + auto View = Arr | Range::Move(); + + auto First = View.Begin(); + auto Last = View.End(); + + FTracker Temp(*First++); + + Temp = *First++; + + always_check(First == Last); + } + + { + TArray Arr = { 0, 1, 2, 3, 4, 5, 6, 7 }; + + auto View = Arr | Range::Move(); + + always_check(View.Num() == 8); + always_check(!View.IsEmpty()); + always_check(!!View); + + always_check(View.Front() == 0); + always_check(View.Back() == 7); + + auto First = View.Begin(); + auto Last = View.End(); + + auto ConstFirst = AsConst(View).Begin(); + auto ConstLast = AsConst(View).End(); + + always_check(First == ConstFirst); + always_check(Last == ConstLast ); + + always_check(ConstLast - First == 8); + + ConstFirst = First; + ConstLast = Last; + + auto Iter = ConstFirst; + auto Jter = ConstLast; + + ++Iter; + --Jter; + + always_check(*Iter++ == 1); + always_check(*Jter-- == 7); + + Iter += 2; + Jter -= 2; + + always_check(Iter[-1] == 3); + always_check(Jter[ 1] == 5); + + Iter = Iter - 2; + Jter = Jter + 2; + + always_check(*Iter == 2); + always_check(*Jter == 6); + + Iter = 2 + Iter; + Jter = Jter - 2; + + always_check(Iter - Jter == 0); + } + + { + auto View = Range::Iota(0) | Range::Move(); + + always_check(!View.IsEmpty()); + always_check(!!View); + + always_check(View.Front() == 0); + + auto First = View.Begin(); + auto Last = View.End(); + + auto ConstFirst = AsConst(View).Begin(); + auto ConstLast = AsConst(View).End(); + + always_check(First == ConstFirst); + + ConstFirst = First; + ConstLast = Last; + + auto Iter = ConstFirst; + auto Jter = ConstLast; + + ++Iter; + + always_check(*Iter++ == 1); + } +} + +void TestMiscView() +{ + { + TArray Arr = { 0, 1, 2, 3, 4, 5, 6, 7 }; + TArray Brr = { 0, 2, 4, 6 }; + + TArray Crr = Arr + | Range::Filter([](int Value) { return Value % 2 == 0; }) + | Range::To>(); + + always_check(Brr == Crr); + } + + { + TArray Arr = { 0, 1, 2, 2, 1, 0 }; + TArray Brr = { 0, 2, 4, 4, 2, 0 }; + + TArray Crr = Arr + | Range::Transform([](int Value) { return Value * 2; }) + | Range::To>(); + + always_check(Brr == Crr); + } + + { + TArray Arr = { 0, 1, 2, 3, 3, 2, 1, 0 }; + TArray Brr = { 0, 2, 4, 4, 2, 0 }; + + TArray Crr = Arr + | Range::Filter ([](int Value) { return Value < 3; }) + | Range::Transform([](int Value) { return Value * 2; }) + | Range::To>(); + + TArray Drr = Arr + | Range::Transform([](int Value) { return Value * 2; }) + | Range::Filter ([](int Value) { return Value < 6; }) + | Range::To>(); + + always_check(Brr == Crr); + always_check(Brr == Drr); + } + + { + TArray Arr = { 0, 1, 2, 3, 4, 5, 6, 7 }; + + TArray Brr = Range::Iota(0) + | Range::Take(8) + | Range::To>(); + + TArray Crr = Range::Iota(0) + | Range::TakeWhile([](int Value) { return Value < 8; }) + | Range::To>(); + + always_check(Arr == Brr); + always_check(Arr == Crr); + } + + { + TArray Arr = { 0, 4, 7, 8, 3, 1, 10 }; + TArray Brr = { 0, 2, 4 }; + + TArray Crr = Arr + | Range::Filter ([](int Value) { return Value % 2 == 0; }) + | Range::Take(3) + | Range::Transform([](int Value) { return Value / 2; }) + | Range::To>(); + + TArray Drr = Arr + | Range::Filter ([](int Value) { return Value % 2 == 0; }) + | Range::TakeWhile([](int Value) { return Value < 10; }) + | Range::Transform([](int Value) { return Value / 2; }) + | Range::To>(); + + TArray Err = Arr + | Range::Filter ([](int Value) { return Value % 2 == 0; }) + | Range::Transform([](int Value) { return Value / 2; }) + | Range::Take(3) + | Range::To>(); + + TArray Frr = Arr + | Range::Filter ([](int Value) { return Value % 2 == 0; }) + | Range::Transform([](int Value) { return Value / 2; }) + | Range::TakeWhile([](int Value) { return Value < 5; }) + | Range::To>(); + + TArray Grr = Arr + | Range::Take(6) + | Range::Filter ([](int Value) { return Value % 2 == 0; }) + | Range::Transform([](int Value) { return Value / 2; }) + | Range::To>(); + + TArray Hrr = Arr + | Range::TakeWhile([](int Value) { return Value < 10; }) + | Range::Filter ([](int Value) { return Value % 2 == 0; }) + | Range::Transform([](int Value) { return Value / 2; }) + | Range::To>(); + + always_check(Brr == Crr); + always_check(Brr == Drr); + always_check(Brr == Err); + always_check(Brr == Frr); + always_check(Brr == Grr); + always_check(Brr == Hrr); + } +} + +NAMESPACE_PRIVATE_END + +void TestRange() +{ + NAMESPACE_PRIVATE::TestConversion(); + NAMESPACE_PRIVATE::TestFactory(); + NAMESPACE_PRIVATE::TestAllView(); + NAMESPACE_PRIVATE::TestMoveView(); + NAMESPACE_PRIVATE::TestMiscView(); +} + +NAMESPACE_END(Testing) + +NAMESPACE_MODULE_END(Utility) +NAMESPACE_MODULE_END(Redcraft) +NAMESPACE_REDCRAFT_END diff --git a/Redcraft.Utility/Source/Public/Testing/Testing.h b/Redcraft.Utility/Source/Public/Testing/Testing.h index 2757bc3..823b6cf 100644 --- a/Redcraft.Utility/Source/Public/Testing/Testing.h +++ b/Redcraft.Utility/Source/Public/Testing/Testing.h @@ -12,6 +12,7 @@ REDCRAFTUTILITY_API void TestTypeTraits(); REDCRAFTUTILITY_API void TestTemplates(); REDCRAFTUTILITY_API void TestNumeric(); REDCRAFTUTILITY_API void TestIterator(); +REDCRAFTUTILITY_API void TestRange(); REDCRAFTUTILITY_API void TestMemory(); REDCRAFTUTILITY_API void TestContainers(); REDCRAFTUTILITY_API void TestString();