func/cmd/templates/template_engine_test.go

173 lines
4.9 KiB
Go

// Copyright © 2020 The Knative 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.
package templates
import (
"strings"
"testing"
flag "github.com/spf13/pflag"
"github.com/spf13/cobra"
"gotest.tools/v3/assert"
"knative.dev/client/pkg/util"
"knative.dev/client/pkg/util/test"
)
type testData struct {
cmd *cobra.Command
validate func(*testing.T, string, *cobra.Command)
}
func TestUsageFunc(t *testing.T) {
rootCmd, engine := newTestTemplateEngine()
subCmdWithSubs, _, _ := rootCmd.Find([]string{"g1.1"})
subCmd, _, _ := rootCmd.Find([]string{"g2.1"})
data := []testData{
{
rootCmd,
func(t *testing.T, out string, command *cobra.Command) {
validateRootUsageOutput(t, out)
},
},
{
subCmd,
func(t *testing.T, out string, command *cobra.Command) {
validateSubUsageOutput(t, out, command)
},
},
{
subCmdWithSubs,
func(t *testing.T, out string, command *cobra.Command) {
validateSubUsageOutput(t, out, command)
subsub := command.Commands()[0]
assert.Assert(t, util.ContainsAll(out, subsub.Name(), subsub.Short, "Available Commands:"))
},
},
}
for _, d := range data {
capture := test.CaptureOutput(t)
err := (engine.usageFunc())(d.cmd)
assert.NilError(t, err)
stdOut, stdErr := capture.Close()
assert.Equal(t, stdErr, "")
d.validate(t, stdOut, d.cmd)
}
}
func TestHelpFunc(t *testing.T) {
rootCmd, engine := newTestTemplateEngine()
subCmd := rootCmd.Commands()[0]
data := []testData{
{
rootCmd,
func(t *testing.T, out string, command *cobra.Command) {
validateRootUsageOutput(t, out)
assert.Assert(t, strings.Contains(out, command.Long))
},
},
{
subCmd,
func(t *testing.T, out string, command *cobra.Command) {
validateSubUsageOutput(t, out, command)
assert.Assert(t, strings.Contains(out, command.Long))
},
},
}
for _, d := range data {
capture := test.CaptureOutput(t)
(engine.helpFunc())(d.cmd, []string{})
stdOut, stdErr := capture.Close()
assert.Equal(t, stdErr, "")
d.validate(t, stdOut, d.cmd)
}
}
func TestUsageFlags(t *testing.T) {
f := flag.NewFlagSet("test", flag.ContinueOnError)
f.StringP("test", "t", "default", "test-option")
usage := flagsUsagesKubectl(f)
assert.Equal(t, usage, " -t, --test='default': test-option\n")
usage = flagsUsagesCobra(f)
assert.Equal(t, usage, " -t, --test string test-option (default \"default\")\n")
// test for flag with no shorthand
fl := f.Lookup("test")
assert.Assert(t, fl != nil)
fl.Shorthand = ""
usage = flagsUsagesKubectl(f)
assert.Equal(t, usage, " --test='default': test-option\n")
// test for hidden flag
err := f.MarkHidden("test")
assert.NilError(t, err)
usage = flagsUsagesKubectl(f)
assert.Equal(t, usage, "")
}
func validateRootUsageOutput(t *testing.T, stdOut string) {
assert.Assert(t, util.ContainsAll(stdOut, "root"))
assert.Assert(t, util.ContainsAll(stdOut, "header-1", "g1.1", "desc-g1.1", "g1.2", "desc-g1.2"))
assert.Assert(t, util.ContainsAll(stdOut, "header-2", "g2.1", "desc-g2.1", "g2.2", "desc-g2.2", "g2.3", "desc-g2.3"))
assert.Assert(t, util.ContainsAll(stdOut, "Use", "root", "--help"))
assert.Assert(t, util.ContainsAll(stdOut, "Use", "root", "<command>"))
}
func validateSubUsageOutput(t *testing.T, stdOut string, cmd *cobra.Command) {
assert.Assert(t, util.ContainsAll(stdOut, "Usage", cmd.CommandPath()+" [flags]"))
assert.Assert(t, util.ContainsAll(stdOut, "Flags", "--local-opt", "local option"))
assert.Assert(t, util.ContainsAll(stdOut, "Aliases", "alias"))
}
func newTestTemplateEngine() (*cobra.Command, templateEngine) {
rootCmd := &cobra.Command{Use: "root", Short: "desc-root", Long: "longdesc-root"}
rootCmd.PersistentFlags().String("global-opt", "", "global option")
cmdGroups := CommandGroups{
{
"header-1",
[]*cobra.Command{newCmd("g1.1"), newCmd("g1.2")},
},
{
"header-2",
[]*cobra.Command{newCmd("g2.1"), newCmd("g2.2"), newCmd("g2.3")},
},
}
engine := newTemplateEngine(rootCmd, cmdGroups, nil)
cmdGroups.AddTo(rootCmd)
// Add a sub-command to first command
cmd, _, _ := rootCmd.Find([]string{"g1.1"})
cmd.AddCommand(newCmd("g1.1.1"))
rootCmd.SetUsageFunc(engine.usageFunc())
return rootCmd, engine
}
func newCmd(name string) *cobra.Command {
ret := &cobra.Command{
Use: name,
Short: "desc-" + name,
Long: "longdesc-" + name,
Run: func(cmd *cobra.Command, args []string) {},
Aliases: []string{"alias"},
}
ret.Flags().String("local-opt", "", "local option")
return ret
}