aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Daniel Neighman <dneighman@gmail.com>2017-12-04 17:51:44 -0800
committerGravatar Connor Jacobsen <jacobsen.connor@gmail.com>2018-03-26 16:00:05 -0700
commit8b7007ad7b99494d449b8345a2bf25461ea8ce3e (patch)
tree12f2de072bf45a6a8c4ad1cd32ed022eff32ec43
parent6fa206de8f8a1444fff19a84945a424c0cabb41c (diff)
Updates the ruby generator RubyAsType to correctly account for underscores in packages
Prior to this change, when the ruby generator tried to reference an entity that was not part of the same package (or a direct parent package) and the package contains underscores, the result would simply uppercase the first character. It should however uppercase each letter that proceeds an underscore and remove underscores. i.e. ``` package my_package.service; import "my_package/data.proto"; service MyService { rpc Test (data.Request) returns data.Response {} } ``` Was ```ruby # ... rpc :Test, My_package::Data::REquest, My_package::Data::Response # ... ``` Should be: ```ruby # ... rpc :Test, MyPackage::Data::REquest, My_package::Data::Response # ... ```
-rw-r--r--src/compiler/ruby_generator.cc2
-rw-r--r--src/compiler/ruby_generator_string-inl.h20
-rw-r--r--src/ruby/spec/pb/package_with_underscore/checker_spec.rb54
-rw-r--r--src/ruby/spec/pb/package_with_underscore/data.proto23
-rw-r--r--src/ruby/spec/pb/package_with_underscore/service.proto23
-rwxr-xr-xtools/run_tests/helper_scripts/run_ruby.sh3
6 files changed, 119 insertions, 6 deletions
diff --git a/src/compiler/ruby_generator.cc b/src/compiler/ruby_generator.cc
index e81dea603b..c7af9c38fa 100644
--- a/src/compiler/ruby_generator.cc
+++ b/src/compiler/ruby_generator.cc
@@ -73,7 +73,7 @@ void PrintService(const ServiceDescriptor* service, const grpc::string& package,
// Begin the service module
std::map<grpc::string, grpc::string> module_vars = ListToDict({
"module.name",
- CapitalizeFirst(service->name()),
+ Modularize(service->name()),
});
out->Print(module_vars, "module $module.name$\n");
out->Indent();
diff --git a/src/compiler/ruby_generator_string-inl.h b/src/compiler/ruby_generator_string-inl.h
index fb429784bb..ecfe796e7a 100644
--- a/src/compiler/ruby_generator_string-inl.h
+++ b/src/compiler/ruby_generator_string-inl.h
@@ -81,13 +81,23 @@ inline bool ReplacePrefix(grpc::string* s, const grpc::string& from,
return true;
}
-// CapitalizeFirst capitalizes the first char in a string.
-inline grpc::string CapitalizeFirst(grpc::string s) {
+// Modularize converts a string into a ruby module compatible name
+inline grpc::string Modularize(grpc::string s) {
if (s.empty()) {
return s;
}
- s[0] = ::toupper(s[0]);
- return s;
+ grpc::string new_string = "";
+ bool was_last_underscore = false;
+ new_string.append(1, ::toupper(s[0]));
+ for (grpc::string::size_type i = 1; i < s.size(); ++i) {
+ if (was_last_underscore && s[i] != '_') {
+ new_string.append(1, ::toupper(s[i]));
+ } else if (s[i] != '_') {
+ new_string.append(1, s[i]);
+ }
+ was_last_underscore = s[i] == '_';
+ }
+ return new_string;
}
// RubyTypeOf updates a proto type to the required ruby equivalent.
@@ -106,7 +116,7 @@ inline grpc::string RubyTypeOf(const grpc::string& a_type,
res += "::"; // switch '.' to the ruby module delim
}
if (i < prefixes_and_type.size() - 1) {
- res += CapitalizeFirst(prefixes_and_type[i]); // capitalize pkgs
+ res += Modularize(prefixes_and_type[i]); // capitalize pkgs
} else {
res += prefixes_and_type[i];
}
diff --git a/src/ruby/spec/pb/package_with_underscore/checker_spec.rb b/src/ruby/spec/pb/package_with_underscore/checker_spec.rb
new file mode 100644
index 0000000000..6155b3b934
--- /dev/null
+++ b/src/ruby/spec/pb/package_with_underscore/checker_spec.rb
@@ -0,0 +1,54 @@
+# Copyright 2016 gRPC authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+require 'open3'
+require 'tmpdir'
+
+def debug_mode?
+ !ENV['CONFIG'].nil? && ENV['CONFIG'] == 'dbg'
+end
+
+describe 'Package with underscore protobuf code generation' do
+ it 'should have the same content as created by code generation' do
+ root_dir = File.join(File.dirname(__FILE__), '..', '..', '..', '..', '..')
+ pb_dir = File.join(root_dir, 'src', 'ruby', 'spec', 'pb')
+
+ bins_sub_dir = debug_mode? ? 'dbg' : 'opt'
+ bins_dir = File.join(root_dir, 'bins', bins_sub_dir)
+
+ plugin = File.join(bins_dir, 'grpc_ruby_plugin')
+ protoc = File.join(bins_dir, 'protobuf', 'protoc')
+
+ got = nil
+
+ Dir.mktmpdir do |tmp_dir|
+ gen_out = File.join(tmp_dir, 'package_with_underscore', 'service_services_pb.rb')
+
+ pid = spawn(
+ protoc,
+ '-I.',
+ 'package_with_underscore/service.proto',
+ "--grpc_out=#{tmp_dir}",
+ "--plugin=protoc-gen-grpc=#{plugin}",
+ chdir: pb_dir)
+ Process.waitpid2(pid)
+ File.open(gen_out) { |f| got = f.read }
+ end
+
+ correct_modularized_rpc = 'rpc :TestOne, ' \
+ 'Grpc::Testing::PackageWithUnderscore::Data::Request, ' \
+ 'Grpc::Testing::PackageWithUnderscore::Data::Response'
+ expect(got).to include(correct_modularized_rpc)
+ end
+end
diff --git a/src/ruby/spec/pb/package_with_underscore/data.proto b/src/ruby/spec/pb/package_with_underscore/data.proto
new file mode 100644
index 0000000000..2706f1d7be
--- /dev/null
+++ b/src/ruby/spec/pb/package_with_underscore/data.proto
@@ -0,0 +1,23 @@
+// Copyright 2018 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+syntax = "proto3";
+
+package grpc.testing.package_with_underscore.data;
+
+message Request {
+}
+
+message Response {
+}
diff --git a/src/ruby/spec/pb/package_with_underscore/service.proto b/src/ruby/spec/pb/package_with_underscore/service.proto
new file mode 100644
index 0000000000..814c7898cd
--- /dev/null
+++ b/src/ruby/spec/pb/package_with_underscore/service.proto
@@ -0,0 +1,23 @@
+// Copyright 2018 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+syntax = "proto3";
+
+package grpc.testing.package_with_underscore.service;
+
+import "package_with_underscore/data.proto";
+
+service MyService {
+ rpc TestOne(data.Request) returns (data.Response) {}
+}
diff --git a/tools/run_tests/helper_scripts/run_ruby.sh b/tools/run_tests/helper_scripts/run_ruby.sh
index 4bd7d743c1..aefdc6fc61 100755
--- a/tools/run_tests/helper_scripts/run_ruby.sh
+++ b/tools/run_tests/helper_scripts/run_ruby.sh
@@ -18,4 +18,7 @@ set -ex
# change to grpc repo root
cd $(dirname $0)/../../..
+# build grpc_ruby_plugin
+make grpc_ruby_plugin -j8
+
rake