From b2dbcb55e2832c373fecb4033a3ed77e5dbc77aa Mon Sep 17 00:00:00 2001 From: Dominick Allen Date: Mon, 21 Oct 2024 12:49:43 -0500 Subject: Add vector and option. --- test/CMakeLists.txt | 2 + test/test_common.hpp | 6 + test/test_fud.cpp | 27 +- test/test_option.cpp | 54 +++ test/test_utf8.cpp | 1125 ++++++++++++++------------------------------------ test/test_vector.cpp | 138 +++++++ 6 files changed, 527 insertions(+), 825 deletions(-) create mode 100644 test/test_option.cpp create mode 100644 test/test_vector.cpp (limited to 'test') diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index c4d957b..515ae16 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -62,11 +62,13 @@ fud_add_test(test_assert SOURCES test_assert.cpp) # fud_add_test(test_c_file SOURCES test_c_file.cpp) fud_add_test(test_directory SOURCES test_directory.cpp) fud_add_test(test_format SOURCES test_format.cpp) +fud_add_test(test_option SOURCES test_option.cpp) fud_add_test(test_result SOURCES test_result.cpp) fud_add_test(test_span SOURCES test_span.cpp) fud_add_test(test_sqlite SOURCES test_sqlite.cpp) fud_add_test(test_string SOURCES test_string.cpp) fud_add_test(test_utf8 SOURCES test_utf8.cpp) +fud_add_test(test_vector SOURCES test_vector.cpp) # fud_add_test(test_deserialize_number SOURCES test_deserialize_number.cpp) # fud_add_test(test_ext_algorithm SOURCES test_algorithm.cpp) diff --git a/test/test_common.hpp b/test/test_common.hpp index 0ca8eb4..f049fed 100644 --- a/test/test_common.hpp +++ b/test/test_common.hpp @@ -38,10 +38,16 @@ static_assert(sizeof(FOUR_BYTE) == 4 + 1); #define LOWERCASE_CHARS "abcdefghijklmnopqrstuvwxyz" #define UPPERCASE_CHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZ" #define DECIMAL_CHARS "0123456789" +#define HEX_LOWER "abcdef" +#define HEX_UPPER "ABCDEF" +#define HEX_CHARS HEX_LOWER HEX_UPPER DECIMAL_CHARS #define ALPHA_CHARS LOWERCASE_CHARS UPPERCASE_CHARS #define ALPHA_NUMERIC_CHARS ALPHA_CHARS DECIMAL_CHARS #define PUNCTUATION_CHARS "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~" #define GRAPHICAL_CHARS ALPHA_NUMERIC_CHARS PUNCTUATION_CHARS +#define BLANK_CHARS " \t" +#define SPACE_CHARS BLANK_CHARS "\v\r\n" +#define PRINTABLE_CHARS " " LOWERCASE_CHARS UPPERCASE_CHARS DECIMAL_CHARS PUNCTUATION_CHARS #define CHARACTER_SET LOWERCASE_CHARS " " UPPERCASE_CHARS // NOLINTEND(cppcoreguidelines-macro-usage) diff --git a/test/test_fud.cpp b/test/test_fud.cpp index 0778f98..72d569a 100644 --- a/test/test_fud.cpp +++ b/test/test_fud.cpp @@ -15,10 +15,11 @@ * limitations under the License. */ -#include "fud_version.hpp" +#include "fud_config.hpp" #include "libfud.hpp" #include "gtest/gtest.h" +#include namespace fud { @@ -32,11 +33,33 @@ TEST(FudTest, FudFud) auto compareResult = compareMem( fudInfo.revision.data(), fudInfo.revision.size(), - GitHash, + FudGitHash, fudInfo.revision.size() - 1); ASSERT_TRUE(compareResult.isOkay()); EXPECT_EQ(compareResult.getOkay(), 0); EXPECT_EQ(fudInfo.revision[fudInfo.revision.size() - 1], '\0'); } +TEST(FudTest, GetEnv) +{ + constexpr const char* testVarName = "FUD_TEST_VAR"; + constexpr const char* testVarValue = "FUD_TEST_VALUE"; + + ASSERT_EQ(unsetenv(testVarName), 0); + + auto fudVarResult = getEnv(nullptr); + ASSERT_TRUE(fudVarResult.isError()); + ASSERT_EQ(fudVarResult.getError(), FudStatus::NullPointer); + + fudVarResult = getEnv(testVarName); + ASSERT_TRUE(fudVarResult.isError()); + ASSERT_EQ(fudVarResult.getError(), FudStatus::NotFound); + + ASSERT_EQ(setenv(testVarName, testVarValue, 1), 0); + fudVarResult = getEnv(testVarName); + ASSERT_TRUE(fudVarResult.isOkay()); + auto fudVar{fudVarResult.takeOkay()}; + ASSERT_STREQ(fudVar.c_str(), testVarValue); +} + } // namespace fud diff --git a/test/test_option.cpp b/test/test_option.cpp new file mode 100644 index 0000000..a503a5f --- /dev/null +++ b/test/test_option.cpp @@ -0,0 +1,54 @@ +/* + * libfud + * Copyright 2024 Dominick Allen + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "fud_option.hpp" + +#include "gtest/gtest.h" + +namespace fud { + +TEST(OptionTest, OptionCreation) +{ + static_assert(sizeof(std::reference_wrapper) == 8); + int value = 42; + Option maybeValue{}; + ASSERT_FALSE(maybeValue.hasValue()); + maybeValue = value; + ASSERT_TRUE(maybeValue.hasValue()); +} + +TEST(OptionTest, OptionRef) +{ + int value = 42; + Option optionalValueRef{value}; + ASSERT_TRUE(optionalValueRef.hasValue()); + ASSERT_EQ(optionalValueRef.value(), 42); + optionalValueRef.value() = 7; + ASSERT_EQ(value, 7); + + value = 42; + int otherValue = 13; + optionalValueRef = otherValue; + ASSERT_TRUE(optionalValueRef.hasValue()); + ASSERT_EQ(optionalValueRef.value(), otherValue); + optionalValueRef.value() = 7; + ASSERT_EQ(optionalValueRef.value(), otherValue); + ASSERT_EQ(otherValue, 7); + ASSERT_EQ(value, 42); +} + +} // namespace fud diff --git a/test/test_utf8.cpp b/test/test_utf8.cpp index 8f1d655..d1737f7 100644 --- a/test/test_utf8.cpp +++ b/test/test_utf8.cpp @@ -38,10 +38,21 @@ constexpr char printableCharOffset = 0x20; constexpr auto invalidAscii = FudUtf8::invalidAsciiCode.character(); -auto generateInvalidAsciiChars() +auto invalidAsciiGenerator() { - Iota iota{}; - return generate([]() { return Array{}; }, [&]() { return iota().value(); }); + return Iota{validAsciiSize, 1, invalidAsciiSize}; +} + +template +auto toUtf8(T letter) +{ + return FudUtf8::make(static_cast(letter)); +} + +template +auto toLetter(T letter) +{ + return static_cast(letter); } TEST(Utf8Test, Utf8Creation) @@ -187,123 +198,80 @@ TEST(Utf8Test, Utf8IsAscii) Iota charIota{0, 1, validAsciiSize}; - ASSERT_TRUE(allOf( - [&]() -> std::optional { - auto value = charIota(); - return value ? std::optional(static_cast(*value)) : std::nullopt; - }, - charIsAscii)); + ASSERT_TRUE(allOf([&]() -> Option { return charIota().map(toLetter); }, charIsAscii)); Iota invalidCharIota{validAsciiSize, 1, invalidAsciiSize}; - ASSERT_FALSE(anyOf( - [&]() -> std::optional { - auto value = invalidCharIota(); - return value ? std::optional(static_cast(*value)) : std::nullopt; - }, - charIsAscii)); + ASSERT_FALSE(anyOf([&]() -> Option { return invalidCharIota().map(toLetter); }, charIsAscii)); FudUtf8 unicode{FudUtf8::invalidAscii()}; ASSERT_FALSE(utf8IsAscii(unicode)); charIota.set(0); - ASSERT_TRUE(allOf( - [&]() -> std::optional { - auto value = charIota(); - return value ? std::optional(FudUtf8::make(static_cast(*value))) : std::nullopt; - }, - utf8IsAscii)); + ASSERT_TRUE(allOf([&]() -> Option { return charIota().map(toUtf8); }, utf8IsAscii)); invalidCharIota.set(invalidAsciiSize); - ASSERT_FALSE(anyOf( - [&]() -> std::optional { - auto value = invalidCharIota(); - return value ? std::optional(FudUtf8::make(static_cast(*value))) : std::nullopt; - }, - utf8IsAscii)); + ASSERT_FALSE(anyOf([&]() -> Option { return invalidCharIota().map(toUtf8); }, utf8IsAscii)); } -TEST(Utf8Test, Utf8IsAlphaNumeric) +template +struct SpanGenerator { + Span span; + size_t index{0}; + + void reset() + { + index = 0; + } + + Option operator()() + { + if (index < span.size()) { + index++; + return span[index - 1]; + } + return NullOpt; + } +}; + +TEST(Utf8Test, Utf8IsAlphanumeric) { - constexpr size_t numAlphaNumericChars = 26 * 2 + 10; - Array alphaNumericCharLiteral{ALPHA_NUMERIC_CHARS}; - Array alphaNumericChars{}; - copyMem(alphaNumericChars, alphaNumericCharLiteral); -#if 0 - ASSERT_TRUE(allOf(alphaNumericChars, charIsAlphanumeric)); - - auto alphaNumericSetResult{StaticSet::makeFromArray(alphaNumericChars)}; - ASSERT_TRUE(alphaNumericSetResult.isOkay()); - auto alphaNumericSet{std::move(alphaNumericSetResult.getOkay())}; - - constexpr size_t numNonAlphaNumericChars = validAsciiSize - numAlphaNumericChars; - FixedVector nonAlphaNumericChars{}; + constexpr size_t numAlphanumericChars = 26 * 2 + 10; + Array alphanumericCharLiteral{ALPHA_NUMERIC_CHARS}; + Array alphanumericChars{}; + copyMem(alphanumericChars, alphanumericCharLiteral); + + ASSERT_TRUE(allOf(alphanumericChars.span(), charIsAlphanumeric)); + + constexpr size_t numNonAlphanumericChars = validAsciiSize - numAlphanumericChars; + Vector nonAlphanumericChars{}; for (char idx = 0; idx < INT8_MAX; ++idx) { - if (!alphaNumericSet.isKey(idx)) { - ASSERT_TRUE(nonAlphaNumericChars.pushBack(idx)); + if (!charIsAlphanumeric(idx)) { + ASSERT_EQ(nonAlphanumericChars.pushBack(idx), FudStatus::Success); } } - ASSERT_FALSE(anyOf(nonAlphaNumericChars, charIsAlphanumeric)); + auto nonAlphanumericSpan{nonAlphanumericChars.span().takeOkay()}; + ASSERT_FALSE(anyOf(nonAlphanumericSpan, charIsAlphanumeric)); - auto invalidAsciiChars = generateInvalidAsciiChars(); + auto invalidAsciiChars = invalidAsciiGenerator(); ASSERT_FALSE(anyOf(invalidAsciiChars, charIsAlphanumeric)); - ASSERT_TRUE(allOf( - map(alphaNumericChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_alphanumeric)); - ASSERT_FALSE(anyOf( - map(nonAlphaNumericChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_alphanumeric)); - ASSERT_FALSE(anyOf( - map(invalidAsciiChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_alphanumeric)); - - ASSERT_TRUE(allOf( - map(alphaNumericChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_alphanumeric)); - ASSERT_FALSE(anyOf( - map(nonAlphaNumericChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_alphanumeric)); - ASSERT_FALSE(anyOf( - map(invalidAsciiChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_alphanumeric)); - - Utf8 utf8{invalidAscii}; - bool isAscii = false; - ASSERT_EQ(ext_lib_utf8_is_alphanumeric(nullptr, nullptr), ExtNullPointer); - ASSERT_EQ(ext_lib_utf8_is_alphanumeric(&utf8, nullptr), ExtNullPointer); - ASSERT_EQ(ext_lib_utf8_is_alphanumeric(nullptr, &isAscii), ExtNullPointer); - ASSERT_EQ(ext_lib_utf8_is_alphanumeric(&utf8, &isAscii), ExtInvalidInput); - ASSERT_FALSE(isAscii); - - ASSERT_TRUE(allOf( - map(alphaNumericChars, - [](char letter) { return FudUtf8::makeUtf8(ExtUtf8Char4{static_cast(letter)}); }), - [](auto& utf8Letter) { - bool predicate = false; - auto isPredicateStatus = ext_lib_utf8_is_alphanumeric(&utf8Letter, &predicate); - return isPredicateStatus == ExtSuccess && predicate; - })); - ASSERT_FALSE(anyOf( - map(nonAlphaNumericChars, - [](char letter) { return FudUtf8::makeUtf8(ExtUtf8Char4{static_cast(letter)}); }), - [](auto& utf8Letter) { - bool predicate = false; - auto isPredicateStatus = ext_lib_utf8_is_alphanumeric(&utf8Letter, &predicate); - return isPredicateStatus != ExtSuccess || predicate; - })); - ASSERT_FALSE(allOf( - map(nonAlphaNumericChars, - [](char letter) { return FudUtf8::makeUtf8(ExtUtf8Char4{static_cast(letter)}); }), - [](auto& utf8Letter) { - bool predicate = false; - auto isPredicateStatus = ext_lib_utf8_is_alphanumeric(&utf8Letter, &predicate); - return isPredicateStatus == ExtInvalidInput && !predicate; - })); -#endif + ASSERT_FALSE(utf8IsAlphanumeric(FudUtf8{Ascii{invalidAscii}})); + + auto iotaGenerator = invalidAsciiGenerator(); + auto generator = generate( + []() { return Array{}; }, + [&]() { return iotaGenerator().map([](auto val) { return static_cast(val); }); }); + + SpanGenerator alphanumericGenerator{alphanumericChars.span()}; + auto utf8AlphanumericGenerator = [&]() { return alphanumericGenerator().map(toUtf8); }; + ASSERT_TRUE(allOf(utf8AlphanumericGenerator, utf8IsAlphanumeric)); + + SpanGenerator nonAlphanumericGenerator{nonAlphanumericChars.span().takeOkay()}; + auto utf8NonAlphanumericGenerator = [&]() { return nonAlphanumericGenerator().map(toUtf8); }; + ASSERT_FALSE(anyOf(utf8NonAlphanumericGenerator, utf8IsAlphanumeric)); } -#if 0 TEST(Utf8Test, Utf8IsAlpha) { constexpr size_t numAlphaChars = sizeof(ALPHA_CHARS) - 1; @@ -311,75 +279,29 @@ TEST(Utf8Test, Utf8IsAlpha) Array alphaChars{}; copyMem(alphaChars, alphaCharLiteral); - ASSERT_TRUE(allOf(alphaChars, ext_lib_char_is_alpha)); - - auto alphaSetResult{StaticSet::makeFromArray(alphaChars)}; - ASSERT_TRUE(alphaSetResult.isOkay()); - auto alphaSet{std::move(alphaSetResult.getOkay())}; + ASSERT_TRUE(allOf(alphaChars.span(), charIsAlpha)); - constexpr size_t numNonAlphaChars = validAsciiSize - numAlphaChars; - FixedVector nonAlphaChars{}; + constexpr size_t numNonAlphanumericChars = validAsciiSize - numAlphaChars; + Vector nonAlphaChars{}; for (char idx = 0; idx < INT8_MAX; ++idx) { - if (!alphaSet.isKey(idx)) { - ASSERT_TRUE(nonAlphaChars.pushBack(idx)); + if (!charIsAlphanumeric(idx)) { + ASSERT_EQ(nonAlphaChars.pushBack(idx), FudStatus::Success); } } - ASSERT_FALSE(anyOf(nonAlphaChars, ext_lib_char_is_alpha)); - - auto invalidAsciiChars = generateInvalidAsciiChars(); - ASSERT_FALSE(anyOf(invalidAsciiChars, ext_lib_char_is_alpha)); - - ASSERT_TRUE(allOf( - map(alphaChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_alpha)); - ASSERT_FALSE(anyOf( - map(nonAlphaChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_alpha)); - ASSERT_FALSE(anyOf( - map(invalidAsciiChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_alpha)); - - ASSERT_TRUE(allOf( - map(alphaChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_alpha)); - ASSERT_FALSE(anyOf( - map(nonAlphaChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_alpha)); - ASSERT_FALSE(anyOf( - map(invalidAsciiChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_alpha)); - - Utf8 utf8{invalidAscii}; - bool isAscii = false; - ASSERT_EQ(ext_lib_utf8_is_alpha(nullptr, nullptr), ExtNullPointer); - ASSERT_EQ(ext_lib_utf8_is_alpha(&utf8, nullptr), ExtNullPointer); - ASSERT_EQ(ext_lib_utf8_is_alpha(nullptr, &isAscii), ExtNullPointer); - ASSERT_EQ(ext_lib_utf8_is_alpha(&utf8, &isAscii), ExtInvalidInput); - ASSERT_FALSE(isAscii); - - ASSERT_TRUE(allOf( - map(alphaChars, [](char letter) { return FudUtf8::makeUtf8(ExtUtf8Char4{static_cast(letter)}); }), - [](auto& utf8Letter) { - bool predicate = false; - auto isPredicateStatus = ext_lib_utf8_is_alpha(&utf8Letter, &predicate); - return isPredicateStatus == ExtSuccess && predicate; - })); - ASSERT_FALSE(anyOf( - map(nonAlphaChars, - [](char letter) { return FudUtf8::makeUtf8(ExtUtf8Char4{static_cast(letter)}); }), - [](auto& utf8Letter) { - bool predicate = false; - auto isPredicateStatus = ext_lib_utf8_is_alpha(&utf8Letter, &predicate); - return isPredicateStatus != ExtSuccess || predicate; - })); - ASSERT_FALSE(allOf( - map(nonAlphaChars, - [](char letter) { return FudUtf8::makeUtf8(ExtUtf8Char4{static_cast(letter)}); }), - [](auto& utf8Letter) { - bool predicate = false; - auto isPredicateStatus = ext_lib_utf8_is_alpha(&utf8Letter, &predicate); - return isPredicateStatus == ExtInvalidInput && !predicate; - })); + ASSERT_FALSE(anyOf(nonAlphaChars.span().takeOkay(), charIsAlpha)); + + auto invalidAsciiChars = invalidAsciiGenerator(); + ASSERT_FALSE(anyOf(invalidAsciiChars, charIsAlpha)); + + ASSERT_FALSE(utf8IsAlpha(FudUtf8{Ascii{invalidAscii}})); + + SpanGenerator alphaGenerator{alphaChars.span()}; + auto utf8AlphaGenerator = [&]() { return alphaGenerator().map(toUtf8); }; + ASSERT_TRUE(allOf(utf8AlphaGenerator, utf8IsAlpha)); + + SpanGenerator nonAlphaGenerator{nonAlphaChars.span().takeOkay()}; + auto utf8NonAlphaGenerator = [&]() { return nonAlphaGenerator().map(toUtf8); }; + ASSERT_FALSE(anyOf(utf8NonAlphaGenerator, utf8IsAlpha)); } TEST(Utf8Test, Utf8IsLower) @@ -389,75 +311,29 @@ TEST(Utf8Test, Utf8IsLower) Array lowerChars{}; copyMem(lowerChars, lowerCharLiteral); - ASSERT_TRUE(allOf(lowerChars, ext_lib_char_is_lowercase)); - - auto lowerSetResult{StaticSet::makeFromArray(lowerChars)}; - ASSERT_TRUE(lowerSetResult.isOkay()); - auto lowerSet{std::move(lowerSetResult.getOkay())}; + ASSERT_TRUE(allOf(lowerChars.span(), charIsLowercase)); constexpr size_t numNonLowerChars = validAsciiSize - numLowerChars; - FixedVector nonLowerChars{}; + Vector nonLowerChars{}; for (char idx = 0; idx < INT8_MAX; ++idx) { - if (!lowerSet.isKey(idx)) { - ASSERT_TRUE(nonLowerChars.pushBack(idx)); + if (!charIsLowercase(idx)) { + ASSERT_EQ(nonLowerChars.pushBack(idx), FudStatus::Success); } } - ASSERT_FALSE(anyOf(nonLowerChars, ext_lib_char_is_lowercase)); - - auto invalidAsciiChars = generateInvalidAsciiChars(); - ASSERT_FALSE(anyOf(invalidAsciiChars, ext_lib_char_is_lowercase)); - - ASSERT_TRUE(allOf( - map(lowerChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_lowercase)); - ASSERT_FALSE(anyOf( - map(nonLowerChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_lowercase)); - ASSERT_FALSE(anyOf( - map(invalidAsciiChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_lowercase)); - - ASSERT_TRUE(allOf( - map(lowerChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_lowercase)); - ASSERT_FALSE(anyOf( - map(nonLowerChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_lowercase)); - ASSERT_FALSE(anyOf( - map(invalidAsciiChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_lowercase)); - - Utf8 utf8{invalidAscii}; - bool isAscii = false; - ASSERT_EQ(ext_lib_utf8_is_lowercase(nullptr, nullptr), ExtNullPointer); - ASSERT_EQ(ext_lib_utf8_is_lowercase(&utf8, nullptr), ExtNullPointer); - ASSERT_EQ(ext_lib_utf8_is_lowercase(nullptr, &isAscii), ExtNullPointer); - ASSERT_EQ(ext_lib_utf8_is_lowercase(&utf8, &isAscii), ExtInvalidInput); - ASSERT_FALSE(isAscii); - - ASSERT_TRUE(allOf( - map(lowerChars, [](char letter) { return FudUtf8::makeUtf8(ExtUtf8Char4{static_cast(letter)}); }), - [](auto& utf8Letter) { - bool predicate = false; - auto isPredicateStatus = ext_lib_utf8_is_lowercase(&utf8Letter, &predicate); - return isPredicateStatus == ExtSuccess && predicate; - })); - ASSERT_FALSE(anyOf( - map(nonLowerChars, - [](char letter) { return FudUtf8::makeUtf8(ExtUtf8Char4{static_cast(letter)}); }), - [](auto& utf8Letter) { - bool predicate = false; - auto isPredicateStatus = ext_lib_utf8_is_lowercase(&utf8Letter, &predicate); - return isPredicateStatus != ExtSuccess || predicate; - })); - ASSERT_FALSE(allOf( - map(nonLowerChars, - [](char letter) { return FudUtf8::makeUtf8(ExtUtf8Char4{static_cast(letter)}); }), - [](auto& utf8Letter) { - bool predicate = false; - auto isPredicateStatus = ext_lib_utf8_is_lowercase(&utf8Letter, &predicate); - return isPredicateStatus == ExtInvalidInput && !predicate; - })); + ASSERT_FALSE(anyOf(nonLowerChars.span().takeOkay(), charIsLowercase)); + + auto invalidAsciiChars = invalidAsciiGenerator(); + ASSERT_FALSE(anyOf(invalidAsciiChars, charIsLowercase)); + + ASSERT_FALSE(utf8IsLowercase(FudUtf8{Ascii{invalidAscii}})); + + SpanGenerator lowerGenerator{lowerChars.span()}; + auto utf8LowerGenerator = [&]() { return lowerGenerator().map(toUtf8); }; + ASSERT_TRUE(allOf(utf8LowerGenerator, utf8IsLowercase)); + + SpanGenerator nonLowerGenerator{nonLowerChars.span().takeOkay()}; + auto utf8NonLowerGenerator = [&]() { return nonLowerGenerator().map(toUtf8); }; + ASSERT_FALSE(anyOf(utf8NonLowerGenerator, utf8IsLowercase)); } TEST(Utf8Test, Utf8IsUpper) @@ -467,153 +343,61 @@ TEST(Utf8Test, Utf8IsUpper) Array upperChars{}; copyMem(upperChars, upperCharLiteral); - ASSERT_TRUE(allOf(upperChars, ext_lib_char_is_uppercase)); - - auto upperSetResult{StaticSet::makeFromArray(upperChars)}; - ASSERT_TRUE(upperSetResult.isOkay()); - auto upperSet{std::move(upperSetResult.getOkay())}; + ASSERT_TRUE(allOf(upperChars.span(), charIsUppercase)); constexpr size_t numNonUpperChars = validAsciiSize - numUpperChars; - FixedVector nonUpperChars{}; + Vector nonUpperChars{}; for (char idx = 0; idx < INT8_MAX; ++idx) { - if (!upperSet.isKey(idx)) { - ASSERT_TRUE(nonUpperChars.pushBack(idx)); + if (!charIsUppercase(idx)) { + ASSERT_EQ(nonUpperChars.pushBack(idx), FudStatus::Success); } } - ASSERT_FALSE(anyOf(nonUpperChars, ext_lib_char_is_uppercase)); - - auto invalidAsciiChars = generateInvalidAsciiChars(); - ASSERT_FALSE(anyOf(invalidAsciiChars, ext_lib_char_is_uppercase)); - - ASSERT_TRUE(allOf( - map(upperChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_uppercase)); - ASSERT_FALSE(anyOf( - map(nonUpperChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_uppercase)); - ASSERT_FALSE(anyOf( - map(invalidAsciiChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_uppercase)); - - ASSERT_TRUE(allOf( - map(upperChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_uppercase)); - ASSERT_FALSE(anyOf( - map(nonUpperChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_uppercase)); - ASSERT_FALSE(anyOf( - map(invalidAsciiChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_uppercase)); - - Utf8 utf8{invalidAscii}; - bool isAscii = false; - ASSERT_EQ(ext_lib_utf8_is_uppercase(nullptr, nullptr), ExtNullPointer); - ASSERT_EQ(ext_lib_utf8_is_uppercase(&utf8, nullptr), ExtNullPointer); - ASSERT_EQ(ext_lib_utf8_is_uppercase(nullptr, &isAscii), ExtNullPointer); - ASSERT_EQ(ext_lib_utf8_is_uppercase(&utf8, &isAscii), ExtInvalidInput); - ASSERT_FALSE(isAscii); - - ASSERT_TRUE(allOf( - map(upperChars, [](char letter) { return FudUtf8::makeUtf8(ExtUtf8Char4{static_cast(letter)}); }), - [](auto& utf8Letter) { - bool predicate = false; - auto isPredicateStatus = ext_lib_utf8_is_uppercase(&utf8Letter, &predicate); - return isPredicateStatus == ExtSuccess && predicate; - })); - ASSERT_FALSE(anyOf( - map(nonUpperChars, - [](char letter) { return FudUtf8::makeUtf8(ExtUtf8Char4{static_cast(letter)}); }), - [](auto& utf8Letter) { - bool predicate = false; - auto isPredicateStatus = ext_lib_utf8_is_uppercase(&utf8Letter, &predicate); - return isPredicateStatus != ExtSuccess || predicate; - })); - ASSERT_FALSE(allOf( - map(nonUpperChars, - [](char letter) { return FudUtf8::makeUtf8(ExtUtf8Char4{static_cast(letter)}); }), - [](auto& utf8Letter) { - bool predicate = false; - auto isPredicateStatus = ext_lib_utf8_is_uppercase(&utf8Letter, &predicate); - return isPredicateStatus == ExtInvalidInput && !predicate; - })); + ASSERT_FALSE(anyOf(nonUpperChars.span().takeOkay(), charIsUppercase)); + + auto invalidAsciiChars = invalidAsciiGenerator(); + ASSERT_FALSE(anyOf(invalidAsciiChars, charIsUppercase)); + + ASSERT_FALSE(utf8IsUppercase(FudUtf8{Ascii{invalidAscii}})); + + SpanGenerator upperGenerator{upperChars.span()}; + auto utf8UpperGenerator = [&]() { return upperGenerator().map(toUtf8); }; + ASSERT_TRUE(allOf(utf8UpperGenerator, utf8IsUppercase)); + + SpanGenerator nonUpperGenerator{nonUpperChars.span().takeOkay()}; + auto utf8NonUpperGenerator = [&]() { return nonUpperGenerator().map(toUtf8); }; + ASSERT_FALSE(anyOf(utf8NonUpperGenerator, utf8IsUppercase)); } TEST(Utf8Test, Utf8IsDigit) { constexpr size_t numDigitChars = 10; - Array digitCharLiteral{"0123456789"}; + Array digitCharLiteral{DECIMAL_CHARS}; Array digitChars{}; copyMem(digitChars, digitCharLiteral); - ASSERT_TRUE(allOf(digitChars, ext_lib_char_is_digit)); - - auto digitSetResult{StaticSet::makeFromArray(digitChars)}; - ASSERT_TRUE(digitSetResult.isOkay()); - auto digitSet{std::move(digitSetResult.getOkay())}; + ASSERT_TRUE(allOf(digitChars.span(), charIsDigit)); constexpr size_t numNonDigitChars = validAsciiSize - numDigitChars; - FixedVector nonDigitChars{}; + Vector nonDigitChars{}; for (char idx = 0; idx < INT8_MAX; ++idx) { - if (!digitSet.isKey(idx)) { - ASSERT_TRUE(nonDigitChars.pushBack(idx)); + if (!charIsDigit(idx)) { + ASSERT_EQ(nonDigitChars.pushBack(idx), FudStatus::Success); } } - ASSERT_FALSE(anyOf(nonDigitChars, ext_lib_char_is_digit)); - - auto invalidAsciiChars = generateInvalidAsciiChars(); - ASSERT_FALSE(anyOf(invalidAsciiChars, ext_lib_char_is_digit)); - - ASSERT_TRUE(allOf( - map(digitChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_digit)); - ASSERT_FALSE(anyOf( - map(nonDigitChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_digit)); - ASSERT_FALSE(anyOf( - map(invalidAsciiChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_digit)); - - ASSERT_TRUE(allOf( - map(digitChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_digit)); - ASSERT_FALSE(anyOf( - map(nonDigitChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_digit)); - ASSERT_FALSE(anyOf( - map(invalidAsciiChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_digit)); - - Utf8 utf8{invalidAscii}; - bool isAscii = false; - ASSERT_EQ(ext_lib_utf8_is_digit(nullptr, nullptr), ExtNullPointer); - ASSERT_EQ(ext_lib_utf8_is_digit(&utf8, nullptr), ExtNullPointer); - ASSERT_EQ(ext_lib_utf8_is_digit(nullptr, &isAscii), ExtNullPointer); - ASSERT_EQ(ext_lib_utf8_is_digit(&utf8, &isAscii), ExtInvalidInput); - ASSERT_FALSE(isAscii); - - ASSERT_TRUE(allOf( - map(digitChars, [](char letter) { return FudUtf8::makeUtf8(ExtUtf8Char4{static_cast(letter)}); }), - [](auto& utf8Letter) { - bool predicate = false; - auto isPredicateStatus = ext_lib_utf8_is_digit(&utf8Letter, &predicate); - return isPredicateStatus == ExtSuccess && predicate; - })); - ASSERT_FALSE(anyOf( - map(nonDigitChars, - [](char letter) { return FudUtf8::makeUtf8(ExtUtf8Char4{static_cast(letter)}); }), - [](auto& utf8Letter) { - bool predicate = false; - auto isPredicateStatus = ext_lib_utf8_is_digit(&utf8Letter, &predicate); - return isPredicateStatus != ExtSuccess || predicate; - })); - ASSERT_FALSE(allOf( - map(nonDigitChars, - [](char letter) { return FudUtf8::makeUtf8(ExtUtf8Char4{static_cast(letter)}); }), - [](auto& utf8Letter) { - bool predicate = false; - auto isPredicateStatus = ext_lib_utf8_is_digit(&utf8Letter, &predicate); - return isPredicateStatus == ExtInvalidInput && !predicate; - })); + ASSERT_FALSE(anyOf(nonDigitChars.span().takeOkay(), charIsDigit)); + + auto invalidAsciiChars = invalidAsciiGenerator(); + ASSERT_FALSE(anyOf(invalidAsciiChars, charIsDigit)); + + ASSERT_FALSE(utf8IsDigit(FudUtf8{Ascii{invalidAscii}})); + + SpanGenerator digitGenerator{digitChars.span()}; + auto utf8DigitGenerator = [&]() { return digitGenerator().map(toUtf8); }; + ASSERT_TRUE(allOf(utf8DigitGenerator, utf8IsDigit)); + + SpanGenerator nonDigitGenerator{nonDigitChars.span().takeOkay()}; + auto utf8NonDigitGenerator = [&]() { return nonDigitGenerator().map(toUtf8); }; + ASSERT_FALSE(anyOf(utf8NonDigitGenerator, utf8IsDigit)); } TEST(Utf8Test, Utf8IsHexDigit) @@ -623,147 +407,61 @@ TEST(Utf8Test, Utf8IsHexDigit) Array hexDigitChars{}; copyMem(hexDigitChars, hexDigitCharLiteral); - ASSERT_TRUE(allOf(hexDigitChars, ext_lib_char_is_hex_digit)); - - auto hexDigitSetResult{StaticSet::makeFromArray(hexDigitChars)}; - ASSERT_TRUE(hexDigitSetResult.isOkay()); - auto hexDigitSet{std::move(hexDigitSetResult.getOkay())}; + ASSERT_TRUE(allOf(hexDigitChars.span(), charIsHexDigit)); constexpr size_t numNonHexDigitChars = validAsciiSize - numHexDigitChars; - FixedVector nonHexDigitChars{}; + Vector nonHexDigitChars{}; for (char idx = 0; idx < INT8_MAX; ++idx) { - if (!hexDigitSet.isKey(idx)) { - ASSERT_TRUE(nonHexDigitChars.pushBack(idx)); + if (!charIsHexDigit(idx)) { + ASSERT_EQ(nonHexDigitChars.pushBack(idx), FudStatus::Success); } } - ASSERT_FALSE(anyOf(nonHexDigitChars, ext_lib_char_is_hex_digit)); - - auto invalidAsciiChars = generateInvalidAsciiChars(); - ASSERT_FALSE(anyOf(invalidAsciiChars, ext_lib_char_is_hex_digit)); - - ASSERT_TRUE(allOf( - map(hexDigitChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_hex_digit)); - ASSERT_FALSE(anyOf( - map(nonHexDigitChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_hex_digit)); - ASSERT_FALSE(anyOf( - map(invalidAsciiChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_hex_digit)); - - ASSERT_TRUE(allOf( - map(hexDigitChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_hex_digit)); - ASSERT_FALSE(anyOf( - map(nonHexDigitChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_hex_digit)); - ASSERT_FALSE(anyOf( - map(invalidAsciiChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_hex_digit)); - - Utf8 utf8{invalidAscii}; - bool isAscii = false; - ASSERT_EQ(ext_lib_utf8_is_hex_digit(nullptr, nullptr), ExtNullPointer); - ASSERT_EQ(ext_lib_utf8_is_hex_digit(&utf8, nullptr), ExtNullPointer); - ASSERT_EQ(ext_lib_utf8_is_hex_digit(nullptr, &isAscii), ExtNullPointer); - ASSERT_EQ(ext_lib_utf8_is_hex_digit(&utf8, &isAscii), ExtInvalidInput); - ASSERT_FALSE(isAscii); - - ASSERT_TRUE(allOf( - map(hexDigitChars, - [](char letter) { return FudUtf8::makeUtf8(ExtUtf8Char4{static_cast(letter)}); }), - [](auto& utf8Letter) { - bool predicate = false; - auto isPredicateStatus = ext_lib_utf8_is_hex_digit(&utf8Letter, &predicate); - return isPredicateStatus == ExtSuccess && predicate; - })); - ASSERT_FALSE(anyOf( - map(nonHexDigitChars, - [](char letter) { return FudUtf8::makeUtf8(ExtUtf8Char4{static_cast(letter)}); }), - [](auto& utf8Letter) { - bool predicate = false; - auto isPredicateStatus = ext_lib_utf8_is_hex_digit(&utf8Letter, &predicate); - return isPredicateStatus != ExtSuccess || predicate; - })); - ASSERT_FALSE(allOf( - map(nonHexDigitChars, - [](char letter) { return FudUtf8::makeUtf8(ExtUtf8Char4{static_cast(letter)}); }), - [](auto& utf8Letter) { - bool predicate = false; - auto isPredicateStatus = ext_lib_utf8_is_hex_digit(&utf8Letter, &predicate); - return isPredicateStatus == ExtInvalidInput && !predicate; - })); + ASSERT_FALSE(anyOf(nonHexDigitChars.span().takeOkay(), charIsHexDigit)); + + auto invalidAsciiChars = invalidAsciiGenerator(); + ASSERT_FALSE(anyOf(invalidAsciiChars, charIsHexDigit)); + + ASSERT_FALSE(utf8IsHexDigit(FudUtf8{Ascii{invalidAscii}})); + + SpanGenerator hexDigitGenerator{hexDigitChars.span()}; + auto utf8HexDigitGenerator = [&]() { return hexDigitGenerator().map(toUtf8); }; + ASSERT_TRUE(allOf(utf8HexDigitGenerator, utf8IsHexDigit)); + + SpanGenerator nonHexDigitGenerator{nonHexDigitChars.span().takeOkay()}; + auto utf8NonHexDigitGenerator = [&]() { return nonHexDigitGenerator().map(toUtf8); }; + ASSERT_FALSE(anyOf(utf8NonHexDigitGenerator, utf8IsHexDigit)); } TEST(Utf8Test, Utf8IsControl) { - auto controlChars = generateIndexArray([](int idx) { return static_cast(idx); }); + Iota controlArrayGenerator{0, 1, numControlChars}; + auto controlChars = generate([]() { return Array{}; }, controlArrayGenerator); constexpr const char deleteChar = 0x7F; controlChars.back() = deleteChar; - ASSERT_TRUE(allOf(controlChars, ext_lib_char_is_control)); - - constexpr size_t numNonControlChars = 256 - numControlChars; - auto nonControlChars = generateIndexArray([](int idx) { - return static_cast(idx + printableCharOffset); - }); - ASSERT_FALSE(anyOf(nonControlChars, ext_lib_char_is_control)); - - auto invalidAsciiChars = generateInvalidAsciiChars(); - ASSERT_FALSE(anyOf(invalidAsciiChars, ext_lib_char_is_control)); - - ASSERT_TRUE(allOf( - map(controlChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_control)); - ASSERT_FALSE(anyOf( - map(nonControlChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_control)); - ASSERT_FALSE(anyOf( - map(invalidAsciiChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_control)); - - ASSERT_TRUE(allOf( - map(controlChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_control)); - ASSERT_FALSE(anyOf( - map(nonControlChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_control)); - ASSERT_FALSE(anyOf( - map(invalidAsciiChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_control)); - - Utf8 utf8{invalidAscii}; - bool isAscii = false; - ASSERT_EQ(ext_lib_utf8_is_control(nullptr, nullptr), ExtNullPointer); - ASSERT_EQ(ext_lib_utf8_is_control(&utf8, nullptr), ExtNullPointer); - ASSERT_EQ(ext_lib_utf8_is_control(nullptr, &isAscii), ExtNullPointer); - ASSERT_EQ(ext_lib_utf8_is_control(&utf8, &isAscii), ExtInvalidInput); - ASSERT_FALSE(isAscii); - - ASSERT_TRUE(allOf( - map(controlChars, - [](char letter) { return FudUtf8::makeUtf8(ExtUtf8Char4{static_cast(letter)}); }), - [](auto& utf8Letter) { - bool predicate = false; - auto isPredicateStatus = ext_lib_utf8_is_control(&utf8Letter, &predicate); - return isPredicateStatus == ExtSuccess && predicate; - })); - ASSERT_FALSE(anyOf( - map(nonControlChars, - [](char letter) { return FudUtf8::makeUtf8(ExtUtf8Char4{static_cast(letter)}); }), - [](auto& utf8Letter) { - bool predicate = false; - auto isPredicateStatus = ext_lib_utf8_is_control(&utf8Letter, &predicate); - return isPredicateStatus != ExtSuccess || predicate; - })); - ASSERT_FALSE(allOf( - map(nonControlChars, - [](char letter) { return FudUtf8::makeUtf8(ExtUtf8Char4{static_cast(letter)}); }), - [](auto& utf8Letter) { - bool predicate = false; - auto isPredicateStatus = ext_lib_utf8_is_control(&utf8Letter, &predicate); - return isPredicateStatus == ExtInvalidInput && !predicate; - })); + ASSERT_TRUE(allOf(controlChars.span(), charIsControl)); + + constexpr size_t numNonControlChars = INT8_MAX + 1 - numControlChars; + Vector nonControlChars{}; + ASSERT_EQ(nonControlChars.reserve(numNonControlChars), FudStatus::Success); + for (auto idx = numControlChars - 1; idx < deleteChar; ++idx) { + ASSERT_EQ(nonControlChars.pushBack(idx), FudStatus::Success); + } + ASSERT_FALSE(anyOf(nonControlChars.span().takeOkay(), charIsControl)); + ASSERT_TRUE(allOf(nonControlChars.span().takeOkay(), charIsAscii)); + + auto invalidAsciiChars = invalidAsciiGenerator(); + ASSERT_FALSE(anyOf(invalidAsciiChars, charIsControl)); + + ASSERT_FALSE(utf8IsControl(FudUtf8{Ascii{invalidAscii}})); + + SpanGenerator controlGenerator{controlChars.span()}; + auto utf8ControlGenerator = [&]() { return controlGenerator().map(toUtf8); }; + ASSERT_TRUE(allOf(utf8ControlGenerator, utf8IsControl)); + + SpanGenerator nonControlGenerator{nonControlChars.span().takeOkay()}; + auto utf8NonControlGenerator = [&]() { return nonControlGenerator().map(toUtf8); }; + ASSERT_FALSE(anyOf(utf8NonControlGenerator, utf8IsControl)); } TEST(Utf8Test, Utf8IsGraphical) @@ -773,311 +471,137 @@ TEST(Utf8Test, Utf8IsGraphical) Array graphicalChars{}; copyMem(graphicalChars, graphicalCharLiteral); - ASSERT_TRUE(allOf(graphicalChars, ext_lib_char_is_graphical)); - - auto graphicalSetResult{StaticSet::makeFromArray(graphicalChars)}; - ASSERT_TRUE(graphicalSetResult.isOkay()); - auto graphicalSet{std::move(graphicalSetResult.getOkay())}; + ASSERT_TRUE(allOf(graphicalChars.span(), charIsGraphical)); constexpr size_t numNonGraphicalChars = validAsciiSize - numGraphicalChars; - FixedVector nonGraphicalChars{}; - for (char idx = 0; idx < INT8_MAX; ++idx) { - if (!graphicalSet.isKey(idx)) { - ASSERT_TRUE(nonGraphicalChars.pushBack(idx)); + Vector nonGraphicalChars{}; + ASSERT_EQ(nonGraphicalChars.reserve(numNonGraphicalChars), FudStatus::Success); + for (uint8_t idx = 0; idx < INT8_MAX + 1; ++idx) { + if (!charIsGraphical(static_cast(idx))) { + ASSERT_EQ(nonGraphicalChars.pushBack(static_cast(idx)), FudStatus::Success); } } - ASSERT_FALSE(anyOf(nonGraphicalChars, ext_lib_char_is_graphical)); - - auto invalidAsciiChars = generateInvalidAsciiChars(); - ASSERT_FALSE(anyOf(invalidAsciiChars, ext_lib_char_is_graphical)); - - ASSERT_TRUE(allOf( - map(graphicalChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_graphical)); - ASSERT_FALSE(anyOf( - map(nonGraphicalChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_graphical)); - ASSERT_FALSE(anyOf( - map(invalidAsciiChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_graphical)); - - ASSERT_TRUE(allOf( - map(graphicalChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_graphical)); - ASSERT_FALSE(anyOf( - map(nonGraphicalChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_graphical)); - ASSERT_FALSE(anyOf( - map(invalidAsciiChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_graphical)); - - Utf8 utf8{invalidAscii}; - bool isAscii = false; - ASSERT_EQ(ext_lib_utf8_is_graphical(nullptr, nullptr), ExtNullPointer); - ASSERT_EQ(ext_lib_utf8_is_graphical(&utf8, nullptr), ExtNullPointer); - ASSERT_EQ(ext_lib_utf8_is_graphical(nullptr, &isAscii), ExtNullPointer); - ASSERT_EQ(ext_lib_utf8_is_graphical(&utf8, &isAscii), ExtInvalidInput); - ASSERT_FALSE(isAscii); - - ASSERT_TRUE(allOf( - map(graphicalChars, - [](char letter) { return FudUtf8::makeUtf8(ExtUtf8Char4{static_cast(letter)}); }), - [](auto& utf8Letter) { - bool predicate = false; - auto isPredicateStatus = ext_lib_utf8_is_graphical(&utf8Letter, &predicate); - return isPredicateStatus == ExtSuccess && predicate; - })); - ASSERT_FALSE(anyOf( - map(nonGraphicalChars, - [](char letter) { return FudUtf8::makeUtf8(ExtUtf8Char4{static_cast(letter)}); }), - [](auto& utf8Letter) { - bool predicate = false; - auto isPredicateStatus = ext_lib_utf8_is_graphical(&utf8Letter, &predicate); - return isPredicateStatus != ExtSuccess || predicate; - })); - ASSERT_FALSE(allOf( - map(nonGraphicalChars, - [](char letter) { return FudUtf8::makeUtf8(ExtUtf8Char4{static_cast(letter)}); }), - [](auto& utf8Letter) { - bool predicate = false; - auto isPredicateStatus = ext_lib_utf8_is_graphical(&utf8Letter, &predicate); - return isPredicateStatus == ExtInvalidInput && !predicate; - })); + ASSERT_FALSE(anyOf(nonGraphicalChars.span().takeOkay(), charIsGraphical)); + ASSERT_TRUE(allOf(nonGraphicalChars.span().takeOkay(), charIsAscii)); + ASSERT_EQ(nonGraphicalChars.size() + graphicalChars.size(), INT8_MAX + 1); + + auto invalidAsciiChars = invalidAsciiGenerator(); + ASSERT_FALSE(anyOf(invalidAsciiChars, charIsGraphical)); + + ASSERT_FALSE(utf8IsGraphical(FudUtf8{Ascii{invalidAscii}})); + + SpanGenerator graphicalGenerator{graphicalChars.span()}; + auto utf8GraphicalGenerator = [&]() { return graphicalGenerator().map(toUtf8); }; + ASSERT_TRUE(allOf(utf8GraphicalGenerator, utf8IsGraphical)); + + SpanGenerator nonGraphicalGenerator{nonGraphicalChars.span().takeOkay()}; + auto utf8NonGraphicalGenerator = [&]() { return nonGraphicalGenerator().map(toUtf8); }; + ASSERT_FALSE(anyOf(utf8NonGraphicalGenerator, utf8IsGraphical)); } TEST(Utf8Test, Utf8IsSpace) { - constexpr size_t numSpaceChars = sizeof(" \t\v\r\n") - 1; - Array spaceCharLiteral{" \t\v\r\n"}; + constexpr size_t numSpaceChars = sizeof(SPACE_CHARS) - 1; + Array spaceCharLiteral{SPACE_CHARS}; Array spaceChars{}; copyMem(spaceChars, spaceCharLiteral); - ASSERT_TRUE(allOf(spaceChars, ext_lib_char_is_space)); - - auto spaceSetResult{StaticSet::makeFromArray(spaceChars)}; - ASSERT_TRUE(spaceSetResult.isOkay()); - auto spaceSet{std::move(spaceSetResult.getOkay())}; + ASSERT_TRUE(allOf(spaceChars.span(), charIsSpace)); constexpr size_t numNonSpaceChars = validAsciiSize - numSpaceChars; - FixedVector nonSpaceChars{}; - for (char idx = 0; idx < INT8_MAX; ++idx) { - if (!spaceSet.isKey(idx)) { - ASSERT_TRUE(nonSpaceChars.pushBack(idx)); + Vector nonSpaceChars{}; + ASSERT_EQ(nonSpaceChars.reserve(numNonSpaceChars), FudStatus::Success); + for (uint8_t idx = 0; idx < INT8_MAX + 1; ++idx) { + if (!charIsSpace(static_cast(idx))) { + ASSERT_EQ(nonSpaceChars.pushBack(static_cast(idx)), FudStatus::Success); } } - ASSERT_FALSE(anyOf(nonSpaceChars, ext_lib_char_is_space)); - - auto invalidAsciiChars = generateInvalidAsciiChars(); - ASSERT_FALSE(anyOf(invalidAsciiChars, ext_lib_char_is_space)); - - ASSERT_TRUE(allOf( - map(spaceChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_space)); - ASSERT_FALSE(anyOf( - map(nonSpaceChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_space)); - ASSERT_FALSE(anyOf( - map(invalidAsciiChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_space)); - - ASSERT_TRUE(allOf( - map(spaceChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_space)); - ASSERT_FALSE(anyOf( - map(nonSpaceChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_space)); - ASSERT_FALSE(anyOf( - map(invalidAsciiChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_space)); - - Utf8 utf8{invalidAscii}; - bool isAscii = false; - ASSERT_EQ(ext_lib_utf8_is_space(nullptr, nullptr), ExtNullPointer); - ASSERT_EQ(ext_lib_utf8_is_space(&utf8, nullptr), ExtNullPointer); - ASSERT_EQ(ext_lib_utf8_is_space(nullptr, &isAscii), ExtNullPointer); - ASSERT_EQ(ext_lib_utf8_is_space(&utf8, &isAscii), ExtInvalidInput); - ASSERT_FALSE(isAscii); - - ASSERT_TRUE(allOf( - map(spaceChars, [](char letter) { return FudUtf8::makeUtf8(ExtUtf8Char4{static_cast(letter)}); }), - [](auto& utf8Letter) { - bool predicate = false; - auto isPredicateStatus = ext_lib_utf8_is_space(&utf8Letter, &predicate); - return isPredicateStatus == ExtSuccess && predicate; - })); - ASSERT_FALSE(anyOf( - map(nonSpaceChars, - [](char letter) { return FudUtf8::makeUtf8(ExtUtf8Char4{static_cast(letter)}); }), - [](auto& utf8Letter) { - bool predicate = false; - auto isPredicateStatus = ext_lib_utf8_is_space(&utf8Letter, &predicate); - return isPredicateStatus != ExtSuccess || predicate; - })); - ASSERT_FALSE(allOf( - map(nonSpaceChars, - [](char letter) { return FudUtf8::makeUtf8(ExtUtf8Char4{static_cast(letter)}); }), - [](auto& utf8Letter) { - bool predicate = false; - auto isPredicateStatus = ext_lib_utf8_is_space(&utf8Letter, &predicate); - return isPredicateStatus == ExtInvalidInput && !predicate; - })); + ASSERT_FALSE(anyOf(nonSpaceChars.span().takeOkay(), charIsSpace)); + ASSERT_TRUE(allOf(nonSpaceChars.span().takeOkay(), charIsAscii)); + ASSERT_EQ(nonSpaceChars.size() + spaceChars.size(), INT8_MAX + 1); + + auto invalidAsciiChars = invalidAsciiGenerator(); + ASSERT_FALSE(anyOf(invalidAsciiChars, charIsSpace)); + + ASSERT_FALSE(utf8IsSpace(FudUtf8{Ascii{invalidAscii}})); + + SpanGenerator spaceGenerator{spaceChars.span()}; + auto utf8SpaceGenerator = [&]() { return spaceGenerator().map(toUtf8); }; + ASSERT_TRUE(allOf(utf8SpaceGenerator, utf8IsSpace)); + + SpanGenerator nonSpaceGenerator{nonSpaceChars.span().takeOkay()}; + auto utf8NonSpaceGenerator = [&]() { return nonSpaceGenerator().map(toUtf8); }; + ASSERT_FALSE(anyOf(utf8NonSpaceGenerator, utf8IsSpace)); } TEST(Utf8Test, Utf8IsBlank) { - constexpr size_t numBlankChars = sizeof(" \t") - 1; - Array blankCharLiteral{" \t"}; + constexpr size_t numBlankChars = sizeof(BLANK_CHARS) - 1; + Array blankCharLiteral{BLANK_CHARS}; Array blankChars{}; copyMem(blankChars, blankCharLiteral); - ASSERT_TRUE(allOf(blankChars, ext_lib_char_is_blank)); - - auto blankSetResult{StaticSet::makeFromArray(blankChars)}; - ASSERT_TRUE(blankSetResult.isOkay()); - auto blankSet{std::move(blankSetResult.getOkay())}; + ASSERT_TRUE(allOf(blankChars.span(), charIsBlank)); constexpr size_t numNonBlankChars = validAsciiSize - numBlankChars; - FixedVector nonBlankChars{}; - for (char idx = 0; idx < INT8_MAX; ++idx) { - if (!blankSet.isKey(idx)) { - ASSERT_TRUE(nonBlankChars.pushBack(idx)); + Vector nonBlankChars{}; + ASSERT_EQ(nonBlankChars.reserve(numNonBlankChars), FudStatus::Success); + for (uint8_t idx = 0; idx < INT8_MAX + 1; ++idx) { + if (!charIsBlank(static_cast(idx))) { + ASSERT_EQ(nonBlankChars.pushBack(static_cast(idx)), FudStatus::Success); } } - ASSERT_FALSE(anyOf(nonBlankChars, ext_lib_char_is_blank)); - - auto invalidAsciiChars = generateInvalidAsciiChars(); - ASSERT_FALSE(anyOf(invalidAsciiChars, ext_lib_char_is_blank)); - - ASSERT_TRUE(allOf( - map(blankChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_blank)); - ASSERT_FALSE(anyOf( - map(nonBlankChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_blank)); - ASSERT_FALSE(anyOf( - map(invalidAsciiChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_blank)); - - ASSERT_TRUE(allOf( - map(blankChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_blank)); - ASSERT_FALSE(anyOf( - map(nonBlankChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_blank)); - ASSERT_FALSE(anyOf( - map(invalidAsciiChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_blank)); - - Utf8 utf8{invalidAscii}; - bool isAscii = false; - ASSERT_EQ(ext_lib_utf8_is_blank(nullptr, nullptr), ExtNullPointer); - ASSERT_EQ(ext_lib_utf8_is_blank(&utf8, nullptr), ExtNullPointer); - ASSERT_EQ(ext_lib_utf8_is_blank(nullptr, &isAscii), ExtNullPointer); - ASSERT_EQ(ext_lib_utf8_is_blank(&utf8, &isAscii), ExtInvalidInput); - ASSERT_FALSE(isAscii); - - ASSERT_TRUE(allOf( - map(blankChars, [](char letter) { return FudUtf8::makeUtf8(ExtUtf8Char4{static_cast(letter)}); }), - [](auto& utf8Letter) { - bool predicate = false; - auto isPredicateStatus = ext_lib_utf8_is_blank(&utf8Letter, &predicate); - return isPredicateStatus == ExtSuccess && predicate; - })); - ASSERT_FALSE(anyOf( - map(nonBlankChars, - [](char letter) { return FudUtf8::makeUtf8(ExtUtf8Char4{static_cast(letter)}); }), - [](auto& utf8Letter) { - bool predicate = false; - auto isPredicateStatus = ext_lib_utf8_is_blank(&utf8Letter, &predicate); - return isPredicateStatus != ExtSuccess || predicate; - })); - ASSERT_FALSE(allOf( - map(nonBlankChars, - [](char letter) { return FudUtf8::makeUtf8(ExtUtf8Char4{static_cast(letter)}); }), - [](auto& utf8Letter) { - bool predicate = false; - auto isPredicateStatus = ext_lib_utf8_is_blank(&utf8Letter, &predicate); - return isPredicateStatus == ExtInvalidInput && !predicate; - })); + ASSERT_FALSE(anyOf(nonBlankChars.span().takeOkay(), charIsBlank)); + ASSERT_TRUE(allOf(nonBlankChars.span().takeOkay(), charIsAscii)); + ASSERT_EQ(nonBlankChars.size() + blankChars.size(), INT8_MAX + 1); + + auto invalidAsciiChars = invalidAsciiGenerator(); + ASSERT_FALSE(anyOf(invalidAsciiChars, charIsBlank)); + + ASSERT_FALSE(utf8IsBlank(FudUtf8{Ascii{invalidAscii}})); + + SpanGenerator blankGenerator{blankChars.span()}; + auto utf8BlankGenerator = [&]() { return blankGenerator().map(toUtf8); }; + ASSERT_TRUE(allOf(utf8BlankGenerator, utf8IsBlank)); + + SpanGenerator nonBlankGenerator{nonBlankChars.span().takeOkay()}; + auto utf8NonBlankGenerator = [&]() { return nonBlankGenerator().map(toUtf8); }; + ASSERT_FALSE(anyOf(utf8NonBlankGenerator, utf8IsBlank)); } TEST(Utf8Test, Utf8IsPrintable) { - constexpr size_t numPrintableChars = validAsciiSize - numControlChars; - auto printableChars = generateIndexArray([](int idx) { - return static_cast(idx + printableCharOffset); - }); - - ASSERT_TRUE(allOf(printableChars, ext_lib_char_is_printable)); + constexpr size_t numPrintableChars = sizeof(PRINTABLE_CHARS) - 1; + Array printableCharLiteral{PRINTABLE_CHARS}; + Array printableChars{}; + copyMem(printableChars, printableCharLiteral); - auto printableSetResult{StaticSet::makeFromArray(printableChars)}; - ASSERT_TRUE(printableSetResult.isOkay()); - auto printableSet{std::move(printableSetResult.getOkay())}; + ASSERT_TRUE(allOf(printableChars.span(), charIsPrintable)); constexpr size_t numNonPrintableChars = validAsciiSize - numPrintableChars; - FixedVector nonPrintableChars{}; - for (char idx = 0; idx < INT8_MAX; ++idx) { - if (!printableSet.isKey(idx)) { - ASSERT_TRUE(nonPrintableChars.pushBack(idx)); + Vector nonPrintableChars{}; + ASSERT_EQ(nonPrintableChars.reserve(numNonPrintableChars), FudStatus::Success); + for (uint8_t idx = 0; idx < INT8_MAX + 1; ++idx) { + if (!charIsPrintable(static_cast(idx))) { + ASSERT_EQ(nonPrintableChars.pushBack(static_cast(idx)), FudStatus::Success); } } - ASSERT_FALSE(anyOf(nonPrintableChars, ext_lib_char_is_printable)); - - auto invalidAsciiChars = generateInvalidAsciiChars(); - ASSERT_FALSE(anyOf(invalidAsciiChars, ext_lib_char_is_printable)); - - ASSERT_TRUE(allOf( - map(printableChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_printable)); - ASSERT_FALSE(anyOf( - map(nonPrintableChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_printable)); - ASSERT_FALSE(anyOf( - map(invalidAsciiChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_printable)); - - ASSERT_TRUE(allOf( - map(printableChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_printable)); - ASSERT_FALSE(anyOf( - map(nonPrintableChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_printable)); - ASSERT_FALSE(anyOf( - map(invalidAsciiChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_printable)); - - Utf8 utf8{invalidAscii}; - bool isAscii = false; - ASSERT_EQ(ext_lib_utf8_is_printable(nullptr, nullptr), ExtNullPointer); - ASSERT_EQ(ext_lib_utf8_is_printable(&utf8, nullptr), ExtNullPointer); - ASSERT_EQ(ext_lib_utf8_is_printable(nullptr, &isAscii), ExtNullPointer); - ASSERT_EQ(ext_lib_utf8_is_printable(&utf8, &isAscii), ExtInvalidInput); - ASSERT_FALSE(isAscii); - - ASSERT_TRUE(allOf( - map(printableChars, - [](char letter) { return FudUtf8::makeUtf8(ExtUtf8Char4{static_cast(letter)}); }), - [](auto& utf8Letter) { - bool predicate = false; - auto isPredicateStatus = ext_lib_utf8_is_printable(&utf8Letter, &predicate); - return isPredicateStatus == ExtSuccess && predicate; - })); - ASSERT_FALSE(anyOf( - map(nonPrintableChars, - [](char letter) { return FudUtf8::makeUtf8(ExtUtf8Char4{static_cast(letter)}); }), - [](auto& utf8Letter) { - bool predicate = false; - auto isPredicateStatus = ext_lib_utf8_is_printable(&utf8Letter, &predicate); - return isPredicateStatus != ExtSuccess || predicate; - })); - ASSERT_FALSE(allOf( - map(nonPrintableChars, - [](char letter) { return FudUtf8::makeUtf8(ExtUtf8Char4{static_cast(letter)}); }), - [](auto& utf8Letter) { - bool predicate = false; - auto isPredicateStatus = ext_lib_utf8_is_printable(&utf8Letter, &predicate); - return isPredicateStatus == ExtInvalidInput && !predicate; - })); + ASSERT_FALSE(anyOf(nonPrintableChars.span().takeOkay(), charIsPrintable)); + ASSERT_TRUE(allOf(nonPrintableChars.span().takeOkay(), charIsAscii)); + ASSERT_EQ(nonPrintableChars.size() + printableChars.size(), INT8_MAX + 1); + + auto invalidAsciiChars = invalidAsciiGenerator(); + ASSERT_FALSE(anyOf(invalidAsciiChars, charIsPrintable)); + + ASSERT_FALSE(utf8IsPrintable(FudUtf8{Ascii{invalidAscii}})); + + SpanGenerator printableGenerator{printableChars.span()}; + auto utf8PrintableGenerator = [&]() { return printableGenerator().map(toUtf8); }; + ASSERT_TRUE(allOf(utf8PrintableGenerator, utf8IsPrintable)); + + SpanGenerator nonPrintableGenerator{nonPrintableChars.span().takeOkay()}; + auto utf8NonPrintableGenerator = [&]() { return nonPrintableGenerator().map(toUtf8); }; + ASSERT_FALSE(anyOf(utf8NonPrintableGenerator, utf8IsPrintable)); } TEST(Utf8Test, Utf8IsPunctuation) @@ -1087,77 +611,32 @@ TEST(Utf8Test, Utf8IsPunctuation) Array punctuationChars{}; copyMem(punctuationChars, punctuationCharLiteral); - ASSERT_TRUE(allOf(punctuationChars, ext_lib_char_is_punctuation)); - - auto punctuationSetResult{StaticSet::makeFromArray(punctuationChars)}; - ASSERT_TRUE(punctuationSetResult.isOkay()); - auto punctuationSet{std::move(punctuationSetResult.getOkay())}; + ASSERT_TRUE(allOf(punctuationChars.span(), charIsPunctuation)); constexpr size_t numNonPunctuationChars = validAsciiSize - numPunctuationChars; - FixedVector nonPunctuationChars{}; - for (char idx = 0; idx < INT8_MAX; ++idx) { - if (!punctuationSet.isKey(idx)) { - ASSERT_TRUE(nonPunctuationChars.pushBack(idx)); + Vector nonPunctuationChars{}; + ASSERT_EQ(nonPunctuationChars.reserve(numNonPunctuationChars), FudStatus::Success); + for (uint8_t idx = 0; idx < INT8_MAX + 1; ++idx) { + if (!charIsPunctuation(static_cast(idx))) { + ASSERT_EQ(nonPunctuationChars.pushBack(static_cast(idx)), FudStatus::Success); } } - ASSERT_FALSE(anyOf(nonPunctuationChars, ext_lib_char_is_punctuation)); - - auto invalidAsciiChars = generateInvalidAsciiChars(); - ASSERT_FALSE(anyOf(invalidAsciiChars, ext_lib_char_is_punctuation)); - - ASSERT_TRUE(allOf( - map(punctuationChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_punctuation)); - ASSERT_FALSE(anyOf( - map(nonPunctuationChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_punctuation)); - ASSERT_FALSE(anyOf( - map(invalidAsciiChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_punctuation)); - - ASSERT_TRUE(allOf( - map(punctuationChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_punctuation)); - ASSERT_FALSE(anyOf( - map(nonPunctuationChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_punctuation)); - ASSERT_FALSE(anyOf( - map(invalidAsciiChars, [](auto input) { return ExtUtf8Char4{static_cast(input)}; }), - ext_lib_char4_is_punctuation)); - - Utf8 utf8{invalidAscii}; - bool isAscii = false; - ASSERT_EQ(ext_lib_utf8_is_punctuation(nullptr, nullptr), ExtNullPointer); - ASSERT_EQ(ext_lib_utf8_is_punctuation(&utf8, nullptr), ExtNullPointer); - ASSERT_EQ(ext_lib_utf8_is_punctuation(nullptr, &isAscii), ExtNullPointer); - ASSERT_EQ(ext_lib_utf8_is_punctuation(&utf8, &isAscii), ExtInvalidInput); - ASSERT_FALSE(isAscii); - - ASSERT_TRUE(allOf( - map(punctuationChars, - [](char letter) { return FudUtf8::makeUtf8(ExtUtf8Char4{static_cast(letter)}); }), - [](auto& utf8Letter) { - bool predicate = false; - auto isPredicateStatus = ext_lib_utf8_is_punctuation(&utf8Letter, &predicate); - return isPredicateStatus == ExtSuccess && predicate; - })); - ASSERT_FALSE(anyOf( - map(nonPunctuationChars, - [](char letter) { return FudUtf8::makeUtf8(ExtUtf8Char4{static_cast(letter)}); }), - [](auto& utf8Letter) { - bool predicate = false; - auto isPredicateStatus = ext_lib_utf8_is_punctuation(&utf8Letter, &predicate); - return isPredicateStatus != ExtSuccess || predicate; - })); - ASSERT_FALSE(allOf( - map(nonPunctuationChars, - [](char letter) { return FudUtf8::makeUtf8(ExtUtf8Char4{static_cast(letter)}); }), - [](auto& utf8Letter) { - bool predicate = false; - auto isPredicateStatus = ext_lib_utf8_is_punctuation(&utf8Letter, &predicate); - return isPredicateStatus == ExtInvalidInput && !predicate; - })); + ASSERT_FALSE(anyOf(nonPunctuationChars.span().takeOkay(), charIsPunctuation)); + ASSERT_TRUE(allOf(nonPunctuationChars.span().takeOkay(), charIsAscii)); + ASSERT_EQ(nonPunctuationChars.size() + punctuationChars.size(), INT8_MAX + 1); + + auto invalidAsciiChars = invalidAsciiGenerator(); + ASSERT_FALSE(anyOf(invalidAsciiChars, charIsPunctuation)); + + ASSERT_FALSE(utf8IsPunctuation(FudUtf8{Ascii{invalidAscii}})); + + SpanGenerator punctuationGenerator{punctuationChars.span()}; + auto utf8PunctuationGenerator = [&]() { return punctuationGenerator().map(toUtf8); }; + ASSERT_TRUE(allOf(utf8PunctuationGenerator, utf8IsPunctuation)); + + SpanGenerator nonPunctuationGenerator{nonPunctuationChars.span().takeOkay()}; + auto utf8NonPunctuationGenerator = [&]() { return nonPunctuationGenerator().map(toUtf8); }; + ASSERT_FALSE(anyOf(utf8NonPunctuationGenerator, utf8IsPunctuation)); } -#endif } // namespace fud diff --git a/test/test_vector.cpp b/test/test_vector.cpp new file mode 100644 index 0000000..b4fd83c --- /dev/null +++ b/test/test_vector.cpp @@ -0,0 +1,138 @@ +/* + * libfud + * Copyright 2024 Dominick Allen + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "fud_vector.hpp" + +#include "gtest/gtest.h" + +namespace fud { + +TEST(VectorTest, TrivialVector) +{ + Vector intVector{}; + ASSERT_EQ(intVector.size(), 0); + ASSERT_EQ(intVector.capacity(), 0); + ASSERT_TRUE(intVector.ref(0).isError()); + + ASSERT_EQ(intVector.resize(10), FudStatus::Success); + ASSERT_EQ(intVector.size(), 10); + ASSERT_EQ(intVector.capacity(), 10); + + ASSERT_TRUE(intVector.ref(0).isOkay()); + ASSERT_EQ(intVector.ref(0).getOkay(), 0); + intVector.get(0).takeOkay().get() = 10; + ASSERT_EQ(intVector.ref(0).getOkay(), 10); +} + +struct NonTrivial { + static thread_local int counter; + NonTrivial() + { + counter++; + } + explicit NonTrivial(int val) : value{val} + { + counter++; + } + NonTrivial(const NonTrivial&) = delete; + NonTrivial(NonTrivial&& rhs) : value{rhs.value}, destroyed{rhs.destroyed} + { + rhs.destroyed = true; + } + ~NonTrivial() + { + if (!destroyed) { + counter--; + destroyed = true; + } + } + NonTrivial& operator=(const NonTrivial& rhs) = delete; + NonTrivial& operator=(NonTrivial&& rhs) { + value = rhs.value; + destroyed = rhs.destroyed; + rhs.destroyed = true; + return *this; + } + int value{0}; + bool destroyed{false}; +}; + +int thread_local NonTrivial::counter = 0; + +TEST(VectorTest, NonTrivialVector) +{ + auto& counter = NonTrivial::counter; + counter = 0; + Vector nonTrivialVector{}; + ASSERT_EQ(nonTrivialVector.size(), 0); + ASSERT_EQ(nonTrivialVector.capacity(), 0); + ASSERT_TRUE(nonTrivialVector.ref(0).isError()); + ASSERT_EQ(counter, 0); + + ASSERT_EQ(nonTrivialVector.resize(10), FudStatus::Success); + ASSERT_EQ(nonTrivialVector.size(), 10); + ASSERT_EQ(nonTrivialVector.capacity(), 10); + ASSERT_EQ(counter, 10); + + ASSERT_TRUE(nonTrivialVector.ref(0).isOkay()); + ASSERT_EQ(nonTrivialVector.ref(0).getOkay().get().value, 0); + nonTrivialVector.get(0).takeOkay().get().value = 10; + ASSERT_EQ(nonTrivialVector.ref(0).getOkay().get().value, 10); + + ASSERT_EQ(nonTrivialVector.pushBack(NonTrivial{42}), FudStatus::Success); + ASSERT_EQ(nonTrivialVector.size(), 11); + ASSERT_GE(nonTrivialVector.capacity(), 11); + ASSERT_EQ(counter, 11); + auto capacity = nonTrivialVector.capacity(); + ASSERT_EQ(nonTrivialVector.reserve(SIZE_MAX / sizeof(NonTrivial)), FudStatus::AllocFailure); + ASSERT_EQ(nonTrivialVector.capacity(), capacity); + + { + auto popResult{nonTrivialVector.popBack()}; + ASSERT_TRUE(popResult.isOkay()); + auto value{popResult.takeOkay()}; + ASSERT_EQ(value.value, 42); + ASSERT_EQ(counter, 11); + } + ASSERT_EQ(counter, 10); + ASSERT_EQ(nonTrivialVector.eraseBack(), FudStatus::Success); + ASSERT_EQ(counter, 9); + + int val = 1; + for (auto& element: nonTrivialVector) { + element.value = val; + val++; + } + ASSERT_EQ(nonTrivialVector.insert(3, NonTrivial{13}), FudStatus::Success); + for (size_t idx = 0; idx < 3; ++idx) { + ASSERT_EQ(nonTrivialVector[idx].value, idx + 1); + } + ASSERT_EQ(counter, 10); + ASSERT_EQ(nonTrivialVector[3].value, 13); + for (size_t idx = 4; idx < nonTrivialVector.size(); ++idx) { + ASSERT_EQ(nonTrivialVector[idx].value, idx); + } + ASSERT_EQ(counter, nonTrivialVector.size()); + + ASSERT_EQ(nonTrivialVector.erase(3), FudStatus::Success); + for (size_t idx = 0; idx < nonTrivialVector.size(); ++idx) { + EXPECT_EQ(nonTrivialVector[idx].value, idx + 1); + } + ASSERT_EQ(counter, nonTrivialVector.size()); +} + +} // namespace fud -- cgit v1.2.3