Repository: googleapis/gapic-generator-go
Pull request #48 (2018-10-29 23:25:17)

sample: properly render samples for methods returning empty


Patch:
diff --git a/cmd/gen-go-sample/main.go b/cmd/gen-go-sample/main.go
index 829ce71..027f8c6 100644
--- a/cmd/gen-go-sample/main.go
+++ b/cmd/gen-go-sample/main.go
@@ -303,20 +303,20 @@ func (g *generator) genSample(ifaceName, methName, regTag string, valSet SampleV
 		}
 	}
 
-	switch pf, err2 := pagingField(g.descInfo, meth); {
-	case err2 != nil:
-		err = err2
-	case pf != nil:
-		err = g.paging(meth, pf, valSet)
-	case meth.GetServerStreaming() || meth.GetClientStreaming():
-		err = errors.E(nil, "streaming methods not supported yet")
-	case meth.GetOutputType() == ".google.protobuf.Empty":
-		err = errors.E(nil, "empty return type not supported yet")
-	case meth.GetOutputType() == ".google.protobuf.Operation":
+	if meth.GetOutputType() == ".google.protobuf.Empty" {
+		err = g.emptyOut(meth, valSet)
+	} else if meth.GetOutputType() == ".google.protobuf.Operation" {
 		err = errors.E(nil, "LRO not supported yet")
-	default:
+	} else if meth.GetServerStreaming() || meth.GetClientStreaming() {
+		err = errors.E(nil, "streaming methods not supported yet")
+	} else if pf, err2 := pagingField(g.descInfo, meth); err2 != nil {
+		err = errors.E(err2, "can't determine whether method is paging")
+	} else if pf != nil {
+		err = g.paging(meth, pf, valSet)
+	} else {
 		err = g.unary(meth, valSet)
 	}
+
 	if err != nil {
 		return err
 	}
@@ -371,7 +371,18 @@ func (g *generator) unary(meth *descriptor.MethodDescriptorProto, valSet SampleV
 	p("}")
 	p("")
 
-	return g.handleOut(meth, valSet, initType{desc: g.descInfo.Type[meth.GetOutputType()]})
+	return g.handleOut(meth, valSet, &initType{desc: g.descInfo.Type[meth.GetOutputType()]})
+}
+
+func (g *generator) emptyOut(meth *descriptor.MethodDescriptorProto, valSet SampleValueSet) error {
+	p := g.pt.Printf
+
+	p("if err := c.%s(ctx, req); err != nil {", meth.GetName())
+	p("  return err")
+	p("}")
+	p("")
+
+	return g.handleOut(meth, valSet, nil)
 }
 
 func (g *generator) paging(meth *descriptor.MethodDescriptorProto, pf *descriptor.FieldDescriptorProto, valSet SampleValueSet) error {
@@ -394,7 +405,7 @@ func (g *generator) paging(meth *descriptor.MethodDescriptorProto, pf *descripto
 		typ = initType{prim: pf.GetType()}
 	}
 
-	err := g.handleOut(meth, valSet, typ)
+	err := g.handleOut(meth, valSet, &typ)
 
 	p("}")
 	p("")
@@ -403,10 +414,12 @@ func (g *generator) paging(meth *descriptor.MethodDescriptorProto, pf *descripto
 	return err
 }
 
-func (g *generator) handleOut(meth *descriptor.MethodDescriptorProto, valSet SampleValueSet, respTyp initType) error {
+func (g *generator) handleOut(meth *descriptor.MethodDescriptorProto, valSet SampleValueSet, respTyp *initType) error {
 	st := newSymTab(nil)
-	st.universe["$resp"] = true
-	st.scope["$resp"] = respTyp
+	if respTyp != nil {
+		st.universe["$resp"] = true
+		st.scope["$resp"] = *respTyp
+	}
 
 	for _, out := range valSet.OnSuccess {
 		if err := writeOutputSpec(out, st, g); err != nil {
@@ -414,7 +427,7 @@ func (g *generator) handleOut(meth *descriptor.MethodDescriptorProto, valSet Sam
 		}
 	}
 
-	if len(valSet.OnSuccess) == 0 {
+	if respTyp != nil && len(valSet.OnSuccess) == 0 {
 		g.pt.Printf("fmt.Println(resp)")
 		g.imports[pbinfo.ImportSpec{Path: "fmt"}] = true
 	}


Test patch:
diff --git a/cmd/gen-go-sample/main_test.go b/cmd/gen-go-sample/main_test.go
index c5e086e..53bd62b 100644
--- a/cmd/gen-go-sample/main_test.go
+++ b/cmd/gen-go-sample/main_test.go
@@ -26,6 +26,8 @@ import (
 )
 
 func TestUnary(t *testing.T) {
+	t.Parallel()
+
 	g := initTestGenerator()
 	fmt.Println(g.descInfo.Serv)
 
@@ -68,14 +70,7 @@ func TestUnary(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	// Don't format. Format can change with Go version.
-	gofmt := false
-	year := 2018
-	content, err := g.commit(gofmt, year)
-	if err != nil {
-		t.Fatal(err)
-	}
-	txtdiff.Diff(t, "TestUnary", string(content), filepath.Join("testdata", "sample_unary.want"))
+	compare(t, g, filepath.Join("testdata", "sample_unary.want"))
 }
 
 func TestSample_InitError(t *testing.T) {
@@ -115,6 +110,8 @@ func TestSample_InitError(t *testing.T) {
 }
 
 func TestPaging(t *testing.T) {
+	t.Parallel()
+
 	g := initTestGenerator()
 
 	vs := SampleValueSet{
@@ -123,15 +120,20 @@ func TestPaging(t *testing.T) {
 	if err := g.genSample("foo.FooService", "PagingMethod", "awesome_region", vs); err != nil {
 		t.Fatal(err)
 	}
+	compare(t, g, filepath.Join("testdata", "sample_paging.want"))
+}
 
-	// Don't format. Format can change with Go version.
-	gofmt := false
-	year := 2018
-	content, err := g.commit(gofmt, year)
-	if err != nil {
+func TestEmpty(t *testing.T) {
+	t.Parallel()
+
+	g := initTestGenerator()
+	vs := SampleValueSet{
+		ID: "my_value_set",
+	}
+	if err := g.genSample("foo.FooService", "EmptyMethod", "awesome_region", vs); err != nil {
 		t.Fatal(err)
 	}
-	txtdiff.Diff(t, "TestUnary", string(content), filepath.Join("testdata", "sample_paging.want"))
+	compare(t, g, filepath.Join("testdata", "sample_empty.want"))
 }
 
 func initTestGenerator() *generator {
@@ -197,6 +199,11 @@ func initTestGenerator() *generator {
 				InputType:  proto.String(".foo.PageInType"),
 				OutputType: proto.String(".foo.PageOutType"),
 			},
+			{
+				Name:       proto.String("EmptyMethod"),
+				InputType:  proto.String(".foo.PageInType"),
+				OutputType: proto.String(".google.protobuf.Empty"),
+			},
 		},
 	}
 	file := &descriptor.FileDescriptorProto{
@@ -214,3 +221,16 @@ func initTestGenerator() *generator {
 		descInfo:  pbinfo.Of([]*descriptor.FileDescriptorProto{file}),
 	}
 }
+
+func compare(t *testing.T, g *generator, goldenPath string) {
+	t.Helper()
+
+	// Don't format. Format can change with Go version.
+	gofmt := false
+	year := 2018
+	content, err := g.commit(gofmt, year)
+	if err != nil {
+		t.Fatal(err)
+	}
+	txtdiff.Diff(t, t.Name(), string(content), goldenPath)
+}
diff --git a/cmd/gen-go-sample/testdata/sample_empty.want b/cmd/gen-go-sample/testdata/sample_empty.want
new file mode 100644
index 0000000..a2c6c55
--- /dev/null
+++ b/cmd/gen-go-sample/testdata/sample_empty.want
@@ -0,0 +1,53 @@
+// Copyright 2018 Google LLC
+//
+// 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
+//
+//     https://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.
+
+// AUTO-GENERATED CODE. DO NOT EDIT.
+
+package main
+import(
+ "context"
+ "flag"
+ "fmt"
+ "log"
+
+foo "path.to/client/foo"
+foopb "path.to/pb/foo"
+)
+// [START awesome_region]
+
+func sampleEmptyMethod() error {
+	ctx := context.Background()
+	c, err := foo.NewClient(ctx)
+	if err != nil {
+		return err
+	}
+
+req := &foopb.PageInType{
+}
+	if err := c.EmptyMethod(ctx, req); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// [END awesome_region]
+
+func main() {
+	flag.Parse()
+	if err := sampleEmptyMethod(); err != nil {
+		log.Fatal(err)
+	}
+}
+