diff options
-rw-r--r-- | include/fud_directory.hpp | 4 | ||||
-rw-r--r-- | include/fud_option.hpp | 17 | ||||
-rw-r--r-- | include/fud_sqlite.hpp | 11 | ||||
-rw-r--r-- | include/fud_string_convert.hpp | 4 | ||||
-rw-r--r-- | include/fud_string_view.hpp | 11 | ||||
-rw-r--r-- | include/libfud.hpp | 7 | ||||
-rw-r--r-- | source/fud_string.cpp | 24 | ||||
-rw-r--r-- | source/fud_string_view.cpp | 115 | ||||
-rw-r--r-- | source/libfud.cpp | 15 | ||||
-rw-r--r-- | test/test_csv.cpp | 2 | ||||
-rw-r--r-- | test/test_directory.cpp | 12 | ||||
-rw-r--r-- | test/test_fud.cpp | 11 | ||||
-rw-r--r-- | test/test_string.cpp | 15 | ||||
-rwxr-xr-x | tools/coverage.sh | 2 |
14 files changed, 188 insertions, 62 deletions
diff --git a/include/fud_directory.hpp b/include/fud_directory.hpp index e935950..d7f6b1f 100644 --- a/include/fud_directory.hpp +++ b/include/fud_directory.hpp @@ -99,11 +99,11 @@ class Directory { Directory& operator=(const Directory& rhs) = delete; Directory& operator=(Directory&& rhs) noexcept = delete; - constexpr const String& name() const { + [[nodiscard]] constexpr const String& name() const { return m_name; } - constexpr int errorCode() const + [[nodiscard]] constexpr int errorCode() const { return m_errorCode; } diff --git a/include/fud_option.hpp b/include/fud_option.hpp index 3c94eaa..9d3068c 100644 --- a/include/fud_option.hpp +++ b/include/fud_option.hpp @@ -75,10 +75,11 @@ class Option { private: static_assert(!std::is_same_v<T, option_detail::NullOptionType>); static constexpr bool IsRef = std::is_reference_v<T>; - using ValueType = typename std::remove_reference<T>::type; - static constexpr size_t Size = IsRef ? sizeof(std::reference_wrapper<ValueType>) : sizeof(ValueType); public: + using ValueType = std::remove_reference_t<T>; + static constexpr size_t Size = IsRef ? sizeof(std::reference_wrapper<ValueType>) : sizeof(ValueType); + constexpr Option() noexcept : m_engaged{false} { } @@ -100,6 +101,7 @@ class Option { constexpr static Option take(T&& value) noexcept { Option option{}; + option.m_engaged = true; if constexpr (IsRef) { new (option.m_data.data()) std::reference_wrapper<ValueType>(std::ref(value)); } else { @@ -152,7 +154,8 @@ class Option { return !m_engaged; } - operator bool() const { + operator bool() const + { return hasValue(); } @@ -160,8 +163,10 @@ class Option { { fudAssert(m_engaged); if constexpr (IsRef) { + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) return *reinterpret_cast<const std::reference_wrapper<ValueType>*>(m_data.data()); } else { + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) return *reinterpret_cast<const ValueType*>(m_data.data()); } } @@ -170,8 +175,10 @@ class Option { { fudAssert(m_engaged); if constexpr (IsRef) { + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) return *reinterpret_cast<std::reference_wrapper<ValueType>*>(m_data.data()); } else { + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) return *reinterpret_cast<ValueType*>(m_data.data()); } } @@ -180,6 +187,7 @@ class Option { { fudAssert(m_engaged); static_assert(!IsRef); + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) return std::move(*reinterpret_cast<const ValueType*>(m_data.data())); } @@ -200,7 +208,7 @@ class Option { } template <typename F> - constexpr auto map(F&& func) const & -> Option<decltype(std::forward<F>(func)(value()))> + constexpr auto map(F&& func) const& -> Option<decltype(std::forward<F>(func)(value()))> { using U = decltype(std::forward<F>(func)(value())); // static_assert(std::is_same_v<decltype(std::forward<F>(func)(value())), Option<U>>()); @@ -217,6 +225,7 @@ class Option { if constexpr (IsRef) { // reinterpret_cast<std::reference_wrapper<ValueType>*>(m_data.data()); } else { + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) reinterpret_cast<ValueType*>(m_data.data())->~ValueType(); } cleanup(); diff --git a/include/fud_sqlite.hpp b/include/fud_sqlite.hpp index c56b4a1..b2d2f5b 100644 --- a/include/fud_sqlite.hpp +++ b/include/fud_sqlite.hpp @@ -28,6 +28,7 @@ namespace fud { class SqliteStatement; +// NOLINTNEXTLINE(performance-enum-size) enum class SqliteOpenMode : int { ReadOnly = SQLITE_OPEN_READONLY, @@ -59,7 +60,7 @@ class SqliteDb { SqliteDb& operator=(SqliteDb&& rhs) noexcept; - bool valid() const; + [[nodiscard]] bool valid() const; bool revalidate(); @@ -69,12 +70,12 @@ class SqliteDb { void* context, std::unique_ptr<SqliteErrorMsg> errorMessage); - constexpr int errorCode() + [[nodiscard]] constexpr int errorCode() const { return m_errorCode; } - constexpr sqlite3* handle() const + [[nodiscard]] constexpr sqlite3* handle() const { return m_dbHandle; } @@ -115,7 +116,7 @@ class SqliteStatement { SqliteStatement& operator=(SqliteStatement&& rhs) noexcept = delete; - bool valid() const; + [[nodiscard]] bool valid() const; sqlite3_stmt* statement(); @@ -123,7 +124,7 @@ class SqliteStatement { FudStatus reset(); - constexpr int errorCode() + [[nodiscard]] constexpr int errorCode() const { return m_errorCode; } diff --git a/include/fud_string_convert.hpp b/include/fud_string_convert.hpp index d7a62f0..e1b7e95 100644 --- a/include/fud_string_convert.hpp +++ b/include/fud_string_convert.hpp @@ -106,6 +106,7 @@ Result<bool, FudStatus> checkNegative(StringView& view, size_t& skipIndex); Result<uint8_t, FudStatus> getRadix(StringView& view, size_t& skipIndex, Option<uint8_t> specifiedRadixOption); template <typename T> +// NOLINTNEXTLINE(performance-unnecessary-value-param) StringConvertResult<T> unsignedFromString(StringView nextView, size_t skipIndex, Option<uint8_t> specifiedRadixOption) { static_assert(std::is_unsigned_v<T> && std::is_integral_v<T>); @@ -114,6 +115,7 @@ StringConvertResult<T> unsignedFromString(StringView nextView, size_t skipIndex, return FudError{FudStatus::ArgumentInvalid}; } + // NOLINTNEXTLINE(performance-unnecessary-value-param) auto radixResult = impl::getRadix(nextView, skipIndex, specifiedRadixOption); if (radixResult.isError()) { return FudError{radixResult.takeError()}; @@ -206,6 +208,7 @@ StringConvertResult<T> signedFromString(StringView nextView, size_t skipIndex, O return FudError{FudStatus::ArgumentInvalid}; } + // NOLINTNEXTLINE(performance-unnecessary-value-param) auto radixResult = impl::getRadix(nextView, skipIndex, specifiedRadixOption); if (radixResult.isError()) { return FudError{radixResult.takeError()}; @@ -372,6 +375,7 @@ StringConvertResult<T> floatFromString(StringView nextView, size_t skipIndex, Op return retSuccess(); } + // NOLINTNEXTLINE(performance-unnecessary-value-param) auto radixResult = impl::getRadix(nextView, skipIndex, specifiedRadixOption); if (radixResult.isError()) { return FudError{radixResult.takeError()}; diff --git a/include/fud_string_view.hpp b/include/fud_string_view.hpp index c3bc0a1..d8f67ba 100644 --- a/include/fud_string_view.hpp +++ b/include/fud_string_view.hpp @@ -84,6 +84,11 @@ struct StringView { return StringView{N - 1, reinterpret_cast<const utf8*>(input)}; } + [[nodiscard]] std::string_view as_string_view() const { + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + return std::string_view{reinterpret_cast<const char*>(m_data), m_length}; + } + [[nodiscard]] constexpr Span<const utf8> asSpan() const { return Span<const utf8>{m_data, m_length}; @@ -144,7 +149,11 @@ struct StringView { const utf8* m_data{nullptr}; - auto operator<=>(const StringView& rhs) const noexcept = default; + // auto operator<=>(const StringView& rhs) const noexcept = default; + auto operator<=>(const StringView& rhs) const noexcept; + bool operator==(const StringView& rhs) const noexcept; + + Result<std::strong_ordering, FudStatus> compare(const StringView& rhs); }; } // namespace fud diff --git a/include/libfud.hpp b/include/libfud.hpp index f0a2517..542c836 100644 --- a/include/libfud.hpp +++ b/include/libfud.hpp @@ -18,8 +18,9 @@ #ifndef LIBFUD_HPP #define LIBFUD_HPP -#include "fud_array.hpp" #include "fud_allocator.hpp" +#include "fud_array.hpp" +#include "fud_option.hpp" #include "fud_result.hpp" #include "fud_status.hpp" #include "fud_string.hpp" @@ -55,7 +56,7 @@ FUD fud(); * \returns FudStatus::NullPointer if name is a null pointer. * \returns FudStatus::NotFound if no binding for the variable exists. */ -Result<String, FudStatus> getEnv(const char* name, Allocator* allocator= &globalFudAllocator); +Result<Option<String>, FudStatus> getEnv(const char* name, Allocator* allocator = &globalFudAllocator); /** \brief A concept requiring the object T to have a method c_str returning a * pointer to a C string. */ @@ -75,7 +76,7 @@ concept CStringRepr = requires(T strObj) { * \returns @getEnv return values. */ template <CStringRepr T> -Result<String, FudStatus> getEnv(const T& name, Allocator* allocator = &globalFudAllocator) +Result<Option<String>, FudStatus> getEnv(const T& name, Allocator* allocator = &globalFudAllocator) { return getEnv(name.c_str(), allocator); } diff --git a/source/fud_string.cpp b/source/fud_string.cpp index 2a17201..37a2a4b 100644 --- a/source/fud_string.cpp +++ b/source/fud_string.cpp @@ -19,12 +19,11 @@ #include "fud_assert.hpp" -#include <type_traits> - namespace fud { StringResult String::makeFromCString(const char8_t* cString) { + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) return makeFromCString(reinterpret_cast<const char*>(cString)); } @@ -35,6 +34,7 @@ StringResult String::makeFromCString(const char* cString) StringResult String::makeFromCString(const char8_t* cString, Allocator* allocator) { + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) return makeFromCString(reinterpret_cast<const char*>(cString), allocator); } @@ -61,6 +61,7 @@ StringResult String::makeFromCString(const char* cString, Allocator* allocator) } String output{}; + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) output.m_allocator = reinterpret_cast<uintptr_t>(allocator); utf8* outputData{nullptr}; @@ -86,6 +87,7 @@ StringResult String::makeFromCString(const char* cString, Allocator* allocator) return StringResult::okay(std::move(output)); } +//NOLINTNEXTLINE(performance-unnecessary-value-param) StringResult String::from(const String& rhs, Option<Allocator*> allocatorOption) { if (!rhs.valid()) { @@ -98,10 +100,11 @@ StringResult String::from(const String& rhs, Option<Allocator*> allocatorOption) } String output{}; + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) output.m_allocator = reinterpret_cast<uintptr_t>(allocator); utf8* outputData{nullptr}; - size_t outputCapacity{0}; - size_t outputLength{0}; + size_t outputCapacity{rhs.capacity()}; + size_t outputLength{rhs.length()}; if (rhs.isLarge()) { auto status = output.makeLarge(outputCapacity, outputLength, outputData); if (status != FudStatus::Success) { @@ -132,6 +135,7 @@ StringResult String::from(StringView view, Allocator* allocator) } String output{}; + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) output.m_allocator = reinterpret_cast<uintptr_t>(allocator); size_t outputCapacity = view.length() + 1U; bool isLarge = outputCapacity > SsoBufSize; @@ -154,7 +158,7 @@ StringResult String::from(StringView view, Allocator* allocator) return StringResult::okay(std::move(output)); } -String::String(String&& rhs) noexcept : m_allocator{rhs.m_allocator}, m_repr{std::move(rhs.m_repr)} +String::String(String&& rhs) noexcept : m_allocator{rhs.m_allocator}, m_repr{rhs.m_repr} { rhs.setSmall(); rhs.m_repr.small.length = 0; @@ -189,6 +193,7 @@ FudStatus String::copy(const String& rhs) if (allocResult.isError()) { return allocResult.takeError(); } + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) m_repr.large.data = reinterpret_cast<utf8*>(allocResult.takeOkay()); outputCapacity = m_repr.large.capacity; outputLength = m_repr.large.length; @@ -219,7 +224,7 @@ String& String::operator=(String&& rhs) noexcept cleanup(); m_allocator = rhs.m_allocator; - m_repr = std::move(rhs.m_repr); + m_repr = rhs.m_repr; if (isLarge()) { rhs.m_repr.large.data = nullptr; @@ -232,6 +237,7 @@ void String::cleanup() { const auto* allocPtr = allocator(); if (isLarge() && m_repr.large.data != nullptr && allocPtr != nullptr) { + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) allocator()->deallocate(reinterpret_cast<std::byte*>(m_repr.large.data), m_repr.large.capacity); m_repr.large.data = nullptr; } @@ -259,6 +265,7 @@ FudStatus String::resize(size_t newCapacity) auto copyResult = copyMem(dataMut(), temp.size(), temp.data(), len); fudAssert(copyResult == FudStatus::Success); + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) allocator()->deallocate(reinterpret_cast<std::byte*>(m_repr.large.data), m_repr.large.capacity); setSmall(); m_repr.small.length = len & smallStringLengthMask; @@ -272,6 +279,7 @@ FudStatus String::resize(size_t newCapacity) if (allocResult.isError()) { return allocResult.takeError(); } + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) auto* newData = reinterpret_cast<utf8*>(allocResult.takeOkay()); fudAssert(newData != nullptr); @@ -279,6 +287,7 @@ FudStatus String::resize(size_t newCapacity) fudAssert(copyResult == FudStatus::Success); if (isLarge()) { + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) allocator()->deallocate(reinterpret_cast<std::byte*>(m_repr.large.data), m_repr.large.capacity); } @@ -658,7 +667,7 @@ StringResult String::catenate(const char* rhs) const if (lenResult < 0 || lenResult >= static_cast<ssize_t>(maxStringLength)) { return StringResult::error(FudStatus::ArgumentInvalid); } - size_t rhsLength = static_cast<size_t>(lenResult); + auto rhsLength = static_cast<size_t>(lenResult); if (maxStringLength - length() < rhsLength) { return StringResult::error(FudStatus::Failure); @@ -804,6 +813,7 @@ FudStatus String::makeLarge(size_t cap, size_t len, utf8*& outputData) if (dataResult.isError()) { return dataResult.getError(); } + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) m_repr.large.data = reinterpret_cast<utf8*>(dataResult.getOkay()); outputData = m_repr.large.data; setLarge(); diff --git a/source/fud_string_view.cpp b/source/fud_string_view.cpp index ba88ad4..5c5e623 100644 --- a/source/fud_string_view.cpp +++ b/source/fud_string_view.cpp @@ -133,6 +133,96 @@ FudStatus skipWhitespace(StringView& view, size_t& skipIndex) return FudStatus::Success; } +FudStatus fud_string_compare(StringView levo, StringView dextro, int& difference) +{ + if (anyAreNull(levo.m_data, dextro.m_data)) { + return FudStatus::NullPointer; + } + + int diff = 0; + size_t index = 0; + while (diff == 0 && index < levo.length() && index < dextro.length()) { + diff = levo.m_data[index] - dextro.m_data[index]; + index++; + } + + if (diff != 0 || levo.length() == dextro.length()) { + /* nothing to do */ + } else if (levo.length() > dextro.length()) { + diff = static_cast<int>(levo.m_data[index]); + } else { + diff = -static_cast<int>(dextro.m_data[index]); + } + + difference = diff; + return FudStatus::Success; +} + +bool StringView::operator==(const StringView& rhs) const noexcept +{ + if (m_length == rhs.m_length && m_data == rhs.m_data) { + return true; + } + int difference{}; + auto compareStatus = fud_string_compare(*this, rhs, difference); + if (compareStatus != FudStatus::Success) { + if (m_data != nullptr && rhs.m_data == nullptr) { + return false; + } + if (m_data == nullptr && rhs.m_data != nullptr) { + return false; + } + fudAssert(m_data == nullptr && rhs.m_data == nullptr); + if (m_length > rhs.m_length) { + return false; + } + fudAssert(m_length < rhs.m_length); + return false; + } + if (difference > 0) { + return false; + } + if (difference < 0) { + return false; + } + return true; + +} + +auto StringView::operator<=>(const StringView& rhs) const noexcept +{ + if (this == &rhs) { + return std::strong_ordering::equivalent; + } + if (m_length == rhs.m_length && m_data == rhs.m_data) + { + return std::strong_ordering::equivalent; + } + int difference{}; + auto compareStatus = fud_string_compare(*this, rhs, difference); + if (compareStatus != FudStatus::Success) { + if (m_data != nullptr && rhs.m_data == nullptr) { + return std::strong_ordering::greater; + } + if (m_data == nullptr && rhs.m_data != nullptr) { + return std::strong_ordering::less; + } + fudAssert(m_data == nullptr && rhs.m_data == nullptr); + if (m_length > rhs.m_length) { + return std::strong_ordering::greater; + } + fudAssert(m_length < rhs.m_length); + return std::strong_ordering::less; + } + if (difference > 0) { + return std::strong_ordering::greater; + } + if (difference < 0) { + return std::strong_ordering::less; + } + return std::strong_ordering::equivalent; +} + #if 0 FudStatus fud_string_truncate(ExtBasicString* source, ssize_t newLength) @@ -226,31 +316,6 @@ FudStatus fud_string_reverse_substring(ExtBasicString* source, StringView subStr return FudStatus::Success; } -FudStatus fud_string_compare(StringView levo, StringView dextro, int* difference) -{ - if (anyAreNull(difference, levo.data, dextro.data)) { - return FudStatus::NullPointer; - } - - int diff = 0; - size_t index = 0; - while (diff == 0 && index < levo.length && index < dextro.length) { - diff = levo.data[index] - dextro.data[index]; - index++; - } - - if (diff != 0 || levo.length == dextro.length) { - /* nothing to do */ - } else if (levo.length > dextro.length) { - diff = static_cast<int>(levo.data[index]); - } else { - diff = -static_cast<int>(dextro.data[index]); - } - - *difference = diff; - return FudStatus::Success; -} - FudStatus fud_string_chr(StringView extStringView, char character, size_t* index) { if (anyAreNull(extStringView.data, index)) { diff --git a/source/libfud.cpp b/source/libfud.cpp index be43490..c4e4b5b 100644 --- a/source/libfud.cpp +++ b/source/libfud.cpp @@ -35,20 +35,23 @@ FUD fud() return fudInfo; } -Result<String, FudStatus> getEnv(const char* name, Allocator* allocator) +Result<Option<String>, FudStatus> getEnv(const char* name, Allocator* allocator) { - using RetType = Result<String, FudStatus>; - if (name == nullptr) { - return RetType::error(FudStatus::NullPointer); + return Error{FudStatus::NullPointer}; } const char* resultString = getenv(name); if (resultString == nullptr) { - return RetType::error(FudStatus::NotFound); + return Okay{Option<String>{NullOpt}}; + } + + auto result{String::makeFromCString(resultString, allocator)}; + if (result.isError()) { + return Error{result.takeError()}; } - return String::makeFromCString(resultString, allocator); + return Okay{Option<String>::take(result.takeOkay())}; } } // namespace fud diff --git a/test/test_csv.cpp b/test/test_csv.cpp index 65c02ef..83bfe0a 100644 --- a/test/test_csv.cpp +++ b/test/test_csv.cpp @@ -201,7 +201,7 @@ TEST(FudCsv, ParseNuclides) pushExpected(StringView{u8"ENSDFauthors"}); pushExpected(StringView{u8"Extraction_date"}); - StringView nuclidesFilename{u8"test/nuclides.csv"}; + StringView nuclidesFilename{u8"nuclides.csv"}; Csv csv{Csv::makeDefault()}; auto parseStatus = Csv::parseFromFilenameUnbuffered(csv, nuclidesFilename); if (parseStatus != FudStatus::Success) { diff --git a/test/test_directory.cpp b/test/test_directory.cpp index 0f7dc8d..7a420ca 100644 --- a/test/test_directory.cpp +++ b/test/test_directory.cpp @@ -20,13 +20,14 @@ #include "fud_directory.hpp" #include "fud_string.hpp" #include "test_common.hpp" +#include "fud_print.hpp" #include "gtest/gtest.h" #include <algorithm> #include <cerrno> #include <fcntl.h> #include <ftw.h> -#include <ranges> +#include <ranges> // IWYU pragma: keep - this warning is WRONG namespace fud { @@ -59,6 +60,7 @@ TEST(FudDirectory, Basic) ASSERT_TRUE(fileResult.isOkay()); CBinaryFile file{std::move(fileResult).takeOkay()}; ASSERT_EQ(file.open(), FudStatus::Success); + // NOLINTNEXTLINE(readability-magic-numbers) Array<utf8, 5> data{u8"test"}; DrainResult expected{data.size(), FudStatus::Success}; auto writeResult = file.write(data); @@ -71,6 +73,8 @@ TEST(FudDirectory, Basic) Directory directory{directoryResult.takeOkay()}; ASSERT_EQ(directory.errorCode(), 0); + debugPrint(u8"What? Filename = '{}', expected '{}' \n'", String::from(files[0]).takeOkay().asView(), files[0].asView()); + debugPrint(u8"What? Filename = '{}', expected '{}' \n'", String::from(files[1]).takeOkay().asView(), files[1].asView()); const Array<DirectoryEntry, 4> expectedFiles{ DirectoryEntry{String::makeFromCString(".").takeOkay(), 0, 0, 2, 0, DirectoryEntryType::Directory}, DirectoryEntry{String::makeFromCString("..").takeOkay(), 0, 0, 1, 0, DirectoryEntryType::Directory}, @@ -80,6 +84,7 @@ TEST(FudDirectory, Basic) ASSERT_TRUE(expectedFiles[0].name.compare(expectedFiles[0].name)); for (auto idx = 0; idx < expectedFiles.size(); ++idx) { + debugPrint(u8"On iteration {} - '{}' \n", idx, expectedFiles[idx].name.asView()); auto dirEntryResult = directory.getNextEntry(); EXPECT_TRUE(dirEntryResult.isOkay()); auto dirEntryOpt = dirEntryResult.takeOkay(); @@ -87,9 +92,8 @@ TEST(FudDirectory, Basic) break; } auto dirEntry{std::move(dirEntryOpt.value())}; - const auto* expected = std::find_if( - expectedFiles.begin(), - expectedFiles.end(), + const auto* expected = std::ranges::find_if( + expectedFiles, [&dirEntry](const DirectoryEntry& entry) { return entry.name.compare(dirEntry.name) && entry.entryType == dirEntry.entryType; }); diff --git a/test/test_fud.cpp b/test/test_fud.cpp index f84ad20..8dea206 100644 --- a/test/test_fud.cpp +++ b/test/test_fud.cpp @@ -33,6 +33,7 @@ TEST(FudTest, FudFud) auto compareResult = compareMem( fudInfo.revision.data(), fudInfo.revision.size(), + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay) FudGitHash, fudInfo.revision.size() - 1); ASSERT_TRUE(compareResult.isOkay()); @@ -52,14 +53,18 @@ TEST(FudTest, GetEnv) ASSERT_EQ(fudVarResult.getError(), FudStatus::NullPointer); fudVarResult = std::move(getEnv(testVarName)); - ASSERT_TRUE(fudVarResult.isError()); - ASSERT_EQ(fudVarResult.getError(), FudStatus::NotFound); + ASSERT_TRUE(fudVarResult.isOkay()); + ASSERT_TRUE(fudVarResult.getOkay().isNone()); ASSERT_EQ(setenv(testVarName, testVarValue, 1), 0); + ASSERT_NE(getenv(testVarName), nullptr); + ASSERT_STREQ(getenv(testVarName), testVarValue); + fudVarResult = getEnv(testVarName); ASSERT_TRUE(fudVarResult.isOkay()); auto fudVar{fudVarResult.takeOkay()}; - ASSERT_STREQ(fudVar.c_str(), testVarValue); + ASSERT_TRUE(fudVar.hasValue()); + ASSERT_STREQ(fudVar.value().c_str(), testVarValue); } } // namespace fud diff --git a/test/test_string.cpp b/test/test_string.cpp index ba2df6c..39a24cb 100644 --- a/test/test_string.cpp +++ b/test/test_string.cpp @@ -39,6 +39,7 @@ TEST(FudString, BasicStringOps) ASSERT_FALSE(Ascii::valid(invalid[0])); const Array<utf8, 2> invalid2{0xFF, 0x00}; + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) auto stringResult = String::makeFromCString(reinterpret_cast<const char*>(invalid2.data())); ASSERT_TRUE(stringResult.isOkay()); @@ -77,7 +78,9 @@ TEST(FudString, ViewFromCString) TEST(FudString, HeapAlloc) { + // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays) constexpr const char filenameLiteral[] = "Amazing Saga Volume 01/000.jpg"; + // NOLINTNEXTLINE auto filenameResult{String::makeFromCString(filenameLiteral)}; ASSERT_TRUE(filenameResult.isOkay()); auto filename{filenameResult.takeOkay()}; @@ -92,6 +95,18 @@ TEST(FudString, Reserve) ASSERT_TRUE(testString.utf8Valid()); } +TEST(FudString, Equality) +{ + StringView levo{u8"a"}; + StringView dextro{u8"a"}; + ASSERT_EQ(levo, dextro); + + levo = StringView{u8"z"}; + dextro = StringView{u8"z"}; + ASSERT_EQ(levo, dextro); + ASSERT_EQ(levo.length(), 1); +} + #if 0 TEST(FudString, FindSubstringCxx) { diff --git a/tools/coverage.sh b/tools/coverage.sh index 0790d68..b5f4a17 100755 --- a/tools/coverage.sh +++ b/tools/coverage.sh @@ -6,7 +6,7 @@ cd $PROJ_ROOT HTML_DIR=build/coverage/html -ctest --test-dir build/test -j8 +ctest --test-dir build/test -j8 --output-on-failure # cd build mkdir -p ${HTML_DIR} gcovr --exclude-throw-branches --exclude build/_deps/ --exclude test -r . --html-details ${HTML_DIR}/gcovr_report.html |