diff --git a/CMakeLists.txt b/CMakeLists.txt index af73da73a5..d2623fcb54 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,6 +50,7 @@ option(SOURCEMETA_CORE_TESTS "Build the Sourcemeta Core tests" OFF) option(SOURCEMETA_CORE_TESTS_CI "Build the Sourcemeta Core CI tests" OFF) option(SOURCEMETA_CORE_BENCHMARK "Build the Sourcemeta Core benchmarks" OFF) option(SOURCEMETA_CORE_DOCS "Build the Sourcemeta Core docs" OFF) +option(SOURCEMETA_CORE_CLANG_TIDY_ANALYZER "Run the Clang static analyzer alongside ClangTidy" OFF) option(SOURCEMETA_CORE_INSTALL "Install the Sourcemeta Core library" ON) option(SOURCEMETA_CORE_ADDRESS_SANITIZER "Build Sourcemeta Core with an address sanitizer" OFF) option(SOURCEMETA_CORE_UNDEFINED_SANITIZER "Build Sourcemeta Core with an undefined behavior sanitizer" OFF) diff --git a/cmake/common/clang-tidy.cmake b/cmake/common/clang-tidy.cmake index f9d78a731e..44680928ac 100644 --- a/cmake/common/clang-tidy.cmake +++ b/cmake/common/clang-tidy.cmake @@ -111,6 +111,7 @@ function(sourcemeta_clang_tidy_attempt_enable) set(CLANG_TIDY_CONFIG "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/clang-tidy.json") execute_process(COMMAND xcrun --show-sdk-path OUTPUT_VARIABLE MACOSX_SDK_PATH OUTPUT_STRIP_TRAILING_WHITESPACE) + set(SOURCEMETA_CXX_CLANG_TIDY "${CLANG_TIDY_BIN};--config-file=${CLANG_TIDY_CONFIG};-header-filter=${PROJECT_SOURCE_DIR}/src/*" "--extra-arg=-isysroot" @@ -118,6 +119,17 @@ function(sourcemeta_clang_tidy_attempt_enable) CACHE STRING "CXX_CLANG_TIDY") endif() + # The static analyzer roughly triples ClangTidy time per translation unit, so + # it stays out of the local edit loop. This sits outside the cache guard above + # so that toggling the option takes effect on an existing build tree. The + # `--checks` argument is appended to the `Checks` option of the configuration + # file rather than replacing it, so the group composes with whatever the file + # enables + set(TARGET_CLANG_TIDY "${SOURCEMETA_CXX_CLANG_TIDY}") + if(SOURCEMETA_CORE_CLANG_TIDY_ANALYZER) + list(APPEND TARGET_CLANG_TIDY "--checks=clang-analyzer-*") + endif() + set_target_properties("${SOURCEMETA_TARGET_CLANG_TIDY_ATTEMPT_ENABLE_TARGET}" - PROPERTIES CXX_CLANG_TIDY "${SOURCEMETA_CXX_CLANG_TIDY}") + PROPERTIES CXX_CLANG_TIDY "${TARGET_CLANG_TIDY}") endfunction() diff --git a/cmake/common/clang-tidy.json b/cmake/common/clang-tidy.json index c9e314e3b3..62bb89d30e 100644 --- a/cmake/common/clang-tidy.json +++ b/cmake/common/clang-tidy.json @@ -1,7 +1,41 @@ { - "Checks": "-*, bugprone-*, -bugprone-easily-swappable-parameters,-bugprone-unchecked-optional-access, concurrency-*,cppcoreguidelines-missing-std-forward, - cppcoreguidelines-avoid-const-or-ref-data-members, modernize-*, performance-*, portability-*", + "Checks": "-*,bugprone-*,cert-*,concurrency-*,cppcoreguidelines-*,google-*,hicpp-*,misc-*,modernize-*,performance-*,portability-*,readability-*,llvm-namespace-comment,-readability-avoid-const-params-in-decls,-llvm-prefer-static-over-anonymous-namespace,-hicpp-multiway-paths-covered,-cppcoreguidelines-pro-bounds-avoid-unchecked-container-access,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-cppcoreguidelines-pro-bounds-constant-array-index,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-hicpp-no-array-decay,-cppcoreguidelines-avoid-goto,-hicpp-avoid-goto,-readability-magic-numbers,-cppcoreguidelines-avoid-magic-numbers,-cppcoreguidelines-macro-usage,-misc-no-recursion,-cppcoreguidelines-pro-type-reinterpret-cast,-cppcoreguidelines-pro-type-union-access,-cppcoreguidelines-pro-type-vararg,-hicpp-vararg,-cppcoreguidelines-owning-memory,-misc-non-private-member-variables-in-classes,-cppcoreguidelines-non-private-member-variables-in-classes,-llvm-header-guard,-readability-use-anyofallof,-readability-use-concise-preprocessor-directives,-hicpp-signed-bitwise,-bugprone-easily-swappable-parameters,-google-objc-*,-google-readability-todo,-google-readability-avoid-underscore-in-googletest-name,-misc-include-cleaner,-modernize-use-std-numbers,-bugprone-exception-escape,-bugprone-macro-parentheses,-bugprone-unchecked-optional-access,-cert-dcl59-cpp,-cert-err33-c,-concurrency-mt-unsafe,-cppcoreguidelines-avoid-c-arrays,-cppcoreguidelines-avoid-const-or-ref-data-members,-cppcoreguidelines-avoid-non-const-global-variables,-cppcoreguidelines-init-variables,-cppcoreguidelines-no-malloc,-cppcoreguidelines-prefer-member-initializer,-cppcoreguidelines-pro-type-const-cast,-cppcoreguidelines-pro-type-member-init,-cppcoreguidelines-rvalue-reference-param-not-moved,-cppcoreguidelines-special-member-functions,-google-build-namespaces,-google-build-using-namespace,-google-explicit-constructor,-google-runtime-int,-hicpp-avoid-c-arrays,-hicpp-exception-baseclass,-hicpp-explicit-conversions,-hicpp-invalid-access-moved,-hicpp-member-init,-hicpp-no-malloc,-hicpp-special-member-functions,-hicpp-uppercase-literal-suffix,-misc-anonymous-namespace-in-header,-misc-const-correctness,-misc-definitions-in-headers,-misc-misplaced-const,-misc-multiple-inheritance,-misc-redundant-expression,-misc-use-anonymous-namespace,-misc-use-internal-linkage,-modernize-use-ranges,-modernize-use-trailing-return-type,-performance-no-automatic-move,-readability-avoid-nested-conditional-operator,-readability-container-contains,-readability-convert-member-functions-to-static,-readability-function-cognitive-complexity,-readability-redundant-casting,-readability-redundant-member-init,-readability-redundant-string-init,-readability-simplify-boolean-expr,-readability-static-accessed-through-instance,-readability-suspicious-call-argument,-readability-uppercase-literal-suffix", "WarningsAsErrors": "*", "FormatStyle": "none", - "UseColor": true + "UseColor": true, + "CheckOptions": { + "bugprone-empty-catch.IgnoreCatchWithKeywords": "@TODO;@FIXME;expected", + "portability-restrict-system-includes.Includes": "*,-expected", + "readability-identifier-length.IgnoredVariableNames": "^([a-h]|[x-z]|r|s|iv|IV)$", + "readability-identifier-length.IgnoredParameterNames": "^(iv|n|x|y)$", + "readability-identifier-naming.NamespaceCase": "lower_case", + "readability-identifier-naming.ClassCase": "CamelCase", + "readability-identifier-naming.ClassIgnoredRegexp": "^const_iterator$", + "readability-identifier-naming.StructCase": "CamelCase", + "readability-identifier-naming.UnionCase": "CamelCase", + "readability-identifier-naming.EnumCase": "CamelCase", + "readability-identifier-naming.EnumConstantCase": "CamelCase", + "readability-identifier-naming.EnumConstantIgnoredRegexp": "^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$", + "readability-identifier-naming.TypeAliasCase": "CamelCase", + "readability-identifier-naming.TypeAliasIgnoredRegexp": "^[a-z][a-z0-9_]*$", + "readability-identifier-naming.TypedefCase": "CamelCase", + "readability-identifier-naming.TypeTemplateParameterCase": "CamelCase", + "readability-identifier-naming.ValueTemplateParameterCase": "CamelCase", + "readability-identifier-naming.FunctionCase": "lower_case", + "readability-identifier-naming.VariableCase": "lower_case", + "readability-identifier-naming.ParameterCase": "lower_case", + "readability-identifier-naming.PublicMemberCase": "lower_case", + "readability-identifier-naming.PrivateMemberCase": "lower_case", + "readability-identifier-naming.PrivateMemberSuffix": "_", + "readability-identifier-naming.ProtectedMemberCase": "lower_case", + "readability-identifier-naming.ProtectedMemberSuffix": "_", + "readability-identifier-naming.GlobalConstantCase": "UPPER_CASE", + "readability-identifier-naming.StaticConstantCase": "UPPER_CASE", + "readability-identifier-naming.ClassConstantCase": "UPPER_CASE", + "readability-identifier-naming.ConstexprVariableCase": "UPPER_CASE", + "readability-identifier-naming.LocalConstantCase": "lower_case", + "readability-identifier-naming.LocalVariableCase": "lower_case", + "readability-identifier-naming.MacroDefinitionCase": "UPPER_CASE", + "readability-identifier-naming.MacroDefinitionIgnoredRegexp": "^[A-Z][A-Z0-9_]*_$" + } } diff --git a/cmake/common/targets/executable.cmake b/cmake/common/targets/executable.cmake index 84814a5b68..1015cbde66 100644 --- a/cmake/common/targets/executable.cmake +++ b/cmake/common/targets/executable.cmake @@ -71,4 +71,9 @@ function(sourcemeta_executable) endif() set_target_properties("${TARGET_NAME}" PROPERTIES FOLDER "${FOLDER_NAME}") + + # We don't want consumers to be bothered with this + if(PROJECT_IS_TOP_LEVEL) + sourcemeta_clang_tidy_attempt_enable(TARGET "${TARGET_NAME}") + endif() endfunction() diff --git a/src/lang/memory/include/sourcemeta/core/memory_owned_or_reference.h b/src/lang/memory/include/sourcemeta/core/memory_owned_or_reference.h index 543afe4385..f17ab39afa 100644 --- a/src/lang/memory/include/sourcemeta/core/memory_owned_or_reference.h +++ b/src/lang/memory/include/sourcemeta/core/memory_owned_or_reference.h @@ -52,7 +52,7 @@ template class OwnedOrReference { /// Hold nothing // NOLINTNEXTLINE(google-explicit-constructor,hicpp-explicit-conversions) - OwnedOrReference(std::nullopt_t) {} + OwnedOrReference([[maybe_unused]] const std::nullopt_t value) {} /// Take ownership of a value that may or may not be there // NOLINTNEXTLINE(google-explicit-constructor,hicpp-explicit-conversions) diff --git a/src/lang/parallel/include/sourcemeta/core/parallel_for_each.h b/src/lang/parallel/include/sourcemeta/core/parallel_for_each.h index a7730c173f..3316138fe6 100644 --- a/src/lang/parallel/include/sourcemeta/core/parallel_for_each.h +++ b/src/lang/parallel/include/sourcemeta/core/parallel_for_each.h @@ -7,7 +7,7 @@ #include // std::exception_ptr, std::current_exception, std::rethrow_exception #include // std::function #include // std::input_iterator, std::iter_reference_t -#include // std::mutex, std::lock_guard +#include // std::mutex, std::scoped_lock #include // std::queue #include // std::runtime_error #include // std::thread @@ -48,7 +48,7 @@ inline auto parallel_for_each_drain_and_join(std::queue &tasks, std::vector &workers) -> void { { - std::lock_guard lock{queue_mutex}; + std::scoped_lock lock{queue_mutex}; std::queue empty; tasks.swap(empty); } @@ -84,7 +84,7 @@ inline auto parallel_for_each_drain_and_join(std::queue &tasks, /// [&mutex, &result](const auto value, /// const auto parallelism, /// const auto cursor) { -/// std::lock_guard lock{mutex}; +/// std::scoped_lock lock{mutex}; /// result.push_back(value); /// std::cerr << "Processing " << cursor /// << " with parallelism " << parallelism << "\n"; @@ -128,8 +128,8 @@ auto parallel_for_each( std::exception_ptr exception = nullptr; auto handle_exception = [&exception_mutex, - &exception](std::exception_ptr pointer) { - std::lock_guard lock{exception_mutex}; + &exception](const std::exception_ptr &pointer) { + std::scoped_lock lock{exception_mutex}; if (!exception) { exception = pointer; } @@ -150,7 +150,7 @@ auto parallel_for_each( Iterator iterator; std::size_t cursor{0}; { - std::lock_guard lock{queue_mutex}; + std::scoped_lock lock{queue_mutex}; if (tasks.empty()) { return; } diff --git a/src/lang/process/usage.cc b/src/lang/process/usage.cc index e1860930a7..f5b68952d7 100644 --- a/src/lang/process/usage.cc +++ b/src/lang/process/usage.cc @@ -267,7 +267,7 @@ auto process_start_time() noexcept const std::chrono::duration since_epoch{ static_cast(information.pbi_start_tvsec) + - static_cast(information.pbi_start_tvusec) / 1000000.0}; + (static_cast(information.pbi_start_tvusec) / 1000000.0)}; return std::chrono::system_clock::time_point{ std::chrono::duration_cast( since_epoch)}; diff --git a/src/lang/test/include/sourcemeta/core/test.h b/src/lang/test/include/sourcemeta/core/test.h index 5f4d98edc5..cf24caad06 100644 --- a/src/lang/test/include/sourcemeta/core/test.h +++ b/src/lang/test/include/sourcemeta/core/test.h @@ -99,6 +99,9 @@ auto test_compare_equal(const Left &left, const Right &right) -> bool { test_comparable_integer) { return std::cmp_equal(left, right); } else { + // Character types reach this branch, and comparing whatever the caller + // passed is the whole point of the helper + // NOLINTNEXTLINE(bugprone-signed-char-misuse) return left == right; } } @@ -249,6 +252,10 @@ auto test_expect_comparison(std::string_view file, int line, } // namespace sourcemeta::core +// The registration symbol is a namespace-scope object whose initializer runs +// the registry call, which no static initialization check can prove +// non-throwing +// NOLINTBEGIN(cert-err58-cpp,bugprone-throwing-static-initialization) #define SOURCEMETA_CORE_TEST_REGISTER(name) \ static auto sourcemeta_test_body_##name()->void; \ [[maybe_unused]] static const int sourcemeta_test_registration_##name = \ @@ -282,6 +289,7 @@ auto test_expect_comparison(std::string_view file, int line, #define TEST_F(fixture, name) \ SOURCEMETA_CORE_TEST_REGISTER_FIXTURE(fixture, name) +// NOLINTEND(cert-err58-cpp,bugprone-throwing-static-initialization) #define SOURCEMETA_CORE_TEST_COMPARE(actual, expected, comparator, operation) \ ::sourcemeta::core::test_expect_comparison( \ @@ -307,6 +315,9 @@ auto test_expect_comparison(std::string_view file, int line, SOURCEMETA_CORE_TEST_COMPARE(actual, expected, test_compare_greater_equal, \ ">=") +// The assertion macros wrap their body in a loop so that they expand into a +// single statement that still requires a trailing semicolon at the call site +// NOLINTBEGIN(cppcoreguidelines-avoid-do-while) #define SOURCEMETA_CORE_TEST_COMPARE_FLOATING(actual, expected, type) \ do { \ const type sourcemeta_test_actual{static_cast(actual)}; \ @@ -358,6 +369,8 @@ auto test_expect_comparison(std::string_view file, int line, } \ } while (false) +// NOLINTEND(cppcoreguidelines-avoid-do-while) + #define FAIL() \ ::sourcemeta::core::test_report_failure(__FILE__, __LINE__, \ "explicit failure") diff --git a/test/crypto/crypto_aes_cbc_hmac_test.cc b/test/crypto/crypto_aes_cbc_hmac_test.cc index 7d88474b76..0b08651abe 100644 --- a/test/crypto/crypto_aes_cbc_hmac_test.cc +++ b/test/crypto/crypto_aes_cbc_hmac_test.cc @@ -6,6 +6,8 @@ #include // std::string_view // A 256-bit key selects A128CBC-HS256 (16-byte tag) +// The key material is binary, so it can only come from decoding at runtime +// NOLINTBEGIN(cert-err58-cpp,bugprone-throwing-static-initialization) static const std::string KEY_256{ sourcemeta::core::hex_to_bytes( "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f") @@ -28,6 +30,7 @@ static const std::string KEY_512{ static const std::string IV{ sourcemeta::core::hex_to_bytes("101112131415161718191a1b1c1d1e1f").value()}; +// NOLINTEND(cert-err58-cpp,bugprone-throwing-static-initialization) static constexpr std::string_view ASSOCIATED_DATA{"protected-header"}; diff --git a/test/crypto/crypto_aes_gcm_test.cc b/test/crypto/crypto_aes_gcm_test.cc index 2e5aab0b33..b2965acbe9 100644 --- a/test/crypto/crypto_aes_gcm_test.cc +++ b/test/crypto/crypto_aes_gcm_test.cc @@ -5,6 +5,8 @@ #include // std::string #include // std::string_view +// The key material is binary, so it can only come from decoding at runtime +// NOLINTBEGIN(cert-err58-cpp,bugprone-throwing-static-initialization) static const std::string KEY{ sourcemeta::core::hex_to_bytes( "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f") @@ -20,6 +22,7 @@ static const std::string KEY_192{ static const std::string IV{ sourcemeta::core::hex_to_bytes("101112131415161718191a1b").value()}; +// NOLINTEND(cert-err58-cpp,bugprone-throwing-static-initialization) static constexpr std::string_view ASSOCIATED_DATA{"protected-header"}; diff --git a/test/crypto/crypto_aes_kw_test.cc b/test/crypto/crypto_aes_kw_test.cc index a9c4dc078b..068af7d43d 100644 --- a/test/crypto/crypto_aes_kw_test.cc +++ b/test/crypto/crypto_aes_kw_test.cc @@ -5,6 +5,8 @@ #include // std::string #include // std::string_view +// The key material is binary, so it can only come from decoding at runtime +// NOLINTBEGIN(cert-err58-cpp,bugprone-throwing-static-initialization) static const std::string KEK_128{ sourcemeta::core::hex_to_bytes("000102030405060708090a0b0c0d0e0f").value()}; @@ -26,6 +28,7 @@ static const std::string OTHER_KEK_128{ // The key being wrapped, a 128-bit content encryption key static const std::string KEY{ sourcemeta::core::hex_to_bytes("00112233445566778899aabbccddeeff").value()}; +// NOLINTEND(cert-err58-cpp,bugprone-throwing-static-initialization) TEST(aes_key_wrap_round_trips_with_a_128_bit_kek) { const auto wrapped{sourcemeta::core::aes_key_wrap(KEK_128, KEY)}; diff --git a/test/crypto/crypto_components_test.cc b/test/crypto/crypto_components_test.cc index 6770a739e3..92a4812ebc 100644 --- a/test/crypto/crypto_components_test.cc +++ b/test/crypto/crypto_components_test.cc @@ -2,10 +2,11 @@ #include #include -#include // std::string +#include // std::string +#include // std::string_view // RFC 7638 Section 3.1: the RSA public key whose thumbprint the RFC publishes -static const std::string RFC7638_RSA_N{ +static constexpr std::string_view RFC7638_RSA_N{ "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK" "7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yB" "XArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb" @@ -13,30 +14,30 @@ static const std::string RFC7638_RSA_N{ "M4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw"}; // RFC 6979 Appendix A.2.5: the NIST P-256 example key and its public point -static const std::string P256_D_HEX{ +static constexpr std::string_view P256_D_HEX{ "c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721"}; -static const std::string P256_QX_HEX{ +static constexpr std::string_view P256_QX_HEX{ "60fed4ba255a9d31c961eb74c6356d68c049b8923b61fa6ce669622e60f29fb6"}; -static const std::string P256_QY_HEX{ +static constexpr std::string_view P256_QY_HEX{ "7903fe1008b8bc99a41ae9e95628bc64f2f1b20c2d7e9f5177a3c294d4462299"}; // A NIST P-384 public point, so the wider field width is exercised too -static const std::string P384_QX_HEX{ +static constexpr std::string_view P384_QX_HEX{ "f3fe7867cd5320449ad98b477d19946ed3488a56c89662fce74ff51afaac5ab6" "0854755c5af8367f916b67accaa444d1"}; -static const std::string P384_QY_HEX{ +static constexpr std::string_view P384_QY_HEX{ "0de9485115027c8dea96c921cda5b071e24c1985ad658284fcac8e4d5abe8362" "10824b5b4142f383d8e7cc62b7842028"}; // The Ed25519 and Ed448 seeds and public keys from the signing test vectors -static const std::string ED25519_SEED_HEX{ +static constexpr std::string_view ED25519_SEED_HEX{ "741ec35ce5e07089ca782f88de00d8103a1cd8e8b116acd8afd922c01bee7867"}; -static const std::string ED25519_PUBLIC_HEX{ +static constexpr std::string_view ED25519_PUBLIC_HEX{ "48539e4fb623b0d221f8cd7e9c20469c1f55598bb5bb236a8a2cc2661c1d743a"}; -static const std::string ED448_SEED_HEX{ +static constexpr std::string_view ED448_SEED_HEX{ "7027028140c9eb422935e1d309e01e66670389173da4f66c4016c2492513b4c1" "989263ea13250e65a784aa8c01a9960a7416c2e2879b2a2295"}; -static const std::string ED448_PUBLIC_HEX{ +static constexpr std::string_view ED448_PUBLIC_HEX{ "04a74611a3714c06363868b8801b3c81d1b373ac7621eef20cf2793518450e60" "7e455b12f21c98fc5ad5098e15604e4e5236a8a455e1280f00"}; diff --git a/test/crypto/crypto_ecdh_test.cc b/test/crypto/crypto_ecdh_test.cc index 4ba05db981..3d7964383d 100644 --- a/test/crypto/crypto_ecdh_test.cc +++ b/test/crypto/crypto_ecdh_test.cc @@ -8,24 +8,24 @@ namespace { // A pair of P-256 keys and their agreed secret, generated out of band -const std::string A_SCALAR{ +constexpr std::string_view A_SCALAR{ "2f2ca554ea1dabab39212f78b4238238b64b246ba7573cd76ef3f8d6705dfde0"}; -const std::string A_COORDINATE_X{ +constexpr std::string_view A_COORDINATE_X{ "7ba511d9f36a052945e3229573db7d5ed17141897e58e9f64abb5464264b7d56"}; -const std::string A_COORDINATE_Y{ +constexpr std::string_view A_COORDINATE_Y{ "d5ee7f014ea98dadab10cb47e6f7ff423a10e02540194e642354b1f56bc17c94"}; -const std::string B_SCALAR{ +constexpr std::string_view B_SCALAR{ "a80aeab3dca90d227049a8197f3198160b1f38bcfbc08955411e1c254858ca6a"}; -const std::string B_COORDINATE_X{ +constexpr std::string_view B_COORDINATE_X{ "6b307d19db9d33d779644c95aca80f23738254deeee8266bc1e4b134686f2c4b"}; -const std::string B_COORDINATE_Y{ +constexpr std::string_view B_COORDINATE_Y{ "b1aa1b614cd45a38b79f75ace6489ff60852cb6c05369034d1729f2d2ec911ac"}; -const std::string SHARED_SECRET{ +constexpr std::string_view SHARED_SECRET{ "07915976af1a99f773825059cd8ca4b1ee2c7dde4bac4d8d0b4175d9760b14e0"}; -const std::string P384_COORDINATE_X{ +constexpr std::string_view P384_COORDINATE_X{ "fbc48e6c25b8b4a04f9fe830dc558906c972118856aef6dd154c7f2d8d0beddb" "d7a91430e0ef3a583eaad396d8d27651"}; -const std::string P384_COORDINATE_Y{ +constexpr std::string_view P384_COORDINATE_Y{ "b941e926ead50d193eae772510b2baca2cf0866eb438938b4c38a2b7f124fae4" "9c698ac2524b3e4ded5d1098d0e5fac5"}; diff --git a/test/crypto/crypto_ecdsa_test.cc b/test/crypto/crypto_ecdsa_test.cc index 18f526585d..7e60c5f882 100644 --- a/test/crypto/crypto_ecdsa_test.cc +++ b/test/crypto/crypto_ecdsa_test.cc @@ -8,36 +8,36 @@ // Test keys and signatures over the message below, one per supported curve, // generated with OpenSSL using the curve's matching hash function -static const std::string MESSAGE{"sourcemeta core JWS signing input"}; +static constexpr std::string_view MESSAGE{"sourcemeta core JWS signing input"}; -static const std::string P256_QX{ +static constexpr std::string_view P256_QX{ "670f3fbe0718a819c012bbf3fe3f60cabb941546f9691e044289ed3fd2f6d58a"}; -static const std::string P256_QY{ +static constexpr std::string_view P256_QY{ "9f8fe89b6e79f099906ec1711876e95d88bf1d53ef4f19319a497b2d7a97fc91"}; -static const std::string P256_SIG{ +static constexpr std::string_view P256_SIG{ "c6982861d40a279c8fdda0f0ca904b3e46502fb9a397f68f1c172055685ebaaa" "a86f9d6252831a1ac7003c3d5dc35843596667951a57113935de42159e2c8740"}; -static const std::string P384_QX{ +static constexpr std::string_view P384_QX{ "ae8aaf3ffbf5fa91be07ade1b3b6730c62189d757436e004de067f545cfe4185" "e93388e7a719a2b90afdd110936583d8"}; -static const std::string P384_QY{ +static constexpr std::string_view P384_QY{ "530f85af20faa09c68ccc6c0d5905ba08a56db76f833dc4d0191e84c1797abdc" "08170a18efca85ddb0d3a1341f3251ed"}; -static const std::string P384_SIG{ +static constexpr std::string_view P384_SIG{ "299af5ab271c78b3c49aafb0303cf2502665752501f14ca9b645fd8580d3a7ca" "34cd4a35e213b6d19c0840140229450ed44317cd43218f12da2fcb20a294a162" "2f99bb00729180abf5677c74d38ef109bdf8db849806b8517e67c59517e2ad51"}; -static const std::string P521_QX{ +static constexpr std::string_view P521_QX{ "01a5c29e777348a0a53ae56ec0ab917caf0a8e7709b7769bc8c969950a3a4da0" "2cbd85d8d63fad67542426e1ba04775b3d9e0dec2cdaf7e76bafafa522bc4bd0" "9e65"}; -static const std::string P521_QY{ +static constexpr std::string_view P521_QY{ "0192bcdaf4cfebaa8e6e46753e31ddfb71607593a4a4307f773679ff31c6f4e6" "b362da98b3b214a5f395b647f5880e752d66038f956cdf5e0fec6e4c5618bcda" "5582"}; -static const std::string P521_SIG{ +static constexpr std::string_view P521_SIG{ "0049a787d04b2174abb7639ee4649c13b95ba11267e6a4fd93c0f96159acf7ce" "2a9deac7f1b4a54984954aecdab9976f16d63fb872f0838cba198cd6feb2c26b" "b43500073f02202696ef9c8f9670737fe829beac30eed4b6f94990ed07288545" @@ -178,12 +178,14 @@ TEST(verify_rejects_empty_coordinate) { } TEST(verify_accepts_leading_zero_padded_coordinates) { - EXPECT_TRUE( - verify_ecdsa(sourcemeta::core::EllipticCurve::P256, - sourcemeta::core::SignatureHashFunction::SHA256, - sourcemeta::core::hex_to_bytes("0000" + P256_QX).value(), - sourcemeta::core::hex_to_bytes("0000" + P256_QY).value(), - MESSAGE, sourcemeta::core::hex_to_bytes(P256_SIG).value())); + EXPECT_TRUE(verify_ecdsa( + sourcemeta::core::EllipticCurve::P256, + sourcemeta::core::SignatureHashFunction::SHA256, + sourcemeta::core::hex_to_bytes(std::string{"0000"}.append(P256_QX)) + .value(), + sourcemeta::core::hex_to_bytes(std::string{"0000"}.append(P256_QY)) + .value(), + MESSAGE, sourcemeta::core::hex_to_bytes(P256_SIG).value())); } TEST(verify_rejects_oversized_coordinate) { diff --git a/test/crypto/crypto_eddsa_test.cc b/test/crypto/crypto_eddsa_test.cc index 4627dbac0c..fdcd750986 100644 --- a/test/crypto/crypto_eddsa_test.cc +++ b/test/crypto/crypto_eddsa_test.cc @@ -11,34 +11,34 @@ // Public keys, messages, and signatures from the Ed25519 test vectors of RFC // 8032 Section 7.1, the authoritative source -static const std::string TEST1_PUBLIC_KEY{ +static constexpr std::string_view TEST1_PUBLIC_KEY{ "d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a"}; -static const std::string TEST1_MESSAGE{""}; -static const std::string TEST1_SIGNATURE{ +static constexpr std::string_view TEST1_MESSAGE{""}; +static constexpr std::string_view TEST1_SIGNATURE{ "e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555f" "b8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b"}; -static const std::string TEST2_PUBLIC_KEY{ +static constexpr std::string_view TEST2_PUBLIC_KEY{ "3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c"}; -static const std::string TEST2_MESSAGE{"72"}; -static const std::string TEST2_SIGNATURE{ +static constexpr std::string_view TEST2_MESSAGE{"72"}; +static constexpr std::string_view TEST2_SIGNATURE{ "92a009a9f0d4cab8720e820b5f642540a2b27b5416503f8fb3762223ebdb69da08" "5ac1e43e15996e458f3613d0f11d8c387b2eaeb4302aeeb00d291612bb0c00"}; -static const std::string TEST3_PUBLIC_KEY{ +static constexpr std::string_view TEST3_PUBLIC_KEY{ "fc51cd8e6218a1a38da47ed00230f0580816ed13ba3303ac5deb911548908025"}; -static const std::string TEST3_MESSAGE{"af82"}; -static const std::string TEST3_SIGNATURE{ +static constexpr std::string_view TEST3_MESSAGE{"af82"}; +static constexpr std::string_view TEST3_SIGNATURE{ "6291d657deec24024827e69c3abe01a30ce548a284743a445e3680d7db5ac3ac18" "ff9b538d16f290ae67f760984dc6594a7c15e9716ed28dc027beceea1ec40a"}; // The message of this vector is itself the SHA-512 digest of "abc" -static const std::string TEST_ABC_PUBLIC_KEY{ +static constexpr std::string_view TEST_ABC_PUBLIC_KEY{ "ec172b93ad5e563bf4932c70e1245034c35467ef2efd4d64ebf819683467e2bf"}; -static const std::string TEST_ABC_MESSAGE{ +static constexpr std::string_view TEST_ABC_MESSAGE{ "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a21" "92992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f"}; -static const std::string TEST_ABC_SIGNATURE{ +static constexpr std::string_view TEST_ABC_SIGNATURE{ "dc2a4459e7369633a52b1bf277839a00201009a3efbf3ecb69bea2186c26b58909" "351fc9ac90b3ecfdfbc7c66431e0303dca179c138ac17ad9bef1177331a704"}; @@ -176,17 +176,17 @@ TEST(verify_rejects_empty_public_key) { // cases that JWS uses // clang-format off -static const std::string ED448_BLANK_PUBLIC_KEY{"5fd7449b59b461fd2ce787ec616ad46a1da1342485a70e1f8a0ea75d80e96778edf124769b46c7061bd6783df1e50f6cd1fa1abeafe8256180"}; -static const std::string ED448_BLANK_MESSAGE{""}; -static const std::string ED448_BLANK_SIGNATURE{"533a37f6bbe457251f023c0d88f976ae2dfb504a843e34d2074fd823d41a591f2b233f034f628281f2fd7a22ddd47d7828c59bd0a21bfd3980ff0d2028d4b18a9df63e006c5d1c2d345b925d8dc00b4104852db99ac5c7cdda8530a113a0f4dbb61149f05a7363268c71d95808ff2e652600"}; +static constexpr std::string_view ED448_BLANK_PUBLIC_KEY{"5fd7449b59b461fd2ce787ec616ad46a1da1342485a70e1f8a0ea75d80e96778edf124769b46c7061bd6783df1e50f6cd1fa1abeafe8256180"}; +static constexpr std::string_view ED448_BLANK_MESSAGE{""}; +static constexpr std::string_view ED448_BLANK_SIGNATURE{"533a37f6bbe457251f023c0d88f976ae2dfb504a843e34d2074fd823d41a591f2b233f034f628281f2fd7a22ddd47d7828c59bd0a21bfd3980ff0d2028d4b18a9df63e006c5d1c2d345b925d8dc00b4104852db99ac5c7cdda8530a113a0f4dbb61149f05a7363268c71d95808ff2e652600"}; -static const std::string ED448_ONE_BYTE_PUBLIC_KEY{"43ba28f430cdff456ae531545f7ecd0ac834a55d9358c0372bfa0c6c6798c0866aea01eb00742802b8438ea4cb82169c235160627b4c3a9480"}; -static const std::string ED448_ONE_BYTE_MESSAGE{"03"}; -static const std::string ED448_ONE_BYTE_SIGNATURE{"26b8f91727bd62897af15e41eb43c377efb9c610d48f2335cb0bd0087810f4352541b143c4b981b7e18f62de8ccdf633fc1bf037ab7cd779805e0dbcc0aae1cbcee1afb2e027df36bc04dcecbf154336c19f0af7e0a6472905e799f1953d2a0ff3348ab21aa4adafd1d234441cf807c03a00"}; +static constexpr std::string_view ED448_ONE_BYTE_PUBLIC_KEY{"43ba28f430cdff456ae531545f7ecd0ac834a55d9358c0372bfa0c6c6798c0866aea01eb00742802b8438ea4cb82169c235160627b4c3a9480"}; +static constexpr std::string_view ED448_ONE_BYTE_MESSAGE{"03"}; +static constexpr std::string_view ED448_ONE_BYTE_SIGNATURE{"26b8f91727bd62897af15e41eb43c377efb9c610d48f2335cb0bd0087810f4352541b143c4b981b7e18f62de8ccdf633fc1bf037ab7cd779805e0dbcc0aae1cbcee1afb2e027df36bc04dcecbf154336c19f0af7e0a6472905e799f1953d2a0ff3348ab21aa4adafd1d234441cf807c03a00"}; -static const std::string ED448_ELEVEN_BYTE_PUBLIC_KEY{"dcea9e78f35a1bf3499a831b10b86c90aac01cd84b67a0109b55a36e9328b1e365fce161d71ce7131a543ea4cb5f7e9f1d8b00696447001400"}; -static const std::string ED448_ELEVEN_BYTE_MESSAGE{"0c3e544074ec63b0265e0c"}; -static const std::string ED448_ELEVEN_BYTE_SIGNATURE{"1f0a8888ce25e8d458a21130879b840a9089d999aaba039eaf3e3afa090a09d389dba82c4ff2ae8ac5cdfb7c55e94d5d961a29fe0109941e00b8dbdeea6d3b051068df7254c0cdc129cbe62db2dc957dbb47b51fd3f213fb8698f064774250a5028961c9bf8ffd973fe5d5c206492b140e00"}; +static constexpr std::string_view ED448_ELEVEN_BYTE_PUBLIC_KEY{"dcea9e78f35a1bf3499a831b10b86c90aac01cd84b67a0109b55a36e9328b1e365fce161d71ce7131a543ea4cb5f7e9f1d8b00696447001400"}; +static constexpr std::string_view ED448_ELEVEN_BYTE_MESSAGE{"0c3e544074ec63b0265e0c"}; +static constexpr std::string_view ED448_ELEVEN_BYTE_SIGNATURE{"1f0a8888ce25e8d458a21130879b840a9089d999aaba039eaf3e3afa090a09d389dba82c4ff2ae8ac5cdfb7c55e94d5d961a29fe0109941e00b8dbdeea6d3b051068df7254c0cdc129cbe62db2dc957dbb47b51fd3f213fb8698f064774250a5028961c9bf8ffd973fe5d5c206492b140e00"}; // clang-format on TEST(verify_ed448_empty_message) { diff --git a/test/crypto/crypto_hkdf_test.cc b/test/crypto/crypto_hkdf_test.cc index e22f7be6c6..3eb11ad514 100644 --- a/test/crypto/crypto_hkdf_test.cc +++ b/test/crypto/crypto_hkdf_test.cc @@ -14,6 +14,11 @@ auto bytes(const std::string_view hexadecimal) -> std::string { return sourcemeta::core::hex_to_bytes(hexadecimal).value(); } +// RFC 5869 §2.3: the expand step emits at most 255 blocks of the hash length +constexpr std::size_t MAXIMUM_SHA256_OUTPUT{std::size_t{255} * 32}; +constexpr std::size_t MAXIMUM_SHA384_OUTPUT{std::size_t{255} * 48}; +constexpr std::size_t MAXIMUM_SHA512_OUTPUT{std::size_t{255} * 64}; + template auto to_hex(const std::array &digest) -> std::string { return sourcemeta::core::bytes_to_hex( @@ -138,22 +143,22 @@ TEST(hkdf_sha256_absent_salt_equals_a_zero_filled_one) { // RFC 5869 §2.3: L is at most 255*HashLen octets TEST(hkdf_sha256_maximum_output_length) { - const auto okm{ - sourcemeta::core::hkdf_sha256(bytes(CASE_1_IKM), "", "", 255 * 32)}; + const auto okm{sourcemeta::core::hkdf_sha256(bytes(CASE_1_IKM), "", "", + MAXIMUM_SHA256_OUTPUT)}; EXPECT_TRUE(okm.has_value()); - EXPECT_EQ(okm.value().size(), static_cast(255 * 32)); + EXPECT_EQ(okm.value().size(), MAXIMUM_SHA256_OUTPUT); } TEST(hkdf_sha256_output_length_past_the_maximum) { - EXPECT_FALSE( - sourcemeta::core::hkdf_sha256(bytes(CASE_1_IKM), "", "", 255 * 32 + 1) - .has_value()); + EXPECT_FALSE(sourcemeta::core::hkdf_sha256(bytes(CASE_1_IKM), "", "", + MAXIMUM_SHA256_OUTPUT + 1) + .has_value()); } TEST(hkdf_sha256_expand_output_length_past_the_maximum) { - EXPECT_FALSE( - sourcemeta::core::hkdf_sha256_expand(bytes(CASE_1_PRK), "", 255 * 32 + 1) - .has_value()); + EXPECT_FALSE(sourcemeta::core::hkdf_sha256_expand(bytes(CASE_1_PRK), "", + MAXIMUM_SHA256_OUTPUT + 1) + .has_value()); } // RFC 5869 §2.3: the pseudorandom key is at least HashLen octets @@ -186,16 +191,16 @@ TEST(hkdf_sha384_extract_produces_a_digest_sized_key) { } TEST(hkdf_sha384_maximum_output_length) { - const auto okm{ - sourcemeta::core::hkdf_sha384(bytes(CASE_1_IKM), "", "", 255 * 48)}; + const auto okm{sourcemeta::core::hkdf_sha384(bytes(CASE_1_IKM), "", "", + MAXIMUM_SHA384_OUTPUT)}; EXPECT_TRUE(okm.has_value()); - EXPECT_EQ(okm.value().size(), static_cast(255 * 48)); + EXPECT_EQ(okm.value().size(), MAXIMUM_SHA384_OUTPUT); } TEST(hkdf_sha384_output_length_past_the_maximum) { - EXPECT_FALSE( - sourcemeta::core::hkdf_sha384(bytes(CASE_1_IKM), "", "", 255 * 48 + 1) - .has_value()); + EXPECT_FALSE(sourcemeta::core::hkdf_sha384(bytes(CASE_1_IKM), "", "", + MAXIMUM_SHA384_OUTPUT + 1) + .has_value()); } TEST(hkdf_sha512_extract_produces_a_digest_sized_key) { @@ -205,16 +210,16 @@ TEST(hkdf_sha512_extract_produces_a_digest_sized_key) { } TEST(hkdf_sha512_maximum_output_length) { - const auto okm{ - sourcemeta::core::hkdf_sha512(bytes(CASE_1_IKM), "", "", 255 * 64)}; + const auto okm{sourcemeta::core::hkdf_sha512(bytes(CASE_1_IKM), "", "", + MAXIMUM_SHA512_OUTPUT)}; EXPECT_TRUE(okm.has_value()); - EXPECT_EQ(okm.value().size(), static_cast(255 * 64)); + EXPECT_EQ(okm.value().size(), MAXIMUM_SHA512_OUTPUT); } TEST(hkdf_sha512_output_length_past_the_maximum) { - EXPECT_FALSE( - sourcemeta::core::hkdf_sha512(bytes(CASE_1_IKM), "", "", 255 * 64 + 1) - .has_value()); + EXPECT_FALSE(sourcemeta::core::hkdf_sha512(bytes(CASE_1_IKM), "", "", + MAXIMUM_SHA512_OUTPUT + 1) + .has_value()); } // Each width is a distinct derivation from the same inputs diff --git a/test/crypto/crypto_rsa_oaep_test.cc b/test/crypto/crypto_rsa_oaep_test.cc index 2cc4cbc432..8791b8a995 100644 --- a/test/crypto/crypto_rsa_oaep_test.cc +++ b/test/crypto/crypto_rsa_oaep_test.cc @@ -7,7 +7,7 @@ // A 2048-bit RSA test key in unencrypted PKCS#8, from which the public key is // derived for the encryption side of each round trip -static const std::string PRIVATE_KEY_PEM{ +static constexpr std::string_view PRIVATE_KEY_PEM{ R"(-----BEGIN PRIVATE KEY----- MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCwidOHq7tHMyQk rKtggHsdpTNL7fv+Rjlve5AgNGbTDMJCWga7LbOxS1B/iaOVyn7pNX4+XVXgRGYG @@ -40,7 +40,7 @@ VoqHMouZBlcLfRprpPpQWlay // A 2048-bit key whose PKCS#8 algorithm is id-RSASSA-PSS rather than // rsaEncryption, so it is restricted to PSS and must refuse OAEP decryption -static const std::string PSS_RESTRICTED_PRIVATE_KEY_PEM{ +static constexpr std::string_view PSS_RESTRICTED_PRIVATE_KEY_PEM{ R"(-----BEGIN PRIVATE KEY----- MIIEugIBADALBgkqhkiG9w0BAQoEggSmMIIEogIBAAKCAQEAmLPlf54G5cTEBgZs sMSaCFtdTcy0Yjv6HAHK0BLYqdsnff6WMGmuSDdNZ/Oh++a3hTGV6ZdpvNFEo1MD diff --git a/test/crypto/crypto_rsassa_pkcs1_v15_test.cc b/test/crypto/crypto_rsassa_pkcs1_v15_test.cc index 093d94e4b0..5956c26108 100644 --- a/test/crypto/crypto_rsassa_pkcs1_v15_test.cc +++ b/test/crypto/crypto_rsassa_pkcs1_v15_test.cc @@ -8,9 +8,9 @@ // A 2048-bit test key with the usual public exponent, along with // signatures over the message below, one per supported hash function -static const std::string MESSAGE{"sourcemeta core JWS signing input"}; +static constexpr std::string_view MESSAGE{"sourcemeta core JWS signing input"}; -static const std::string MODULUS_HEX{ +static constexpr std::string_view MODULUS_HEX{ "c18bb08bad1c930bb6eed38f60299c28f28e0dabf53557fa8ac9a63044413a3c" "74671a8b316ec972b25faa13826b10e0d78f90da1b697805202faf58c5768361" "ad0006364e5f5bbf6e95a222f894be4cdccfe52aca34b48a1f92a1192214f78e" @@ -20,9 +20,9 @@ static const std::string MODULUS_HEX{ "4fa1506e0d5d5d9c7f531112485219c783228ae9b81ff65725513d559131ee06" "c5299d6531d0b9abe13ee19924f1fa47f25136fc948daf0cac721a277255af3d"}; -static const std::string EXPONENT_HEX{"010001"}; +static constexpr std::string_view EXPONENT_HEX{"010001"}; -static const std::string SIGNATURE_SHA256_HEX{ +static constexpr std::string_view SIGNATURE_SHA256_HEX{ "b03580590d438d7a0cec9dbaf9046414c8474ec5bfa0809ce456036110730d72" "1ce914ccda9da01d80d4f21490a1e9263391f434ede0c901d4bfcf983b8ad1c1" "cc97d879a0315b0b69ee13c5a2fd2ddfce4d407d65351a902f90630eb398a2d6" @@ -32,7 +32,7 @@ static const std::string SIGNATURE_SHA256_HEX{ "7080b42118a2380d03d58f488a4241f1624cbda93d9f50b95fbd0f2ff7e35b54" "f0c410dd41988958e0400e20442efdd2f8a7c963b9e874f50bf489b553269ba4"}; -static const std::string SIGNATURE_SHA384_HEX{ +static constexpr std::string_view SIGNATURE_SHA384_HEX{ "6ef5d288aaead69bf4743721be8ade1b3d1e49070655159cba6d0c856a9c189f" "70d0862d18904b8ed991a8e6c29fc93493b59123da80ef8d20434c08fea261d6" "fa403cee6f322fc1d0dd23398f11df9e39456f08a2576b7b5b7051927769593f" @@ -42,7 +42,7 @@ static const std::string SIGNATURE_SHA384_HEX{ "c847a79311730949ae988a0665f009f17f6cd417f4885cdf7739a8f5f8d481ea" "5185cab358b6bd0605fcb868ec912e11f20e679d01310379ae0fbd71c16d94bf"}; -static const std::string SIGNATURE_SHA512_HEX{ +static constexpr std::string_view SIGNATURE_SHA512_HEX{ "2b4e81f5f54a1e152b2369679c124869d0c9b8548bd561ad0f8db31c037126d3" "b122cca0202891ec827a14ecbbe3fa76dfb2aec9884eb45a54888f9f39614b73" "ca55cd270fa538a81a1c841757f390c8d04973e8eea09d35b6b95172c3a10545" @@ -92,7 +92,9 @@ TEST(verify_exponent_with_leading_zeros) { EXPECT_TRUE(verify_pkcs1( sourcemeta::core::SignatureHashFunction::SHA256, sourcemeta::core::hex_to_bytes(MODULUS_HEX).value(), - sourcemeta::core::hex_to_bytes("00000000" + EXPONENT_HEX).value(), + sourcemeta::core::hex_to_bytes( + std::string{"00000000"}.append(EXPONENT_HEX)) + .value(), MESSAGE, sourcemeta::core::hex_to_bytes(SIGNATURE_SHA256_HEX).value())); } @@ -191,7 +193,8 @@ TEST(verify_rejects_empty_message) { TEST(verify_modulus_with_leading_zeros) { EXPECT_TRUE(verify_pkcs1( sourcemeta::core::SignatureHashFunction::SHA256, - sourcemeta::core::hex_to_bytes("0000" + MODULUS_HEX).value(), + sourcemeta::core::hex_to_bytes(std::string{"0000"}.append(MODULUS_HEX)) + .value(), sourcemeta::core::hex_to_bytes(EXPONENT_HEX).value(), MESSAGE, sourcemeta::core::hex_to_bytes(SIGNATURE_SHA256_HEX).value())); } @@ -222,7 +225,9 @@ TEST(verify_rejects_a_zero_padded_signature) { sourcemeta::core::SignatureHashFunction::SHA256, sourcemeta::core::hex_to_bytes(MODULUS_HEX).value(), sourcemeta::core::hex_to_bytes(EXPONENT_HEX).value(), MESSAGE, - sourcemeta::core::hex_to_bytes("00" + SIGNATURE_SHA256_HEX).value())); + sourcemeta::core::hex_to_bytes( + std::string{"00"}.append(SIGNATURE_SHA256_HEX)) + .value())); } TEST(verify_rejects_a_truncated_signature) { diff --git a/test/crypto/crypto_rsassa_pss_test.cc b/test/crypto/crypto_rsassa_pss_test.cc index de3125f241..c876788169 100644 --- a/test/crypto/crypto_rsassa_pss_test.cc +++ b/test/crypto/crypto_rsassa_pss_test.cc @@ -9,9 +9,9 @@ // The same 2048-bit test key as the RSASSA-PKCS1-v1_5 tests, along with // RSASSA-PSS signatures over the message below using a salt as long as the // hash function output, one per supported hash function -static const std::string MESSAGE{"sourcemeta core JWS signing input"}; +static constexpr std::string_view MESSAGE{"sourcemeta core JWS signing input"}; -static const std::string MODULUS_HEX{ +static constexpr std::string_view MODULUS_HEX{ "c18bb08bad1c930bb6eed38f60299c28f28e0dabf53557fa8ac9a63044413a3c" "74671a8b316ec972b25faa13826b10e0d78f90da1b697805202faf58c5768361" "ad0006364e5f5bbf6e95a222f894be4cdccfe52aca34b48a1f92a1192214f78e" @@ -21,9 +21,9 @@ static const std::string MODULUS_HEX{ "4fa1506e0d5d5d9c7f531112485219c783228ae9b81ff65725513d559131ee06" "c5299d6531d0b9abe13ee19924f1fa47f25136fc948daf0cac721a277255af3d"}; -static const std::string EXPONENT_HEX{"010001"}; +static constexpr std::string_view EXPONENT_HEX{"010001"}; -static const std::string SIGNATURE_SHA256_HEX{ +static constexpr std::string_view SIGNATURE_SHA256_HEX{ "9ce80cd6ab0f6b11df7b5cbabd2c3a274bb25065d1be44d42ea7fc6b36d77f15" "971e5741dc19ae58c4a7459d3a571407efe41c125935e43804ecbd97ce36a6e4" "4ee4d4a700e2fb40e5694178c9897dbb50cf0d9fa7de7fb8501d601edde08519" @@ -33,7 +33,7 @@ static const std::string SIGNATURE_SHA256_HEX{ "7fe292ef9df85629ef98c66df0a3a113bd0bb9156a49297da8ecd8eb374b6f09" "1d596e1d7917c654a8332c0cfe72593cdd4d8c5ec32d18849018e24ba2ea7460"}; -static const std::string SIGNATURE_SHA384_HEX{ +static constexpr std::string_view SIGNATURE_SHA384_HEX{ "8bff2ed16017c973ea443044b8c44d2618ba6c5c5b0de90a3ac62312cfa6f28b" "5b17cc113a9628d2b83c116cba723eb33677b5ad12a85708f41e26817621a1ef" "c60fa8bb11cf2279e8be2d3301e0811fbcf2a8c7b36b50521ecb6124b9d82b2b" @@ -43,7 +43,7 @@ static const std::string SIGNATURE_SHA384_HEX{ "cb7c616a28a3eb563a49d0ff8584d18265deba60ef0bed17ef447477c6f6668f" "d97a130d6988a508c9fa333a31a37d1ee3200b777850b2305c3171600f770f82"}; -static const std::string SIGNATURE_SHA512_HEX{ +static constexpr std::string_view SIGNATURE_SHA512_HEX{ "10c523c1742867b219193507ebbc5cd3d149d39400d615ef30136374b8dd454f" "a677352abd46260f4e33a27660c6d7f3576c2645e49412176fb921bcc3842d63" "d7360fc08a0797f5a6e7a05a0be67987525f308badbb415797f899316070b7a4" @@ -55,7 +55,7 @@ static const std::string SIGNATURE_SHA512_HEX{ // A signature over the same message and hash that uses a 10-byte salt // rather than one as long as the hash function output -static const std::string SIGNATURE_SHA256_SALT_10_HEX{ +static constexpr std::string_view SIGNATURE_SHA256_SALT_10_HEX{ "9a8f3208169b0c6f10f0e7246d2a3e028b746a1215daaa9b89fbb93dc3a09f47" "ae4a60c696107d93bfb1e1b6ed1e830980b972b17659f2d023c4c5a3aaa2497e" "1d7f70b431ea552ae38d95bbf5c777d40f8c35882e91a3fb3b2cf567a5f0c3ac" @@ -67,7 +67,7 @@ static const std::string SIGNATURE_SHA256_SALT_10_HEX{ // The RSASSA-PKCS1-v1_5 signature over the same message and hash, which // must never verify under RSASSA-PSS -static const std::string SIGNATURE_SHA256_PKCS1_V15_HEX{ +static constexpr std::string_view SIGNATURE_SHA256_PKCS1_V15_HEX{ "b03580590d438d7a0cec9dbaf9046414c8474ec5bfa0809ce456036110730d72" "1ce914ccda9da01d80d4f21490a1e9263391f434ede0c901d4bfcf983b8ad1c1" "cc97d879a0315b0b69ee13c5a2fd2ddfce4d407d65351a902f90630eb398a2d6" @@ -196,11 +196,12 @@ TEST(verify_rejects_empty_exponent) { } TEST(verify_modulus_with_leading_zeros) { - EXPECT_TRUE( - verify_pss(sourcemeta::core::SignatureHashFunction::SHA256, - sourcemeta::core::hex_to_bytes("0000" + MODULUS_HEX).value(), - sourcemeta::core::hex_to_bytes(EXPONENT_HEX).value(), MESSAGE, - sourcemeta::core::hex_to_bytes(SIGNATURE_SHA256_HEX).value())); + EXPECT_TRUE(verify_pss( + sourcemeta::core::SignatureHashFunction::SHA256, + sourcemeta::core::hex_to_bytes(std::string{"0000"}.append(MODULUS_HEX)) + .value(), + sourcemeta::core::hex_to_bytes(EXPONENT_HEX).value(), MESSAGE, + sourcemeta::core::hex_to_bytes(SIGNATURE_SHA256_HEX).value())); } TEST(verify_rejects_oversized_modulus) { @@ -224,11 +225,13 @@ TEST(verify_rejects_a_zero_padded_signature) { // RFC 8017 Section 8.1.2 step 1, the same length rule the PKCS1-v1_5 // verification follows, so a leading zero octet cannot give a signature a // second encoding - EXPECT_FALSE(verify_pss( - sourcemeta::core::SignatureHashFunction::SHA256, - sourcemeta::core::hex_to_bytes(MODULUS_HEX).value(), - sourcemeta::core::hex_to_bytes(EXPONENT_HEX).value(), MESSAGE, - sourcemeta::core::hex_to_bytes("00" + SIGNATURE_SHA256_HEX).value())); + EXPECT_FALSE(verify_pss(sourcemeta::core::SignatureHashFunction::SHA256, + sourcemeta::core::hex_to_bytes(MODULUS_HEX).value(), + sourcemeta::core::hex_to_bytes(EXPONENT_HEX).value(), + MESSAGE, + sourcemeta::core::hex_to_bytes( + std::string{"00"}.append(SIGNATURE_SHA256_HEX)) + .value())); } TEST(verify_rejects_a_truncated_signature) { diff --git a/test/crypto/crypto_secure_test.cc b/test/crypto/crypto_secure_test.cc index 71dc43fbb3..a0aec78ea9 100644 --- a/test/crypto/crypto_secure_test.cc +++ b/test/crypto/crypto_secure_test.cc @@ -1,10 +1,11 @@ #include #include -#include // std::uint64_t -#include // std::numeric_limits -#include // std::bad_array_new_length -#include // std::string +#include // std::uint64_t +#include // std::numeric_limits +#include // std::bad_array_new_length +#include // std::string +#include // std::string_view TEST(secure_zero_clears_a_string) { std::string secret{"password"}; @@ -138,8 +139,8 @@ TEST(secure_zero_of_a_null_buffer_is_a_no_op) { } TEST(secure_string_from_a_pointer_and_a_length) { - const char content[]{"hunter2"}; - const sourcemeta::core::SecureString secret{content, 7}; + const std::string_view content{"hunter2"}; + const sourcemeta::core::SecureString secret{content.data(), content.size()}; EXPECT_EQ(secret.size(), 7); EXPECT_EQ(secret, "hunter2"); EXPECT_EQ(secret[0], 'h'); @@ -176,5 +177,6 @@ TEST(secure_allocator_rejects_an_overflowing_allocation) { allocator.allocate(std::numeric_limits::max())}; FAIL(); } catch (const std::bad_array_new_length &) { + // Refusing the allocation is expected } } diff --git a/test/crypto/crypto_sign_test.cc b/test/crypto/crypto_sign_test.cc index aa15a8e262..99e3a6c9d7 100644 --- a/test/crypto/crypto_sign_test.cc +++ b/test/crypto/crypto_sign_test.cc @@ -8,11 +8,11 @@ // The message signed throughout, along with keys and known-answer signatures // generated with OpenSSL over that message using each scheme -static const std::string MESSAGE{"sourcemeta core JWS signing input"}; +static constexpr std::string_view MESSAGE{"sourcemeta core JWS signing input"}; // A 2048-bit RSA private key in unencrypted PKCS#8, with the deterministic // RSASSA-PKCS1-v1_5 signatures it produces, one per supported hash function -static const std::string RSA_PRIVATE_KEY{ +static constexpr std::string_view RSA_PRIVATE_KEY{ R"(-----BEGIN PRIVATE KEY----- MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCf6K9Ys3QJNItd zsY1wcY65kd27pBwZPdKUVNp/ZyTEtUQNwBTh8h7Pusq29loLOkonpxvkpmcNwif @@ -45,7 +45,7 @@ LotnyAB/PnO2eU6aOt6q6EcZ // A 2048-bit key whose PKCS#8 algorithm is id-RSASSA-PSS rather than // rsaEncryption, so it is restricted to PSS and must refuse PKCS1v15 signing -static const std::string PSS_RESTRICTED_PRIVATE_KEY{ +static constexpr std::string_view PSS_RESTRICTED_PRIVATE_KEY{ R"(-----BEGIN PRIVATE KEY----- MIIEugIBADALBgkqhkiG9w0BAQoEggSmMIIEogIBAAKCAQEAmLPlf54G5cTEBgZs sMSaCFtdTcy0Yjv6HAHK0BLYqdsnff6WMGmuSDdNZ/Oh++a3hTGV6ZdpvNFEo1MD @@ -79,8 +79,8 @@ zz/p2wIRJlfNHxRap+Q= // leading octet is zero, which holds for roughly one signature in 256. Signing // cannot be asked for that property, so a known pair is pinned to keep the // truncation case deterministic rather than a rare coincidence -static const std::string LEADING_ZERO_MESSAGE{"probe-962"}; -static const std::string LEADING_ZERO_SIGNATURE_HEX{ +static constexpr std::string_view LEADING_ZERO_MESSAGE{"probe-962"}; +static constexpr std::string_view LEADING_ZERO_SIGNATURE_HEX{ "006dd09d02b89420a6485f64197ae248fceb2bfdc83ea36a544c92317c04b64c" "304f5d204a8c85f79d78b6a234d1b8e47b1b79331d835862f8096fa2524f0c9a" "728d6b0872d04198fed0c2d9790281a018482ff072f7ad4113b5a05fb3d034b6" @@ -94,7 +94,7 @@ static const std::string LEADING_ZERO_SIGNATURE_HEX{ // 65536, which RFC 8017 Section 3.1 excludes because an even exponent is // not invertible modulo the totient. Every octet length is unchanged, so // only the value is unacceptable -static const std::string EVEN_EXPONENT_KEY{ +static constexpr std::string_view EVEN_EXPONENT_KEY{ R"(-----BEGIN PRIVATE KEY----- MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCf6K9Ys3QJNItd zsY1wcY65kd27pBwZPdKUVNp/ZyTEtUQNwBTh8h7Pusq29loLOkonpxvkpmcNwif @@ -128,7 +128,7 @@ LotnyAB/PnO2eU6aOt6q6EcZ // The same key with its public exponent given a leading zero octet where // the next octet is already below 0x80, which X.690 Section 8.3 makes a // non-canonical encoding -static const std::string NONCANONICAL_EXPONENT_KEY{ +static constexpr std::string_view NONCANONICAL_EXPONENT_KEY{ R"(-----BEGIN PRIVATE KEY----- MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCf6K9Ys3QJNItd zsY1wcY65kd27pBwZPdKUVNp/ZyTEtUQNwBTh8h7Pusq29loLOkonpxvkpmcNwif @@ -161,7 +161,7 @@ LotnyAB/PnO2eU6aOt6q6EcZ // The same key with the modulus sign octet set, making it a negative // INTEGER that must not be reinterpreted as a large positive one -static const std::string NEGATIVE_MODULUS_KEY{ +static constexpr std::string_view NEGATIVE_MODULUS_KEY{ R"(-----BEGIN PRIVATE KEY----- MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAYCf6K9Ys3QJNItd zsY1wcY65kd27pBwZPdKUVNp/ZyTEtUQNwBTh8h7Pusq29loLOkonpxvkpmcNwif @@ -195,7 +195,7 @@ LotnyAB/PnO2eU6aOt6q6EcZ // The same key with one octet appended inside the privateKey octets, so the // RSAPrivateKey SEQUENCE no longer fills them. The enclosing lengths are // widened to match, leaving the outer structure well formed -static const std::string TRAILING_BYTES_KEY{ +static constexpr std::string_view TRAILING_BYTES_KEY{ R"(-----BEGIN PRIVATE KEY----- MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSkAgEAAoIBAQCf6K9Ys3QJNItd zsY1wcY65kd27pBwZPdKUVNp/ZyTEtUQNwBTh8h7Pusq29loLOkonpxvkpmcNwif @@ -226,7 +226,7 @@ LotnyAB/PnO2eU6aOt6q6EcZAA== -----END PRIVATE KEY----- )"}; -static const std::string MODULUS_HEX{ +static constexpr std::string_view MODULUS_HEX{ "9fe8af58b37409348b5dcec635c1c63ae64776ee907064f74a515369fd9c9312" "d51037005387c87b3eeb2adbd9682ce9289e9c6f92999c37089fe80e0ab13414" "8e8e65d0af80018daa8147e83d4000d93c9564857356d6a2d8b9c735e5b3620d" @@ -236,9 +236,9 @@ static const std::string MODULUS_HEX{ "f7438ea455b9e33c625f611f7f9f5ecf8ea3f75ff677a4a54b3161370aef6996" "0a04997ebcd7a0273c6c1d63f0ac670d477d631176ba91ea636c0b29d0538127"}; -static const std::string EXPONENT_HEX{"010001"}; +static constexpr std::string_view EXPONENT_HEX{"010001"}; -static const std::string SIGNATURE_SHA256_HEX{ +static constexpr std::string_view SIGNATURE_SHA256_HEX{ "935fb06194272d8c59729a4ebc19b1152ed553030ba2175d52d4a65f6577444a" "cac9cc65296b85ec76e243a8b71c3ecc8db9d4595b7b7a598fd07fb538854f54" "0aaaaf9d7c00697f5e8146d48ef8968daf74c369fd32f51769a8dd53dec10223" @@ -248,7 +248,7 @@ static const std::string SIGNATURE_SHA256_HEX{ "5f97c76e5e77aac1472365f92d6254d5e77ba1f73879c47b1cccf93dc7780546" "25229f7a6b39445d377f10c922399e31447ece1a40587dabd55660bc708bfde5"}; -static const std::string SIGNATURE_SHA384_HEX{ +static constexpr std::string_view SIGNATURE_SHA384_HEX{ "7b23a38a1f9e222ee227c251548ca052ae35f7d748d4394e9b1ea6037d7f10d5" "aafc677a3864111e479a4d29937e980b00fcf2a481719dff7e53748eb4be1823" "88bd590a78ca5b0cbed432e54ef1dcb5ce00964c59c7eb02bb196f09904944a6" @@ -258,7 +258,7 @@ static const std::string SIGNATURE_SHA384_HEX{ "34b27aa6572ac5dcb4aff40104457d9ec36282f8db2e29a5e78d0c5c055c979d" "52cf463962974976cce6c71179b9c95c04e2a3133d6157f911dbce83583a21d4"}; -static const std::string SIGNATURE_SHA512_HEX{ +static constexpr std::string_view SIGNATURE_SHA512_HEX{ "15e37914281fb105f833706b3c1796dd6bbb740873668812df8d68727e0d80b2" "befee774d16f97927caa63a86fcb31d2f65c9572ba49750364de26e650899361" "746496c692ac9a0e1977b9df286cce35dd3cce2ef16246771fca40362f8aae90" @@ -270,7 +270,7 @@ static const std::string SIGNATURE_SHA512_HEX{ // The private components of the RSA key above, so that the same known-answer // signatures can be reproduced from the raw integers rather than the document -static const std::string PRIVATE_EXPONENT_HEX{ +static constexpr std::string_view PRIVATE_EXPONENT_HEX{ "0dd258f051228dcbcd8d60300b0ecd5ee344a367b4c8623c6b0a0dd7082573ce" "443da5e365ff988e93e8fe72b39f5387c66109f882dd657e999a3e13e8a20474" "6516088039e080973423a9decdb1d88b990c4dfca84985e7dc2a6d539ff51a06" @@ -279,27 +279,27 @@ static const std::string PRIVATE_EXPONENT_HEX{ "a196d323abf7a85463639c6b1f7dc5bb63332898841e47bbdf721e7ed93d1b5f" "0139e602e8e358f57b2a777d9f578efa10ba5fc7fe78a97dbfe8aa2ee84d9c50" "461e17774a8fc56745b7a974d77c2d0eab84d4b118dfe24e04b4e7067fcd12a1"}; -static const std::string PRIME1_HEX{ +static constexpr std::string_view PRIME1_HEX{ "cd80890bbd2a523348971519e2efd798317c16222c128e40d3d7913507212e71" "82969fe9550f73efb99289c5acc9424eb48f584ca58a0b09e23744483d93363b" "7715e190bc85d58fe67a13c62b676cb61ec9fa190ebfa2f2e3ea1c7bb7bda5be" "5498467898f9c842c5acec570258a403641091e727f7886cde243db5d14573ef"}; -static const std::string PRIME2_HEX{ +static constexpr std::string_view PRIME2_HEX{ "c734085a976b91e4273a4dff6283bb5d8f19c91890c2ffbc92a43ca1a7b7363a" "34ea83160b455b57ca391cf8fea4231606fc007cc759ce73a13068d5d808e56b" "ecf600db5e59e6c5558b75c6ed9bc6c30320fa8c7d74f15947ed1ed9858ba3d2" "4bd64de66236d806ab4749cb0ee147af7286de55a6d7bdfe45f82f847fd7ae49"}; -static const std::string EXPONENT1_HEX{ +static constexpr std::string_view EXPONENT1_HEX{ "59259f4df65bbb98ffae7abae615818346443c1dcadca9d53990d42f1aceac25" "15af5de38cc0cd5c7b36348a0a30ac911406f3191cdecb7718293d77d12e6162" "5e80a17f7628e0c2320b5734aa738d575bf7e684a43f41e2f83800ef328014bc" "825a24880064ab193c438dab191b76daf9b7ae738684fd2bad1a2fa3060b8905"}; -static const std::string EXPONENT2_HEX{ +static constexpr std::string_view EXPONENT2_HEX{ "a34f250a1fd93061bb47316a8d7931c221ef21cde1dffb88bd2fa8055f59f43b" "03e6be50f42c881610d381cd1ff5b04dfeabda3a71b44e6cbd58d2997de2cd33" "0db12042b7b73c59cb27ea068c05898d96a312c4da9564c7ad0fd89abbc11f2c" "e8bf685dd766def398b778e7dfeb10b9e54a6c3c0bec12f6c2a6154eab004701"}; -static const std::string COEFFICIENT_HEX{ +static constexpr std::string_view COEFFICIENT_HEX{ "a8d8d74eb3ac304a8a61224db24e99d2c8c3076cae1d2e3b09b9166638a48384" "c84785a6a58558ec439f89da1ba1e9f98c628532e5c0268e29cfa201812e5e37" "abb33ef7efa8952230673a946ff30452ac73e5a7bde508cd8aaacf780dac0fe0" @@ -307,32 +307,32 @@ static const std::string COEFFICIENT_HEX{ // Elliptic curve keys, one per supported curve, as the private scalar and the // public point coordinates -static const std::string P256_D_HEX{ +static constexpr std::string_view P256_D_HEX{ "b6d7a9c5ca7e3b05c28f8fafe2c19cc51c5045703c0f94afbb4db285c1ef6ddd"}; -static const std::string P256_QX_HEX{ +static constexpr std::string_view P256_QX_HEX{ "d930111925aaf05f7b8aadcd838f30084376e9cc73cbc382cdb15afba65f9da2"}; -static const std::string P256_QY_HEX{ +static constexpr std::string_view P256_QY_HEX{ "e6593366a8563a47369b6cc93a8b65e8adffc7af934acf4e9f340ac1bdf90f14"}; -static const std::string P384_D_HEX{ +static constexpr std::string_view P384_D_HEX{ "02d5a44b4f3b542bdcfd311b0697d2cc8f593453fce78a65af26fa2d5a2f1534" "6880d0904bafd103b1e0e6a0d7e25b50"}; -static const std::string P384_QX_HEX{ +static constexpr std::string_view P384_QX_HEX{ "9c0c86e4069fbc1334034e6746ba23bce4c280d36bc147245b422f9767ed6bf9" "60c1f5e13138dbff9f72d012cedc61ff"}; -static const std::string P384_QY_HEX{ +static constexpr std::string_view P384_QY_HEX{ "86d66436fd623dfd007354ef241d0b45d1480f5295f56c4e86243411cdf671d6" "d359a4aef3e36eb0a5acea677cd15f06"}; -static const std::string P521_D_HEX{ +static constexpr std::string_view P521_D_HEX{ "011d9c388a9f757f0b665a7dfc5c877eed242ee30eeee9d4e7fa5bbfeaae19d9" "c7bfc093b7004cae81e4448eb7a0929080fff4600bd2493fd87eaf9557fed1aa" "45ff"}; -static const std::string P521_QX_HEX{ +static constexpr std::string_view P521_QX_HEX{ "01471aed01e0ebd9486a5acc37de6e1928e7aa9c4d542e63c4fae50ee9126d17" "1cd101e90f38f9d18dd29cc609489a4063e844e6b7246cb48808f910ae389e77" "216f"}; -static const std::string P521_QY_HEX{ +static constexpr std::string_view P521_QY_HEX{ "0144d992633416fec1c5e87e156f4551e26ff34f6a494f7ea9e891c8f41bc6ee" "5b08d302f139eda5656c3a139ab71f1db2879170a1a5dedc3214e3e7ce630fef" "4300"}; @@ -340,29 +340,29 @@ static const std::string P521_QY_HEX{ // RFC 6979 Appendix A.2.5: the NIST P-256 example key and the deterministic // ECDSA signature it produces over the message below with SHA-256, reproduced // only by a backend that derives the nonce deterministically -static const std::string RFC6979_MESSAGE{"sample"}; -static const std::string RFC6979_P256_D_HEX{ +static constexpr std::string_view RFC6979_MESSAGE{"sample"}; +static constexpr std::string_view RFC6979_P256_D_HEX{ "c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721"}; -static const std::string RFC6979_P256_QX_HEX{ +static constexpr std::string_view RFC6979_P256_QX_HEX{ "60fed4ba255a9d31c961eb74c6356d68c049b8923b61fa6ce669622e60f29fb6"}; -static const std::string RFC6979_P256_QY_HEX{ +static constexpr std::string_view RFC6979_P256_QY_HEX{ "7903fe1008b8bc99a41ae9e95628bc64f2f1b20c2d7e9f5177a3c294d4462299"}; -static const std::string RFC6979_P256_SIGNATURE_HEX{ +static constexpr std::string_view RFC6979_P256_SIGNATURE_HEX{ "efd48b2aacb6a8fd1140dd9cd45e81d69d2c877b56aaf991c34d0ea84eaf3716" "f7cb1c942d657c41d436c7a1b6e29f65f3e900dbb9aff4064dc4ab2f843acda8"}; // RFC 6979 Appendix A.2.6: the NIST P-384 example key and the deterministic // ECDSA signature it produces over the same message with SHA-384 -static const std::string RFC6979_P384_D_HEX{ +static constexpr std::string_view RFC6979_P384_D_HEX{ "6b9d3dad2e1b8c1c05b19875b6659f4de23c3b667bf297ba9aa47740787137d8" "96d5724e4c70a825f872c9ea60d2edf5"}; -static const std::string RFC6979_P384_QX_HEX{ +static constexpr std::string_view RFC6979_P384_QX_HEX{ "ec3a4e415b4e19a4568618029f427fa5da9a8bc4ae92e02e06aae5286b300c64" "def8f0ea9055866064a254515480bc13"}; -static const std::string RFC6979_P384_QY_HEX{ +static constexpr std::string_view RFC6979_P384_QY_HEX{ "8015d9b72d7d57244ea8ef9ac0c621896708a59367f9dfb9f54ca84b3f1c9db1" "288b231c3ae0d4fe7344fd2533264720"}; -static const std::string RFC6979_P384_SIGNATURE_HEX{ +static constexpr std::string_view RFC6979_P384_SIGNATURE_HEX{ "94edbb92a5ecb8aad4736e56c691916b3f88140666ce9fa73d64c4ea95ad133c" "81a648152e44acf96e36dd1e80fabe46" "99ef4aeb15f178cea1fe40db2603138f130e740a19624526203b6351d0a3a94f" @@ -371,30 +371,28 @@ static const std::string RFC6979_P384_SIGNATURE_HEX{ // The same keys signing a second message draw a different deterministic nonce, // so these exercise the signing scalar multiplication and inverse over another // secret value (RFC 6979 Appendix A.2.5 and A.2.6, message "test") -static const std::string RFC6979_TEST_MESSAGE{"test"}; -static const std::string RFC6979_P256_TEST_SIGNATURE_HEX{ +static constexpr std::string_view RFC6979_TEST_MESSAGE{"test"}; +static constexpr std::string_view RFC6979_P256_TEST_SIGNATURE_HEX{ "f1abb023518351cd71d881567b1ea663ed3efcf6c5132b354f28d3b0b7d38367" "019f4113742a2b14bd25926b49c649155f267e60d3814b4c0cc84250e46f0083"}; -static const std::string RFC6979_P384_TEST_SIGNATURE_HEX{ +static constexpr std::string_view RFC6979_P384_TEST_SIGNATURE_HEX{ "8203b63d3c853e8d77227fb377bcf7b7b772e97892a80f36ab775d509d7a5feb" "0542a7f0812998da8f1dd3ca3cf023db" "ddd0760448d42d8a43af45af836fce4de8be06b485e9b61b827c2f13173923e0" "6a739f040649a667bf3b828246baa5a5"}; -// Edwards keys as their raw seed and public key, with the deterministic Ed448 +// Edwards keys as their raw seed, the Ed25519 public key that verifies a +// signature the Apple backend randomizes, and the deterministic Ed448 // signature over the message (RFC 8032 uses no randomization for Ed448) -static const std::string ED25519_SEED_HEX{ +static constexpr std::string_view ED25519_SEED_HEX{ "741ec35ce5e07089ca782f88de00d8103a1cd8e8b116acd8afd922c01bee7867"}; -static const std::string ED25519_PUBLIC_HEX{ +static constexpr std::string_view ED25519_PUBLIC_HEX{ "48539e4fb623b0d221f8cd7e9c20469c1f55598bb5bb236a8a2cc2661c1d743a"}; -static const std::string ED448_SEED_HEX{ +static constexpr std::string_view ED448_SEED_HEX{ "7027028140c9eb422935e1d309e01e66670389173da4f66c4016c2492513b4c1" "989263ea13250e65a784aa8c01a9960a7416c2e2879b2a2295"}; -static const std::string ED448_PUBLIC_HEX{ - "04a74611a3714c06363868b8801b3c81d1b373ac7621eef20cf2793518450e60" - "7e455b12f21c98fc5ad5098e15604e4e5236a8a455e1280f00"}; -static const std::string ED448_SIGNATURE_HEX{ +static constexpr std::string_view ED448_SIGNATURE_HEX{ "cb5ee48e2aa415ed66c0b0485683af33f66976193425e6306eda272f9258dd0b" "d9a14223a295425d21adc4128f326f80805532ac3af546eb806c922e7cfda76a" "e959fc284b2c1fe36291845a4ce6133d7a8ca63396cd36e4568628d74c4e583f" @@ -896,7 +894,8 @@ TEST(verify_rejects_a_zero_padded_signature) { EXPECT_FALSE(sourcemeta::core::rsassa_pkcs1_v15_verify( key.value(), sourcemeta::core::SignatureHashFunction::SHA256, LEADING_ZERO_MESSAGE, - sourcemeta::core::hex_to_bytes("00" + LEADING_ZERO_SIGNATURE_HEX) + sourcemeta::core::hex_to_bytes( + std::string{"00"}.append(LEADING_ZERO_SIGNATURE_HEX)) .value())); } diff --git a/test/crypto/pyca_cryptography_test.cc b/test/crypto/pyca_cryptography_test.cc index ce1300b29b..97ee93e0d3 100644 --- a/test/crypto/pyca_cryptography_test.cc +++ b/test/crypto/pyca_cryptography_test.cc @@ -52,13 +52,16 @@ struct CurveParameters { auto to_curve(const std::string_view name) -> std::optional { if (name == "P-256") { - return CurveParameters{sourcemeta::core::EllipticCurve::P256, 32}; + return CurveParameters{.curve = sourcemeta::core::EllipticCurve::P256, + .coordinate_bytes = 32}; } if (name == "P-384") { - return CurveParameters{sourcemeta::core::EllipticCurve::P384, 48}; + return CurveParameters{.curve = sourcemeta::core::EllipticCurve::P384, + .coordinate_bytes = 48}; } if (name == "P-521") { - return CurveParameters{sourcemeta::core::EllipticCurve::P521, 66}; + return CurveParameters{.curve = sourcemeta::core::EllipticCurve::P521, + .coordinate_bytes = 66}; } return std::nullopt; } @@ -215,7 +218,7 @@ auto register_sha_msg_tests(const std::filesystem::path &file_path, } else if (field->first == "MD") { const auto expected_digest{std::string{field->second}}; const auto empty_message{current_length == "0"}; - const auto message_hex{current_message_hex}; + const auto &message_hex{current_message_hex}; register_case(suite_name, "len_" + current_length, [=]() { const auto message{ @@ -272,8 +275,9 @@ auto register_sha_monte_tests(const std::filesystem::path &file_path, for (std::uint64_t iteration{3}; iteration <= 1002; ++iteration) { std::string next; if (multi_part_digest == nullptr) { - next = sourcemeta::core::hex_to_bytes(digest(md_0 + md_1 + md_2)) - .value(); + std::string message{md_0}; + message.append(md_1).append(md_2); + next = sourcemeta::core::hex_to_bytes(digest(message)).value(); } else { const std::array parts{{md_0, md_1, md_2}}; const auto raw_digest{multi_part_digest(parts)}; @@ -332,8 +336,8 @@ auto register_hmac_tests(const std::filesystem::path &file_path, message_hex = field->second; } else if (field->first == "MD") { const auto expected_tag{std::string{field->second}}; - const auto current_key{key_hex}; - const auto current_message{message_hex}; + const auto ¤t_key{key_hex}; + const auto ¤t_message{message_hex}; case_count += 1; register_case(suite_name, "case_" + std::to_string(case_count), [=]() { const auto key{sourcemeta::core::hex_to_bytes(current_key).value()}; @@ -696,8 +700,8 @@ auto register_eddsa_448_tests(const std::filesystem::path &file_path) -> void { return; } - const auto public_key{public_key_hex}; - const auto message{message_hex}; + const auto &public_key{public_key_hex}; + const auto &message{message_hex}; const auto signature{signature_hex}; register_case("PyCA_Cryptography_Ed448_SigVer", "count_" + current_count, [=]() { @@ -786,8 +790,8 @@ auto register_eddsa_448_sign_tests(const std::filesystem::path &file_path) return; } - const auto seed{secret_hex}; - const auto message{message_hex}; + const auto &seed{secret_hex}; + const auto &message{message_hex}; const std::string expected_signature_hex{value}; register_case( "PyCA_Cryptography_Ed448_SigGen", "count_" + current_count, [=]() { diff --git a/test/crypto/wycheproof_test.cc b/test/crypto/wycheproof_test.cc index 952ea256c8..6a3486a5df 100644 --- a/test/crypto/wycheproof_test.cc +++ b/test/crypto/wycheproof_test.cc @@ -37,13 +37,16 @@ struct CurveParameters { auto to_curve(const std::string_view name) -> std::optional { if (name == "secp256r1") { - return CurveParameters{sourcemeta::core::EllipticCurve::P256, 32}; + return CurveParameters{.curve = sourcemeta::core::EllipticCurve::P256, + .coordinate_bytes = 32}; } if (name == "secp384r1") { - return CurveParameters{sourcemeta::core::EllipticCurve::P384, 48}; + return CurveParameters{.curve = sourcemeta::core::EllipticCurve::P384, + .coordinate_bytes = 48}; } if (name == "secp521r1") { - return CurveParameters{sourcemeta::core::EllipticCurve::P521, 66}; + return CurveParameters{.curve = sourcemeta::core::EllipticCurve::P521, + .coordinate_bytes = 66}; } return std::nullopt; } @@ -736,29 +739,45 @@ struct EcdhCurve { auto to_ecdh_curve(const std::string_view name) -> std::optional { if (name == "secp256r1") { return EcdhCurve{ - sourcemeta::core::EllipticCurve::P256, 32, - "00809c461d8b39163537ff8f5ef5b977e4cdb980e70e38a7ee0b37cc876729e9ff", - "0468ae7706221e5990f7484d34fbec5a99050179a6c11817bbed4aed962998ff", - "b5228d89a1b448f12332376c8c7f080763532a055e07f14a5de0dc30104579e1"}; + .curve = sourcemeta::core::EllipticCurve::P256, + .field_bytes = 32, + .private_scalar = "00809c461d8b39163537ff8f5ef5b977e4cdb980e70e38a7ee0b" + "37cc876729e9ff", + .coordinate_x = + "0468ae7706221e5990f7484d34fbec5a99050179a6c11817bbed4aed962998ff", + .coordinate_y = + "b5228d89a1b448f12332376c8c7f080763532a055e07f14a5de0dc30104579e1"}; } if (name == "secp384r1") { - return EcdhCurve{sourcemeta::core::EllipticCurve::P384, 48, - "00c1781d86cac2c052b7e4f48cef415c5c133052f4e504397e75e4d7" - "cd0ca149da0b4988b8a6ded5ceae4b580691376187", - "29eb9c63a12322cd99de0e8e3c11e6c8a486b1008181be4c825f38b3" - "71e6f03e2926cd60e9a9ccd42e1aa8799d2ef3a7", - "9d045f3a3df974743268be650fbaf68c7045a483093ce2e289903097" - "396f040058faacb723eb493b5b631bc365c5fc49"}; + return EcdhCurve{ + .curve = sourcemeta::core::EllipticCurve::P384, + .field_bytes = 48, + .private_scalar = + "00c1781d86cac2c052b7e4f48cef415c5c133052f4e504397e75e4d7" + "cd0ca149da0b4988b8a6ded5ceae4b580691376187", + .coordinate_x = + "29eb9c63a12322cd99de0e8e3c11e6c8a486b1008181be4c825f38b3" + "71e6f03e2926cd60e9a9ccd42e1aa8799d2ef3a7", + .coordinate_y = + "9d045f3a3df974743268be650fbaf68c7045a483093ce2e289903097" + "396f040058faacb723eb493b5b631bc365c5fc49"}; } if (name == "secp521r1") { return EcdhCurve{ - sourcemeta::core::EllipticCurve::P521, 66, - "01781d86cac2c052b7e4f48cef415c5c1319e07db70db92a497c2ac764e9509ac0b073" - "22801f5ae1f28c9d7db71f79e5f51bf646790af988d62339a6d1543192e327", - "0026e4bc8e3dfcb2898f9fb71eb373199ecd58b13b66c221110819bd05159eb5e3b8d1" - "376f7d5151db140b3cdae698bca9683f3d041164fe0e3dba0d2f02d6643adb", - "010a3f1fcb6dbccc773d143d454347145a9bec498e7a5e2d412095b9350c58d8e9411e" - "a85afe4c56053ad35d8be4230f5e2718365f43dbd2ed44b096a90bfc6227b6"}; + .curve = sourcemeta::core::EllipticCurve::P521, + .field_bytes = 66, + .private_scalar = + "01781d86cac2c052b7e4f48cef415c5c1319e07db70db92a497c2ac764e9509ac0" + "b073" + "22801f5ae1f28c9d7db71f79e5f51bf646790af988d62339a6d1543192e327", + .coordinate_x = + "0026e4bc8e3dfcb2898f9fb71eb373199ecd58b13b66c221110819bd05159eb5e3" + "b8d1" + "376f7d5151db140b3cdae698bca9683f3d041164fe0e3dba0d2f02d6643adb", + .coordinate_y = + "010a3f1fcb6dbccc773d143d454347145a9bec498e7a5e2d412095b9350c58d8e9" + "411e" + "a85afe4c56053ad35d8be4230f5e2718365f43dbd2ed44b096a90bfc6227b6"}; } return std::nullopt; } diff --git a/test/dns/idn_hostname_uts46_test.cc b/test/dns/idn_hostname_uts46_test.cc index b523c0690f..1c5cadfcd4 100644 --- a/test/dns/idn_hostname_uts46_test.cc +++ b/test/dns/idn_hostname_uts46_test.cc @@ -122,7 +122,7 @@ TEST(invalid_utf8) { // UTS #46 maps each U+FF41 to an ASCII letter, so the 63-codepoint label is 63 // octets after mapping even though it is 189 before TEST(valid_length_measured_on_mapped_form) { - static constexpr char value[] = + static constexpr std::string_view INPUT{ "\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81" "\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81" "\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81" @@ -133,16 +133,15 @@ TEST(valid_length_measured_on_mapped_form) { "\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81" "\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81" "\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81" - "\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81"; - static_assert(sizeof(value) - 1 == 189, "literal length"); - const std::string_view input{value, 189}; - EXPECT_TRUE(sourcemeta::core::is_idn_hostname_uts46(input)); - EXPECT_FALSE(sourcemeta::core::is_idn_hostname(input)); + "\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81"}; + static_assert(INPUT.size() == 189, "literal length"); + EXPECT_TRUE(sourcemeta::core::is_idn_hostname_uts46(INPUT)); + EXPECT_FALSE(sourcemeta::core::is_idn_hostname(INPUT)); } // the same label one character longer is over the 63-octet limit TEST(invalid_length_measured_on_mapped_form_at_64) { - static constexpr char value[] = + static constexpr std::string_view INPUT{ "\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81" "\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81" "\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81" @@ -153,233 +152,211 @@ TEST(invalid_length_measured_on_mapped_form_at_64) { "\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81" "\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81" "\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81" - "\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81"; - static_assert(sizeof(value) - 1 == 192, "literal length"); - const std::string_view input{value, 192}; - EXPECT_FALSE(sourcemeta::core::is_idn_hostname_uts46(input)); - EXPECT_FALSE(sourcemeta::core::is_idn_hostname(input)); + "\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81\xef\xbd\x81"}; + static_assert(INPUT.size() == 192, "literal length"); + EXPECT_FALSE(sourcemeta::core::is_idn_hostname_uts46(INPUT)); + EXPECT_FALSE(sourcemeta::core::is_idn_hostname(INPUT)); } // U+200B is ignored, so it must not count toward the 63-octet label limit TEST(valid_ignored_codepoint_not_counted_in_length) { - static constexpr char value[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaa\xe2\x80\x8b"; - static_assert(sizeof(value) - 1 == 66, "literal length"); - const std::string_view input{value, 66}; - EXPECT_TRUE(sourcemeta::core::is_idn_hostname_uts46(input)); - EXPECT_FALSE(sourcemeta::core::is_idn_hostname(input)); + static constexpr std::string_view INPUT{ + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaa\xe2\x80\x8b"}; + static_assert(INPUT.size() == 66, "literal length"); + EXPECT_TRUE(sourcemeta::core::is_idn_hostname_uts46(INPUT)); + EXPECT_FALSE(sourcemeta::core::is_idn_hostname(INPUT)); } // the ignored codepoint does not rescue a label that is already too long TEST(invalid_ignored_codepoint_label_still_over) { - static constexpr char value[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaa\xe2\x80\x8b"; - static_assert(sizeof(value) - 1 == 67, "literal length"); - const std::string_view input{value, 67}; - EXPECT_FALSE(sourcemeta::core::is_idn_hostname_uts46(input)); - EXPECT_FALSE(sourcemeta::core::is_idn_hostname(input)); + static constexpr std::string_view INPUT{ + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaa\xe2\x80\x8b"}; + static_assert(INPUT.size() == 67, "literal length"); + EXPECT_FALSE(sourcemeta::core::is_idn_hostname_uts46(INPUT)); + EXPECT_FALSE(sourcemeta::core::is_idn_hostname(INPUT)); } // U+FF58 U+FF4E map to "xn", so the xn-- test has to run after mapping TEST(valid_ace_prefix_produced_by_mapping) { - static constexpr char value[] = "\xef\xbd\x98\xef\xbd\x8e--nxasmq6b"; - static_assert(sizeof(value) - 1 == 16, "literal length"); - const std::string_view input{value, 16}; - EXPECT_TRUE(sourcemeta::core::is_idn_hostname_uts46(input)); - EXPECT_FALSE(sourcemeta::core::is_idn_hostname(input)); + static constexpr std::string_view INPUT{"\xef\xbd\x98\xef\xbd\x8e--nxasmq6b"}; + static_assert(INPUT.size() == 16, "literal length"); + EXPECT_TRUE(sourcemeta::core::is_idn_hostname_uts46(INPUT)); + EXPECT_FALSE(sourcemeta::core::is_idn_hostname(INPUT)); } // the mapped label is xn--b, which is not decodable Punycode TEST(invalid_ace_prefix_produced_by_mapping_bad_payload) { - static constexpr char value[] = "\xef\xbd\x98\xef\xbd\x8e--b"; - static_assert(sizeof(value) - 1 == 9, "literal length"); - const std::string_view input{value, 9}; - EXPECT_FALSE(sourcemeta::core::is_idn_hostname_uts46(input)); - EXPECT_FALSE(sourcemeta::core::is_idn_hostname(input)); + static constexpr std::string_view INPUT{"\xef\xbd\x98\xef\xbd\x8e--b"}; + static_assert(INPUT.size() == 9, "literal length"); + EXPECT_FALSE(sourcemeta::core::is_idn_hostname_uts46(INPUT)); + EXPECT_FALSE(sourcemeta::core::is_idn_hostname(INPUT)); } // U+FF0D maps to a hyphen, producing a leading hyphen TEST(invalid_hyphen_produced_by_mapping_leading) { - static constexpr char value[] = "\xef\xbc\x8d" - "abc"; - static_assert(sizeof(value) - 1 == 6, "literal length"); - const std::string_view input{value, 6}; - EXPECT_FALSE(sourcemeta::core::is_idn_hostname_uts46(input)); - EXPECT_FALSE(sourcemeta::core::is_idn_hostname(input)); + static constexpr std::string_view INPUT{"\xef\xbc\x8d" + "abc"}; + static_assert(INPUT.size() == 6, "literal length"); + EXPECT_FALSE(sourcemeta::core::is_idn_hostname_uts46(INPUT)); + EXPECT_FALSE(sourcemeta::core::is_idn_hostname(INPUT)); } // U+FF0D maps to a hyphen, producing a trailing hyphen TEST(invalid_hyphen_produced_by_mapping_trailing) { - static constexpr char value[] = "abc\xef\xbc\x8d"; - static_assert(sizeof(value) - 1 == 6, "literal length"); - const std::string_view input{value, 6}; - EXPECT_FALSE(sourcemeta::core::is_idn_hostname_uts46(input)); - EXPECT_FALSE(sourcemeta::core::is_idn_hostname(input)); + static constexpr std::string_view INPUT{"abc\xef\xbc\x8d"}; + static_assert(INPUT.size() == 6, "literal length"); + EXPECT_FALSE(sourcemeta::core::is_idn_hostname_uts46(INPUT)); + EXPECT_FALSE(sourcemeta::core::is_idn_hostname(INPUT)); } // a pair of U+FF0D maps to -- in the third and fourth positions TEST(invalid_double_hyphen_produced_by_mapping) { - static constexpr char value[] = "ab\xef\xbc\x8d\xef\xbc\x8d" - "cd"; - static_assert(sizeof(value) - 1 == 10, "literal length"); - const std::string_view input{value, 10}; - EXPECT_FALSE(sourcemeta::core::is_idn_hostname_uts46(input)); - EXPECT_FALSE(sourcemeta::core::is_idn_hostname(input)); + static constexpr std::string_view INPUT{"ab\xef\xbc\x8d\xef\xbc\x8d" + "cd"}; + static_assert(INPUT.size() == 10, "literal length"); + EXPECT_FALSE(sourcemeta::core::is_idn_hostname_uts46(INPUT)); + EXPECT_FALSE(sourcemeta::core::is_idn_hostname(INPUT)); } // two U+FF0E map to full stops, producing an empty label TEST(invalid_empty_label_produced_by_mapping) { - static constexpr char value[] = "a\xef\xbc\x8e\xef\xbc\x8e" - "b"; - static_assert(sizeof(value) - 1 == 8, "literal length"); - const std::string_view input{value, 8}; - EXPECT_FALSE(sourcemeta::core::is_idn_hostname_uts46(input)); - EXPECT_FALSE(sourcemeta::core::is_idn_hostname(input)); + static constexpr std::string_view INPUT{"a\xef\xbc\x8e\xef\xbc\x8e" + "b"}; + static_assert(INPUT.size() == 8, "literal length"); + EXPECT_FALSE(sourcemeta::core::is_idn_hostname_uts46(INPUT)); + EXPECT_FALSE(sourcemeta::core::is_idn_hostname(INPUT)); } // U+03C2 is a deviation character; nontransitional processing keeps it TEST(valid_deviation_final_sigma_kept) { - static constexpr char value[] = "\xcf\x82"; - static_assert(sizeof(value) - 1 == 2, "literal length"); - const std::string_view input{value, 2}; - EXPECT_TRUE(sourcemeta::core::is_idn_hostname_uts46(input)); - EXPECT_TRUE(sourcemeta::core::is_idn_hostname(input)); + static constexpr std::string_view INPUT{"\xcf\x82"}; + static_assert(INPUT.size() == 2, "literal length"); + EXPECT_TRUE(sourcemeta::core::is_idn_hostname_uts46(INPUT)); + EXPECT_TRUE(sourcemeta::core::is_idn_hostname(INPUT)); } // U+200D is a deviation character kept by nontransitional processing, and then // fails its ContextJ rule TEST(invalid_deviation_zwj_without_context) { - static constexpr char value[] = "a\xe2\x80\x8d" - "b"; - static_assert(sizeof(value) - 1 == 5, "literal length"); - const std::string_view input{value, 5}; - EXPECT_FALSE(sourcemeta::core::is_idn_hostname_uts46(input)); - EXPECT_FALSE(sourcemeta::core::is_idn_hostname(input)); + static constexpr std::string_view INPUT{"a\xe2\x80\x8d" + "b"}; + static_assert(INPUT.size() == 5, "literal length"); + EXPECT_FALSE(sourcemeta::core::is_idn_hostname_uts46(INPUT)); + EXPECT_FALSE(sourcemeta::core::is_idn_hostname(INPUT)); } // U+1D400 MATHEMATICAL BOLD CAPITAL A maps to a TEST(valid_mathematical_bold_is_mapped) { - static constexpr char value[] = "\xf0\x9d\x90\x80" - "bc"; - static_assert(sizeof(value) - 1 == 6, "literal length"); - const std::string_view input{value, 6}; - EXPECT_TRUE(sourcemeta::core::is_idn_hostname_uts46(input)); - EXPECT_FALSE(sourcemeta::core::is_idn_hostname(input)); + static constexpr std::string_view INPUT{"\xf0\x9d\x90\x80" + "bc"}; + static_assert(INPUT.size() == 6, "literal length"); + EXPECT_TRUE(sourcemeta::core::is_idn_hostname_uts46(INPUT)); + EXPECT_FALSE(sourcemeta::core::is_idn_hostname(INPUT)); } // U+FE00 VARIATION SELECTOR-1 is ignored by the mapping TEST(valid_variation_selector_is_ignored) { - static constexpr char value[] = "a\xef\xb8\x80" - "b"; - static_assert(sizeof(value) - 1 == 5, "literal length"); - const std::string_view input{value, 5}; - EXPECT_TRUE(sourcemeta::core::is_idn_hostname_uts46(input)); - EXPECT_FALSE(sourcemeta::core::is_idn_hostname(input)); + static constexpr std::string_view INPUT{"a\xef\xb8\x80" + "b"}; + static_assert(INPUT.size() == 5, "literal length"); + EXPECT_TRUE(sourcemeta::core::is_idn_hostname_uts46(INPUT)); + EXPECT_FALSE(sourcemeta::core::is_idn_hostname(INPUT)); } // U+24D0 CIRCLED LATIN SMALL LETTER A maps to a TEST(valid_circled_latin_is_mapped) { - static constexpr char value[] = "\xe2\x93\x90" - "bc"; - static_assert(sizeof(value) - 1 == 5, "literal length"); - const std::string_view input{value, 5}; - EXPECT_TRUE(sourcemeta::core::is_idn_hostname_uts46(input)); - EXPECT_FALSE(sourcemeta::core::is_idn_hostname(input)); + static constexpr std::string_view INPUT{"\xe2\x93\x90" + "bc"}; + static_assert(INPUT.size() == 5, "literal length"); + EXPECT_TRUE(sourcemeta::core::is_idn_hostname_uts46(INPUT)); + EXPECT_FALSE(sourcemeta::core::is_idn_hostname(INPUT)); } // U+FB01 LATIN SMALL LIGATURE FI maps to the two letters f and i TEST(valid_ligature_is_mapped) { - static constexpr char value[] = "\xef\xac\x81x"; - static_assert(sizeof(value) - 1 == 4, "literal length"); - const std::string_view input{value, 4}; - EXPECT_TRUE(sourcemeta::core::is_idn_hostname_uts46(input)); - EXPECT_FALSE(sourcemeta::core::is_idn_hostname(input)); + static constexpr std::string_view INPUT{"\xef\xac\x81x"}; + static_assert(INPUT.size() == 4, "literal length"); + EXPECT_TRUE(sourcemeta::core::is_idn_hostname_uts46(INPUT)); + EXPECT_FALSE(sourcemeta::core::is_idn_hostname(INPUT)); } // U+005F is UTS #46 valid but carries the IDNA 2008 NV8 tag, so it is excluded // from an IDN label TEST(invalid_underscore_nv8) { - static constexpr char value[] = "a_b"; - static_assert(sizeof(value) - 1 == 3, "literal length"); - const std::string_view input{value, 3}; - EXPECT_FALSE(sourcemeta::core::is_idn_hostname_uts46(input)); - EXPECT_FALSE(sourcemeta::core::is_idn_hostname(input)); + static constexpr std::string_view INPUT{"a_b"}; + static_assert(INPUT.size() == 3, "literal length"); + EXPECT_FALSE(sourcemeta::core::is_idn_hostname_uts46(INPUT)); + EXPECT_FALSE(sourcemeta::core::is_idn_hostname(INPUT)); } // the mapping step normalises to NFC, so the decomposed label is accepted TEST(valid_nfc_composition_by_mapping) { - static constexpr char value[] = "cafe\xcc\x81"; - static_assert(sizeof(value) - 1 == 6, "literal length"); - const std::string_view input{value, 6}; - EXPECT_TRUE(sourcemeta::core::is_idn_hostname_uts46(input)); - EXPECT_FALSE(sourcemeta::core::is_idn_hostname(input)); + static constexpr std::string_view INPUT{"cafe\xcc\x81"}; + static_assert(INPUT.size() == 6, "literal length"); + EXPECT_TRUE(sourcemeta::core::is_idn_hostname_uts46(INPUT)); + EXPECT_FALSE(sourcemeta::core::is_idn_hostname(INPUT)); } // RFC 5893 condition 2: an RTL label may not contain a character with Bidi // property L TEST(invalid_bidi_ltr_char_inside_rtl_label) { - static constexpr char value[] = "\xd7\x90" - "a\xd7\x90"; - static_assert(sizeof(value) - 1 == 5, "literal length"); - const std::string_view input{value, 5}; - EXPECT_FALSE(sourcemeta::core::is_idn_hostname_uts46(input)); - EXPECT_FALSE(sourcemeta::core::is_idn_hostname(input)); + static constexpr std::string_view INPUT{"\xd7\x90" + "a\xd7\x90"}; + static_assert(INPUT.size() == 5, "literal length"); + EXPECT_FALSE(sourcemeta::core::is_idn_hostname_uts46(INPUT)); + EXPECT_FALSE(sourcemeta::core::is_idn_hostname(INPUT)); } // RFC 5893 condition 3: an RTL label must end with R, AL, EN, AN or NSM TEST(invalid_bidi_rtl_label_ends_with_on) { - static constexpr char value[] = "\xd7\x90\xcb\x87"; - static_assert(sizeof(value) - 1 == 4, "literal length"); - const std::string_view input{value, 4}; - EXPECT_FALSE(sourcemeta::core::is_idn_hostname_uts46(input)); - EXPECT_FALSE(sourcemeta::core::is_idn_hostname(input)); + static constexpr std::string_view INPUT{"\xd7\x90\xcb\x87"}; + static_assert(INPUT.size() == 4, "literal length"); + EXPECT_FALSE(sourcemeta::core::is_idn_hostname_uts46(INPUT)); + EXPECT_FALSE(sourcemeta::core::is_idn_hostname(INPUT)); } // RFC 5893 condition 4: an RTL label may not contain both EN and AN TEST(invalid_bidi_rtl_label_mixes_en_and_an) { - static constexpr char value[] = "\xd7\x90" - "0\xd9\xa0"; - static_assert(sizeof(value) - 1 == 5, "literal length"); - const std::string_view input{value, 5}; - EXPECT_FALSE(sourcemeta::core::is_idn_hostname_uts46(input)); - EXPECT_FALSE(sourcemeta::core::is_idn_hostname(input)); + static constexpr std::string_view INPUT{"\xd7\x90" + "0\xd9\xa0"}; + static_assert(INPUT.size() == 5, "literal length"); + EXPECT_FALSE(sourcemeta::core::is_idn_hostname_uts46(INPUT)); + EXPECT_FALSE(sourcemeta::core::is_idn_hostname(INPUT)); } // RFC 5893 condition 1 allows only L, R or AL as a first character, and an // Arabic-Indic digit is AN TEST(invalid_bidi_pure_arabic_indic_digit_label) { - static constexpr char value[] = "\xd9\xa0\xd9\xa1"; - static_assert(sizeof(value) - 1 == 4, "literal length"); - const std::string_view input{value, 4}; - EXPECT_FALSE(sourcemeta::core::is_idn_hostname_uts46(input)); - EXPECT_FALSE(sourcemeta::core::is_idn_hostname(input)); + static constexpr std::string_view INPUT{"\xd9\xa0\xd9\xa1"}; + static_assert(INPUT.size() == 4, "literal length"); + EXPECT_FALSE(sourcemeta::core::is_idn_hostname_uts46(INPUT)); + EXPECT_FALSE(sourcemeta::core::is_idn_hostname(INPUT)); } // RFC 5892 appendix A.9 permits extended Arabic-Indic digits when the label // carries none of the U+0660 block TEST(valid_extended_arabic_indic_digits_only) { - static constexpr char value[] = "\xd8\xa8\xdb\xb0\xdb\xb1"; - static_assert(sizeof(value) - 1 == 6, "literal length"); - const std::string_view input{value, 6}; - EXPECT_TRUE(sourcemeta::core::is_idn_hostname_uts46(input)); - EXPECT_TRUE(sourcemeta::core::is_idn_hostname(input)); + static constexpr std::string_view INPUT{"\xd8\xa8\xdb\xb0\xdb\xb1"}; + static_assert(INPUT.size() == 6, "literal length"); + EXPECT_TRUE(sourcemeta::core::is_idn_hostname_uts46(INPUT)); + EXPECT_TRUE(sourcemeta::core::is_idn_hostname(INPUT)); } // appendix A.9 forbids the two digit blocks in one label TEST(invalid_extended_arabic_indic_mixed_with_arabic_indic) { - static constexpr char value[] = "\xd8\xa8\xdb\xb0\xd9\xa0"; - static_assert(sizeof(value) - 1 == 6, "literal length"); - const std::string_view input{value, 6}; - EXPECT_FALSE(sourcemeta::core::is_idn_hostname_uts46(input)); - EXPECT_FALSE(sourcemeta::core::is_idn_hostname(input)); + static constexpr std::string_view INPUT{"\xd8\xa8\xdb\xb0\xd9\xa0"}; + static_assert(INPUT.size() == 6, "literal length"); + EXPECT_FALSE(sourcemeta::core::is_idn_hostname_uts46(INPUT)); + EXPECT_FALSE(sourcemeta::core::is_idn_hostname(INPUT)); } // appendices A.8 and A.9 scope the rule to "this label", so one block per label // is permitted TEST(valid_arabic_indic_digit_blocks_in_separate_labels) { - static constexpr char value[] = "\xd8\xa8\xd9\xa0.\xd8\xa8\xdb\xb0"; - static_assert(sizeof(value) - 1 == 9, "literal length"); - const std::string_view input{value, 9}; - EXPECT_TRUE(sourcemeta::core::is_idn_hostname_uts46(input)); - EXPECT_TRUE(sourcemeta::core::is_idn_hostname(input)); + static constexpr std::string_view INPUT{"\xd8\xa8\xd9\xa0.\xd8\xa8\xdb\xb0"}; + static_assert(INPUT.size() == 9, "literal length"); + EXPECT_TRUE(sourcemeta::core::is_idn_hostname_uts46(INPUT)); + EXPECT_TRUE(sourcemeta::core::is_idn_hostname(INPUT)); } diff --git a/test/email/email_test.cc b/test/email/email_test.cc index 9e08a40245..fe03a6cc9d 100644 --- a/test/email/email_test.cc +++ b/test/email/email_test.cc @@ -2,6 +2,9 @@ #include #include +#include // std::string_view + +using namespace std::literals::string_view_literals; // RFC 5321 §4.1.2: minimal Dot-string Atom + minimal Domain sub-domain TEST(valid_dot_string_single_letter) { @@ -1133,8 +1136,10 @@ TEST(invalid_trailing_space) { // RFC 5321 §4.1.2 Domain: NUL is not in Ldh-str TEST(invalid_nul_in_domain) { - EXPECT_FALSE(sourcemeta::core::is_email(std::string_view{"a@b\x00c", 5})); - EXPECT_FALSE(sourcemeta::core::is_idn_email(std::string_view{"a@b\x00c", 5})); + EXPECT_FALSE(sourcemeta::core::is_email("a@b\x00" + "c"sv)); + EXPECT_FALSE(sourcemeta::core::is_idn_email("a@b\x00" + "c"sv)); } // RFC 5321 §4.1.2: CRLF bytes are not in the Mailbox alphabet diff --git a/test/email/mailto_iri_test.cc b/test/email/mailto_iri_test.cc index ffdc442677..a565054ece 100644 --- a/test/email/mailto_iri_test.cc +++ b/test/email/mailto_iri_test.cc @@ -46,7 +46,7 @@ TEST(mailto_iri_rfc_quoted_at_sign) { // RFC 6068 §6.2: email address "oh\\no"@example.org corresponds to // TEST(mailto_iri_rfc_quoted_backslash_pairs) { - const auto result{sourcemeta::core::mailto_iri("\"oh\\\\no\"@example.org")}; + const auto result{sourcemeta::core::mailto_iri(R"("oh\\no"@example.org)")}; EXPECT_TRUE(result.has_value()); EXPECT_EQ(result.value(), "mailto:%22oh%5C%5Cno%22@example.org"); } @@ -54,8 +54,8 @@ TEST(mailto_iri_rfc_quoted_backslash_pairs) { // RFC 6068 §6.2: email address "\\\"it's\ ugly\\\""@example.org corresponds // to TEST(mailto_iri_rfc_quoted_ugly_address) { - const auto result{sourcemeta::core::mailto_iri( - "\"\\\\\\\"it's\\ ugly\\\\\\\"\"@example.org")}; + const auto result{ + sourcemeta::core::mailto_iri(R"("\\\"it's\ ugly\\\""@example.org)")}; EXPECT_TRUE(result.has_value()); EXPECT_EQ(result.value(), "mailto:%22%5C%5C%5C%22it's%5C%20ugly%5C%5C%5C%22%22@example.org"); @@ -278,7 +278,7 @@ TEST(mailto_iri_encodes_quoted_angle_brackets) { // RFC 5321 §4.1.2: quoted-pairSMTP = %d92 %d32-126, the backslash cannot // appear in a URI and is percent-encoded TEST(mailto_iri_encodes_quoted_pair) { - const auto result{sourcemeta::core::mailto_iri("\"\\a\"@example.com")}; + const auto result{sourcemeta::core::mailto_iri(R"("\a"@example.com)")}; EXPECT_TRUE(result.has_value()); EXPECT_EQ(result.value(), "mailto:%22%5Ca%22@example.com"); } diff --git a/test/gzip/gzip_streambuf_test.cc b/test/gzip/gzip_streambuf_test.cc index 40310af373..f58b6ab462 100644 --- a/test/gzip/gzip_streambuf_test.cc +++ b/test/gzip/gzip_streambuf_test.cc @@ -208,7 +208,7 @@ TEST(output_size_32768) { TEST(output_size_one_megabyte) { std::string input; - input.resize(1024 * 1024); + input.resize(std::size_t{1024} * 1024); for (std::size_t index = 0; index < input.size(); ++index) { input[index] = static_cast(index & 0xff); } @@ -240,6 +240,8 @@ TEST(highly_compressible_repeated_byte) { } TEST(incompressible_random_bytes) { + // A fixed seed keeps the incompressible payload identical across runs + // NOLINTNEXTLINE(cert-msc32-c,cert-msc51-cpp,bugprone-random-generator-seed) std::mt19937 generator{42}; std::uniform_int_distribution distribution{0, 255}; std::string input; @@ -1197,5 +1199,6 @@ TEST(truncated_trailer_throws) { decompress_via_stream(compressed); FAIL(); } catch (const sourcemeta::core::GZIPError &) { + // Rejecting the corrupt stream is expected } } diff --git a/test/html/html_escape_test.cc b/test/html/html_escape_test.cc index d511cf9190..3533118dfb 100644 --- a/test/html/html_escape_test.cc +++ b/test/html/html_escape_test.cc @@ -400,7 +400,7 @@ TEST(consecutive_greater_than) { } TEST(consecutive_double_quotes) { - std::string text = "\"\"\""; + std::string text = R"(""")"; sourcemeta::core::html_escape(text); EXPECT_EQ(text, """""); } diff --git a/test/http/http_cache_control_max_age_test.cc b/test/http/http_cache_control_max_age_test.cc index 28a5ce67bf..da85e4039b 100644 --- a/test/http/http_cache_control_max_age_test.cc +++ b/test/http/http_cache_control_max_age_test.cc @@ -110,7 +110,7 @@ TEST(non_numeric_quoted_value_rejected) { TEST(quoted_pair_escaped_digits) { const auto result{ - sourcemeta::core::http_cache_control_max_age("max-age=\"6\\0\\0\"")}; + sourcemeta::core::http_cache_control_max_age(R"(max-age="6\0\0")")}; EXPECT_TRUE(result.has_value()); EXPECT_EQ(result.value(), std::chrono::seconds{600}); } diff --git a/test/http/http_field_list_contains_any_test.cc b/test/http/http_field_list_contains_any_test.cc index e583a97896..5d22845a7e 100644 --- a/test/http/http_field_list_contains_any_test.cc +++ b/test/http/http_field_list_contains_any_test.cc @@ -139,8 +139,8 @@ TEST(etag_with_comma_inside_quotes_not_split_into_pieces) { } TEST(escaped_quote_in_quoted_string_handled) { - const std::string_view header{"\"a\\\"b,c\", \"xyz\""}; - const std::string_view token{"\"a\\\"b,c\""}; + const std::string_view header{R"("a\"b,c", "xyz")"}; + const std::string_view token{R"("a\"b,c")"}; EXPECT_TRUE(sourcemeta::core::http_field_list_contains_any(header, {token})); } diff --git a/test/http/http_match_accept_test.cc b/test/http/http_match_accept_test.cc index 6281debbad..ea9f5273b6 100644 --- a/test/http/http_match_accept_test.cc +++ b/test/http/http_match_accept_test.cc @@ -320,7 +320,7 @@ TEST(quoted_string_with_comma_does_not_split_entry) { // it TEST(escaped_quote_inside_quoted_string_handled) { const std::string_view header{ - "text/html;profile=\"a\\\"b,c\", application/json;q=0.5"}; + R"(text/html;profile="a\"b,c", application/json;q=0.5)"}; EXPECT_EQ(sourcemeta::core::http_match_accept( header, {"text/html;profile=\"a\\\"b,c\"", "application/json"}), "text/html;profile=\"a\\\"b,c\""); diff --git a/test/http/http_parse_challenges_test.cc b/test/http/http_parse_challenges_test.cc index 912003251e..15f523f7d2 100644 --- a/test/http/http_parse_challenges_test.cc +++ b/test/http/http_parse_challenges_test.cc @@ -9,7 +9,7 @@ namespace { using Challenges = std::vector; -} +} // namespace // RFC 6750 §3: "WWW-Authenticate: Bearer realm="example"" TEST(parse_challenges_bearer_with_a_realm) { diff --git a/test/http/http_serialize_challenge_test.cc b/test/http/http_serialize_challenge_test.cc index 7736f6192c..3f8871f4d2 100644 --- a/test/http/http_serialize_challenge_test.cc +++ b/test/http/http_serialize_challenge_test.cc @@ -8,7 +8,7 @@ namespace { using Parameter = std::pair; -} +} // namespace // RFC 6750 §3: "WWW-Authenticate: Bearer realm="example"" TEST(serialize_challenge_bearer_with_a_realm) { diff --git a/test/io/io_binary_test.cc b/test/io/io_binary_test.cc index 03f0d7fb51..ffd1164cd2 100644 --- a/test/io/io_binary_test.cc +++ b/test/io/io_binary_test.cc @@ -110,7 +110,8 @@ TEST(put_bytes_zero_length_is_noop) { } TEST(put_pod_via_put_bytes) { - const ExampleHeader expected{0xDEADBEEF, 7, 0x42, 1024}; + const ExampleHeader expected{ + .magic = 0xDEADBEEF, .version = 7, .flags = 0x42, .payload_size = 1024}; std::ostringstream stream; sourcemeta::core::BinaryWriter writer{stream}; writer.put_bytes(reinterpret_cast(&expected), @@ -173,7 +174,8 @@ TEST(get_qword_roundtrip_via_stringstream) { } TEST(get_pod_roundtrip_via_stringstream) { - const ExampleHeader expected{0xDEADBEEF, 7, 0x42, 1024}; + const ExampleHeader expected{ + .magic = 0xDEADBEEF, .version = 7, .flags = 0x42, .payload_size = 1024}; std::ostringstream output; sourcemeta::core::BinaryWriter writer{output}; writer.put_bytes(reinterpret_cast(&expected), @@ -303,7 +305,8 @@ TEST_F(IOBinaryTest, get_after_put_integer_roundtrip_via_file) { TEST_F(IOBinaryTest, get_after_put_struct_roundtrip_via_file) { const auto path{this->workspace_ / "header.bin"}; - const ExampleHeader expected{0xDEADBEEF, 7, 0x42, 1024}; + const ExampleHeader expected{ + .magic = 0xDEADBEEF, .version = 7, .flags = 0x42, .payload_size = 1024}; { std::ofstream raw{path, std::ios::binary}; sourcemeta::core::BinaryWriter writer{raw}; diff --git a/test/io/io_canonical_test.cc b/test/io/io_canonical_test.cc index a0ba70e680..17d3b9d3f3 100644 --- a/test/io/io_canonical_test.cc +++ b/test/io/io_canonical_test.cc @@ -51,6 +51,7 @@ TEST(file_as_intermediate_directory_throws) { sourcemeta::core::canonical(path); FAIL(); } catch (const std::filesystem::filesystem_error &) { + // Refusing the missing path is expected } catch (...) { FAIL(); } diff --git a/test/io/io_fileview_test.cc b/test/io/io_fileview_test.cc index 8e32ffd050..9f06510b92 100644 --- a/test/io/io_fileview_test.cc +++ b/test/io/io_fileview_test.cc @@ -43,8 +43,8 @@ TEST(as_with_offset) { TEST(file_not_found) { try { - sourcemeta::core::FileView(std::filesystem::path{STUBS_DIRECTORY} / - "nonexistent.bin"); + const sourcemeta::core::FileView view{ + std::filesystem::path{STUBS_DIRECTORY} / "nonexistent.bin"}; FAIL(); } catch (const sourcemeta::core::FileViewError &error) { EXPECT_EQ(error.path(), diff --git a/test/io/io_flush_test.cc b/test/io/io_flush_test.cc index 912be9f604..fd5db667a4 100644 --- a/test/io/io_flush_test.cc +++ b/test/io/io_flush_test.cc @@ -28,6 +28,7 @@ TEST(flush_a_directory_throws) { sourcemeta::core::flush(path); FAIL(); } catch (const std::filesystem::filesystem_error &) { + // Refusing the unflushable path is expected } catch (...) { FAIL(); } diff --git a/test/io/io_read_to_string_test.cc b/test/io/io_read_to_string_test.cc index 43c525a8c1..ffbe1f7c6e 100644 --- a/test/io/io_read_to_string_test.cc +++ b/test/io/io_read_to_string_test.cc @@ -104,7 +104,7 @@ TEST_F(IOReadFileToStringTest, freshly_written_file) { TEST_F(IOReadFileToStringTest, empty_file) { const auto path{this->workspace_ / "empty.txt"}; - std::ofstream{path}; + const std::ofstream stream{path}; EXPECT_EQ(sourcemeta::core::read_file_to_string(path), ""); } diff --git a/test/io/io_temporary_test.cc b/test/io/io_temporary_test.cc index fa83f79708..3b5e0da129 100644 --- a/test/io/io_temporary_test.cc +++ b/test/io/io_temporary_test.cc @@ -83,12 +83,12 @@ TEST(parent_is_a_file) { const sourcemeta::core::TemporaryDirectory unique_parent{ std::filesystem::path{BUILD_DIRECTORY}, ".test-parent-"}; const auto file_path{unique_parent.path() / "test_parent_file"}; - std::ofstream{file_path}; + const std::ofstream stream{file_path}; EXPECT_TRUE(std::filesystem::exists(file_path)); EXPECT_FALSE(std::filesystem::is_directory(file_path)); try { - sourcemeta::core::TemporaryDirectory(file_path, ".test-"); + const sourcemeta::core::TemporaryDirectory directory{file_path, ".test-"}; FAIL(); } catch (const sourcemeta::core::IONotADirectoryError &error) { EXPECT_EQ(error.path(), file_path); diff --git a/test/jose/jose_jwe_decrypt_test.cc b/test/jose/jose_jwe_decrypt_test.cc index 48988c43a0..09c10772f5 100644 --- a/test/jose/jose_jwe_decrypt_test.cc +++ b/test/jose/jose_jwe_decrypt_test.cc @@ -8,7 +8,7 @@ #include // std::string #include // std::string_view -static const std::string PLAINTEXT{"Encrypt then authenticate."}; +static constexpr std::string_view PLAINTEXT{"Encrypt then authenticate."}; static auto header_for(const std::string_view algorithm, const std::string_view encryption) diff --git a/test/jose/jose_jwe_encrypt_test.cc b/test/jose/jose_jwe_encrypt_test.cc index 3c3885636d..9a70f8a15c 100644 --- a/test/jose/jose_jwe_encrypt_test.cc +++ b/test/jose/jose_jwe_encrypt_test.cc @@ -7,7 +7,7 @@ #include // std::string #include // std::string_view -static const std::string PLAINTEXT{ +static constexpr std::string_view PLAINTEXT{ "The true sign of intelligence is not knowledge but imagination."}; static auto header_for(const std::string_view algorithm, diff --git a/test/jose/jose_jwk_private_test.cc b/test/jose/jose_jwk_private_test.cc index 0e5c941296..a5e179e16d 100644 --- a/test/jose/jose_jwk_private_test.cc +++ b/test/jose/jose_jwk_private_test.cc @@ -3,12 +3,13 @@ #include #include -#include // std::string +#include // std::string +#include // std::string_view // A private RSA JSON Web Key in the two-prime form, its elliptic curve and // octet key pair counterparts, and the same RSA key as a PKCS#8 PEM document. // The material matches the keys exercised by the crypto module tests -static const std::string RSA_PRIVATE_JWK{ +static constexpr std::string_view RSA_PRIVATE_JWK{ R"({"kty":"RSA",)" R"("n":"n-ivWLN0CTSLXc7GNcHGOuZHdu6QcGT3SlFTaf2ckxLVEDcAU4fIez7rKtvZaCzp)" R"(KJ6cb5KZnDcIn-gOCrE0FI6OZdCvgAGNqoFH6D1AANk8lWSFc1bWoti5xzXls2IN4fDRDa)" @@ -37,23 +38,23 @@ static const std::string RSA_PRIVATE_JWK{ R"(jGKFMuXAJo4pz6IBgS5eN6uzPvfvqJUiMGc6lG_zBFKsc-WnveUIzYqqz3gNrA_gwN872o)" R"(JCzSsEiFwMKFkui2fIAH8-c7Z5Tpo63qroRxk"})"}; -static const std::string EC_PUBLIC_X_B64URL{ +static constexpr std::string_view EC_PUBLIC_X_B64URL{ "2TARGSWq8F97iq3Ng48wCEN26cxzy8OCzbFa-6ZfnaI"}; -static const std::string EC_PUBLIC_Y_B64URL{ +static constexpr std::string_view EC_PUBLIC_Y_B64URL{ "5lkzZqhWOkc2m2zJOotl6K3_x6-TSs9OnzQKwb35DxQ"}; -static const std::string EC_PRIVATE_JWK{ +static constexpr std::string_view EC_PRIVATE_JWK{ R"({"kty":"EC","crv":"P-256",)" R"("x":"2TARGSWq8F97iq3Ng48wCEN26cxzy8OCzbFa-6ZfnaI",)" R"("y":"5lkzZqhWOkc2m2zJOotl6K3_x6-TSs9OnzQKwb35DxQ",)" R"("d":"ttepxcp-OwXCj4-v4sGcxRxQRXA8D5Svu02yhcHvbd0"})"}; -static const std::string OKP_PRIVATE_JWK{ +static constexpr std::string_view OKP_PRIVATE_JWK{ R"({"kty":"OKP","crv":"Ed25519",)" R"("x":"SFOeT7YjsNIh-M1-nCBGnB9VWYu1uyNqiizCZhwddDo",)" R"("d":"dB7DXOXgcInKeC-I3gDYEDoc2OixFqzYr9kiwBvueGc"})"}; -static const std::string RSA_PRIVATE_KEY_PEM{ +static constexpr std::string_view RSA_PRIVATE_KEY_PEM{ R"(-----BEGIN PRIVATE KEY----- MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCf6K9Ys3QJNItd zsY1wcY65kd27pBwZPdKUVNp/ZyTEtUQNwBTh8h7Pusq29loLOkonpxvkpmcNwif diff --git a/test/jose/jose_jwk_test.cc b/test/jose/jose_jwk_test.cc index facb7fa1ea..6a6e1d01b8 100644 --- a/test/jose/jose_jwk_test.cc +++ b/test/jose/jose_jwk_test.cc @@ -166,7 +166,7 @@ TEST(rejects_rsa_modulus_below_minimum) { TEST(constructor_throws_on_invalid_input) { const auto document{sourcemeta::core::parse_json(R"({ "kty": "oct" })")}; try { - sourcemeta::core::JWK{document}; + const sourcemeta::core::JWK key{document}; FAIL(); } catch (const sourcemeta::core::JWKParseError &error) { EXPECT_STREQ(error.what(), "The input is not a valid JSON Web Key"); diff --git a/test/jose/jose_jwks_provider_test.cc b/test/jose/jose_jwks_provider_test.cc index 930dc4bd4f..15c5999d69 100644 --- a/test/jose/jose_jwks_provider_test.cc +++ b/test/jose/jose_jwks_provider_test.cc @@ -98,8 +98,8 @@ auto oct_provider() -> sourcemeta::core::JWKSProvider { "https://issuer.test/jwks", [](const std::string_view) -> std::optional { - return sourcemeta::core::JWKSProvider::FetchResult{oct_key_document(), - std::nullopt}; + return sourcemeta::core::JWKSProvider::FetchResult{ + .body = oct_key_document(), .max_age = std::nullopt}; }}; } @@ -131,8 +131,8 @@ TEST(malformed_body_is_treated_as_failure) { const auto fetcher{ [](const std::string_view) -> std::optional { - return sourcemeta::core::JWKSProvider::FetchResult{"not json at all", - std::nullopt}; + return sourcemeta::core::JWKSProvider::FetchResult{ + .body = "not json at all", .max_age = std::nullopt}; }}; auto now{std::chrono::system_clock::from_time_t(1000000000)}; sourcemeta::core::JWKSProvider provider{ @@ -154,7 +154,7 @@ TEST(cache_hit_does_not_refetch) { -> std::optional { calls += 1; return sourcemeta::core::JWKSProvider::FetchResult{ - std::string{SIGNED_KEYS}, std::nullopt}; + .body = std::string{SIGNED_KEYS}, .max_age = std::nullopt}; }}; auto now{std::chrono::system_clock::from_time_t(1000000000)}; sourcemeta::core::JWKSProvider provider{ @@ -183,7 +183,7 @@ TEST(cache_control_absent_uses_fallback) { -> std::optional { calls += 1; return sourcemeta::core::JWKSProvider::FetchResult{ - std::string{SIGNED_KEYS}, std::nullopt}; + .body = std::string{SIGNED_KEYS}, .max_age = std::nullopt}; }}; auto now{std::chrono::system_clock::from_time_t(1000000000)}; sourcemeta::core::JWKSProvider provider{ @@ -222,7 +222,8 @@ TEST(cache_control_above_maximum_clamps_down) { -> std::optional { calls += 1; return sourcemeta::core::JWKSProvider::FetchResult{ - std::string{SIGNED_KEYS}, std::chrono::hours{48}}; + .body = std::string{SIGNED_KEYS}, + .max_age = std::chrono::hours{48}}; }}; auto now{std::chrono::system_clock::from_time_t(1000000000)}; sourcemeta::core::JWKSProvider provider{ @@ -261,7 +262,8 @@ TEST(cache_control_below_minimum_clamps_up) { -> std::optional { calls += 1; return sourcemeta::core::JWKSProvider::FetchResult{ - std::string{SIGNED_KEYS}, std::chrono::seconds{60}}; + .body = std::string{SIGNED_KEYS}, + .max_age = std::chrono::seconds{60}}; }}; auto now{std::chrono::system_clock::from_time_t(1000000000)}; sourcemeta::core::JWKSProvider provider{ @@ -301,7 +303,8 @@ TEST(cache_control_zero_clamps_to_minimum) { calls += 1; // A real, advertised lifetime of zero, distinct from no advertisement return sourcemeta::core::JWKSProvider::FetchResult{ - std::string{SIGNED_KEYS}, std::chrono::seconds{0}}; + .body = std::string{SIGNED_KEYS}, + .max_age = std::chrono::seconds{0}}; }}; auto now{std::chrono::system_clock::from_time_t(1000000000)}; sourcemeta::core::JWKSProvider provider{ @@ -343,8 +346,8 @@ TEST(unknown_key_triggers_one_guarded_refetch) { -> std::optional { calls += 1; return sourcemeta::core::JWKSProvider::FetchResult{ - std::string{calls == 1 ? ELLIPTIC_CURVE_KEYS : SIGNED_KEYS}, - std::nullopt}; + .body = std::string{calls == 1 ? ELLIPTIC_CURVE_KEYS : SIGNED_KEYS}, + .max_age = std::nullopt}; }}; auto now{std::chrono::system_clock::from_time_t(1000000000)}; sourcemeta::core::JWKSProvider provider{ @@ -366,7 +369,7 @@ TEST(signature_failure_is_not_retried) { -> std::optional { calls += 1; return sourcemeta::core::JWKSProvider::FetchResult{ - std::string{RSA_KEYS_KEY_ID_K1}, std::nullopt}; + .body = std::string{RSA_KEYS_KEY_ID_K1}, .max_age = std::nullopt}; }}; auto now{std::chrono::system_clock::from_time_t(1300000000)}; sourcemeta::core::JWKSProvider provider{ @@ -395,7 +398,8 @@ TEST(unknown_key_refetch_is_bounded_by_cooldown) { -> std::optional { calls += 1; return sourcemeta::core::JWKSProvider::FetchResult{ - std::string{RSA_KEYS_KEY_ID_OTHER}, std::nullopt}; + .body = std::string{RSA_KEYS_KEY_ID_OTHER}, + .max_age = std::nullopt}; }}; auto now{std::chrono::system_clock::from_time_t(1300000000)}; sourcemeta::core::JWKSProvider provider{ @@ -436,7 +440,7 @@ TEST(failed_refresh_serves_stale_keys) { calls += 1; if (calls == 1) { return sourcemeta::core::JWKSProvider::FetchResult{ - std::string{SIGNED_KEYS}, std::nullopt}; + .body = std::string{SIGNED_KEYS}, .max_age = std::nullopt}; } return std::nullopt; }}; @@ -477,7 +481,7 @@ TEST(expected_type_is_forwarded) { [](const std::string_view) -> std::optional { return sourcemeta::core::JWKSProvider::FetchResult{ - std::string{SIGNED_KEYS}, std::nullopt}; + .body = std::string{SIGNED_KEYS}, .max_age = std::nullopt}; }}; auto now{std::chrono::system_clock::from_time_t(1000000000)}; sourcemeta::core::JWKSProvider provider{ @@ -500,7 +504,7 @@ TEST(clock_skew_tolerates_recent_expiry) { [](const std::string_view) -> std::optional { return sourcemeta::core::JWKSProvider::FetchResult{ - std::string{SIGNED_KEYS}, std::nullopt}; + .body = std::string{SIGNED_KEYS}, .max_age = std::nullopt}; }}; // Thirty seconds past the token's expiry, but a sixty second skew absorbs it, // proving the configured tolerance reaches the underlying verification @@ -550,7 +554,7 @@ TEST(fetcher_recovers_after_exception) { throw std::runtime_error{"transport failure"}; } return sourcemeta::core::JWKSProvider::FetchResult{ - std::string{SIGNED_KEYS}, std::nullopt}; + .body = std::string{SIGNED_KEYS}, .max_age = std::nullopt}; }}; auto now{std::chrono::system_clock::from_time_t(1000000000)}; sourcemeta::core::JWKSProvider provider{ @@ -581,7 +585,7 @@ TEST(fetcher_exception_serves_stale_keys) { calls += 1; if (calls == 1) { return sourcemeta::core::JWKSProvider::FetchResult{ - std::string{SIGNED_KEYS}, std::nullopt}; + .body = std::string{SIGNED_KEYS}, .max_age = std::nullopt}; } throw std::runtime_error{"transport failure"}; }}; @@ -612,8 +616,8 @@ TEST(empty_key_set_is_treated_as_failure) { const auto fetcher{ [](const std::string_view) -> std::optional { - return sourcemeta::core::JWKSProvider::FetchResult{R"({ "keys": [] })", - std::nullopt}; + return sourcemeta::core::JWKSProvider::FetchResult{ + .body = R"({ "keys": [] })", .max_age = std::nullopt}; }}; auto now{std::chrono::system_clock::from_time_t(1000000000)}; sourcemeta::core::JWKSProvider provider{ @@ -635,7 +639,7 @@ TEST(disallowed_algorithm_denies) { -> std::optional { calls += 1; return sourcemeta::core::JWKSProvider::FetchResult{ - std::string{SIGNED_KEYS}, std::nullopt}; + .body = std::string{SIGNED_KEYS}, .max_age = std::nullopt}; }}; auto now{std::chrono::system_clock::from_time_t(1000000000)}; sourcemeta::core::JWKSProvider provider{ @@ -661,7 +665,7 @@ TEST(expired_token_denies) { [](const std::string_view) -> std::optional { return sourcemeta::core::JWKSProvider::FetchResult{ - std::string{SIGNED_KEYS}, std::nullopt}; + .body = std::string{SIGNED_KEYS}, .max_age = std::nullopt}; }}; // One second past the token's expiry of 2000000000 auto now{std::chrono::system_clock::from_time_t(2000000001)}; @@ -682,7 +686,7 @@ TEST(wrong_audience_denies) { [](const std::string_view) -> std::optional { return sourcemeta::core::JWKSProvider::FetchResult{ - std::string{SIGNED_KEYS}, std::nullopt}; + .body = std::string{SIGNED_KEYS}, .max_age = std::nullopt}; }}; auto now{std::chrono::system_clock::from_time_t(1000000000)}; sourcemeta::core::JWKSProvider provider{ @@ -704,7 +708,7 @@ TEST(inverted_lifetime_bounds_stay_well_defined) { -> std::optional { calls += 1; return sourcemeta::core::JWKSProvider::FetchResult{ - std::string{SIGNED_KEYS}, std::chrono::hours{1}}; + .body = std::string{SIGNED_KEYS}, .max_age = std::chrono::hours{1}}; }}; auto now{std::chrono::system_clock::from_time_t(1000000000)}; // A misconfiguration with the minimum above the maximum must not be undefined @@ -745,7 +749,7 @@ TEST(empty_clock_falls_back_to_the_system_clock) { [](const std::string_view) -> std::optional { return sourcemeta::core::JWKSProvider::FetchResult{ - std::string{SIGNED_KEYS}, std::nullopt}; + .body = std::string{SIGNED_KEYS}, .max_age = std::nullopt}; }}; // A default-constructed clock falls back to real time rather than calling an // empty target, so the far-future token verifies instead of throwing @@ -766,7 +770,7 @@ TEST(verify_shares_its_resolved_clock_reading) { [](const std::string_view) -> std::optional { return sourcemeta::core::JWKSProvider::FetchResult{ - std::string{SIGNED_KEYS}, std::nullopt}; + .body = std::string{SIGNED_KEYS}, .max_age = std::nullopt}; }}; const auto now{std::chrono::system_clock::from_time_t(1000000000)}; sourcemeta::core::JWKSProvider provider{ diff --git a/test/jose/jose_jwks_test.cc b/test/jose/jose_jwks_test.cc index c05e219ede..1711d249ff 100644 --- a/test/jose/jose_jwks_test.cc +++ b/test/jose/jose_jwks_test.cc @@ -49,14 +49,15 @@ TEST(parses_multiple_keys) { EXPECT_TRUE(rsa->key_id().has_value()); EXPECT_EQ(rsa->key_id().value(), "rsa-1"); - const auto *ec{keys.value().find("ec-1")}; - EXPECT_NE(ec, nullptr); - EXPECT_EQ(ec->type(), sourcemeta::core::JWK::Type::EllipticCurve); - EXPECT_EQ(ec->curve(), "P-256"); - EXPECT_TRUE(ec->algorithm().has_value()); - EXPECT_EQ(ec->algorithm().value(), sourcemeta::core::JWSAlgorithm::ES256); - EXPECT_TRUE(ec->key_id().has_value()); - EXPECT_EQ(ec->key_id().value(), "ec-1"); + const auto *elliptic_curve{keys.value().find("ec-1")}; + EXPECT_NE(elliptic_curve, nullptr); + EXPECT_EQ(elliptic_curve->type(), sourcemeta::core::JWK::Type::EllipticCurve); + EXPECT_EQ(elliptic_curve->curve(), "P-256"); + EXPECT_TRUE(elliptic_curve->algorithm().has_value()); + EXPECT_EQ(elliptic_curve->algorithm().value(), + sourcemeta::core::JWSAlgorithm::ES256); + EXPECT_TRUE(elliptic_curve->key_id().has_value()); + EXPECT_EQ(elliptic_curve->key_id().value(), "ec-1"); } TEST(skips_unsupported_key) { @@ -246,7 +247,7 @@ TEST(from_accepts_rvalue) { TEST(constructor_throws_on_invalid_input) { const auto document{sourcemeta::core::parse_json(R"("not an object")")}; try { - sourcemeta::core::JWKS{document}; + const sourcemeta::core::JWKS keys{document}; FAIL(); } catch (const sourcemeta::core::JWKSParseError &error) { EXPECT_STREQ(error.what(), "The input is not a valid JSON Web Key Set"); diff --git a/test/jose/jose_jws_sign_test.cc b/test/jose/jose_jws_sign_test.cc index a36af1c4f4..be36b2f3cc 100644 --- a/test/jose/jose_jws_sign_test.cc +++ b/test/jose/jose_jws_sign_test.cc @@ -6,33 +6,33 @@ #include // std::string_view // An Ed25519 key pair, since the JOSE cookbook carries no Edwards example -static const std::string OKP_PRIVATE_JWK{ +static constexpr std::string_view OKP_PRIVATE_JWK{ R"({"kty":"OKP","crv":"Ed25519",)" R"("x":"SFOeT7YjsNIh-M1-nCBGnB9VWYu1uyNqiizCZhwddDo",)" R"("d":"dB7DXOXgcInKeC-I3gDYEDoc2OixFqzYr9kiwBvueGc"})"}; -static const std::string OKP_PUBLIC_JWK{ +static constexpr std::string_view OKP_PUBLIC_JWK{ R"({"kty":"OKP","crv":"Ed25519",)" R"("x":"SFOeT7YjsNIh-M1-nCBGnB9VWYu1uyNqiizCZhwddDo"})"}; // A P-256 key as PEM, whose parsed form carries no curve name, with its public // coordinates -static const std::string EC_PRIVATE_KEY_PEM{ +static constexpr std::string_view EC_PRIVATE_KEY_PEM{ R"(-----BEGIN PRIVATE KEY----- MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg+WFQs5q2XetYWqZm Ci8zy4KBzd25YLQ/9CCEgd/fZVWhRANCAATbql1xB7Tw6SgrR2SdqcmKGpxOuTaz tFKcM9RWrXyBKkkB1YI1epQBgrAVNIfpp4k/nzHACQBp5iZictVxHsBm -----END PRIVATE KEY----- )"}; -static const std::string EC_PUBLIC_JWK{ +static constexpr std::string_view EC_PUBLIC_JWK{ R"({"kty":"EC","crv":"P-256",)" R"("x":"26pdcQe08OkoK0dknanJihqcTrk2s7RSnDPUVq18gSo",)" R"("y":"SQHVgjV6lAGCsBU0h-mniT-fMcAJAGnmJmJy1XEewGY"})"}; // The RFC 7515 Appendix A.1 example key and signing input -static const std::string OCT_JWK{ +static constexpr std::string_view OCT_JWK{ R"({"kty":"oct","k":"AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T)" R"(-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow"})"}; -static const std::string_view RFC7515_A1_SIGNING_INPUT{ +static constexpr std::string_view RFC7515_A1_SIGNING_INPUT{ "eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9." "eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlL" "mNvbS9pc19yb290Ijp0cnVlfQ"}; diff --git a/test/jose/jose_jwt_sign_test.cc b/test/jose/jose_jwt_sign_test.cc index dc0db9df7c..dc54654635 100644 --- a/test/jose/jose_jwt_sign_test.cc +++ b/test/jose/jose_jwt_sign_test.cc @@ -2,20 +2,21 @@ #include #include -#include // std::string +#include // std::string +#include // std::string_view -static const std::string EC_PRIVATE_JWK{ +static constexpr std::string_view EC_PRIVATE_JWK{ R"({"kty":"EC","crv":"P-256",)" R"("x":"2TARGSWq8F97iq3Ng48wCEN26cxzy8OCzbFa-6ZfnaI",)" R"("y":"5lkzZqhWOkc2m2zJOotl6K3_x6-TSs9OnzQKwb35DxQ",)" R"("d":"ttepxcp-OwXCj4-v4sGcxRxQRXA8D5Svu02yhcHvbd0"})"}; -static const std::string EC_PUBLIC_JWK{ +static constexpr std::string_view EC_PUBLIC_JWK{ R"({"kty":"EC","crv":"P-256",)" R"("x":"2TARGSWq8F97iq3Ng48wCEN26cxzy8OCzbFa-6ZfnaI",)" R"("y":"5lkzZqhWOkc2m2zJOotl6K3_x6-TSs9OnzQKwb35DxQ"})"}; // The RFC 7515 Appendix A.1 example symmetric key -static const std::string OCT_JWK{ +static constexpr std::string_view OCT_JWK{ R"({"kty":"oct","k":"AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T)" R"(-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow"})"}; diff --git a/test/jose/jose_jwt_test.cc b/test/jose/jose_jwt_test.cc index a70b3dbdc0..0f1007b568 100644 --- a/test/jose/jose_jwt_test.cc +++ b/test/jose/jose_jwt_test.cc @@ -354,7 +354,7 @@ TEST(rejects_critical_header) { TEST(constructor_throws_on_invalid_input) { try { - sourcemeta::core::JWT{"abc.def"}; + const sourcemeta::core::JWT token{"abc.def"}; FAIL(); } catch (const sourcemeta::core::JWTParseError &error) { EXPECT_STREQ(error.what(), "The input is not a valid JSON Web Token"); diff --git a/test/jose/jose_thumbprint_test.cc b/test/jose/jose_thumbprint_test.cc index 3f54a12f40..7bb1652d8d 100644 --- a/test/jose/jose_thumbprint_test.cc +++ b/test/jose/jose_thumbprint_test.cc @@ -2,11 +2,12 @@ #include #include -#include // std::string +#include // std::string +#include // std::string_view // A 2048-bit RSA private key in unencrypted PKCS#8, reused from the signing // tests, to exercise the PEM public-recovery path -static const std::string RSA_PRIVATE_KEY{ +static constexpr std::string_view RSA_PRIVATE_KEY{ R"(-----BEGIN PRIVATE KEY----- MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCf6K9Ys3QJNItd zsY1wcY65kd27pBwZPdKUVNp/ZyTEtUQNwBTh8h7Pusq29loLOkonpxvkpmcNwif diff --git a/test/json/json_array_test.cc b/test/json/json_array_test.cc index 939317e3d7..7b8b139764 100644 --- a/test/json/json_array_test.cc +++ b/test/json/json_array_test.cc @@ -10,31 +10,28 @@ #include TEST(general_traits) { - EXPECT_TRUE( - std::is_default_constructible::value); - EXPECT_FALSE(std::is_nothrow_default_constructible< - sourcemeta::core::JSON::Array>::value); - EXPECT_TRUE(std::is_destructible::value); - EXPECT_TRUE( - std::is_nothrow_destructible::value); + EXPECT_TRUE(std::is_default_constructible_v); + EXPECT_FALSE( + std::is_nothrow_default_constructible_v); + EXPECT_TRUE(std::is_destructible_v); + EXPECT_TRUE(std::is_nothrow_destructible_v); } TEST(copy_traits) { - EXPECT_TRUE(std::is_copy_assignable::value); - EXPECT_TRUE(std::is_copy_constructible::value); + EXPECT_TRUE(std::is_copy_assignable_v); + EXPECT_TRUE(std::is_copy_constructible_v); EXPECT_FALSE( - std::is_nothrow_copy_assignable::value); + std::is_nothrow_copy_assignable_v); EXPECT_FALSE( - std::is_nothrow_copy_constructible::value); + std::is_nothrow_copy_constructible_v); } TEST(move_traits) { - EXPECT_TRUE(std::is_move_assignable::value); - EXPECT_TRUE(std::is_move_constructible::value); - EXPECT_TRUE( - std::is_nothrow_move_assignable::value); + EXPECT_TRUE(std::is_move_assignable_v); + EXPECT_TRUE(std::is_move_constructible_v); + EXPECT_TRUE(std::is_nothrow_move_assignable_v); EXPECT_TRUE( - std::is_nothrow_move_constructible::value); + std::is_nothrow_move_constructible_v); } TEST(make_array_2_booleans) { @@ -94,6 +91,7 @@ TEST(make_array_1_array) { TEST(brace_initialization_from_integer_document) { const sourcemeta::core::JSON element{1}; + // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) const sourcemeta::core::JSON document{element}; EXPECT_FALSE(document.is_array()); @@ -104,6 +102,7 @@ TEST(brace_initialization_from_integer_document) { TEST(brace_initialization_from_array_document) { const auto element{sourcemeta::core::JSON::make_array( {sourcemeta::core::JSON{1}, sourcemeta::core::JSON{2}})}; + // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) const sourcemeta::core::JSON document{element}; EXPECT_TRUE(document.is_array()); @@ -404,13 +403,13 @@ TEST(erase_many_full_const) { TEST(contains_string_key_true) { const sourcemeta::core::JSON document = - sourcemeta::core::parse_json("[ \"foo\", \"bar\" ]"); + sourcemeta::core::parse_json(R"([ "foo", "bar" ])"); EXPECT_TRUE(document.contains(sourcemeta::core::JSON{"bar"})); } TEST(contains_string_key_false) { const sourcemeta::core::JSON document = - sourcemeta::core::parse_json("[ \"foo\", \"bar\" ]"); + sourcemeta::core::parse_json(R"([ "foo", "bar" ])"); EXPECT_FALSE(document.contains(sourcemeta::core::JSON{"baz"})); } @@ -456,7 +455,7 @@ TEST(contains_string_in_mixed_array) { TEST(defines_any_with_iterators_has_one) { const sourcemeta::core::JSON document = - sourcemeta::core::parse_json("{\"foo\":true,\"bar\":false,\"baz\":true}"); + sourcemeta::core::parse_json(R"({"foo":true,"bar":false,"baz":true})"); EXPECT_TRUE(document.is_object()); EXPECT_EQ(document.size(), 3); EXPECT_TRUE(document.defines("foo")); @@ -468,7 +467,7 @@ TEST(defines_any_with_iterators_has_one) { TEST(defines_any_with_iterators_has_two) { const sourcemeta::core::JSON document = - sourcemeta::core::parse_json("{\"foo\":true,\"bar\":false,\"baz\":true}"); + sourcemeta::core::parse_json(R"({"foo":true,"bar":false,"baz":true})"); EXPECT_TRUE(document.is_object()); EXPECT_EQ(document.size(), 3); const std::vector keys{"foo", "baz"}; @@ -477,7 +476,7 @@ TEST(defines_any_with_iterators_has_two) { TEST(defines_any_with_iterators_has_none) { const sourcemeta::core::JSON document = - sourcemeta::core::parse_json("{\"foo\":true,\"bar\":false,\"baz\":true}"); + sourcemeta::core::parse_json(R"({"foo":true,"bar":false,"baz":true})"); EXPECT_TRUE(document.is_object()); EXPECT_EQ(document.size(), 3); const std::vector keys{"qux", "test"}; @@ -486,7 +485,7 @@ TEST(defines_any_with_iterators_has_none) { TEST(defines_any_with_initializer_list_has_one) { const sourcemeta::core::JSON document = - sourcemeta::core::parse_json("{\"foo\":true,\"bar\":false,\"baz\":true}"); + sourcemeta::core::parse_json(R"({"foo":true,"bar":false,"baz":true})"); EXPECT_TRUE(document.is_object()); EXPECT_EQ(document.size(), 3); EXPECT_TRUE(document.defines_any({"foo", "qux"})); @@ -494,7 +493,7 @@ TEST(defines_any_with_initializer_list_has_one) { TEST(defines_any_with_initializer_list_has_two) { const sourcemeta::core::JSON document = - sourcemeta::core::parse_json("{\"foo\":true,\"bar\":false,\"baz\":true}"); + sourcemeta::core::parse_json(R"({"foo":true,"bar":false,"baz":true})"); EXPECT_TRUE(document.is_object()); EXPECT_EQ(document.size(), 3); EXPECT_TRUE(document.defines_any({"foo", "baz"})); @@ -502,7 +501,7 @@ TEST(defines_any_with_initializer_list_has_two) { TEST(defines_any_with_initializer_list_has_none) { const sourcemeta::core::JSON document = - sourcemeta::core::parse_json("{\"foo\":true,\"bar\":false,\"baz\":true}"); + sourcemeta::core::parse_json(R"({"foo":true,"bar":false,"baz":true})"); EXPECT_TRUE(document.is_object()); EXPECT_EQ(document.size(), 3); EXPECT_FALSE(document.defines_any({"qux", "test"})); diff --git a/test/json/json_auto_test.cc b/test/json/json_auto_test.cc index 38731d9f94..c78ebc011f 100644 --- a/test/json/json_auto_test.cc +++ b/test/json/json_auto_test.cc @@ -30,7 +30,7 @@ struct ClassWithCustomMethod { -> bool = default; }; -enum class SampleEnum { Foo = 0, Bar = 1, Baz = 2 }; +enum class SampleEnum : std::uint8_t { Foo = 0, Bar = 1, Baz = 2 }; TEST(class_with_custom_method) { const ClassWithCustomMethod value; @@ -65,7 +65,7 @@ TEST(json) { } TEST(from_constructor) { - const auto value{"foo bar"}; + const auto *const value{"foo bar"}; const auto result{sourcemeta::core::to_json(value)}; const sourcemeta::core::JSON expected{"foo bar"}; EXPECT_EQ(result, expected); diff --git a/test/json/json_decimal_test.cc b/test/json/json_decimal_test.cc index 4a0e3ac184..05b9300a08 100644 --- a/test/json/json_decimal_test.cc +++ b/test/json/json_decimal_test.cc @@ -31,6 +31,7 @@ TEST(zero) { TEST(copy_constructor_from_json) { const sourcemeta::core::Decimal value{123}; const sourcemeta::core::JSON decimal{value}; + // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) const sourcemeta::core::JSON document{decimal}; EXPECT_TRUE(document.is_decimal()); EXPECT_EQ(document.to_decimal().to_int64(), 123); @@ -152,6 +153,7 @@ TEST(copy_preserves_precision) { const sourcemeta::core::Decimal value{ "12345678901234567890.123456789012345678901234567890"}; const sourcemeta::core::JSON original{value}; + // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) const sourcemeta::core::JSON copy{original}; EXPECT_EQ(copy.to_decimal().to_string(), original.to_decimal().to_string()); } @@ -207,7 +209,9 @@ TEST(unsigned_integer_construction) { TEST(multiple_copies) { const sourcemeta::core::Decimal value{111}; const sourcemeta::core::JSON first{value}; + // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) const sourcemeta::core::JSON second{first}; + // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) const sourcemeta::core::JSON third{second}; EXPECT_TRUE(third.is_decimal()); EXPECT_EQ(third.to_decimal().to_int64(), 111); @@ -536,7 +540,7 @@ TEST(is_integral_zero_real) { TEST(construction_rejects_nan) { const sourcemeta::core::Decimal value{sourcemeta::core::Decimal::nan()}; try { - sourcemeta::core::JSON{value}; + const sourcemeta::core::JSON document{value}; FAIL(); } catch (const std::invalid_argument &error) { EXPECT_STREQ(error.what(), "JSON does not support Infinity or NaN"); @@ -546,7 +550,7 @@ TEST(construction_rejects_nan) { TEST(construction_rejects_positive_infinity) { const sourcemeta::core::Decimal value{sourcemeta::core::Decimal::infinity()}; try { - sourcemeta::core::JSON{value}; + const sourcemeta::core::JSON document{value}; FAIL(); } catch (const std::invalid_argument &error) { EXPECT_STREQ(error.what(), "JSON does not support Infinity or NaN"); @@ -557,7 +561,7 @@ TEST(construction_rejects_negative_infinity) { const sourcemeta::core::Decimal value{ sourcemeta::core::Decimal::negative_infinity()}; try { - sourcemeta::core::JSON{value}; + const sourcemeta::core::JSON document{value}; FAIL(); } catch (const std::invalid_argument &error) { EXPECT_STREQ(error.what(), "JSON does not support Infinity or NaN"); @@ -567,7 +571,7 @@ TEST(construction_rejects_negative_infinity) { TEST(construction_move_rejects_nan) { sourcemeta::core::Decimal value{sourcemeta::core::Decimal::nan()}; try { - sourcemeta::core::JSON{std::move(value)}; + const sourcemeta::core::JSON document{std::move(value)}; FAIL(); } catch (const std::invalid_argument &error) { EXPECT_STREQ(error.what(), "JSON does not support Infinity or NaN"); @@ -577,7 +581,7 @@ TEST(construction_move_rejects_nan) { TEST(construction_move_rejects_positive_infinity) { sourcemeta::core::Decimal value{sourcemeta::core::Decimal::infinity()}; try { - sourcemeta::core::JSON{std::move(value)}; + const sourcemeta::core::JSON document{std::move(value)}; FAIL(); } catch (const std::invalid_argument &error) { EXPECT_STREQ(error.what(), "JSON does not support Infinity or NaN"); @@ -588,7 +592,7 @@ TEST(construction_move_rejects_negative_infinity) { sourcemeta::core::Decimal value{ sourcemeta::core::Decimal::negative_infinity()}; try { - sourcemeta::core::JSON{std::move(value)}; + const sourcemeta::core::JSON document{std::move(value)}; FAIL(); } catch (const std::invalid_argument &error) { EXPECT_STREQ(error.what(), "JSON does not support Infinity or NaN"); @@ -598,7 +602,6 @@ TEST(construction_move_rejects_negative_infinity) { TEST(copy_constructor_cannot_create_invalid_json) { try { const sourcemeta::core::JSON source{sourcemeta::core::Decimal::nan()}; - const sourcemeta::core::JSON copy{source}; FAIL(); } catch (const std::invalid_argument &error) { EXPECT_STREQ(error.what(), "JSON does not support Infinity or NaN"); diff --git a/test/json/json_integer_test.cc b/test/json/json_integer_test.cc index 82005ba977..0cf83dbaac 100644 --- a/test/json/json_integer_test.cc +++ b/test/json/json_integer_test.cc @@ -31,6 +31,7 @@ TEST(zero) { // creating an array with a single integer item instead. TEST(copy_constructor) { const sourcemeta::core::JSON integer{5}; + // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) const sourcemeta::core::JSON document{integer}; EXPECT_TRUE(document.is_integer()); EXPECT_EQ(document.to_integer(), 5); diff --git a/test/json/json_object_test.cc b/test/json/json_object_test.cc index 53f181f98b..1dfc5e4bb6 100644 --- a/test/json/json_object_test.cc +++ b/test/json/json_object_test.cc @@ -12,31 +12,27 @@ #include TEST(general_traits) { + EXPECT_TRUE(std::is_default_constructible_v); EXPECT_TRUE( - std::is_default_constructible::value); - EXPECT_TRUE(std::is_nothrow_default_constructible< - sourcemeta::core::JSON::Object>::value); - EXPECT_TRUE(std::is_destructible::value); - EXPECT_TRUE( - std::is_nothrow_destructible::value); + std::is_nothrow_default_constructible_v); + EXPECT_TRUE(std::is_destructible_v); + EXPECT_TRUE(std::is_nothrow_destructible_v); } TEST(copy_traits) { - EXPECT_TRUE(std::is_copy_assignable::value); - EXPECT_TRUE( - std::is_copy_constructible::value); + EXPECT_TRUE(std::is_copy_assignable_v); + EXPECT_TRUE(std::is_copy_constructible_v); EXPECT_FALSE( - std::is_nothrow_copy_assignable::value); - EXPECT_FALSE(std::is_nothrow_copy_constructible< - sourcemeta::core::JSON::Object>::value); + std::is_nothrow_copy_assignable_v); + EXPECT_FALSE( + std::is_nothrow_copy_constructible_v); } TEST(move_traits) { - EXPECT_TRUE(std::is_move_assignable::value); - EXPECT_TRUE( - std::is_move_constructible::value); + EXPECT_TRUE(std::is_move_assignable_v); + EXPECT_TRUE(std::is_move_constructible_v); EXPECT_TRUE( - std::is_nothrow_move_assignable::value); + std::is_nothrow_move_assignable_v); } TEST(type) { @@ -295,7 +291,7 @@ TEST(key_move_assignment_different_type) { TEST(all_of_true) { sourcemeta::core::JSON document = - sourcemeta::core::parse_json("{ \"foo\": 1, \"bar\": 2 }"); + sourcemeta::core::parse_json(R"({ "foo": 1, "bar": 2 })"); const bool result = std::all_of(document.as_object().begin(), document.as_object().end(), [](auto &pair) { return pair.second.is_integer(); }); @@ -304,7 +300,7 @@ TEST(all_of_true) { TEST(all_of_with_key_true) { sourcemeta::core::JSON document = - sourcemeta::core::parse_json("{ \"foo\": 1, \"bar\": 2 }"); + sourcemeta::core::parse_json(R"({ "foo": 1, "bar": 2 })"); const bool result = std::all_of(document.as_object().begin(), document.as_object().end(), [](auto &pair) { return pair.first.size() > 2; }); @@ -313,7 +309,7 @@ TEST(all_of_with_key_true) { TEST(all_of_with_key_false) { sourcemeta::core::JSON document = - sourcemeta::core::parse_json("{ \"f\": 1, \"bar\": 2 }"); + sourcemeta::core::parse_json(R"({ "f": 1, "bar": 2 })"); const bool result = std::all_of(document.as_object().begin(), document.as_object().end(), [](auto &pair) { return pair.first.size() > 2; }); @@ -323,7 +319,7 @@ TEST(all_of_with_key_false) { TEST(const_object_iterator) { std::map result; const sourcemeta::core::JSON document = - sourcemeta::core::parse_json("{ \"foo\": 1, \"bar\": 2 }"); + sourcemeta::core::parse_json(R"({ "foo": 1, "bar": 2 })"); for (const auto &pair : document.as_object()) { result.insert({pair.first, pair.second.to_integer()}); } @@ -336,8 +332,8 @@ TEST(const_object_iterator) { TEST(iterator) { std::map result; sourcemeta::core::JSON document = - sourcemeta::core::parse_json("{ \"foo\": 1, \"bar\": 2 }"); - for (auto &pair : document.as_object()) { + sourcemeta::core::parse_json(R"({ "foo": 1, "bar": 2 })"); + for (const auto &pair : document.as_object()) { result.insert({pair.first, pair.second.to_integer()}); } @@ -357,7 +353,7 @@ TEST(into_object) { TEST(erase_with_initializer_list) { sourcemeta::core::JSON document = - sourcemeta::core::parse_json("{\"foo\":true,\"bar\":false,\"baz\":true}"); + sourcemeta::core::parse_json(R"({"foo":true,"bar":false,"baz":true})"); EXPECT_TRUE(document.is_object()); EXPECT_EQ(document.size(), 3); EXPECT_EQ(document.object_size(), 3); @@ -372,7 +368,7 @@ TEST(erase_with_initializer_list) { TEST(erase_with_vector_iterators) { sourcemeta::core::JSON document = - sourcemeta::core::parse_json("{\"foo\":true,\"bar\":false,\"baz\":true}"); + sourcemeta::core::parse_json(R"({"foo":true,"bar":false,"baz":true})"); EXPECT_TRUE(document.is_object()); EXPECT_EQ(document.size(), 3); EXPECT_EQ(document.object_size(), 3); @@ -388,7 +384,7 @@ TEST(erase_with_vector_iterators) { TEST(erase_non_existent) { sourcemeta::core::JSON document = - sourcemeta::core::parse_json("{\"foo\":true,\"bar\":false,\"baz\":true}"); + sourcemeta::core::parse_json(R"({"foo":true,"bar":false,"baz":true})"); EXPECT_TRUE(document.is_object()); EXPECT_EQ(document.size(), 3); EXPECT_EQ(document.object_size(), 3); @@ -486,7 +482,7 @@ TEST(long_key_move_assignment_hash_collision) { TEST(clear_except_one_key_initializer_list) { sourcemeta::core::JSON document = - sourcemeta::core::parse_json("{\"foo\":true,\"bar\":false}"); + sourcemeta::core::parse_json(R"({"foo":true,"bar":false})"); EXPECT_TRUE(document.is_object()); EXPECT_EQ(document.size(), 2); EXPECT_EQ(document.object_size(), 2); @@ -501,7 +497,7 @@ TEST(clear_except_one_key_initializer_list) { TEST(clear_except_extra_key_initializer_list) { sourcemeta::core::JSON document = - sourcemeta::core::parse_json("{\"foo\":true,\"bar\":false}"); + sourcemeta::core::parse_json(R"({"foo":true,"bar":false})"); EXPECT_TRUE(document.is_object()); EXPECT_EQ(document.size(), 2); EXPECT_EQ(document.object_size(), 2); @@ -513,7 +509,7 @@ TEST(clear_except_extra_key_initializer_list) { TEST(clear_except_multiple_intersection_initializer_list) { sourcemeta::core::JSON document = - sourcemeta::core::parse_json("{\"foo\":1,\"bar\":2,\"baz\":3,\"qux\":4}"); + sourcemeta::core::parse_json(R"({"foo":1,"bar":2,"baz":3,"qux":4})"); EXPECT_TRUE(document.is_object()); EXPECT_EQ(document.size(), 4); EXPECT_EQ(document.object_size(), 4); @@ -532,7 +528,7 @@ TEST(clear_except_multiple_intersection_initializer_list) { TEST(at_index_using_integer) { const sourcemeta::core::JSON document = - sourcemeta::core::parse_json("{\"0\":1,\"1\":2,\"2\":3}"); + sourcemeta::core::parse_json(R"({"0":1,"1":2,"2":3})"); EXPECT_TRUE(document.is_object()); EXPECT_EQ(document.size(), 3); EXPECT_EQ(document.object_size(), 3); @@ -549,7 +545,7 @@ TEST(at_index_using_integer) { TEST(at_index_using_integer_non_const) { sourcemeta::core::JSON document = - sourcemeta::core::parse_json("{\"0\":1,\"1\":2,\"2\":3}"); + sourcemeta::core::parse_json(R"({"0":1,"1":2,"2":3})"); EXPECT_TRUE(document.is_object()); EXPECT_EQ(document.size(), 3); EXPECT_EQ(document.object_size(), 3); @@ -566,7 +562,7 @@ TEST(at_index_using_integer_non_const) { TEST(defines_property_using_integer) { const sourcemeta::core::JSON document = - sourcemeta::core::parse_json("{\"0\":1,\"1\":2,\"2\":3}"); + sourcemeta::core::parse_json(R"({"0":1,"1":2,"2":3})"); EXPECT_TRUE(document.is_object()); EXPECT_EQ(document.size(), 3); EXPECT_EQ(document.object_size(), 3); @@ -746,25 +742,25 @@ TEST(assign_assume_new_rvalue_key_with_hash) { TEST(estimated_byte_size_integers) { const sourcemeta::core::JSON document = - sourcemeta::core::parse_json("{ \"foo\": 1, \"bar\": 2 }"); + sourcemeta::core::parse_json(R"({ "foo": 1, "bar": 2 })"); EXPECT_EQ(document.estimated_byte_size(), 22); } TEST(estimated_byte_size_nested) { - const sourcemeta::core::JSON document = sourcemeta::core::parse_json( - "{ \"foo\": 1, \"bar\": { \"bar\": true } }"); + const sourcemeta::core::JSON document = + sourcemeta::core::parse_json(R"({ "foo": 1, "bar": { "bar": true } })"); EXPECT_EQ(document.estimated_byte_size(), 18); } TEST(fast_hash_integers) { const sourcemeta::core::JSON document = - sourcemeta::core::parse_json("{ \"foo\": 1, \"bar\": 2 }"); + sourcemeta::core::parse_json(R"({ "foo": 1, "bar": 2 })"); EXPECT_EQ(document.fast_hash(), 26); } TEST(fast_hash_nested) { - const sourcemeta::core::JSON document = sourcemeta::core::parse_json( - "{ \"foo\": 1, \"bar\": { \"bar\": true } }"); + const sourcemeta::core::JSON document = + sourcemeta::core::parse_json(R"({ "foo": 1, "bar": { "bar": true } })"); EXPECT_EQ(document.fast_hash(), 32); } @@ -1233,7 +1229,7 @@ TEST(reorder_already_ordered) { TEST(try_at_start_hit) { const sourcemeta::core::JSON document = - sourcemeta::core::parse_json("{\"foo\":1,\"bar\":2,\"baz\":3}"); + sourcemeta::core::parse_json(R"({"foo":1,"bar":2,"baz":3})"); const auto &object{document.as_object()}; sourcemeta::core::JSON::Object::size_type start{0}; @@ -1258,7 +1254,7 @@ TEST(try_at_start_hit) { TEST(try_at_start_miss) { const sourcemeta::core::JSON document = - sourcemeta::core::parse_json("{\"foo\":1,\"bar\":2}"); + sourcemeta::core::parse_json(R"({"foo":1,"bar":2})"); const auto &object{document.as_object()}; sourcemeta::core::JSON::Object::size_type start{0}; @@ -1270,7 +1266,7 @@ TEST(try_at_start_miss) { TEST(try_at_start_reverse_order) { const sourcemeta::core::JSON document = - sourcemeta::core::parse_json("{\"foo\":1,\"bar\":2,\"baz\":3}"); + sourcemeta::core::parse_json(R"({"foo":1,"bar":2,"baz":3})"); const auto &object{document.as_object()}; sourcemeta::core::JSON::Object::size_type start{0}; @@ -1308,7 +1304,7 @@ TEST(try_at_start_single_property) { TEST(try_at_start_wraparound) { const sourcemeta::core::JSON document = - sourcemeta::core::parse_json("{\"foo\":1,\"bar\":2,\"baz\":3}"); + sourcemeta::core::parse_json(R"({"foo":1,"bar":2,"baz":3})"); const auto &object{document.as_object()}; sourcemeta::core::JSON::Object::size_type start{object.size()}; @@ -1321,7 +1317,7 @@ TEST(try_at_start_wraparound) { TEST(try_at_start_sequential_advances) { const sourcemeta::core::JSON document = - sourcemeta::core::parse_json("{\"a\":1,\"b\":2,\"c\":3,\"d\":4}"); + sourcemeta::core::parse_json(R"({"a":1,"b":2,"c":3,"d":4})"); const auto &object{document.as_object()}; sourcemeta::core::JSON::Object::size_type start{0}; @@ -1350,7 +1346,7 @@ TEST(try_at_start_sequential_advances) { TEST(defines_with_string_view) { const sourcemeta::core::JSON document = - sourcemeta::core::parse_json("{\"foo\":1,\"bar\":2}"); + sourcemeta::core::parse_json(R"({"foo":1,"bar":2})"); const std::string_view foo{"foo"}; const std::string_view bar{"bar"}; const std::string_view qux{"qux"}; @@ -1361,7 +1357,7 @@ TEST(defines_with_string_view) { TEST(defines_with_string_view_subview) { const sourcemeta::core::JSON document = - sourcemeta::core::parse_json("{\"foo\":1,\"bar\":2}"); + sourcemeta::core::parse_json(R"({"foo":1,"bar":2})"); const std::string buffer{"foobar"}; const std::string_view foo_view{buffer.data(), 3}; const std::string_view bar_view{buffer.data() + 3, 3}; @@ -1371,7 +1367,7 @@ TEST(defines_with_string_view_subview) { TEST(defines_with_string_view_and_hash) { const sourcemeta::core::JSON document = - sourcemeta::core::parse_json("{\"foo\":1,\"bar\":2}"); + sourcemeta::core::parse_json(R"({"foo":1,"bar":2})"); const auto &object{document.as_object()}; const std::string_view foo{"foo"}; const auto foo_hash{object.hash(foo)}; @@ -1380,7 +1376,7 @@ TEST(defines_with_string_view_and_hash) { TEST(at_const_with_string_view) { const sourcemeta::core::JSON document = - sourcemeta::core::parse_json("{\"foo\":1,\"bar\":2}"); + sourcemeta::core::parse_json(R"({"foo":1,"bar":2})"); const std::string_view foo{"foo"}; const std::string_view bar{"bar"}; EXPECT_EQ(document.at(foo).to_integer(), 1); @@ -1389,7 +1385,7 @@ TEST(at_const_with_string_view) { TEST(at_const_with_string_view_subview) { const sourcemeta::core::JSON document = - sourcemeta::core::parse_json("{\"foo\":1,\"bar\":2}"); + sourcemeta::core::parse_json(R"({"foo":1,"bar":2})"); const std::string buffer{"foobar"}; const std::string_view foo_view{buffer.data(), 3}; const std::string_view bar_view{buffer.data() + 3, 3}; @@ -1399,7 +1395,7 @@ TEST(at_const_with_string_view_subview) { TEST(at_mutable_with_string_view) { sourcemeta::core::JSON document = - sourcemeta::core::parse_json("{\"foo\":1,\"bar\":2}"); + sourcemeta::core::parse_json(R"({"foo":1,"bar":2})"); const std::string_view foo{"foo"}; document.at(foo) = sourcemeta::core::JSON{42}; EXPECT_EQ(document.at("foo").to_integer(), 42); @@ -1407,7 +1403,7 @@ TEST(at_mutable_with_string_view) { TEST(at_const_with_string_view_and_hash) { const sourcemeta::core::JSON document = - sourcemeta::core::parse_json("{\"foo\":1,\"bar\":2}"); + sourcemeta::core::parse_json(R"({"foo":1,"bar":2})"); const auto &object{document.as_object()}; const std::string_view foo{"foo"}; const auto foo_hash{object.hash(foo)}; @@ -1453,7 +1449,7 @@ TEST(assign_with_string_view_subview_key) { TEST(erase_with_string_view) { sourcemeta::core::JSON document = - sourcemeta::core::parse_json("{\"foo\":1,\"bar\":2}"); + sourcemeta::core::parse_json(R"({"foo":1,"bar":2})"); const std::string_view foo{"foo"}; document.erase(foo); EXPECT_FALSE(document.defines("foo")); @@ -1462,7 +1458,7 @@ TEST(erase_with_string_view) { TEST(erase_with_string_view_subview) { sourcemeta::core::JSON document = - sourcemeta::core::parse_json("{\"foo\":1,\"bar\":2}"); + sourcemeta::core::parse_json(R"({"foo":1,"bar":2})"); const std::string buffer{"foobar"}; const std::string_view foo_view{buffer.data(), 3}; document.erase(foo_view); diff --git a/test/json/json_parse_callback_test.cc b/test/json/json_parse_callback_test.cc index 6636617177..3242c8a197 100644 --- a/test/json/json_parse_callback_test.cc +++ b/test/json/json_parse_callback_test.cc @@ -60,70 +60,70 @@ EXPECT_EQ(std::get<6>(traces.at(index)), expected_property) TEST(true) { - const auto input{"true"}; + const auto *const input{"true"}; PARSE_WITH_TRACES(document, input, 2); EXPECT_TRACE(0, Pre, Boolean, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Post, Boolean, 1, 4, Root, 0, ""); } TEST(true_with_padding) { - const auto input{" true "}; + const auto *const input{" true "}; PARSE_WITH_TRACES(document, input, 2); EXPECT_TRACE(0, Pre, Boolean, 1, 3, Root, 0, ""); EXPECT_TRACE(1, Post, Boolean, 1, 6, Root, 0, ""); } TEST(false) { - const auto input{"false"}; + const auto *const input{"false"}; PARSE_WITH_TRACES(document, input, 2); EXPECT_TRACE(0, Pre, Boolean, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Post, Boolean, 1, 5, Root, 0, ""); } TEST(null) { - const auto input{"null"}; + const auto *const input{"null"}; PARSE_WITH_TRACES(document, input, 2); EXPECT_TRACE(0, Pre, Null, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Post, Null, 1, 4, Root, 0, ""); } TEST(empty_string) { - const auto input{"\"\""}; + const auto *const input{"\"\""}; PARSE_WITH_TRACES(document, input, 2); EXPECT_TRACE(0, Pre, String, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Post, String, 1, 2, Root, 0, ""); } TEST(non_empty_string) { - const auto input{"\"foo\""}; + const auto *const input{"\"foo\""}; PARSE_WITH_TRACES(document, input, 2); EXPECT_TRACE(0, Pre, String, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Post, String, 1, 5, Root, 0, ""); } TEST(integer) { - const auto input{"1234"}; + const auto *const input{"1234"}; PARSE_WITH_TRACES(document, input, 2); EXPECT_TRACE(0, Pre, Integer, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Post, Integer, 1, 4, Root, 0, ""); } TEST(real) { - const auto input{"3.5"}; + const auto *const input{"3.5"}; PARSE_WITH_TRACES(document, input, 2); EXPECT_TRACE(0, Pre, Real, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Post, Real, 1, 3, Root, 0, ""); } TEST(empty_array) { - const auto input{"[]"}; + const auto *const input{"[]"}; PARSE_WITH_TRACES(document, input, 2); EXPECT_TRACE(0, Pre, Array, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Post, Array, 1, 2, Root, 0, ""); } TEST(array_booleans) { - const auto input{"[\n true,\n false\n]"}; + const auto *const input{"[\n true,\n false\n]"}; PARSE_WITH_TRACES(document, input, 6); EXPECT_TRACE(0, Pre, Array, 1, 1, Root, 0, ""); @@ -135,7 +135,7 @@ TEST(array_booleans) { } TEST(array_nulls) { - const auto input{"[\n null,\n null\n]"}; + const auto *const input{"[\n null,\n null\n]"}; PARSE_WITH_TRACES(document, input, 6); EXPECT_TRACE(0, Pre, Array, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Pre, Null, 2, 3, Index, 0, ""); @@ -146,7 +146,7 @@ TEST(array_nulls) { } TEST(array_strings) { - const auto input{"[\n \"foo\",\n \"bar\"\n]"}; + const auto *const input{"[\n \"foo\",\n \"bar\"\n]"}; PARSE_WITH_TRACES(document, input, 6); EXPECT_TRACE(0, Pre, Array, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Pre, String, 2, 3, Index, 0, ""); @@ -157,7 +157,7 @@ TEST(array_strings) { } TEST(array_integers) { - const auto input{"[\n 1,\n 234\n]"}; + const auto *const input{"[\n 1,\n 234\n]"}; PARSE_WITH_TRACES(document, input, 6); EXPECT_TRACE(0, Pre, Array, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Pre, Integer, 2, 3, Index, 0, ""); @@ -168,7 +168,7 @@ TEST(array_integers) { } TEST(array_reals) { - const auto input{"[\n 1.0,\n 2.5\n]"}; + const auto *const input{"[\n 1.0,\n 2.5\n]"}; PARSE_WITH_TRACES(document, input, 6); EXPECT_TRACE(0, Pre, Array, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Pre, Real, 2, 3, Index, 0, ""); @@ -179,7 +179,7 @@ TEST(array_reals) { } TEST(array_empty_objects) { - const auto input{"[\n {},\n {}\n]"}; + const auto *const input{"[\n {},\n {}\n]"}; PARSE_WITH_TRACES(document, input, 6); EXPECT_TRACE(0, Pre, Array, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Pre, Object, 2, 3, Index, 0, ""); @@ -190,7 +190,7 @@ TEST(array_empty_objects) { } TEST(array_empty_arrays) { - const auto input{"[\n [],\n []\n]"}; + const auto *const input{"[\n [],\n []\n]"}; PARSE_WITH_TRACES(document, input, 6); EXPECT_TRACE(0, Pre, Array, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Pre, Array, 2, 3, Index, 0, ""); @@ -201,14 +201,14 @@ TEST(array_empty_arrays) { } TEST(empty_object) { - const auto input{"{}"}; + const auto *const input{"{}"}; PARSE_WITH_TRACES(document, input, 2); EXPECT_TRACE(0, Pre, Object, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Post, Object, 1, 2, Root, 0, ""); } TEST(object_booleans) { - const auto input{"{\n \"foo\": true,\n \"bar\": false\n}"}; + const auto *const input{"{\n \"foo\": true,\n \"bar\": false\n}"}; PARSE_WITH_TRACES(document, input, 6); EXPECT_TRACE(0, Pre, Object, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Pre, Boolean, 2, 3, Property, 0, "foo"); @@ -219,7 +219,7 @@ TEST(object_booleans) { } TEST(object_nulls) { - const auto input{"{\n \"foo\": null,\n \"bar\": null\n}"}; + const auto *const input{"{\n \"foo\": null,\n \"bar\": null\n}"}; PARSE_WITH_TRACES(document, input, 6); EXPECT_TRACE(0, Pre, Object, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Pre, Null, 2, 3, Property, 0, "foo"); @@ -230,7 +230,7 @@ TEST(object_nulls) { } TEST(object_strings) { - const auto input{"{\n \"foo\": \"baz\",\n \"bar\": \"qux\"\n}"}; + const auto *const input{"{\n \"foo\": \"baz\",\n \"bar\": \"qux\"\n}"}; PARSE_WITH_TRACES(document, input, 6); EXPECT_TRACE(0, Pre, Object, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Pre, String, 2, 3, Property, 0, "foo"); @@ -241,7 +241,7 @@ TEST(object_strings) { } TEST(object_integers) { - const auto input{"{\n \"foo\": 1,\n \"bar\": 234\n}"}; + const auto *const input{"{\n \"foo\": 1,\n \"bar\": 234\n}"}; PARSE_WITH_TRACES(document, input, 6); EXPECT_TRACE(0, Pre, Object, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Pre, Integer, 2, 3, Property, 0, "foo"); @@ -252,7 +252,7 @@ TEST(object_integers) { } TEST(object_reals) { - const auto input{"{\n \"foo\": 1.0,\n \"bar\": 2.5\n}"}; + const auto *const input{"{\n \"foo\": 1.0,\n \"bar\": 2.5\n}"}; PARSE_WITH_TRACES(document, input, 6); EXPECT_TRACE(0, Pre, Object, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Pre, Real, 2, 3, Property, 0, "foo"); @@ -263,7 +263,7 @@ TEST(object_reals) { } TEST(object_empty_arrays) { - const auto input{"{\n \"foo\": [],\n \"bar\": []\n}"}; + const auto *const input{"{\n \"foo\": [],\n \"bar\": []\n}"}; PARSE_WITH_TRACES(document, input, 6); EXPECT_TRACE(0, Pre, Object, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Pre, Array, 2, 3, Property, 0, "foo"); @@ -274,7 +274,7 @@ TEST(object_empty_arrays) { } TEST(object_empty_objects) { - const auto input{"{\n \"foo\": {},\n \"bar\": {}\n}"}; + const auto *const input{"{\n \"foo\": {},\n \"bar\": {}\n}"}; PARSE_WITH_TRACES(document, input, 6); EXPECT_TRACE(0, Pre, Object, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Pre, Object, 2, 3, Property, 0, "foo"); @@ -285,7 +285,7 @@ TEST(object_empty_objects) { } TEST(complex_1) { - const auto input{R"JSON([ + const auto *const input{R"JSON([ { "foo": { "bar": 3 @@ -314,21 +314,21 @@ TEST(read_json_stub_valid) { } TEST(decimal_simple) { - const auto input{"9223372036854776000"}; + const auto *const input{"9223372036854776000"}; PARSE_WITH_TRACES(document, input, 2); EXPECT_TRACE(0, Pre, Decimal, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Post, Decimal, 1, 19, Root, 0, ""); } TEST(decimal_negative) { - const auto input{"-9223372036854776000"}; + const auto *const input{"-9223372036854776000"}; PARSE_WITH_TRACES(document, input, 2); EXPECT_TRACE(0, Pre, Decimal, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Post, Decimal, 1, 20, Root, 0, ""); } TEST(decimal_in_array) { - const auto input{"[1, 9223372036854776000, 3]"}; + const auto *const input{"[1, 9223372036854776000, 3]"}; PARSE_WITH_TRACES(document, input, 8); EXPECT_TRACE(0, Pre, Array, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Pre, Integer, 1, 2, Index, 0, ""); @@ -341,7 +341,7 @@ TEST(decimal_in_array) { } TEST(decimal_in_object) { - const auto input{"{\"big\":9223372036854776000}"}; + const auto *const input{"{\"big\":9223372036854776000}"}; PARSE_WITH_TRACES(document, input, 4); EXPECT_TRACE(0, Pre, Object, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Pre, Decimal, 1, 2, Property, 0, "big"); @@ -350,7 +350,7 @@ TEST(decimal_in_object) { } TEST(decimals_mixed_in_object) { - const auto input{"{\"big\":9223372036854776000,\"small\":42}"}; + const auto *const input{R"({"big":9223372036854776000,"small":42})"}; PARSE_WITH_TRACES(document, input, 6); EXPECT_TRACE(0, Pre, Object, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Pre, Decimal, 1, 2, Property, 0, "big"); @@ -361,14 +361,15 @@ TEST(decimals_mixed_in_object) { } TEST(decimal_big_real) { - const auto input{"3.14159265358979323846264338327950288419716939937510"}; + const auto *const input{ + "3.14159265358979323846264338327950288419716939937510"}; PARSE_WITH_TRACES(document, input, 2); EXPECT_TRACE(0, Pre, Decimal, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Post, Decimal, 1, 52, Root, 0, ""); } TEST(nested_decimals) { - const auto input{"{\"data\":[{\"big_int\":9223372036854776000}]}"}; + const auto *const input{R"({"data":[{"big_int":9223372036854776000}]})"}; PARSE_WITH_TRACES(document, input, 8); EXPECT_TRACE(0, Pre, Object, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Pre, Array, 1, 2, Property, 0, "data"); diff --git a/test/json/json_parse_error_test.cc b/test/json/json_parse_error_test.cc index 17a577f226..cb499e2a2e 100644 --- a/test/json/json_parse_error_test.cc +++ b/test/json/json_parse_error_test.cc @@ -4,6 +4,10 @@ #include #include +#include +#include // std::string_view + +using namespace std::literals::string_view_literals; #define __EXPECT_PARSE_ERROR(input, expected_line, expected_column, \ expected_error, expected_message) \ @@ -262,12 +266,12 @@ TEST(object_key_without_value) { } TEST(object_key_without_value_after_valid_key) { - std::istringstream input{"{\"foo\": 1,\"bar\"}"}; + std::istringstream input{R"({"foo": 1,"bar"})"}; EXPECT_PARSE_ERROR(input, 1, 16); } TEST(object_trailing_comma_after_element) { - std::istringstream input{"{\"foo\": 1,\"bar\":0,}"}; + std::istringstream input{R"({"foo": 1,"bar":0,})"}; EXPECT_PARSE_ERROR(input, 1, 19); } @@ -317,17 +321,18 @@ TEST(string_only_quote) { } TEST(string_escaped_invalid) { - std::istringstream input{"\"foo\\xbar\""}; + std::istringstream input{R"("foo\xbar")"}; EXPECT_PARSE_ERROR(input, 1, 6); } TEST(string_escaped_incomplete) { - std::istringstream input{"\"foo\\\""}; + std::istringstream input{R"("foo\")"}; EXPECT_PARSE_ERROR(input, 1, 7); } TEST(string_invalid_control_characters) { - std::istringstream input00{"\"foo \u0000 bar\""}; + std::istringstream input00{std::string{"\"foo \x00" + " bar\""sv}}; std::istringstream input01{"\"foo \u0001 bar\""}; std::istringstream input02{"\"foo \u0002 bar\""}; std::istringstream input03{"\"foo \u0003 bar\""}; @@ -395,37 +400,37 @@ TEST(string_invalid_control_characters) { } TEST(string_invalid_code_point) { - std::istringstream input{"\"\\uXXXX\""}; + std::istringstream input{R"("\uXXXX")"}; EXPECT_PARSE_ERROR(input, 1, 4); } TEST(string_invalid_lowercase_code_point) { - std::istringstream input{"\"\\uqqqq\""}; + std::istringstream input{R"("\uqqqq")"}; EXPECT_PARSE_ERROR(input, 1, 4); } TEST(string_incomplete_code_point_0) { - std::istringstream input{"\"\\u\""}; + std::istringstream input{R"("\u")"}; EXPECT_PARSE_ERROR(input, 1, 4); } TEST(string_incomplete_code_point_1) { - std::istringstream input{"\"\\u6\""}; + std::istringstream input{R"("\u6")"}; EXPECT_PARSE_ERROR(input, 1, 5); } TEST(string_incomplete_code_point_2) { - std::istringstream input{"\"\\u2F\""}; + std::istringstream input{R"("\u2F")"}; EXPECT_PARSE_ERROR(input, 1, 6); } TEST(string_incomplete_code_point_3) { - std::istringstream input{"\"\\u02F\""}; + std::istringstream input{R"("\u02F")"}; EXPECT_PARSE_ERROR(input, 1, 7); } TEST(string_incomplete_code_point_space) { - std::istringstream input{"\"\\u0F 2F\""}; + std::istringstream input{R"("\u0F 2F")"}; EXPECT_PARSE_ERROR(input, 1, 6); } diff --git a/test/json/json_parse_test.cc b/test/json/json_parse_test.cc index 427566e35c..a1f39c71fd 100644 --- a/test/json/json_parse_test.cc +++ b/test/json/json_parse_test.cc @@ -100,7 +100,7 @@ TEST(string_empty) { } TEST(string_with_null) { - std::istringstream input{"\"foo \\u0000 bar\""}; + std::istringstream input{R"("foo \u0000 bar")"}; const sourcemeta::core::JSON document = sourcemeta::core::parse_json(input); EXPECT_TRUE(document.is_string()); EXPECT_EQ(document.size(), 9); @@ -139,7 +139,7 @@ TEST(string_foo_padded) { } TEST(string_escape_quote) { - std::istringstream input{"\"foo\\\"bar\""}; + std::istringstream input{R"("foo\"bar")"}; const sourcemeta::core::JSON document = sourcemeta::core::parse_json(input); EXPECT_TRUE(document.is_string()); EXPECT_EQ(document.size(), 7); @@ -245,7 +245,7 @@ TEST(array_false_true_false) { } TEST(array_foo_bar_baz) { - std::istringstream input{"[\"foo\",\"bar\",\"baz\"]"}; + std::istringstream input{R"(["foo","bar","baz"])"}; const sourcemeta::core::JSON document = sourcemeta::core::parse_json(input); EXPECT_TRUE(document.is_array()); EXPECT_EQ(document.size(), 3); @@ -442,7 +442,7 @@ TEST(object_single_null_with_spaces) { } TEST(object_multiple_null) { - std::istringstream input{"{\"foo\":null,\"bar\":null,\"baz\":null}"}; + std::istringstream input{R"({"foo":null,"bar":null,"baz":null})"}; const sourcemeta::core::JSON document = sourcemeta::core::parse_json(input); EXPECT_TRUE(document.is_object()); EXPECT_EQ(document.size(), 3); @@ -465,7 +465,7 @@ TEST(array_with_object_size_1) { } TEST(array_with_object_size_2) { - std::istringstream input{"[ { \"foo\": false, \"bar\": true } ]"}; + std::istringstream input{R"([ { "foo": false, "bar": true } ])"}; const sourcemeta::core::JSON document = sourcemeta::core::parse_json(input); EXPECT_TRUE(document.is_array()); EXPECT_EQ(document.size(), 1); @@ -489,7 +489,7 @@ TEST(array_with_empty_object) { } TEST(array_escaped_quote_within_string_element) { - std::istringstream input{"[\"foo\\\"bar\"]"}; + std::istringstream input{R"(["foo\"bar"])"}; const sourcemeta::core::JSON document = sourcemeta::core::parse_json(input); EXPECT_TRUE(document.is_array()); EXPECT_EQ(document.size(), 1); @@ -523,7 +523,7 @@ TEST(object_with_array_two_elements) { } TEST(object_with_object) { - std::istringstream input{"{ \"foo\": { \"bar\": null } }"}; + std::istringstream input{R"({ "foo": { "bar": null } })"}; const sourcemeta::core::JSON document = sourcemeta::core::parse_json(input); EXPECT_TRUE(document.is_object()); EXPECT_EQ(document.size(), 1); @@ -559,7 +559,7 @@ TEST(empty_object_with_spacing) { } TEST(object_string_value_with_comma) { - std::istringstream input{"{\"foo\":\"bar,baz\"}"}; + std::istringstream input{R"({"foo":"bar,baz"})"}; const sourcemeta::core::JSON document = sourcemeta::core::parse_json(input); EXPECT_TRUE(document.is_object()); EXPECT_EQ(document.size(), 1); @@ -569,7 +569,7 @@ TEST(object_string_value_with_comma) { } TEST(object_string_value_with_escaped_quote) { - std::istringstream input{"{\"foo\":\"bar\\\"baz\"}"}; + std::istringstream input{R"({"foo":"bar\"baz"})"}; const sourcemeta::core::JSON document = sourcemeta::core::parse_json(input); EXPECT_TRUE(document.is_object()); EXPECT_EQ(document.size(), 1); @@ -579,7 +579,7 @@ TEST(object_string_value_with_escaped_quote) { } TEST(object_empty_string_key) { - std::istringstream input{"{\"\":\"foo\"}"}; + std::istringstream input{R"({"":"foo"})"}; const sourcemeta::core::JSON document = sourcemeta::core::parse_json(input); EXPECT_TRUE(document.is_object()); EXPECT_EQ(document.size(), 1); @@ -589,7 +589,7 @@ TEST(object_empty_string_key) { } TEST(object_string_key_with_comma) { - std::istringstream input{"{\"foo,bar\":\"baz\"}"}; + std::istringstream input{R"({"foo,bar":"baz"})"}; const sourcemeta::core::JSON document = sourcemeta::core::parse_json(input); EXPECT_TRUE(document.is_object()); EXPECT_EQ(document.size(), 1); @@ -599,7 +599,7 @@ TEST(object_string_key_with_comma) { } TEST(object_string_key_with_space) { - std::istringstream input{"{\"foo bar\":\"baz\"}"}; + std::istringstream input{R"({"foo bar":"baz"})"}; const sourcemeta::core::JSON document = sourcemeta::core::parse_json(input); EXPECT_TRUE(document.is_object()); EXPECT_EQ(document.size(), 1); @@ -609,7 +609,7 @@ TEST(object_string_key_with_space) { } TEST(object_string_value_with_stringified) { - std::istringstream input{"{\"foo\":\"{\\\"x\\\":1}\"}"}; + std::istringstream input{R"({"foo":"{\"x\":1}"})"}; const sourcemeta::core::JSON document = sourcemeta::core::parse_json(input); EXPECT_TRUE(document.is_object()); EXPECT_EQ(document.size(), 1); @@ -630,7 +630,7 @@ TEST(object_one_true_boolean_element_with_space) { TEST(object_two_boolean_values_with_space) { std::istringstream input{ - "{ \"foo\" : true , \"bar\" : false}"}; + R"({ "foo" : true , "bar" : false})"}; const sourcemeta::core::JSON document = sourcemeta::core::parse_json(input); EXPECT_TRUE(document.is_object()); EXPECT_EQ(document.size(), 2); @@ -657,7 +657,7 @@ TEST(object_one_array_element_with_space) { } TEST(object_minified_nested) { - std::istringstream input{"{\"foo\":{\"bar\":true}}"}; + std::istringstream input{R"({"foo":{"bar":true}})"}; const sourcemeta::core::JSON document = sourcemeta::core::parse_json(input); EXPECT_TRUE(document.is_object()); EXPECT_EQ(document.size(), 1); @@ -1065,7 +1065,7 @@ TEST(integer_real_equal) { } TEST(string_escaped_quotes) { - std::istringstream input{"\"\\\"foo\\\"\""}; + std::istringstream input{R"("\"foo\"")"}; const sourcemeta::core::JSON document = sourcemeta::core::parse_json(input); EXPECT_TRUE(document.is_string()); EXPECT_EQ(document.size(), 5); @@ -1073,7 +1073,7 @@ TEST(string_escaped_quotes) { } TEST(string_escaped_reverse_solidus) { - std::istringstream input{"\"foo\\\\bar\""}; + std::istringstream input{R"("foo\\bar")"}; const sourcemeta::core::JSON document = sourcemeta::core::parse_json(input); EXPECT_TRUE(document.is_string()); EXPECT_EQ(document.size(), 7); @@ -1081,7 +1081,7 @@ TEST(string_escaped_reverse_solidus) { } TEST(string_escaped_solidus) { - std::istringstream input{"\"foo\\/bar\""}; + std::istringstream input{R"("foo\/bar")"}; const sourcemeta::core::JSON document = sourcemeta::core::parse_json(input); EXPECT_TRUE(document.is_string()); EXPECT_EQ(document.size(), 7); @@ -1089,7 +1089,7 @@ TEST(string_escaped_solidus) { } TEST(string_escaped_backspace) { - std::istringstream input{"\"foo\\bbar\""}; + std::istringstream input{R"("foo\bbar")"}; const sourcemeta::core::JSON document = sourcemeta::core::parse_json(input); EXPECT_TRUE(document.is_string()); EXPECT_EQ(document.size(), 7); @@ -1097,7 +1097,7 @@ TEST(string_escaped_backspace) { } TEST(string_escaped_form_feed) { - std::istringstream input{"\"foo\\fbar\""}; + std::istringstream input{R"("foo\fbar")"}; const sourcemeta::core::JSON document = sourcemeta::core::parse_json(input); EXPECT_TRUE(document.is_string()); EXPECT_EQ(document.size(), 7); @@ -1105,7 +1105,7 @@ TEST(string_escaped_form_feed) { } TEST(string_escaped_line_feed) { - std::istringstream input{"\"foo\\nbar\""}; + std::istringstream input{R"("foo\nbar")"}; const sourcemeta::core::JSON document = sourcemeta::core::parse_json(input); EXPECT_TRUE(document.is_string()); EXPECT_EQ(document.size(), 7); @@ -1113,7 +1113,7 @@ TEST(string_escaped_line_feed) { } TEST(string_escaped_carriage_return) { - std::istringstream input{"\"foo\\rbar\""}; + std::istringstream input{R"("foo\rbar")"}; const sourcemeta::core::JSON document = sourcemeta::core::parse_json(input); EXPECT_TRUE(document.is_string()); EXPECT_EQ(document.size(), 7); @@ -1121,7 +1121,7 @@ TEST(string_escaped_carriage_return) { } TEST(string_escaped_tab) { - std::istringstream input{"\"foo\\tbar\""}; + std::istringstream input{R"("foo\tbar")"}; const sourcemeta::core::JSON document = sourcemeta::core::parse_json(input); EXPECT_TRUE(document.is_string()); EXPECT_EQ(document.size(), 7); @@ -1129,7 +1129,7 @@ TEST(string_escaped_tab) { } TEST(string_unicode_code_points) { - std::istringstream input{"\"\\u002F\""}; + std::istringstream input{R"("\u002F")"}; const sourcemeta::core::JSON document = sourcemeta::core::parse_json(input); EXPECT_TRUE(document.is_string()); EXPECT_EQ(document.size(), 1); @@ -1140,7 +1140,7 @@ TEST(string_unicode_length_surrogates) { // See https://en.wikipedia.org/wiki/UTF-8#Surrogates // https://unicodeplus.com/U+D83D // https://unicodeplus.com/U+DCA9 - std::istringstream input{"\"\\uD83D\\uDCA9\""}; + std::istringstream input{R"("\uD83D\uDCA9")"}; const sourcemeta::core::JSON document = sourcemeta::core::parse_json(input); EXPECT_TRUE(document.is_string()); EXPECT_EQ(document.size(), 1); @@ -1148,9 +1148,9 @@ TEST(string_unicode_length_surrogates) { } TEST(string_unicode_code_point_equality) { - std::istringstream input_1{"\"\\u002F\""}; - std::istringstream input_2{"\"\\u002f\""}; - std::istringstream input_3{"\"\\/\""}; + std::istringstream input_1{R"("\u002F")"}; + std::istringstream input_2{R"("\u002f")"}; + std::istringstream input_3{R"("\/")"}; std::istringstream input_4{"\"/\""}; const sourcemeta::core::JSON document_1 = @@ -1466,7 +1466,7 @@ TEST(big_integer_in_array) { } TEST(big_integer_in_object) { - std::istringstream input{"{\"big\":9223372036854776000,\"small\":42}"}; + std::istringstream input{R"({"big":9223372036854776000,"small":42})"}; const sourcemeta::core::JSON document = sourcemeta::core::parse_json(input); EXPECT_TRUE(document.is_object()); EXPECT_EQ(document.size(), 2); diff --git a/test/json/json_prettify_test.cc b/test/json/json_prettify_test.cc index 2a7c25ba1a..509495aa23 100644 --- a/test/json/json_prettify_test.cc +++ b/test/json/json_prettify_test.cc @@ -140,7 +140,7 @@ TEST(array_strings_almost_long_with_indentation) { std::ostringstream stream; sourcemeta::core::prettify(document, stream); - const auto expected = R"JSON({ + const auto *const expected = R"JSON({ "1": { "2": { "3": { @@ -180,7 +180,7 @@ TEST(array_strings_almost_long_with_long_property) { std::ostringstream stream; sourcemeta::core::prettify(document, stream); - const auto expected = R"JSON({ + const auto *const expected = R"JSON({ "longlonglonglonglonglonglonglonglonglong": [ "aaaaaaaaaa", "bbbbbbbbbb", diff --git a/test/json/json_real_test.cc b/test/json/json_real_test.cc index 373d04a101..86039695be 100644 --- a/test/json/json_real_test.cc +++ b/test/json/json_real_test.cc @@ -30,7 +30,7 @@ TEST(type) { TEST(long_double_nan) { const double value{static_cast(NAN)}; try { - sourcemeta::core::JSON{value}; + const sourcemeta::core::JSON document{value}; FAIL(); } catch (const std::invalid_argument &error) { EXPECT_STREQ(error.what(), "JSON does not support Infinity or NaN"); @@ -40,7 +40,7 @@ TEST(long_double_nan) { TEST(double_nan) { const double value{static_cast(NAN)}; try { - sourcemeta::core::JSON{value}; + const sourcemeta::core::JSON document{value}; FAIL(); } catch (const std::invalid_argument &error) { EXPECT_STREQ(error.what(), "JSON does not support Infinity or NaN"); @@ -50,7 +50,7 @@ TEST(double_nan) { TEST(float_nan) { const float value{NAN}; try { - sourcemeta::core::JSON{value}; + const sourcemeta::core::JSON document{value}; FAIL(); } catch (const std::invalid_argument &error) { EXPECT_STREQ(error.what(), "JSON does not support Infinity or NaN"); @@ -60,7 +60,7 @@ TEST(float_nan) { TEST(long_double_infinity) { const double value{std::numeric_limits::infinity()}; try { - sourcemeta::core::JSON{value}; + const sourcemeta::core::JSON document{value}; FAIL(); } catch (const std::invalid_argument &error) { EXPECT_STREQ(error.what(), "JSON does not support Infinity or NaN"); @@ -70,7 +70,7 @@ TEST(long_double_infinity) { TEST(double_infinity) { const double value{std::numeric_limits::infinity()}; try { - sourcemeta::core::JSON{value}; + const sourcemeta::core::JSON document{value}; FAIL(); } catch (const std::invalid_argument &error) { EXPECT_STREQ(error.what(), "JSON does not support Infinity or NaN"); @@ -80,7 +80,7 @@ TEST(double_infinity) { TEST(float_infinity) { const float value{std::numeric_limits::infinity()}; try { - sourcemeta::core::JSON{value}; + const sourcemeta::core::JSON document{value}; FAIL(); } catch (const std::invalid_argument &error) { EXPECT_STREQ(error.what(), "JSON does not support Infinity or NaN"); @@ -91,6 +91,7 @@ TEST(copy_constructor_cannot_create_invalid_json) { try { const sourcemeta::core::JSON source{ std::numeric_limits::quiet_NaN()}; + // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) const sourcemeta::core::JSON copy{source}; FAIL(); } catch (const std::invalid_argument &error) { diff --git a/test/json/json_stringify_test.cc b/test/json/json_stringify_test.cc index f491bc840d..dd54721987 100644 --- a/test/json/json_stringify_test.cc +++ b/test/json/json_stringify_test.cc @@ -170,8 +170,8 @@ TEST(object_integers) { std::ostringstream stream; sourcemeta::core::stringify(document, stream); // Because order is irrelevant - const bool matches = stream.str() == "{\"foo\":1,\"bar\":2}" || - stream.str() == "{\"bar\":2,\"foo\":1}"; + const bool matches = stream.str() == R"({"foo":1,"bar":2})" || + stream.str() == R"({"bar":2,"foo":1})"; EXPECT_TRUE(matches); } @@ -652,8 +652,8 @@ TEST(decimal_in_object) { std::ostringstream stream; sourcemeta::core::stringify(document, stream); const bool matches = - stream.str() == "{\"integer\":1.2345e+4,\"fractional\":-6.789e+1}" || - stream.str() == "{\"fractional\":-6.789e+1,\"integer\":1.2345e+4}"; + stream.str() == R"({"integer":1.2345e+4,"fractional":-6.789e+1})" || + stream.str() == R"({"fractional":-6.789e+1,"integer":1.2345e+4})"; EXPECT_TRUE(matches); } diff --git a/test/json/json_type_test.cc b/test/json/json_type_test.cc index 622977c388..de7741255f 100644 --- a/test/json/json_type_test.cc +++ b/test/json/json_type_test.cc @@ -109,23 +109,23 @@ TEST(make_set_no_intersection) { } TEST(make_set_constexpr) { - constexpr auto types = + constexpr auto TYPES = sourcemeta::core::make_set({sourcemeta::core::JSON::Type::Integer, sourcemeta::core::JSON::Type::Real}); - static_assert(types.test( + static_assert(TYPES.test( static_cast(sourcemeta::core::JSON::Type::Integer))); static_assert( - types.test(static_cast(sourcemeta::core::JSON::Type::Real))); - static_assert(!types.test( + TYPES.test(static_cast(sourcemeta::core::JSON::Type::Real))); + static_assert(!TYPES.test( static_cast(sourcemeta::core::JSON::Type::String))); - static_assert(!types.test( + static_assert(!TYPES.test( static_cast(sourcemeta::core::JSON::Type::Object))); - EXPECT_TRUE(types.test( + EXPECT_TRUE(TYPES.test( static_cast(sourcemeta::core::JSON::Type::Integer))); EXPECT_TRUE( - types.test(static_cast(sourcemeta::core::JSON::Type::Real))); - EXPECT_FALSE(types.test( + TYPES.test(static_cast(sourcemeta::core::JSON::Type::Real))); + EXPECT_FALSE(TYPES.test( static_cast(sourcemeta::core::JSON::Type::String))); - EXPECT_FALSE(types.test( + EXPECT_FALSE(TYPES.test( static_cast(sourcemeta::core::JSON::Type::Object))); } diff --git a/test/json/json_value_test.cc b/test/json/json_value_test.cc index 4479ed2ded..eaea7a62cc 100644 --- a/test/json/json_value_test.cc +++ b/test/json/json_value_test.cc @@ -13,9 +13,9 @@ #include // std::move TEST(general_traits) { - EXPECT_FALSE(std::is_default_constructible::value); - EXPECT_TRUE(std::is_destructible::value); - EXPECT_TRUE(std::is_nothrow_destructible::value); + EXPECT_FALSE(std::is_default_constructible_v); + EXPECT_TRUE(std::is_destructible_v); + EXPECT_TRUE(std::is_nothrow_destructible_v); } // BIG WARNING! Increase this number will make projects like Blaze slower, @@ -28,16 +28,15 @@ TEST(size) { } TEST(copy_traits) { - EXPECT_TRUE(std::is_copy_assignable::value); - EXPECT_TRUE(std::is_copy_constructible::value); - EXPECT_FALSE(std::is_nothrow_copy_assignable::value); - EXPECT_FALSE( - std::is_nothrow_copy_constructible::value); + EXPECT_TRUE(std::is_copy_assignable_v); + EXPECT_TRUE(std::is_copy_constructible_v); + EXPECT_FALSE(std::is_nothrow_copy_assignable_v); + EXPECT_FALSE(std::is_nothrow_copy_constructible_v); } TEST(move_traits) { - EXPECT_TRUE(std::is_move_assignable::value); - EXPECT_TRUE(std::is_move_constructible::value); + EXPECT_TRUE(std::is_move_assignable_v); + EXPECT_TRUE(std::is_move_constructible_v); } TEST(copy_equivalence_assignment) { @@ -227,7 +226,7 @@ TEST(compare_object_object_different) { const sourcemeta::core::JSON left = sourcemeta::core::parse_json("{\"foo\":1}"); const sourcemeta::core::JSON right = - sourcemeta::core::parse_json("{\"foo\":1, \"bar\":2}"); + sourcemeta::core::parse_json(R"({"foo":1, "bar":2})"); EXPECT_TRUE(left < right); EXPECT_FALSE(right < left); } @@ -389,7 +388,7 @@ TEST(try_at) { const sourcemeta::core::JSON document = sourcemeta::core::parse_json("{\"foo\":5}"); EXPECT_TRUE(document.is_object()); - const auto result = document.try_at("foo"); + const auto *const result = document.try_at("foo"); EXPECT_TRUE(result); EXPECT_EQ(result->to_integer(), 5); } @@ -398,14 +397,14 @@ TEST(try_at_fail) { const sourcemeta::core::JSON document = sourcemeta::core::parse_json("{\"foo\":5}"); EXPECT_TRUE(document.is_object()); - const auto result = document.try_at("boo"); + const auto *const result = document.try_at("boo"); EXPECT_FALSE(result); } TEST(try_at_mutable) { sourcemeta::core::JSON document = sourcemeta::core::parse_json("{\"foo\":5}"); EXPECT_TRUE(document.is_object()); - const auto result = document.try_at("foo"); + auto *const result = document.try_at("foo"); EXPECT_TRUE(result); EXPECT_EQ(result->to_integer(), 5); result->into(sourcemeta::core::JSON{7}); @@ -415,7 +414,7 @@ TEST(try_at_mutable) { TEST(try_at_mutable_fail) { sourcemeta::core::JSON document = sourcemeta::core::parse_json("{\"foo\":5}"); EXPECT_TRUE(document.is_object()); - const auto result = document.try_at("boo"); + auto *const result = document.try_at("boo"); EXPECT_FALSE(result); } @@ -423,7 +422,7 @@ TEST(try_at_mutable_string_view) { sourcemeta::core::JSON document = sourcemeta::core::parse_json("{\"foo\":5}"); EXPECT_TRUE(document.is_object()); const sourcemeta::core::JSON::StringView key{"foo"}; - const auto result = document.try_at(key); + auto *const result = document.try_at(key); EXPECT_TRUE(result); EXPECT_EQ(result->to_integer(), 5); result->into(sourcemeta::core::JSON{7}); @@ -433,7 +432,7 @@ TEST(try_at_mutable_string_view) { TEST(try_at_mutable_with_hash) { sourcemeta::core::JSON document = sourcemeta::core::parse_json("{\"foo\":5}"); EXPECT_TRUE(document.is_object()); - const auto result = document.try_at("foo", document.as_object().hash("foo")); + auto *const result = document.try_at("foo", document.as_object().hash("foo")); EXPECT_TRUE(result); EXPECT_EQ(result->to_integer(), 5); result->into(sourcemeta::core::JSON{7}); @@ -443,7 +442,7 @@ TEST(try_at_mutable_with_hash) { TEST(try_at_mutable_with_hash_fail) { sourcemeta::core::JSON document = sourcemeta::core::parse_json("{\"foo\":5}"); EXPECT_TRUE(document.is_object()); - const auto result = document.try_at("boo", document.as_object().hash("boo")); + auto *const result = document.try_at("boo", document.as_object().hash("boo")); EXPECT_FALSE(result); } @@ -451,7 +450,7 @@ TEST(try_at_mutable_string_view_with_hash) { sourcemeta::core::JSON document = sourcemeta::core::parse_json("{\"foo\":5}"); EXPECT_TRUE(document.is_object()); const sourcemeta::core::JSON::StringView key{"foo"}; - const auto result = document.try_at(key, document.as_object().hash(key)); + auto *const result = document.try_at(key, document.as_object().hash(key)); EXPECT_TRUE(result); EXPECT_EQ(result->to_integer(), 5); result->into(sourcemeta::core::JSON{7}); @@ -700,7 +699,8 @@ TEST(copies_deeply_nested_array_without_stack_overflow) { deep.push_back('0'); deep.append(DEPTH, ']'); auto document = sourcemeta::core::parse_json(deep); - auto copy = document; + // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) + const auto copy = document; EXPECT_TRUE(copy.is_array()); } @@ -714,7 +714,8 @@ TEST(copies_deeply_nested_object_without_stack_overflow) { deep.push_back('0'); deep.append(DEPTH, '}'); auto document = sourcemeta::core::parse_json(deep); - auto copy = document; + // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) + const auto copy = document; EXPECT_TRUE(copy.is_object()); } @@ -784,7 +785,8 @@ TEST(direct_list_inits_deeply_nested_array_without_stack_overflow) { deep.push_back('0'); deep.append(DEPTH, ']'); auto source = sourcemeta::core::parse_json(deep); - sourcemeta::core::JSON copy{source}; + // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) + const sourcemeta::core::JSON copy{source}; EXPECT_TRUE(copy.is_array()); } @@ -841,6 +843,7 @@ TEST(copy_assign_decimal_over_object) { TEST(deep_copy_of_a_nested_object) { const auto document{sourcemeta::core::parse_json( R"JSON([ { "a": { "b": [ 1, 2 ] } }, 3 ])JSON")}; + // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) const sourcemeta::core::JSON copy{document}; EXPECT_EQ(copy, document); EXPECT_EQ(copy.at(0).at("a").at("b").at(1).to_integer(), 2); @@ -893,6 +896,7 @@ TEST(real_below_int64_range_throws_on_as_integer) { static_cast(value.as_integer()); FAIL(); } catch (const std::out_of_range &) { + // Refusing the out of range value is expected } } diff --git a/test/json/jsontestsuite.cc b/test/json/jsontestsuite.cc index 70e9130a07..e1391a70a3 100644 --- a/test/json/jsontestsuite.cc +++ b/test/json/jsontestsuite.cc @@ -1,13 +1,14 @@ #include #include +#include // std::uint8_t #include // std::filesystem #include // std::ifstream #include // std::ios::binary, std::ios_base::badbit #include // std::string, std::char_traits namespace { -enum class JSONTestType { Accept, Reject }; +enum class JSONTestType : std::uint8_t { Accept, Reject }; auto run_json_test_case(const std::filesystem::path &path, const JSONTestType type) -> void { @@ -48,7 +49,7 @@ auto main(int argc, char **argv) -> int { std::filesystem::path{JSONTESTSUITE_PATH} / "test_parsing"}; for (const std::filesystem::directory_entry &entry : std::filesystem::directory_iterator{test_parsing_path}) { - const std::filesystem::path test_path{entry.path()}; + const std::filesystem::path &test_path{entry.path()}; const char front{test_path.filename().string().front()}; const JSONTestType type{front == 'n' || front == 'i' ? JSONTestType::Reject diff --git a/test/jsonld/jsonld_materialize_test.cc b/test/jsonld/jsonld_materialize_test.cc index bee8d192ce..7e9c92b5cc 100644 --- a/test/jsonld/jsonld_materialize_test.cc +++ b/test/jsonld/jsonld_materialize_test.cc @@ -15,10 +15,11 @@ TEST(node_with_literal_property) { sourcemeta::core::JSONLDDescriptor{.edges = {}, .value = sourcemeta::core::JSONLDNode{ .id = "https://example.com/org"}}); - annotations.emplace_back(sourcemeta::core::Pointer{"name"}, - sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/name", false}}, - .value = sourcemeta::core::JSONLDLiteral{}}); + annotations.emplace_back( + sourcemeta::core::Pointer{"name"}, + sourcemeta::core::JSONLDDescriptor{ + .edges = {{.predicate = "https://schema.org/name"}}, + .value = sourcemeta::core::JSONLDLiteral{}}); const auto expected = sourcemeta::core::parse_json(R"([ { @@ -46,7 +47,7 @@ TEST(literal_with_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"isbn"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/isbn", false}}, + .edges = {{.predicate = "https://schema.org/isbn"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#string"}}); @@ -80,7 +81,7 @@ TEST(literal_with_language_and_direction) { annotations.emplace_back( sourcemeta::core::Pointer{"title"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/name", false}}, + .edges = {{.predicate = "https://schema.org/name"}}, .value = sourcemeta::core::JSONLDLiteral{ .language = "ar", .direction = sourcemeta::core::JSONLDDirection::RTL}}); @@ -113,7 +114,7 @@ TEST(reference_property) { annotations.emplace_back( sourcemeta::core::Pointer{"currency"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/priceCurrency", false}}, + .edges = {{.predicate = "https://schema.org/priceCurrency"}}, .value = sourcemeta::core::JSONLDReference{ .id = "https://www.iso.org/iso-4217/USD", .types = {"https://schema.org/Currency"}}}); @@ -149,7 +150,7 @@ TEST(ordered_collection_becomes_list) { annotations.emplace_back( sourcemeta::core::Pointer{"authors"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/author", false}}, + .edges = {{.predicate = "https://schema.org/author"}}, .value = sourcemeta::core::JSONLDCollection{ .container = sourcemeta::core::JSONLDContainer::List}}); annotations.emplace_back( @@ -198,7 +199,7 @@ TEST(unordered_collection_spreads_into_property) { annotations.emplace_back( sourcemeta::core::Pointer{"tags"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/keywords", false}}, + .edges = {{.predicate = "https://schema.org/keywords"}}, .value = sourcemeta::core::JSONLDCollection{ .container = sourcemeta::core::JSONLDContainer::Set}}); annotations.emplace_back( @@ -235,8 +236,9 @@ TEST(field_with_multiple_predicates) { annotations.emplace_back( sourcemeta::core::Pointer{"label"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/name", false}, - {"http://www.w3.org/2000/01/rdf-schema#label", false}}, + .edges = {{.predicate = "https://schema.org/name"}, + {.predicate = + "http://www.w3.org/2000/01/rdf-schema#label"}}, .value = sourcemeta::core::JSONLDLiteral{}}); const auto expected = sourcemeta::core::parse_json(R"([ @@ -263,14 +265,17 @@ TEST(reverse_edge) { .edges = {}, .value = sourcemeta::core::JSONLDNode{ .id = "https://example.com/book"}}); - annotations.emplace_back(sourcemeta::core::Pointer{"series"}, - sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/hasPart", true}}, - .value = sourcemeta::core::JSONLDNode{}}); - annotations.emplace_back(sourcemeta::core::Pointer{"series", "name"}, - sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/name", false}}, - .value = sourcemeta::core::JSONLDLiteral{}}); + annotations.emplace_back( + sourcemeta::core::Pointer{"series"}, + sourcemeta::core::JSONLDDescriptor{ + .edges = {{.predicate = "https://schema.org/hasPart", + .reverse = true}}, + .value = sourcemeta::core::JSONLDNode{}}); + annotations.emplace_back( + sourcemeta::core::Pointer{"series", "name"}, + sourcemeta::core::JSONLDDescriptor{ + .edges = {{.predicate = "https://schema.org/name"}}, + .value = sourcemeta::core::JSONLDLiteral{}}); const auto expected = sourcemeta::core::parse_json(R"([ { @@ -302,12 +307,12 @@ TEST(shared_blank_node_identifier_co_refers) { annotations.emplace_back( sourcemeta::core::Pointer{"billing"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/billing", false}}, + .edges = {{.predicate = "https://example.com/billing"}}, .value = sourcemeta::core::JSONLDNode{.id = "_:address"}}); annotations.emplace_back( sourcemeta::core::Pointer{"shipping"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/shipping", false}}, + .edges = {{.predicate = "https://example.com/shipping"}}, .value = sourcemeta::core::JSONLDNode{.id = "_:address"}}); const auto expected = sourcemeta::core::parse_json(R"([ @@ -337,7 +342,7 @@ TEST(json_literal_preserved_verbatim) { annotations.emplace_back( sourcemeta::core::Pointer{"payload"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/raw", false}}, + .edges = {{.predicate = "https://example.com/raw"}}, .value = sourcemeta::core::JSONLDLiteral{.json = true}}); const auto expected = sourcemeta::core::parse_json(R"([ @@ -368,7 +373,7 @@ TEST(nested_ordered_collection_is_list_of_lists) { annotations.emplace_back( sourcemeta::core::Pointer{"matrix"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/rows", false}}, + .edges = {{.predicate = "https://example.com/rows"}}, .value = sourcemeta::core::JSONLDCollection{ .container = sourcemeta::core::JSONLDContainer::List}}); annotations.emplace_back( @@ -427,7 +432,7 @@ TEST(ordered_collection_wraps_undescribed_nested_arrays) { annotations.emplace_back( sourcemeta::core::Pointer{"tags"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/tags", false}}, + .edges = {{.predicate = "https://example.com/tags"}}, .value = sourcemeta::core::JSONLDCollection{ .container = sourcemeta::core::JSONLDContainer::List}}); @@ -464,7 +469,7 @@ TEST(ordered_collection_wraps_deeply_nested_undescribed_arrays) { annotations.emplace_back( sourcemeta::core::Pointer{"matrix"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/rows", false}}, + .edges = {{.predicate = "https://example.com/rows"}}, .value = sourcemeta::core::JSONLDCollection{ .container = sourcemeta::core::JSONLDContainer::List}}); @@ -504,7 +509,7 @@ TEST(ordered_collection_wraps_mixed_nested_and_scalar_members) { annotations.emplace_back( sourcemeta::core::Pointer{"tags"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/tags", false}}, + .edges = {{.predicate = "https://example.com/tags"}}, .value = sourcemeta::core::JSONLDCollection{ .container = sourcemeta::core::JSONLDContainer::List}}); @@ -540,7 +545,7 @@ TEST(ordered_collection_wraps_empty_nested_array) { annotations.emplace_back( sourcemeta::core::Pointer{"tags"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/tags", false}}, + .edges = {{.predicate = "https://example.com/tags"}}, .value = sourcemeta::core::JSONLDCollection{ .container = sourcemeta::core::JSONLDContainer::List}}); @@ -578,7 +583,7 @@ TEST(weak_ordered_collection_wraps_undescribed_nested_arrays) { annotations.emplace_back( sourcemeta::core::WeakPointer{std::cref(tags_key)}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/tags", false}}, + .edges = {{.predicate = "https://example.com/tags"}}, .value = sourcemeta::core::JSONLDCollection{ .container = sourcemeta::core::JSONLDContainer::List}}); @@ -612,14 +617,16 @@ TEST(undescribed_object_with_described_child) { sourcemeta::core::JSONLDDescriptor{.edges = {}, .value = sourcemeta::core::JSONLDNode{ .id = "https://example.com/doc"}}); - annotations.emplace_back(sourcemeta::core::Pointer{"name"}, - sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/name", false}}, - .value = sourcemeta::core::JSONLDLiteral{}}); - annotations.emplace_back(sourcemeta::core::Pointer{"meta", "title"}, - sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/title", false}}, - .value = sourcemeta::core::JSONLDLiteral{}}); + annotations.emplace_back( + sourcemeta::core::Pointer{"name"}, + sourcemeta::core::JSONLDDescriptor{ + .edges = {{.predicate = "https://schema.org/name"}}, + .value = sourcemeta::core::JSONLDLiteral{}}); + annotations.emplace_back( + sourcemeta::core::Pointer{"meta", "title"}, + sourcemeta::core::JSONLDDescriptor{ + .edges = {{.predicate = "https://example.com/title"}}, + .value = sourcemeta::core::JSONLDLiteral{}}); const auto expected = sourcemeta::core::parse_json(R"([ { @@ -650,10 +657,11 @@ TEST(described_node_without_edge_is_standalone) { .edges = {}, .value = sourcemeta::core::JSONLDNode{ .id = "https://example.com/other"}}); - annotations.emplace_back(sourcemeta::core::Pointer{"extra", "x"}, - sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/x", false}}, - .value = sourcemeta::core::JSONLDLiteral{}}); + annotations.emplace_back( + sourcemeta::core::Pointer{"extra", "x"}, + sourcemeta::core::JSONLDDescriptor{ + .edges = {{.predicate = "https://example.com/x"}}, + .value = sourcemeta::core::JSONLDLiteral{}}); const auto expected = sourcemeta::core::parse_json(R"([ { "@id": "https://example.com/doc" }, @@ -678,10 +686,11 @@ TEST(null_value_produces_no_triple) { sourcemeta::core::JSONLDDescriptor{.edges = {}, .value = sourcemeta::core::JSONLDNode{ .id = "https://example.com/doc"}}); - annotations.emplace_back(sourcemeta::core::Pointer{"maybe"}, - sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/name", false}}, - .value = sourcemeta::core::JSONLDLiteral{}}); + annotations.emplace_back( + sourcemeta::core::Pointer{"maybe"}, + sourcemeta::core::JSONLDDescriptor{ + .edges = {{.predicate = "https://schema.org/name"}}, + .value = sourcemeta::core::JSONLDLiteral{}}); const auto expected = sourcemeta::core::parse_json(R"([ { "@id": "https://example.com/doc" } @@ -702,12 +711,13 @@ TEST(null_value_with_node_descriptor_produces_no_triple) { sourcemeta::core::JSONLDDescriptor{.edges = {}, .value = sourcemeta::core::JSONLDNode{ .id = "https://example.com/doc"}}); - annotations.emplace_back(sourcemeta::core::Pointer{"maybe"}, - sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/child", false}}, - .value = sourcemeta::core::JSONLDNode{ - .id = "https://example.com/thing", - .types = {"https://example.com/Thing"}}}); + annotations.emplace_back( + sourcemeta::core::Pointer{"maybe"}, + sourcemeta::core::JSONLDDescriptor{ + .edges = {{.predicate = "https://example.com/child"}}, + .value = sourcemeta::core::JSONLDNode{ + .id = "https://example.com/thing", + .types = {"https://example.com/Thing"}}}); const auto expected = sourcemeta::core::parse_json(R"([ { "@id": "https://example.com/doc" } @@ -728,11 +738,12 @@ TEST(null_value_with_reference_descriptor_produces_no_triple) { sourcemeta::core::JSONLDDescriptor{.edges = {}, .value = sourcemeta::core::JSONLDNode{ .id = "https://example.com/doc"}}); - annotations.emplace_back(sourcemeta::core::Pointer{"maybe"}, - sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/child", false}}, - .value = sourcemeta::core::JSONLDReference{ - .id = "https://example.com/ref"}}); + annotations.emplace_back( + sourcemeta::core::Pointer{"maybe"}, + sourcemeta::core::JSONLDDescriptor{ + .edges = {{.predicate = "https://example.com/child"}}, + .value = sourcemeta::core::JSONLDReference{ + .id = "https://example.com/ref"}}); const auto expected = sourcemeta::core::parse_json(R"([ { "@id": "https://example.com/doc" } @@ -756,7 +767,7 @@ TEST(null_value_with_collection_descriptor_produces_no_triple) { annotations.emplace_back( sourcemeta::core::Pointer{"maybe"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/items", false}}, + .edges = {{.predicate = "https://example.com/items"}}, .value = sourcemeta::core::JSONLDCollection{ .container = sourcemeta::core::JSONLDContainer::List}}); @@ -785,7 +796,7 @@ TEST(json_literal_null_is_data) { annotations.emplace_back( sourcemeta::core::Pointer{"payload"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/raw", false}}, + .edges = {{.predicate = "https://example.com/raw"}}, .value = sourcemeta::core::JSONLDLiteral{.json = true}}); const auto expected = sourcemeta::core::parse_json(R"([ @@ -816,7 +827,7 @@ TEST(json_literal_null_member_in_ordered_collection) { annotations.emplace_back( sourcemeta::core::Pointer{"items"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/items", false}}, + .edges = {{.predicate = "https://example.com/items"}}, .value = sourcemeta::core::JSONLDCollection{ .container = sourcemeta::core::JSONLDContainer::List}}); annotations.emplace_back( @@ -857,7 +868,7 @@ TEST(weak_json_literal_null_is_data) { annotations.emplace_back( sourcemeta::core::WeakPointer{std::cref(payload_key)}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/raw", false}}, + .edges = {{.predicate = "https://example.com/raw"}}, .value = sourcemeta::core::JSONLDLiteral{.json = true}}); const auto expected = sourcemeta::core::parse_json(R"([ @@ -968,10 +979,11 @@ TEST(edge_attached_empty_node_below_root_is_kept) { sourcemeta::core::JSONLDDescriptor{.edges = {}, .value = sourcemeta::core::JSONLDNode{ .id = "https://example.com/doc"}}); - annotations.emplace_back(sourcemeta::core::Pointer{"meta"}, - sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/meta", false}}, - .value = sourcemeta::core::JSONLDNode{}}); + annotations.emplace_back( + sourcemeta::core::Pointer{"meta"}, + sourcemeta::core::JSONLDDescriptor{ + .edges = {{.predicate = "https://example.com/meta"}}, + .value = sourcemeta::core::JSONLDNode{}}); const auto expected = sourcemeta::core::parse_json(R"([ { @@ -999,13 +1011,14 @@ TEST(named_graph) { annotations.emplace_back( sourcemeta::core::Pointer{"prov"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/statedIn", false}}, + .edges = {{.predicate = "https://example.com/statedIn"}}, .value = sourcemeta::core::JSONLDNode{ .id = "https://example.com/graph", .graph = true}}); - annotations.emplace_back(sourcemeta::core::Pointer{"prov", "who"}, - sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/name", false}}, - .value = sourcemeta::core::JSONLDLiteral{}}); + annotations.emplace_back( + sourcemeta::core::Pointer{"prov", "who"}, + sourcemeta::core::JSONLDDescriptor{ + .edges = {{.predicate = "https://schema.org/name"}}, + .value = sourcemeta::core::JSONLDLiteral{}}); const auto expected = sourcemeta::core::parse_json(R"([ { @@ -1046,17 +1059,18 @@ TEST(standalone_empty_node_inside_named_graph_is_dropped) { annotations.emplace_back( sourcemeta::core::Pointer{"prov"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/statedIn", false}}, + .edges = {{.predicate = "https://example.com/statedIn"}}, .value = sourcemeta::core::JSONLDNode{ .id = "https://example.com/graph", .graph = true}}); annotations.emplace_back( sourcemeta::core::Pointer{"prov", "meta"}, sourcemeta::core::JSONLDDescriptor{ .edges = {}, .value = sourcemeta::core::JSONLDNode{}}); - annotations.emplace_back(sourcemeta::core::Pointer{"prov", "who"}, - sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/name", false}}, - .value = sourcemeta::core::JSONLDLiteral{}}); + annotations.emplace_back( + sourcemeta::core::Pointer{"prov", "who"}, + sourcemeta::core::JSONLDDescriptor{ + .edges = {{.predicate = "https://schema.org/name"}}, + .value = sourcemeta::core::JSONLDLiteral{}}); const auto expected = sourcemeta::core::parse_json(R"([ { @@ -1094,17 +1108,19 @@ TEST(edge_attached_empty_node_inside_named_graph_is_kept) { annotations.emplace_back( sourcemeta::core::Pointer{"prov"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/statedIn", false}}, + .edges = {{.predicate = "https://example.com/statedIn"}}, .value = sourcemeta::core::JSONLDNode{ .id = "https://example.com/graph", .graph = true}}); - annotations.emplace_back(sourcemeta::core::Pointer{"prov", "meta"}, - sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/meta", false}}, - .value = sourcemeta::core::JSONLDNode{}}); - annotations.emplace_back(sourcemeta::core::Pointer{"prov", "who"}, - sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/name", false}}, - .value = sourcemeta::core::JSONLDLiteral{}}); + annotations.emplace_back( + sourcemeta::core::Pointer{"prov", "meta"}, + sourcemeta::core::JSONLDDescriptor{ + .edges = {{.predicate = "https://example.com/meta"}}, + .value = sourcemeta::core::JSONLDNode{}}); + annotations.emplace_back( + sourcemeta::core::Pointer{"prov", "who"}, + sourcemeta::core::JSONLDDescriptor{ + .edges = {{.predicate = "https://schema.org/name"}}, + .value = sourcemeta::core::JSONLDLiteral{}}); const auto expected = sourcemeta::core::parse_json(R"([ { @@ -1176,10 +1192,11 @@ TEST(node_with_type) { .value = sourcemeta::core::JSONLDNode{ .id = "https://example.com/ada", .types = {"https://schema.org/Person"}}}); - annotations.emplace_back(sourcemeta::core::Pointer{"name"}, - sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/name", false}}, - .value = sourcemeta::core::JSONLDLiteral{}}); + annotations.emplace_back( + sourcemeta::core::Pointer{"name"}, + sourcemeta::core::JSONLDDescriptor{ + .edges = {{.predicate = "https://schema.org/name"}}, + .value = sourcemeta::core::JSONLDLiteral{}}); const auto expected = sourcemeta::core::parse_json(R"([ { @@ -1233,7 +1250,7 @@ TEST(reference_without_types) { annotations.emplace_back( sourcemeta::core::Pointer{"currency"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/priceCurrency", false}}, + .edges = {{.predicate = "https://schema.org/priceCurrency"}}, .value = sourcemeta::core::JSONLDReference{ .id = "https://www.iso.org/iso-4217/USD"}}); @@ -1264,7 +1281,7 @@ TEST(literal_with_language_only) { annotations.emplace_back( sourcemeta::core::Pointer{"title"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/name", false}}, + .edges = {{.predicate = "https://schema.org/name"}}, .value = sourcemeta::core::JSONLDLiteral{.language = "en"}}); const auto expected = sourcemeta::core::parse_json(R"([ @@ -1292,7 +1309,7 @@ TEST(literal_with_ltr_direction) { annotations.emplace_back( sourcemeta::core::Pointer{"title"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/name", false}}, + .edges = {{.predicate = "https://schema.org/name"}}, .value = sourcemeta::core::JSONLDLiteral{ .language = "en", .direction = sourcemeta::core::JSONLDDirection::LTR}}); @@ -1321,10 +1338,11 @@ TEST(boolean_literal) { sourcemeta::core::JSONLDDescriptor{.edges = {}, .value = sourcemeta::core::JSONLDNode{ .id = "https://example.com/doc"}}); - annotations.emplace_back(sourcemeta::core::Pointer{"active"}, - sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/active", false}}, - .value = sourcemeta::core::JSONLDLiteral{}}); + annotations.emplace_back( + sourcemeta::core::Pointer{"active"}, + sourcemeta::core::JSONLDDescriptor{ + .edges = {{.predicate = "https://example.com/active"}}, + .value = sourcemeta::core::JSONLDLiteral{}}); const auto expected = sourcemeta::core::parse_json(R"([ { @@ -1348,10 +1366,11 @@ TEST(integer_literal_without_datatype) { sourcemeta::core::JSONLDDescriptor{.edges = {}, .value = sourcemeta::core::JSONLDNode{ .id = "https://example.com/doc"}}); - annotations.emplace_back(sourcemeta::core::Pointer{"count"}, - sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/count", false}}, - .value = sourcemeta::core::JSONLDLiteral{}}); + annotations.emplace_back( + sourcemeta::core::Pointer{"count"}, + sourcemeta::core::JSONLDDescriptor{ + .edges = {{.predicate = "https://example.com/count"}}, + .value = sourcemeta::core::JSONLDLiteral{}}); const auto expected = sourcemeta::core::parse_json(R"([ { @@ -1379,17 +1398,18 @@ TEST(ordered_collection_of_nodes) { annotations.emplace_back( sourcemeta::core::Pointer{"authors"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/author", false}}, + .edges = {{.predicate = "https://schema.org/author"}}, .value = sourcemeta::core::JSONLDCollection{ .container = sourcemeta::core::JSONLDContainer::List}}); annotations.emplace_back( sourcemeta::core::Pointer{"authors", 0}, sourcemeta::core::JSONLDDescriptor{ .edges = {}, .value = sourcemeta::core::JSONLDNode{}}); - annotations.emplace_back(sourcemeta::core::Pointer{"authors", 0, "name"}, - sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/name", false}}, - .value = sourcemeta::core::JSONLDLiteral{}}); + annotations.emplace_back( + sourcemeta::core::Pointer{"authors", 0, "name"}, + sourcemeta::core::JSONLDDescriptor{ + .edges = {{.predicate = "https://schema.org/name"}}, + .value = sourcemeta::core::JSONLDLiteral{}}); const auto expected = sourcemeta::core::parse_json(R"([ { @@ -1423,25 +1443,27 @@ TEST(unordered_collection_of_nodes) { annotations.emplace_back( sourcemeta::core::Pointer{"items"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/item", false}}, + .edges = {{.predicate = "https://example.com/item"}}, .value = sourcemeta::core::JSONLDCollection{ .container = sourcemeta::core::JSONLDContainer::Set}}); annotations.emplace_back( sourcemeta::core::Pointer{"items", 0}, sourcemeta::core::JSONLDDescriptor{ .edges = {}, .value = sourcemeta::core::JSONLDNode{}}); - annotations.emplace_back(sourcemeta::core::Pointer{"items", 0, "sku"}, - sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/sku", false}}, - .value = sourcemeta::core::JSONLDLiteral{}}); + annotations.emplace_back( + sourcemeta::core::Pointer{"items", 0, "sku"}, + sourcemeta::core::JSONLDDescriptor{ + .edges = {{.predicate = "https://example.com/sku"}}, + .value = sourcemeta::core::JSONLDLiteral{}}); annotations.emplace_back( sourcemeta::core::Pointer{"items", 1}, sourcemeta::core::JSONLDDescriptor{ .edges = {}, .value = sourcemeta::core::JSONLDNode{}}); - annotations.emplace_back(sourcemeta::core::Pointer{"items", 1, "sku"}, - sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/sku", false}}, - .value = sourcemeta::core::JSONLDLiteral{}}); + annotations.emplace_back( + sourcemeta::core::Pointer{"items", 1, "sku"}, + sourcemeta::core::JSONLDDescriptor{ + .edges = {{.predicate = "https://example.com/sku"}}, + .value = sourcemeta::core::JSONLDLiteral{}}); const auto expected = sourcemeta::core::parse_json(R"([ { @@ -1471,7 +1493,7 @@ TEST(empty_ordered_collection_is_rdf_nil) { annotations.emplace_back( sourcemeta::core::Pointer{"authors"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/author", false}}, + .edges = {{.predicate = "https://schema.org/author"}}, .value = sourcemeta::core::JSONLDCollection{ .container = sourcemeta::core::JSONLDContainer::List}}); @@ -1500,7 +1522,7 @@ TEST(empty_unordered_collection_adds_no_property) { annotations.emplace_back( sourcemeta::core::Pointer{"tags"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/keywords", false}}, + .edges = {{.predicate = "https://schema.org/keywords"}}, .value = sourcemeta::core::JSONLDCollection{ .container = sourcemeta::core::JSONLDContainer::Set}}); @@ -1527,7 +1549,7 @@ TEST(collection_defaults_undescribed_scalar_elements) { annotations.emplace_back( sourcemeta::core::Pointer{"authors"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/author", false}}, + .edges = {{.predicate = "https://schema.org/author"}}, .value = sourcemeta::core::JSONLDCollection{ .container = sourcemeta::core::JSONLDContainer::List}}); annotations.emplace_back( @@ -1569,7 +1591,7 @@ TEST(unordered_collection_defaults_all_undescribed_elements) { annotations.emplace_back( sourcemeta::core::Pointer{"keywords"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/keywords", false}}, + .edges = {{.predicate = "https://schema.org/keywords"}}, .value = sourcemeta::core::JSONLDCollection{ .container = sourcemeta::core::JSONLDContainer::Set}}); @@ -1604,7 +1626,7 @@ TEST(index_collection_defaults_undescribed_members) { annotations.emplace_back( sourcemeta::core::Pointer{"identifiers"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/identifier", false}}, + .edges = {{.predicate = "https://schema.org/identifier"}}, .value = sourcemeta::core::JSONLDCollection{ .container = sourcemeta::core::JSONLDContainer::Index}}); @@ -1637,7 +1659,7 @@ TEST(collection_defaults_nested_undescribed_array_as_set) { annotations.emplace_back( sourcemeta::core::Pointer{"groups"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/member", false}}, + .edges = {{.predicate = "https://example.com/member"}}, .value = sourcemeta::core::JSONLDCollection{ .container = sourcemeta::core::JSONLDContainer::Set}}); @@ -1669,7 +1691,7 @@ TEST(collection_undescribed_object_element_is_still_dropped) { annotations.emplace_back( sourcemeta::core::Pointer{"keywords"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/keywords", false}}, + .edges = {{.predicate = "https://schema.org/keywords"}}, .value = sourcemeta::core::JSONLDCollection{ .container = sourcemeta::core::JSONLDContainer::Set}}); @@ -1699,7 +1721,7 @@ TEST(collection_null_element_is_still_dropped) { annotations.emplace_back( sourcemeta::core::Pointer{"keywords"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/keywords", false}}, + .edges = {{.predicate = "https://schema.org/keywords"}}, .value = sourcemeta::core::JSONLDCollection{ .container = sourcemeta::core::JSONLDContainer::Set}}); @@ -1731,7 +1753,7 @@ TEST(nested_unordered_collection_flattens) { annotations.emplace_back( sourcemeta::core::Pointer{"groups"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/member", false}}, + .edges = {{.predicate = "https://example.com/member"}}, .value = sourcemeta::core::JSONLDCollection{ .container = sourcemeta::core::JSONLDContainer::Set}}); annotations.emplace_back( @@ -1790,19 +1812,21 @@ TEST(array_root_spreads_into_default_graph) { sourcemeta::core::JSONLDDescriptor{.edges = {}, .value = sourcemeta::core::JSONLDNode{ .id = "https://example.com/a"}}); - annotations.emplace_back(sourcemeta::core::Pointer{0, "name"}, - sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/name", false}}, - .value = sourcemeta::core::JSONLDLiteral{}}); + annotations.emplace_back( + sourcemeta::core::Pointer{0, "name"}, + sourcemeta::core::JSONLDDescriptor{ + .edges = {{.predicate = "https://schema.org/name"}}, + .value = sourcemeta::core::JSONLDLiteral{}}); annotations.emplace_back( sourcemeta::core::Pointer{1}, sourcemeta::core::JSONLDDescriptor{.edges = {}, .value = sourcemeta::core::JSONLDNode{ .id = "https://example.com/b"}}); - annotations.emplace_back(sourcemeta::core::Pointer{1, "name"}, - sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/name", false}}, - .value = sourcemeta::core::JSONLDLiteral{}}); + annotations.emplace_back( + sourcemeta::core::Pointer{1, "name"}, + sourcemeta::core::JSONLDDescriptor{ + .edges = {{.predicate = "https://schema.org/name"}}, + .value = sourcemeta::core::JSONLDLiteral{}}); const auto expected = sourcemeta::core::parse_json(R"([ { @@ -1864,10 +1888,11 @@ TEST(root_collection_keeps_only_node_elements) { sourcemeta::core::JSONLDDescriptor{.edges = {}, .value = sourcemeta::core::JSONLDNode{ .id = "https://example.com/a"}}); - annotations.emplace_back(sourcemeta::core::Pointer{0, "name"}, - sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/name", false}}, - .value = sourcemeta::core::JSONLDLiteral{}}); + annotations.emplace_back( + sourcemeta::core::Pointer{0, "name"}, + sourcemeta::core::JSONLDDescriptor{ + .edges = {{.predicate = "https://schema.org/name"}}, + .value = sourcemeta::core::JSONLDLiteral{}}); annotations.emplace_back( sourcemeta::core::Pointer{1}, sourcemeta::core::JSONLDDescriptor{ @@ -1915,7 +1940,7 @@ TEST(collection_descriptor_on_non_array_is_dropped) { annotations.emplace_back( sourcemeta::core::Pointer{"x"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/x", false}}, + .edges = {{.predicate = "https://example.com/x"}}, .value = sourcemeta::core::JSONLDCollection{ .container = sourcemeta::core::JSONLDContainer::List}}); @@ -1943,19 +1968,21 @@ TEST(output_is_a_fixed_point_of_expansion) { .value = sourcemeta::core::JSONLDNode{ .id = "https://example.com/ada", .types = {"https://schema.org/Person"}}}); - annotations.emplace_back(sourcemeta::core::Pointer{"name"}, - sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/name", false}}, - .value = sourcemeta::core::JSONLDLiteral{}}); - annotations.emplace_back(sourcemeta::core::Pointer{"homepage"}, - sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/url", false}}, - .value = sourcemeta::core::JSONLDReference{ - .id = "https://ada.example"}}); + annotations.emplace_back( + sourcemeta::core::Pointer{"name"}, + sourcemeta::core::JSONLDDescriptor{ + .edges = {{.predicate = "https://schema.org/name"}}, + .value = sourcemeta::core::JSONLDLiteral{}}); + annotations.emplace_back( + sourcemeta::core::Pointer{"homepage"}, + sourcemeta::core::JSONLDDescriptor{ + .edges = {{.predicate = "https://schema.org/url"}}, + .value = + sourcemeta::core::JSONLDReference{.id = "https://ada.example"}}); annotations.emplace_back( sourcemeta::core::Pointer{"books"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/author", false}}, + .edges = {{.predicate = "https://schema.org/author"}}, .value = sourcemeta::core::JSONLDCollection{ .container = sourcemeta::core::JSONLDContainer::List}}); annotations.emplace_back( @@ -1983,11 +2010,12 @@ TEST(node_descriptor_on_scalar_ignores_value) { sourcemeta::core::JSONLDDescriptor{.edges = {}, .value = sourcemeta::core::JSONLDNode{ .id = "https://example.com/doc"}}); - annotations.emplace_back(sourcemeta::core::Pointer{"x"}, - sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/x", false}}, - .value = sourcemeta::core::JSONLDNode{ - .id = "https://example.com/other"}}); + annotations.emplace_back( + sourcemeta::core::Pointer{"x"}, + sourcemeta::core::JSONLDDescriptor{ + .edges = {{.predicate = "https://example.com/x"}}, + .value = + sourcemeta::core::JSONLDNode{.id = "https://example.com/other"}}); const auto expected = sourcemeta::core::parse_json(R"([ { @@ -2014,10 +2042,11 @@ TEST(weak_node_with_literal_property) { sourcemeta::core::JSONLDDescriptor{.edges = {}, .value = sourcemeta::core::JSONLDNode{ .id = "https://example.com/org"}}); - annotations.emplace_back(sourcemeta::core::WeakPointer{std::cref(name_key)}, - sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/name", false}}, - .value = sourcemeta::core::JSONLDLiteral{}}); + annotations.emplace_back( + sourcemeta::core::WeakPointer{std::cref(name_key)}, + sourcemeta::core::JSONLDDescriptor{ + .edges = {{.predicate = "https://schema.org/name"}}, + .value = sourcemeta::core::JSONLDLiteral{}}); const auto expected = sourcemeta::core::parse_json(R"([ { @@ -2047,7 +2076,7 @@ TEST(weak_reference_property) { annotations.emplace_back( sourcemeta::core::WeakPointer{std::cref(currency_key)}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/priceCurrency", false}}, + .edges = {{.predicate = "https://schema.org/priceCurrency"}}, .value = sourcemeta::core::JSONLDReference{ .id = "https://www.iso.org/iso-4217/USD", .types = {"https://schema.org/Currency"}}}); @@ -2085,7 +2114,7 @@ TEST(weak_ordered_collection_becomes_list) { annotations.emplace_back( sourcemeta::core::WeakPointer{std::cref(authors_key)}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/author", false}}, + .edges = {{.predicate = "https://schema.org/author"}}, .value = sourcemeta::core::JSONLDCollection{ .container = sourcemeta::core::JSONLDContainer::List}}); annotations.emplace_back( @@ -2134,14 +2163,16 @@ TEST(weak_reverse_edge) { .edges = {}, .value = sourcemeta::core::JSONLDNode{ .id = "https://example.com/book"}}); - annotations.emplace_back(sourcemeta::core::WeakPointer{std::cref(series_key)}, - sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/hasPart", true}}, - .value = sourcemeta::core::JSONLDNode{}}); + annotations.emplace_back( + sourcemeta::core::WeakPointer{std::cref(series_key)}, + sourcemeta::core::JSONLDDescriptor{ + .edges = {{.predicate = "https://schema.org/hasPart", + .reverse = true}}, + .value = sourcemeta::core::JSONLDNode{}}); annotations.emplace_back( sourcemeta::core::WeakPointer{std::cref(series_key), std::cref(name_key)}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/name", false}}, + .edges = {{.predicate = "https://schema.org/name"}}, .value = sourcemeta::core::JSONLDLiteral{}}); const auto expected = sourcemeta::core::parse_json(R"([ @@ -2182,7 +2213,7 @@ TEST(weak_array_root_spreads_into_default_graph) { annotations.emplace_back( sourcemeta::core::WeakPointer{0, std::cref(name_key)}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/name", false}}, + .edges = {{.predicate = "https://schema.org/name"}}, .value = sourcemeta::core::JSONLDLiteral{}}); annotations.emplace_back( sourcemeta::core::WeakPointer{1}, @@ -2192,7 +2223,7 @@ TEST(weak_array_root_spreads_into_default_graph) { annotations.emplace_back( sourcemeta::core::WeakPointer{1, std::cref(name_key)}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/name", false}}, + .edges = {{.predicate = "https://schema.org/name"}}, .value = sourcemeta::core::JSONLDLiteral{}}); const auto expected = sourcemeta::core::parse_json(R"([ @@ -2225,7 +2256,7 @@ TEST(language_container) { annotations.emplace_back( sourcemeta::core::Pointer{"label"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/name", false}}, + .edges = {{.predicate = "https://schema.org/name"}}, .value = sourcemeta::core::JSONLDCollection{ .container = sourcemeta::core::JSONLDContainer::Language}}); @@ -2259,7 +2290,7 @@ TEST(language_container_empty) { annotations.emplace_back( sourcemeta::core::Pointer{"label"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/name", false}}, + .edges = {{.predicate = "https://schema.org/name"}}, .value = sourcemeta::core::JSONLDCollection{ .container = sourcemeta::core::JSONLDContainer::Language}}); @@ -2286,7 +2317,7 @@ TEST(language_container_null_value) { annotations.emplace_back( sourcemeta::core::Pointer{"label"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/name", false}}, + .edges = {{.predicate = "https://schema.org/name"}}, .value = sourcemeta::core::JSONLDCollection{ .container = sourcemeta::core::JSONLDContainer::Language}}); @@ -2318,7 +2349,7 @@ TEST(language_container_null_array_element) { annotations.emplace_back( sourcemeta::core::Pointer{"label"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/name", false}}, + .edges = {{.predicate = "https://schema.org/name"}}, .value = sourcemeta::core::JSONLDCollection{ .container = sourcemeta::core::JSONLDContainer::Language}}); @@ -2351,7 +2382,7 @@ TEST(language_container_null_none) { annotations.emplace_back( sourcemeta::core::Pointer{"label"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/name", false}}, + .edges = {{.predicate = "https://schema.org/name"}}, .value = sourcemeta::core::JSONLDCollection{ .container = sourcemeta::core::JSONLDContainer::Language}}); @@ -2383,7 +2414,7 @@ TEST(language_container_all_null) { annotations.emplace_back( sourcemeta::core::Pointer{"label"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/name", false}}, + .edges = {{.predicate = "https://schema.org/name"}}, .value = sourcemeta::core::JSONLDCollection{ .container = sourcemeta::core::JSONLDContainer::Language}}); @@ -2410,7 +2441,7 @@ TEST(index_container_of_nodes) { annotations.emplace_back( sourcemeta::core::Pointer{"posts"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/blogPost", false}}, + .edges = {{.predicate = "https://schema.org/blogPost"}}, .value = sourcemeta::core::JSONLDCollection{ .container = sourcemeta::core::JSONLDContainer::Index}}); annotations.emplace_back(sourcemeta::core::Pointer{"posts", "2023"}, @@ -2421,7 +2452,7 @@ TEST(index_container_of_nodes) { annotations.emplace_back( sourcemeta::core::Pointer{"posts", "2023", "title"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/headline", false}}, + .edges = {{.predicate = "https://schema.org/headline"}}, .value = sourcemeta::core::JSONLDLiteral{}}); annotations.emplace_back(sourcemeta::core::Pointer{"posts", "2024"}, sourcemeta::core::JSONLDDescriptor{ @@ -2431,7 +2462,7 @@ TEST(index_container_of_nodes) { annotations.emplace_back( sourcemeta::core::Pointer{"posts", "2024", "title"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/headline", false}}, + .edges = {{.predicate = "https://schema.org/headline"}}, .value = sourcemeta::core::JSONLDLiteral{}}); const auto expected = sourcemeta::core::parse_json(R"([ @@ -2471,7 +2502,7 @@ TEST(index_container_of_literals) { annotations.emplace_back( sourcemeta::core::Pointer{"scores"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/value", false}}, + .edges = {{.predicate = "https://schema.org/value"}}, .value = sourcemeta::core::JSONLDCollection{ .container = sourcemeta::core::JSONLDContainer::Index}}); annotations.emplace_back( @@ -2512,7 +2543,7 @@ TEST(index_container_with_nested_set) { annotations.emplace_back( sourcemeta::core::Pointer{"groups"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/item", false}}, + .edges = {{.predicate = "https://schema.org/item"}}, .value = sourcemeta::core::JSONLDCollection{ .container = sourcemeta::core::JSONLDContainer::Index}}); annotations.emplace_back( @@ -2558,7 +2589,7 @@ TEST(index_container_empty) { annotations.emplace_back( sourcemeta::core::Pointer{"posts"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/blogPost", false}}, + .edges = {{.predicate = "https://schema.org/blogPost"}}, .value = sourcemeta::core::JSONLDCollection{ .container = sourcemeta::core::JSONLDContainer::Index}}); @@ -2587,7 +2618,7 @@ TEST(index_container_none_key_carries_no_index) { annotations.emplace_back( sourcemeta::core::Pointer{"posts"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/blogPost", false}}, + .edges = {{.predicate = "https://schema.org/blogPost"}}, .value = sourcemeta::core::JSONLDCollection{ .container = sourcemeta::core::JSONLDContainer::Index}}); @@ -2620,7 +2651,7 @@ TEST(index_container_of_described_typed_literals) { annotations.emplace_back( sourcemeta::core::Pointer{"scores"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/value", false}}, + .edges = {{.predicate = "https://schema.org/value"}}, .value = sourcemeta::core::JSONLDCollection{ .container = sourcemeta::core::JSONLDContainer::Index}}); annotations.emplace_back( @@ -2664,7 +2695,7 @@ TEST(weak_collection_defaults_undescribed_scalar_elements) { annotations.emplace_back( sourcemeta::core::WeakPointer{std::cref(keywords_key)}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/keywords", false}}, + .edges = {{.predicate = "https://schema.org/keywords"}}, .value = sourcemeta::core::JSONLDCollection{ .container = sourcemeta::core::JSONLDContainer::Set}}); @@ -2692,10 +2723,11 @@ TEST(duplicate_annotations_first_one_wins) { .edges = {}, .value = sourcemeta::core::JSONLDNode{ .id = "https://example.com/person"}}); - annotations.emplace_back(sourcemeta::core::Pointer{"name"}, - sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/name", false}}, - .value = sourcemeta::core::JSONLDLiteral{}}); + annotations.emplace_back( + sourcemeta::core::Pointer{"name"}, + sourcemeta::core::JSONLDDescriptor{ + .edges = {{.predicate = "https://schema.org/name"}}, + .value = sourcemeta::core::JSONLDLiteral{}}); annotations.emplace_back(sourcemeta::core::Pointer{}, sourcemeta::core::JSONLDDescriptor{ .edges = {}, @@ -2704,7 +2736,7 @@ TEST(duplicate_annotations_first_one_wins) { annotations.emplace_back( sourcemeta::core::Pointer{"name"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/ignored", false}}, + .edges = {{.predicate = "https://example.com/ignored"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "https://example.com/ignored"}}); @@ -2738,7 +2770,7 @@ TEST(fractional_literal_with_decimal_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#decimal"}}); @@ -2772,7 +2804,7 @@ TEST(precise_fractional_literal_with_decimal_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#decimal"}}); @@ -2809,7 +2841,7 @@ TEST(integer_literal_with_decimal_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#decimal"}}); @@ -2845,7 +2877,7 @@ TEST(integral_real_literal_with_decimal_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#decimal"}}); @@ -2879,7 +2911,7 @@ TEST(zero_real_literal_with_decimal_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#decimal"}}); @@ -2913,7 +2945,7 @@ TEST(negative_fractional_literal_with_decimal_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#decimal"}}); @@ -2947,7 +2979,7 @@ TEST(negative_integer_literal_with_decimal_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#decimal"}}); @@ -2984,7 +3016,7 @@ TEST(small_fractional_literal_with_decimal_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#decimal"}}); @@ -3021,7 +3053,7 @@ TEST(large_real_literal_with_decimal_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#decimal"}}); @@ -3057,7 +3089,7 @@ TEST(exponent_notation_literal_with_decimal_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#decimal"}}); @@ -3094,7 +3126,7 @@ TEST(long_fractional_literal_with_decimal_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#decimal"}}); @@ -3130,7 +3162,7 @@ TEST(fractional_literal_with_integer_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#integer"}}); @@ -3164,7 +3196,7 @@ TEST(integer_literal_with_integer_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#integer"}}); @@ -3199,7 +3231,7 @@ TEST(large_integer_literal_with_integer_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#integer"}}); @@ -3236,7 +3268,7 @@ TEST(high_precision_fractional_literal_with_decimal_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#decimal"}}); @@ -3271,7 +3303,7 @@ TEST(huge_integer_literal_with_integer_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#integer"}}); @@ -3308,7 +3340,7 @@ TEST(fractional_literal_with_double_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#double"}}); @@ -3342,7 +3374,7 @@ TEST(precise_fractional_literal_with_double_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#double"}}); @@ -3376,7 +3408,7 @@ TEST(integer_literal_with_double_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#double"}}); @@ -3410,7 +3442,7 @@ TEST(integral_real_literal_with_double_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#double"}}); @@ -3446,7 +3478,7 @@ TEST(zero_real_literal_with_double_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#double"}}); @@ -3482,7 +3514,7 @@ TEST(negative_zero_real_literal_with_double_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#double"}}); @@ -3516,7 +3548,7 @@ TEST(negative_zero_real_literal_with_float_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#float"}}); @@ -3552,7 +3584,7 @@ TEST(negative_integer_zero_literal_with_double_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#double"}}); @@ -3586,7 +3618,7 @@ TEST(negative_fractional_literal_with_double_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#double"}}); @@ -3620,7 +3652,7 @@ TEST(small_fractional_literal_with_double_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#double"}}); @@ -3654,7 +3686,7 @@ TEST(large_real_literal_with_double_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#double"}}); @@ -3692,7 +3724,7 @@ TEST(large_integer_literal_with_double_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#double"}}); @@ -3728,7 +3760,7 @@ TEST(tiny_real_literal_with_double_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#double"}}); @@ -3764,7 +3796,7 @@ TEST(fractional_literal_with_float_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#float"}}); @@ -3800,7 +3832,7 @@ TEST(true_literal_with_boolean_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#boolean"}}); @@ -3834,7 +3866,7 @@ TEST(false_literal_with_boolean_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#boolean"}}); @@ -3870,7 +3902,7 @@ TEST(true_literal_with_double_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#double"}}); @@ -3901,11 +3933,12 @@ TEST(true_literal_with_custom_datatype) { sourcemeta::core::JSONLDDescriptor{.edges = {}, .value = sourcemeta::core::JSONLDNode{ .id = "https://example.com/doc"}}); - annotations.emplace_back(sourcemeta::core::Pointer{"value"}, - sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, - .value = sourcemeta::core::JSONLDLiteral{ - .datatype = "https://example.com/flag"}}); + annotations.emplace_back( + sourcemeta::core::Pointer{"value"}, + sourcemeta::core::JSONLDDescriptor{ + .edges = {{.predicate = "https://example.com/value"}}, + .value = sourcemeta::core::JSONLDLiteral{ + .datatype = "https://example.com/flag"}}); const auto expected = sourcemeta::core::parse_json(R"([ { @@ -3937,7 +3970,7 @@ TEST(fractional_literal_with_custom_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "https://example.com/quantity"}}); @@ -3971,7 +4004,7 @@ TEST(integer_literal_with_custom_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "https://example.com/quantity"}}); @@ -4005,10 +4038,11 @@ TEST(fractional_literal_without_datatype) { sourcemeta::core::JSONLDDescriptor{.edges = {}, .value = sourcemeta::core::JSONLDNode{ .id = "https://example.com/doc"}}); - annotations.emplace_back(sourcemeta::core::Pointer{"value"}, - sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, - .value = sourcemeta::core::JSONLDLiteral{}}); + annotations.emplace_back( + sourcemeta::core::Pointer{"value"}, + sourcemeta::core::JSONLDDescriptor{ + .edges = {{.predicate = "https://example.com/value"}}, + .value = sourcemeta::core::JSONLDLiteral{}}); const auto expected = sourcemeta::core::parse_json(R"([ { @@ -4032,10 +4066,11 @@ TEST(boolean_literal_without_datatype) { sourcemeta::core::JSONLDDescriptor{.edges = {}, .value = sourcemeta::core::JSONLDNode{ .id = "https://example.com/doc"}}); - annotations.emplace_back(sourcemeta::core::Pointer{"value"}, - sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, - .value = sourcemeta::core::JSONLDLiteral{}}); + annotations.emplace_back( + sourcemeta::core::Pointer{"value"}, + sourcemeta::core::JSONLDDescriptor{ + .edges = {{.predicate = "https://example.com/value"}}, + .value = sourcemeta::core::JSONLDLiteral{}}); const auto expected = sourcemeta::core::parse_json(R"([ { @@ -4062,7 +4097,7 @@ TEST(fractional_json_literal_preserved_verbatim) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{.json = true}}); const auto expected = sourcemeta::core::parse_json(R"([ @@ -4094,7 +4129,7 @@ TEST(string_literal_with_decimal_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#decimal"}}); @@ -4129,7 +4164,7 @@ TEST(minimum_integer_literal_with_integer_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#integer"}}); @@ -4164,7 +4199,7 @@ TEST(maximum_integer_literal_with_integer_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#integer"}}); @@ -4198,7 +4233,7 @@ TEST(zero_integer_literal_with_decimal_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#decimal"}}); @@ -4232,7 +4267,7 @@ TEST(zero_integer_literal_with_double_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#double"}}); @@ -4267,7 +4302,7 @@ TEST(minimum_integer_literal_with_double_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#double"}}); @@ -4301,7 +4336,7 @@ TEST(integer_literal_with_float_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#float"}}); @@ -4340,7 +4375,7 @@ TEST(maximum_real_literal_with_decimal_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#decimal"}}); @@ -4377,7 +4412,7 @@ TEST(subnormal_real_literal_with_decimal_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#decimal"}}); @@ -4411,7 +4446,7 @@ TEST(negative_large_decimal_literal_with_decimal_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#decimal"}}); @@ -4445,7 +4480,7 @@ TEST(negative_fraction_decimal_literal_with_decimal_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#decimal"}}); @@ -4480,7 +4515,7 @@ TEST(interior_point_decimal_literal_with_decimal_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#decimal"}}); @@ -4517,7 +4552,7 @@ TEST(trailing_zeros_decimal_literal_with_decimal_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#decimal"}}); @@ -4552,7 +4587,7 @@ TEST(trailing_zeros_integer_decimal_literal_with_integer_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#integer"}}); @@ -4586,7 +4621,7 @@ TEST(zero_decimal_literal_with_decimal_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#decimal"}}); @@ -4620,7 +4655,7 @@ TEST(zero_decimal_literal_with_double_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#double"}}); @@ -4656,7 +4691,7 @@ TEST(overflowing_decimal_literal_with_double_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#double"}}); @@ -4690,7 +4725,7 @@ TEST(underflowing_decimal_literal_with_double_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#double"}}); @@ -4725,7 +4760,7 @@ TEST(high_precision_fraction_decimal_literal_with_decimal_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#decimal"}}); @@ -4760,7 +4795,7 @@ TEST(maximum_double_decimal_literal_with_double_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#double"}}); @@ -4796,7 +4831,7 @@ TEST(json_literal_ignores_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#decimal", .json = true}}); @@ -4829,7 +4864,7 @@ TEST(null_literal_with_decimal_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#decimal"}}); @@ -4859,7 +4894,7 @@ TEST(boundary_exponent_decimal_literal_with_decimal_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#decimal"}}); @@ -4896,7 +4931,7 @@ TEST(above_boundary_exponent_decimal_literal_with_decimal_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#decimal"}}); @@ -4931,7 +4966,7 @@ TEST(below_boundary_exponent_decimal_literal_with_decimal_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#decimal"}}); @@ -4966,7 +5001,7 @@ TEST(maximum_exponent_decimal_literal_with_decimal_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#decimal"}}); @@ -5001,7 +5036,7 @@ TEST(minimum_exponent_decimal_literal_with_decimal_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#decimal"}}); @@ -5038,7 +5073,7 @@ TEST(huge_exponent_decimal_literal_with_double_datatype) { annotations.emplace_back( sourcemeta::core::Pointer{"value"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/value", false}}, + .edges = {{.predicate = "https://example.com/value"}}, .value = sourcemeta::core::JSONLDLiteral{ .datatype = "http://www.w3.org/2001/XMLSchema#double"}}); @@ -5074,10 +5109,11 @@ TEST(node_with_constants) { annotations.emplace_back(sourcemeta::core::Pointer{}, sourcemeta::core::JSONLDDescriptor{ .edges = {}, .value = std::move(node)}); - annotations.emplace_back(sourcemeta::core::Pointer{"name"}, - sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/name", false}}, - .value = sourcemeta::core::JSONLDLiteral{}}); + annotations.emplace_back( + sourcemeta::core::Pointer{"name"}, + sourcemeta::core::JSONLDDescriptor{ + .edges = {{.predicate = "https://schema.org/name"}}, + .value = sourcemeta::core::JSONLDLiteral{}}); const auto expected = sourcemeta::core::parse_json(R"([ { @@ -5109,10 +5145,11 @@ TEST(node_constants_dedupe_against_instance_members) { annotations.emplace_back(sourcemeta::core::Pointer{}, sourcemeta::core::JSONLDDescriptor{ .edges = {}, .value = std::move(node)}); - annotations.emplace_back(sourcemeta::core::Pointer{"kind"}, - sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/kind", false}}, - .value = sourcemeta::core::JSONLDLiteral{}}); + annotations.emplace_back( + sourcemeta::core::Pointer{"kind"}, + sourcemeta::core::JSONLDDescriptor{ + .edges = {{.predicate = "https://example.com/kind"}}, + .value = sourcemeta::core::JSONLDLiteral{}}); const auto expected = sourcemeta::core::parse_json(R"([ { @@ -5144,10 +5181,11 @@ TEST(graph_node_constants_on_inner_subject) { annotations.emplace_back(sourcemeta::core::Pointer{}, sourcemeta::core::JSONLDDescriptor{ .edges = {}, .value = std::move(node)}); - annotations.emplace_back(sourcemeta::core::Pointer{"name"}, - sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://schema.org/name", false}}, - .value = sourcemeta::core::JSONLDLiteral{}}); + annotations.emplace_back( + sourcemeta::core::Pointer{"name"}, + sourcemeta::core::JSONLDDescriptor{ + .edges = {{.predicate = "https://schema.org/name"}}, + .value = sourcemeta::core::JSONLDLiteral{}}); const auto expected = sourcemeta::core::parse_json(R"([ { @@ -5183,7 +5221,7 @@ TEST(reference_with_constants_renders_node_object) { annotations.emplace_back( sourcemeta::core::Pointer{"code"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/currency", false}}, + .edges = {{.predicate = "https://example.com/currency"}}, .value = std::move(reference)}); const auto expected = sourcemeta::core::parse_json(R"([ @@ -5216,10 +5254,11 @@ TEST(promotion_with_constants) { })"); sourcemeta::core::JSONLDAnnotationList annotations; - annotations.emplace_back(sourcemeta::core::Pointer{"height"}, - sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/height", false}}, - .value = std::move(promotion)}); + annotations.emplace_back( + sourcemeta::core::Pointer{"height"}, + sourcemeta::core::JSONLDDescriptor{ + .edges = {{.predicate = "https://example.com/height"}}, + .value = std::move(promotion)}); const auto expected = sourcemeta::core::parse_json(R"([ { @@ -5247,10 +5286,11 @@ TEST(promotion_typed_inner_literal_canonical_lexical_form) { promotion.literal.datatype = "http://www.w3.org/2001/XMLSchema#decimal"; sourcemeta::core::JSONLDAnnotationList annotations; - annotations.emplace_back(sourcemeta::core::Pointer{"height"}, - sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/height", false}}, - .value = std::move(promotion)}); + annotations.emplace_back( + sourcemeta::core::Pointer{"height"}, + sourcemeta::core::JSONLDDescriptor{ + .edges = {{.predicate = "https://example.com/height"}}, + .value = std::move(promotion)}); const auto expected = sourcemeta::core::parse_json(R"([ { @@ -5281,10 +5321,11 @@ TEST(promotion_language_inner_literal) { promotion.literal.language = "es"; sourcemeta::core::JSONLDAnnotationList annotations; - annotations.emplace_back(sourcemeta::core::Pointer{"name"}, - sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/name", false}}, - .value = std::move(promotion)}); + annotations.emplace_back( + sourcemeta::core::Pointer{"name"}, + sourcemeta::core::JSONLDDescriptor{ + .edges = {{.predicate = "https://example.com/name"}}, + .value = std::move(promotion)}); const auto expected = sourcemeta::core::parse_json(R"([ { @@ -5314,10 +5355,11 @@ TEST(promotion_null_instance_emits_nothing) { })"); sourcemeta::core::JSONLDAnnotationList annotations; - annotations.emplace_back(sourcemeta::core::Pointer{"height"}, - sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/height", false}}, - .value = std::move(promotion)}); + annotations.emplace_back( + sourcemeta::core::Pointer{"height"}, + sourcemeta::core::JSONLDDescriptor{ + .edges = {{.predicate = "https://example.com/height"}}, + .value = std::move(promotion)}); const auto expected = sourcemeta::core::parse_json(R"([])"); const auto result{ @@ -5422,7 +5464,7 @@ TEST(promotion_anonymous_list_member_survives) { annotations.emplace_back( sourcemeta::core::Pointer{"heights"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/heights", false}}, + .edges = {{.predicate = "https://example.com/heights"}}, .value = sourcemeta::core::JSONLDCollection{ .container = sourcemeta::core::JSONLDContainer::List}}); annotations.emplace_back(sourcemeta::core::Pointer{"heights", 0}, @@ -5461,10 +5503,11 @@ TEST(promotion_value_predicate_collision_unions) { })"); sourcemeta::core::JSONLDAnnotationList annotations; - annotations.emplace_back(sourcemeta::core::Pointer{"height"}, - sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/height", false}}, - .value = std::move(promotion)}); + annotations.emplace_back( + sourcemeta::core::Pointer{"height"}, + sourcemeta::core::JSONLDDescriptor{ + .edges = {{.predicate = "https://example.com/height"}}, + .value = std::move(promotion)}); const auto expected = sourcemeta::core::parse_json(R"([ { @@ -5495,10 +5538,11 @@ TEST(promotion_value_predicate_collision_dedupes_equal_terms) { })"); sourcemeta::core::JSONLDAnnotationList annotations; - annotations.emplace_back(sourcemeta::core::Pointer{"height"}, - sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/height", false}}, - .value = std::move(promotion)}); + annotations.emplace_back( + sourcemeta::core::Pointer{"height"}, + sourcemeta::core::JSONLDDescriptor{ + .edges = {{.predicate = "https://example.com/height"}}, + .value = std::move(promotion)}); const auto expected = sourcemeta::core::parse_json(R"([ { @@ -5523,8 +5567,8 @@ TEST(promotion_under_multiple_edges_distinct_nodes) { annotations.emplace_back( sourcemeta::core::Pointer{"height"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/height", false}, - {"https://example.com/stature", false}}, + .edges = {{.predicate = "https://example.com/height"}, + {.predicate = "https://example.com/stature"}}, .value = std::move(promotion)}); const auto expected = sourcemeta::core::parse_json(R"([ @@ -5554,7 +5598,8 @@ TEST(promotion_reverse_edge) { annotations.emplace_back( sourcemeta::core::Pointer{"height"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/measurementOf", true}}, + .edges = {{.predicate = "https://example.com/measurementOf", + .reverse = true}}, .value = std::move(promotion)}); const auto expected = sourcemeta::core::parse_json(R"([ @@ -5583,7 +5628,7 @@ TEST(promotion_index_container_member_keeps_index) { annotations.emplace_back( sourcemeta::core::Pointer{"readings"}, sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/readings", false}}, + .edges = {{.predicate = "https://example.com/readings"}}, .value = sourcemeta::core::JSONLDCollection{ .container = sourcemeta::core::JSONLDContainer::Index}}); annotations.emplace_back(sourcemeta::core::Pointer{"readings", "morning"}, @@ -5615,10 +5660,11 @@ TEST(promotion_empty_constants_no_op) { promotion.constants = sourcemeta::core::JSON::make_object(); sourcemeta::core::JSONLDAnnotationList annotations; - annotations.emplace_back(sourcemeta::core::Pointer{"height"}, - sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/height", false}}, - .value = std::move(promotion)}); + annotations.emplace_back( + sourcemeta::core::Pointer{"height"}, + sourcemeta::core::JSONLDDescriptor{ + .edges = {{.predicate = "https://example.com/height"}}, + .value = std::move(promotion)}); const auto expected = sourcemeta::core::parse_json(R"([ { @@ -5644,10 +5690,11 @@ TEST(promotion_output_flattens) { })"); sourcemeta::core::JSONLDAnnotationList annotations; - annotations.emplace_back(sourcemeta::core::Pointer{"height"}, - sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/height", false}}, - .value = std::move(promotion)}); + annotations.emplace_back( + sourcemeta::core::Pointer{"height"}, + sourcemeta::core::JSONLDDescriptor{ + .edges = {{.predicate = "https://example.com/height"}}, + .value = std::move(promotion)}); const auto expanded{ sourcemeta::core::jsonld_materialize(instance, annotations)}; @@ -5667,10 +5714,11 @@ TEST(promotion_output_compacts_and_re_expands) { })"); sourcemeta::core::JSONLDAnnotationList annotations; - annotations.emplace_back(sourcemeta::core::Pointer{"height"}, - sourcemeta::core::JSONLDDescriptor{ - .edges = {{"https://example.com/height", false}}, - .value = std::move(promotion)}); + annotations.emplace_back( + sourcemeta::core::Pointer{"height"}, + sourcemeta::core::JSONLDDescriptor{ + .edges = {{.predicate = "https://example.com/height"}}, + .value = std::move(promotion)}); const auto expanded{ sourcemeta::core::jsonld_materialize(instance, annotations)}; diff --git a/test/jsonpath/jsonpath_evaluate_test.cc b/test/jsonpath/jsonpath_evaluate_test.cc index 8357de7b77..7c77b4cd26 100644 --- a/test/jsonpath/jsonpath_evaluate_test.cc +++ b/test/jsonpath/jsonpath_evaluate_test.cc @@ -20,7 +20,7 @@ auto evaluate_nodes(const sourcemeta::core::JSONPath &path, document, [&result](const sourcemeta::core::JSON &value, const sourcemeta::core::WeakPointer &location) -> void { - result.push_back({&value, location}); + result.push_back({.value = &value, .location = location}); }); return result; } @@ -282,6 +282,7 @@ TEST(jsonpath_evaluate_deep_name_chain_document) { TEST(jsonpath_evaluate_copy_construction) { const auto document{sourcemeta::core::parse_json(R"JSON({ "a": 1 })JSON")}; const sourcemeta::core::JSONPath original{"$.a"}; + // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) const sourcemeta::core::JSONPath copy{original}; EXPECT_EQ(evaluate_nodes(original, document).size(), 1); EXPECT_EQ(evaluate_nodes(copy, document).size(), 1); diff --git a/test/jsonpath/jsonpath_filter_test.cc b/test/jsonpath/jsonpath_filter_test.cc index a7f849ecac..a347209f14 100644 --- a/test/jsonpath/jsonpath_filter_test.cc +++ b/test/jsonpath/jsonpath_filter_test.cc @@ -20,7 +20,7 @@ auto evaluate_nodes(const sourcemeta::core::JSONPath &path, document, [&result](const sourcemeta::core::JSON &value, const sourcemeta::core::WeakPointer &location) -> void { - result.push_back({&value, location}); + result.push_back({.value = &value, .location = location}); }); return result; } diff --git a/test/jsonpath/jsonpath_suite.cc b/test/jsonpath/jsonpath_suite.cc index 227c1a7c73..e151c6c2e8 100644 --- a/test/jsonpath/jsonpath_suite.cc +++ b/test/jsonpath/jsonpath_suite.cc @@ -23,7 +23,7 @@ auto evaluate_nodes(const sourcemeta::core::JSONPath &path, document, [&result](const sourcemeta::core::JSON &value, const sourcemeta::core::WeakPointer &location) -> void { - result.push_back({&value, location}); + result.push_back({.value = &value, .location = location}); }); return result; } diff --git a/test/jsonpointer/jsonpointer_error_test.cc b/test/jsonpointer/jsonpointer_error_test.cc index fd606bb05c..97a3fa6181 100644 --- a/test/jsonpointer/jsonpointer_error_test.cc +++ b/test/jsonpointer/jsonpointer_error_test.cc @@ -10,9 +10,9 @@ TEST(parse_error) { static_assert( std::is_base_of_v, "Must subclass std::exception"); - auto exception{sourcemeta::core::PointerParseError(5)}; + const auto exception{sourcemeta::core::PointerParseError(5)}; try { - throw exception; + throw sourcemeta::core::PointerParseError{5}; FAIL(); } catch (const sourcemeta::core::PointerParseError &error) { EXPECT_STREQ(error.what(), "The input is not a valid JSON Pointer"); diff --git a/test/jsonpointer/jsonpointer_is_relative_pointer_test.cc b/test/jsonpointer/jsonpointer_is_relative_pointer_test.cc index 75c53687aa..fac27c78e5 100644 --- a/test/jsonpointer/jsonpointer_is_relative_pointer_test.cc +++ b/test/jsonpointer/jsonpointer_is_relative_pointer_test.cc @@ -1,7 +1,9 @@ #include #include -#include +#include // std::string_view + +using namespace std::literals::string_view_literals; TEST(valid_zero) { EXPECT_TRUE(sourcemeta::core::is_relative_pointer("0")); } @@ -421,29 +423,26 @@ TEST(valid_tab_inside_reference_token) { // embedded NUL - legal in a token; a truncating validator would differ TEST(valid_nul_inside_reference_token) { - static constexpr char VALUE[]{"0/foo\x00" - "bar"}; - static_assert(sizeof(VALUE) - 1 == 9, + static constexpr auto VALUE{"0/foo\x00" + "bar"sv}; + static_assert(VALUE.size() == 9, "string literal length changed - check \\xNN escaping"); - EXPECT_TRUE( - sourcemeta::core::is_relative_pointer(std::string_view{VALUE, 9})); + EXPECT_TRUE(sourcemeta::core::is_relative_pointer(VALUE)); } TEST(invalid_nul_then_dangling_tilde) { - static constexpr char VALUE[]{"0/foo\x00~"}; - static_assert(sizeof(VALUE) - 1 == 7, + static constexpr auto VALUE{"0/foo\x00~"sv}; + static_assert(VALUE.size() == 7, "string literal length changed - check \\xNN escaping"); - EXPECT_FALSE( - sourcemeta::core::is_relative_pointer(std::string_view{VALUE, 7})); + EXPECT_FALSE(sourcemeta::core::is_relative_pointer(VALUE)); } TEST(invalid_nul_before_integer) { - static constexpr char VALUE[]{"\x00" - "0"}; - static_assert(sizeof(VALUE) - 1 == 2, + static constexpr auto VALUE{"\x00" + "0"sv}; + static_assert(VALUE.size() == 2, "string literal length changed - check \\xNN escaping"); - EXPECT_FALSE( - sourcemeta::core::is_relative_pointer(std::string_view{VALUE, 2})); + EXPECT_FALSE(sourcemeta::core::is_relative_pointer(VALUE)); } // escape sequences inherited from RFC 6901 section 3 through the wrapper diff --git a/test/jsonpointer/jsonpointer_pointer_test.cc b/test/jsonpointer/jsonpointer_pointer_test.cc index d37a40acef..c114d0a403 100644 --- a/test/jsonpointer/jsonpointer_pointer_test.cc +++ b/test/jsonpointer/jsonpointer_pointer_test.cc @@ -6,29 +6,25 @@ #include TEST(general_traits) { - EXPECT_TRUE(std::is_default_constructible::value); + EXPECT_TRUE(std::is_default_constructible_v); EXPECT_TRUE( - std::is_nothrow_default_constructible::value); - EXPECT_TRUE(std::is_destructible::value); - EXPECT_TRUE(std::is_nothrow_destructible::value); + std::is_nothrow_default_constructible_v); + EXPECT_TRUE(std::is_destructible_v); + EXPECT_TRUE(std::is_nothrow_destructible_v); } TEST(copy_traits) { - EXPECT_TRUE(std::is_copy_assignable::value); - EXPECT_TRUE(std::is_copy_constructible::value); - EXPECT_FALSE( - std::is_nothrow_copy_assignable::value); - EXPECT_FALSE( - std::is_nothrow_copy_constructible::value); + EXPECT_TRUE(std::is_copy_assignable_v); + EXPECT_TRUE(std::is_copy_constructible_v); + EXPECT_FALSE(std::is_nothrow_copy_assignable_v); + EXPECT_FALSE(std::is_nothrow_copy_constructible_v); } TEST(move_traits) { - EXPECT_TRUE(std::is_move_assignable::value); - EXPECT_TRUE(std::is_move_constructible::value); - EXPECT_TRUE( - std::is_nothrow_move_assignable::value); - EXPECT_TRUE( - std::is_nothrow_move_constructible::value); + EXPECT_TRUE(std::is_move_assignable_v); + EXPECT_TRUE(std::is_move_constructible_v); + EXPECT_TRUE(std::is_nothrow_move_assignable_v); + EXPECT_TRUE(std::is_nothrow_move_constructible_v); } TEST(empty) { diff --git a/test/jsonpointer/jsonpointer_position_test.cc b/test/jsonpointer/jsonpointer_position_test.cc index 7f61039370..7f8ce5ad65 100644 --- a/test/jsonpointer/jsonpointer_position_test.cc +++ b/test/jsonpointer/jsonpointer_position_test.cc @@ -3,7 +3,7 @@ #include TEST(track_1) { - const auto input{R"JSON([ + const auto *const input{R"JSON([ { "foo": { "bar": 3 @@ -39,7 +39,7 @@ TEST(track_1) { } TEST(track_index_token_against_object_member) { - const auto input{R"JSON({ "0": 1 })JSON"}; + const auto *const input{R"JSON({ "0": 1 })JSON"}; sourcemeta::core::PointerPositionTracker tracker; sourcemeta::core::JSON result{nullptr}; @@ -55,7 +55,7 @@ TEST(track_index_token_against_object_member) { } TEST(track_index_token_against_array_element) { - const auto input{R"JSON([ 10, 20 ])JSON"}; + const auto *const input{R"JSON([ 10, 20 ])JSON"}; sourcemeta::core::PointerPositionTracker tracker; sourcemeta::core::JSON result{nullptr}; @@ -68,7 +68,7 @@ TEST(track_index_token_against_array_element) { } TEST(to_json_1) { - const auto input{R"JSON([ + const auto *const input{R"JSON([ { "foo": { "bar": 3 diff --git a/test/jsonpointer/jsonpointer_set_test.cc b/test/jsonpointer/jsonpointer_set_test.cc index 0229610f87..18ba487f64 100644 --- a/test/jsonpointer/jsonpointer_set_test.cc +++ b/test/jsonpointer/jsonpointer_set_test.cc @@ -85,7 +85,7 @@ TEST(array_element_to_integer_copy) { TEST(hyphen_property_in_object) { sourcemeta::core::JSON document = - sourcemeta::core::parse_json("{ \"foo\": { \"-\": 1 } }"); + sourcemeta::core::parse_json(R"({ "foo": { "-": 1 } })"); const sourcemeta::core::Pointer pointer{"foo", "-"}; sourcemeta::core::set(document, pointer, sourcemeta::core::JSON{2}); EXPECT_TRUE(document.is_object()); diff --git a/test/jsonpointer/jsonpointer_token_test.cc b/test/jsonpointer/jsonpointer_token_test.cc index 04d9004019..4ed543bd13 100644 --- a/test/jsonpointer/jsonpointer_token_test.cc +++ b/test/jsonpointer/jsonpointer_token_test.cc @@ -7,32 +7,29 @@ TEST(general_traits) { EXPECT_FALSE( - std::is_default_constructible::value); - EXPECT_FALSE(std::is_nothrow_default_constructible< - sourcemeta::core::Pointer::Token>::value); - EXPECT_TRUE(std::is_destructible::value); - EXPECT_TRUE( - std::is_nothrow_destructible::value); + std::is_default_constructible_v); + EXPECT_FALSE(std::is_nothrow_default_constructible_v< + sourcemeta::core::Pointer::Token>); + EXPECT_TRUE(std::is_destructible_v); + EXPECT_TRUE(std::is_nothrow_destructible_v); } TEST(copy_traits) { - EXPECT_TRUE(std::is_copy_assignable::value); - EXPECT_TRUE( - std::is_copy_constructible::value); + EXPECT_TRUE(std::is_copy_assignable_v); + EXPECT_TRUE(std::is_copy_constructible_v); + EXPECT_FALSE( + std::is_nothrow_copy_assignable_v); EXPECT_FALSE( - std::is_nothrow_copy_assignable::value); - EXPECT_FALSE(std::is_nothrow_copy_constructible< - sourcemeta::core::Pointer::Token>::value); + std::is_nothrow_copy_constructible_v); } TEST(move_traits) { - EXPECT_TRUE(std::is_move_assignable::value); + EXPECT_TRUE(std::is_move_assignable_v); + EXPECT_TRUE(std::is_move_constructible_v); EXPECT_TRUE( - std::is_move_constructible::value); + std::is_nothrow_move_assignable_v); EXPECT_TRUE( - std::is_nothrow_move_assignable::value); - EXPECT_TRUE(std::is_nothrow_move_constructible< - sourcemeta::core::Pointer::Token>::value); + std::is_nothrow_move_constructible_v); } TEST(character_token) { diff --git a/test/jsonpointer/jsonpointer_try_get_test.cc b/test/jsonpointer/jsonpointer_try_get_test.cc index 1f48dd2893..2f9aecfc8a 100644 --- a/test/jsonpointer/jsonpointer_try_get_test.cc +++ b/test/jsonpointer/jsonpointer_try_get_test.cc @@ -5,7 +5,7 @@ TEST(empty_on_integer) { const sourcemeta::core::JSON document{5}; const sourcemeta::core::Pointer pointer; - const auto result{sourcemeta::core::try_get(document, pointer)}; + const auto *const result{sourcemeta::core::try_get(document, pointer)}; EXPECT_TRUE(result); EXPECT_EQ(*result, document); } @@ -16,7 +16,7 @@ TEST(empty_on_object) { })JSON")}; const sourcemeta::core::Pointer pointer; - const auto result{sourcemeta::core::try_get(document, pointer)}; + const auto *const result{sourcemeta::core::try_get(document, pointer)}; EXPECT_TRUE(result); EXPECT_EQ(*result, document); } @@ -24,7 +24,7 @@ TEST(empty_on_object) { TEST(empty_on_array) { const auto document{sourcemeta::core::parse_json(R"JSON([ 1, 2, 3 ])JSON")}; const sourcemeta::core::Pointer pointer; - const auto result{sourcemeta::core::try_get(document, pointer)}; + const auto *const result{sourcemeta::core::try_get(document, pointer)}; EXPECT_TRUE(result); EXPECT_EQ(*result, document); } @@ -35,7 +35,7 @@ TEST(top_level_property_true) { })JSON")}; const sourcemeta::core::Pointer pointer{"foo"}; - const auto result{sourcemeta::core::try_get(document, pointer)}; + const auto *const result{sourcemeta::core::try_get(document, pointer)}; EXPECT_TRUE(result); EXPECT_EQ(*result, document.at("foo")); } @@ -46,7 +46,7 @@ TEST(top_level_property_false) { })JSON")}; const sourcemeta::core::Pointer pointer{"bar"}; - const auto result{sourcemeta::core::try_get(document, pointer)}; + const auto *const result{sourcemeta::core::try_get(document, pointer)}; EXPECT_FALSE(result); } @@ -54,7 +54,7 @@ TEST(top_level_index_true) { const auto document{sourcemeta::core::parse_json(R"JSON([ 1, 2, 3 ])JSON")}; const sourcemeta::core::Pointer pointer{2}; - const auto result{sourcemeta::core::try_get(document, pointer)}; + const auto *const result{sourcemeta::core::try_get(document, pointer)}; EXPECT_TRUE(result); EXPECT_EQ(*result, document.at(2)); } @@ -63,7 +63,7 @@ TEST(top_level_index_false) { const auto document{sourcemeta::core::parse_json(R"JSON([ 1, 2, 3 ])JSON")}; const sourcemeta::core::Pointer pointer{3}; - const auto result{sourcemeta::core::try_get(document, pointer)}; + const auto *const result{sourcemeta::core::try_get(document, pointer)}; EXPECT_FALSE(result); } @@ -73,7 +73,7 @@ TEST(top_level_numeric_property_true) { })JSON")}; const sourcemeta::core::Pointer pointer{"0"}; - const auto result{sourcemeta::core::try_get(document, pointer)}; + const auto *const result{sourcemeta::core::try_get(document, pointer)}; EXPECT_TRUE(result); EXPECT_EQ(*result, document.at("0")); } @@ -84,7 +84,7 @@ TEST(top_level_numeric_property_as_index_true) { })JSON")}; const sourcemeta::core::Pointer pointer{0}; - const auto result{sourcemeta::core::try_get(document, pointer)}; + const auto *const result{sourcemeta::core::try_get(document, pointer)}; EXPECT_TRUE(result); EXPECT_EQ(*result, document.at("0")); } @@ -97,7 +97,7 @@ TEST(complex_true) { })JSON")}; const sourcemeta::core::Pointer pointer{"foo", "bar", 2, "baz"}; - const auto result{sourcemeta::core::try_get(document, pointer)}; + const auto *const result{sourcemeta::core::try_get(document, pointer)}; EXPECT_TRUE(result); EXPECT_EQ(*result, document.at("foo").at("bar").at(2).at("baz")); } @@ -110,7 +110,7 @@ TEST(complex_false) { })JSON")}; const sourcemeta::core::Pointer pointer{"foo", 2, "baz"}; - const auto result{sourcemeta::core::try_get(document, pointer)}; + const auto *const result{sourcemeta::core::try_get(document, pointer)}; EXPECT_FALSE(result); } @@ -122,7 +122,7 @@ TEST(complex_non_existent_property) { })JSON")}; const sourcemeta::core::Pointer pointer{"foo", 2, "xxx"}; - const auto result{sourcemeta::core::try_get(document, pointer)}; + const auto *const result{sourcemeta::core::try_get(document, pointer)}; EXPECT_FALSE(result); } @@ -134,21 +134,21 @@ TEST(complex_non_existent_index) { })JSON")}; const sourcemeta::core::Pointer pointer{"foo", 9, "xxx"}; - const auto result{sourcemeta::core::try_get(document, pointer)}; + const auto *const result{sourcemeta::core::try_get(document, pointer)}; EXPECT_FALSE(result); } TEST(non_object) { const sourcemeta::core::JSON document{"foo"}; const sourcemeta::core::Pointer pointer{"bar"}; - const auto result{sourcemeta::core::try_get(document, pointer)}; + const auto *const result{sourcemeta::core::try_get(document, pointer)}; EXPECT_FALSE(result); } TEST(non_array) { const sourcemeta::core::JSON document{"foo"}; const sourcemeta::core::Pointer pointer{2}; - const auto result{sourcemeta::core::try_get(document, pointer)}; + const auto *const result{sourcemeta::core::try_get(document, pointer)}; EXPECT_FALSE(result); } @@ -158,7 +158,7 @@ TEST(out_of_range_index_resolves_object_member) { })JSON")}; const auto pointer{sourcemeta::core::to_pointer("/18446744073709551616")}; - const auto result{sourcemeta::core::try_get(document, pointer)}; + const auto *const result{sourcemeta::core::try_get(document, pointer)}; EXPECT_TRUE(result); EXPECT_EQ(*result, document.at("18446744073709551616")); } @@ -166,6 +166,6 @@ TEST(out_of_range_index_resolves_object_member) { TEST(out_of_range_index_not_found_against_array) { const auto document{sourcemeta::core::parse_json(R"JSON([ 1, 2, 3 ])JSON")}; const auto pointer{sourcemeta::core::to_pointer("/18446744073709551616")}; - const auto result{sourcemeta::core::try_get(document, pointer)}; + const auto *const result{sourcemeta::core::try_get(document, pointer)}; EXPECT_FALSE(result); } diff --git a/test/jsonpointer/jsonpointer_walker_test.cc b/test/jsonpointer/jsonpointer_walker_test.cc index 9a99132131..9f2d85d0e2 100644 --- a/test/jsonpointer/jsonpointer_walker_test.cc +++ b/test/jsonpointer/jsonpointer_walker_test.cc @@ -134,7 +134,7 @@ TEST(object_empty) { TEST(object_scalars) { const sourcemeta::core::JSON document = - sourcemeta::core::parse_json("{ \"foo\": 1, \"bar\": 2, \"baz\": 3 }"); + sourcemeta::core::parse_json(R"({ "foo": 1, "bar": 2, "baz": 3 })"); // Do a set to not depend on object property ordering std::set subpointers; for (const auto &subpointer : sourcemeta::core::PointerWalker{document}) { @@ -150,7 +150,7 @@ TEST(object_scalars) { TEST(object_nested) { const sourcemeta::core::JSON document = - sourcemeta::core::parse_json("{ \"foo\": { \"bar\": 1 } }"); + sourcemeta::core::parse_json(R"({ "foo": { "bar": 1 } })"); std::vector subpointers; for (const auto &subpointer : sourcemeta::core::PointerWalker{document}) { subpointers.push_back(sourcemeta::core::to_string(subpointer)); diff --git a/test/jsonpointer/jsonpointer_weakpointer_test.cc b/test/jsonpointer/jsonpointer_weakpointer_test.cc index e54ce88f94..31d210d7e4 100644 --- a/test/jsonpointer/jsonpointer_weakpointer_test.cc +++ b/test/jsonpointer/jsonpointer_weakpointer_test.cc @@ -10,37 +10,37 @@ #include #include +// A weak pointer refers to these by address, so they need real storage +// NOLINTBEGIN(cert-err58-cpp,bugprone-throwing-static-initialization) static const std::string FOO = "foo"; static const std::string BAR = "bar"; static const std::string BAZ = "baz"; static const std::string QUX = "qux"; +// NOLINTEND(cert-err58-cpp,bugprone-throwing-static-initialization) TEST(general_traits) { + EXPECT_TRUE(std::is_default_constructible_v); EXPECT_TRUE( - std::is_default_constructible::value); - EXPECT_TRUE(std::is_nothrow_default_constructible< - sourcemeta::core::WeakPointer>::value); - EXPECT_TRUE(std::is_destructible::value); - EXPECT_TRUE( - std::is_nothrow_destructible::value); + std::is_nothrow_default_constructible_v); + EXPECT_TRUE(std::is_destructible_v); + EXPECT_TRUE(std::is_nothrow_destructible_v); } TEST(copy_traits) { - EXPECT_TRUE(std::is_copy_assignable::value); - EXPECT_TRUE(std::is_copy_constructible::value); + EXPECT_TRUE(std::is_copy_assignable_v); + EXPECT_TRUE(std::is_copy_constructible_v); EXPECT_FALSE( - std::is_nothrow_copy_assignable::value); + std::is_nothrow_copy_assignable_v); EXPECT_FALSE( - std::is_nothrow_copy_constructible::value); + std::is_nothrow_copy_constructible_v); } TEST(move_traits) { - EXPECT_TRUE(std::is_move_assignable::value); - EXPECT_TRUE(std::is_move_constructible::value); - EXPECT_TRUE( - std::is_nothrow_move_assignable::value); + EXPECT_TRUE(std::is_move_assignable_v); + EXPECT_TRUE(std::is_move_constructible_v); + EXPECT_TRUE(std::is_nothrow_move_assignable_v); EXPECT_TRUE( - std::is_nothrow_move_constructible::value); + std::is_nothrow_move_constructible_v); } TEST(empty) { @@ -289,7 +289,7 @@ TEST(try_get_complex_true) { const sourcemeta::core::WeakPointer pointer{std::cref(FOO), std::cref(BAR), 2, std::cref(BAZ)}; - const auto result{sourcemeta::core::try_get(document, pointer)}; + const auto *const result{sourcemeta::core::try_get(document, pointer)}; EXPECT_TRUE(result); EXPECT_EQ(*result, document.at("foo").at("bar").at(2).at("baz")); } @@ -304,7 +304,7 @@ TEST(try_get_complex_false) { const sourcemeta::core::WeakPointer pointer{std::cref(FOO), 2, std::cref(BAZ)}; - const auto result{sourcemeta::core::try_get(document, pointer)}; + const auto *const result{sourcemeta::core::try_get(document, pointer)}; EXPECT_FALSE(result); } diff --git a/test/mcp/mcp_test.cc b/test/mcp/mcp_test.cc index 5cbe0b1dd4..bfe5e86299 100644 --- a/test/mcp/mcp_test.cc +++ b/test/mcp/mcp_test.cc @@ -870,7 +870,11 @@ TEST(make_initialize_result_minimal_2025_11_25) { "params": { "protocolVersion": "2025-11-25" } })JSON")}; const sourcemeta::core::MCPServerCapabilities capabilities; - const sourcemeta::core::MCPImplementation server{"srv", "1.0.0", {}, {}, {}}; + const sourcemeta::core::MCPImplementation server{.name = "srv", + .version = "1.0.0", + .title = {}, + .description = {}, + .website_url = {}}; const auto envelope{sourcemeta::core::mcp_make_initialize_result( request, capabilities, server)}; const auto expected{sourcemeta::core::parse_json(R"JSON({ @@ -893,7 +897,11 @@ TEST(make_initialize_result_missing_protocol_version_is_invalid_params) { "params": {} })JSON")}; const sourcemeta::core::MCPServerCapabilities capabilities; - const sourcemeta::core::MCPImplementation server{"srv", "1.0.0", {}, {}, {}}; + const sourcemeta::core::MCPImplementation server{.name = "srv", + .version = "1.0.0", + .title = {}, + .description = {}, + .website_url = {}}; const auto envelope{sourcemeta::core::mcp_make_initialize_result( request, capabilities, server)}; const auto expected{sourcemeta::core::parse_json(R"JSON({ @@ -912,7 +920,11 @@ TEST(make_initialize_result_non_string_protocol_version_is_invalid_params) { "params": { "protocolVersion": 123 } })JSON")}; const sourcemeta::core::MCPServerCapabilities capabilities; - const sourcemeta::core::MCPImplementation server{"srv", "1.0.0", {}, {}, {}}; + const sourcemeta::core::MCPImplementation server{.name = "srv", + .version = "1.0.0", + .title = {}, + .description = {}, + .website_url = {}}; const auto envelope{sourcemeta::core::mcp_make_initialize_result( request, capabilities, server)}; const auto expected{sourcemeta::core::parse_json(R"JSON({ @@ -931,7 +943,11 @@ TEST(make_initialize_result_unsupported_protocol_version_negotiates_latest) { "params": { "protocolVersion": "9999-01-01" } })JSON")}; const sourcemeta::core::MCPServerCapabilities capabilities; - const sourcemeta::core::MCPImplementation server{"srv", "1.0.0", {}, {}, {}}; + const sourcemeta::core::MCPImplementation server{.name = "srv", + .version = "1.0.0", + .title = {}, + .description = {}, + .website_url = {}}; const auto envelope{sourcemeta::core::mcp_make_initialize_result( request, capabilities, server)}; const auto expected{sourcemeta::core::parse_json(R"JSON({ @@ -959,7 +975,11 @@ TEST(make_initialize_result_with_all_capabilities) { capabilities.tools = true; capabilities.logging = true; capabilities.completions = true; - const sourcemeta::core::MCPImplementation server{"srv", "1.0.0", {}, {}, {}}; + const sourcemeta::core::MCPImplementation server{.name = "srv", + .version = "1.0.0", + .title = {}, + .description = {}, + .website_url = {}}; const auto envelope{sourcemeta::core::mcp_make_initialize_result( request, capabilities, server)}; const auto expected{sourcemeta::core::parse_json(R"JSON({ @@ -988,7 +1008,11 @@ TEST(make_initialize_result_includes_instructions_when_provided) { "params": { "protocolVersion": "2025-11-25" } })JSON")}; const sourcemeta::core::MCPServerCapabilities capabilities; - const sourcemeta::core::MCPImplementation server{"srv", "1.0.0", {}, {}, {}}; + const sourcemeta::core::MCPImplementation server{.name = "srv", + .version = "1.0.0", + .title = {}, + .description = {}, + .website_url = {}}; const auto envelope{sourcemeta::core::mcp_make_initialize_result( request, capabilities, server, "Be careful.")}; EXPECT_EQ(envelope.at("result").at("instructions").to_string(), @@ -1003,8 +1027,11 @@ TEST(make_initialize_result_includes_title_on_2025_06_18) { "params": { "protocolVersion": "2025-06-18" } })JSON")}; const sourcemeta::core::MCPServerCapabilities capabilities; - const sourcemeta::core::MCPImplementation server{"srv", "1.0.0", "Server", - "desc", "https://x"}; + const sourcemeta::core::MCPImplementation server{.name = "srv", + .version = "1.0.0", + .title = "Server", + .description = "desc", + .website_url = "https://x"}; const auto envelope{sourcemeta::core::mcp_make_initialize_result( request, capabilities, server)}; EXPECT_EQ(envelope.at("result").at("serverInfo").at("title").to_string(), @@ -1021,8 +1048,11 @@ TEST(make_initialize_result_includes_full_implementation_on_2025_11_25) { "params": { "protocolVersion": "2025-11-25" } })JSON")}; const sourcemeta::core::MCPServerCapabilities capabilities; - const sourcemeta::core::MCPImplementation server{"srv", "1.0.0", "Server", - "desc", "https://x"}; + const sourcemeta::core::MCPImplementation server{.name = "srv", + .version = "1.0.0", + .title = "Server", + .description = "desc", + .website_url = "https://x"}; const auto envelope{sourcemeta::core::mcp_make_initialize_result( request, capabilities, server)}; EXPECT_EQ(envelope.at("result").at("serverInfo").at("title").to_string(), @@ -1043,8 +1073,11 @@ TEST( "params": { "protocolVersion": "2025-03-26" } })JSON")}; const sourcemeta::core::MCPServerCapabilities capabilities; - const sourcemeta::core::MCPImplementation server{"srv", "1.0.0", "Server", - "desc", "https://x"}; + const sourcemeta::core::MCPImplementation server{.name = "srv", + .version = "1.0.0", + .title = "Server", + .description = "desc", + .website_url = "https://x"}; const auto envelope{sourcemeta::core::mcp_make_initialize_result( request, capabilities, server)}; EXPECT_FALSE(envelope.at("result").at("serverInfo").defines("title")); @@ -1060,7 +1093,11 @@ TEST(make_initialize_result_falls_back_to_2025_11_25_on_unknown_version) { "params": { "protocolVersion": "9999-01-01" } })JSON")}; const sourcemeta::core::MCPServerCapabilities capabilities; - const sourcemeta::core::MCPImplementation server{"srv", "1.0.0", {}, {}, {}}; + const sourcemeta::core::MCPImplementation server{.name = "srv", + .version = "1.0.0", + .title = {}, + .description = {}, + .website_url = {}}; const auto envelope{sourcemeta::core::mcp_make_initialize_result( request, capabilities, server)}; EXPECT_EQ(envelope.at("result").at("protocolVersion").to_string(), @@ -1072,7 +1109,11 @@ TEST(make_initialize_result_returns_invalid_request_when_missing_params) { "jsonrpc": "2.0", "id": 1, "method": "initialize" })JSON")}; const sourcemeta::core::MCPServerCapabilities capabilities; - const sourcemeta::core::MCPImplementation server{"srv", "1.0.0", {}, {}, {}}; + const sourcemeta::core::MCPImplementation server{.name = "srv", + .version = "1.0.0", + .title = {}, + .description = {}, + .website_url = {}}; const auto envelope{sourcemeta::core::mcp_make_initialize_result( request, capabilities, server)}; EXPECT_EQ(envelope.at("error").at("code").to_integer(), @@ -1084,7 +1125,11 @@ TEST(make_initialize_result_returns_invalid_request_when_id_missing) { "jsonrpc": "2.0", "method": "initialize", "params": {} })JSON")}; const sourcemeta::core::MCPServerCapabilities capabilities; - const sourcemeta::core::MCPImplementation server{"srv", "1.0.0", {}, {}, {}}; + const sourcemeta::core::MCPImplementation server{.name = "srv", + .version = "1.0.0", + .title = {}, + .description = {}, + .website_url = {}}; const auto envelope{sourcemeta::core::mcp_make_initialize_result( request, capabilities, server)}; EXPECT_EQ(envelope.at("error").at("code").to_integer(), diff --git a/test/memory/memory_owned_or_reference_test.cc b/test/memory/memory_owned_or_reference_test.cc index d6a1e1e342..ce7ba25ba8 100644 --- a/test/memory/memory_owned_or_reference_test.cc +++ b/test/memory/memory_owned_or_reference_test.cc @@ -4,10 +4,14 @@ #include #include #include +#include // std::string_view #include #include #include +// The reference case asserts on the address of this object, so it needs +// the storage that a view cannot provide +// NOLINTNEXTLINE(cert-err58-cpp,bugprone-throwing-static-initialization) static const std::string CACHED{"cached"}; struct Point { @@ -17,6 +21,8 @@ struct Point { struct HostileAddress { int value{0}; + // The point of this type is that taking its address misbehaves + // NOLINTNEXTLINE(google-runtime-operator) auto operator&() const -> const HostileAddress * { return nullptr; } }; diff --git a/test/numeric/decimal_ibm_dectest.cc b/test/numeric/decimal_ibm_dectest.cc index 59d4601883..40554cca5e 100644 --- a/test/numeric/decimal_ibm_dectest.cc +++ b/test/numeric/decimal_ibm_dectest.cc @@ -3,6 +3,7 @@ #include #include // std::transform, std::any_of +#include // std::array #include // std::tolower, std::isalnum #include // std::size_t #include // std::filesystem @@ -12,26 +13,25 @@ #include // std::string_view #include // std::vector -static constexpr std::string_view SUPPORTED_OPERATIONS[] = { - "compare", "add", "subtract", "multiply", "divide", - "remainder", "minus", "plus", "abs", "tointegral", - "tointegralx", "tosci", "toeng", "copy", "copyabs", - "copynegate", "copysign", "comparesig", "comparetotal", "comparetotmag", - "max", "min", "maxmag", "minmag", "divideint", - "samequantum", "logb", "scaleb", "reduce", "trim"}; +static constexpr std::array SUPPORTED_OPERATIONS{ + {"compare", "add", "subtract", "multiply", "divide", + "remainder", "minus", "plus", "abs", "tointegral", + "tointegralx", "tosci", "toeng", "copy", "copyabs", + "copynegate", "copysign", "comparesig", "comparetotal", "comparetotmag", + "max", "min", "maxmag", "minmag", "divideint", + "samequantum", "logb", "scaleb", "reduce", "trim"}}; -static constexpr std::string_view UNARY_OPERATIONS[] = { - "minus", "plus", "abs", "tointegral", "tointegralx", - "tosci", "toeng", "copy", "copyabs", "copynegate", - "logb", "reduce", "trim"}; +static constexpr std::array UNARY_OPERATIONS{ + {"minus", "plus", "abs", "tointegral", "tointegralx", "tosci", "toeng", + "copy", "copyabs", "copynegate", "logb", "reduce", "trim"}}; -static constexpr std::string_view SKIP_CONDITIONS[] = { - "inexact", "rounded", "overflow", "underflow", - "subnormal", "clamped", "division_impossible"}; +static constexpr std::array SKIP_CONDITIONS{ + {"inexact", "rounded", "overflow", "underflow", "subnormal", "clamped", + "division_impossible"}}; -static constexpr std::string_view KNOWN_DIRECTIVES[] = { - "precision", "rounding", "maxexponent", "minexponent", - "extended", "clamp", "version", "dectest"}; +static constexpr std::array KNOWN_DIRECTIVES{ + {"precision", "rounding", "maxexponent", "minexponent", "extended", "clamp", + "version", "dectest"}}; struct DecTestCase { std::string id; @@ -93,7 +93,7 @@ static auto count_significant_digits(const std::string &value) -> std::size_t { if (character == 'e' || character == 'E') { in_exponent = true; } else if (!in_exponent && - std::isdigit(static_cast(character))) { + (std::isdigit(static_cast(character)) != 0)) { if (character != '0' || found_nonzero) { found_nonzero = true; count++; @@ -185,7 +185,8 @@ static auto run_comparison(const DecTestCase &test_case, bool signal_on_nan) } template -static auto run_binary(const DecTestCase &test_case, Operation op) -> void { +static auto run_binary(const DecTestCase &test_case, Operation operation) + -> void { const auto has_invalid{ has_condition(test_case.conditions, "invalid_operation") || has_condition(test_case.conditions, "division_undefined")}; @@ -194,19 +195,21 @@ static auto run_binary(const DecTestCase &test_case, Operation op) -> void { if (has_invalid) { try { - const auto result{op(make_decimal(test_case.operand1), - make_decimal(test_case.operand2))}; + const auto result{operation(make_decimal(test_case.operand1), + make_decimal(test_case.operand2))}; EXPECT_TRUE(result.is_nan()); } catch (const sourcemeta::core::NumericInvalidOperationError &) { + // Signalling the condition rather than returning NaN is expected too } catch (const sourcemeta::core::NumericDivisionByZeroError &) { + // Signalling the condition rather than returning NaN is expected too } return; } if (has_divzero) { try { - const auto result{op(make_decimal(test_case.operand1), - make_decimal(test_case.operand2))}; + const auto result{operation(make_decimal(test_case.operand1), + make_decimal(test_case.operand2))}; const auto expected_value{make_decimal(test_case.expected)}; if (expected_value.is_infinite() && result.is_infinite()) { EXPECT_EQ(result.is_signed(), expected_value.is_signed()); @@ -214,27 +217,30 @@ static auto run_binary(const DecTestCase &test_case, Operation op) -> void { FAIL(); } } catch (const sourcemeta::core::NumericDivisionByZeroError &) { + // Signalling the condition rather than returning infinity is expected too } return; } const auto expected_value{make_decimal(test_case.expected)}; - const auto result{ - op(make_decimal(test_case.operand1), make_decimal(test_case.operand2))}; + const auto result{operation(make_decimal(test_case.operand1), + make_decimal(test_case.operand2))}; expect_decimal_eq(result, expected_value); } template -static auto run_unary(const DecTestCase &test_case, Operation op) -> void { +static auto run_unary(const DecTestCase &test_case, Operation operation) + -> void { if (has_condition(test_case.conditions, "invalid_operation")) { try { - EXPECT_TRUE(op(make_decimal(test_case.operand1)).is_nan()); + EXPECT_TRUE(operation(make_decimal(test_case.operand1)).is_nan()); } catch (const sourcemeta::core::NumericInvalidOperationError &) { + // Signalling the condition rather than returning NaN is expected too } return; } - expect_decimal_eq(op(make_decimal(test_case.operand1)), + expect_decimal_eq(operation(make_decimal(test_case.operand1)), make_decimal(test_case.expected)); } @@ -250,6 +256,7 @@ static auto run_conversion(const DecTestCase &test_case) -> void { const auto result{sourcemeta::core::Decimal{input}}; EXPECT_TRUE(result.is_nan()); } catch (const sourcemeta::core::DecimalParseError &) { + // Rejecting the operand outright is expected too } return; } @@ -276,6 +283,7 @@ static auto run_logb(const DecTestCase &test_case) -> void { static_cast(result); FAIL(); } catch (const sourcemeta::core::NumericDivisionByZeroError &) { + // Signalling the condition rather than returning infinity is expected too } return; } @@ -560,7 +568,7 @@ static auto nan_payload_digits(const std::string &operand) -> std::size_t { std::size_t count{0}; bool found_nonzero{false}; for (auto index = position + 3; index < lower.size(); index++) { - if (!std::isdigit(static_cast(lower[index]))) { + if (std::isdigit(static_cast(lower[index])) == 0) { break; } @@ -675,7 +683,7 @@ auto main(int argc, char **argv) -> int { continue; } - const auto filepath{entry.path()}; + const auto &filepath{entry.path()}; if (filepath.extension() != ".decTest") { continue; } diff --git a/test/numeric/numeric_decimal_test.cc b/test/numeric/numeric_decimal_test.cc index 948a2d69d3..c959a714ad 100644 --- a/test/numeric/numeric_decimal_test.cc +++ b/test/numeric/numeric_decimal_test.cc @@ -1273,6 +1273,7 @@ TEST(default_constructor) { TEST(copy_constructor) { const sourcemeta::core::Decimal original{42}; + // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) const sourcemeta::core::Decimal copy{original}; EXPECT_EQ(copy, original); EXPECT_EQ(copy, sourcemeta::core::Decimal{42}); @@ -1280,6 +1281,7 @@ TEST(copy_constructor) { TEST(copy_constructor_decimal_value) { const sourcemeta::core::Decimal original{"3.14159"}; + // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) const sourcemeta::core::Decimal copy{original}; EXPECT_EQ(copy, original); } @@ -1321,7 +1323,9 @@ TEST(copy_then_modify) { TEST(multiple_copies) { const sourcemeta::core::Decimal value1{7}; + // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) const sourcemeta::core::Decimal value2{value1}; + // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) const sourcemeta::core::Decimal value3{value2}; EXPECT_EQ(value1, value2); EXPECT_EQ(value2, value3); @@ -1619,6 +1623,7 @@ TEST(exception_overflow_addition) { TEST(copy_constructor_preserves_negative_sign) { const sourcemeta::core::Decimal original{"-123.456"}; + // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) const sourcemeta::core::Decimal copy{original}; EXPECT_EQ(copy.to_string(), "-123.456"); EXPECT_TRUE(copy.is_signed()); @@ -1649,8 +1654,11 @@ TEST(move_assignment_preserves_negative_sign) { TEST(multiple_copies_preserve_negative_sign) { const sourcemeta::core::Decimal first{"-55.55"}; + // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) const sourcemeta::core::Decimal second{first}; + // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) const sourcemeta::core::Decimal third{second}; + // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) const sourcemeta::core::Decimal fourth{third}; EXPECT_EQ(fourth.to_string(), "-55.55"); EXPECT_TRUE(fourth.is_signed()); @@ -1667,6 +1675,7 @@ TEST(copy_then_move_preserves_negative_sign) { TEST(move_then_copy_preserves_negative_sign) { sourcemeta::core::Decimal original{"-444.444"}; const sourcemeta::core::Decimal moved{std::move(original)}; + // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) const sourcemeta::core::Decimal copy{moved}; EXPECT_EQ(copy.to_string(), "-444.444"); EXPECT_TRUE(copy.is_signed()); @@ -1674,6 +1683,7 @@ TEST(move_then_copy_preserves_negative_sign) { TEST(negative_integer_copy) { const sourcemeta::core::Decimal original{-12345}; + // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) const sourcemeta::core::Decimal copy{original}; EXPECT_EQ(copy.to_int64(), -12345); EXPECT_TRUE(copy.is_signed()); @@ -1688,6 +1698,7 @@ TEST(negative_integer_move) { TEST(very_small_negative_copy) { const sourcemeta::core::Decimal original{"-0.000000000000001"}; + // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) const sourcemeta::core::Decimal copy{original}; EXPECT_TRUE(copy.is_signed()); EXPECT_TRUE(copy < sourcemeta::core::Decimal{0}); @@ -1702,6 +1713,7 @@ TEST(very_small_negative_move) { TEST(large_negative_number_copy) { const sourcemeta::core::Decimal original{"-999999999999999999999999999999"}; + // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) const sourcemeta::core::Decimal copy{original}; EXPECT_EQ(copy.to_string(), "-999999999999999999999999999999"); EXPECT_TRUE(copy.is_signed()); @@ -1716,6 +1728,7 @@ TEST(large_negative_number_move) { TEST(negative_scientific_notation_copy) { const sourcemeta::core::Decimal original{"-1.23e50"}; + // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) const sourcemeta::core::Decimal copy{original}; EXPECT_TRUE(copy.is_signed()); EXPECT_TRUE(copy < sourcemeta::core::Decimal{0}); @@ -1742,6 +1755,7 @@ TEST(assignment_chain_with_negative) { TEST(positive_not_signed_after_copy) { const sourcemeta::core::Decimal original{"123.456"}; + // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) const sourcemeta::core::Decimal copy{original}; EXPECT_FALSE(copy.is_signed()); } @@ -1754,12 +1768,14 @@ TEST(positive_not_signed_after_move) { TEST(zero_not_signed_after_copy) { const sourcemeta::core::Decimal original{0}; + // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) const sourcemeta::core::Decimal copy{original}; EXPECT_FALSE(copy.is_signed()); } TEST(negative_zero_preserves_sign) { const sourcemeta::core::Decimal original{"-0"}; + // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) const sourcemeta::core::Decimal copy{original}; EXPECT_TRUE(copy.is_signed()); EXPECT_TRUE(copy.is_zero()); @@ -4362,6 +4378,7 @@ TEST(heap_coefficient_copy_assignment_over_small) { TEST(heap_coefficient_copy_construction) { const sourcemeta::core::Decimal source{ "123456789012345678901234567890123456789012345"}; + // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) const sourcemeta::core::Decimal copy{source}; EXPECT_EQ(copy, source); EXPECT_EQ(copy.to_string(), "123456789012345678901234567890123456789012345"); diff --git a/test/oauth/oauth_assertion_test.cc b/test/oauth/oauth_assertion_test.cc index cf52839567..e1776219f6 100644 --- a/test/oauth/oauth_assertion_test.cc +++ b/test/oauth/oauth_assertion_test.cc @@ -55,9 +55,9 @@ static constexpr std::string_view OTHER_OCT_JWKS_JSON{ static const auto FIXED_TIME{ std::chrono::system_clock::from_time_t(1562262616)}; -static const std::array AUDIENCES{ +static constexpr std::array AUDIENCES{ {"https://server.example/token"}}; -static const std::array ALLOWED{ +static constexpr std::array ALLOWED{ {sourcemeta::core::JWSAlgorithm::ES256}}; TEST(grant_type_and_assertion_type_constants) { diff --git a/test/oauth/oauth_authorization_test.cc b/test/oauth/oauth_authorization_test.cc index e9147257f6..583e983f6b 100644 --- a/test/oauth/oauth_authorization_test.cc +++ b/test/oauth/oauth_authorization_test.cc @@ -182,7 +182,8 @@ TEST(build_url_emits_repeatable_resources) { sourcemeta::core::OAuthAuthorizationRequest request; request.client_id = "abc"; const std::array resources{ - {{"resource", "https://api.a"}, {"resource", "https://api.b"}}}; + {{.name = "resource", .value = "https://api.a"}, + {.name = "resource", .value = "https://api.b"}}}; request.resources = resources; std::string url; sourcemeta::core::oauth_build_authorization_url("https://server.example/auth", @@ -195,7 +196,7 @@ TEST(build_url_emits_extra_parameters) { sourcemeta::core::OAuthAuthorizationRequest request; request.client_id = "abc"; const std::array extra{ - {{"nonce", "n-0S6_WzA2Mj"}}}; + {{.name = "nonce", .value = "n-0S6_WzA2Mj"}}}; request.extra = extra; std::string url; sourcemeta::core::oauth_build_authorization_url("https://server.example/auth", @@ -328,7 +329,8 @@ TEST(parse_authorization_response_accepts_an_empty_query) { TEST(build_url_escapes_an_extra_parameter_name) { sourcemeta::core::OAuthAuthorizationRequest request; request.client_id = "abc"; - const std::array extra{{{"a b", "c"}}}; + const std::array extra{ + {{.name = "a b", .value = "c"}}}; request.extra = extra; std::string url; sourcemeta::core::oauth_build_authorization_url("https://server.example/auth", diff --git a/test/oauth/oauth_conformance_test.cc b/test/oauth/oauth_conformance_test.cc index 989086aa8b..a6c59222d5 100644 --- a/test/oauth/oauth_conformance_test.cc +++ b/test/oauth/oauth_conformance_test.cc @@ -54,7 +54,8 @@ TEST(conformance_authorization_request_round_trips) { TEST(conformance_authorization_request_resources_round_trip) { const std::array resources{ - {{"resource", "https://a.example"}, {"resource", "https://b.example"}}}; + {{.name = "resource", .value = "https://a.example"}, + {.name = "resource", .value = "https://b.example"}}}; sourcemeta::core::OAuthAuthorizationRequest built; built.client_id = "s6BhdRkqt3"; built.resources = resources; diff --git a/test/oauth/oauth_dpop_test.cc b/test/oauth/oauth_dpop_test.cc index 25e4a9ae8d..f3105ff303 100644 --- a/test/oauth/oauth_dpop_test.cc +++ b/test/oauth/oauth_dpop_test.cc @@ -4,12 +4,13 @@ #include #include -#include // std::array -#include // std::chrono::system_clock, std::chrono::seconds -#include // std::optional -#include // std::ostringstream -#include // std::string -#include // std::move +#include // std::array +#include // std::chrono::system_clock, std::chrono::seconds +#include // std::optional +#include // std::ostringstream +#include // std::string +#include // std::string_view +#include // std::move static constexpr std::string_view EC_PRIVATE_JWK{ R"({"kty":"EC","crv":"P-256",)" @@ -35,7 +36,7 @@ static constexpr std::string_view OCT_JWK{ static constexpr std::string_view OTHER_THUMBPRINT{ "0ZcOCORZNYy-DWpqq30jZyJGHTN0d2HglBV3uiguA4I"}; -static const std::string RSA_PRIVATE_JWK{ +static constexpr std::string_view RSA_PRIVATE_JWK{ R"({"kty":"RSA",)" R"("n":"n-ivWLN0CTSLXc7GNcHGOuZHdu6QcGT3SlFTaf2ckxLVEDcAU4fIez7rKtvZaCzp)" R"(KJ6cb5KZnDcIn-gOCrE0FI6OZdCvgAGNqoFH6D1AANk8lWSFc1bWoti5xzXls2IN4fDRDa)" diff --git a/test/oauth/oauth_par_test.cc b/test/oauth/oauth_par_test.cc index ae995b9224..014f1d4d9d 100644 --- a/test/oauth/oauth_par_test.cc +++ b/test/oauth/oauth_par_test.cc @@ -63,7 +63,7 @@ TEST(build_par_request_emits_a_challenge_without_a_method) { TEST(build_par_request_emits_extension_parameters) { const std::array extra{ - {{"nonce", "n-0S6_WzA2Mj"}}}; + {{.name = "nonce", .value = "n-0S6_WzA2Mj"}}}; sourcemeta::core::OAuthAuthorizationRequest request; request.scope = "read"; request.extra = extra; @@ -108,8 +108,8 @@ TEST(build_par_request_honors_a_custom_response_type) { TEST(build_par_request_emits_repeatable_resources) { const std::array resources{ - {{"resource", "https://api.example"}, - {"resource", "https://other.example"}}}; + {{.name = "resource", .value = "https://api.example"}, + {.name = "resource", .value = "https://other.example"}}}; sourcemeta::core::OAuthAuthorizationRequest request; request.scope = "read"; request.resources = resources; @@ -122,7 +122,8 @@ TEST(build_par_request_emits_repeatable_resources) { TEST(build_par_request_drops_a_smuggled_request_uri) { const std::array extra{ - {{"request_uri", "urn:evil"}, {"nonce", "n-0S6"}}}; + {{.name = "request_uri", .value = "urn:evil"}, + {.name = "nonce", .value = "n-0S6"}}}; sourcemeta::core::OAuthAuthorizationRequest request; request.scope = "read"; request.extra = extra; diff --git a/test/oauth/oauth_token_test.cc b/test/oauth/oauth_token_test.cc index da9aa1dae5..905cf0b908 100644 --- a/test/oauth/oauth_token_test.cc +++ b/test/oauth/oauth_token_test.cc @@ -32,7 +32,7 @@ TEST(build_token_request_code_escapes_the_code) { TEST(build_token_request_code_with_resources) { const std::array resources{ - {{"resource", "https://api.example"}}}; + {{.name = "resource", .value = "https://api.example"}}}; sourcemeta::core::SecureString body; sourcemeta::core::oauth_build_token_request_code("abc", "", "", resources, body); @@ -227,7 +227,7 @@ TEST(token_response_scope_with_trailing_and_double_spaces) { TEST(build_token_request_refresh_with_resources) { const std::array resources{ - {{"resource", "https://api.example"}}}; + {{.name = "resource", .value = "https://api.example"}}}; sourcemeta::core::SecureString body; sourcemeta::core::oauth_build_token_request_refresh("rt", "", resources, body); @@ -237,7 +237,8 @@ TEST(build_token_request_refresh_with_resources) { TEST(build_token_request_client_credentials_with_two_resources) { const std::array resources{ - {{"resource", "https://a"}, {"resource", "https://b"}}}; + {{.name = "resource", .value = "https://a"}, + {.name = "resource", .value = "https://b"}}}; sourcemeta::core::SecureString body; sourcemeta::core::oauth_build_token_request_client_credentials( "read", resources, body); diff --git a/test/oidc/oidc_metadata_test.cc b/test/oidc/oidc_metadata_test.cc index 3ab92e1561..111cb00a6c 100644 --- a/test/oidc/oidc_metadata_test.cc +++ b/test/oidc/oidc_metadata_test.cc @@ -6,6 +6,7 @@ #include // std::string_view #include // std::move +// NOLINTNEXTLINE(cert-err58-cpp,bugprone-throwing-static-initialization) static const auto VALID_PROVIDER_DOCUMENT{sourcemeta::core::parse_json(R"JSON({ "issuer": "https://example.com", "authorization_endpoint": "https://example.com/authorize", diff --git a/test/options/options_test.cc b/test/options/options_test.cc index 8c58af0017..6fb228bc92 100644 --- a/test/options/options_test.cc +++ b/test/options/options_test.cc @@ -1,16 +1,15 @@ #include #include +#include // std::array + TEST(long_option_equals_parses_value_with_equal_sign) { sourcemeta::core::Options app; app.option("foo", {"f"}); - const char arg0[] = "prog"; - const char arg1[] = "--foo=bar"; - const char *const argv[] = {arg0, arg1}; - const int argc = 2; + const std::array argv{{"prog", "--foo=bar"}}; - app.parse(argc, argv); + app.parse(static_cast(argv.size()), argv.data()); EXPECT_TRUE(app.positional().empty()); EXPECT_EQ(app.at("foo").size(), 1); @@ -22,13 +21,9 @@ TEST(long_option_space_parses_value_after_space) { sourcemeta::core::Options app; app.option("foo", {"f"}); - const char arg0[] = "prog"; - const char arg1[] = "--foo"; - const char arg2[] = "bar"; - const char *const argv[] = {arg0, arg1, arg2}; - const int argc = 3; + const std::array argv{{"prog", "--foo", "bar"}}; - app.parse(argc, argv); + app.parse(static_cast(argv.size()), argv.data()); EXPECT_TRUE(app.positional().empty()); EXPECT_EQ(app.at("foo").size(), 1); @@ -39,13 +34,9 @@ TEST(short_option_space_parses_short_option_with_space_value) { sourcemeta::core::Options app; app.option("file", {"f"}); - const char arg0[] = "prog"; - const char arg1[] = "-f"; - const char arg2[] = "path/to/x"; - const char *const argv[] = {arg0, arg1, arg2}; - const int argc = 3; + const std::array argv{{"prog", "-f", "path/to/x"}}; - app.parse(argc, argv); + app.parse(static_cast(argv.size()), argv.data()); EXPECT_TRUE(app.positional().empty()); EXPECT_EQ(app.at("file").size(), 1); @@ -56,12 +47,9 @@ TEST(short_option_attached_value_parses_short_option_attached_value) { sourcemeta::core::Options app; app.option("file", {"f"}); - const char arg0[] = "prog"; - const char arg1[] = "-fpath"; - const char *const argv[] = {arg0, arg1}; - const int argc = 2; + const std::array argv{{"prog", "-fpath"}}; - app.parse(argc, argv); + app.parse(static_cast(argv.size()), argv.data()); EXPECT_TRUE(app.positional().empty()); EXPECT_EQ(app.at("file").size(), 1); @@ -74,12 +62,9 @@ TEST(combined_flags_parses_combined_short_flags) { app.flag("beta", {"b"}); app.flag("gamma", {"c"}); - const char arg0[] = "prog"; - const char arg1[] = "-abc"; - const char *const argv[] = {arg0, arg1}; - const int argc = 2; + const std::array argv{{"prog", "-abc"}}; - app.parse(argc, argv); + app.parse(static_cast(argv.size()), argv.data()); EXPECT_TRUE(app.positional().empty()); EXPECT_EQ(app.at("alpha").size(), 1); @@ -93,12 +78,9 @@ TEST( app.flag("alpha", {"a"}); app.option("bopt", {"b"}); - const char arg0[] = "prog"; - const char arg1[] = "-abvalue"; - const char *const argv[] = {arg0, arg1}; - const int argc = 2; + const std::array argv{{"prog", "-abvalue"}}; - app.parse(argc, argv); + app.parse(static_cast(argv.size()), argv.data()); EXPECT_TRUE(app.positional().empty()); EXPECT_EQ(app.at("alpha").size(), 1); @@ -110,16 +92,10 @@ TEST(repeated_options_preserved_order) { sourcemeta::core::Options app; app.option("foo", {"f"}); - const char arg0[] = "prog"; - const char arg1[] = "--foo=one"; - const char arg2[] = "--foo"; - const char arg3[] = "two"; - const char arg4[] = "-f"; - const char arg5[] = "three"; - const char *const argv[] = {arg0, arg1, arg2, arg3, arg4, arg5}; - const int argc = 6; + const std::array argv{ + {"prog", "--foo=one", "--foo", "two", "-f", "three"}}; - app.parse(argc, argv); + app.parse(static_cast(argv.size()), argv.data()); EXPECT_TRUE(app.positional().empty()); EXPECT_EQ(app.at("foo").size(), 3); @@ -132,13 +108,9 @@ TEST(flags_count_multiple_occurrences) { sourcemeta::core::Options app; app.flag("exclude", {"x"}); - const char arg0[] = "prog"; - const char arg1[] = "-x"; - const char arg2[] = "--exclude"; - const char *const argv[] = {arg0, arg1, arg2}; - const int argc = 3; + const std::array argv{{"prog", "-x", "--exclude"}}; - app.parse(argc, argv); + app.parse(static_cast(argv.size()), argv.data()); EXPECT_TRUE(app.positional().empty()); EXPECT_EQ(app.at("exclude").size(), 2); @@ -149,13 +121,10 @@ TEST(unknown_option_throws) { sourcemeta::core::Options app; app.option("foo", {"f"}); - const char arg0[] = "prog"; - const char arg1[] = "--unknown"; - const char *const argv[] = {arg0, arg1}; - const int argc = 2; + const std::array argv{{"prog", "--unknown"}}; try { - app.parse(argc, argv); + app.parse(static_cast(argv.size()), argv.data()); FAIL(); } catch (const sourcemeta::core::OptionsUnknownOptionError &error) { EXPECT_STREQ(error.what(), "Unknown option"); @@ -167,13 +136,10 @@ TEST(flag_given_value_throws) { sourcemeta::core::Options app; app.flag("verbose", {"v"}); - const char arg0[] = "prog"; - const char arg1[] = "--verbose=1"; - const char *const argv[] = {arg0, arg1}; - const int argc = 2; + const std::array argv{{"prog", "--verbose=1"}}; try { - app.parse(argc, argv); + app.parse(static_cast(argv.size()), argv.data()); FAIL(); } catch (const sourcemeta::core::OptionsUnexpectedValueFlagError &error) { EXPECT_STREQ(error.what(), "This flag cannot take a value"); @@ -186,14 +152,9 @@ TEST(positional_after_double_dash) { app.option("foo", {"f"}); app.flag("x", {"x"}); - const char arg0[] = "prog"; - const char arg1[] = "--"; - const char arg2[] = "-not-an-opt"; - const char arg3[] = "pos2"; - const char *const argv[] = {arg0, arg1, arg2, arg3}; - const int argc = 4; + const std::array argv{{"prog", "--", "-not-an-opt", "pos2"}}; - app.parse(argc, argv); + app.parse(static_cast(argv.size()), argv.data()); EXPECT_EQ(app.positional().size(), 2); EXPECT_EQ(app.positional()[0], "-not-an-opt"); @@ -204,14 +165,9 @@ TEST(positional_before_options) { sourcemeta::core::Options app; app.option("foo", {"foo"}); - const char arg0[] = "prog"; - const char arg1[] = "pos1"; - const char arg2[] = "--foo"; - const char arg3[] = "bar"; - const char *const argv[] = {arg0, arg1, arg2, arg3}; - const int argc = 4; + const std::array argv{{"prog", "pos1", "--foo", "bar"}}; - app.parse(argc, argv); + app.parse(static_cast(argv.size()), argv.data()); EXPECT_EQ(app.positional().size(), 1); EXPECT_EQ(app.positional()[0], "pos1"); @@ -223,14 +179,9 @@ TEST(skip_parameter_works) { sourcemeta::core::Options app; app.option("file", {"f"}); - const char arg0[] = "prog"; - const char arg1[] = "cmd"; - const char arg2[] = "-f"; - const char arg3[] = "file.txt"; - const char *const argv[] = {arg0, arg1, arg2, arg3}; - const int argc = 4; + const std::array argv{{"prog", "cmd", "-f", "file.txt"}}; - app.parse(argc, argv, {.skip = 1}); + app.parse(static_cast(argv.size()), argv.data(), {.skip = 1}); EXPECT_TRUE(app.positional().empty()); EXPECT_EQ(app.at("file").size(), 1); @@ -241,13 +192,9 @@ TEST(alias_mapping_recognizes_aliases) { sourcemeta::core::Options app; app.option("file", {"f", "a"}); - const char arg0[] = "prog"; - const char arg1[] = "-a"; - const char arg2[] = "ok"; - const char *const argv[] = {arg0, arg1, arg2}; - const int argc = 3; + const std::array argv{{"prog", "-a", "ok"}}; - app.parse(argc, argv); + app.parse(static_cast(argv.size()), argv.data()); EXPECT_TRUE(app.positional().empty()); EXPECT_EQ(app.at("file").size(), 1); @@ -259,13 +206,9 @@ TEST(option_value) { app.option("file", {"f"}); app.flag("other", {"o"}); - const char arg0[] = "prog"; - const char arg1[] = "--file"; - const char arg2[] = "--other"; - const char *const argv[] = {arg0, arg1, arg2}; - const int argc = 3; + const std::array argv{{"prog", "--file", "--other"}}; - app.parse(argc, argv); + app.parse(static_cast(argv.size()), argv.data()); EXPECT_TRUE(app.positional().empty()); EXPECT_EQ(app.at("file").size(), 1); @@ -277,13 +220,10 @@ TEST(long_option_without_value) { sourcemeta::core::Options app; app.option("file", {"f"}); - const char arg0[] = "prog"; - const char arg1[] = "--file"; - const char *const argv[] = {arg0, arg1}; - const int argc = 2; + const std::array argv{{"prog", "--file"}}; try { - app.parse(argc, argv); + app.parse(static_cast(argv.size()), argv.data()); FAIL(); } catch (const sourcemeta::core::OptionsMissingOptionValueError &error) { EXPECT_STREQ(error.what(), "This option must take a value"); @@ -295,13 +235,10 @@ TEST(short_option_without_value) { sourcemeta::core::Options app; app.option("file", {"f"}); - const char arg0[] = "prog"; - const char arg1[] = "-f"; - const char *const argv[] = {arg0, arg1}; - const int argc = 2; + const std::array argv{{"prog", "-f"}}; try { - app.parse(argc, argv); + app.parse(static_cast(argv.size()), argv.data()); FAIL(); } catch (const sourcemeta::core::OptionsMissingOptionValueError &error) { EXPECT_EQ(error.option(), "f"); @@ -312,13 +249,9 @@ TEST(single_dash_is_consumed_as_value) { sourcemeta::core::Options app; app.option("file", {"f"}); - const char arg0[] = "prog"; - const char arg1[] = "-f"; - const char arg2[] = "-"; - const char *const argv[] = {arg0, arg1, arg2}; - const int argc = 3; + const std::array argv{{"prog", "-f", "-"}}; - app.parse(argc, argv); + app.parse(static_cast(argv.size()), argv.data()); EXPECT_TRUE(app.positional().empty()); EXPECT_EQ(app.at("file").size(), 1); @@ -329,11 +262,9 @@ TEST(empty_result_for_missing_option) { sourcemeta::core::Options app; app.option("file", {"f"}); - const char arg0[] = "prog"; - const char *const argv[] = {arg0}; - const int argc = 1; + const std::array argv{{"prog"}}; - app.parse(argc, argv); + app.parse(static_cast(argv.size()), argv.data()); EXPECT_TRUE(app.positional().empty()); } @@ -345,24 +276,11 @@ TEST(mixed_complex_scenario_parses_complex_mixture_correctly) { app.option("opt", {"o"}); app.flag("x", {"x"}); - const char arg0[] = "prog"; - const char arg1[] = "-vx"; - const char arg2[] = "--file=first"; - const char arg3[] = "-o"; - const char arg4[] = "second"; - const char arg5[] = "-vfthird"; - const char arg6[] = "pos1"; - const char arg7[] = "--"; - const char arg8[] = "should-be-pos"; - const char arg9[] = "--also-pos"; - const char arg10[] = "extra"; - const char arg11[] = "ignored"; - const char arg12[] = "values"; - const char *const argv[] = {arg0, arg1, arg2, arg3, arg4, arg5, arg6, - arg7, arg8, arg9, arg10, arg11, arg12}; - const int argc = 13; - - app.parse(argc, argv); + const std::array argv{ + {"prog", "-vx", "--file=first", "-o", "second", "-vfthird", "pos1", "--", + "should-be-pos", "--also-pos", "extra", "ignored", "values"}}; + + app.parse(static_cast(argv.size()), argv.data()); EXPECT_GE(app.at("verbose").size(), 2); EXPECT_EQ(app.at("x").size(), 1); @@ -381,13 +299,9 @@ TEST(no_skip_includes_program_name_as_positional) { sourcemeta::core::Options app; app.option("foo", {"f"}); - const char arg0[] = "prog"; - const char arg1[] = "--foo"; - const char arg2[] = "bar"; - const char *const argv[] = {arg0, arg1, arg2}; - const int argc = 3; + const std::array argv{{"prog", "--foo", "bar"}}; - app.parse(argc, argv); + app.parse(static_cast(argv.size()), argv.data()); EXPECT_TRUE(app.positional().empty()); EXPECT_EQ(app.at("foo").size(), 1); @@ -398,12 +312,9 @@ TEST(no_skip_treats_program_name_as_option_if_prefixed) { sourcemeta::core::Options app; app.option("file", {"f"}); - const char arg0[] = "prog"; - const char arg1[] = "-ffromprog"; - const char *const argv[] = {arg0, arg1}; - const int argc = 2; + const std::array argv{{"prog", "-ffromprog"}}; - app.parse(argc, argv); + app.parse(static_cast(argv.size()), argv.data()); EXPECT_EQ(app.at("file").size(), 1); EXPECT_EQ(app.at("file")[0], "fromprog"); diff --git a/test/parallel/parallel_for_each_test.cc b/test/parallel/parallel_for_each_test.cc index a62c37fa51..af1a00fe0f 100644 --- a/test/parallel/parallel_for_each_test.cc +++ b/test/parallel/parallel_for_each_test.cc @@ -13,6 +13,7 @@ TEST(processes_all_elements_once) { std::vector items; + items.reserve(20); for (std::size_t index = 0; index < 20; index++) { items.push_back(index); } @@ -23,7 +24,7 @@ TEST(processes_all_elements_once) { sourcemeta::core::parallel_for_each( items.cbegin(), items.cend(), [&mutex, &processed](const auto value, const auto, const auto) { - std::lock_guard lock{mutex}; + std::scoped_lock lock{mutex}; processed.push_back(value); }); @@ -34,6 +35,7 @@ TEST(processes_all_elements_once) { TEST(processes_all_elements_once_concurrency_1) { std::vector items; + items.reserve(20); for (std::size_t index = 0; index < 20; index++) { items.push_back(index); } @@ -47,7 +49,7 @@ TEST(processes_all_elements_once_concurrency_1) { items.cbegin(), items.cend(), [&mutex, &processed, ¶llelism, &cursors](const auto value, const auto concurrency, const auto cursor) { - std::lock_guard lock{mutex}; + std::scoped_lock lock{mutex}; processed.push_back(value); parallelism.emplace(concurrency); cursors.push_back(cursor - 1); diff --git a/test/process/process_spawn_and_capture_main.cc b/test/process/process_spawn_and_capture_main.cc index 0df133bdd8..a89b4344b0 100644 --- a/test/process/process_spawn_and_capture_main.cc +++ b/test/process/process_spawn_and_capture_main.cc @@ -1,8 +1,9 @@ #include +#include // std::array #include // std::size_t #include // std::fread, std::fwrite, std::fflush, std::FILE -#include // std::atoi, std::atoll +#include // std::strtol, std::strtoll #include // std::filesystem::current_path #include // std::string, std::to_string #include // std::string_view @@ -40,8 +41,8 @@ auto environment_name_matches(const std::string_view left, // Scanning the block avoids the lookup the Microsoft runtime deprecates, and // keeps one way of reading the environment across every platform auto find_environment(const std::string_view name) -> const char * { - for (char **entry = environment_entries(); entry != nullptr && *entry; - ++entry) { + for (char **entry = environment_entries(); + entry != nullptr && ((*entry) != nullptr); ++entry) { const std::string_view current{*entry}; const auto separator{current.find('=')}; if (separator != std::string_view::npos && @@ -63,10 +64,10 @@ auto write_all(std::FILE *stream, const std::string_view payload) -> void { auto read_all(std::FILE *stream) -> std::string { std::string result; - char buffer[4096]; + std::array buffer{}; std::size_t count{0}; - while ((count = std::fread(buffer, 1, sizeof(buffer), stream)) > 0) { - result.append(buffer, count); + while ((count = std::fread(buffer.data(), 1, buffer.size(), stream)) > 0) { + result.append(buffer.data(), count); } return result; @@ -85,7 +86,7 @@ auto payload_of(const std::size_t size) -> std::string { } auto to_size(const char *value) -> std::size_t { - return static_cast(std::atoll(value)); + return static_cast(std::strtoll(value, nullptr, 10)); } } // namespace @@ -106,7 +107,7 @@ auto main(int argc, char *argv[]) -> int { const std::string_view command{argv[1]}; if (command == "exit") { - return std::atoi(argv[2]); + return static_cast(std::strtol(argv[2], nullptr, 10)); } if (command == "stdout") { @@ -163,8 +164,8 @@ auto main(int argc, char *argv[]) -> int { if (command == "environment") { std::string result; - for (char **entry = environment_entries(); entry != nullptr && *entry; - ++entry) { + for (char **entry = environment_entries(); + entry != nullptr && ((*entry) != nullptr); ++entry) { result.append(*entry); result.push_back('\n'); } diff --git a/test/process/process_spawn_and_capture_test.cc b/test/process/process_spawn_and_capture_test.cc index dcddde8e61..0e33c06290 100644 --- a/test/process/process_spawn_and_capture_test.cc +++ b/test/process/process_spawn_and_capture_test.cc @@ -9,11 +9,14 @@ #include // std::thread #include // std::vector +// Spawning takes the program by string reference, so the path to the +// helper needs storage of its own +// NOLINTNEXTLINE(cert-err58-cpp,bugprone-throwing-static-initialization) static const std::string HELPER{HELPER_BINARY}; // Enough to overrun the pipe buffer of every platform this builds on, so that a // transfer that does not interleave reading and writing cannot complete -static constexpr std::size_t FLOOD_SIZE{1024 * 1024}; +static constexpr std::size_t FLOOD_SIZE{std::size_t{1024} * 1024}; // Mirrors what the helper program writes, so that a truncated or reordered // transfer cannot pass by accident diff --git a/test/process/process_spawn_input_test.cc b/test/process/process_spawn_input_test.cc index 7e7723ae68..535fdf372a 100644 --- a/test/process/process_spawn_input_test.cc +++ b/test/process/process_spawn_input_test.cc @@ -7,6 +7,9 @@ #include // std::string #include // std::string_view +// Spawning takes the program by string reference, so the path to the +// helper needs storage of its own +// NOLINTNEXTLINE(cert-err58-cpp,bugprone-throwing-static-initialization) static const std::string HELPER{HELPER_BINARY}; static auto payload_of(const std::size_t size) -> std::string { @@ -40,7 +43,7 @@ TEST(an_absent_standard_input_leaves_the_stream_alone) { } TEST(a_large_standard_input_is_delivered_without_capturing) { - const auto payload{payload_of(1024 * 1024)}; + const auto payload{payload_of(std::size_t{1024} * 1024)}; const sourcemeta::core::ProcessInput input{.standard_input = payload}; const int exit_code{ sourcemeta::core::spawn(HELPER, {"expect-stdin-size", "1048576"}, input)}; @@ -55,7 +58,7 @@ TEST(a_short_standard_input_is_measured_exactly_without_capturing) { } TEST(a_program_that_never_reads_a_large_input_does_not_kill_the_caller) { - const auto payload{payload_of(1024 * 1024)}; + const auto payload{payload_of(std::size_t{1024} * 1024)}; const sourcemeta::core::ProcessInput input{.standard_input = payload}; const int exit_code{sourcemeta::core::spawn(HELPER, {"exit", "3"}, input)}; EXPECT_EQ(exit_code, 3); @@ -90,7 +93,7 @@ TEST(the_working_directory_is_honoured_without_capturing) { std::filesystem::canonical(std::filesystem::temp_directory_path())}; const sourcemeta::core::ProcessInput input{.directory = directory}; const int exit_code{sourcemeta::core::spawn( - HELPER, {"expect-directory", directory.string().c_str()}, input)}; + HELPER, {"expect-directory", directory.string()}, input)}; EXPECT_EQ(exit_code, 0); } diff --git a/test/process/process_spawn_test_unix.cc b/test/process/process_spawn_test_unix.cc index a8759e69e9..829c6ded28 100644 --- a/test/process/process_spawn_test_unix.cc +++ b/test/process/process_spawn_test_unix.cc @@ -39,7 +39,7 @@ TEST(test_command_passing_condition) { } TEST(nonexistent_program_throws_exception) { - const auto program{"/bin/this_program_definitely_does_not_exist"}; + const auto *const program{"/bin/this_program_definitely_does_not_exist"}; try { sourcemeta::core::spawn(program, {}); FAIL(); @@ -55,16 +55,15 @@ TEST(echo_with_arguments) { TEST(argument_with_spaces_is_a_single_argument) { const int exit_code{sourcemeta::core::spawn( - "/bin/sh", - {"-c", "test \"$#\" -eq 1 && test \"$1\" = \"alpha beta gamma\"", "sh", - "alpha beta gamma"})}; + "/bin/sh", {"-c", R"(test "$#" -eq 1 && test "$1" = "alpha beta gamma")", + "sh", "alpha beta gamma"})}; EXPECT_EQ(exit_code, 0); } TEST(empty_argument_is_preserved) { const int exit_code{sourcemeta::core::spawn( "/bin/sh", - {"-c", "test \"$#\" -eq 2 && test -z \"$1\"", "sh", "", "second"})}; + {"-c", R"(test "$#" -eq 2 && test -z "$1")", "sh", "", "second"})}; EXPECT_EQ(exit_code, 0); } diff --git a/test/regex/regex_permissive_matches_ecma262_test.cc b/test/regex/regex_permissive_matches_ecma262_test.cc index f5b8bab013..caf270391b 100644 --- a/test/regex/regex_permissive_matches_ecma262_test.cc +++ b/test/regex/regex_permissive_matches_ecma262_test.cc @@ -243,7 +243,7 @@ TEST(ecma262_lookbehind_negative) { TEST(ecma262_combined_digit_word_anchors) { const auto regex{sourcemeta::core::to_regex( - "^\\w+@\\w+\\.\\w+$", sourcemeta::core::RegexDialect::Permissive)}; + R"(^\w+@\w+\.\w+$)", sourcemeta::core::RegexDialect::Permissive)}; EXPECT_TRUE(regex.has_value()); EXPECT_TRUE(sourcemeta::core::is_regex_ecma("^\\w+@\\w+\\.\\w+$")); EXPECT_TRUE(sourcemeta::core::matches(regex.value(), "user@example.com")); @@ -252,7 +252,7 @@ TEST(ecma262_combined_digit_word_anchors) { TEST(ecma262_digit_range_pattern) { const auto regex{sourcemeta::core::to_regex( - "\\d{3}-\\d{2}-\\d{4}", sourcemeta::core::RegexDialect::Permissive)}; + R"(\d{3}-\d{2}-\d{4})", sourcemeta::core::RegexDialect::Permissive)}; EXPECT_TRUE(regex.has_value()); EXPECT_TRUE(sourcemeta::core::is_regex_ecma("\\d{3}-\\d{2}-\\d{4}")); EXPECT_TRUE(sourcemeta::core::matches(regex.value(), "123-45-6789")); @@ -261,7 +261,7 @@ TEST(ecma262_digit_range_pattern) { TEST(ecma262_mixed_escapes) { const auto regex{sourcemeta::core::to_regex( - "\\w+\\s+\\d+", sourcemeta::core::RegexDialect::Permissive)}; + R"(\w+\s+\d+)", sourcemeta::core::RegexDialect::Permissive)}; EXPECT_TRUE(regex.has_value()); EXPECT_TRUE(sourcemeta::core::is_regex_ecma("\\w+\\s+\\d+")); EXPECT_TRUE(sourcemeta::core::matches(regex.value(), "hello 123")); @@ -281,7 +281,7 @@ TEST(ecma262_anchor_with_digit) { TEST(ecma262_word_boundary_with_digit) { const auto regex{sourcemeta::core::to_regex( - "\\b\\d{3}\\b", sourcemeta::core::RegexDialect::Permissive)}; + R"(\b\d{3}\b)", sourcemeta::core::RegexDialect::Permissive)}; EXPECT_TRUE(regex.has_value()); EXPECT_TRUE(sourcemeta::core::is_regex_ecma("\\b\\d{3}\\b")); EXPECT_TRUE(sourcemeta::core::matches(regex.value(), "123")); @@ -303,7 +303,7 @@ TEST(ecma262_whitespace_variants) { TEST(ecma262_complex_email_pattern) { const auto regex{ - sourcemeta::core::to_regex("^[\\w.+-]+@[\\w.-]+\\.[a-zA-Z]{2,}$", + sourcemeta::core::to_regex(R"(^[\w.+-]+@[\w.-]+\.[a-zA-Z]{2,}$)", sourcemeta::core::RegexDialect::Permissive)}; EXPECT_TRUE(regex.has_value()); EXPECT_TRUE( @@ -329,7 +329,7 @@ TEST(ecma262_complex_url_pattern) { TEST(ecma262_phone_number_pattern) { const auto regex{ - sourcemeta::core::to_regex("^\\(\\d{3}\\)\\s*\\d{3}-\\d{4}$", + sourcemeta::core::to_regex(R"(^\(\d{3}\)\s*\d{3}-\d{4}$)", sourcemeta::core::RegexDialect::Permissive)}; EXPECT_TRUE(regex.has_value()); EXPECT_TRUE( @@ -372,7 +372,7 @@ TEST(ecma262_lookahead_with_quantifier) { TEST(ecma262_multiple_word_boundaries) { const auto regex{sourcemeta::core::to_regex( - "\\btest\\b.*\\bcase\\b", sourcemeta::core::RegexDialect::Permissive)}; + R"(\btest\b.*\bcase\b)", sourcemeta::core::RegexDialect::Permissive)}; EXPECT_TRUE(regex.has_value()); EXPECT_TRUE(sourcemeta::core::is_regex_ecma("\\btest\\b.*\\bcase\\b")); EXPECT_TRUE(sourcemeta::core::matches(regex.value(), "test case")); @@ -665,7 +665,7 @@ TEST(ecma262_negated_charclass) { TEST(ecma262_escaped_metacharacters) { const auto regex{sourcemeta::core::to_regex( - "^\\.\\.\\.$", sourcemeta::core::RegexDialect::Permissive)}; + R"(^\.\.\.$)", sourcemeta::core::RegexDialect::Permissive)}; EXPECT_TRUE(regex.has_value()); EXPECT_TRUE(sourcemeta::core::is_regex_ecma("^\\.\\.\\.$")); EXPECT_TRUE(sourcemeta::core::matches(regex.value(), "...")); @@ -980,7 +980,7 @@ TEST(ecma262_unicode_escape_4digit_arabic_digit_range) { TEST(ecma262_unicode_property_letter_identifier) { const auto regex{ - sourcemeta::core::to_regex("^\\p{Letter}[\\p{Letter}\\p{Number}]*$", + sourcemeta::core::to_regex(R"(^\p{Letter}[\p{Letter}\p{Number}]*$)", sourcemeta::core::RegexDialect::Permissive)}; EXPECT_TRUE(regex.has_value()); EXPECT_TRUE(sourcemeta::core::is_regex_ecma( @@ -995,7 +995,7 @@ TEST(ecma262_unicode_property_letter_identifier) { TEST(ecma262_unicode_property_negative_lookahead_identifier) { const auto regex{sourcemeta::core::to_regex( - "^(?!\\p{Number})\\p{Letter}[\\p{Letter}\\p{Number}\\-_.]*$", + R"(^(?!\p{Number})\p{Letter}[\p{Letter}\p{Number}\-_.]*$)", sourcemeta::core::RegexDialect::Permissive)}; EXPECT_TRUE(regex.has_value()); EXPECT_TRUE(sourcemeta::core::is_regex_ecma( @@ -1104,7 +1104,7 @@ TEST(ecma262_escaped_backslash_before_bracket) { TEST(ecma262_triple_backslash_before_bracket) { const auto regex{sourcemeta::core::to_regex( - "\\\\\\[", sourcemeta::core::RegexDialect::Permissive)}; + R"(\\\[)", sourcemeta::core::RegexDialect::Permissive)}; EXPECT_TRUE(regex.has_value()); EXPECT_TRUE(sourcemeta::core::is_regex_ecma("\\\\\\[")); EXPECT_TRUE(sourcemeta::core::matches(regex.value(), "\\[")); @@ -1218,7 +1218,7 @@ TEST(ecma262_backslash_in_char_class) { TEST(ecma262_complex_char_class_with_escaped_chars) { const auto regex{sourcemeta::core::to_regex( - "[a\\]b\\\\c]", sourcemeta::core::RegexDialect::Permissive)}; + R"([a\]b\\c])", sourcemeta::core::RegexDialect::Permissive)}; EXPECT_TRUE(regex.has_value()); EXPECT_TRUE(sourcemeta::core::is_regex_ecma("[a\\]b\\\\c]")); EXPECT_TRUE(sourcemeta::core::matches(regex.value(), "a")); @@ -1277,7 +1277,7 @@ TEST(ecma262_dollar_before_alternation) { TEST(ecma262_multiple_backslashes_complex) { const auto regex{sourcemeta::core::to_regex( - "\\\\\\\\\\\\\\\\", sourcemeta::core::RegexDialect::Permissive)}; + R"(\\\\\\\\)", sourcemeta::core::RegexDialect::Permissive)}; EXPECT_TRUE(regex.has_value()); EXPECT_TRUE(sourcemeta::core::is_regex_ecma("\\\\\\\\\\\\\\\\")); EXPECT_TRUE(sourcemeta::core::matches(regex.value(), "\\\\\\\\")); @@ -1340,7 +1340,7 @@ TEST(ecma262_caret_in_middle_of_pattern) { TEST(ecma262_backslash_before_digit_escape) { const auto regex{sourcemeta::core::to_regex( - "\\\\\\d", sourcemeta::core::RegexDialect::Permissive)}; + R"(\\\d)", sourcemeta::core::RegexDialect::Permissive)}; EXPECT_TRUE(regex.has_value()); EXPECT_TRUE(sourcemeta::core::is_regex_ecma("\\\\\\d")); EXPECT_TRUE(sourcemeta::core::matches(regex.value(), "\\0")); @@ -1479,7 +1479,7 @@ TEST(ecma262_unicode_hex_too_large) { TEST(ecma262_multiple_backslashes_before_d) { const auto regex{sourcemeta::core::to_regex( - "\\\\\\\\d", sourcemeta::core::RegexDialect::Permissive)}; + R"(\\\\d)", sourcemeta::core::RegexDialect::Permissive)}; EXPECT_TRUE(regex.has_value()); EXPECT_TRUE(sourcemeta::core::is_regex_ecma("\\\\\\\\d")); EXPECT_TRUE(sourcemeta::core::matches(regex.value(), "\\\\d")); @@ -1649,7 +1649,7 @@ TEST(ecma262_caret_at_end) { TEST(ecma262_escaped_quantifiers) { const auto regex{sourcemeta::core::to_regex( - "\\*\\+\\?", sourcemeta::core::RegexDialect::Permissive)}; + R"(\*\+\?)", sourcemeta::core::RegexDialect::Permissive)}; EXPECT_TRUE(regex.has_value()); EXPECT_TRUE(sourcemeta::core::is_regex_ecma("\\*\\+\\?")); EXPECT_TRUE(sourcemeta::core::matches(regex.value(), "*+?")); @@ -2228,7 +2228,7 @@ TEST(ecma262_v_flag_intersect_single_chars_different) { TEST(ecma262_v_flag_hex_intersect_hex) { const auto regex{ - sourcemeta::core::to_regex("[[\\x30-\\x39]&&[\\x33-\\x37]]", + sourcemeta::core::to_regex(R"([[\x30-\x39]&&[\x33-\x37]])", sourcemeta::core::RegexDialect::Permissive)}; EXPECT_TRUE(regex.has_value()); EXPECT_TRUE( @@ -2255,7 +2255,7 @@ TEST(ecma262_v_flag_subtract_all_digits_from_word) { TEST(ecma262_v_flag_intersect_with_escaped_backslash) { const auto regex{sourcemeta::core::to_regex( - "[[\\\\a-z]&&[\\\\]]", sourcemeta::core::RegexDialect::Permissive)}; + R"([[\\a-z]&&[\\]])", sourcemeta::core::RegexDialect::Permissive)}; EXPECT_TRUE(regex.has_value()); EXPECT_TRUE(sourcemeta::core::is_regex_ecma("[[\\\\a-z]&&[\\\\]]")); EXPECT_TRUE(sourcemeta::core::matches(regex.value(), "\\")); @@ -2265,7 +2265,7 @@ TEST(ecma262_v_flag_intersect_with_escaped_backslash) { TEST(ecma262_v_flag_subtract_control_chars) { const auto regex{ - sourcemeta::core::to_regex("[[\\x00-\\x1f]--[\\x00-\\x08]]", + sourcemeta::core::to_regex(R"([[\x00-\x1f]--[\x00-\x08]])", sourcemeta::core::RegexDialect::Permissive)}; EXPECT_TRUE(regex.has_value()); EXPECT_TRUE( @@ -2278,7 +2278,7 @@ TEST(ecma262_v_flag_subtract_control_chars) { TEST(ecma262_v_flag_intersect_with_tab_newline) { const auto regex{sourcemeta::core::to_regex( - "[[\\t\\n\\r ]&&[\\t\\n]]", sourcemeta::core::RegexDialect::Permissive)}; + R"([[\t\n\r ]&&[\t\n]])", sourcemeta::core::RegexDialect::Permissive)}; EXPECT_TRUE(regex.has_value()); EXPECT_TRUE(sourcemeta::core::is_regex_ecma("[[\\t\\n\\r ]&&[\\t\\n]]")); EXPECT_TRUE(sourcemeta::core::matches(regex.value(), "\t")); @@ -2334,7 +2334,7 @@ TEST(ecma262_v_flag_subtract_boundary_chars) { TEST(ecma262_v_flag_intersect_complement_like) { const auto regex{ - sourcemeta::core::to_regex("[[\\x00-\\x60\\x7b-\\x7f]&&[\\x00-\\x7f]]", + sourcemeta::core::to_regex(R"([[\x00-\x60\x7b-\x7f]&&[\x00-\x7f]])", sourcemeta::core::RegexDialect::Permissive)}; EXPECT_TRUE(regex.has_value()); EXPECT_TRUE(sourcemeta::core::is_regex_ecma( @@ -2348,7 +2348,7 @@ TEST(ecma262_v_flag_intersect_complement_like) { TEST(ecma262_v_flag_subtract_from_shorthand_with_hex) { const auto regex{sourcemeta::core::to_regex( - "[[\\d]--[\\x30-\\x34]]", sourcemeta::core::RegexDialect::Permissive)}; + R"([[\d]--[\x30-\x34]])", sourcemeta::core::RegexDialect::Permissive)}; EXPECT_TRUE(regex.has_value()); EXPECT_TRUE(sourcemeta::core::is_regex_ecma("[[\\d]--[\\x30-\\x34]]")); EXPECT_TRUE(sourcemeta::core::matches(regex.value(), "5")); @@ -2398,7 +2398,7 @@ TEST(ecma262_v_flag_subtract_all_but_one_from_range) { TEST(ecma262_v_flag_multiple_hex_escapes_in_subtraction) { const auto regex{sourcemeta::core::to_regex( - "[[\\x20-\\x7e]--[\\x30-\\x39]--[\\x41-\\x5a]--[\\x61-\\x7a]]", + R"([[\x20-\x7e]--[\x30-\x39]--[\x41-\x5a]--[\x61-\x7a]])", sourcemeta::core::RegexDialect::Permissive)}; EXPECT_TRUE(regex.has_value()); EXPECT_TRUE(sourcemeta::core::is_regex_ecma( @@ -2653,7 +2653,7 @@ TEST(ecma262_v_flag_negated_digit_intersect) { TEST(ecma262_v_flag_negated_word_intersect) { const auto regex{sourcemeta::core::to_regex( - "[[\\W]&&[\\!-\\/]]", sourcemeta::core::RegexDialect::Permissive)}; + R"([[\W]&&[\!-\/]])", sourcemeta::core::RegexDialect::Permissive)}; EXPECT_TRUE(regex.has_value()); EXPECT_TRUE(sourcemeta::core::is_regex_ecma("[[\\W]&&[\\!-\\/]]")); EXPECT_TRUE(sourcemeta::core::matches(regex.value(), "!")); @@ -2774,7 +2774,7 @@ TEST(ecma262_v_flag_backspace_in_class) { TEST(ecma262_v_flag_control_escape_intersect) { const auto regex{ - sourcemeta::core::to_regex("[[\\cA-\\cZ]&&[\\x01-\\x03]]", + sourcemeta::core::to_regex(R"([[\cA-\cZ]&&[\x01-\x03]])", sourcemeta::core::RegexDialect::Permissive)}; EXPECT_TRUE(regex.has_value()); EXPECT_TRUE(sourcemeta::core::is_regex_ecma("[[\\cA-\\cZ]&&[\\x01-\\x03]]")); @@ -2893,7 +2893,7 @@ TEST(ecma262_v_flag_word_minus_alphanumeric) { TEST(ecma262_v_flag_multiple_escape_sequences_subtract) { const auto regex{sourcemeta::core::to_regex( - "[[[\\t\\n\\r]]--[\\t]]", sourcemeta::core::RegexDialect::Permissive)}; + R"([[[\t\n\r]]--[\t]])", sourcemeta::core::RegexDialect::Permissive)}; EXPECT_TRUE(regex.has_value()); EXPECT_TRUE(sourcemeta::core::is_regex_ecma("[[[\\t\\n\\r]]--[\\t]]")); EXPECT_TRUE(sourcemeta::core::matches(regex.value(), "\n")); @@ -2915,7 +2915,7 @@ TEST(ecma262_v_flag_mixed_unicode_escape_types) { TEST(ecma262_v_flag_control_char_range_intersect) { const auto regex{ - sourcemeta::core::to_regex("[[\\x00-\\x1F]&&[\\x00-\\x0F]]", + sourcemeta::core::to_regex(R"([[\x00-\x1F]&&[\x00-\x0F]])", sourcemeta::core::RegexDialect::Permissive)}; EXPECT_TRUE(regex.has_value()); EXPECT_TRUE( @@ -2928,7 +2928,7 @@ TEST(ecma262_v_flag_control_char_range_intersect) { TEST(ecma262_v_flag_del_char_subtract) { const auto regex{sourcemeta::core::to_regex( - "[[\\x7E-\\x7F]--[\\x7E]]", sourcemeta::core::RegexDialect::Permissive)}; + R"([[\x7E-\x7F]--[\x7E]])", sourcemeta::core::RegexDialect::Permissive)}; EXPECT_TRUE(regex.has_value()); EXPECT_TRUE(sourcemeta::core::is_regex_ecma("[[\\x7E-\\x7F]--[\\x7E]]")); EXPECT_TRUE(sourcemeta::core::matches(regex.value(), "\x7F")); @@ -2938,7 +2938,7 @@ TEST(ecma262_v_flag_del_char_subtract) { TEST(ecma262_v_flag_form_feed_and_vertical_tab) { const auto regex{sourcemeta::core::to_regex( - "[[\\f\\v]--[\\f]]", sourcemeta::core::RegexDialect::Permissive)}; + R"([[\f\v]--[\f]])", sourcemeta::core::RegexDialect::Permissive)}; EXPECT_TRUE(regex.has_value()); EXPECT_TRUE(sourcemeta::core::is_regex_ecma("[[\\f\\v]--[\\f]]")); EXPECT_TRUE(sourcemeta::core::matches(regex.value(), "\v")); @@ -2947,7 +2947,7 @@ TEST(ecma262_v_flag_form_feed_and_vertical_tab) { TEST(ecma262_v_flag_null_char_in_operation) { const auto regex{sourcemeta::core::to_regex( - "[[\\x00-\\x02]--[\\x00]]", sourcemeta::core::RegexDialect::Permissive)}; + R"([[\x00-\x02]--[\x00]])", sourcemeta::core::RegexDialect::Permissive)}; EXPECT_TRUE(regex.has_value()); EXPECT_TRUE(sourcemeta::core::is_regex_ecma("[[\\x00-\\x02]--[\\x00]]")); EXPECT_TRUE(sourcemeta::core::matches(regex.value(), "\x01")); @@ -2984,7 +2984,7 @@ TEST(ecma262_v_flag_five_way_chained_intersection) { TEST(ecma262_v_flag_lowercase_control_escape) { const auto regex{ - sourcemeta::core::to_regex("[[\\ca-\\cz]&&[\\x01-\\x03]]", + sourcemeta::core::to_regex(R"([[\ca-\cz]&&[\x01-\x03]])", sourcemeta::core::RegexDialect::Permissive)}; EXPECT_TRUE(regex.has_value()); EXPECT_TRUE(sourcemeta::core::is_regex_ecma("[[\\ca-\\cz]&&[\\x01-\\x03]]")); @@ -3090,7 +3090,7 @@ TEST(ecma262_v_flag_escaped_open_bracket) { TEST(ecma262_v_flag_only_special_punctuation) { const auto regex{sourcemeta::core::to_regex( - "[[\\!-\\/]&&[\\(-+]]", sourcemeta::core::RegexDialect::Permissive)}; + R"([[\!-\/]&&[\(-+]])", sourcemeta::core::RegexDialect::Permissive)}; EXPECT_TRUE(regex.has_value()); EXPECT_TRUE(sourcemeta::core::is_regex_ecma("[[\\!-\\/]&&[\\(-+]]")); EXPECT_TRUE(sourcemeta::core::matches(regex.value(), "(")); @@ -3334,7 +3334,7 @@ TEST(ecma262_v_flag_space_in_operation) { TEST(ecma262_v_flag_bell_char_subtract) { const auto regex{sourcemeta::core::to_regex( - "[[\\x07-\\x09]--[\\x08]]", sourcemeta::core::RegexDialect::Permissive)}; + R"([[\x07-\x09]--[\x08]])", sourcemeta::core::RegexDialect::Permissive)}; EXPECT_TRUE(regex.has_value()); EXPECT_TRUE(sourcemeta::core::is_regex_ecma("[[\\x07-\\x09]--[\\x08]]")); EXPECT_TRUE(sourcemeta::core::matches(regex.value(), "\x07")); @@ -3353,7 +3353,7 @@ TEST(ecma262_v_flag_escape_sequence_vs_hex) { TEST(ecma262_v_flag_carriage_return_line_feed) { const auto regex{sourcemeta::core::to_regex( - "[[\\r\\n]--[\\n]]", sourcemeta::core::RegexDialect::Permissive)}; + R"([[\r\n]--[\n]])", sourcemeta::core::RegexDialect::Permissive)}; EXPECT_TRUE(regex.has_value()); EXPECT_TRUE(sourcemeta::core::is_regex_ecma("[[\\r\\n]--[\\n]]")); EXPECT_TRUE(sourcemeta::core::matches(regex.value(), "\r")); @@ -3468,7 +3468,7 @@ TEST(ecma262_v_flag_equals_and_less_greater) { TEST(ecma262_v_flag_curly_braces_in_class) { const auto regex{sourcemeta::core::to_regex( - "[[\\{\\}]--[\\{]]", sourcemeta::core::RegexDialect::Permissive)}; + R"([[\{\}]--[\{]])", sourcemeta::core::RegexDialect::Permissive)}; EXPECT_TRUE(regex.has_value()); EXPECT_TRUE(sourcemeta::core::is_regex_ecma("[[\\{\\}]--[\\{]]")); EXPECT_TRUE(sourcemeta::core::matches(regex.value(), "}")); @@ -3477,7 +3477,7 @@ TEST(ecma262_v_flag_curly_braces_in_class) { TEST(ecma262_v_flag_parentheses_in_class) { const auto regex{sourcemeta::core::to_regex( - "[[\\(\\)]--[\\(]]", sourcemeta::core::RegexDialect::Permissive)}; + R"([[\(\)]--[\(]])", sourcemeta::core::RegexDialect::Permissive)}; EXPECT_TRUE(regex.has_value()); EXPECT_TRUE(sourcemeta::core::is_regex_ecma("[[\\(\\)]--[\\(]]")); EXPECT_TRUE(sourcemeta::core::matches(regex.value(), ")")); @@ -3580,7 +3580,7 @@ TEST(ecma262_v_flag_single_quote_double_quote) { TEST(ecma262_v_flag_forward_slash_backslash) { const auto regex{sourcemeta::core::to_regex( - "[[\\\\]--[\\/]]", sourcemeta::core::RegexDialect::Permissive)}; + R"([[\\]--[\/]])", sourcemeta::core::RegexDialect::Permissive)}; EXPECT_TRUE(regex.has_value()); EXPECT_TRUE(sourcemeta::core::is_regex_ecma("[[\\\\]--[\\/]]")); EXPECT_TRUE(sourcemeta::core::matches(regex.value(), "\\")); diff --git a/test/regex/regex_permissive_matches_rfc9485_test.cc b/test/regex/regex_permissive_matches_rfc9485_test.cc index 43fc42aa51..ebaf8203b7 100644 --- a/test/regex/regex_permissive_matches_rfc9485_test.cc +++ b/test/regex/regex_permissive_matches_rfc9485_test.cc @@ -1048,7 +1048,7 @@ TEST(rfc9485_edge_charclass_with_unicode_properties) { TEST(rfc9485_all_major_categories_combined) { const auto regex{ - sourcemeta::core::to_regex("[\\p{L}\\p{M}\\p{N}\\p{P}\\p{Z}\\p{S}\\p{C}]", + sourcemeta::core::to_regex(R"([\p{L}\p{M}\p{N}\p{P}\p{Z}\p{S}\p{C}])", sourcemeta::core::RegexDialect::Permissive)}; EXPECT_TRUE(regex.has_value()); EXPECT_TRUE(sourcemeta::core::is_regex_ecma( @@ -1062,7 +1062,7 @@ TEST(rfc9485_all_major_categories_combined) { TEST(rfc9485_complement_all_major_categories) { const auto regex{sourcemeta::core::to_regex( - "\\P{L}\\P{N}\\P{P}", sourcemeta::core::RegexDialect::Permissive)}; + R"(\P{L}\P{N}\P{P})", sourcemeta::core::RegexDialect::Permissive)}; EXPECT_TRUE(regex.has_value()); EXPECT_TRUE(sourcemeta::core::is_regex_ecma("\\P{L}\\P{N}\\P{P}")); EXPECT_TRUE(sourcemeta::core::matches(regex.value(), " ")); @@ -1129,7 +1129,7 @@ TEST(rfc9485_edge_mixed_quantifiers_sequence) { TEST(rfc9485_edge_unicode_in_alternation) { const auto regex{sourcemeta::core::to_regex( - "\\p{Lu}|\\p{Ll}|\\p{Nd}", sourcemeta::core::RegexDialect::Permissive)}; + R"(\p{Lu}|\p{Ll}|\p{Nd})", sourcemeta::core::RegexDialect::Permissive)}; EXPECT_TRUE(regex.has_value()); EXPECT_TRUE(sourcemeta::core::is_regex_ecma("\\p{Lu}|\\p{Ll}|\\p{Nd}")); EXPECT_TRUE(sourcemeta::core::matches(regex.value(), "A")); @@ -1186,7 +1186,7 @@ TEST(rfc9485_edge_complex_real_world_uuid_partial) { TEST(rfc9485_preprocessing_literal_backslash_p) { const auto regex{sourcemeta::core::to_regex( - "\\\\p\\{L\\}", sourcemeta::core::RegexDialect::Permissive)}; + R"(\\p\{L\})", sourcemeta::core::RegexDialect::Permissive)}; EXPECT_TRUE(regex.has_value()); EXPECT_TRUE(sourcemeta::core::is_regex_ecma("\\\\p\\{L\\}")); EXPECT_TRUE(sourcemeta::core::matches(regex.value(), "\\p{L}")); @@ -1195,7 +1195,7 @@ TEST(rfc9485_preprocessing_literal_backslash_p) { TEST(rfc9485_preprocessing_literal_backslash_P) { const auto regex{sourcemeta::core::to_regex( - "\\\\P\\{N\\}", sourcemeta::core::RegexDialect::Permissive)}; + R"(\\P\{N\})", sourcemeta::core::RegexDialect::Permissive)}; EXPECT_TRUE(regex.has_value()); EXPECT_TRUE(sourcemeta::core::is_regex_ecma("\\\\P\\{N\\}")); EXPECT_TRUE(sourcemeta::core::matches(regex.value(), "\\P{N}")); @@ -1204,7 +1204,7 @@ TEST(rfc9485_preprocessing_literal_backslash_P) { TEST(rfc9485_preprocessing_mixed_escaped_and_unicode) { const auto regex{sourcemeta::core::to_regex( - "\\\\p\\{L\\} \\p{L}", sourcemeta::core::RegexDialect::Permissive)}; + R"(\\p\{L\} \p{L})", sourcemeta::core::RegexDialect::Permissive)}; EXPECT_TRUE(regex.has_value()); EXPECT_TRUE(sourcemeta::core::is_regex_ecma("\\\\p\\{L\\} \\p{L}")); EXPECT_TRUE(sourcemeta::core::matches(regex.value(), "\\p{L} A")); diff --git a/test/regex/regex_rfc9485_matches_test.cc b/test/regex/regex_rfc9485_matches_test.cc index 20c30643d8..094ab56ac1 100644 --- a/test/regex/regex_rfc9485_matches_test.cc +++ b/test/regex/regex_rfc9485_matches_test.cc @@ -142,7 +142,7 @@ TEST(rfc9485_matches_bare_dash) { TEST(rfc9485_matches_single_char_escapes_punctuation) { const auto regex{sourcemeta::core::to_regex( - "\\(\\)\\*\\+\\.\\?\\[\\\\", sourcemeta::core::RegexDialect::IRegexp)}; + R"(\(\)\*\+\.\?\[\\)", sourcemeta::core::RegexDialect::IRegexp)}; EXPECT_TRUE(regex.has_value()); EXPECT_TRUE(sourcemeta::core::matches(regex.value(), "()*+.?[\\")); EXPECT_FALSE(sourcemeta::core::matches(regex.value(), "()*+.?[")); @@ -150,7 +150,7 @@ TEST(rfc9485_matches_single_char_escapes_punctuation) { TEST(rfc9485_matches_single_char_escapes_delimiters) { const auto regex{sourcemeta::core::to_regex( - "\\]\\{\\|\\}\\t\\r\\n", sourcemeta::core::RegexDialect::IRegexp)}; + R"(\]\{\|\}\t\r\n)", sourcemeta::core::RegexDialect::IRegexp)}; EXPECT_TRUE(regex.has_value()); EXPECT_TRUE(sourcemeta::core::matches(regex.value(), "]{|}\t\r\n")); EXPECT_FALSE(sourcemeta::core::matches(regex.value(), "]{|}trn")); diff --git a/test/regex/regex_test.cc b/test/regex/regex_test.cc index 3c4be75f13..a9267339a7 100644 --- a/test/regex/regex_test.cc +++ b/test/regex/regex_test.cc @@ -9,6 +9,7 @@ TEST(copy_construct) { const auto regex{sourcemeta::core::to_regex("^foo")}; EXPECT_TRUE(regex.has_value()); + // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) const sourcemeta::core::Regex copy{regex.value()}; EXPECT_TRUE(sourcemeta::core::matches(copy, "foo bar")); EXPECT_FALSE(sourcemeta::core::matches(copy, "bar foo")); @@ -95,6 +96,7 @@ TEST(pcre2_equality_of_a_copy) { EXPECT_TRUE(regex.has_value()); EXPECT_TRUE( std::holds_alternative(regex.value())); + // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) const sourcemeta::core::Regex copy{regex.value()}; EXPECT_EQ(copy, regex.value()); } diff --git a/test/time/rfc3339_duration_test.cc b/test/time/rfc3339_duration_test.cc index 3951aeb653..17b5537cc5 100644 --- a/test/time/rfc3339_duration_test.cc +++ b/test/time/rfc3339_duration_test.cc @@ -1,7 +1,9 @@ #include #include -#include +#include // std::string_view + +using namespace std::literals::string_view_literals; TEST(valid_year_only) { EXPECT_TRUE(sourcemeta::core::is_rfc3339_duration("P1Y")); @@ -1089,17 +1091,15 @@ TEST(ext_invalid_garbage_8) { } TEST(delta_u0000_u0050_day_0) { - static constexpr char VALUE[] = "\x00P1D"; - static_assert(sizeof(VALUE) - 1 == 4); - EXPECT_FALSE( - sourcemeta::core::is_rfc3339_duration(std::string_view{VALUE, 4})); + static constexpr auto VALUE{"\x00P1D"sv}; + static_assert(VALUE.size() == 4); + EXPECT_FALSE(sourcemeta::core::is_rfc3339_duration(VALUE)); } TEST(delta_u0000_u0050_day_u0000_1) { - static constexpr char VALUE[] = "\x00P1D\x00"; - static_assert(sizeof(VALUE) - 1 == 5); - EXPECT_FALSE( - sourcemeta::core::is_rfc3339_duration(std::string_view{VALUE, 5})); + static constexpr auto VALUE{"\x00P1D\x00"sv}; + static_assert(VALUE.size() == 5); + EXPECT_FALSE(sourcemeta::core::is_rfc3339_duration(VALUE)); } TEST(delta_u0009_u0050_day_u0009_2) { @@ -1259,11 +1259,10 @@ TEST(delta_u0078_year_40) { } TEST(delta_u0000_day_41) { - static constexpr char VALUE[] = "P1\x00" - "D"; - static_assert(sizeof(VALUE) - 1 == 4); - EXPECT_FALSE( - sourcemeta::core::is_rfc3339_duration(std::string_view{VALUE, 4})); + static constexpr auto VALUE{"P1\x00" + "D"sv}; + static_assert(VALUE.size() == 4); + EXPECT_FALSE(sourcemeta::core::is_rfc3339_duration(VALUE)); } TEST(delta_u0009_day_42) { @@ -1414,10 +1413,9 @@ TEST(delta_u0043_76) { } TEST(delta_day_u0000_77) { - static constexpr char VALUE[] = "P1D\x00"; - static_assert(sizeof(VALUE) - 1 == 4); - EXPECT_FALSE( - sourcemeta::core::is_rfc3339_duration(std::string_view{VALUE, 4})); + static constexpr auto VALUE{"P1D\x00"sv}; + static_assert(VALUE.size() == 4); + EXPECT_FALSE(sourcemeta::core::is_rfc3339_duration(VALUE)); } TEST(delta_day_u000b_78) { diff --git a/test/time/rfc3339_fulldate_test.cc b/test/time/rfc3339_fulldate_test.cc index 5661be64e2..b0d9988d4a 100644 --- a/test/time/rfc3339_fulldate_test.cc +++ b/test/time/rfc3339_fulldate_test.cc @@ -1,6 +1,10 @@ #include #include +#include // std::string_view + +using namespace std::literals::string_view_literals; + TEST(valid_basic) { EXPECT_TRUE(sourcemeta::core::is_rfc3339_fulldate("2024-01-15")); } @@ -340,8 +344,7 @@ TEST(length_11_trailing_cr) { } TEST(length_11_trailing_nul) { - EXPECT_FALSE(sourcemeta::core::is_rfc3339_fulldate( - std::string_view("2020-01-01\x00", 11))); + EXPECT_FALSE(sourcemeta::core::is_rfc3339_fulldate("2020-01-01\x00"sv)); } TEST(length_11_leading_newline) { @@ -632,18 +635,19 @@ TEST(both_separators_newline) { } TEST(first_separator_nul) { - EXPECT_FALSE(sourcemeta::core::is_rfc3339_fulldate( - std::string_view("2020\x0001-01", 10))); + EXPECT_FALSE(sourcemeta::core::is_rfc3339_fulldate("2020\x00" + "01-01"sv)); } TEST(second_separator_nul) { - EXPECT_FALSE(sourcemeta::core::is_rfc3339_fulldate( - std::string_view("2020-01\x0001", 10))); + EXPECT_FALSE(sourcemeta::core::is_rfc3339_fulldate("2020-01\x00" + "01"sv)); } TEST(both_separators_nul) { - EXPECT_FALSE(sourcemeta::core::is_rfc3339_fulldate( - std::string_view("2020\x0001\x0001", 10))); + EXPECT_FALSE(sourcemeta::core::is_rfc3339_fulldate("2020\x00" + "01\x00" + "01"sv)); } TEST(digit_slot_year_d1_alpha) { @@ -667,8 +671,8 @@ TEST(digit_slot_year_d1_slash) { } TEST(digit_slot_year_d1_nul) { - EXPECT_FALSE(sourcemeta::core::is_rfc3339_fulldate( - std::string_view("\x00020-01-01", 10))); + EXPECT_FALSE(sourcemeta::core::is_rfc3339_fulldate("\x00" + "020-01-01"sv)); } TEST(digit_slot_year_d2_alpha) { @@ -692,8 +696,8 @@ TEST(digit_slot_year_d2_slash) { } TEST(digit_slot_year_d2_nul) { - EXPECT_FALSE(sourcemeta::core::is_rfc3339_fulldate( - std::string_view("2\x0020-01-01", 10))); + EXPECT_FALSE(sourcemeta::core::is_rfc3339_fulldate("2\x00" + "20-01-01"sv)); } TEST(digit_slot_year_d3_alpha) { @@ -717,8 +721,8 @@ TEST(digit_slot_year_d3_slash) { } TEST(digit_slot_year_d3_nul) { - EXPECT_FALSE(sourcemeta::core::is_rfc3339_fulldate( - std::string_view("20\x000-01-01", 10))); + EXPECT_FALSE(sourcemeta::core::is_rfc3339_fulldate("20\x00" + "0-01-01"sv)); } TEST(digit_slot_year_d4_alpha) { @@ -742,8 +746,8 @@ TEST(digit_slot_year_d4_slash) { } TEST(digit_slot_year_d4_nul) { - EXPECT_FALSE(sourcemeta::core::is_rfc3339_fulldate( - std::string_view("202\x00-01-01", 10))); + EXPECT_FALSE(sourcemeta::core::is_rfc3339_fulldate("202\x00" + "-01-01"sv)); } TEST(digit_slot_month_d1_alpha) { @@ -767,8 +771,8 @@ TEST(digit_slot_month_d1_slash) { } TEST(digit_slot_month_d1_nul) { - EXPECT_FALSE(sourcemeta::core::is_rfc3339_fulldate( - std::string_view("2020-\x001-01", 10))); + EXPECT_FALSE(sourcemeta::core::is_rfc3339_fulldate("2020-\x00" + "1-01"sv)); } TEST(digit_slot_month_d2_alpha) { @@ -792,8 +796,8 @@ TEST(digit_slot_month_d2_slash) { } TEST(digit_slot_month_d2_nul) { - EXPECT_FALSE(sourcemeta::core::is_rfc3339_fulldate( - std::string_view("2020-0\x00-01", 10))); + EXPECT_FALSE(sourcemeta::core::is_rfc3339_fulldate("2020-0\x00" + "-01"sv)); } TEST(digit_slot_day_d1_alpha) { @@ -817,8 +821,8 @@ TEST(digit_slot_day_d1_slash) { } TEST(digit_slot_day_d1_nul) { - EXPECT_FALSE(sourcemeta::core::is_rfc3339_fulldate( - std::string_view("2020-01-\x001", 10))); + EXPECT_FALSE(sourcemeta::core::is_rfc3339_fulldate("2020-01-\x00" + "1"sv)); } TEST(digit_slot_day_d2_alpha) { @@ -842,8 +846,7 @@ TEST(digit_slot_day_d2_slash) { } TEST(digit_slot_day_d2_nul) { - EXPECT_FALSE(sourcemeta::core::is_rfc3339_fulldate( - std::string_view("2020-01-0\x00", 10))); + EXPECT_FALSE(sourcemeta::core::is_rfc3339_fulldate("2020-01-0\x00"sv)); } TEST(month_second_digit_colon_lands_in_range) { diff --git a/test/unicode/unicode_normalization_suite.cc b/test/unicode/unicode_normalization_suite.cc index 6818df989c..ad939fc4dc 100644 --- a/test/unicode/unicode_normalization_suite.cc +++ b/test/unicode/unicode_normalization_suite.cc @@ -75,27 +75,27 @@ auto run_normalization_test_case(const std::string_view raw_line) -> void { // Per the NormalizationTest.txt header, the NFC invariants over the // five columns are: // - // c2 == toNFC(c1) == toNFC(c2) == toNFC(c3) - // c4 == toNFC(c4) == toNFC(c5) + // column2 == toNFC(column1) == toNFC(column2) == toNFC(column3) + // column4 == toNFC(column4) == toNFC(column5) // // and a codepoint is in NFC iff its NFC form equals itself. - const auto &c1{fields[0]}; - const auto &c2{fields[1]}; - const auto &c3{fields[2]}; - const auto &c4{fields[3]}; - const auto &c5{fields[4]}; - - EXPECT_EQ(sourcemeta::core::nfc(c1), c2); - EXPECT_EQ(sourcemeta::core::nfc(c2), c2); - EXPECT_EQ(sourcemeta::core::nfc(c3), c2); - EXPECT_EQ(sourcemeta::core::nfc(c4), c4); - EXPECT_EQ(sourcemeta::core::nfc(c5), c4); - - EXPECT_TRUE(sourcemeta::core::is_nfc(c2)); - EXPECT_TRUE(sourcemeta::core::is_nfc(c4)); - EXPECT_EQ(sourcemeta::core::is_nfc(c1), c1 == c2); - EXPECT_EQ(sourcemeta::core::is_nfc(c3), c3 == c2); - EXPECT_EQ(sourcemeta::core::is_nfc(c5), c5 == c4); + const auto &column1{fields[0]}; + const auto &column2{fields[1]}; + const auto &column3{fields[2]}; + const auto &column4{fields[3]}; + const auto &column5{fields[4]}; + + EXPECT_EQ(sourcemeta::core::nfc(column1), column2); + EXPECT_EQ(sourcemeta::core::nfc(column2), column2); + EXPECT_EQ(sourcemeta::core::nfc(column3), column2); + EXPECT_EQ(sourcemeta::core::nfc(column4), column4); + EXPECT_EQ(sourcemeta::core::nfc(column5), column4); + + EXPECT_TRUE(sourcemeta::core::is_nfc(column2)); + EXPECT_TRUE(sourcemeta::core::is_nfc(column4)); + EXPECT_EQ(sourcemeta::core::is_nfc(column1), column1 == column2); + EXPECT_EQ(sourcemeta::core::is_nfc(column3), column3 == column2); + EXPECT_EQ(sourcemeta::core::is_nfc(column5), column5 == column4); } auto register_tests(const std::string_view contents) -> void { diff --git a/test/uri/uri_fragment_test.cc b/test/uri/uri_fragment_test.cc index 002d543a24..06c6f75401 100644 --- a/test/uri/uri_fragment_test.cc +++ b/test/uri/uri_fragment_test.cc @@ -45,7 +45,7 @@ TEST(encoded_question_mark_preserved) { TEST(invalid_fragment_with_pointer) { try { - sourcemeta::core::URI{"#foo#/$defs/bar"}; + const sourcemeta::core::URI uri{"#foo#/$defs/bar"}; FAIL(); } catch (const sourcemeta::core::URIParseError &error) { EXPECT_EQ(error.column(), 5); diff --git a/test/uri/uri_from_path_test.cc b/test/uri/uri_from_path_test.cc index 2ae87b3518..3e075e4093 100644 --- a/test/uri/uri_from_path_test.cc +++ b/test/uri/uri_from_path_test.cc @@ -152,7 +152,7 @@ TEST(windows_relative_with_dot) { } TEST(windows_relative_with_dotdot) { - const std::filesystem::path example{"..\\up\\one\\level"}; + const std::filesystem::path example{R"(..\up\one\level)"}; try { sourcemeta::core::URI::from_path(example); FAIL(); diff --git a/test/uri/uri_is_internationalized_test.cc b/test/uri/uri_is_internationalized_test.cc index 314a480aac..c88f00b4b4 100644 --- a/test/uri/uri_is_internationalized_test.cc +++ b/test/uri/uri_is_internationalized_test.cc @@ -48,12 +48,14 @@ TEST(from_path) { TEST(survives_copy) { const auto original{ sourcemeta::core::URI::from_iri("https://example.com/caf\xC3\xA9")}; + // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) const sourcemeta::core::URI copy{original}; EXPECT_TRUE(copy.is_internationalized()); } TEST(plain_uri_survives_copy) { const sourcemeta::core::URI original{"https://example.com/foo"}; + // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) const sourcemeta::core::URI copy{original}; EXPECT_FALSE(copy.is_internationalized()); } diff --git a/test/uri/uri_is_uri_test.cc b/test/uri/uri_is_uri_test.cc index ec2dce1681..54574ff08c 100644 --- a/test/uri/uri_is_uri_test.cc +++ b/test/uri/uri_is_uri_test.cc @@ -725,6 +725,7 @@ TEST(userinfo_with_non_ascii) { } TEST(path_with_right_to_left_override) { + // NOLINTNEXTLINE(misc-misleading-bidirectional) const std::string input{"http://example.com/a\xE2\x80\xAE" "b"}; EXPECT_FALSE(sourcemeta::core::URI::is_uri(input)); diff --git a/test/uri/uri_parse_test.cc b/test/uri/uri_parse_test.cc index bde63c34c2..d2f05ee0cf 100644 --- a/test/uri/uri_parse_test.cc +++ b/test/uri/uri_parse_test.cc @@ -941,7 +941,7 @@ TEST(rfc3986_empty_path_with_fragment) { TEST(uri_constructor_rejects_non_ascii) { // The plain URI constructor does not accept IRI characters try { - sourcemeta::core::URI{"https://example.com/caf\xC3\xA9"}; + const sourcemeta::core::URI uri{"https://example.com/caf\xC3\xA9"}; FAIL(); } catch (const sourcemeta::core::URIParseError &error) { EXPECT_EQ(error.column(), 24); diff --git a/test/uri/uri_path_test.cc b/test/uri/uri_path_test.cc index ac9a5a55f2..a47cfab5b5 100644 --- a/test/uri/uri_path_test.cc +++ b/test/uri/uri_path_test.cc @@ -171,7 +171,7 @@ TEST(set_relative_path) { "You cannot set a relative path to an absolute URI"); } - auto path{"../foo"}; + const auto *path{"../foo"}; try { uri.path(path); FAIL(); @@ -321,7 +321,7 @@ TEST(lowercase_relative_path) { EXPECT_EQ(uri.recompose(), "../SERVER.JSON"); uri.path("../server.json"); EXPECT_EQ(uri.recompose(), "../server.json"); - const auto const_path{"../foo.json"}; + const auto *const const_path{"../foo.json"}; uri.path(const_path); EXPECT_EQ(uri.recompose(), "../foo.json"); } diff --git a/test/uri/uri_test.cc b/test/uri/uri_test.cc index dc17f48899..b453e6cab4 100644 --- a/test/uri/uri_test.cc +++ b/test/uri/uri_test.cc @@ -19,12 +19,14 @@ TEST(default_constructor_equals_empty_string) { TEST(copy_constructor) { const sourcemeta::core::URI uri_1{"https://example.com"}; + // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) const sourcemeta::core::URI uri_2{uri_1}; EXPECT_EQ(uri_1.recompose(), uri_2.recompose()); } TEST(copy_constructor_empty) { const sourcemeta::core::URI uri_1; + // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) const sourcemeta::core::URI uri_2{uri_1}; EXPECT_TRUE(uri_2.empty()); EXPECT_EQ(uri_1, uri_2); diff --git a/test/uritemplate/uritemplate_router_test.cc b/test/uritemplate/uritemplate_router_test.cc index 6492e42942..3a6e45c588 100644 --- a/test/uritemplate/uritemplate_router_test.cc +++ b/test/uritemplate/uritemplate_router_test.cc @@ -1706,6 +1706,7 @@ TEST(listing_iterate_via_size_and_at) { router.add("/c/{+rest}", "op_202", 30); std::vector seen; + seen.reserve(router.size()); for (std::size_t index = 0; index < router.size(); ++index) { seen.push_back(router.at(index)); } diff --git a/test/uritemplate/uritemplate_router_view_test.cc b/test/uritemplate/uritemplate_router_view_test.cc index 2e366c857b..383edb74e2 100644 --- a/test/uritemplate/uritemplate_router_view_test.cc +++ b/test/uritemplate/uritemplate_router_view_test.cc @@ -37,12 +37,13 @@ namespace { auto corrupt_router_core(const std::uint32_t operations_offset, const std::uint32_t paths_offset) -> std::vector { - const std::uint32_t words[] = {0x52544552, 9, 1, 80, 80, 0x50, 0, - 0, 0, 0, 0, 0, 0, 0, - 0xFFFFFFFF, 0, 0xFFFFFFFF, 0, 0, 0}; + const std::array words{ + {0x52544552, 9, 1, 80, 80, 0x50, 0, 0, 0, 0, + 0, 0, 0, 0, 0xFFFFFFFF, 0, 0xFFFFFFFF, 0, 0, 0}}; std::vector bytes{ - reinterpret_cast(words), - reinterpret_cast(words) + sizeof(words)}; + reinterpret_cast(words.data()), + reinterpret_cast(words.data()) + + (words.size() * sizeof(words[0]))}; std::memcpy(bytes.data() + 20, &operations_offset, sizeof(operations_offset)); std::memcpy(bytes.data() + 44, &paths_offset, sizeof(paths_offset)); return bytes; @@ -763,119 +764,135 @@ TEST_F(URITemplateRouterViewTest, matches_from_unaligned_external_buffer) { } TEST(corrupt_too_small_for_header) { - const std::uint8_t data[] = {0xDE, 0xAD, 0xBE, 0xEF, 0x01, 0x02, 0x03}; - const sourcemeta::core::URITemplateRouterView view{data, sizeof(data)}; + const std::array data{ + {0xDE, 0xAD, 0xBE, 0xEF, 0x01, 0x02, 0x03}}; + const sourcemeta::core::URITemplateRouterView view{ + data.data(), (data.size() * sizeof(data[0]))}; EXPECT_ROUTER_MATCH(view, "/users", 0, 0, captures); EXPECT_EQ(captures.size(), 0); } TEST(corrupt_wrong_magic) { - const std::uint32_t data[] = {0xDEADBEEF, 9, 1, 80, 80, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + const std::array data{ + {0xDEADBEEF, 9, 1, 80, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}; const sourcemeta::core::URITemplateRouterView view{ - reinterpret_cast(data), sizeof(data)}; + reinterpret_cast(data.data()), + (data.size() * sizeof(data[0]))}; EXPECT_ROUTER_MATCH(view, "/users", 0, 0, captures); EXPECT_EQ(captures.size(), 0); } TEST(corrupt_wrong_version) { - const std::uint32_t data[] = {0x52544552, 99, 1, 80, 80, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + const std::array data{ + {0x52544552, 99, 1, 80, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}; const sourcemeta::core::URITemplateRouterView view{ - reinterpret_cast(data), sizeof(data)}; + reinterpret_cast(data.data()), + (data.size() * sizeof(data[0]))}; EXPECT_ROUTER_MATCH(view, "/users", 0, 0, captures); EXPECT_EQ(captures.size(), 0); } TEST(corrupt_node_count_exceeds_file) { - const std::uint32_t data[] = {0x52544552, 9, 10, 48, 48, 0, 0, 0, 0, 0, 0, 0}; + const std::array data{ + {0x52544552, 9, 10, 48, 48, 0, 0, 0, 0, 0, 0, 0}}; const sourcemeta::core::URITemplateRouterView view{ - reinterpret_cast(data), sizeof(data)}; + reinterpret_cast(data.data()), + (data.size() * sizeof(data[0]))}; EXPECT_ROUTER_MATCH(view, "/users", 0, 0, captures); EXPECT_EQ(captures.size(), 0); } TEST(corrupt_literal_child_out_of_bounds) { - const std::uint32_t data[] = {0x52544552, 9, 1, 80, 80, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 999, 1, 0xFFFFFFFF, 0, 0, 0}; + const std::array data{{0x52544552, 9, 1, 80, 80, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 999, 1, + 0xFFFFFFFF, 0, 0, 0}}; const sourcemeta::core::URITemplateRouterView view{ - reinterpret_cast(data), sizeof(data)}; + reinterpret_cast(data.data()), + (data.size() * sizeof(data[0]))}; EXPECT_ROUTER_MATCH(view, "/users", 0, 0, captures); EXPECT_EQ(captures.size(), 0); } TEST(corrupt_variable_child_out_of_bounds) { - const std::uint32_t data[] = {0x52544552, 9, 1, 80, 80, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0xFFFFFFFF, 0, 500, 0, 0, 0}; + const std::array data{{0x52544552, 9, 1, 80, 80, 0, 0, + 0, 0, 0, 0, 0, 0, 0, + 0xFFFFFFFF, 0, 500, 0, 0, 0}}; const sourcemeta::core::URITemplateRouterView view{ - reinterpret_cast(data), sizeof(data)}; + reinterpret_cast(data.data()), + (data.size() * sizeof(data[0]))}; EXPECT_ROUTER_MATCH(view, "/users", 0, 0, captures); EXPECT_EQ(captures.size(), 0); } TEST(corrupt_string_offset_out_of_bounds) { - const std::uint32_t data[] = {0x52544552, 9, 2, 112, 112, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 1, - 0xFFFFFFFF, 0, 0, 0, 9999, 5, 0xFFFFFFFF, 0, - 0xFFFFFFFF, 0, 0, 0}; + const std::array data{ + {0x52544552, 9, 2, 112, 112, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 0xFFFFFFFF, 0, 0, 0, + 9999, 5, 0xFFFFFFFF, 0, 0xFFFFFFFF, 0, 0, 0}}; const sourcemeta::core::URITemplateRouterView view{ - reinterpret_cast(data), sizeof(data)}; + reinterpret_cast(data.data()), + (data.size() * sizeof(data[0]))}; EXPECT_ROUTER_MATCH(view, "/users", 0, 0, captures); EXPECT_EQ(captures.size(), 0); } TEST(corrupt_variable_string_offset_out_of_bounds) { - const std::uint32_t data[] = { - 0x52544552, 9, 2, 112, 112, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0xFFFFFFFF, 0, 1, 0, 0, 0, - 9999, 100, 0xFFFFFFFF, 0, 0xFFFFFFFF, 0x00000002, 0, 0}; + const std::array data{ + {0x52544552, 9, 2, 112, 112, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0xFFFFFFFF, 0, 1, 0, 0, 0, + 9999, 100, 0xFFFFFFFF, 0, 0xFFFFFFFF, 0x00000002, 0, 0}}; const sourcemeta::core::URITemplateRouterView view{ - reinterpret_cast(data), sizeof(data)}; + reinterpret_cast(data.data()), + (data.size() * sizeof(data[0]))}; EXPECT_ROUTER_MATCH(view, "/users", 0, 0, captures); EXPECT_EQ(captures.size(), 0); } TEST(corrupt_all_zeroes) { - const std::uint8_t data[128] = {}; - const sourcemeta::core::URITemplateRouterView view{data, sizeof(data)}; + const std::array data{}; + const sourcemeta::core::URITemplateRouterView view{ + data.data(), (data.size() * sizeof(data[0]))}; EXPECT_ROUTER_MATCH(view, "/users", 0, 0, captures); EXPECT_EQ(captures.size(), 0); } TEST(corrupt_all_ones) { - std::uint8_t data[128]; - std::memset(data, 0xFF, sizeof(data)); - const sourcemeta::core::URITemplateRouterView view{data, sizeof(data)}; + std::array data{}; + data.fill(0xFF); + const sourcemeta::core::URITemplateRouterView view{ + data.data(), (data.size() * sizeof(data[0]))}; EXPECT_ROUTER_MATCH(view, "/users", 0, 0, captures); EXPECT_EQ(captures.size(), 0); } TEST(corrupt_string_table_offset_overlaps_header) { - const std::uint32_t data[] = {0x52544552, 9, 1, 4, 80, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0xFFFFFFFF, 0, 0xFFFFFFFF, 0, 0, 0}; + const std::array data{ + {0x52544552, 9, 1, 4, 80, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0xFFFFFFFF, 0, 0xFFFFFFFF, 0, 0, 0}}; const sourcemeta::core::URITemplateRouterView view{ - reinterpret_cast(data), sizeof(data)}; + reinterpret_cast(data.data()), + (data.size() * sizeof(data[0]))}; EXPECT_ROUTER_MATCH(view, "/users", 0, 0, captures); EXPECT_EQ(captures.size(), 0); } TEST(corrupt_string_table_offset_past_end) { - const std::uint32_t data[] = {0x52544552, 9, 1, 99999, 99999, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0xFFFFFFFF, 0, 0xFFFFFFFF, 0, 0, 0}; + const std::array data{ + {0x52544552, 9, 1, 99999, 99999, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0xFFFFFFFF, 0, 0xFFFFFFFF, 0, 0, 0}}; const sourcemeta::core::URITemplateRouterView view{ - reinterpret_cast(data), sizeof(data)}; + reinterpret_cast(data.data()), + (data.size() * sizeof(data[0]))}; EXPECT_ROUTER_MATCH(view, "/users", 0, 0, captures); EXPECT_EQ(captures.size(), 0); } TEST(corrupt_zero_node_count) { - const std::uint32_t data[] = {0x52544552, 9, 0, 48, 48, 0, 0, 0, 0, 0, 0, 0}; + const std::array data{ + {0x52544552, 9, 0, 48, 48, 0, 0, 0, 0, 0, 0, 0}}; const sourcemeta::core::URITemplateRouterView view{ - reinterpret_cast(data), sizeof(data)}; + reinterpret_cast(data.data()), + (data.size() * sizeof(data[0]))}; EXPECT_ROUTER_MATCH(view, "/users", 0, 0, captures); EXPECT_EQ(captures.size(), 0); } @@ -893,38 +910,44 @@ TEST(corrupt_empty_data_match_root) { } TEST(corrupt_literal_child_count_overflow) { - const std::uint32_t data[] = { - 0x52544552, 9, 2, 112, 112, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 0xFFFFFFFF, 0xFFFFFFFF, 0, 0, 0, 0, 0, - 0xFFFFFFFF, 0, 0xFFFFFFFF, 0, 0, 0}; + const std::array data{ + {0x52544552, 9, 2, 112, 112, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0xFFFFFFFF, 0xFFFFFFFF, 0, 0, 0, 0, 0, + 0xFFFFFFFF, 0, 0xFFFFFFFF, 0, 0, 0}}; const sourcemeta::core::URITemplateRouterView view{ - reinterpret_cast(data), sizeof(data)}; + reinterpret_cast(data.data()), + (data.size() * sizeof(data[0]))}; EXPECT_ROUTER_MATCH(view, "/users", 0, 0, captures); EXPECT_EQ(captures.size(), 0); } TEST(corrupt_root_literal_child_oob_match_root) { - const std::uint32_t data[] = {0x52544552, 9, 1, 80, 80, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 999, 1, 0xFFFFFFFF, 0, 0, 0}; + const std::array data{{0x52544552, 9, 1, 80, 80, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 999, 1, + 0xFFFFFFFF, 0, 0, 0}}; const sourcemeta::core::URITemplateRouterView view{ - reinterpret_cast(data), sizeof(data)}; + reinterpret_cast(data.data()), + (data.size() * sizeof(data[0]))}; EXPECT_ROUTER_MATCH(view, "/", 0, 0, captures); EXPECT_EQ(captures.size(), 0); } TEST(corrupt_deep_node_variable_child_oob) { std::vector data; - const std::uint32_t header[] = {0x52544552, 9, 2, 112, 117, 0, - 0, 0, 0, 0, 0, 0}; - const std::uint32_t root[] = {0, 0, 1, 1, 0xFFFFFFFF, 0, 0, 0}; - const std::uint32_t child[] = {0, 5, 0xFFFFFFFF, 0, 999, 0x00000001, 0, 0}; - data.insert(data.end(), reinterpret_cast(header), - reinterpret_cast(header) + sizeof(header)); - data.insert(data.end(), reinterpret_cast(root), - reinterpret_cast(root) + sizeof(root)); - data.insert(data.end(), reinterpret_cast(child), - reinterpret_cast(child) + sizeof(child)); + const std::array header{ + {0x52544552, 9, 2, 112, 117, 0, 0, 0, 0, 0, 0, 0}}; + const std::array root{{0, 0, 1, 1, 0xFFFFFFFF, 0, 0, 0}}; + const std::array child{ + {0, 5, 0xFFFFFFFF, 0, 999, 0x00000001, 0, 0}}; + data.insert(data.end(), reinterpret_cast(header.data()), + reinterpret_cast(header.data()) + + (header.size() * sizeof(header[0]))); + data.insert(data.end(), reinterpret_cast(root.data()), + reinterpret_cast(root.data()) + + (root.size() * sizeof(root[0]))); + data.insert(data.end(), reinterpret_cast(child.data()), + reinterpret_cast(child.data()) + + (child.size() * sizeof(child[0]))); data.insert(data.end(), {'u', 's', 'e', 'r', 's'}); const sourcemeta::core::URITemplateRouterView view{data.data(), data.size()}; @@ -933,62 +956,69 @@ TEST(corrupt_deep_node_variable_child_oob) { } TEST(corrupt_expansion_string_oob) { - const std::uint32_t data[] = { - 0x52544552, 9, 2, 112, 112, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0xFFFFFFFF, 0, 1, 0, 0, 0, - 5000, 200, 0xFFFFFFFF, 0, 0xFFFFFFFF, 0x00000003, 0, 0}; + const std::array data{ + {0x52544552, 9, 2, 112, 112, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0xFFFFFFFF, 0, 1, 0, 0, 0, + 5000, 200, 0xFFFFFFFF, 0, 0xFFFFFFFF, 0x00000003, 0, 0}}; const sourcemeta::core::URITemplateRouterView view{ - reinterpret_cast(data), sizeof(data)}; + reinterpret_cast(data.data()), + (data.size() * sizeof(data[0]))}; EXPECT_ROUTER_MATCH(view, "/files/foo/bar", 0, 0, captures); EXPECT_EQ(captures.size(), 0); } TEST(corrupt_empty_string_table_with_string_ref) { - const std::uint32_t data[] = {0x52544552, 9, 2, 112, 112, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 1, - 0xFFFFFFFF, 0, 0, 0, 0, 10, 0xFFFFFFFF, 0, - 0xFFFFFFFF, 0, 0, 0}; + const std::array data{ + {0x52544552, 9, 2, 112, 112, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 0xFFFFFFFF, 0, 0, 0, + 0, 10, 0xFFFFFFFF, 0, 0xFFFFFFFF, 0, 0, 0}}; const sourcemeta::core::URITemplateRouterView view{ - reinterpret_cast(data), sizeof(data)}; + reinterpret_cast(data.data()), + (data.size() * sizeof(data[0]))}; EXPECT_ROUTER_MATCH(view, "/users", 0, 0, captures); EXPECT_EQ(captures.size(), 0); } TEST(corrupt_node_count_max_uint32) { - const std::uint32_t data[] = {0x52544552, 9, 0xFFFFFFFF, 48, 48, 0, - 0, 0, 0, 0, 0, 0}; + const std::array data{ + {0x52544552, 9, 0xFFFFFFFF, 48, 48, 0, 0, 0, 0, 0, 0, 0}}; const sourcemeta::core::URITemplateRouterView view{ - reinterpret_cast(data), sizeof(data)}; + reinterpret_cast(data.data()), + (data.size() * sizeof(data[0]))}; EXPECT_ROUTER_MATCH(view, "/users", 0, 0, captures); EXPECT_EQ(captures.size(), 0); } TEST(corrupt_string_offset_plus_length_overflow) { - const std::uint32_t data[] = { - 0x52544552, 9, 2, 112, 112, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0xFFFFFFFF, 0, 1, 0, 0, 0, 0x80000000, - 0x80000001, 0xFFFFFFFF, 0, 0xFFFFFFFF, 0x00000002, 0, 0}; + const std::array data{ + {0x52544552, 9, 2, 112, 112, 0, 0, + 0, 0, 0, 0, 0, 0, 0, + 0xFFFFFFFF, 0, 1, 0, 0, 0, 0x80000000, + 0x80000001, 0xFFFFFFFF, 0, 0xFFFFFFFF, 0x00000002, 0, 0}}; const sourcemeta::core::URITemplateRouterView view{ - reinterpret_cast(data), sizeof(data)}; + reinterpret_cast(data.data()), + (data.size() * sizeof(data[0]))}; EXPECT_ROUTER_MATCH(view, "/users", 0, 0, captures); EXPECT_EQ(captures.size(), 0); } TEST(corrupt_string_offset_plus_length_overflow_with_data) { std::vector data; - const std::uint32_t header[] = {0x52544552, 9, 2, 112, 113, 0, - 0, 0, 0, 0, 0, 0}; - const std::uint32_t root[] = {0, 0, 0xFFFFFFFF, 0, 1, 0, 0, 0}; - const std::uint32_t variable[] = {0xFFFFFFFF, 2, 0xFFFFFFFF, 0, - 0xFFFFFFFF, 0x00000002, 0, 0}; - data.insert(data.end(), reinterpret_cast(header), - reinterpret_cast(header) + sizeof(header)); - data.insert(data.end(), reinterpret_cast(root), - reinterpret_cast(root) + sizeof(root)); - data.insert(data.end(), reinterpret_cast(variable), - reinterpret_cast(variable) + - sizeof(variable)); + const std::array header{ + {0x52544552, 9, 2, 112, 113, 0, 0, 0, 0, 0, 0, 0}}; + const std::array root{{0, 0, 0xFFFFFFFF, 0, 1, 0, 0, 0}}; + const std::array variable{ + {0xFFFFFFFF, 2, 0xFFFFFFFF, 0, 0xFFFFFFFF, 0x00000002, 0, 0}}; + data.insert(data.end(), reinterpret_cast(header.data()), + reinterpret_cast(header.data()) + + (header.size() * sizeof(header[0]))); + data.insert(data.end(), reinterpret_cast(root.data()), + reinterpret_cast(root.data()) + + (root.size() * sizeof(root[0]))); + data.insert(data.end(), + reinterpret_cast(variable.data()), + reinterpret_cast(variable.data()) + + (variable.size() * sizeof(variable[0]))); data.push_back('x'); const sourcemeta::core::URITemplateRouterView view{data.data(), data.size()}; @@ -998,17 +1028,20 @@ TEST(corrupt_string_offset_plus_length_overflow_with_data) { TEST(corrupt_literal_string_offset_plus_length_overflow) { std::vector data; - const std::uint32_t header[] = {0x52544552, 9, 2, 112, 113, 0, - 0, 0, 0, 0, 0, 0}; - const std::uint32_t root[] = {0, 0, 1, 1, 0xFFFFFFFF, 0, 0, 0}; - const std::uint32_t child[] = {0xFFFFFFFF, 2, 0xFFFFFFFF, 0, - 0xFFFFFFFF, 0, 0, 0}; - data.insert(data.end(), reinterpret_cast(header), - reinterpret_cast(header) + sizeof(header)); - data.insert(data.end(), reinterpret_cast(root), - reinterpret_cast(root) + sizeof(root)); - data.insert(data.end(), reinterpret_cast(child), - reinterpret_cast(child) + sizeof(child)); + const std::array header{ + {0x52544552, 9, 2, 112, 113, 0, 0, 0, 0, 0, 0, 0}}; + const std::array root{{0, 0, 1, 1, 0xFFFFFFFF, 0, 0, 0}}; + const std::array child{ + {0xFFFFFFFF, 2, 0xFFFFFFFF, 0, 0xFFFFFFFF, 0, 0, 0}}; + data.insert(data.end(), reinterpret_cast(header.data()), + reinterpret_cast(header.data()) + + (header.size() * sizeof(header[0]))); + data.insert(data.end(), reinterpret_cast(root.data()), + reinterpret_cast(root.data()) + + (root.size() * sizeof(root[0]))); + data.insert(data.end(), reinterpret_cast(child.data()), + reinterpret_cast(child.data()) + + (child.size() * sizeof(child[0]))); data.push_back('x'); const sourcemeta::core::URITemplateRouterView view{data.data(), data.size()}; @@ -4078,8 +4111,10 @@ TEST_F(URITemplateRouterViewTest, view_of_a_missing_file_throws) { } TEST(corrupt_too_small_accessors_yield_defaults) { - const std::uint8_t data[] = {0xDE, 0xAD, 0xBE, 0xEF, 0x01, 0x02, 0x03}; - const sourcemeta::core::URITemplateRouterView view{data, sizeof(data)}; + const std::array data{ + {0xDE, 0xAD, 0xBE, 0xEF, 0x01, 0x02, 0x03}}; + const sourcemeta::core::URITemplateRouterView view{ + data.data(), (data.size() * sizeof(data[0]))}; EXPECT_EQ(view.size(), 0); EXPECT_TRUE(view.base_path().empty()); EXPECT_TRUE(view.base_url().empty()); @@ -4101,10 +4136,12 @@ TEST(corrupt_too_small_accessors_yield_defaults) { } TEST(corrupt_wrong_magic_accessors_yield_defaults) { - const std::uint32_t data[] = {0xDEADBEEF, 9, 1, 64, 64, 64, 0, 5, 0, 0, - 5, 64, 0, 0, 0, 0, 0, 0, 0, 0}; + const std::array data{{0xDEADBEEF, 9, 1, 64, 64, 64, 0, + 5, 0, 0, 5, 64, 0, 0, + 0, 0, 0, 0, 0, 0}}; const sourcemeta::core::URITemplateRouterView view{ - reinterpret_cast(data), sizeof(data)}; + reinterpret_cast(data.data()), + (data.size() * sizeof(data[0]))}; EXPECT_EQ(view.size(), 0); EXPECT_TRUE(view.base_path().empty()); EXPECT_TRUE(view.base_url().empty()); @@ -4126,10 +4163,12 @@ TEST(corrupt_wrong_magic_accessors_yield_defaults) { } TEST(corrupt_wrong_version_accessors_yield_defaults) { - const std::uint32_t data[] = {0x52544552, 99, 1, 64, 64, 64, 0, 5, 0, 0, - 5, 64, 0, 0, 0, 0, 0, 0, 0, 0}; + const std::array data{{0x52544552, 99, 1, 64, 64, 64, 0, + 5, 0, 0, 5, 64, 0, 0, + 0, 0, 0, 0, 0, 0}}; const sourcemeta::core::URITemplateRouterView view{ - reinterpret_cast(data), sizeof(data)}; + reinterpret_cast(data.data()), + (data.size() * sizeof(data[0]))}; EXPECT_EQ(view.size(), 0); EXPECT_TRUE(view.base_path().empty()); EXPECT_TRUE(view.base_url().empty()); @@ -4143,11 +4182,12 @@ TEST(corrupt_wrong_version_accessors_yield_defaults) { } TEST(corrupt_offsets_accessors_yield_defaults) { - const std::uint32_t data[] = {0x52544552, 9, 1, 99999, 99999, 99999, 0, - 5, 0, 0, 5, 99999, 0, 0, - 0, 0, 0, 0, 0, 0}; + const std::array data{ + {0x52544552, 9, 1, 99999, 99999, 99999, 0, 5, 0, 0, + 5, 99999, 0, 0, 0, 0, 0, 0, 0, 0}}; const sourcemeta::core::URITemplateRouterView view{ - reinterpret_cast(data), sizeof(data)}; + reinterpret_cast(data.data()), + (data.size() * sizeof(data[0]))}; EXPECT_TRUE(view.base_path().empty()); EXPECT_TRUE(view.base_url().empty()); EXPECT_EQ(view.at(0), 0); @@ -4168,50 +4208,55 @@ TEST(corrupt_offsets_accessors_yield_defaults) { } TEST(corrupt_zero_node_count_accessors_yield_defaults) { - const std::uint32_t data[] = {0x52544552, 9, 0, 48, 48, 48, - 0, 0, 0, 0, 0, 48}; + const std::array data{ + {0x52544552, 9, 0, 48, 48, 48, 0, 0, 0, 0, 0, 48}}; const sourcemeta::core::URITemplateRouterView view{ - reinterpret_cast(data), sizeof(data)}; + reinterpret_cast(data.data()), + (data.size() * sizeof(data[0]))}; EXPECT_EQ(view.size(), 0); EXPECT_EQ(view.at(0), 0); EXPECT_FALSE(view.describes("/users")); } TEST(corrupt_literal_child_out_of_bounds_describes_nothing) { - const std::uint32_t data[] = {0x52544552, 9, 1, 80, 80, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 999, 1, 0xFFFFFFFF, 0, 0, 0}; + const std::array data{{0x52544552, 9, 1, 80, 80, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 999, 1, + 0xFFFFFFFF, 0, 0, 0}}; const sourcemeta::core::URITemplateRouterView view{ - reinterpret_cast(data), sizeof(data)}; + reinterpret_cast(data.data()), + (data.size() * sizeof(data[0]))}; EXPECT_FALSE(view.describes("/users")); } TEST(corrupt_variable_child_out_of_bounds_describes_nothing) { - const std::uint32_t data[] = {0x52544552, 9, 1, 80, 80, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0xFFFFFFFF, 0, 500, 0, 0, 0}; + const std::array data{{0x52544552, 9, 1, 80, 80, 0, 0, + 0, 0, 0, 0, 0, 0, 0, + 0xFFFFFFFF, 0, 500, 0, 0, 0}}; const sourcemeta::core::URITemplateRouterView view{ - reinterpret_cast(data), sizeof(data)}; + reinterpret_cast(data.data()), + (data.size() * sizeof(data[0]))}; EXPECT_FALSE(view.describes("/users")); } TEST(corrupt_variable_string_offset_out_of_bounds_describes_nothing) { - const std::uint32_t data[] = { - 0x52544552, 9, 2, 112, 112, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0xFFFFFFFF, 0, 1, 0, 0, 0, - 9999, 100, 0xFFFFFFFF, 0, 0xFFFFFFFF, 0x00000002, 0, 0}; + const std::array data{ + {0x52544552, 9, 2, 112, 112, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0xFFFFFFFF, 0, 1, 0, 0, 0, + 9999, 100, 0xFFFFFFFF, 0, 0xFFFFFFFF, 0x00000002, 0, 0}}; const sourcemeta::core::URITemplateRouterView view{ - reinterpret_cast(data), sizeof(data)}; + reinterpret_cast(data.data()), + (data.size() * sizeof(data[0]))}; EXPECT_FALSE(view.describes("/users")); } TEST(corrupt_literal_string_offset_describes_nothing) { - const std::uint32_t data[] = {0x52544552, 9, 2, 112, 112, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 1, - 0xFFFFFFFF, 0, 0, 0, 9999, 5, 0xFFFFFFFF, 0, - 0xFFFFFFFF, 0, 0, 0}; + const std::array data{ + {0x52544552, 9, 2, 112, 112, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 0xFFFFFFFF, 0, 0, 0, + 9999, 5, 0xFFFFFFFF, 0, 0xFFFFFFFF, 0, 0, 0}}; const sourcemeta::core::URITemplateRouterView view{ - reinterpret_cast(data), sizeof(data)}; + reinterpret_cast(data.data()), + (data.size() * sizeof(data[0]))}; EXPECT_FALSE(view.describes("/users")); } @@ -4234,18 +4279,20 @@ TEST_F(URITemplateRouterViewTest, serialized_version_matches_corrupt_fixtures) { } TEST(corrupt_arguments_offset_before_string_table_describes_nothing) { - const std::uint32_t data[] = {0x52544552, 9, 1, 80, 4, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + const std::array data{ + {0x52544552, 9, 1, 80, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}; const sourcemeta::core::URITemplateRouterView view{ - reinterpret_cast(data), sizeof(data)}; + reinterpret_cast(data.data()), + (data.size() * sizeof(data[0]))}; EXPECT_FALSE(view.describes("/users")); } TEST(corrupt_match_arguments_offset_before_string_table) { - const std::uint32_t data[] = {0x52544552, 9, 1, 80, 4, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + const std::array data{ + {0x52544552, 9, 1, 80, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}; const sourcemeta::core::URITemplateRouterView view{ - reinterpret_cast(data), sizeof(data)}; + reinterpret_cast(data.data()), + (data.size() * sizeof(data[0]))}; EXPECT_ROUTER_MATCH(view, "/users", 0, 0, captures); EXPECT_EQ(captures.size(), 0); } @@ -4485,30 +4532,33 @@ TEST(corrupt_path_entry_string_out_of_bounds) { } TEST(corrupt_base_path_outside_string_table) { - const std::uint32_t data[] = {0x52544552, 9, 1, 80, 80, 0, 999, - 5, 0, 0, 0, 0, 0, 0, - 0xFFFFFFFF, 0, 0xFFFFFFFF, 0, 0, 0}; + const std::array data{ + {0x52544552, 9, 1, 80, 80, 0, 999, 5, 0, 0, + 0, 0, 0, 0, 0xFFFFFFFF, 0, 0xFFFFFFFF, 0, 0, 0}}; const sourcemeta::core::URITemplateRouterView view{ - reinterpret_cast(data), sizeof(data)}; + reinterpret_cast(data.data()), + (data.size() * sizeof(data[0]))}; EXPECT_TRUE(view.base_path().empty()); } TEST(corrupt_base_url_outside_string_table) { - const std::uint32_t data[] = {0x52544552, 9, 1, 80, 80, 0, 0, - 0, 0, 999, 5, 0, 0, 0, - 0xFFFFFFFF, 0, 0xFFFFFFFF, 0, 0, 0}; + const std::array data{ + {0x52544552, 9, 1, 80, 80, 0, 0, 0, 0, 999, + 5, 0, 0, 0, 0xFFFFFFFF, 0, 0xFFFFFFFF, 0, 0, 0}}; const sourcemeta::core::URITemplateRouterView view{ - reinterpret_cast(data), sizeof(data)}; + reinterpret_cast(data.data()), + (data.size() * sizeof(data[0]))}; EXPECT_TRUE(view.base_url().empty()); } TEST(corrupt_string_table_with_valid_operation_and_path_tables) { - const std::uint32_t words[] = { - 0x52544552, 9, 1, 99999, 99999, 0x50, 0, 0, 0, 0, - 0, 0, 0, 0, 0xFFFFFFFF, 0, 0xFFFFFFFF, 0, 0, 0}; + const std::array words{ + {0x52544552, 9, 1, 99999, 99999, 0x50, 0, 0, 0, 0, + 0, 0, 0, 0, 0xFFFFFFFF, 0, 0xFFFFFFFF, 0, 0, 0}}; std::vector bytes{ - reinterpret_cast(words), - reinterpret_cast(words) + sizeof(words)}; + reinterpret_cast(words.data()), + reinterpret_cast(words.data()) + + (words.size() * sizeof(words[0]))}; const std::uint32_t paths_offset{static_cast(bytes.size())}; std::memcpy(bytes.data() + 44, &paths_offset, sizeof(paths_offset)); bytes.insert(bytes.end(), {0x01, 0x00}); diff --git a/test/uritemplate/uritemplate_suite.cc b/test/uritemplate/uritemplate_suite.cc index cc6690c1c7..662ec3e38c 100644 --- a/test/uritemplate/uritemplate_suite.cc +++ b/test/uritemplate/uritemplate_suite.cc @@ -145,7 +145,9 @@ auto register_tests(const sourcemeta::core::JSON &document, std::ostringstream test_name; test_name << prefix << "_"; for (const auto character : entry.first) { - test_name << (std::isalnum(character) ? character : '_'); + test_name << ((std::isalnum(static_cast(character)) != 0) + ? character + : '_'); } test_name << "_testcase_" << index; diff --git a/test/uritemplate/uritemplate_test.cc b/test/uritemplate/uritemplate_test.cc index 0035a9f116..510879dde5 100644 --- a/test/uritemplate/uritemplate_test.cc +++ b/test/uritemplate/uritemplate_test.cc @@ -51,6 +51,7 @@ TEST(iterator) { TEST(copy_constructor) { const sourcemeta::core::URITemplate original{"http://example.com/{id}"}; + // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) const sourcemeta::core::URITemplate copy{original}; EXPECT_EQ(copy.size(), 2); diff --git a/test/yaml/yaml_parse_callback_test.cc b/test/yaml/yaml_parse_callback_test.cc index eea8dcf658..4b28c09012 100644 --- a/test/yaml/yaml_parse_callback_test.cc +++ b/test/yaml/yaml_parse_callback_test.cc @@ -61,56 +61,56 @@ EXPECT_EQ(std::get<6>(traces.at(index)), expected_property) TEST(yaml_true) { - const auto input{"true"}; + const auto *const input{"true"}; PARSE_YAML_WITH_TRACES(document, input, 2); EXPECT_TRACE(0, Pre, Boolean, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Post, Boolean, 1, 4, Root, 0, ""); } TEST(yaml_false) { - const auto input{"false"}; + const auto *const input{"false"}; PARSE_YAML_WITH_TRACES(document, input, 2); EXPECT_TRACE(0, Pre, Boolean, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Post, Boolean, 1, 5, Root, 0, ""); } TEST(yaml_null) { - const auto input{"null"}; + const auto *const input{"null"}; PARSE_YAML_WITH_TRACES(document, input, 2); EXPECT_TRACE(0, Pre, Null, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Post, Null, 1, 4, Root, 0, ""); } TEST(yaml_string) { - const auto input{"\"foo\""}; + const auto *const input{"\"foo\""}; PARSE_YAML_WITH_TRACES(document, input, 2); EXPECT_TRACE(0, Pre, String, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Post, String, 1, 5, Root, 0, ""); } TEST(yaml_integer) { - const auto input{"1234"}; + const auto *const input{"1234"}; PARSE_YAML_WITH_TRACES(document, input, 2); EXPECT_TRACE(0, Pre, Integer, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Post, Integer, 1, 4, Root, 0, ""); } TEST(yaml_real) { - const auto input{"3.5"}; + const auto *const input{"3.5"}; PARSE_YAML_WITH_TRACES(document, input, 2); EXPECT_TRACE(0, Pre, Real, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Post, Real, 1, 3, Root, 0, ""); } TEST(yaml_empty_array) { - const auto input{"[]"}; + const auto *const input{"[]"}; PARSE_YAML_WITH_TRACES(document, input, 2); EXPECT_TRACE(0, Pre, Array, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Post, Array, 1, 2, Root, 0, ""); } TEST(yaml_array_integers) { - const auto input{"[1, 2, 3]"}; + const auto *const input{"[1, 2, 3]"}; PARSE_YAML_WITH_TRACES(document, input, 8); EXPECT_TRACE(0, Pre, Array, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Pre, Integer, 1, 2, Index, 0, ""); @@ -123,14 +123,14 @@ TEST(yaml_array_integers) { } TEST(yaml_empty_object) { - const auto input{"{}"}; + const auto *const input{"{}"}; PARSE_YAML_WITH_TRACES(document, input, 2); EXPECT_TRACE(0, Pre, Object, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Post, Object, 1, 2, Root, 0, ""); } TEST(yaml_object_simple) { - const auto input{"{\"foo\": \"bar\"}"}; + const auto *const input{R"({"foo": "bar"})"}; PARSE_YAML_WITH_TRACES(document, input, 4); EXPECT_TRACE(0, Pre, Object, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Pre, String, 1, 2, Property, 0, "foo"); @@ -139,7 +139,7 @@ TEST(yaml_object_simple) { } TEST(yaml_block_mapping_multiline) { - const auto input{"foo: bar\nbaz: qux\ntest: 123"}; + const auto *const input{"foo: bar\nbaz: qux\ntest: 123"}; PARSE_YAML_WITH_TRACES(document, input, 8); EXPECT_TRACE(0, Pre, Object, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Pre, String, 1, 1, Property, 0, "foo"); @@ -152,7 +152,7 @@ TEST(yaml_block_mapping_multiline) { } TEST(yaml_block_sequence_multiline) { - const auto input{"- foo\n- bar\n- baz"}; + const auto *const input{"- foo\n- bar\n- baz"}; PARSE_YAML_WITH_TRACES(document, input, 8); EXPECT_TRACE(0, Pre, Array, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Pre, String, 1, 3, Index, 0, ""); @@ -165,7 +165,7 @@ TEST(yaml_block_sequence_multiline) { } TEST(yaml_nested_arrays) { - const auto input{"[[1, 2], [3, 4]]"}; + const auto *const input{"[[1, 2], [3, 4]]"}; PARSE_YAML_WITH_TRACES(document, input, 14); EXPECT_TRACE(0, Pre, Array, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Pre, Array, 1, 2, Index, 0, ""); @@ -184,7 +184,7 @@ TEST(yaml_nested_arrays) { } TEST(yaml_nested_objects) { - const auto input{"{\"outer\": {\"inner\": \"value\"}}"}; + const auto *const input{R"({"outer": {"inner": "value"}})"}; PARSE_YAML_WITH_TRACES(document, input, 6); EXPECT_TRACE(0, Pre, Object, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Pre, Object, 1, 2, Property, 0, "outer"); @@ -195,7 +195,7 @@ TEST(yaml_nested_objects) { } TEST(yaml_block_nested_objects) { - const auto input{"outer:\n inner:\n deep: value"}; + const auto *const input{"outer:\n inner:\n deep: value"}; PARSE_YAML_WITH_TRACES(document, input, 8); EXPECT_TRACE(0, Pre, Object, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Pre, Object, 1, 1, Property, 0, "outer"); @@ -208,7 +208,7 @@ TEST(yaml_block_nested_objects) { } TEST(yaml_block_nested_arrays) { - const auto input{"- - foo\n - bar\n- - baz"}; + const auto *const input{"- - foo\n - bar\n- - baz"}; PARSE_YAML_WITH_TRACES(document, input, 12); EXPECT_TRACE(0, Pre, Array, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Pre, Array, 1, 3, Index, 0, ""); @@ -225,7 +225,7 @@ TEST(yaml_block_nested_arrays) { } TEST(yaml_mixed_block_and_flow) { - const auto input{"array:\n - {key: value}\n - [1, 2, 3]"}; + const auto *const input{"array:\n - {key: value}\n - [1, 2, 3]"}; PARSE_YAML_WITH_TRACES(document, input, 16); EXPECT_TRACE(0, Pre, Object, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Pre, Array, 1, 1, Property, 0, "array"); @@ -246,7 +246,7 @@ TEST(yaml_mixed_block_and_flow) { } TEST(yaml_quoted_strings) { - const auto input{"single: 'foo bar'\ndouble: \"baz qux\""}; + const auto *const input{"single: 'foo bar'\ndouble: \"baz qux\""}; PARSE_YAML_WITH_TRACES(document, input, 6); EXPECT_TRACE(0, Pre, Object, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Pre, String, 1, 1, Property, 0, "single"); @@ -257,7 +257,7 @@ TEST(yaml_quoted_strings) { } TEST(yaml_unquoted_strings) { - const auto input{"plain: hello world\nunquoted: test"}; + const auto *const input{"plain: hello world\nunquoted: test"}; PARSE_YAML_WITH_TRACES(document, input, 6); EXPECT_TRACE(0, Pre, Object, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Pre, String, 1, 1, Property, 0, "plain"); @@ -268,7 +268,8 @@ TEST(yaml_unquoted_strings) { } TEST(yaml_numbers_various_formats) { - const auto input{"decimal: 42\nfloat: 3.5\nnegative: -10\nexponential: 1e10"}; + const auto *const input{ + "decimal: 42\nfloat: 3.5\nnegative: -10\nexponential: 1e10"}; PARSE_YAML_WITH_TRACES(document, input, 10); EXPECT_TRACE(0, Pre, Object, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Pre, Integer, 1, 1, Property, 0, "decimal"); @@ -283,7 +284,7 @@ TEST(yaml_numbers_various_formats) { } TEST(yaml_booleans_all_forms) { - const auto input{"bool_true: true\nbool_false: false"}; + const auto *const input{"bool_true: true\nbool_false: false"}; PARSE_YAML_WITH_TRACES(document, input, 6); EXPECT_TRACE(0, Pre, Object, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Pre, Boolean, 1, 1, Property, 0, "bool_true"); @@ -294,7 +295,7 @@ TEST(yaml_booleans_all_forms) { } TEST(yaml_null_values) { - const auto input{"explicit_null: null\n"}; + const auto *const input{"explicit_null: null\n"}; PARSE_YAML_WITH_TRACES(document, input, 4); EXPECT_TRACE(0, Pre, Object, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Pre, Null, 1, 1, Property, 0, "explicit_null"); @@ -303,7 +304,7 @@ TEST(yaml_null_values) { } TEST(yaml_empty_values) { - const auto input{"empty_key:"}; + const auto *const input{"empty_key:"}; PARSE_YAML_WITH_TRACES(document, input, 4); EXPECT_TRACE(0, Pre, Object, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Pre, Null, 1, 1, Property, 0, "empty_key"); @@ -312,7 +313,7 @@ TEST(yaml_empty_values) { } TEST(yaml_simple_multiline_object) { - const auto input{"name: Alice\nage: 30"}; + const auto *const input{"name: Alice\nage: 30"}; PARSE_YAML_WITH_TRACES(document, input, 6); EXPECT_TRACE(0, Pre, Object, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Pre, String, 1, 1, Property, 0, "name"); @@ -323,7 +324,7 @@ TEST(yaml_simple_multiline_object) { } TEST(yaml_array_of_objects) { - const auto input{"[\n {id: 1, name: foo},\n {id: 2, name: bar}\n]"}; + const auto *const input{"[\n {id: 1, name: foo},\n {id: 2, name: bar}\n]"}; PARSE_YAML_WITH_TRACES(document, input, 14); EXPECT_TRACE(0, Pre, Array, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Pre, Object, 2, 3, Index, 0, ""); @@ -342,7 +343,7 @@ TEST(yaml_array_of_objects) { } TEST(yaml_deeply_nested) { - const auto input{"{a: {b: {c: {d: {e: 42}}}}}"}; + const auto *const input{"{a: {b: {c: {d: {e: 42}}}}}"}; PARSE_YAML_WITH_TRACES(document, input, 12); EXPECT_TRACE(0, Pre, Object, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Pre, Object, 1, 2, Property, 0, "a"); @@ -381,7 +382,7 @@ TEST(yaml_or_json_stub_test_2) { } TEST(yaml_simple_anchor_and_alias) { - const auto input{"anchor: &node foo\nalias: *node"}; + const auto *const input{"anchor: &node foo\nalias: *node"}; PARSE_YAML_WITH_TRACES(document, input, 6); EXPECT_TRACE(0, Pre, Object, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Pre, String, 1, 1, Property, 0, "anchor"); @@ -392,7 +393,7 @@ TEST(yaml_simple_anchor_and_alias) { } TEST(yaml_anchor_object_with_alias) { - const auto input{"original: &obj {x: 1, y: 2}\ncopy: *obj"}; + const auto *const input{"original: &obj {x: 1, y: 2}\ncopy: *obj"}; PARSE_YAML_WITH_TRACES(document, input, 14); EXPECT_TRACE(0, Pre, Object, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Pre, Object, 1, 1, Property, 0, "original"); @@ -411,7 +412,8 @@ TEST(yaml_anchor_object_with_alias) { } TEST(yaml_anchor_array_with_multiple_aliases) { - const auto input{"items: &list [a, b, c]\nfirst: *list\nsecond: *list"}; + const auto *const input{ + "items: &list [a, b, c]\nfirst: *list\nsecond: *list"}; PARSE_YAML_WITH_TRACES(document, input, 26); EXPECT_TRACE(0, Pre, Object, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Pre, Array, 1, 1, Property, 0, "items"); @@ -442,7 +444,7 @@ TEST(yaml_anchor_array_with_multiple_aliases) { } TEST(yaml_nested_anchor_and_alias) { - const auto input{"outer:\n inner: &val 42\n ref: *val"}; + const auto *const input{"outer:\n inner: &val 42\n ref: *val"}; PARSE_YAML_WITH_TRACES(document, input, 8); EXPECT_TRACE(0, Pre, Object, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Pre, Object, 1, 1, Property, 0, "outer"); @@ -455,21 +457,21 @@ TEST(yaml_nested_anchor_and_alias) { } TEST(decimal_large_integer) { - const auto input{"123456789012345678901234567890"}; + const auto *const input{"123456789012345678901234567890"}; PARSE_YAML_WITH_TRACES(document, input, 2); EXPECT_TRACE(0, Pre, Decimal, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Post, Decimal, 1, 30, Root, 0, ""); } TEST(decimal_high_precision_real) { - const auto input{"3.141592653589793238462643383279"}; + const auto *const input{"3.141592653589793238462643383279"}; PARSE_YAML_WITH_TRACES(document, input, 2); EXPECT_TRACE(0, Pre, Decimal, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Post, Decimal, 1, 32, Root, 0, ""); } TEST(decimal_in_object) { - const auto input{"large: 999999999999999999999999999999"}; + const auto *const input{"large: 999999999999999999999999999999"}; PARSE_YAML_WITH_TRACES(document, input, 4); EXPECT_TRACE(0, Pre, Object, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Pre, Decimal, 1, 1, Property, 0, "large"); @@ -478,7 +480,7 @@ TEST(decimal_in_object) { } TEST(scalar_alias_pre_post_balance) { - const auto input{"anchor: &node foo\nalias: *node"}; + const auto *const input{"anchor: &node foo\nalias: *node"}; PARSE_YAML_WITH_TRACES(document, input, 6); EXPECT_TRACE(0, Pre, Object, 1, 1, Root, 0, ""); EXPECT_TRACE(1, Pre, String, 1, 1, Property, 0, "anchor"); diff --git a/test/yaml/yaml_parse_test.cc b/test/yaml/yaml_parse_test.cc index 02a56e0a22..e0821aab96 100644 --- a/test/yaml/yaml_parse_test.cc +++ b/test/yaml/yaml_parse_test.cc @@ -715,7 +715,7 @@ TEST(plain_scalar_triple_dot_value) { } TEST(invalid_hex_escape) { - const std::string input{"\"\\xGG\""}; + const std::string input{R"("\xGG")"}; try { sourcemeta::core::parse_yaml(input); FAIL(); @@ -727,7 +727,7 @@ TEST(invalid_hex_escape) { } TEST(invalid_unicode_escape_4) { - const std::string input{"\"\\uZZZZ\""}; + const std::string input{R"("\uZZZZ")"}; try { sourcemeta::core::parse_yaml(input); FAIL(); @@ -739,7 +739,7 @@ TEST(invalid_unicode_escape_4) { } TEST(invalid_unicode_escape_8) { - const std::string input{"\"\\UZZZZZZZZ\""}; + const std::string input{R"("\UZZZZZZZZ")"}; try { sourcemeta::core::parse_yaml(input); FAIL(); @@ -751,14 +751,14 @@ TEST(invalid_unicode_escape_8) { } TEST(valid_bmp_unicode_escape) { - const std::string input{"\"\\u00e9\""}; + const std::string input{R"("\u00e9")"}; const auto result{sourcemeta::core::parse_yaml(input)}; const sourcemeta::core::JSON expected{"\xC3\xA9"}; EXPECT_EQ(result, expected); } TEST(valid_astral_unicode_escape) { - const std::string input{"\"\\U0001F600\""}; + const std::string input{R"("\U0001F600")"}; const auto result{sourcemeta::core::parse_yaml(input)}; const sourcemeta::core::JSON expected{"\xF0\x9F\x98\x80"}; EXPECT_EQ(result, expected); @@ -766,7 +766,7 @@ TEST(valid_astral_unicode_escape) { TEST(surrogate_unicode_escape_is_rejected) { // YAML 1.2.2 Section 5.7: a lone surrogate is not a Unicode scalar value - const std::string input{"\"\\uD800\""}; + const std::string input{R"("\uD800")"}; try { sourcemeta::core::parse_yaml(input); FAIL(); @@ -778,7 +778,7 @@ TEST(surrogate_unicode_escape_is_rejected) { } TEST(out_of_range_unicode_escape_is_rejected) { - const std::string input{"\"\\UFFFFFFFF\""}; + const std::string input{R"("\UFFFFFFFF")"}; try { sourcemeta::core::parse_yaml(input); FAIL(); @@ -1241,7 +1241,8 @@ TEST(tab_after_spaces_flow_scalar_continuation_is_rejected) { sourcemeta::core::parse_yaml(input); FAIL(); } catch (const sourcemeta::core::YAMLParseError &) { - // Expected: the continuation reaches only the block indentation with spaces + // The continuation reaching only the block indentation with spaces is + // expected } catch (...) { FAIL(); } @@ -1952,35 +1953,35 @@ TEST(alias_quoted_keyword_key_is_preserved) { } TEST(escape_vertical_tab) { - const std::string input{"\"\\v\""}; + const std::string input{R"("\v")"}; const auto result{sourcemeta::core::parse_yaml(input)}; EXPECT_TRUE(result.is_string()); EXPECT_EQ(result.to_string(), std::string("\x0b", 1)); } TEST(escape_form_feed) { - const std::string input{"\"\\f\""}; + const std::string input{R"("\f")"}; const auto result{sourcemeta::core::parse_yaml(input)}; EXPECT_TRUE(result.is_string()); EXPECT_EQ(result.to_string(), std::string("\x0c", 1)); } TEST(escape_line_separator) { - const std::string input{"\"\\L\""}; + const std::string input{R"("\L")"}; const auto result{sourcemeta::core::parse_yaml(input)}; EXPECT_TRUE(result.is_string()); EXPECT_EQ(result.to_string(), std::string("\xe2\x80\xa8", 3)); } TEST(escape_paragraph_separator) { - const std::string input{"\"\\P\""}; + const std::string input{R"("\P")"}; const auto result{sourcemeta::core::parse_yaml(input)}; EXPECT_TRUE(result.is_string()); EXPECT_EQ(result.to_string(), std::string("\xe2\x80\xa9", 3)); } TEST(escape_incomplete_hex) { - const std::string input{"\"\\xZ\""}; + const std::string input{R"("\xZ")"}; try { const auto result{sourcemeta::core::parse_yaml(input)}; FAIL(); diff --git a/test/yaml/yamltestsuite.cc b/test/yaml/yamltestsuite.cc index 3fa5c1b82d..375e2a1afb 100644 --- a/test/yaml/yamltestsuite.cc +++ b/test/yaml/yamltestsuite.cc @@ -3,13 +3,14 @@ #include #include // std::min +#include // std::uint8_t #include // std::filesystem #include // std::ifstream #include // std::string #include // std::vector namespace { -enum class YAMLTestType { Success, Error }; +enum class YAMLTestType : std::uint8_t { Success, Error }; auto run_yaml_test_case(const std::filesystem::path &test_directory, const YAMLTestType type) -> void { @@ -88,7 +89,7 @@ auto main(int argc, char **argv) -> int { continue; } - const auto test_directory{entry.path()}; + const auto &test_directory{entry.path()}; const auto test_name{test_directory.filename().string()}; // A suite entry either holds the case files directly or, for the