1919#include < gmock/gmock.h>
2020#include " absl/log/absl_check.h"
2121#include " absl/strings/escaping.h"
22+ #include " absl/strings/match.h"
2223#include " absl/strings/str_cat.h"
2324#include " absl/types/span.h"
2425#include " google/protobuf/compiler/command_line_interface_tester.h"
@@ -4022,6 +4023,20 @@ TEST_F(CommandLineInterfaceTest,
40224023 " extendee message foo.Foo" );
40234024}
40244025
4026+ TEST_F (CommandLineInterfaceTest, WarningForReservedNameNotIdentifier) {
4027+ CreateTempFile (" foo.proto" , R"schema(
4028+ syntax = "proto2";
4029+ package foo;
4030+ message Foo {
4031+ reserved "not ident";
4032+ })schema" );
4033+
4034+ Run (" protocol_compiler --test_out=$tmpdir --proto_path=$tmpdir foo.proto" );
4035+ ExpectNoErrors ();
4036+ ExpectWarningSubstring (
4037+ " Reserved name \" not ident\" is not a valid identifier." );
4038+ }
4039+
40254040TEST_F (CommandLineInterfaceTest,
40264041 ExtensionDeclarationVerificationDeclarationUndeclaredError) {
40274042 CreateTempFile (" foo.proto" , R"schema(
@@ -4236,6 +4251,19 @@ class EncodeDecodeTest : public testing::TestWithParam<EncodeDecodeTestMode> {
42364251 captured_stdout_ = GetCapturedTestStdout ();
42374252 captured_stderr_ = GetCapturedTestStderr ();
42384253
4254+ // Note: since warnings and errors are both simply printed to stderr, we
4255+ // can't holistically distinguish them here; in practice we don't have
4256+ // multiline warnings so just counting any line with 'warning:' in it
4257+ // is sufficient to separate warnings and errors in practice.
4258+ for (const auto & line :
4259+ absl::StrSplit (StripCR (captured_stderr_), ' \n ' , absl::SkipEmpty ())) {
4260+ if (absl::StrContains (line, " warning:" )) {
4261+ captured_warnings_.push_back (std::string (line));
4262+ } else {
4263+ captured_errors_.push_back (std::string (line));
4264+ }
4265+ }
4266+
42394267 return result == 0 ;
42404268 }
42414269
@@ -4257,6 +4285,30 @@ class EncodeDecodeTest : public testing::TestWithParam<EncodeDecodeTestMode> {
42574285 ExpectStdoutMatchesText (expected_output);
42584286 }
42594287
4288+ void ExpectNoErrors () { EXPECT_THAT (captured_errors_, testing::IsEmpty ()); }
4289+
4290+ void ExpectNoWarnings () {
4291+ EXPECT_THAT (captured_warnings_, testing::IsEmpty ());
4292+ }
4293+
4294+ void ExpectError (absl::string_view expected_text) {
4295+ EXPECT_THAT (captured_errors_, testing::Contains (expected_text));
4296+ }
4297+
4298+ void ExpectErrorSubstring (absl::string_view expected_substring) {
4299+ EXPECT_THAT (captured_errors_,
4300+ testing::Contains (testing::HasSubstr (expected_substring)));
4301+ }
4302+
4303+ void ExpectWarning (absl::string_view expected_text) {
4304+ EXPECT_THAT (captured_warnings_, testing::Contains (expected_text));
4305+ }
4306+
4307+ void ExpectWarningSubstring (absl::string_view expected_substring) {
4308+ EXPECT_THAT (captured_warnings_,
4309+ testing::Contains (testing::HasSubstr (expected_substring)));
4310+ }
4311+
42604312 void ExpectStdoutMatchesText (const std::string& expected_text) {
42614313 EXPECT_EQ (StripCR (expected_text), StripCR (captured_stdout_));
42624314 }
@@ -4295,6 +4347,9 @@ class EncodeDecodeTest : public testing::TestWithParam<EncodeDecodeTestMode> {
42954347 int duped_stdin_;
42964348 std::string captured_stdout_;
42974349 std::string captured_stderr_;
4350+ std::vector<std::string> captured_warnings_;
4351+ std::vector<std::string> captured_errors_;
4352+
42984353 std::string unittest_proto_descriptor_set_filename_;
42994354};
43004355
@@ -4318,7 +4373,7 @@ TEST_P(EncodeDecodeTest, Encode) {
43184373 EXPECT_TRUE (
43194374 Run (absl::StrCat (args, " --encode=protobuf_unittest.TestAllTypes" )));
43204375 ExpectStdoutMatchesBinaryFile (golden_path);
4321- ExpectStderrMatchesText ( " " );
4376+ ExpectNoErrors ( );
43224377}
43234378
43244379TEST_P (EncodeDecodeTest, Decode) {
@@ -4331,7 +4386,7 @@ TEST_P(EncodeDecodeTest, Decode) {
43314386 ExpectStdoutMatchesTextFile (TestUtil::GetTestDataPath (
43324387 " google/protobuf/"
43334388 " testdata/text_format_unittest_data_oneof_implemented.txt" ));
4334- ExpectStderrMatchesText ( " " );
4389+ ExpectNoErrors ( );
43354390}
43364391
43374392TEST_P (EncodeDecodeTest, Partial) {
@@ -4340,8 +4395,7 @@ TEST_P(EncodeDecodeTest, Partial) {
43404395 Run (" google/protobuf/unittest.proto"
43414396 " --encode=protobuf_unittest.TestRequired" ));
43424397 ExpectStdoutMatchesText (" " );
4343- ExpectStderrMatchesText (
4344- " warning: Input message is missing required fields: a, b, c\n " );
4398+ ExpectWarning (" warning: Input message is missing required fields: a, b, c" );
43454399}
43464400
43474401TEST_P (EncodeDecodeTest, DecodeRaw) {
@@ -4356,24 +4410,25 @@ TEST_P(EncodeDecodeTest, DecodeRaw) {
43564410 ExpectStdoutMatchesText (
43574411 " 1: 123\n "
43584412 " 14: \" foo\"\n " );
4359- ExpectStderrMatchesText ( " " );
4413+ ExpectNoErrors ( );
43604414}
43614415
43624416TEST_P (EncodeDecodeTest, UnknownType) {
43634417 EXPECT_FALSE (
43644418 Run (" google/protobuf/unittest.proto"
43654419 " --encode=NoSuchType" ));
43664420 ExpectStdoutMatchesText (" " );
4367- ExpectStderrMatchesText (" Type not defined: NoSuchType\n " );
4421+ ExpectError (" Type not defined: NoSuchType" );
43684422}
43694423
43704424TEST_P (EncodeDecodeTest, ProtoParseError) {
43714425 EXPECT_FALSE (
43724426 Run (" net/proto2/internal/no_such_file.proto "
43734427 " --encode=NoSuchType" ));
43744428 ExpectStdoutMatchesText (" " );
4375- ExpectStderrContainsText (
4376- " net/proto2/internal/no_such_file.proto: No such file or directory\n " );
4429+ ExpectErrorSubstring (
4430+ " net/proto2/internal/no_such_file.proto: "
4431+ " No such file or directory" );
43774432}
43784433
43794434TEST_P (EncodeDecodeTest, EncodeDeterministicOutput) {
@@ -4389,7 +4444,7 @@ TEST_P(EncodeDecodeTest, EncodeDeterministicOutput) {
43894444 EXPECT_TRUE (Run (absl::StrCat (
43904445 args, " --encode=protobuf_unittest.TestAllTypes --deterministic_output" )));
43914446 ExpectStdoutMatchesBinaryFile (golden_path);
4392- ExpectStderrMatchesText ( " " );
4447+ ExpectNoErrors ( );
43934448}
43944449
43954450TEST_P (EncodeDecodeTest, DecodeDeterministicOutput) {
@@ -4399,8 +4454,7 @@ TEST_P(EncodeDecodeTest, DecodeDeterministicOutput) {
43994454 EXPECT_FALSE (
44004455 Run (" google/protobuf/unittest.proto"
44014456 " --decode=protobuf_unittest.TestAllTypes --deterministic_output" ));
4402- ExpectStderrMatchesText (
4403- " Can only use --deterministic_output with --encode.\n " );
4457+ ExpectError (" Can only use --deterministic_output with --encode." );
44044458}
44054459
44064460INSTANTIATE_TEST_SUITE_P (FileDescriptorSetSource, EncodeDecodeTest,
0 commit comments