aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/google/protobuf/compiler/command_line_interface_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/google/protobuf/compiler/command_line_interface_unittest.cc')
-rw-r--r--src/google/protobuf/compiler/command_line_interface_unittest.cc782
1 files changed, 696 insertions, 86 deletions
diff --git a/src/google/protobuf/compiler/command_line_interface_unittest.cc b/src/google/protobuf/compiler/command_line_interface_unittest.cc
index dda007d4..41eb244a 100644
--- a/src/google/protobuf/compiler/command_line_interface_unittest.cc
+++ b/src/google/protobuf/compiler/command_line_interface_unittest.cc
@@ -32,56 +32,56 @@
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
-#include <sys/types.h>
-#include <sys/stat.h>
#include <fcntl.h>
-#ifdef _MSC_VER
-#include <io.h>
-#else
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#ifndef _MSC_VER
#include <unistd.h>
#endif
#include <memory>
-#ifndef _SHARED_PTR_H
-#include <google/protobuf/stubs/shared_ptr.h>
-#endif
#include <vector>
-#include <google/protobuf/descriptor.pb.h>
-#include <google/protobuf/descriptor.h>
-#include <google/protobuf/io/zero_copy_stream.h>
-#include <google/protobuf/compiler/command_line_interface.h>
-#include <google/protobuf/compiler/code_generator.h>
+#include <google/protobuf/stubs/stringprintf.h>
+#include <google/protobuf/testing/file.h>
#include <google/protobuf/testing/file.h>
#include <google/protobuf/compiler/mock_code_generator.h>
#include <google/protobuf/compiler/subprocess.h>
-#include <google/protobuf/io/printer.h>
+#include <google/protobuf/compiler/code_generator.h>
+#include <google/protobuf/compiler/command_line_interface.h>
#include <google/protobuf/unittest.pb.h>
-#include <google/protobuf/testing/file.h>
-#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/descriptor.h>
#include <google/protobuf/stubs/substitute.h>
+#include <google/protobuf/testing/file.h>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/io_win32.h>
+
namespace google {
namespace protobuf {
namespace compiler {
+#if defined(_WIN32)
+// DO NOT include <io.h>, instead create functions in io_win32.{h,cc} and import
+// them like we do below.
+using google::protobuf::internal::win32::access;
+using google::protobuf::internal::win32::dup;
+using google::protobuf::internal::win32::dup2;
+using google::protobuf::internal::win32::close;
+using google::protobuf::internal::win32::open;
+using google::protobuf::internal::win32::write;
+#endif
+
// Disable the whole test when we use tcmalloc for "draconian" heap checks, in
// which case tcmalloc will print warnings that fail the plugin tests.
#if !GOOGLE_PROTOBUF_HEAP_CHECK_DRACONIAN
-#if defined(_WIN32)
-#ifndef STDIN_FILENO
-#define STDIN_FILENO 0
-#endif
-#ifndef STDOUT_FILENO
-#define STDOUT_FILENO 1
-#endif
-#ifndef F_OK
-#define F_OK 00 // not defined by MSVC for whatever reason
-#endif
-#endif
namespace {
@@ -98,6 +98,7 @@ class CommandLineInterfaceTest : public testing::Test {
// command is automatically split on spaces, and the string "$tmpdir"
// is replaced with TestTempDir().
void Run(const string& command);
+ void RunWithArgs(std::vector<string> args);
// -----------------------------------------------------------------
// Methods to set up the test (called before Run()).
@@ -125,10 +126,6 @@ class CommandLineInterfaceTest : public testing::Test {
// google3.
#endif // !PROTOBUF_OPENSOURCE
- void SetInputsAreProtoPathRelative(bool enable) {
- cli_.SetInputsAreProtoPathRelative(enable);
- }
-
// -----------------------------------------------------------------
// Methods to check the test results (called after Run()).
@@ -152,6 +149,11 @@ class CommandLineInterfaceTest : public testing::Test {
// Checks that the captured stdout is the same as the expected_text.
void ExpectCapturedStdout(const string& expected_text);
+ // Checks that Run() returned zero and the stdout contains the given
+ // substring.
+ void ExpectCapturedStdoutSubstringWithZeroReturnCode(
+ const string& expected_substring);
+
// Returns true if ExpectErrorSubstring(expected_substring) would pass, but
// does not fail otherwise.
bool HasAlternateErrorSubstring(const string& expected_substring);
@@ -183,12 +185,17 @@ class CommandLineInterfaceTest : public testing::Test {
const string& insertions,
const string& proto_name,
const string& message_name);
+ void CheckGeneratedAnnotations(const string& name, const string& file);
void ExpectNullCodeGeneratorCalled(const string& parameter);
+
void ReadDescriptorSet(const string& filename,
FileDescriptorSet* descriptor_set);
+ void WriteDescriptorSet(const string& filename,
+ const FileDescriptorSet* descriptor_set);
+
void ExpectFileContent(const string& filename,
const string& content);
@@ -215,7 +222,7 @@ class CommandLineInterfaceTest : public testing::Test {
string captured_stdout_;
// Pointers which need to be deleted later.
- vector<CodeGenerator*> mock_generators_to_delete_;
+ std::vector<CodeGenerator*> mock_generators_to_delete_;
NullCodeGenerator* null_generator_;
};
@@ -242,11 +249,6 @@ class CommandLineInterfaceTest::NullCodeGenerator : public CodeGenerator {
// ===================================================================
void CommandLineInterfaceTest::SetUp() {
- // Most of these tests were written before this option was added, so we
- // run with the option on (which used to be the only way) except in certain
- // tests where we turn it off.
- cli_.SetInputsAreProtoPathRelative(true);
-
temp_directory_ = TestTempDir() + "/proto2_cli_test_temp";
// If the temp directory already exists, it must be left over from a
@@ -272,6 +274,7 @@ void CommandLineInterfaceTest::SetUp() {
mock_generators_to_delete_.push_back(generator);
cli_.RegisterGenerator("--null_out", generator, "Null output.");
+
disallow_plugins_ = false;
}
@@ -289,8 +292,10 @@ void CommandLineInterfaceTest::TearDown() {
}
void CommandLineInterfaceTest::Run(const string& command) {
- vector<string> args = Split(command, " ", true);
+ RunWithArgs(Split(command, " ", true));
+}
+void CommandLineInterfaceTest::RunWithArgs(std::vector<string> args) {
if (!disallow_plugins_) {
cli_.AllowPlugins("prefix-");
#ifndef GOOGLE_THIRD_PARTY_PROTOBUF
@@ -336,7 +341,7 @@ void CommandLineInterfaceTest::Run(const string& command) {
}
}
- google::protobuf::scoped_array<const char * > argv(new const char* [args.size()]);
+ std::unique_ptr<const char * []> argv(new const char* [args.size()]);
for (int i = 0; i < args.size(); i++) {
args[i] = StringReplace(args[i], "$tmpdir", temp_directory_, true);
@@ -376,7 +381,9 @@ void CommandLineInterfaceTest::CreateTempFile(
// Write file.
string full_name = temp_directory_ + "/" + name;
- GOOGLE_CHECK_OK(File::SetContents(full_name, contents, true));
+ GOOGLE_CHECK_OK(File::SetContents(
+ full_name, StringReplace(contents, "$tmpdir", temp_directory_, true),
+ true));
}
void CommandLineInterfaceTest::CreateTempDir(const string& name) {
@@ -458,12 +465,18 @@ void CommandLineInterfaceTest::ExpectGeneratedWithInsertions(
proto_name, temp_directory_);
}
+void CommandLineInterfaceTest::CheckGeneratedAnnotations(const string& name,
+ const string& file) {
+ MockCodeGenerator::CheckGeneratedAnnotations(name, file, temp_directory_);
+}
+
void CommandLineInterfaceTest::ExpectNullCodeGeneratorCalled(
const string& parameter) {
EXPECT_TRUE(null_generator_->called_);
EXPECT_EQ(parameter, null_generator_->parameter_);
}
+
void CommandLineInterfaceTest::ReadDescriptorSet(
const string& filename, FileDescriptorSet* descriptor_set) {
string path = temp_directory_ + "/" + filename;
@@ -475,11 +488,24 @@ void CommandLineInterfaceTest::ReadDescriptorSet(
}
}
+void CommandLineInterfaceTest::WriteDescriptorSet(
+ const string& filename, const FileDescriptorSet* descriptor_set) {
+ string binary_proto;
+ GOOGLE_CHECK(descriptor_set->SerializeToString(&binary_proto));
+ CreateTempFile(filename, binary_proto);
+}
+
void CommandLineInterfaceTest::ExpectCapturedStdout(
const string& expected_text) {
EXPECT_EQ(expected_text, captured_stdout_);
}
+void CommandLineInterfaceTest::ExpectCapturedStdoutSubstringWithZeroReturnCode(
+ const string& expected_substring) {
+ EXPECT_EQ(0, return_code_);
+ EXPECT_PRED_FORMAT2(
+ testing::IsSubstring, expected_substring, captured_stdout_);
+}
void CommandLineInterfaceTest::ExpectFileContent(
const string& filename, const string& content) {
@@ -507,6 +533,22 @@ TEST_F(CommandLineInterfaceTest, BasicOutput) {
ExpectGenerated("test_generator", "", "foo.proto", "Foo");
}
+TEST_F(CommandLineInterfaceTest, BasicOutput_DescriptorSetIn) {
+ // Test that the common case works.
+ FileDescriptorSet file_descriptor_set;
+ FileDescriptorProto* file_descriptor_proto = file_descriptor_set.add_file();
+ file_descriptor_proto->set_name("foo.proto");
+ file_descriptor_proto->add_message_type()->set_name("Foo");
+
+ WriteDescriptorSet("foo.bin", &file_descriptor_set);
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--descriptor_set_in=$tmpdir/foo.bin foo.proto");
+
+ ExpectNoErrors();
+ ExpectGenerated("test_generator", "", "foo.proto", "Foo");
+}
+
TEST_F(CommandLineInterfaceTest, BasicPlugin) {
// Test that basic plugins work.
@@ -521,6 +563,23 @@ TEST_F(CommandLineInterfaceTest, BasicPlugin) {
ExpectGenerated("test_plugin", "", "foo.proto", "Foo");
}
+TEST_F(CommandLineInterfaceTest, BasicPlugin_DescriptorSetIn) {
+ // Test that basic plugins work.
+
+ FileDescriptorSet file_descriptor_set;
+ FileDescriptorProto* file_descriptor_proto = file_descriptor_set.add_file();
+ file_descriptor_proto->set_name("foo.proto");
+ file_descriptor_proto->add_message_type()->set_name("Foo");
+
+ WriteDescriptorSet("foo.bin", &file_descriptor_set);
+
+ Run("protocol_compiler --plug_out=$tmpdir "
+ "--descriptor_set_in=$tmpdir/foo.bin foo.proto");
+
+ ExpectNoErrors();
+ ExpectGenerated("test_plugin", "", "foo.proto", "Foo");
+}
+
TEST_F(CommandLineInterfaceTest, GeneratorAndPlugin) {
// Invoke a generator and a plugin at the same time.
@@ -536,6 +595,24 @@ TEST_F(CommandLineInterfaceTest, GeneratorAndPlugin) {
ExpectGenerated("test_plugin", "", "foo.proto", "Foo");
}
+TEST_F(CommandLineInterfaceTest, GeneratorAndPlugin_DescriptorSetIn) {
+ // Invoke a generator and a plugin at the same time.
+
+ FileDescriptorSet file_descriptor_set;
+ FileDescriptorProto* file_descriptor_proto = file_descriptor_set.add_file();
+ file_descriptor_proto->set_name("foo.proto");
+ file_descriptor_proto->add_message_type()->set_name("Foo");
+
+ WriteDescriptorSet("foo.bin", &file_descriptor_set);
+
+ Run("protocol_compiler --test_out=$tmpdir --plug_out=$tmpdir "
+ "--descriptor_set_in=$tmpdir/foo.bin foo.proto");
+
+ ExpectNoErrors();
+ ExpectGenerated("test_generator", "", "foo.proto", "Foo");
+ ExpectGenerated("test_plugin", "", "foo.proto", "Foo");
+}
+
TEST_F(CommandLineInterfaceTest, MultipleInputs) {
// Test parsing multiple input files.
@@ -560,6 +637,34 @@ TEST_F(CommandLineInterfaceTest, MultipleInputs) {
"bar.proto", "Bar");
}
+TEST_F(CommandLineInterfaceTest, MultipleInputs_DescriptorSetIn) {
+ // Test parsing multiple input files.
+ FileDescriptorSet file_descriptor_set;
+
+ FileDescriptorProto* file_descriptor_proto = file_descriptor_set.add_file();
+ file_descriptor_proto->set_name("foo.proto");
+ file_descriptor_proto->add_message_type()->set_name("Foo");
+
+ file_descriptor_proto = file_descriptor_set.add_file();
+ file_descriptor_proto->set_name("bar.proto");
+ file_descriptor_proto->add_message_type()->set_name("Bar");
+
+ WriteDescriptorSet("foo.bin", &file_descriptor_set);
+
+ Run("protocol_compiler --test_out=$tmpdir --plug_out=$tmpdir "
+ "--descriptor_set_in=$tmpdir/foo.bin foo.proto bar.proto");
+
+ ExpectNoErrors();
+ ExpectGeneratedWithMultipleInputs("test_generator", "foo.proto,bar.proto",
+ "foo.proto", "Foo");
+ ExpectGeneratedWithMultipleInputs("test_generator", "foo.proto,bar.proto",
+ "bar.proto", "Bar");
+ ExpectGeneratedWithMultipleInputs("test_plugin", "foo.proto,bar.proto",
+ "foo.proto", "Foo");
+ ExpectGeneratedWithMultipleInputs("test_plugin", "foo.proto,bar.proto",
+ "bar.proto", "Bar");
+}
+
TEST_F(CommandLineInterfaceTest, MultipleInputsWithImport) {
// Test parsing multiple input files with an import of a separate file.
@@ -590,6 +695,165 @@ TEST_F(CommandLineInterfaceTest, MultipleInputsWithImport) {
"bar.proto", "Bar");
}
+TEST_F(CommandLineInterfaceTest, MultipleInputsWithImport_DescriptorSetIn) {
+ // Test parsing multiple input files with an import of a separate file.
+ FileDescriptorSet file_descriptor_set;
+
+ FileDescriptorProto* file_descriptor_proto = file_descriptor_set.add_file();
+ file_descriptor_proto->set_name("foo.proto");
+ file_descriptor_proto->add_message_type()->set_name("Foo");
+
+ file_descriptor_proto = file_descriptor_set.add_file();
+ file_descriptor_proto->set_name("bar.proto");
+ file_descriptor_proto->add_dependency("baz.proto");
+ DescriptorProto* message = file_descriptor_proto->add_message_type();
+ message->set_name("Bar");
+ FieldDescriptorProto* field = message->add_field();
+ field->set_type_name("Baz");
+ field->set_name("a");
+ field->set_number(1);
+
+ WriteDescriptorSet("foo_and_bar.bin", &file_descriptor_set);
+
+ file_descriptor_set.clear_file();
+ file_descriptor_proto = file_descriptor_set.add_file();
+ file_descriptor_proto->set_name("baz.proto");
+ file_descriptor_proto->add_message_type()->set_name("Baz");
+
+ file_descriptor_proto = file_descriptor_set.add_file();
+ file_descriptor_proto->set_name("bat.proto");
+ file_descriptor_proto->add_dependency("baz.proto");
+ message = file_descriptor_proto->add_message_type();
+ message->set_name("Bat");
+ field = message->add_field();
+ field->set_type_name("Baz");
+ field->set_name("a");
+ field->set_number(1);
+
+ WriteDescriptorSet("baz_and_bat.bin", &file_descriptor_set);
+ Run(strings::Substitute(
+ "protocol_compiler --test_out=$$tmpdir --plug_out=$$tmpdir "
+ "--descriptor_set_in=$0 foo.proto bar.proto",
+ string("$tmpdir/foo_and_bar.bin") +
+ CommandLineInterface::kPathSeparator +
+ "$tmpdir/baz_and_bat.bin"));
+
+ ExpectNoErrors();
+ ExpectGeneratedWithMultipleInputs("test_generator", "foo.proto,bar.proto",
+ "foo.proto", "Foo");
+ ExpectGeneratedWithMultipleInputs("test_generator", "foo.proto,bar.proto",
+ "bar.proto", "Bar");
+ ExpectGeneratedWithMultipleInputs("test_plugin", "foo.proto,bar.proto",
+ "foo.proto", "Foo");
+ ExpectGeneratedWithMultipleInputs("test_plugin", "foo.proto,bar.proto",
+ "bar.proto", "Bar");
+
+ Run(strings::Substitute(
+ "protocol_compiler --test_out=$$tmpdir --plug_out=$$tmpdir "
+ "--descriptor_set_in=$0 baz.proto bat.proto",
+ string("$tmpdir/foo_and_bar.bin") +
+ CommandLineInterface::kPathSeparator +
+ "$tmpdir/baz_and_bat.bin"));
+
+ ExpectNoErrors();
+ ExpectGeneratedWithMultipleInputs("test_generator", "baz.proto,bat.proto",
+ "baz.proto", "Baz");
+ ExpectGeneratedWithMultipleInputs("test_generator", "baz.proto,bat.proto",
+ "bat.proto", "Bat");
+ ExpectGeneratedWithMultipleInputs("test_plugin", "baz.proto,bat.proto",
+ "baz.proto", "Baz");
+ ExpectGeneratedWithMultipleInputs("test_plugin", "baz.proto,bat.proto",
+ "bat.proto", "Bat");
+}
+
+TEST_F(CommandLineInterfaceTest,
+ MultipleInputsWithImport_DescriptorSetIn_DuplicateFileDescriptor) {
+ // Test parsing multiple input files with an import of a separate file.
+ FileDescriptorSet file_descriptor_set;
+
+ FileDescriptorProto foo_file_descriptor_proto;
+ foo_file_descriptor_proto.set_name("foo.proto");
+ foo_file_descriptor_proto.add_message_type()->set_name("Foo");
+
+ file_descriptor_set.add_file()->CopyFrom(foo_file_descriptor_proto);
+
+ FileDescriptorProto* file_descriptor_proto = file_descriptor_set.add_file();
+ file_descriptor_proto->set_name("bar.proto");
+ file_descriptor_proto->add_dependency("baz.proto");
+ file_descriptor_proto->add_dependency("foo.proto");
+ DescriptorProto* message = file_descriptor_proto->add_message_type();
+ message->set_name("Bar");
+ FieldDescriptorProto* field = message->add_field();
+ field->set_type_name("Baz");
+ field->set_name("a");
+ field->set_number(1);
+ field = message->add_field();
+ field->set_type_name("Foo");
+ field->set_name("f");
+ field->set_number(2);
+ WriteDescriptorSet("foo_and_bar.bin", &file_descriptor_set);
+
+ file_descriptor_set.clear_file();
+ file_descriptor_set.add_file()->CopyFrom(foo_file_descriptor_proto);
+
+ file_descriptor_proto = file_descriptor_set.add_file();
+ file_descriptor_proto->set_name("baz.proto");
+ file_descriptor_proto->add_dependency("foo.proto");
+ message = file_descriptor_proto->add_message_type();
+ message->set_name("Baz");
+ field = message->add_field();
+ field->set_type_name("Foo");
+ field->set_name("f");
+ field->set_number(1);
+ WriteDescriptorSet("foo_and_baz.bin", &file_descriptor_set);
+
+ Run(strings::Substitute(
+ "protocol_compiler --test_out=$$tmpdir --plug_out=$$tmpdir "
+ "--descriptor_set_in=$0 bar.proto",
+ string("$tmpdir/foo_and_bar.bin") +
+ CommandLineInterface::kPathSeparator +
+ "$tmpdir/foo_and_baz.bin"));
+
+ ExpectNoErrors();
+ ExpectGenerated("test_generator", "", "bar.proto", "Bar");
+ ExpectGenerated("test_plugin", "", "bar.proto", "Bar");
+}
+
+TEST_F(CommandLineInterfaceTest,
+ MultipleInputsWithImport_DescriptorSetIn_MissingImport) {
+ // Test parsing multiple input files with an import of a separate file.
+ FileDescriptorSet file_descriptor_set;
+
+ FileDescriptorProto* file_descriptor_proto = file_descriptor_set.add_file();
+ file_descriptor_proto->set_name("foo.proto");
+ file_descriptor_proto->add_message_type()->set_name("Foo");
+
+ file_descriptor_proto = file_descriptor_set.add_file();
+ file_descriptor_proto->set_name("bar.proto");
+ file_descriptor_proto->add_dependency("baz.proto");
+ DescriptorProto* message = file_descriptor_proto->add_message_type();
+ message->set_name("Bar");
+ FieldDescriptorProto* field = message->add_field();
+ field->set_type_name("Baz");
+ field->set_name("a");
+ field->set_number(1);
+
+ WriteDescriptorSet("foo_and_bar.bin", &file_descriptor_set);
+
+ file_descriptor_set.clear_file();
+ file_descriptor_proto = file_descriptor_set.add_file();
+ file_descriptor_proto->set_name("baz.proto");
+ file_descriptor_proto->add_message_type()->set_name("Baz");
+
+ WriteDescriptorSet("baz.bin", &file_descriptor_set);
+ Run("protocol_compiler --test_out=$tmpdir --plug_out=$tmpdir "
+ "--descriptor_set_in=$tmpdir/foo_and_bar.bin "
+ "foo.proto bar.proto");
+ ExpectErrorSubstring(
+ "bar.proto: Import \"baz.proto\" was not found or had errors.");
+ ExpectErrorSubstring("bar.proto: \"Baz\" is not defined.");
+}
+
TEST_F(CommandLineInterfaceTest, CreateDirectory) {
// Test that when we output to a sub-directory, it is created.
@@ -649,6 +913,70 @@ TEST_F(CommandLineInterfaceTest, ExtraGeneratorParameters) {
"test_generator", "baz,foo1,foo2,foo3", "foo.proto", "Foo", "b");
}
+TEST_F(CommandLineInterfaceTest, ExtraPluginParameters) {
+ // Test that generator parameters specified with the option flag are
+ // correctly passed to the code generator.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+ // Create the "a" and "b" sub-directories.
+ CreateTempDir("a");
+ CreateTempDir("b");
+
+ Run("protocol_compiler "
+ "--plug_opt=foo1 "
+ "--plug_out=bar:$tmpdir/a "
+ "--plug_opt=foo2 "
+ "--plug_out=baz:$tmpdir/b "
+ "--plug_opt=foo3 "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectNoErrors();
+ ExpectGenerated(
+ "test_plugin", "bar,foo1,foo2,foo3", "foo.proto", "Foo", "a");
+ ExpectGenerated(
+ "test_plugin", "baz,foo1,foo2,foo3", "foo.proto", "Foo", "b");
+}
+
+TEST_F(CommandLineInterfaceTest, UnrecognizedExtraParameters) {
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ Run("protocol_compiler --plug_out=TestParameter:$tmpdir "
+ "--unknown_plug_a_opt=Foo "
+ "--unknown_plug_b_opt=Bar "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectErrorSubstring("Unknown flag: --unknown_plug_a_opt");
+ ExpectErrorSubstring("Unknown flag: --unknown_plug_b_opt");
+}
+
+TEST_F(CommandLineInterfaceTest, ExtraPluginParametersForOutParameters) {
+ // This doesn't rely on the plugin having been registred and instead that
+ // the existence of --[name]_out is enough to make the --[name]_opt valid.
+ // However, running out of process plugins found via the search path (i.e. -
+ // not pre registered with --plugin) isn't support in this test suite, so we
+ // list the options pre/post the _out directive, and then include _opt that
+ // will be unknown, and confirm the failure output is about the expected
+ // unknown directive, which means the other were accepted.
+ // NOTE: UnrecognizedExtraParameters confirms that if two unknown _opt
+ // directives appear, they both are reported.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ Run("protocol_compiler --plug_out=TestParameter:$tmpdir "
+ "--xyz_opt=foo=bar --xyz_out=$tmpdir "
+ "--abc_out=$tmpdir --abc_opt=foo=bar "
+ "--unknown_plug_opt=Foo "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectErrorText("Unknown flag: --unknown_plug_opt\n");
+}
+
TEST_F(CommandLineInterfaceTest, Insert) {
// Test running a generator that inserts code into another's output.
@@ -672,6 +1000,25 @@ TEST_F(CommandLineInterfaceTest, Insert) {
"foo.proto", "Foo");
}
+TEST_F(CommandLineInterfaceTest, InsertWithAnnotationFixup) {
+ // Check that annotation spans are updated after insertions.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message MockCodeGenerator_Annotate {}\n");
+
+ Run("protocol_compiler "
+ "--test_out=TestParameter:$tmpdir "
+ "--plug_out=TestPluginParameter:$tmpdir "
+ "--test_out=insert=test_generator,test_plugin:$tmpdir "
+ "--plug_out=insert=test_generator,test_plugin:$tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectNoErrors();
+ CheckGeneratedAnnotations("test_generator", "foo.proto");
+ CheckGeneratedAnnotations("test_plugin", "foo.proto");
+}
+
#if defined(_WIN32)
TEST_F(CommandLineInterfaceTest, WindowsOutputPath) {
@@ -715,6 +1062,11 @@ TEST_F(CommandLineInterfaceTest, TrailingBackslash) {
ExpectGenerated("test_generator", "", "foo.proto", "Foo");
}
+TEST_F(CommandLineInterfaceTest, Win32ErrorMessage) {
+ EXPECT_EQ("The system cannot find the file specified.\r\n",
+ Subprocess::Win32ErrorMessage(ERROR_FILE_NOT_FOUND));
+}
+
#endif // defined(_WIN32) || defined(__CYGWIN__)
TEST_F(CommandLineInterfaceTest, PathLookup) {
@@ -752,17 +1104,11 @@ TEST_F(CommandLineInterfaceTest, ColonDelimitedPath) {
"}\n");
CreateTempFile("b/foo.proto", "this should not be parsed\n");
-#undef PATH_SEPARATOR
-#if defined(_WIN32)
-#define PATH_SEPARATOR ";"
-#else
-#define PATH_SEPARATOR ":"
-#endif
-
- Run("protocol_compiler --test_out=$tmpdir "
- "--proto_path=$tmpdir/a" PATH_SEPARATOR "$tmpdir/b foo.proto");
-
-#undef PATH_SEPARATOR
+ Run(strings::Substitute(
+ "protocol_compiler --test_out=$$tmpdir --proto_path=$0 foo.proto",
+ string("$tmpdir/a") +
+ CommandLineInterface::kPathSeparator +
+ "$tmpdir/b"));
ExpectNoErrors();
ExpectGenerated("test_generator", "", "foo.proto", "Foo");
@@ -782,6 +1128,21 @@ TEST_F(CommandLineInterfaceTest, NonRootMapping) {
ExpectGenerated("test_generator", "", "bar/foo.proto", "Foo");
}
+TEST_F(CommandLineInterfaceTest, PathWithEqualsSign) {
+ // Test setting up a search path which happens to have '=' in it.
+
+ CreateTempDir("with=sign");
+ CreateTempFile("with=sign/foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir/with=sign foo.proto");
+
+ ExpectNoErrors();
+ ExpectGenerated("test_generator", "", "foo.proto", "Foo");
+}
+
TEST_F(CommandLineInterfaceTest, MultipleGenerators) {
// Test that we can have multiple generators and use both in one invocation,
// each with a different output directory.
@@ -847,11 +1208,116 @@ TEST_F(CommandLineInterfaceTest, AllowServicesHasService) {
ExpectGenerated("test_generator", "", "foo.proto", "Foo");
}
+TEST_F(CommandLineInterfaceTest, DirectDependencies_Missing_EmptyList) {
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "import \"bar.proto\";\n"
+ "message Foo { optional Bar bar = 1; }");
+ CreateTempFile("bar.proto",
+ "syntax = \"proto2\";\n"
+ "message Bar { optional string text = 1; }");
+
+ Run("protocol_compiler --test_out=$tmpdir --proto_path=$tmpdir "
+ "--direct_dependencies= foo.proto");
+
+ ExpectErrorText(
+ "foo.proto: File is imported but not declared in --direct_dependencies: "
+ "bar.proto\n");
+}
+
+TEST_F(CommandLineInterfaceTest, DirectDependencies_Missing) {
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "import \"bar.proto\";\n"
+ "import \"bla.proto\";\n"
+ "message Foo { optional Bar bar = 1; optional Bla bla = 2; }");
+ CreateTempFile("bar.proto",
+ "syntax = \"proto2\";\n"
+ "message Bar { optional string text = 1; }");
+ CreateTempFile("bla.proto",
+ "syntax = \"proto2\";\n"
+ "message Bla { optional int64 number = 1; }");
+
+ Run("protocol_compiler --test_out=$tmpdir --proto_path=$tmpdir "
+ "--direct_dependencies=bla.proto foo.proto");
+
+ ExpectErrorText(
+ "foo.proto: File is imported but not declared in --direct_dependencies: "
+ "bar.proto\n");
+}
+
+TEST_F(CommandLineInterfaceTest, DirectDependencies_NoViolation) {
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "import \"bar.proto\";\n"
+ "message Foo { optional Bar bar = 1; }");
+ CreateTempFile("bar.proto",
+ "syntax = \"proto2\";\n"
+ "message Bar { optional string text = 1; }");
+
+ Run("protocol_compiler --test_out=$tmpdir --proto_path=$tmpdir "
+ "--direct_dependencies=bar.proto foo.proto");
+
+ ExpectNoErrors();
+}
+
+TEST_F(CommandLineInterfaceTest, DirectDependencies_NoViolation_MultiImports) {
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "import \"bar.proto\";\n"
+ "import \"bla.proto\";\n"
+ "message Foo { optional Bar bar = 1; optional Bla bla = 2; }");
+ CreateTempFile("bar.proto",
+ "syntax = \"proto2\";\n"
+ "message Bar { optional string text = 1; }");
+ CreateTempFile("bla.proto",
+ "syntax = \"proto2\";\n"
+ "message Bla { optional int64 number = 1; }");
+
+ Run("protocol_compiler --test_out=$tmpdir --proto_path=$tmpdir "
+ "--direct_dependencies=bar.proto:bla.proto foo.proto");
+
+ ExpectNoErrors();
+}
+
+TEST_F(CommandLineInterfaceTest, DirectDependencies_ProvidedMultipleTimes) {
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n");
+
+ Run("protocol_compiler --test_out=$tmpdir --proto_path=$tmpdir "
+ "--direct_dependencies=bar.proto --direct_dependencies=bla.proto "
+ "foo.proto");
+
+ ExpectErrorText(
+ "--direct_dependencies may only be passed once. To specify multiple "
+ "direct dependencies, pass them all as a single parameter separated by "
+ "':'.\n");
+}
+
+TEST_F(CommandLineInterfaceTest, DirectDependencies_CustomErrorMessage) {
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "import \"bar.proto\";\n"
+ "message Foo { optional Bar bar = 1; }");
+ CreateTempFile("bar.proto",
+ "syntax = \"proto2\";\n"
+ "message Bar { optional string text = 1; }");
+
+ std::vector<string> commands;
+ commands.push_back("protocol_compiler");
+ commands.push_back("--test_out=$tmpdir");
+ commands.push_back("--proto_path=$tmpdir");
+ commands.push_back("--direct_dependencies=");
+ commands.push_back("--direct_dependencies_violation_msg=Bla \"%s\" Bla");
+ commands.push_back("foo.proto");
+ RunWithArgs(commands);
+
+ ExpectErrorText("foo.proto: Bla \"bar.proto\" Bla\n");
+}
+
TEST_F(CommandLineInterfaceTest, CwdRelativeInputs) {
// Test that we can accept working-directory-relative input files.
- SetInputsAreProtoPathRelative(false);
-
CreateTempFile("foo.proto",
"syntax = \"proto2\";\n"
"message Foo {}\n");
@@ -918,15 +1384,17 @@ TEST_F(CommandLineInterfaceTest, WriteDescriptorSetWithDuplicates) {
ReadDescriptorSet("descriptor_set", &descriptor_set);
if (HasFatalFailure()) return;
EXPECT_EQ(3, descriptor_set.file_size());
- EXPECT_EQ("bar.proto", descriptor_set.file(0).name());
- EXPECT_EQ("foo.proto", descriptor_set.file(1).name());
+ // foo should come first since the output is in dependency order.
+ // since bar and baz are unordered, they should be in command line order.
+ EXPECT_EQ("foo.proto", descriptor_set.file(0).name());
+ EXPECT_EQ("bar.proto", descriptor_set.file(1).name());
EXPECT_EQ("baz.proto", descriptor_set.file(2).name());
// Descriptor set should not have source code info.
EXPECT_FALSE(descriptor_set.file(0).has_source_code_info());
// Descriptor set should have json_name.
- EXPECT_EQ("Bar", descriptor_set.file(0).message_type(0).name());
- EXPECT_EQ("foo", descriptor_set.file(0).message_type(0).field(0).name());
- EXPECT_TRUE(descriptor_set.file(0).message_type(0).field(0).has_json_name());
+ EXPECT_EQ("Bar", descriptor_set.file(1).message_type(0).name());
+ EXPECT_EQ("foo", descriptor_set.file(1).message_type(0).field(0).name());
+ EXPECT_TRUE(descriptor_set.file(1).message_type(0).field(0).has_json_name());
}
TEST_F(CommandLineInterfaceTest, WriteDescriptorSetWithSourceInfo) {
@@ -1090,6 +1558,37 @@ TEST_F(CommandLineInterfaceTest, WriteDependencyManifestFileForAbsolutePath) {
}
#endif // !_WIN32
+TEST_F(CommandLineInterfaceTest, TestArgumentFile) {
+ // Test parsing multiple input files using an argument file.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+ CreateTempFile("bar.proto",
+ "syntax = \"proto2\";\n"
+ "message Bar {}\n");
+ CreateTempFile("arguments.txt",
+ "--test_out=$tmpdir\n"
+ "--plug_out=$tmpdir\n"
+ "--proto_path=$tmpdir\n"
+ "--direct_dependencies_violation_msg=%s is not imported\n"
+ "foo.proto\n"
+ "bar.proto");
+
+ Run("protocol_compiler @$tmpdir/arguments.txt");
+
+ ExpectNoErrors();
+ ExpectGeneratedWithMultipleInputs("test_generator", "foo.proto,bar.proto",
+ "foo.proto", "Foo");
+ ExpectGeneratedWithMultipleInputs("test_generator", "foo.proto,bar.proto",
+ "bar.proto", "Bar");
+ ExpectGeneratedWithMultipleInputs("test_plugin", "foo.proto,bar.proto",
+ "foo.proto", "Foo");
+ ExpectGeneratedWithMultipleInputs("test_plugin", "foo.proto,bar.proto",
+ "bar.proto", "Bar");
+}
+
+
// -------------------------------------------------------------------
TEST_F(CommandLineInterfaceTest, ParseErrors) {
@@ -1106,6 +1605,17 @@ TEST_F(CommandLineInterfaceTest, ParseErrors) {
"foo.proto:2:1: Expected top-level statement (e.g. \"message\").\n");
}
+TEST_F(CommandLineInterfaceTest, ParseErrors_DescriptorSetIn) {
+ // Test that parse errors are reported.
+ CreateTempFile("foo.bin", "not a FileDescriptorSet");
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--descriptor_set_in=$tmpdir/foo.bin foo.proto");
+
+ ExpectErrorText(
+ "$tmpdir/foo.bin: Unable to parse.\n");
+}
+
TEST_F(CommandLineInterfaceTest, ParseErrorsMultipleFiles) {
// Test that parse errors are reported from multiple files.
@@ -1133,22 +1643,42 @@ TEST_F(CommandLineInterfaceTest, ParseErrorsMultipleFiles) {
"foo.proto: Import \"baz.proto\" was not found or had errors.\n");
}
+TEST_F(CommandLineInterfaceTest, RecursiveImportFails) {
+ // Create a proto file that imports itself.
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "import \"foo.proto\";\n");
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectErrorSubstring(
+ "foo.proto: File recursively imports itself: foo.proto -> foo.proto\n");
+}
+
TEST_F(CommandLineInterfaceTest, InputNotFoundError) {
// Test what happens if the input file is not found.
Run("protocol_compiler --test_out=$tmpdir "
"--proto_path=$tmpdir foo.proto");
+ ExpectErrorText("foo.proto: No such file or directory\n");
+}
+
+TEST_F(CommandLineInterfaceTest, InputNotFoundError_DescriptorSetIn) {
+ // Test what happens if the input file is not found.
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--descriptor_set_in=$tmpdir/foo.bin foo.proto");
+
ExpectErrorText(
- "foo.proto: File not found.\n");
+ "$tmpdir/foo.bin: No such file or directory\n");
}
TEST_F(CommandLineInterfaceTest, CwdRelativeInputNotFoundError) {
// Test what happens when a working-directory-relative input file is not
// found.
- SetInputsAreProtoPathRelative(false);
-
Run("protocol_compiler --test_out=$tmpdir "
"--proto_path=$tmpdir $tmpdir/foo.proto");
@@ -1160,8 +1690,6 @@ TEST_F(CommandLineInterfaceTest, CwdRelativeInputNotMappedError) {
// Test what happens when a working-directory-relative input file is not
// mapped to a virtual path.
- SetInputsAreProtoPathRelative(false);
-
CreateTempFile("foo.proto",
"syntax = \"proto2\";\n"
"message Foo {}\n");
@@ -1186,8 +1714,6 @@ TEST_F(CommandLineInterfaceTest, CwdRelativeInputNotFoundAndNotMappedError) {
// Check what happens if the input file is not found *and* is not mapped
// in the proto_path.
- SetInputsAreProtoPathRelative(false);
-
// Create a directory called "bar" so that we can point --proto_path at it.
CreateTempFile("bar/dummy", "");
@@ -1202,8 +1728,6 @@ TEST_F(CommandLineInterfaceTest, CwdRelativeInputShadowedError) {
// Test what happens when a working-directory-relative input file is shadowed
// by another file in the virtual path.
- SetInputsAreProtoPathRelative(false);
-
CreateTempFile("foo/foo.proto",
"syntax = \"proto2\";\n"
"message Foo {}\n");
@@ -1229,8 +1753,34 @@ TEST_F(CommandLineInterfaceTest, ProtoPathNotFoundError) {
"--proto_path=$tmpdir/foo foo.proto");
ExpectErrorText(
- "$tmpdir/foo: warning: directory does not exist.\n"
- "foo.proto: File not found.\n");
+ "$tmpdir/foo: warning: directory does not exist.\n"
+ "foo.proto: No such file or directory\n");
+}
+
+TEST_F(CommandLineInterfaceTest, ProtoPathAndDescriptorSetIn) {
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir --descriptor_set_in=$tmpdir/foo.bin foo.proto");
+ ExpectErrorText(
+ "Only one of --descriptor_set_in and --proto_path can be specified.\n");
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--descriptor_set_in=$tmpdir/foo.bin --proto_path=$tmpdir foo.proto");
+ ExpectErrorText(
+ "Only one of --proto_path and --descriptor_set_in can be specified.\n");
+}
+
+TEST_F(CommandLineInterfaceTest, ProtoPathAndDependencyOut) {
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--dependency_out=$tmpdir/manifest "
+ "--descriptor_set_in=$tmpdir/foo.bin foo.proto");
+ ExpectErrorText(
+ "--descriptor_set_in cannot be used with --dependency_out.\n");
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--descriptor_set_in=$tmpdir/foo.bin "
+ "--dependency_out=$tmpdir/manifest foo.proto");
+ ExpectErrorText(
+ "--dependency_out cannot be used with --descriptor_set_in.\n");
}
TEST_F(CommandLineInterfaceTest, MissingInputError) {
@@ -1433,6 +1983,21 @@ TEST_F(CommandLineInterfaceTest, PluginReceivesJsonName) {
ExpectErrorSubstring("Saw json_name: 1");
}
+TEST_F(CommandLineInterfaceTest, PluginReceivesCompilerVersion) {
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message MockCodeGenerator_ShowVersionNumber {\n"
+ " optional int32 value = 1;\n"
+ "}\n");
+
+ Run("protocol_compiler --plug_out=$tmpdir --proto_path=$tmpdir foo.proto");
+
+ ExpectErrorSubstring(
+ StringPrintf("Saw compiler_version: %d %s",
+ GOOGLE_PROTOBUF_VERSION,
+ GOOGLE_PROTOBUF_VERSION_SUFFIX));
+}
+
TEST_F(CommandLineInterfaceTest, GeneratorPluginNotFound) {
// Test what happens if the plugin isn't found.
@@ -1475,11 +2040,11 @@ TEST_F(CommandLineInterfaceTest, GeneratorPluginNotAllowed) {
TEST_F(CommandLineInterfaceTest, HelpText) {
Run("test_exec_name --help");
- ExpectErrorSubstringWithZeroReturnCode("Usage: test_exec_name ");
- ExpectErrorSubstringWithZeroReturnCode("--test_out=OUT_DIR");
- ExpectErrorSubstringWithZeroReturnCode("Test output.");
- ExpectErrorSubstringWithZeroReturnCode("--alt_out=OUT_DIR");
- ExpectErrorSubstringWithZeroReturnCode("Alt output.");
+ ExpectCapturedStdoutSubstringWithZeroReturnCode("Usage: test_exec_name ");
+ ExpectCapturedStdoutSubstringWithZeroReturnCode("--test_out=OUT_DIR");
+ ExpectCapturedStdoutSubstringWithZeroReturnCode("Test output.");
+ ExpectCapturedStdoutSubstringWithZeroReturnCode("--alt_out=OUT_DIR");
+ ExpectCapturedStdoutSubstringWithZeroReturnCode("Alt output.");
}
TEST_F(CommandLineInterfaceTest, GccFormatErrors) {
@@ -1665,9 +2230,16 @@ TEST_F(CommandLineInterfaceTest, PrintFreeFieldNumbers) {
// test as a shell script, but we'd like to be able to run the test on
// platforms that don't have a Bourne-compatible shell available (especially
// Windows/MSVC).
-class EncodeDecodeTest : public testing::Test {
+
+enum EncodeDecodeTestMode {
+ PROTO_PATH,
+ DESCRIPTOR_SET_IN
+};
+
+class EncodeDecodeTest : public testing::TestWithParam<EncodeDecodeTestMode> {
protected:
virtual void SetUp() {
+ WriteUnittestProtoDescriptorSet();
duped_stdin_ = dup(STDIN_FILENO);
}
@@ -1707,18 +2279,28 @@ class EncodeDecodeTest : public testing::Test {
enum ReturnCode { SUCCESS, ERROR };
bool Run(const string& command) {
- vector<string> args;
+ std::vector<string> args;
args.push_back("protoc");
SplitStringUsing(command, " ", &args);
- args.push_back("--proto_path=" + TestSourceDir());
+ switch (GetParam()) {
+ case PROTO_PATH:
+ args.push_back("--proto_path=" + TestSourceDir());
+ break;
+ case DESCRIPTOR_SET_IN:
+ args.push_back(StrCat(
+ "--descriptor_set_in=",
+ unittest_proto_descriptor_set_filename_));
+ break;
+ default:
+ ADD_FAILURE() << "unexpected EncodeDecodeTestMode: " << GetParam();
+ }
- google::protobuf::scoped_array<const char * > argv(new const char* [args.size()]);
+ std::unique_ptr<const char * []> argv(new const char* [args.size()]);
for (int i = 0; i < args.size(); i++) {
argv[i] = args[i].c_str();
}
CommandLineInterface cli;
- cli.SetInputsAreProtoPathRelative(true);
CaptureTestStdout();
CaptureTestStderr();
@@ -1756,12 +2338,37 @@ class EncodeDecodeTest : public testing::Test {
}
private:
+ void WriteUnittestProtoDescriptorSet() {
+ unittest_proto_descriptor_set_filename_ =
+ TestTempDir() + "/unittest_proto_descriptor_set.bin";
+ FileDescriptorSet file_descriptor_set;
+ protobuf_unittest::TestAllTypes test_all_types;
+ test_all_types.descriptor()->file()->CopyTo(file_descriptor_set.add_file());
+
+ protobuf_unittest_import::ImportMessage import_message;
+ import_message.descriptor()->file()->CopyTo(file_descriptor_set.add_file());
+
+
+ protobuf_unittest_import::PublicImportMessage public_import_message;
+ public_import_message.descriptor()->file()->CopyTo(
+ file_descriptor_set.add_file());
+ GOOGLE_DCHECK(file_descriptor_set.IsInitialized());
+
+ string binary_proto;
+ GOOGLE_CHECK(file_descriptor_set.SerializeToString(&binary_proto));
+ GOOGLE_CHECK_OK(File::SetContents(
+ unittest_proto_descriptor_set_filename_,
+ binary_proto,
+ true));
+ }
+
int duped_stdin_;
string captured_stdout_;
string captured_stderr_;
+ string unittest_proto_descriptor_set_filename_;
};
-TEST_F(EncodeDecodeTest, Encode) {
+TEST_P(EncodeDecodeTest, Encode) {
RedirectStdinFromFile(TestSourceDir() + "/google/protobuf/"
"testdata/text_format_unittest_data_oneof_implemented.txt");
EXPECT_TRUE(Run("google/protobuf/unittest.proto "
@@ -1771,7 +2378,7 @@ TEST_F(EncodeDecodeTest, Encode) {
ExpectStderrMatchesText("");
}
-TEST_F(EncodeDecodeTest, Decode) {
+TEST_P(EncodeDecodeTest, Decode) {
RedirectStdinFromFile(TestSourceDir() +
"/google/protobuf/testdata/golden_message_oneof_implemented");
EXPECT_TRUE(Run("google/protobuf/unittest.proto "
@@ -1782,7 +2389,7 @@ TEST_F(EncodeDecodeTest, Decode) {
ExpectStderrMatchesText("");
}
-TEST_F(EncodeDecodeTest, Partial) {
+TEST_P(EncodeDecodeTest, Partial) {
RedirectStdinFromText("");
EXPECT_TRUE(Run("google/protobuf/unittest.proto "
"--encode=protobuf_unittest.TestRequired"));
@@ -1791,7 +2398,7 @@ TEST_F(EncodeDecodeTest, Partial) {
"warning: Input message is missing required fields: a, b, c\n");
}
-TEST_F(EncodeDecodeTest, DecodeRaw) {
+TEST_P(EncodeDecodeTest, DecodeRaw) {
protobuf_unittest::TestAllTypes message;
message.set_optional_int32(123);
message.set_optional_string("foo");
@@ -1805,21 +2412,24 @@ TEST_F(EncodeDecodeTest, DecodeRaw) {
ExpectStderrMatchesText("");
}
-TEST_F(EncodeDecodeTest, UnknownType) {
+TEST_P(EncodeDecodeTest, UnknownType) {
EXPECT_FALSE(Run("google/protobuf/unittest.proto "
"--encode=NoSuchType"));
ExpectStdoutMatchesText("");
ExpectStderrMatchesText("Type not defined: NoSuchType\n");
}
-TEST_F(EncodeDecodeTest, ProtoParseError) {
+TEST_P(EncodeDecodeTest, ProtoParseError) {
EXPECT_FALSE(Run("google/protobuf/no_such_file.proto "
"--encode=NoSuchType"));
ExpectStdoutMatchesText("");
ExpectStderrMatchesText(
- "google/protobuf/no_such_file.proto: File not found.\n");
+ "google/protobuf/no_such_file.proto: No such file or directory\n");
}
+INSTANTIATE_TEST_CASE_P(FileDescriptorSetSource,
+ EncodeDecodeTest,
+ testing::Values(PROTO_PATH, DESCRIPTOR_SET_IN));
} // anonymous namespace
#endif // !GOOGLE_PROTOBUF_HEAP_CHECK_DRACONIAN