From ba1e88797c94a5692f090d07325aeb8479557dd2 Mon Sep 17 00:00:00 2001 From: "Matthew \"strager\" Glazar" Date: Fri, 21 Jul 2023 21:42:31 -0700 Subject: [PATCH] feat(test): support String8_View values in ""_diag --- test/diag-matcher.cpp | 18 +++++++ test/diagnostic-assertion.cpp | 11 ++++ test/quick-lint-js/diag-matcher.h | 6 +++ test/quick-lint-js/diagnostic-assertion.h | 3 ++ test/test-diagnostic-assertion.cpp | 60 +++++++++++++++++++++ test/test-lex.cpp | 66 ++++++----------------- 6 files changed, 114 insertions(+), 50 deletions(-) diff --git a/test/diag-matcher.cpp b/test/diag-matcher.cpp index 9549031a41..0212b61d73 100644 --- a/test/diag-matcher.cpp +++ b/test/diag-matcher.cpp @@ -179,6 +179,14 @@ Char8 Diag_Matcher_Arg::get_char8(const void *error_object) const noexcept { return *static_cast(member_data); } +String8_View Diag_Matcher_Arg::get_string8_view(const void *error_object) const + noexcept { + QLJS_ASSERT(this->member_type == Diagnostic_Arg_Type::string8_view); + const void *member_data = + reinterpret_cast(error_object) + this->member_offset; + return *static_cast(member_data); +} + template class Diag_Fields_Matcher_Impl_Base : public testing::MatcherInterface { @@ -320,6 +328,16 @@ class Diag_Matcher_2::Impl return character_matches; } + case Diagnostic_Arg_Type::string8_view: { + String8_View string = f.arg.get_string8_view(error.data()); + bool character_matches = string == f.string; + *listener << "whose ." << f.arg.member_name << " (\"" + << to_string_view(string) << "\") " + << (character_matches ? "equals" : "doesn't equal") << " \"" + << to_string_view(f.string) << "\""; + return character_matches; + } + default: QLJS_ASSERT(false); return false; diff --git a/test/diagnostic-assertion.cpp b/test/diagnostic-assertion.cpp index 9b6267e1a3..4a4a1fb328 100644 --- a/test/diagnostic-assertion.cpp +++ b/test/diagnostic-assertion.cpp @@ -192,6 +192,14 @@ Diagnostic_Assertion::parse(const Char8* specification) { out_assertion.members[1].type = extra_member->type; out_assertion.members[1].character = extra_member_value_span[0]; break; + + case Diagnostic_Arg_Type::string8_view: + out_assertion.members[1].name = extra_member->name; + out_assertion.members[1].offset = extra_member->offset; + out_assertion.members[1].type = extra_member->type; + out_assertion.members[1].string = extra_member_value_span; + break; + default: errors.push_back(concat("member {."sv, to_string_view(extra_member_span), "} has unsupported type"sv)); @@ -337,6 +345,9 @@ diagnostics_matcher(Padded_String_View code, case Diagnostic_Arg_Type::char8: field.character = member.character; break; + case Diagnostic_Arg_Type::string8_view: + field.string = member.string; + break; default: QLJS_ASSERT(false); break; diff --git a/test/quick-lint-js/diag-matcher.h b/test/quick-lint-js/diag-matcher.h index 64128133d7..49e8f3b858 100644 --- a/test/quick-lint-js/diag-matcher.h +++ b/test/quick-lint-js/diag-matcher.h @@ -203,6 +203,9 @@ struct Diag_Matcher_Arg { // Precondition: this->member_type == Diagnostic_Arg_Type::char8 Char8 get_char8(const void *error_object) const noexcept; + + // Precondition: this->member_type == Diagnostic_Arg_Type::string8_view + String8_View get_string8_view(const void *error_object) const noexcept; }; // Create a Diag_Matcher_Arg from a Diag_ struct type and the name of a member @@ -274,6 +277,9 @@ class Diag_Matcher_2 { // If this->arg.member_type == Diag_Matcher_Arg::char8: Char8 character; + + // If this->arg.member_type == Diag_Matcher_Arg::string8_view: + String8_View string; }; explicit Diag_Matcher_2(Padded_String_View input, Diag_Type type, diff --git a/test/quick-lint-js/diagnostic-assertion.h b/test/quick-lint-js/diagnostic-assertion.h index d458ba246d..483919a918 100644 --- a/test/quick-lint-js/diagnostic-assertion.h +++ b/test/quick-lint-js/diagnostic-assertion.h @@ -87,6 +87,9 @@ struct Diagnostic_Assertion { // If type == Diagnostic_Arg_Type::char8: Char8 character; + + // If type == Diagnostic_Arg_Type::string8_view: + String8_View string; }; Diag_Type type = Diag_Type(); diff --git a/test/test-diagnostic-assertion.cpp b/test/test-diagnostic-assertion.cpp index 170c5675dd..84ca80bc73 100644 --- a/test/test-diagnostic-assertion.cpp +++ b/test/test-diagnostic-assertion.cpp @@ -209,6 +209,29 @@ TEST(Test_Diagnostic_Assertion, diag_type_with_char8_member_explicit) { } } +TEST(Test_Diagnostic_Assertion, diag_type_with_string8_view_member_explicit) { + { + Diagnostic_Assertion da = parse_or_fail( + u8"^ " + u8"Diag_Integer_Literal_Will_Lose_Precision.characters{.rounded_val=" + u8"hello}"); + ASSERT_EQ(da.member_count(), 2); + + EXPECT_STREQ(da.members[0].name, "characters"); + EXPECT_EQ(da.members[0].type, Diagnostic_Arg_Type::source_code_span); + EXPECT_EQ(da.members[0].offset, + offsetof(Diag_Integer_Literal_Will_Lose_Precision, characters)); + EXPECT_EQ(da.members[0].span_begin_offset, 0); + EXPECT_EQ(da.members[0].span_end_offset, 1); + + EXPECT_STREQ(da.members[1].name, "rounded_val"); + EXPECT_EQ(da.members[1].type, Diagnostic_Arg_Type::string8_view); + EXPECT_EQ(da.members[1].offset, + offsetof(Diag_Integer_Literal_Will_Lose_Precision, rounded_val)); + EXPECT_EQ(da.members[1].string, u8"hello"_sv); + } +} + TEST(Test_Diagnostic_Assertion, adjust_with_no_escaped_characters) { Diagnostic_Assertion da = parse_or_fail(u8" ^^ Diag_Unexpected_Token"); da = da.adjusted_for_escaped_characters(u8"abcdef"_sv); @@ -523,6 +546,43 @@ TEST(Test_Diagnostic_Assertion, char8_message) { "whose .token ('(') doesn't equal ')'"); } +TEST(Test_Diagnostic_Assertion, match_span_and_string8_view) { + Padded_String code(u8"hi"_sv); + + ::testing::Matcher matcher = diagnostics_matcher( + &code, + {u8"^ Diag_Integer_Literal_Will_Lose_Precision.characters{.rounded_val=hello}"_diag}); + EXPECT_TRUE(matcher.Matches({ + Diag_Collector::Diag(Diag_Integer_Literal_Will_Lose_Precision{ + .characters = Source_Code_Span(&code[0], &code[1]), + .rounded_val = u8"hello"_sv, + }), + })); + EXPECT_FALSE(matcher.Matches({ + Diag_Collector::Diag(Diag_Integer_Literal_Will_Lose_Precision{ + .characters = Source_Code_Span(&code[0], &code[1]), + .rounded_val = u8"HELLO"_sv, + }), + })); +} + +TEST(Test_Diagnostic_Assertion, string8_view_message) { + Padded_String code(u8"hi"_sv); + + ::testing::Matcher matcher = diagnostics_matcher( + &code, + {u8"^ Diag_Integer_Literal_Will_Lose_Precision.characters{.rounded_val=hello}"_diag}); + + Diag_Collector::Diag value(Diag_Integer_Literal_Will_Lose_Precision{ + .characters = Source_Code_Span(&code[0], &code[1]), + .rounded_val = u8"HELLO"_sv, + }); + EXPECT_EQ( + get_matcher_message(matcher, {value}), + "whose element #0 doesn't match, whose .characters (0-1) equals 0-1 and " + "whose .rounded_val (\"HELLO\") doesn't equal \"hello\""); +} + TEST(Test_Diagnostic_Assertion, multiple_diagnostics_are_matched_in_any_order) { Padded_String code(u8"hello"_sv); diff --git a/test/test-lex.cpp b/test/test-lex.cpp index 475ac6f867..b1e6ff8e05 100644 --- a/test/test-lex.cpp +++ b/test/test-lex.cpp @@ -361,18 +361,10 @@ TEST_F(Test_Lex, lex_binary_numbers) { TEST_F(Test_Lex, fail_lex_integer_loses_precision) { this->check_tokens_with_errors( - u8"9007199254740993"_sv, {Token_Type::number}, - [](Padded_String_View input, const auto& errors) { - EXPECT_THAT( - errors, - ElementsAreArray({ - DIAG_TYPE_2_FIELDS( - Diag_Integer_Literal_Will_Lose_Precision, // - characters, - Offsets_Matcher(input, 0, u8"9007199254740993"_sv), // - rounded_val, u8"9007199254740992"_sv), - })); - }); + u8"9007199254740993"_sv, + u8"^^^^^^^^^^^^^^^^ Diag_Integer_Literal_Will_Lose_Precision.characters"_diag + u8"{.rounded_val=9007199254740992}"_diag, + {Token_Type::number}); this->check_tokens(u8"999999999999999"_sv, {Token_Type::number}); this->check_tokens( u8"179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368"_sv, @@ -391,46 +383,20 @@ TEST_F(Test_Lex, fail_lex_integer_loses_precision) { })); }); this->check_tokens_with_errors( - u8"179769313486231580000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"_sv, - {Token_Type::number}, [](Padded_String_View input, const auto& errors) { - EXPECT_THAT( - errors, - ElementsAreArray({ - DIAG_TYPE_2_FIELDS( - Diag_Integer_Literal_Will_Lose_Precision, // - characters, - Offsets_Matcher(input, 0, - 309), // - rounded_val, - u8"179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368"_sv), - })); - }); + u8"179769313486231580000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"_sv, // + u8"^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Diag_Integer_Literal_Will_Lose_Precision.characters"_diag + u8"{.rounded_val=179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368}"_diag, + {Token_Type::number}); this->check_tokens_with_errors( - u8"179769313486231589999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"_sv, - {Token_Type::number}, [](Padded_String_View input, const auto& errors) { - EXPECT_THAT( - errors, - ElementsAreArray({ - DIAG_TYPE_2_FIELDS(Diag_Integer_Literal_Will_Lose_Precision, // - characters, - Offsets_Matcher(input, 0, - 309), // - rounded_val, u8"inf"_sv), - })); - }); + u8"179769313486231589999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"_sv, // + u8"^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Diag_Integer_Literal_Will_Lose_Precision.characters"_diag + u8"{.rounded_val=inf}"_diag, + {Token_Type::number}); this->check_tokens_with_errors( - u8"18014398509481986"_sv, {Token_Type::number}, - [](Padded_String_View input, const auto& errors) { - EXPECT_THAT( - errors, - ElementsAreArray({ - DIAG_TYPE_2_FIELDS( - Diag_Integer_Literal_Will_Lose_Precision, // - characters, - Offsets_Matcher(input, 0, u8"18014398509481986"_sv), // - rounded_val, u8"18014398509481984"_sv), - })); - }); + u8"18014398509481986"_sv, // + u8"^^^^^^^^^^^^^^^^^ Diag_Integer_Literal_Will_Lose_Precision.characters"_diag + u8"{.rounded_val=18014398509481984}"_diag, + {Token_Type::number}); } TEST_F(Test_Lex, fail_lex_binary_number_no_digits) {