From a40d298b5df981b70cf08d2d030673d1114714e6 Mon Sep 17 00:00:00 2001 From: Ashar Fuadi Date: Sun, 27 Oct 2024 17:01:17 +0700 Subject: [PATCH] Validator: refactor vector validators to core --- CMakeLists.txt | 2 - include/tcframe/validator/core.hpp | 87 +++++++++++++++++++ include/tcframe/validator/vector.hpp | 64 -------------- .../tcframe/validator/CoreValidatorTests.cpp | 49 +++++++++++ .../validator/VectorValidatorTests.cpp | 60 ------------- 5 files changed, 136 insertions(+), 126 deletions(-) delete mode 100644 include/tcframe/validator/vector.hpp delete mode 100644 test/unit/tcframe/validator/VectorValidatorTests.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 3f2a71f..2ddd01a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -165,7 +165,6 @@ set(INCLUDE include/tcframe/util/StringUtils.hpp include/tcframe/util/optional.hpp include/tcframe/validator/core.hpp - include/tcframe/validator/vector.hpp ) set(TEST_UNIT @@ -261,7 +260,6 @@ set(TEST_UNIT test/unit/tcframe/util/StringUtilsTests.cpp test/unit/tcframe/util/TestUtils.hpp test/unit/tcframe/validator/CoreValidatorTests.cpp - test/unit/tcframe/validator/VectorValidatorTests.cpp ) add_executable(test_unit ${INCLUDE} ${TEST_UNIT}) diff --git a/include/tcframe/validator/core.hpp b/include/tcframe/validator/core.hpp index 51eaf08..04310b1 100644 --- a/include/tcframe/validator/core.hpp +++ b/include/tcframe/validator/core.hpp @@ -3,6 +3,8 @@ using std::enable_if_t; using std::is_arithmetic_v; +using std::size_t; +using std::vector; namespace tcframe { @@ -27,4 +29,89 @@ ScalarValidator valueOf(T val) { return ScalarValidator(val); } +template> +struct VectorElementValidator { +private: + const vector& val; + +public: + explicit VectorElementValidator(const vector& _val) : val(_val) {} + + bool isBetween(T minVal, T maxVal) { + for (T v : val) { + if (!valueOf(v).isBetween(minVal, maxVal)) { + return false; + } + } + return true; + } +}; + +template> +VectorElementValidator eachElementOf(const vector& val) { + return VectorElementValidator(val); +} + +template> +VectorElementValidator eachElementOf(vector&& val) { + return VectorElementValidator(val); +} + +template> +struct VectorElementsValidator { +private: + const vector& val; + +public: + explicit VectorElementsValidator(const vector& _val) : val(_val) {} + + bool areAscending() { + for (size_t i = 1; i < val.size(); ++i) { + if (val[i - 1] >= val[i]) { + return false; + } + } + return true; + } + + bool areDescending() { + for (size_t i = 1; i < val.size(); ++i) { + if (val[i - 1] >= val[i]) { + return false; + } + } + return true; + } + + bool areNonAscending() { + for (size_t i = 1; i < val.size(); ++i) { + if (val[i - 1] < val[i]) { + return false; + } + } + return true; + } + + bool areNonDescending() { + for (size_t i = 1; i < val.size(); ++i) { + if (val[i - 1] > val[i]) { + return false; + } + } + return true; + } + + bool areUnique() { + vector v = *val; + sort(v.begin(), v.end()); + size_t ns = unique(v.begin(), v.end()) - v.begin(); + return ns == v.size(); + } +}; + +template> +VectorElementsValidator elementsOf(const vector& val) { + return VectorElementsValidator(val); +} + } diff --git a/include/tcframe/validator/vector.hpp b/include/tcframe/validator/vector.hpp deleted file mode 100644 index 5819bc2..0000000 --- a/include/tcframe/validator/vector.hpp +++ /dev/null @@ -1,64 +0,0 @@ -#include - -using std::vector; - -namespace tcframe { - -template -bool eachElementIsBetween(const vector& v, T minVal, T maxVal) { - for (T x : v) { - if (x < minVal || x > maxVal) { - return false; - } - } - return true; -} - -template -bool elementsAreNonDescending(const vector& v) { - for (std::size_t i = 1; i < v.size(); ++i) { - if (v[i - 1] > v[i]) { - return false; - } - } - return true; -} - -template -bool elementsAreNonAscending(const vector &v) { - for (std::size_t i = 1; i < v.size(); ++i) { - if (v[i - 1] < v[i]) { - return false; - } - } - return true; -} - -template -bool elementsAreDescending(const vector& v) { - for (std::size_t i = 1; i < v.size(); ++i) { - if (v[i - 1] <= v[i]) { - return false; - } - } - return true; -} - -template -bool elementsAreAscending(const vector &v) { - for (std::size_t i = 1; i < v.size(); ++i) { - if (v[i - 1] >= v[i]) { - return false; - } - } - return true; -} - -template -bool elementsAreUnique(vector v) { - sort(v.begin(), v.end()); - std::size_t ns = unique(v.begin(), v.end()) - v.begin(); - return ns == v.size(); -} - -} diff --git a/test/unit/tcframe/validator/CoreValidatorTests.cpp b/test/unit/tcframe/validator/CoreValidatorTests.cpp index 5d38541..36b738b 100644 --- a/test/unit/tcframe/validator/CoreValidatorTests.cpp +++ b/test/unit/tcframe/validator/CoreValidatorTests.cpp @@ -18,4 +18,53 @@ TEST_F(CoreValidatorTests, valueOf_isBetween) { EXPECT_TRUE(valueOf(5).isBetween(0, 10)); } +TEST_F(CoreValidatorTests, eachElementOf_isBetween) { + EXPECT_FALSE(eachElementOf(vector{2, 3, 1, 5, 4}).isBetween(1, 4)); + EXPECT_FALSE(eachElementOf(vector{2, 3, 1, 5, 4}).isBetween(2, 5)); + EXPECT_FALSE(eachElementOf(vector{2, 3, 1, 5, 4}).isBetween(2, 4)); + EXPECT_TRUE(eachElementOf(vector{2, 3, 1, 5, 4}).isBetween(1, 5)); + EXPECT_TRUE(eachElementOf(vector{2, 3, 1, 5, 4}).isBetween(0, 6)); +} + + +TEST_F(CoreValidatorTests, elementsOf_areAscending) { + EXPECT_FALSE(elementsOf(vector{1, 2, 3, 5, 3}).areAscending()); + EXPECT_FALSE(elementsOf(vector{2, 1, 1, 2, 5}).areAscending()); + EXPECT_FALSE(elementsOf(vector{1, 1, 2, 3, 3, 7}).areAscending()); + EXPECT_TRUE(elementsOf(vector()).areAscending()); + EXPECT_TRUE(elementsOf(vector{1, 2, 3, 4, 5}).areAscending()); +} + +TEST_F(CoreValidatorTests, elementsOf_areDescending) { + EXPECT_FALSE(elementsOf(vector{3, 5, 3, 2, 1}).areDescending()); + EXPECT_FALSE(elementsOf(vector{5, 2, 1, 1, 2}).areDescending()); + EXPECT_FALSE(elementsOf(vector{7, 3, 3, 2, 1, 1}).areDescending()); + EXPECT_TRUE(elementsOf(vector()).areDescending()); + EXPECT_TRUE(elementsOf(vector{5, 4, 3, 2, 1}).areDescending()); +} + +TEST_F(CoreValidatorTests, elementsOf_areNonAscending) { + EXPECT_FALSE(elementsOf(vector{3, 5, 3, 2, 1}).areNonAscending()); + EXPECT_FALSE(elementsOf(vector{5, 2, 1, 1, 2}).areNonAscending()); + EXPECT_TRUE(elementsOf(vector()).areNonAscending()); + EXPECT_TRUE(elementsOf(vector{5, 4, 3, 2, 1}).areNonAscending()); + EXPECT_TRUE(elementsOf(vector{7, 3, 3, 2, 1, 1}).areNonAscending()); +} + +TEST_F(CoreValidatorTests, elementsOf_areNonDescending) { + EXPECT_FALSE(elementsOf(vector{1, 2, 3, 5, 3}).areNonDescending()); + EXPECT_FALSE(elementsOf(vector{2, 1, 1, 2, 5}).areNonDescending()); + EXPECT_TRUE(elementsOf(vector()).areNonDescending()); + EXPECT_TRUE(elementsOf(vector{1, 2, 3, 4, 5}).areNonDescending()); + EXPECT_TRUE(elementsOf(vector{1, 1, 2, 3, 3, 7}).areNonDescending()); +} + +TEST_F(CoreValidatorTests, elementsOf_areUnique) { + EXPECT_FALSE(elementsOf(vector{5, 1, 3, 4, 2, 1}).areUnique()); + EXPECT_FALSE(elementsOf(vector{'a', 'c', 'f', 'f', 'd'}).areUnique()); + EXPECT_TRUE(elementsOf(vector()).areUnique()); + EXPECT_TRUE(elementsOf(vector{5, 2, 4, 1, 9}).areUnique()); + EXPECT_TRUE(elementsOf(vector{'a', 'x', 'd', 'g', 'h'}).areUnique()); +} + } diff --git a/test/unit/tcframe/validator/VectorValidatorTests.cpp b/test/unit/tcframe/validator/VectorValidatorTests.cpp deleted file mode 100644 index 956beb9..0000000 --- a/test/unit/tcframe/validator/VectorValidatorTests.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include "gmock/gmock.h" - -#include "tcframe/validator/vector.hpp" - -using ::testing::Eq; -using ::testing::Test; - -namespace tcframe { - -class VectorValidatorTests : public Test {}; - -TEST_F(VectorValidatorTests, eachElementIsBetween) { - EXPECT_FALSE(eachElementIsBetween(vector{2, 3, 1, 5, 4}, 1, 4)); - EXPECT_FALSE(eachElementIsBetween(vector{2, 3, 1, 5, 4}, 2, 5)); - EXPECT_FALSE(eachElementIsBetween(vector{2, 3, 1, 5, 4}, 2, 4)); - EXPECT_TRUE(eachElementIsBetween(vector{2, 3, 1, 5, 4}, 1, 5)); - EXPECT_TRUE(eachElementIsBetween(vector{2, 3, 1, 5, 4}, 0, 6)); -} - -TEST_F(VectorValidatorTests, elementsAreNonDescending) { - EXPECT_FALSE(elementsAreNonDescending(vector{1, 2, 3, 5, 3})); - EXPECT_FALSE(elementsAreNonDescending(vector{2, 1, 1, 2, 5})); - EXPECT_TRUE(elementsAreNonDescending(vector())); - EXPECT_TRUE(elementsAreNonDescending(vector{1, 2, 3, 4, 5})); - EXPECT_TRUE(elementsAreNonDescending(vector{1, 1, 2, 3, 3, 7})); -} - -TEST_F(VectorValidatorTests, elementsAreNonAscending) { - EXPECT_FALSE(elementsAreNonAscending(vector{3, 5, 3, 2, 1})); - EXPECT_FALSE(elementsAreNonAscending(vector{5, 2, 1, 1, 2})); - EXPECT_TRUE(elementsAreNonAscending(vector())); - EXPECT_TRUE(elementsAreNonAscending(vector{5, 4, 3, 2, 1})); - EXPECT_TRUE(elementsAreNonAscending(vector{7, 3, 3, 2, 1, 1})); -} - -TEST_F(VectorValidatorTests, elementsAreDescending) { - EXPECT_FALSE(elementsAreDescending(vector{3, 5, 3, 2, 1})); - EXPECT_FALSE(elementsAreDescending(vector{5, 2, 1, 1, 2})); - EXPECT_FALSE(elementsAreDescending(vector{7, 3, 3, 2, 1, 1})); - EXPECT_TRUE(elementsAreDescending(vector())); - EXPECT_TRUE(elementsAreDescending(vector{5, 4, 3, 2, 1})); -} - -TEST_F(VectorValidatorTests, elementsAreAscending) { - EXPECT_FALSE(elementsAreAscending(vector{1, 2, 3, 5, 3})); - EXPECT_FALSE(elementsAreAscending(vector{2, 1, 1, 2, 5})); - EXPECT_FALSE(elementsAreAscending(vector{1, 1, 2, 3, 3, 7})); - EXPECT_TRUE(elementsAreAscending(vector())); - EXPECT_TRUE(elementsAreAscending(vector{1, 2, 3, 4, 5})); -} - -TEST_F(VectorValidatorTests, elementsAreUnique) { - EXPECT_FALSE(elementsAreUnique(vector{5, 1, 3, 4, 2, 1})); - EXPECT_FALSE(elementsAreUnique(vector{'a', 'c', 'f', 'f', 'd'})); - EXPECT_TRUE(elementsAreUnique(vector())); - EXPECT_TRUE(elementsAreUnique(vector{5, 2, 4, 1, 9})); - EXPECT_TRUE(elementsAreUnique(vector{'a', 'x', 'd', 'g', 'h'})); -} - -}