зеркало из https://github.com/arthurnn/twirp-ruby.git
merge from master and resolve conflicts. Add more tests in main_test.go
This commit is contained in:
Коммит
73ec3c3003
|
@ -2,7 +2,8 @@
|
|||
require 'twirp'
|
||||
require_relative 'service_pb.rb'
|
||||
|
||||
module Example::HelloWorld
|
||||
module Example
|
||||
module HelloWorld
|
||||
class HelloWorldService < Twirp::Service
|
||||
package 'example.hello_world'
|
||||
service 'HelloWorld'
|
||||
|
@ -13,3 +14,4 @@ module Example::HelloWorld
|
|||
client_for HelloWorldService
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -74,11 +74,12 @@ func (g *generator) generateRubyCode(file *descriptor.FileDescriptorProto, pbFil
|
|||
print(b, "require_relative '%s'", pbFileRelativePath) // require generated file with messages
|
||||
print(b, "")
|
||||
|
||||
indent := ""
|
||||
indent := indentation(0)
|
||||
pkgName := file.GetPackage()
|
||||
if pkgName != "" {
|
||||
print(b, "module %s", packageToRubyModule(pkgName))
|
||||
indent = indent + " "
|
||||
modules := packageToRubyModules(pkgName)
|
||||
for _, m := range modules {
|
||||
print(b, "%smodule %s", indent, m)
|
||||
indent += 1
|
||||
}
|
||||
|
||||
for i, service := range file.Service {
|
||||
|
@ -104,8 +105,10 @@ func (g *generator) generateRubyCode(file *descriptor.FileDescriptorProto, pbFil
|
|||
print(b, "")
|
||||
}
|
||||
}
|
||||
if pkgName != "" {
|
||||
print(b, "end")
|
||||
|
||||
for range modules {
|
||||
indent -= 1
|
||||
print(b, "%send", indent)
|
||||
}
|
||||
|
||||
return b.String()
|
||||
|
@ -125,6 +128,15 @@ func (g *generator) protoFilesToGenerate() []*descriptor.FileDescriptorProto {
|
|||
return files
|
||||
}
|
||||
|
||||
// indentation represents the level of Ruby indentation for a block of code. It
|
||||
// implements the fmt.Stringer interface to output the correct number of spaces
|
||||
// for the given level of indentation
|
||||
type indentation int
|
||||
|
||||
func (i indentation) String() string {
|
||||
return strings.Repeat(" ", int(i))
|
||||
}
|
||||
|
||||
func print(buf *bytes.Buffer, tpl string, args ...interface{}) {
|
||||
buf.WriteString(fmt.Sprintf(tpl, args...))
|
||||
buf.WriteByte('\n')
|
||||
|
@ -190,15 +202,14 @@ func writeGenResponse(w io.Writer, resp *plugin.CodeGeneratorResponse) {
|
|||
}
|
||||
}
|
||||
|
||||
// packageToModule converts a protobuf package like "my.cool.package" to a
|
||||
// Ruby module constant like "My::Cool::Package".
|
||||
func packageToRubyModule(pkgName string) string {
|
||||
pkgParts := strings.Split(pkgName, ".")
|
||||
modules := []string{}
|
||||
for _, p := range pkgParts {
|
||||
modules = append(modules, camelCase(p))
|
||||
// Modules converts protobuf package name to a list of Ruby module names to
|
||||
// represent it. e.g. packageToRubyModules("my.cool.package") => ["My", "Cool", "Package"]
|
||||
func packageToRubyModules(pkgName string) []string {
|
||||
parts := []string{}
|
||||
for _, p := range strings.Split(pkgName, ".") {
|
||||
parts = append(parts, camelCase(p))
|
||||
}
|
||||
return strings.Join(modules, "::")
|
||||
return parts
|
||||
}
|
||||
|
||||
// snakeCase converts a string from CamelCase to snake_case.
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestPrint(t *testing.T) {
|
||||
b := new(bytes.Buffer)
|
||||
print(b, "Hello World")
|
||||
print(b, "Hello %s %d", "My Friend", 999)
|
||||
actual := b.String()
|
||||
expected := "Hello World\nHello My Friend 999\n"
|
||||
if expected != actual {
|
||||
t.Errorf("Unexpected print: %v", actual)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilePathOnlyBaseNoExtension(t *testing.T) {
|
||||
tests := []struct {
|
||||
actual string
|
||||
expected string
|
||||
}{
|
||||
{noExtension("foo_bar.txt"), "foo_bar"},
|
||||
{noExtension("my/filename.txt"), "my/filename"},
|
||||
{onlyBase("foo_bar.txt"), "foo_bar.txt"},
|
||||
{onlyBase("/long/path/stuff/foo_bar.txt"), "foo_bar.txt"},
|
||||
{noExtension(onlyBase("/long/path/stuff/foo_bar.txt")), "foo_bar"},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
if tt.expected != tt.actual {
|
||||
t.Errorf("expected %v; actual %v", tt.expected, tt.actual)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPackageToRubyModules(t *testing.T) {
|
||||
tests := []struct {
|
||||
pkgName string
|
||||
expected []string
|
||||
}{
|
||||
{"example", []string{"Example"}},
|
||||
{"example.hello_world", []string{"Example", "HelloWorld"}},
|
||||
{"m.v.p", []string{"M", "V", "P"}},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
actual := packageToRubyModules(tt.pkgName)
|
||||
if !reflect.DeepEqual(actual, tt.expected) {
|
||||
t.Errorf("expected %v; actual %v", tt.expected, actual)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSnakeCase(t *testing.T) {
|
||||
tests := []struct {
|
||||
actual string
|
||||
expected string
|
||||
}{
|
||||
{snakeCase("foo_bar"), "foo_bar"},
|
||||
{snakeCase("FooBar"), "foo_bar"},
|
||||
{snakeCase("fooBar"), "foo_bar"},
|
||||
{snakeCase("myLong_miXEDName"), "my_long_mi_x_e_d_name"},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
if tt.expected != tt.actual {
|
||||
t.Errorf("expected %v; actual %v", tt.expected, tt.actual)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCamelCase(t *testing.T) {
|
||||
tests := []struct {
|
||||
actual string
|
||||
expected string
|
||||
}{
|
||||
{camelCase("foo_bar"), "FooBar"},
|
||||
{camelCase("FooBar"), "FooBar"},
|
||||
{camelCase("fooBar"), "FooBar"},
|
||||
{camelCase("myLong_miXEDName"), "MyLongMiXEDName"},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
if tt.expected != tt.actual {
|
||||
t.Errorf("expected %v; actual %v", tt.expected, tt.actual)
|
||||
}
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче