aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/google/protobuf/compiler/ruby/ruby_generated_code_pb.rb112
-rw-r--r--src/google/protobuf/compiler/ruby/ruby_generated_code_proto2.proto68
-rw-r--r--src/google/protobuf/compiler/ruby/ruby_generated_code_proto2_pb.rb77
-rw-r--r--src/google/protobuf/compiler/ruby/ruby_generator.cc139
-rw-r--r--src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc48
5 files changed, 363 insertions, 81 deletions
diff --git a/src/google/protobuf/compiler/ruby/ruby_generated_code_pb.rb b/src/google/protobuf/compiler/ruby/ruby_generated_code_pb.rb
index 49b23fbe..0c9ed6fb 100644
--- a/src/google/protobuf/compiler/ruby/ruby_generated_code_pb.rb
+++ b/src/google/protobuf/compiler/ruby/ruby_generated_code_pb.rb
@@ -4,62 +4,64 @@
require 'google/protobuf'
Google::Protobuf::DescriptorPool.generated_pool.build do
- add_message "A.B.C.TestMessage" do
- optional :optional_int32, :int32, 1
- optional :optional_int64, :int64, 2
- optional :optional_uint32, :uint32, 3
- optional :optional_uint64, :uint64, 4
- optional :optional_bool, :bool, 5
- optional :optional_double, :double, 6
- optional :optional_float, :float, 7
- optional :optional_string, :string, 8
- optional :optional_bytes, :bytes, 9
- optional :optional_enum, :enum, 10, "A.B.C.TestEnum"
- optional :optional_msg, :message, 11, "A.B.C.TestMessage"
- repeated :repeated_int32, :int32, 21
- repeated :repeated_int64, :int64, 22
- repeated :repeated_uint32, :uint32, 23
- repeated :repeated_uint64, :uint64, 24
- repeated :repeated_bool, :bool, 25
- repeated :repeated_double, :double, 26
- repeated :repeated_float, :float, 27
- repeated :repeated_string, :string, 28
- repeated :repeated_bytes, :bytes, 29
- repeated :repeated_enum, :enum, 30, "A.B.C.TestEnum"
- repeated :repeated_msg, :message, 31, "A.B.C.TestMessage"
- map :map_int32_string, :int32, :string, 61
- map :map_int64_string, :int64, :string, 62
- map :map_uint32_string, :uint32, :string, 63
- map :map_uint64_string, :uint64, :string, 64
- map :map_bool_string, :bool, :string, 65
- map :map_string_string, :string, :string, 66
- map :map_string_msg, :string, :message, 67, "A.B.C.TestMessage"
- map :map_string_enum, :string, :enum, 68, "A.B.C.TestEnum"
- map :map_string_int32, :string, :int32, 69
- map :map_string_bool, :string, :bool, 70
- optional :nested_message, :message, 80, "A.B.C.TestMessage.NestedMessage"
- oneof :my_oneof do
- optional :oneof_int32, :int32, 41
- optional :oneof_int64, :int64, 42
- optional :oneof_uint32, :uint32, 43
- optional :oneof_uint64, :uint64, 44
- optional :oneof_bool, :bool, 45
- optional :oneof_double, :double, 46
- optional :oneof_float, :float, 47
- optional :oneof_string, :string, 48
- optional :oneof_bytes, :bytes, 49
- optional :oneof_enum, :enum, 50, "A.B.C.TestEnum"
- optional :oneof_msg, :message, 51, "A.B.C.TestMessage"
+ add_file("ruby_generated_code.proto", :syntax => :proto3) do
+ add_message "A.B.C.TestMessage" do
+ optional :optional_int32, :int32, 1
+ optional :optional_int64, :int64, 2
+ optional :optional_uint32, :uint32, 3
+ optional :optional_uint64, :uint64, 4
+ optional :optional_bool, :bool, 5
+ optional :optional_double, :double, 6
+ optional :optional_float, :float, 7
+ optional :optional_string, :string, 8
+ optional :optional_bytes, :bytes, 9
+ optional :optional_enum, :enum, 10, "A.B.C.TestEnum"
+ optional :optional_msg, :message, 11, "A.B.C.TestMessage"
+ repeated :repeated_int32, :int32, 21
+ repeated :repeated_int64, :int64, 22
+ repeated :repeated_uint32, :uint32, 23
+ repeated :repeated_uint64, :uint64, 24
+ repeated :repeated_bool, :bool, 25
+ repeated :repeated_double, :double, 26
+ repeated :repeated_float, :float, 27
+ repeated :repeated_string, :string, 28
+ repeated :repeated_bytes, :bytes, 29
+ repeated :repeated_enum, :enum, 30, "A.B.C.TestEnum"
+ repeated :repeated_msg, :message, 31, "A.B.C.TestMessage"
+ map :map_int32_string, :int32, :string, 61
+ map :map_int64_string, :int64, :string, 62
+ map :map_uint32_string, :uint32, :string, 63
+ map :map_uint64_string, :uint64, :string, 64
+ map :map_bool_string, :bool, :string, 65
+ map :map_string_string, :string, :string, 66
+ map :map_string_msg, :string, :message, 67, "A.B.C.TestMessage"
+ map :map_string_enum, :string, :enum, 68, "A.B.C.TestEnum"
+ map :map_string_int32, :string, :int32, 69
+ map :map_string_bool, :string, :bool, 70
+ optional :nested_message, :message, 80, "A.B.C.TestMessage.NestedMessage"
+ oneof :my_oneof do
+ optional :oneof_int32, :int32, 41
+ optional :oneof_int64, :int64, 42
+ optional :oneof_uint32, :uint32, 43
+ optional :oneof_uint64, :uint64, 44
+ optional :oneof_bool, :bool, 45
+ optional :oneof_double, :double, 46
+ optional :oneof_float, :float, 47
+ optional :oneof_string, :string, 48
+ optional :oneof_bytes, :bytes, 49
+ optional :oneof_enum, :enum, 50, "A.B.C.TestEnum"
+ optional :oneof_msg, :message, 51, "A.B.C.TestMessage"
+ end
+ end
+ add_message "A.B.C.TestMessage.NestedMessage" do
+ optional :foo, :int32, 1
+ end
+ add_enum "A.B.C.TestEnum" do
+ value :Default, 0
+ value :A, 1
+ value :B, 2
+ value :C, 3
end
- end
- add_message "A.B.C.TestMessage.NestedMessage" do
- optional :foo, :int32, 1
- end
- add_enum "A.B.C.TestEnum" do
- value :Default, 0
- value :A, 1
- value :B, 2
- value :C, 3
end
end
diff --git a/src/google/protobuf/compiler/ruby/ruby_generated_code_proto2.proto b/src/google/protobuf/compiler/ruby/ruby_generated_code_proto2.proto
new file mode 100644
index 00000000..8d3cc13e
--- /dev/null
+++ b/src/google/protobuf/compiler/ruby/ruby_generated_code_proto2.proto
@@ -0,0 +1,68 @@
+syntax = "proto2";
+
+package A.B.C;
+
+message TestMessage {
+ optional int32 optional_int32 = 1 [default = 1];
+ optional int64 optional_int64 = 2 [default = 2];
+ optional uint32 optional_uint32 = 3 [default = 3];
+ optional uint64 optional_uint64 = 4 [default = 4];
+ optional bool optional_bool = 5 [default = true];
+ optional double optional_double = 6 [default = 6.0];
+ optional float optional_float = 7 [default = 7.0];
+ optional string optional_string = 8 [default = "default str"];
+ optional bytes optional_bytes = 9 [default = "\0\1\2\100fubar"];
+ optional TestEnum optional_enum = 10 [default = A];
+ optional TestMessage optional_msg = 11;
+
+ repeated int32 repeated_int32 = 21;
+ repeated int64 repeated_int64 = 22;
+ repeated uint32 repeated_uint32 = 23;
+ repeated uint64 repeated_uint64 = 24;
+ repeated bool repeated_bool = 25;
+ repeated double repeated_double = 26;
+ repeated float repeated_float = 27;
+ repeated string repeated_string = 28;
+ repeated bytes repeated_bytes = 29;
+ repeated TestEnum repeated_enum = 30;
+ repeated TestMessage repeated_msg = 31;
+
+ required int32 required_int32 = 41;
+ required int64 required_int64 = 42;
+ required uint32 required_uint32 = 43;
+ required uint64 required_uint64 = 44;
+ required bool required_bool = 45;
+ required double required_double = 46;
+ required float required_float = 47;
+ required string required_string = 48;
+ required bytes required_bytes = 49;
+ required TestEnum required_enum = 50;
+ required TestMessage required_msg = 51;
+
+ oneof my_oneof {
+ int32 oneof_int32 = 61;
+ int64 oneof_int64 = 62;
+ uint32 oneof_uint32 = 63;
+ uint64 oneof_uint64 = 64;
+ bool oneof_bool = 65;
+ double oneof_double = 66;
+ float oneof_float = 67;
+ string oneof_string = 68;
+ bytes oneof_bytes = 69;
+ TestEnum oneof_enum = 70;
+ TestMessage oneof_msg = 71;
+ }
+
+ message NestedMessage {
+ optional int32 foo = 1;
+ }
+
+ optional NestedMessage nested_message = 80;
+}
+
+enum TestEnum {
+ Default = 0;
+ A = 1;
+ B = 2;
+ C = 3;
+}
diff --git a/src/google/protobuf/compiler/ruby/ruby_generated_code_proto2_pb.rb b/src/google/protobuf/compiler/ruby/ruby_generated_code_proto2_pb.rb
new file mode 100644
index 00000000..15b340ad
--- /dev/null
+++ b/src/google/protobuf/compiler/ruby/ruby_generated_code_proto2_pb.rb
@@ -0,0 +1,77 @@
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# source: ruby_generated_code_proto2.proto
+
+require 'google/protobuf'
+
+Google::Protobuf::DescriptorPool.generated_pool.build do
+ add_file("ruby_generated_code_proto2.proto", :syntax => :proto2) do
+ add_message "A.B.C.TestMessage" do
+ optional :optional_int32, :int32, 1, default: 1
+ optional :optional_int64, :int64, 2, default: 2
+ optional :optional_uint32, :uint32, 3, default: 3
+ optional :optional_uint64, :uint64, 4, default: 4
+ optional :optional_bool, :bool, 5, default: true
+ optional :optional_double, :double, 6, default: 6
+ optional :optional_float, :float, 7, default: 7
+ optional :optional_string, :string, 8, default: "default str"
+ optional :optional_bytes, :bytes, 9, default: "\x00\x01\x02\x40\x66\x75\x62\x61\x72".force_encoding("ASCII-8BIT")
+ optional :optional_enum, :enum, 10, "A.B.C.TestEnum", default: 1
+ optional :optional_msg, :message, 11, "A.B.C.TestMessage"
+ repeated :repeated_int32, :int32, 21
+ repeated :repeated_int64, :int64, 22
+ repeated :repeated_uint32, :uint32, 23
+ repeated :repeated_uint64, :uint64, 24
+ repeated :repeated_bool, :bool, 25
+ repeated :repeated_double, :double, 26
+ repeated :repeated_float, :float, 27
+ repeated :repeated_string, :string, 28
+ repeated :repeated_bytes, :bytes, 29
+ repeated :repeated_enum, :enum, 30, "A.B.C.TestEnum"
+ repeated :repeated_msg, :message, 31, "A.B.C.TestMessage"
+ required :required_int32, :int32, 41
+ required :required_int64, :int64, 42
+ required :required_uint32, :uint32, 43
+ required :required_uint64, :uint64, 44
+ required :required_bool, :bool, 45
+ required :required_double, :double, 46
+ required :required_float, :float, 47
+ required :required_string, :string, 48
+ required :required_bytes, :bytes, 49
+ required :required_enum, :enum, 50, "A.B.C.TestEnum"
+ required :required_msg, :message, 51, "A.B.C.TestMessage"
+ optional :nested_message, :message, 80, "A.B.C.TestMessage.NestedMessage"
+ oneof :my_oneof do
+ optional :oneof_int32, :int32, 61
+ optional :oneof_int64, :int64, 62
+ optional :oneof_uint32, :uint32, 63
+ optional :oneof_uint64, :uint64, 64
+ optional :oneof_bool, :bool, 65
+ optional :oneof_double, :double, 66
+ optional :oneof_float, :float, 67
+ optional :oneof_string, :string, 68
+ optional :oneof_bytes, :bytes, 69
+ optional :oneof_enum, :enum, 70, "A.B.C.TestEnum"
+ optional :oneof_msg, :message, 71, "A.B.C.TestMessage"
+ end
+ end
+ add_message "A.B.C.TestMessage.NestedMessage" do
+ optional :foo, :int32, 1
+ end
+ add_enum "A.B.C.TestEnum" do
+ value :Default, 0
+ value :A, 1
+ value :B, 2
+ value :C, 3
+ end
+ end
+end
+
+module A
+ module B
+ module C
+ TestMessage = Google::Protobuf::DescriptorPool.generated_pool.lookup("A.B.C.TestMessage").msgclass
+ TestMessage::NestedMessage = Google::Protobuf::DescriptorPool.generated_pool.lookup("A.B.C.TestMessage.NestedMessage").msgclass
+ TestEnum = Google::Protobuf::DescriptorPool.generated_pool.lookup("A.B.C.TestEnum").enummodule
+ end
+ end
+end
diff --git a/src/google/protobuf/compiler/ruby/ruby_generator.cc b/src/google/protobuf/compiler/ruby/ruby_generator.cc
index bd737c02..6b9ea822 100644
--- a/src/google/protobuf/compiler/ruby/ruby_generator.cc
+++ b/src/google/protobuf/compiler/ruby/ruby_generator.cc
@@ -28,6 +28,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#include <iomanip>
#include <sstream>
#include <google/protobuf/compiler/code_generator.h>
@@ -45,12 +46,13 @@ namespace compiler {
namespace ruby {
// Forward decls.
-std::string IntToString(int32 value);
+template<class numeric_type> std::string NumberToString(numeric_type value);
std::string GetRequireName(const std::string& proto_file);
std::string LabelForField(google::protobuf::FieldDescriptor* field);
std::string TypeName(google::protobuf::FieldDescriptor* field);
-void GenerateMessage(const google::protobuf::Descriptor* message,
- google::protobuf::io::Printer* printer);
+bool GenerateMessage(const google::protobuf::Descriptor* message,
+ google::protobuf::io::Printer* printer,
+ std::string* error);
void GenerateEnum(const google::protobuf::EnumDescriptor* en,
google::protobuf::io::Printer* printer);
void GenerateMessageAssignment(
@@ -61,8 +63,11 @@ void GenerateEnumAssignment(
const std::string& prefix,
const google::protobuf::EnumDescriptor* en,
google::protobuf::io::Printer* printer);
-
-std::string IntToString(int32 value) {
+std::string DefaultValueForField(
+ const google::protobuf::FieldDescriptor* field);
+
+template<class numeric_type>
+std::string NumberToString(numeric_type value) {
std::ostringstream os;
os << value;
return os.str();
@@ -110,6 +115,62 @@ std::string TypeName(const google::protobuf::FieldDescriptor* field) {
}
}
+string StringifySyntax(FileDescriptor::Syntax syntax) {
+ switch (syntax) {
+ case FileDescriptor::SYNTAX_PROTO2:
+ return "proto2";
+ case FileDescriptor::SYNTAX_PROTO3:
+ return "proto3";
+ case FileDescriptor::SYNTAX_UNKNOWN:
+ default:
+ GOOGLE_LOG(FATAL) << "Unsupported syntax; this generator only supports "
+ "proto2 and proto3 syntax.";
+ return "";
+ }
+}
+
+std::string DefaultValueForField(const google::protobuf::FieldDescriptor* field) {
+ switch(field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ return NumberToString(field->default_value_int32());
+ case FieldDescriptor::CPPTYPE_INT64:
+ return NumberToString(field->default_value_int64());
+ case FieldDescriptor::CPPTYPE_UINT32:
+ return NumberToString(field->default_value_uint32());
+ case FieldDescriptor::CPPTYPE_UINT64:
+ return NumberToString(field->default_value_uint64());
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ return NumberToString(field->default_value_float());
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ return NumberToString(field->default_value_double());
+ case FieldDescriptor::CPPTYPE_BOOL:
+ return field->default_value_bool() ? "true" : "false";
+ case FieldDescriptor::CPPTYPE_ENUM:
+ return NumberToString(field->default_value_enum()->number());
+ case FieldDescriptor::CPPTYPE_STRING: {
+ std::ostringstream os;
+ string default_str = field->default_value_string();
+
+ if (field->type() == FieldDescriptor::TYPE_STRING) {
+ os << "\"" << default_str << "\"";
+ } else if (field->type() == FieldDescriptor::TYPE_BYTES) {
+ os << "\"";
+
+ os.fill('0');
+ for (int i = 0; i < default_str.length(); ++i) {
+ // Write the hex form of each byte.
+ os << "\\x" << std::hex << std::setw(2)
+ << ((uint16) ((unsigned char) default_str.at(i)));
+ }
+ os << "\".force_encoding(\"ASCII-8BIT\")";
+ }
+
+ return os.str();
+ }
+ default: assert(false); return "";
+ }
+}
+
void GenerateField(const google::protobuf::FieldDescriptor* field,
google::protobuf::io::Printer* printer) {
@@ -124,7 +185,7 @@ void GenerateField(const google::protobuf::FieldDescriptor* field,
"name", field->name(),
"key_type", TypeName(key_field),
"value_type", TypeName(value_field),
- "number", IntToString(field->number()));
+ "number", NumberToString(field->number()));
if (value_field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
printer->Print(
@@ -146,19 +207,25 @@ void GenerateField(const google::protobuf::FieldDescriptor* field,
printer->Print(
":$type$, $number$",
"type", TypeName(field),
- "number", IntToString(field->number()));
+ "number", NumberToString(field->number()));
if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
printer->Print(
- ", \"$subtype$\"\n",
+ ", \"$subtype$\"",
"subtype", field->message_type()->full_name());
} else if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
printer->Print(
- ", \"$subtype$\"\n",
+ ", \"$subtype$\"",
"subtype", field->enum_type()->full_name());
- } else {
- printer->Print("\n");
}
+
+ if (field->has_default_value()) {
+ printer->Print(
+ ", default: $default$",
+ "default", DefaultValueForField(field));
+ }
+
+ printer->Print("\n");
}
}
@@ -178,13 +245,18 @@ void GenerateOneof(const google::protobuf::OneofDescriptor* oneof,
printer->Print("end\n");
}
-void GenerateMessage(const google::protobuf::Descriptor* message,
- google::protobuf::io::Printer* printer) {
-
+bool GenerateMessage(const google::protobuf::Descriptor* message,
+ google::protobuf::io::Printer* printer,
+ std::string* error) {
+ if (message->extension_range_count() > 0 || message->extension_count() > 0) {
+ *error = "Extensions are not yet supported for proto2 .proto files.";
+ return false;
+ }
+
// Don't generate MapEntry messages -- we use the Ruby extension's native
// support for map fields instead.
if (message->options().map_entry()) {
- return;
+ return true;
}
printer->Print(
@@ -208,11 +280,15 @@ void GenerateMessage(const google::protobuf::Descriptor* message,
printer->Print("end\n");
for (int i = 0; i < message->nested_type_count(); i++) {
- GenerateMessage(message->nested_type(i), printer);
+ if (!GenerateMessage(message->nested_type(i), printer, error)) {
+ return false;
+ }
}
for (int i = 0; i < message->enum_type_count(); i++) {
GenerateEnum(message->enum_type(i), printer);
}
+
+ return true;
}
void GenerateEnum(const google::protobuf::EnumDescriptor* en,
@@ -227,7 +303,7 @@ void GenerateEnum(const google::protobuf::EnumDescriptor* en,
printer->Print(
"value :$name$, $number$\n",
"name", value->name(),
- "number", IntToString(value->number()));
+ "number", NumberToString(value->number()));
}
printer->Outdent();
@@ -423,7 +499,8 @@ bool MaybeEmitDependency(const FileDescriptor* import,
const FileDescriptor* from,
io::Printer* printer,
string* error) {
- if (import->syntax() == FileDescriptor::SYNTAX_PROTO2) {
+ if (from->syntax() == FileDescriptor::SYNTAX_PROTO3 &&
+ import->syntax() == FileDescriptor::SYNTAX_PROTO2) {
for (int i = 0; i < from->message_type_count(); i++) {
if (UsesTypeFromFile(from->message_type(i), import, error)) {
// Error text was already set by UsesTypeFromFile().
@@ -462,16 +539,29 @@ bool GenerateFile(const FileDescriptor* file, io::Printer* printer,
}
}
- printer->Print(
- "Google::Protobuf::DescriptorPool.generated_pool.build do\n");
+ // TODO: Remove this when ruby supports extensions for proto2 syntax.
+ if (file->extension_count() > 0) {
+ *error = "Extensions are not yet supported for proto2 .proto files.";
+ return false;
+ }
+
+ printer->Print("Google::Protobuf::DescriptorPool.generated_pool.build do\n");
+ printer->Indent();
+ printer->Print("add_file(\"$filename$\", :syntax => :$syntax$) do\n",
+ "filename", file->name(), "syntax",
+ StringifySyntax(file->syntax()));
printer->Indent();
for (int i = 0; i < file->message_type_count(); i++) {
- GenerateMessage(file->message_type(i), printer);
+ if (!GenerateMessage(file->message_type(i), printer, error)) {
+ return false;
+ }
}
for (int i = 0; i < file->enum_type_count(); i++) {
GenerateEnum(file->enum_type(i), printer);
}
printer->Outdent();
+ printer->Print("end\n");
+ printer->Outdent();
printer->Print(
"end\n\n");
@@ -492,10 +582,9 @@ bool Generator::Generate(
GeneratorContext* generator_context,
string* error) const {
- if (file->syntax() != FileDescriptor::SYNTAX_PROTO3) {
- *error =
- "Can only generate Ruby code for proto3 .proto files.\n"
- "Please add 'syntax = \"proto3\";' to the top of your .proto file.\n";
+ if (file->syntax() != FileDescriptor::SYNTAX_PROTO3 &&
+ file->syntax() != FileDescriptor::SYNTAX_PROTO2) {
+ *error = "Invalid or unsupported proto syntax";
return false;
}
diff --git a/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc b/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc
index 8454a5c5..2e9b2e12 100644
--- a/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc
+++ b/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc
@@ -56,7 +56,7 @@ string FindRubyTestDir() {
// Some day, we may integrate build systems between protoc and the language
// extensions to the point where we can do this test in a more automated way.
-TEST(RubyGeneratorTest, GeneratorTest) {
+TEST(RubyGeneratorTest, Proto3GeneratorTest) {
string ruby_tests = FindRubyTestDir();
google::protobuf::compiler::CommandLineInterface cli;
@@ -102,6 +102,52 @@ TEST(RubyGeneratorTest, GeneratorTest) {
EXPECT_EQ(expected_output, output);
}
+TEST(RubyGeneratorTest, Proto2GeneratorTest) {
+ string ruby_tests = FindRubyTestDir();
+
+ google::protobuf::compiler::CommandLineInterface cli;
+ cli.SetInputsAreProtoPathRelative(true);
+
+ ruby::Generator ruby_generator;
+ cli.RegisterGenerator("--ruby_out", &ruby_generator, "");
+
+ // Copy generated_code.proto to the temporary test directory.
+ string test_input;
+ GOOGLE_CHECK_OK(File::GetContents(
+ ruby_tests + "/ruby_generated_code_proto2.proto",
+ &test_input,
+ true));
+ GOOGLE_CHECK_OK(File::SetContents(
+ TestTempDir() + "/ruby_generated_code_proto2.proto",
+ test_input,
+ true));
+
+ // Invoke the proto compiler (we will be inside TestTempDir() at this point).
+ string ruby_out = "--ruby_out=" + TestTempDir();
+ string proto_path = "--proto_path=" + TestTempDir();
+ const char* argv[] = {
+ "protoc",
+ ruby_out.c_str(),
+ proto_path.c_str(),
+ "ruby_generated_code_proto2.proto",
+ };
+
+ EXPECT_EQ(0, cli.Run(4, argv));
+
+ // Load the generated output and compare to the expected result.
+ string output;
+ GOOGLE_CHECK_OK(File::GetContents(
+ TestTempDir() + "/ruby_generated_code_proto2_pb.rb",
+ &output,
+ true));
+ string expected_output;
+ GOOGLE_CHECK_OK(File::GetContents(
+ ruby_tests + "/ruby_generated_code_proto2_pb.rb",
+ &expected_output,
+ true));
+ EXPECT_EQ(expected_output, output);
+}
+
} // namespace
} // namespace ruby
} // namespace compiler