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.cc576
1 files changed, 274 insertions, 302 deletions
diff --git a/src/google/protobuf/compiler/command_line_interface_unittest.cc b/src/google/protobuf/compiler/command_line_interface_unittest.cc
index 9da41c02..83850cf9 100644
--- a/src/google/protobuf/compiler/command_line_interface_unittest.cc
+++ b/src/google/protobuf/compiler/command_line_interface_unittest.cc
@@ -47,10 +47,12 @@
#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/compiler/mock_code_generator.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/unittest.pb.h>
#include <google/protobuf/testing/file.h>
#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/substitute.h>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
@@ -83,28 +85,19 @@ class CommandLineInterfaceTest : public testing::Test {
// -----------------------------------------------------------------
// Methods to set up the test (called before Run()).
- class MockCodeGenerator;
class NullCodeGenerator;
- // Registers a MockCodeGenerator with the given name.
- MockCodeGenerator* RegisterGenerator(const string& generator_name,
- const string& flag_name,
- const string& filename,
- const string& help_text);
- MockCodeGenerator* RegisterErrorGenerator(const string& generator_name,
- const string& error_text,
- const string& flag_name,
- const string& filename,
- const string& help_text);
-
- // Registers a CodeGenerator which will not actually generate anything,
- // but records the parameter passed to the generator.
- NullCodeGenerator* RegisterNullGenerator(const string& flag_name);
+ // Normally plugins are allowed for all tests. Call this to explicitly
+ // disable them.
+ void DisallowPlugins() { disallow_plugins_ = true; }
// Create a temp file within temp_directory_ with the given name.
// The containing directory is also created if necessary.
void CreateTempFile(const string& name, const string& contents);
+ // Create a subdirectory within temp_directory_.
+ void CreateTempDir(const string& name);
+
void SetInputsAreProtoPathRelative(bool enable) {
cli_.SetInputsAreProtoPathRelative(enable);
}
@@ -130,7 +123,8 @@ class CommandLineInterfaceTest : public testing::Test {
bool HasAlternateErrorSubstring(const string& expected_substring);
// Checks that MockCodeGenerator::Generate() was called in the given
- // context. That is, this tests if the generator with the given name
+ // context (or the generator in test_plugin.cc, which produces the same
+ // output). That is, this tests if the generator with the given name
// was called with the given parameter and proto file and produced the
// given output file. This is checked by reading the output file and
// checking that it contains the content that MockCodeGenerator would
@@ -140,8 +134,17 @@ class CommandLineInterfaceTest : public testing::Test {
void ExpectGenerated(const string& generator_name,
const string& parameter,
const string& proto_name,
+ const string& message_name);
+ void ExpectGenerated(const string& generator_name,
+ const string& parameter,
+ const string& proto_name,
const string& message_name,
- const string& output_file);
+ const string& output_directory);
+ void ExpectGeneratedWithInsertions(const string& generator_name,
+ const string& parameter,
+ const string& insertions,
+ const string& proto_name,
+ const string& message_name);
void ReadDescriptorSet(const string& filename,
FileDescriptorSet* descriptor_set);
@@ -150,6 +153,9 @@ class CommandLineInterfaceTest : public testing::Test {
// The object we are testing.
CommandLineInterface cli_;
+ // Was DisallowPlugins() called?
+ bool disallow_plugins_;
+
// We create a directory within TestTempDir() in order to add extra
// protection against accidentally deleting user files (since we recursively
// delete this directory during the test). This is the full path of that
@@ -166,40 +172,6 @@ class CommandLineInterfaceTest : public testing::Test {
vector<CodeGenerator*> mock_generators_to_delete_;
};
-// A mock CodeGenerator which outputs information about the context in which
-// it was called, which can then be checked. Output is written to a filename
-// constructed by concatenating the filename_prefix (given to the constructor)
-// with the proto file name, separated by a '.'.
-class CommandLineInterfaceTest::MockCodeGenerator : public CodeGenerator {
- public:
- // Create a MockCodeGenerator whose Generate() method returns true.
- MockCodeGenerator(const string& name, const string& filename_prefix);
-
- // Create a MockCodeGenerator whose Generate() method returns false
- // and sets the error string to the given string.
- MockCodeGenerator(const string& name, const string& filename_prefix,
- const string& error);
-
- ~MockCodeGenerator();
-
- void set_expect_write_error(bool value) {
- expect_write_error_ = value;
- }
-
- // implements CodeGenerator ----------------------------------------
- bool Generate(const FileDescriptor* file,
- const string& parameter,
- OutputDirectory* output_directory,
- string* error) const;
-
- private:
- string name_;
- string filename_prefix_;
- bool return_error_;
- string error_;
- bool expect_write_error_;
-};
-
class CommandLineInterfaceTest::NullCodeGenerator : public CodeGenerator {
public:
NullCodeGenerator() : called_(false) {}
@@ -237,6 +209,22 @@ void CommandLineInterfaceTest::SetUp() {
// Create the temp directory.
GOOGLE_CHECK(File::CreateDir(temp_directory_.c_str(), DEFAULT_FILE_MODE));
+
+ // Register generators.
+ CodeGenerator* generator = new MockCodeGenerator("test_generator");
+ mock_generators_to_delete_.push_back(generator);
+ cli_.RegisterGenerator("--test_out", generator, "Test output.");
+ cli_.RegisterGenerator("-t", generator, "Test output.");
+
+ generator = new MockCodeGenerator("alt_generator");
+ mock_generators_to_delete_.push_back(generator);
+ cli_.RegisterGenerator("--alt_out", generator, "Alt output.");
+
+ generator = new NullCodeGenerator();
+ mock_generators_to_delete_.push_back(generator);
+ cli_.RegisterGenerator("--null_out", generator, "Null output.");
+
+ disallow_plugins_ = false;
}
void CommandLineInterfaceTest::TearDown() {
@@ -254,6 +242,11 @@ void CommandLineInterfaceTest::Run(const string& command) {
vector<string> args;
SplitStringUsing(command, " ", &args);
+ if (!disallow_plugins_) {
+ cli_.AllowPlugins("prefix-");
+ args.push_back("--plugin=prefix-gen-plug=test_plugin");
+ }
+
scoped_array<const char*> argv(new const char*[args.size()]);
for (int i = 0; i < args.size(); i++) {
@@ -270,44 +263,6 @@ void CommandLineInterfaceTest::Run(const string& command) {
// -------------------------------------------------------------------
-CommandLineInterfaceTest::MockCodeGenerator*
-CommandLineInterfaceTest::RegisterGenerator(
- const string& generator_name,
- const string& flag_name,
- const string& filename,
- const string& help_text) {
- MockCodeGenerator* generator =
- new MockCodeGenerator(generator_name, filename);
- mock_generators_to_delete_.push_back(generator);
-
- cli_.RegisterGenerator(flag_name, generator, help_text);
- return generator;
-}
-
-CommandLineInterfaceTest::MockCodeGenerator*
-CommandLineInterfaceTest::RegisterErrorGenerator(
- const string& generator_name,
- const string& error_text,
- const string& flag_name,
- const string& filename_prefix,
- const string& help_text) {
- MockCodeGenerator* generator =
- new MockCodeGenerator(generator_name, filename_prefix, error_text);
- mock_generators_to_delete_.push_back(generator);
-
- cli_.RegisterGenerator(flag_name, generator, help_text);
- return generator;
-}
-
-CommandLineInterfaceTest::NullCodeGenerator*
-CommandLineInterfaceTest::RegisterNullGenerator(
- const string& flag_name) {
- NullCodeGenerator* generator = new NullCodeGenerator;
- mock_generators_to_delete_.push_back(generator);
- cli_.RegisterGenerator(flag_name, generator, "");
- return generator;
-}
-
void CommandLineInterfaceTest::CreateTempFile(
const string& name,
const string& contents) {
@@ -323,6 +278,10 @@ void CommandLineInterfaceTest::CreateTempFile(
File::WriteStringToFileOrDie(contents, full_name);
}
+void CommandLineInterfaceTest::CreateTempDir(const string& name) {
+ File::RecursivelyCreateDir(temp_directory_ + "/" + name, 0777);
+}
+
// -------------------------------------------------------------------
void CommandLineInterfaceTest::ExpectNoErrors() {
@@ -352,21 +311,31 @@ void CommandLineInterfaceTest::ExpectGenerated(
const string& generator_name,
const string& parameter,
const string& proto_name,
+ const string& message_name) {
+ MockCodeGenerator::ExpectGenerated(
+ generator_name, parameter, "", proto_name, message_name, temp_directory_);
+}
+
+void CommandLineInterfaceTest::ExpectGenerated(
+ const string& generator_name,
+ const string& parameter,
+ const string& proto_name,
const string& message_name,
- const string& output_file_prefix) {
- // Open and read the file.
- string output_file = output_file_prefix + "." + proto_name;
- string file_contents;
- ASSERT_TRUE(File::ReadFileToString(temp_directory_ + "/" + output_file,
- &file_contents))
- << "Failed to open file: " + output_file;
+ const string& output_directory) {
+ MockCodeGenerator::ExpectGenerated(
+ generator_name, parameter, "", proto_name, message_name,
+ temp_directory_ + "/" + output_directory);
+}
- // Check that the contents are as we expect.
- string expected_contents =
- generator_name + ": " + parameter + ", " + proto_name + ", " +
- message_name + "\n";
- EXPECT_EQ(expected_contents, file_contents)
- << "Output file did not have expected contents: " + output_file;
+void CommandLineInterfaceTest::ExpectGeneratedWithInsertions(
+ const string& generator_name,
+ const string& parameter,
+ const string& insertions,
+ const string& proto_name,
+ const string& message_name) {
+ MockCodeGenerator::ExpectGenerated(
+ generator_name, parameter, insertions, proto_name, message_name,
+ temp_directory_);
}
void CommandLineInterfaceTest::ReadDescriptorSet(
@@ -383,77 +352,52 @@ void CommandLineInterfaceTest::ReadDescriptorSet(
// ===================================================================
-CommandLineInterfaceTest::MockCodeGenerator::MockCodeGenerator(
- const string& name, const string& filename_prefix)
- : name_(name),
- filename_prefix_(filename_prefix),
- return_error_(false),
- expect_write_error_(false) {
-}
-
-CommandLineInterfaceTest::MockCodeGenerator::MockCodeGenerator(
- const string& name, const string& filename_prefix, const string& error)
- : name_(name),
- filename_prefix_(filename_prefix),
- return_error_(true),
- error_(error),
- expect_write_error_(false) {
-}
+TEST_F(CommandLineInterfaceTest, BasicOutput) {
+ // Test that the common case works.
-CommandLineInterfaceTest::MockCodeGenerator::~MockCodeGenerator() {}
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
-bool CommandLineInterfaceTest::MockCodeGenerator::Generate(
- const FileDescriptor* file,
- const string& parameter,
- OutputDirectory* output_directory,
- string* error) const {
- scoped_ptr<io::ZeroCopyOutputStream> output(
- output_directory->Open(filename_prefix_ + "." + file->name()));
- io::Printer printer(output.get(), '$');
- map<string, string> vars;
- vars["name"] = name_;
- vars["parameter"] = parameter;
- vars["proto_name"] = file->name();
- vars["message_name"] = file->message_type_count() > 0 ?
- file->message_type(0)->full_name().c_str() : "(none)";
-
- printer.Print(vars, "$name$: $parameter$, $proto_name$, $message_name$\n");
-
- if (expect_write_error_) {
- EXPECT_TRUE(printer.failed());
- } else {
- EXPECT_FALSE(printer.failed());
- }
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir foo.proto");
- *error = error_;
- return !return_error_;
+ ExpectNoErrors();
+ ExpectGenerated("test_generator", "", "foo.proto", "Foo");
}
-// ===================================================================
+TEST_F(CommandLineInterfaceTest, BasicPlugin) {
+ // Test that basic plugins work.
-TEST_F(CommandLineInterfaceTest, BasicOutput) {
- // Test that the common case works.
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
- RegisterGenerator("test_generator", "--test_out",
- "output.test", "Test output.");
+ Run("protocol_compiler --plug_out=$tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectNoErrors();
+ ExpectGenerated("test_plugin", "", "foo.proto", "Foo");
+}
+
+TEST_F(CommandLineInterfaceTest, GeneratorAndPlugin) {
+ // Invoke a generator and a plugin at the same time.
CreateTempFile("foo.proto",
"syntax = \"proto2\";\n"
"message Foo {}\n");
- Run("protocol_compiler --test_out=$tmpdir "
+ Run("protocol_compiler --test_out=$tmpdir --plug_out=$tmpdir "
"--proto_path=$tmpdir foo.proto");
ExpectNoErrors();
- ExpectGenerated("test_generator", "", "foo.proto", "Foo", "output.test");
+ ExpectGenerated("test_generator", "", "foo.proto", "Foo");
+ ExpectGenerated("test_plugin", "", "foo.proto", "Foo");
}
TEST_F(CommandLineInterfaceTest, MultipleInputs) {
// Test parsing multiple input files.
- RegisterGenerator("test_generator", "--test_out",
- "output.test", "Test output.");
-
CreateTempFile("foo.proto",
"syntax = \"proto2\";\n"
"message Foo {}\n");
@@ -461,48 +405,68 @@ TEST_F(CommandLineInterfaceTest, MultipleInputs) {
"syntax = \"proto2\";\n"
"message Bar {}\n");
- Run("protocol_compiler --test_out=$tmpdir "
+ Run("protocol_compiler --test_out=$tmpdir --plug_out=$tmpdir "
"--proto_path=$tmpdir foo.proto bar.proto");
ExpectNoErrors();
- ExpectGenerated("test_generator", "", "foo.proto", "Foo", "output.test");
- ExpectGenerated("test_generator", "", "bar.proto", "Bar", "output.test");
+ ExpectGenerated("test_generator", "", "foo.proto", "Foo");
+ ExpectGenerated("test_generator", "", "bar.proto", "Bar");
}
TEST_F(CommandLineInterfaceTest, CreateDirectory) {
// Test that when we output to a sub-directory, it is created.
- RegisterGenerator("test_generator", "--test_out",
- "bar/baz/output.test", "Test output.");
-
- CreateTempFile("foo.proto",
+ CreateTempFile("bar/baz/foo.proto",
"syntax = \"proto2\";\n"
"message Foo {}\n");
+ CreateTempDir("out");
+ CreateTempDir("plugout");
- Run("protocol_compiler --test_out=$tmpdir "
- "--proto_path=$tmpdir foo.proto");
+ Run("protocol_compiler --test_out=$tmpdir/out --plug_out=$tmpdir/plugout "
+ "--proto_path=$tmpdir bar/baz/foo.proto");
ExpectNoErrors();
- ExpectGenerated("test_generator", "",
- "foo.proto", "Foo", "bar/baz/output.test");
+ ExpectGenerated("test_generator", "", "bar/baz/foo.proto", "Foo", "out");
+ ExpectGenerated("test_plugin", "", "bar/baz/foo.proto", "Foo", "plugout");
}
TEST_F(CommandLineInterfaceTest, GeneratorParameters) {
// Test that generator parameters are correctly parsed from the command line.
- RegisterGenerator("test_generator", "--test_out",
- "output.test", "Test output.");
-
CreateTempFile("foo.proto",
"syntax = \"proto2\";\n"
"message Foo {}\n");
Run("protocol_compiler --test_out=TestParameter:$tmpdir "
+ "--plug_out=TestPluginParameter:$tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectNoErrors();
+ ExpectGenerated("test_generator", "TestParameter", "foo.proto", "Foo");
+ ExpectGenerated("test_plugin", "TestPluginParameter", "foo.proto", "Foo");
+}
+
+TEST_F(CommandLineInterfaceTest, Insert) {
+ // Test running a generator that inserts code into another's output.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\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();
- ExpectGenerated("test_generator", "TestParameter",
- "foo.proto", "Foo", "output.test");
+ ExpectGeneratedWithInsertions(
+ "test_generator", "TestParameter", "test_generator,test_plugin",
+ "foo.proto", "Foo");
+ ExpectGeneratedWithInsertions(
+ "test_plugin", "TestPluginParameter", "test_generator,test_plugin",
+ "foo.proto", "Foo");
}
#if defined(_WIN32) || defined(__CYGWIN__)
@@ -510,12 +474,10 @@ TEST_F(CommandLineInterfaceTest, GeneratorParameters) {
TEST_F(CommandLineInterfaceTest, WindowsOutputPath) {
// Test that the output path can be a Windows-style path.
- NullCodeGenerator* generator = RegisterNullGenerator("--test_out");
-
CreateTempFile("foo.proto",
"syntax = \"proto2\";\n");
- Run("protocol_compiler --test_out=C:\\ "
+ Run("protocol_compiler --null_out=C:\\ "
"--proto_path=$tmpdir foo.proto");
ExpectNoErrors();
@@ -526,12 +488,10 @@ TEST_F(CommandLineInterfaceTest, WindowsOutputPath) {
TEST_F(CommandLineInterfaceTest, WindowsOutputPathAndParameter) {
// Test that we can have a windows-style output path and a parameter.
- NullCodeGenerator* generator = RegisterNullGenerator("--test_out");
-
CreateTempFile("foo.proto",
"syntax = \"proto2\";\n");
- Run("protocol_compiler --test_out=bar:C:\\ "
+ Run("protocol_compiler --null_out=bar:C:\\ "
"--proto_path=$tmpdir foo.proto");
ExpectNoErrors();
@@ -543,9 +503,6 @@ TEST_F(CommandLineInterfaceTest, TrailingBackslash) {
// Test that the directories can end in backslashes. Some users claim this
// doesn't work on their system.
- RegisterGenerator("test_generator", "--test_out",
- "output.test", "Test output.");
-
CreateTempFile("foo.proto",
"syntax = \"proto2\";\n"
"message Foo {}\n");
@@ -554,7 +511,7 @@ TEST_F(CommandLineInterfaceTest, TrailingBackslash) {
"--proto_path=$tmpdir\\ foo.proto");
ExpectNoErrors();
- ExpectGenerated("test_generator", "", "foo.proto", "Foo", "output.test");
+ ExpectGenerated("test_generator", "", "foo.proto", "Foo");
}
#endif // defined(_WIN32) || defined(__CYGWIN__)
@@ -562,9 +519,6 @@ TEST_F(CommandLineInterfaceTest, TrailingBackslash) {
TEST_F(CommandLineInterfaceTest, PathLookup) {
// Test that specifying multiple directories in the proto search path works.
- RegisterGenerator("test_generator", "--test_out",
- "output.test", "Test output.");
-
CreateTempFile("b/bar.proto",
"syntax = \"proto2\";\n"
"message Bar {}\n");
@@ -580,15 +534,12 @@ TEST_F(CommandLineInterfaceTest, PathLookup) {
"--proto_path=$tmpdir/a --proto_path=$tmpdir/b foo.proto");
ExpectNoErrors();
- ExpectGenerated("test_generator", "", "foo.proto", "Foo", "output.test");
+ ExpectGenerated("test_generator", "", "foo.proto", "Foo");
}
TEST_F(CommandLineInterfaceTest, ColonDelimitedPath) {
// Same as PathLookup, but we provide the proto_path in a single flag.
- RegisterGenerator("test_generator", "--test_out",
- "output.test", "Test output.");
-
CreateTempFile("b/bar.proto",
"syntax = \"proto2\";\n"
"message Bar {}\n");
@@ -613,15 +564,12 @@ TEST_F(CommandLineInterfaceTest, ColonDelimitedPath) {
#undef PATH_SEPARATOR
ExpectNoErrors();
- ExpectGenerated("test_generator", "", "foo.proto", "Foo", "output.test");
+ ExpectGenerated("test_generator", "", "foo.proto", "Foo");
}
TEST_F(CommandLineInterfaceTest, NonRootMapping) {
// Test setting up a search path mapping a directory to a non-root location.
- RegisterGenerator("test_generator", "--test_out",
- "output.test", "Test output.");
-
CreateTempFile("foo.proto",
"syntax = \"proto2\";\n"
"message Foo {}\n");
@@ -630,42 +578,34 @@ TEST_F(CommandLineInterfaceTest, NonRootMapping) {
"--proto_path=bar=$tmpdir bar/foo.proto");
ExpectNoErrors();
- ExpectGenerated("test_generator", "", "bar/foo.proto", "Foo", "output.test");
+ ExpectGenerated("test_generator", "", "bar/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.
- RegisterGenerator("test_generator_1", "--test1_out",
- "output1.test", "Test output 1.");
- RegisterGenerator("test_generator_2", "--test2_out",
- "output2.test", "Test output 2.");
-
CreateTempFile("foo.proto",
"syntax = \"proto2\";\n"
"message Foo {}\n");
// Create the "a" and "b" sub-directories.
- CreateTempFile("a/dummy", "");
- CreateTempFile("b/dummy", "");
+ CreateTempDir("a");
+ CreateTempDir("b");
Run("protocol_compiler "
- "--test1_out=$tmpdir/a "
- "--test2_out=$tmpdir/b "
+ "--test_out=$tmpdir/a "
+ "--alt_out=$tmpdir/b "
"--proto_path=$tmpdir foo.proto");
ExpectNoErrors();
- ExpectGenerated("test_generator_1", "", "foo.proto", "Foo", "a/output1.test");
- ExpectGenerated("test_generator_2", "", "foo.proto", "Foo", "b/output2.test");
+ ExpectGenerated("test_generator", "", "foo.proto", "Foo", "a");
+ ExpectGenerated("alt_generator", "", "foo.proto", "Foo", "b");
}
TEST_F(CommandLineInterfaceTest, DisallowServicesNoServices) {
// Test that --disallow_services doesn't cause a problem when there are no
// services.
- RegisterGenerator("test_generator", "--test_out",
- "output.test", "Test output.");
-
CreateTempFile("foo.proto",
"syntax = \"proto2\";\n"
"message Foo {}\n");
@@ -674,15 +614,12 @@ TEST_F(CommandLineInterfaceTest, DisallowServicesNoServices) {
"--proto_path=$tmpdir foo.proto");
ExpectNoErrors();
- ExpectGenerated("test_generator", "", "foo.proto", "Foo", "output.test");
+ ExpectGenerated("test_generator", "", "foo.proto", "Foo");
}
TEST_F(CommandLineInterfaceTest, DisallowServicesHasService) {
// Test that --disallow_services produces an error when there are services.
- RegisterGenerator("test_generator", "--test_out",
- "output.test", "Test output.");
-
CreateTempFile("foo.proto",
"syntax = \"proto2\";\n"
"message Foo {}\n"
@@ -697,9 +634,6 @@ TEST_F(CommandLineInterfaceTest, DisallowServicesHasService) {
TEST_F(CommandLineInterfaceTest, AllowServicesHasService) {
// Test that services work fine as long as --disallow_services is not used.
- RegisterGenerator("test_generator", "--test_out",
- "output.test", "Test output.");
-
CreateTempFile("foo.proto",
"syntax = \"proto2\";\n"
"message Foo {}\n"
@@ -709,7 +643,7 @@ TEST_F(CommandLineInterfaceTest, AllowServicesHasService) {
"--proto_path=$tmpdir foo.proto");
ExpectNoErrors();
- ExpectGenerated("test_generator", "", "foo.proto", "Foo", "output.test");
+ ExpectGenerated("test_generator", "", "foo.proto", "Foo");
}
TEST_F(CommandLineInterfaceTest, CwdRelativeInputs) {
@@ -717,9 +651,6 @@ TEST_F(CommandLineInterfaceTest, CwdRelativeInputs) {
SetInputsAreProtoPathRelative(false);
- RegisterGenerator("test_generator", "--test_out",
- "output.test", "Test output.");
-
CreateTempFile("foo.proto",
"syntax = \"proto2\";\n"
"message Foo {}\n");
@@ -728,7 +659,7 @@ TEST_F(CommandLineInterfaceTest, CwdRelativeInputs) {
"--proto_path=$tmpdir $tmpdir/foo.proto");
ExpectNoErrors();
- ExpectGenerated("test_generator", "", "foo.proto", "Foo", "output.test");
+ ExpectGenerated("test_generator", "", "foo.proto", "Foo");
}
TEST_F(CommandLineInterfaceTest, WriteDescriptorSet) {
@@ -787,9 +718,6 @@ TEST_F(CommandLineInterfaceTest, WriteTransitiveDescriptorSet) {
TEST_F(CommandLineInterfaceTest, ParseErrors) {
// Test that parse errors are reported.
- RegisterGenerator("test_generator", "--test_out",
- "output.test", "Test output.");
-
CreateTempFile("foo.proto",
"syntax = \"proto2\";\n"
"badsyntax\n");
@@ -804,9 +732,6 @@ TEST_F(CommandLineInterfaceTest, ParseErrors) {
TEST_F(CommandLineInterfaceTest, ParseErrorsMultipleFiles) {
// Test that parse errors are reported from multiple files.
- RegisterGenerator("test_generator", "--test_out",
- "output.test", "Test output.");
-
// We set up files such that foo.proto actually depends on bar.proto in
// two ways: Directly and through baz.proto. bar.proto's errors should
// only be reported once.
@@ -834,9 +759,6 @@ TEST_F(CommandLineInterfaceTest, ParseErrorsMultipleFiles) {
TEST_F(CommandLineInterfaceTest, InputNotFoundError) {
// Test what happens if the input file is not found.
- RegisterGenerator("test_generator", "--test_out",
- "output.test", "Test output.");
-
Run("protocol_compiler --test_out=$tmpdir "
"--proto_path=$tmpdir foo.proto");
@@ -850,9 +772,6 @@ TEST_F(CommandLineInterfaceTest, CwdRelativeInputNotFoundError) {
SetInputsAreProtoPathRelative(false);
- RegisterGenerator("test_generator", "--test_out",
- "output.test", "Test output.");
-
Run("protocol_compiler --test_out=$tmpdir "
"--proto_path=$tmpdir $tmpdir/foo.proto");
@@ -866,9 +785,6 @@ TEST_F(CommandLineInterfaceTest, CwdRelativeInputNotMappedError) {
SetInputsAreProtoPathRelative(false);
- RegisterGenerator("test_generator", "--test_out",
- "output.test", "Test output.");
-
CreateTempFile("foo.proto",
"syntax = \"proto2\";\n"
"message Foo {}\n");
@@ -895,9 +811,6 @@ TEST_F(CommandLineInterfaceTest, CwdRelativeInputNotFoundAndNotMappedError) {
SetInputsAreProtoPathRelative(false);
- RegisterGenerator("test_generator", "--test_out",
- "output.test", "Test output.");
-
// Create a directory called "bar" so that we can point --proto_path at it.
CreateTempFile("bar/dummy", "");
@@ -914,9 +827,6 @@ TEST_F(CommandLineInterfaceTest, CwdRelativeInputShadowedError) {
SetInputsAreProtoPathRelative(false);
- RegisterGenerator("test_generator", "--test_out",
- "output.test", "Test output.");
-
CreateTempFile("foo/foo.proto",
"syntax = \"proto2\";\n"
"message Foo {}\n");
@@ -938,9 +848,6 @@ TEST_F(CommandLineInterfaceTest, CwdRelativeInputShadowedError) {
TEST_F(CommandLineInterfaceTest, ProtoPathNotFoundError) {
// Test what happens if the input file is not found.
- RegisterGenerator("test_generator", "--test_out",
- "output.test", "Test output.");
-
Run("protocol_compiler --test_out=$tmpdir "
"--proto_path=$tmpdir/foo foo.proto");
@@ -952,9 +859,6 @@ TEST_F(CommandLineInterfaceTest, ProtoPathNotFoundError) {
TEST_F(CommandLineInterfaceTest, MissingInputError) {
// Test that we get an error if no inputs are given.
- RegisterGenerator("test_generator", "--test_out",
- "output.test", "Test output.");
-
Run("protocol_compiler --test_out=$tmpdir "
"--proto_path=$tmpdir");
@@ -962,9 +866,6 @@ TEST_F(CommandLineInterfaceTest, MissingInputError) {
}
TEST_F(CommandLineInterfaceTest, MissingOutputError) {
- RegisterGenerator("test_generator", "--test_out",
- "output.test", "Test output.");
-
CreateTempFile("foo.proto",
"syntax = \"proto2\";\n"
"message Foo {}\n");
@@ -975,35 +876,56 @@ TEST_F(CommandLineInterfaceTest, MissingOutputError) {
}
TEST_F(CommandLineInterfaceTest, OutputWriteError) {
- MockCodeGenerator* generator =
- RegisterGenerator("test_generator", "--test_out",
- "output.test", "Test output.");
- generator->set_expect_write_error(true);
-
CreateTempFile("foo.proto",
"syntax = \"proto2\";\n"
"message Foo {}\n");
+ string output_file =
+ MockCodeGenerator::GetOutputFileName("test_generator", "foo.proto");
+
// Create a directory blocking our output location.
- CreateTempFile("output.test.foo.proto/foo", "");
+ CreateTempDir(output_file);
Run("protocol_compiler --test_out=$tmpdir "
"--proto_path=$tmpdir foo.proto");
+ ExpectErrorSubstring("MockCodeGenerator detected write error.");
+
#if defined(_WIN32) && !defined(__CYGWIN__)
// Windows with MSVCRT.dll produces EPERM instead of EISDIR.
- if (HasAlternateErrorSubstring("output.test.foo.proto: Permission denied")) {
+ if (HasAlternateErrorSubstring(output_file + ": Permission denied")) {
return;
}
#endif
- ExpectErrorSubstring("output.test.foo.proto: Is a directory");
+ ExpectErrorSubstring(output_file + ": Is a directory");
}
-TEST_F(CommandLineInterfaceTest, OutputDirectoryNotFoundError) {
- RegisterGenerator("test_generator", "--test_out",
- "output.test", "Test output.");
+TEST_F(CommandLineInterfaceTest, PluginOutputWriteError) {
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ string output_file =
+ MockCodeGenerator::GetOutputFileName("test_plugin", "foo.proto");
+
+ // Create a directory blocking our output location.
+ CreateTempDir(output_file);
+
+ Run("protocol_compiler --plug_out=$tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ // Windows with MSVCRT.dll produces EPERM instead of EISDIR.
+ if (HasAlternateErrorSubstring(output_file + ": Permission denied")) {
+ return;
+ }
+#endif
+
+ ExpectErrorSubstring(output_file + ": Is a directory");
+}
+TEST_F(CommandLineInterfaceTest, OutputDirectoryNotFoundError) {
CreateTempFile("foo.proto",
"syntax = \"proto2\";\n"
"message Foo {}\n");
@@ -1011,14 +933,21 @@ TEST_F(CommandLineInterfaceTest, OutputDirectoryNotFoundError) {
Run("protocol_compiler --test_out=$tmpdir/nosuchdir "
"--proto_path=$tmpdir foo.proto");
- ExpectErrorSubstring("nosuchdir/: "
- "No such file or directory");
+ ExpectErrorSubstring("nosuchdir/: No such file or directory");
}
-TEST_F(CommandLineInterfaceTest, OutputDirectoryIsFileError) {
- RegisterGenerator("test_generator", "--test_out",
- "output.test", "Test output.");
+TEST_F(CommandLineInterfaceTest, PluginOutputDirectoryNotFoundError) {
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+ Run("protocol_compiler --plug_out=$tmpdir/nosuchdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectErrorSubstring("nosuchdir/: No such file or directory");
+}
+
+TEST_F(CommandLineInterfaceTest, OutputDirectoryIsFileError) {
CreateTempFile("foo.proto",
"syntax = \"proto2\";\n"
"message Foo {}\n");
@@ -1037,45 +966,109 @@ TEST_F(CommandLineInterfaceTest, OutputDirectoryIsFileError) {
}
TEST_F(CommandLineInterfaceTest, GeneratorError) {
- RegisterErrorGenerator("error_generator", "Test error message.",
- "--error_out", "output.test", "Test error output.");
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message MockCodeGenerator_Error {}\n");
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectErrorSubstring(
+ "--test_out: foo.proto: Saw message type MockCodeGenerator_Error.");
+}
+
+TEST_F(CommandLineInterfaceTest, GeneratorPluginError) {
+ // Test a generator plugin that returns an error.
CreateTempFile("foo.proto",
"syntax = \"proto2\";\n"
- "message Foo {}\n");
+ "message MockCodeGenerator_Error {}\n");
- Run("protocol_compiler --error_out=$tmpdir "
+ Run("protocol_compiler --plug_out=TestParameter:$tmpdir "
"--proto_path=$tmpdir foo.proto");
- ExpectErrorSubstring("--error_out: Test error message.");
+ ExpectErrorSubstring(
+ "--plug_out: foo.proto: Saw message type MockCodeGenerator_Error.");
}
-TEST_F(CommandLineInterfaceTest, HelpText) {
- RegisterGenerator("test_generator", "--test_out",
- "output.test", "Test output.");
- RegisterErrorGenerator("error_generator", "Test error message.",
- "--error_out", "output.test", "Test error output.");
+TEST_F(CommandLineInterfaceTest, GeneratorPluginFail) {
+ // Test a generator plugin that exits with an error code.
CreateTempFile("foo.proto",
"syntax = \"proto2\";\n"
+ "message MockCodeGenerator_Exit {}\n");
+
+ Run("protocol_compiler --plug_out=TestParameter:$tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectErrorSubstring("Saw message type MockCodeGenerator_Exit.");
+ ExpectErrorSubstring(
+ "--plug_out: prefix-gen-plug: Plugin failed with status code 123.");
+}
+
+TEST_F(CommandLineInterfaceTest, GeneratorPluginCrash) {
+ // Test a generator plugin that crashes.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message MockCodeGenerator_Abort {}\n");
+
+ Run("protocol_compiler --plug_out=TestParameter:$tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectErrorSubstring("Saw message type MockCodeGenerator_Abort.");
+
+ // Don't depend on the exact signal number.
+ ExpectErrorSubstring(
+ "--plug_out: prefix-gen-plug: Plugin killed by signal");
+}
+
+TEST_F(CommandLineInterfaceTest, GeneratorPluginNotFound) {
+ // Test what happens if the plugin isn't found.
+
+ CreateTempFile("error.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ Run("protocol_compiler --badplug_out=TestParameter:$tmpdir "
+ "--plugin=prefix-gen-badplug=no_such_file "
+ "--proto_path=$tmpdir error.proto");
+
+ ExpectErrorSubstring(
+ "no_such_file: program not found or is not executable");
+
+ ExpectErrorSubstring(
+ "--badplug_out: prefix-gen-badplug: Plugin failed with status code 1.");
+}
+
+TEST_F(CommandLineInterfaceTest, GeneratorPluginNotAllowed) {
+ // Test what happens if plugins aren't allowed.
+
+ CreateTempFile("error.proto",
+ "syntax = \"proto2\";\n"
"message Foo {}\n");
+ DisallowPlugins();
+ Run("protocol_compiler --plug_out=TestParameter:$tmpdir "
+ "--proto_path=$tmpdir error.proto");
+
+ ExpectErrorSubstring("Unknown flag: --plug_out");
+}
+
+TEST_F(CommandLineInterfaceTest, HelpText) {
Run("test_exec_name --help");
ExpectErrorSubstring("Usage: test_exec_name ");
ExpectErrorSubstring("--test_out=OUT_DIR");
ExpectErrorSubstring("Test output.");
- ExpectErrorSubstring("--error_out=OUT_DIR");
- ExpectErrorSubstring("Test error output.");
+ ExpectErrorSubstring("--alt_out=OUT_DIR");
+ ExpectErrorSubstring("Alt output.");
}
TEST_F(CommandLineInterfaceTest, GccFormatErrors) {
// Test --error_format=gcc (which is the default, but we want to verify
// that it can be set explicitly).
- RegisterGenerator("test_generator", "--test_out",
- "output.test", "Test output.");
-
CreateTempFile("foo.proto",
"syntax = \"proto2\";\n"
"badsyntax\n");
@@ -1090,9 +1083,6 @@ TEST_F(CommandLineInterfaceTest, GccFormatErrors) {
TEST_F(CommandLineInterfaceTest, MsvsFormatErrors) {
// Test --error_format=msvs
- RegisterGenerator("test_generator", "--test_out",
- "output.test", "Test output.");
-
CreateTempFile("foo.proto",
"syntax = \"proto2\";\n"
"badsyntax\n");
@@ -1108,9 +1098,6 @@ TEST_F(CommandLineInterfaceTest, MsvsFormatErrors) {
TEST_F(CommandLineInterfaceTest, InvalidErrorFormat) {
// Test --error_format=msvs
- RegisterGenerator("test_generator", "--test_out",
- "output.test", "Test output.");
-
CreateTempFile("foo.proto",
"syntax = \"proto2\";\n"
"badsyntax\n");
@@ -1128,9 +1115,6 @@ TEST_F(CommandLineInterfaceTest, InvalidErrorFormat) {
TEST_F(CommandLineInterfaceTest, ParseSingleCharacterFlag) {
// Test that a single-character flag works.
- RegisterGenerator("test_generator", "-t",
- "output.test", "Test output.");
-
CreateTempFile("foo.proto",
"syntax = \"proto2\";\n"
"message Foo {}\n");
@@ -1139,15 +1123,12 @@ TEST_F(CommandLineInterfaceTest, ParseSingleCharacterFlag) {
"--proto_path=$tmpdir foo.proto");
ExpectNoErrors();
- ExpectGenerated("test_generator", "", "foo.proto", "Foo", "output.test");
+ ExpectGenerated("test_generator", "", "foo.proto", "Foo");
}
TEST_F(CommandLineInterfaceTest, ParseSpaceDelimitedValue) {
// Test that separating the flag value with a space works.
- RegisterGenerator("test_generator", "--test_out",
- "output.test", "Test output.");
-
CreateTempFile("foo.proto",
"syntax = \"proto2\";\n"
"message Foo {}\n");
@@ -1156,16 +1137,13 @@ TEST_F(CommandLineInterfaceTest, ParseSpaceDelimitedValue) {
"--proto_path=$tmpdir foo.proto");
ExpectNoErrors();
- ExpectGenerated("test_generator", "", "foo.proto", "Foo", "output.test");
+ ExpectGenerated("test_generator", "", "foo.proto", "Foo");
}
TEST_F(CommandLineInterfaceTest, ParseSingleCharacterSpaceDelimitedValue) {
// Test that separating the flag value with a space works for
// single-character flags.
- RegisterGenerator("test_generator", "-t",
- "output.test", "Test output.");
-
CreateTempFile("foo.proto",
"syntax = \"proto2\";\n"
"message Foo {}\n");
@@ -1174,15 +1152,12 @@ TEST_F(CommandLineInterfaceTest, ParseSingleCharacterSpaceDelimitedValue) {
"--proto_path=$tmpdir foo.proto");
ExpectNoErrors();
- ExpectGenerated("test_generator", "", "foo.proto", "Foo", "output.test");
+ ExpectGenerated("test_generator", "", "foo.proto", "Foo");
}
TEST_F(CommandLineInterfaceTest, MissingValueError) {
// Test that we get an error if a flag is missing its value.
- RegisterGenerator("test_generator", "--test_out",
- "output.test", "Test output.");
-
Run("protocol_compiler --test_out --proto_path=$tmpdir foo.proto");
ExpectErrorText("Missing value for flag: --test_out\n");
@@ -1192,9 +1167,6 @@ TEST_F(CommandLineInterfaceTest, MissingValueAtEndError) {
// Test that we get an error if the last argument is a flag requiring a
// value.
- RegisterGenerator("test_generator", "--test_out",
- "output.test", "Test output.");
-
Run("protocol_compiler --test_out");
ExpectErrorText("Missing value for flag: --test_out\n");