Skip to content

Commit 9b5195e

Browse files
committed
add unit tests for func cmd
1 parent dc66784 commit 9b5195e

File tree

4 files changed

+145
-7
lines changed

4 files changed

+145
-7
lines changed

cmd/function.go

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package cmd
2+
3+
import (
4+
"fmt"
5+
"go/ast"
6+
"go/doc"
7+
"go/parser"
8+
"go/token"
9+
"path/filepath"
10+
"reflect"
11+
"runtime"
12+
"strings"
13+
14+
"github.com/linuxsuren/api-testing/pkg/render"
15+
"github.com/spf13/cobra"
16+
)
17+
18+
func createFunctionCmd() (c *cobra.Command) {
19+
c = &cobra.Command{
20+
Use: "func",
21+
Short: "Print all the supported functions",
22+
RunE: func(cmd *cobra.Command, args []string) (err error) {
23+
if len(args) > 0 {
24+
name := args[0]
25+
if fn, ok := render.FuncMap()[name]; ok {
26+
cmd.Println(reflect.TypeOf(fn))
27+
desc := FuncDescription(fn)
28+
if desc != "" {
29+
fmt.Println(desc)
30+
}
31+
} else {
32+
cmd.Println("No such function")
33+
}
34+
} else {
35+
for name, fn := range render.FuncMap() {
36+
cmd.Println(name, reflect.TypeOf(fn))
37+
}
38+
}
39+
return
40+
},
41+
}
42+
return
43+
}
44+
45+
// Get the name and path of a func
46+
func FuncPathAndName(f interface{}) string {
47+
return runtime.FuncForPC(reflect.ValueOf(f).Pointer()).Name()
48+
}
49+
50+
// Get the name of a func (with package path)
51+
func FuncName(f interface{}) string {
52+
splitFuncName := strings.Split(FuncPathAndName(f), ".")
53+
return splitFuncName[len(splitFuncName)-1]
54+
}
55+
56+
// Get description of a func
57+
func FuncDescription(f interface{}) (desc string) {
58+
fileName, _ := runtime.FuncForPC(reflect.ValueOf(f).Pointer()).FileLine(0)
59+
funcName := FuncName(f)
60+
fset := token.NewFileSet()
61+
62+
// Parse src
63+
parsedAst, err := parser.ParseFile(fset, fileName, nil, parser.ParseComments)
64+
if err == nil {
65+
pkg := &ast.Package{
66+
Name: "Any",
67+
Files: make(map[string]*ast.File),
68+
}
69+
pkg.Files[fileName] = parsedAst
70+
71+
importPath, _ := filepath.Abs("/")
72+
myDoc := doc.New(pkg, importPath, doc.AllDecls)
73+
for _, theFunc := range myDoc.Funcs {
74+
if theFunc.Name == funcName {
75+
desc = theFunc.Doc
76+
break
77+
}
78+
}
79+
}
80+
return
81+
}

cmd/function_test.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package cmd_test
2+
3+
import (
4+
"bytes"
5+
"testing"
6+
7+
"github.com/linuxsuren/api-testing/cmd"
8+
fakeruntime "github.com/linuxsuren/go-fake-runtime"
9+
"github.com/stretchr/testify/assert"
10+
)
11+
12+
func TestCreateFunctionCommand(t *testing.T) {
13+
tests := []struct {
14+
name string
15+
args []string
16+
verify func(t *testing.T, output string)
17+
}{{
18+
name: "normal",
19+
args: []string{"func"},
20+
verify: func(t *testing.T, output string) {
21+
assert.NotEmpty(t, output)
22+
},
23+
}, {
24+
name: "with function name",
25+
args: []string{"func", "clean"},
26+
verify: func(t *testing.T, output string) {
27+
assert.NotEmpty(t, output)
28+
},
29+
}, {
30+
name: "with not exit function",
31+
args: []string{"func", "fake"},
32+
verify: func(t *testing.T, output string) {
33+
assert.Equal(t, "No such function\n", output)
34+
},
35+
}}
36+
for _, tt := range tests {
37+
t.Run(tt.name, func(t *testing.T) {
38+
c := cmd.NewRootCmd(fakeruntime.FakeExecer{ExpectOS: "linux"}, cmd.NewFakeGRPCServer())
39+
40+
buf := new(bytes.Buffer)
41+
c.SetOut(buf)
42+
c.SetArgs(tt.args)
43+
44+
err := c.Execute()
45+
assert.NoError(t, err)
46+
47+
if tt.verify != nil {
48+
tt.verify(t, buf.String())
49+
}
50+
})
51+
}
52+
}

cmd/root.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ func NewRootCmd(execer fakeruntime.Execer, gRPCServer gRPCServer) (c *cobra.Comm
1919
c.AddCommand(createInitCommand(execer),
2020
createRunCommand(), createSampleCmd(),
2121
createServerCmd(gRPCServer), createJSONSchemaCmd(),
22-
createServiceCommand(execer))
22+
createServiceCommand(execer), createFunctionCmd())
2323
return
2424
}
2525

pkg/render/template.go

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,21 @@ import (
1313
func Render(name, text string, ctx interface{}) (result string, err error) {
1414
var tpl *template.Template
1515
if tpl, err = template.New(name).
16-
Funcs(sprig.FuncMap()).
17-
Funcs(template.FuncMap{
18-
"randomKubernetesName": func() string {
19-
return util.String(8)
20-
},
21-
}).Parse(text); err == nil {
16+
Funcs(FuncMap()).
17+
Parse(text); err == nil {
2218
buf := new(bytes.Buffer)
2319
if err = tpl.Execute(buf, ctx); err == nil {
2420
result = strings.TrimSpace(buf.String())
2521
}
2622
}
2723
return
2824
}
25+
26+
// FuncMap reutrns all the supported functions
27+
func FuncMap() template.FuncMap {
28+
funcs := sprig.FuncMap()
29+
funcs["randomKubernetesName"] = func() string {
30+
return util.String(8)
31+
}
32+
return funcs
33+
}

0 commit comments

Comments
 (0)