diff --git a/commands/cli/parse_test.go b/commands/cli/parse_test.go index edbca7f76..5248b4a2a 100644 --- a/commands/cli/parse_test.go +++ b/commands/cli/parse_test.go @@ -3,10 +3,67 @@ package cli import ( "strings" "testing" + "io" + "io/ioutil" + "os" "github.com/ipfs/go-ipfs/commands" ) +type kvs map[string]interface{} +type words []string + +func sameWords(a words, b words) bool { + if len(a) != len(b) { + return false + } + for i, w := range a { + if w != b[i] { + return false + } + } + return true +} + +func sameKVs(a kvs, b kvs) bool { + if len(a) != len(b) { + return false + } + for k, v := range a { + if v != b[k] { + return false + } + } + return true +} + +func TestSameWords(t *testing.T) { + a := []string{"v1", "v2"} + b := []string{"v1", "v2", "v3"} + c := []string{"v2", "v3"} + d := []string{"v2"} + e := []string{"v2", "v3"} + f := []string{"v2", "v1"} + + test := func(a words, b words, v bool) { + if sameWords(a, b) != v { + t.Errorf("sameWords('%v', '%v') != %v", a, b, v) + } + } + + test(a, b, false) + test(a, a, true) + test(a, c, false) + test(b, c, false) + test(c, d, false) + test(c, e, true) + test(b, e, false) + test(a, b, false) + test(a, f, false) + test(e, f, false) + test(f, f, true) +} + func TestOptionParsing(t *testing.T) { subCmd := &commands.Command{} cmd := &commands.Command{ @@ -19,30 +76,6 @@ func TestOptionParsing(t *testing.T) { }, } - type kvs map[string]interface{} - type words []string - - sameWords := func(a words, b words) bool { - for i, w := range a { - if w != b[i] { - return false - } - } - return true - } - - sameKVs := func(a kvs, b kvs) bool { - if len(a) != len(b) { - return false - } - for k, v := range a { - if v != b[k] { - return false - } - } - return true - } - testHelper := func(args string, expectedOpts kvs, expectedWords words, expectErr bool) { _, opts, input, _, err := parseOpts(strings.Split(args, " "), cmd) if expectErr { @@ -117,76 +150,78 @@ func TestArgumentParsing(t *testing.T) { commands.StringArg("b", true, false, "another arg"), }, }, + "stdinenabled": &commands.Command{ + Arguments: []commands.Argument{ + commands.StringArg("a", true, true, "some arg").EnableStdin(), + }, + }, }, } - _, _, _, err := Parse([]string{"noarg"}, nil, rootCmd) - if err != nil { - t.Error("Should have passed") - } - _, _, _, err = Parse([]string{"noarg", "value!"}, nil, rootCmd) - if err == nil { - t.Error("Should have failed (provided an arg, but command didn't define any)") + test := func(cmd words, f *os.File, res words) { + if f != nil { + if _, err := f.Seek(0, os.SEEK_SET); err != nil { + t.Fatal(err) + } + } + req, _, _, err := Parse(cmd, f, rootCmd) + if err != nil { + t.Errorf("Command '%v' should have passed parsing", cmd) + } + if !sameWords(req.Arguments(), res) { + t.Errorf("Arguments parsed from '%v' are not '%v'", cmd, res) + } } - _, _, _, err = Parse([]string{"onearg", "value!"}, nil, rootCmd) - if err != nil { - t.Error("Should have passed") - } - _, _, _, err = Parse([]string{"onearg"}, nil, rootCmd) - if err == nil { - t.Error("Should have failed (didn't provide any args, arg is required)") + testFail := func(cmd words, msg string) { + _, _, _, err := Parse(cmd, nil, rootCmd) + if err == nil { + t.Errorf("Should have failed: %v", msg) + } } - _, _, _, err = Parse([]string{"twoargs", "value1", "value2"}, nil, rootCmd) - if err != nil { - t.Error("Should have passed") - } - _, _, _, err = Parse([]string{"twoargs", "value!"}, nil, rootCmd) - if err == nil { - t.Error("Should have failed (only provided 1 arg, needs 2)") - } - _, _, _, err = Parse([]string{"twoargs"}, nil, rootCmd) - if err == nil { - t.Error("Should have failed (didn't provide any args, 2 required)") + test([]string{"noarg"}, nil, []string{}) + testFail([]string{"noarg", "value!"}, "provided an arg, but command didn't define any") + + test([]string{"onearg", "value!"}, nil, []string{"value!"}) + testFail([]string{"onearg"}, "didn't provide any args, arg is required") + + test([]string{"twoargs", "value1", "value2"}, nil, []string{"value1", "value2"}) + testFail([]string{"twoargs", "value!"}, "only provided 1 arg, needs 2") + testFail([]string{"twoargs"}, "didn't provide any args, 2 required") + + test([]string{"variadic", "value!"}, nil, []string{"value!"}) + test([]string{"variadic", "value1", "value2", "value3"}, nil, []string{"value1", "value2", "value3"}) + testFail([]string{"variadic"}, "didn't provide any args, 1 required") + + test([]string{"optional", "value!"}, nil, []string{"value!"}) + test([]string{"optional"}, nil, []string{}) + + test([]string{"reversedoptional", "value1", "value2"}, nil, []string{"value1", "value2"}) + test([]string{"reversedoptional", "value!"}, nil, []string{"value!"}) + + testFail([]string{"reversedoptional"}, "didn't provide any args, 1 required") + testFail([]string{"reversedoptional", "value1", "value2", "value3"}, "provided too many args, only takes 1") + + // Use a temp file to simulate stdin + fileToSimulateStdin := func(t *testing.T, content string) (*os.File) { + fstdin, err := ioutil.TempFile("", "") + if err != nil { + t.Fatal(err) + } + defer os.Remove(fstdin.Name()) + + if _, err := io.WriteString(fstdin, content); err != nil { + t.Fatal(err) + } + return fstdin } - _, _, _, err = Parse([]string{"variadic", "value!"}, nil, rootCmd) - if err != nil { - t.Error("Should have passed") - } - _, _, _, err = Parse([]string{"variadic", "value1", "value2", "value3"}, nil, rootCmd) - if err != nil { - t.Error("Should have passed") - } - _, _, _, err = Parse([]string{"variadic"}, nil, rootCmd) - if err == nil { - t.Error("Should have failed (didn't provide any args, 1 required)") - } + test([]string{"stdinenabled", "value1", "value2"}, nil, []string{"value1", "value2"}) - _, _, _, err = Parse([]string{"optional", "value!"}, nil, rootCmd) - if err != nil { - t.Error("Should have passed") - } - _, _, _, err = Parse([]string{"optional"}, nil, rootCmd) - if err != nil { - t.Error("Should have passed") - } + fstdin := fileToSimulateStdin(t, "stdin1") - _, _, _, err = Parse([]string{"reversedoptional", "value1", "value2"}, nil, rootCmd) - if err != nil { - t.Error("Should have passed") - } - _, _, _, err = Parse([]string{"reversedoptional", "value!"}, nil, rootCmd) - if err != nil { - t.Error("Should have passed") - } - _, _, _, err = Parse([]string{"reversedoptional"}, nil, rootCmd) - if err == nil { - t.Error("Should have failed (didn't provide any args, 1 required)") - } - _, _, _, err = Parse([]string{"reversedoptional", "value1", "value2", "value3"}, nil, rootCmd) - if err == nil { - t.Error("Should have failed (provided too many args, only takes 1)") - } + test([]string{"stdinenabled"}, fstdin, []string{"stdin1"}) + test([]string{"stdinenabled", "value1"}, fstdin, []string{"stdin1", "value1"}) + test([]string{"stdinenabled", "value1", "value2"}, fstdin, []string{"stdin1", "value1", "value2"}) }