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
   # ...
```
pull/13634/head
Daniel Neighman 7 years ago committed by Connor Jacobsen
parent 6fa206de8f
commit 8b7007ad7b
  1. 2
      src/compiler/ruby_generator.cc
  2. 20
      src/compiler/ruby_generator_string-inl.h
  3. 54
      src/ruby/spec/pb/package_with_underscore/checker_spec.rb
  4. 23
      src/ruby/spec/pb/package_with_underscore/data.proto
  5. 23
      src/ruby/spec/pb/package_with_underscore/service.proto
  6. 3
      tools/run_tests/helper_scripts/run_ruby.sh

@ -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();

@ -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];
}

@ -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

@ -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 {
}

@ -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) {}
}

@ -18,4 +18,7 @@ set -ex
# change to grpc repo root
cd $(dirname $0)/../../..
# build grpc_ruby_plugin
make grpc_ruby_plugin -j8
rake

Loading…
Cancel
Save