dnote/pkg/cli/command/command_test.go
2023-03-11 18:06:40 +11:00

187 lines
5.4 KiB
Go

package command
import (
"fmt"
"testing"
"github.com/dnote/dnote/pkg/assert"
)
func TestAddCommand(t *testing.T) {
cmd := Command{Name: "root command"}
assert.Equal(t, len(cmd.commands), 0, "Commands length mismatch")
subCommand1 := Command{Name: "foo"}
cmd.AddCommand(&subCommand1)
assert.Equal(t, subCommand1.Parent, &cmd, "subCommand1 Parent mismatch")
assert.Equal(t, len(cmd.commands), 1, "Commands length mismatch")
assert.Equal(t, cmd.commands[0], &subCommand1, "commands[0] mismatch")
subCommand2 := Command{Name: "bar"}
cmd.AddCommand(&subCommand2)
assert.Equal(t, len(cmd.commands), 2, "Commands length mismatch")
assert.Equal(t, subCommand2.Parent, &cmd, "subCommand2 Parent mismatch")
assert.Equal(t, cmd.commands[0], &subCommand1, "commands[0] mismatch")
assert.Equal(t, cmd.commands[1], &subCommand2, "commands[1] mismatch")
}
func TestHasAlias(t *testing.T) {
cmd := Command{
Name: "foo",
Aliases: []string{"f", "bar"},
}
assert.Equal(t, cmd.hasAlias("f"), true, "Command should have 'f' alias")
assert.Equal(t, cmd.hasAlias("F"), false, "Command should not have 'F' alias")
assert.Equal(t, cmd.hasAlias("bar"), true, "Command should have 'bar' alias")
assert.Equal(t, cmd.hasAlias("BAR"), false, "Command should have 'BAR' alias")
assert.Equal(t, cmd.hasAlias("baz"), false, "Command should not have 'baz' alias")
assert.Equal(t, cmd.hasAlias(""), false, "Command should not have an empty alias")
}
func TestHasAlias_withoutAlias(t *testing.T) {
cmd := Command{
Name: "foo",
}
assert.Equal(t, cmd.hasAlias("f"), false, "Command should not have any alias")
assert.Equal(t, cmd.hasAlias(""), false, "Command should not have any alias")
}
func TestCommandRoot(t *testing.T) {
subCommand2 := Command{
Name: "baz",
}
subCommand1 := Command{
Name: "bar",
commands: []*Command{
&subCommand2,
},
}
cmd := Command{
Name: "foo",
commands: []*Command{
&subCommand1,
},
}
subCommand1.Parent = &cmd
subCommand2.Parent = &subCommand1
assert.Equal(t, cmd.Root(), &cmd, "Command should already be a root")
assert.Equal(t, subCommand1.Root(), &cmd, "subCommand1 root mismatch")
assert.Equal(t, subCommand2.Root(), &cmd, "subCommand2 root mismatch")
}
func TestFindSubcommand(t *testing.T) {
subCommand1 := Command{
Name: "bar",
Aliases: []string{"quz"},
}
subCommand2 := Command{
Name: "baz",
}
cmd := Command{
Name: "foo",
commands: []*Command{
&subCommand1,
&subCommand2,
},
}
subcommandResult1, subcommandArgResult1 := cmd.findSubCommand([]string{"bar"})
assert.Equal(t, subcommandResult1, &subCommand1, "Subcommand 'bar' mismatch")
assert.DeepEqual(t, subcommandArgResult1, []string{}, "Subcommand arg for 'bar' mismatch")
subcommandResult2, subcommandArgResult2 := cmd.findSubCommand([]string{"baz", "echo"})
assert.Equal(t, subcommandResult2, &subCommand2, "Subcommand 'baz' mismatch")
assert.DeepEqual(t, subcommandArgResult2, []string{"echo"}, "Subcommand arg for 'baz' mismatch")
// Should match an alias
subcommandResult3, subcommandArgResult3 := cmd.findSubCommand([]string{"quz"})
assert.Equal(t, subcommandResult3, &subCommand1, "Subcommand 'quz' mismatch")
assert.DeepEqual(t, subcommandArgResult3, []string{}, "Subcommand arg for 'quz' mismatch")
// Should not match if not exists
subcommandResult4, subcommandArgResult4 := cmd.findSubCommand([]string{"qux"})
assert.Equal(t, subcommandResult4, (*Command)(nil), "Subcommand 'qux' mismatch")
assert.DeepEqual(t, subcommandArgResult4, []string{}, "Subcommand arg for 'qux' mismatch")
// Should not match itself
subcommandResult5, subcommandArgResult5 := subCommand1.findSubCommand([]string{"bar"})
assert.Equal(t, subcommandResult5, (*Command)(nil), "Subcommand 'bar' should not exist on 'bar'")
assert.DeepEqual(t, subcommandArgResult5, []string{}, "Subcommand arg for 'bar' should be empty when there is no match")
}
func executeCommand(root *Command, args ...string) error {
return root.Execute()
}
func TestFilterFlags(t *testing.T) {
testCases := []struct {
arguments []string
expected []string
}{
{
arguments: []string{"a", "b", "c"},
expected: []string{"a", "b", "c"},
},
{
arguments: []string{"-b", "cmd"},
expected: []string{"cmd"},
},
{
arguments: []string{"foo", "-b", "--str"},
expected: []string{"foo"},
},
{
arguments: []string{"foo", "-b", "baz"},
expected: []string{"foo", "baz"},
},
{
arguments: []string{"foo", "-i", "123"},
expected: []string{"foo"},
},
{
arguments: []string{"-b", "bar", "-i", "1", "a"},
expected: []string{"bar", "a"},
},
{
arguments: []string{"a", "-b", "bar", "-i", "1"},
expected: []string{"a", "bar"},
},
{
arguments: []string{"--foo", "b", "-baz"},
expected: []string{},
},
{
arguments: []string{"--s=hello", "foo"},
expected: []string{"foo"},
},
{
arguments: []string{"-shello", "foo"},
expected: []string{"foo"},
},
{
arguments: []string{"-shello", "foo", "-i1"},
expected: []string{"foo"},
},
{
arguments: []string{"-si", "foo"},
expected: []string{"foo"},
},
}
cmd := Command{}
cmd.Flags().StringP("str", "s", "", "")
cmd.Flags().IntP("int", "i", 1, "")
cmd.Flags().BoolP("bool", "b", false, "")
// Default 'bool' to "true"
cmd.Flags().Lookup("bool").NoOptDefVal = "true"
for idx, testCase := range testCases {
got := filterFlags(testCase.arguments, &cmd)
assert.DeepEqual(t, got, testCase.expected, fmt.Sprintf("result mismatch for test case %d", idx))
}
}