diff --git a/args_test.go b/args_test.go index 4c1fd42a..dfecb1a0 100644 --- a/args_test.go +++ b/args_test.go @@ -6,204 +6,126 @@ import ( "testing" ) -func newCommand(args PositionalArgs, withValid bool) *Command { +type argsTestcase struct { + exerr string // Expected error key (see map[string][string]) + args PositionalArgs // Args validator + wValid bool // Define `ValidArgs` in the command + rargs []string // Runtime args +} + +var errStrings = map[string]string{ + "invalid": `invalid argument "a" for "c"`, + "unknown": `unknown command "one" for "c"`, + "less": "requires at least 2 arg(s), only received 1", + "more": "accepts at most 2 arg(s), received 3", + "notexact": "accepts 2 arg(s), received 3", + "notinrange": "accepts between 2 and 4 arg(s), received 1", +} + +func (tc *argsTestcase) test(t *testing.T) { c := &Command{ Use: "c", - Args: args, + Args: tc.args, Run: emptyRun, } - if withValid { + if tc.wValid { c.ValidArgs = []string{"one", "two", "three"} } - return c -} -func expectSuccess(output string, err error, t *testing.T) { - if output != "" { - t.Errorf("Unexpected output: %v", output) - } - if err != nil { - t.Fatalf("Unexpected error: %v", err) + o, e := executeCommand(c, tc.rargs...) + + if len(tc.exerr) > 0 { + // Expect error + if e == nil { + t.Fatal("Expected an error") + } + expected, ok := errStrings[tc.exerr] + if !ok { + t.Errorf(`key "%s" is not found in map "errStrings"`, tc.exerr) + return + } + if got := e.Error(); got != expected { + t.Errorf("Expected: %q, got: %q", expected, got) + } + } else { + // Expect success + if o != "" { + t.Errorf("Unexpected output: %v", o) + } + if e != nil { + t.Fatalf("Unexpected error: %v", e) + } } } -func expectError(err error, t *testing.T, ex string) { - if err == nil { - t.Fatal("Expected an error") - } - expected := map[string]string{ - "valid": `invalid argument "a" for "c"`, - "no": `unknown command "one" for "c"`, - "min": "requires at least 2 arg(s), only received 1", - "max": "accepts at most 2 arg(s), received 3", - "exact": "accepts 2 arg(s), received 3", - "range": "accepts between 2 and 4 arg(s), received 1", - }[ex] - if got := err.Error(); got != expected { - t.Errorf("Expected: %q, got: %q", expected, got) +func testArgs(t *testing.T, tests map[string]argsTestcase) { + for name, tc := range tests { + t.Run(name, tc.test) } } -// NoArgs - -func TestNoArgs(t *testing.T) { - o, e := executeCommand(newCommand(NoArgs, false)) - expectSuccess(o, e, t) +func TestArgs_No(t *testing.T) { + testArgs(t, map[string]argsTestcase{ + " | ": {"", NoArgs, false, []string{}}, + " | Arb": {"unknown", NoArgs, false, []string{"one"}}, + "Valid | Valid": {"unknown", NoArgs, true, []string{"one"}}, + }) } - -func TestNoArgs_WithArgs(t *testing.T) { - _, e := executeCommand(newCommand(NoArgs, false), "one") - expectError(e, t, "no") +func TestArgs_Arbitrary(t *testing.T) { + testArgs(t, map[string]argsTestcase{ + " | Arb": {"", ArbitraryArgs, false, []string{"a", "b"}}, + "Valid | Valid": {"", ArbitraryArgs, true, []string{"one", "two"}}, + "Valid | Invalid": {"invalid", ArbitraryArgs, true, []string{"a"}}, + }) } - -func TestNoArgs_WithArgs_WithValid(t *testing.T) { - _, e := executeCommand(newCommand(NoArgs, true), "one") - expectError(e, t, "no") +func TestArgs_MinimumN(t *testing.T) { + testArgs(t, map[string]argsTestcase{ + " | Arb": {"", MinimumNArgs(2), false, []string{"a", "b", "c"}}, + "Valid | Valid": {"", MinimumNArgs(2), true, []string{"one", "three"}}, + "Valid | Invalid": {"invalid", MinimumNArgs(2), true, []string{"a", "b"}}, + " | Less": {"less", MinimumNArgs(2), false, []string{"a"}}, + "Valid | Less": {"less", MinimumNArgs(2), true, []string{"one"}}, + "Valid | LessInvalid": {"invalid", MinimumNArgs(2), true, []string{"a"}}, + }) } - -// ArbitraryArgs - -func TestArbitraryArgs(t *testing.T) { - o, e := executeCommand(newCommand(ArbitraryArgs, false), "a", "b") - expectSuccess(o, e, t) +func TestArgs_MaximumN(t *testing.T) { + testArgs(t, map[string]argsTestcase{ + " | Arb": {"", MaximumNArgs(3), false, []string{"a", "b"}}, + "Valid | Valid": {"", MaximumNArgs(2), true, []string{"one", "three"}}, + "Valid | Invalid": {"invalid", MaximumNArgs(2), true, []string{"a", "b"}}, + " | More": {"more", MaximumNArgs(2), false, []string{"a", "b", "c"}}, + "Valid | More": {"more", MaximumNArgs(2), true, []string{"one", "three", "two"}}, + "Valid | MoreInvalid": {"invalid", MaximumNArgs(2), true, []string{"a", "b", "c"}}, + }) } - -func TestArbitraryArgs_WithValid(t *testing.T) { - o, e := executeCommand(newCommand(ArbitraryArgs, true), "one", "two") - expectSuccess(o, e, t) +func TestArgs_Exact(t *testing.T) { + testArgs(t, map[string]argsTestcase{ + " | Arb": {"", ExactArgs(3), false, []string{"a", "b", "c"}}, + "Valid | Valid": {"", ExactArgs(3), true, []string{"three", "one", "two"}}, + "Valid | Invalid": {"invalid", ExactArgs(3), true, []string{"three", "a", "two"}}, + " | InvalidCount": {"notexact", ExactArgs(2), false, []string{"a", "b", "c"}}, + "Valid | InvalidCount": {"notexact", ExactArgs(2), true, []string{"three", "one", "two"}}, + "Valid | InvalidCountInvalid": {"invalid", ExactArgs(2), true, []string{"three", "a", "two"}}, + }) } - -func TestArbitraryArgs_WithValid_WithInvalidArgs(t *testing.T) { - _, e := executeCommand(newCommand(ArbitraryArgs, true), "a") - expectError(e, t, "valid") +func TestArgs_Range(t *testing.T) { + testArgs(t, map[string]argsTestcase{ + " | Arb": {"", RangeArgs(2, 4), false, []string{"a", "b", "c"}}, + "Valid | Valid": {"", RangeArgs(2, 4), true, []string{"three", "one", "two"}}, + "Valid | Invalid": {"invalid", RangeArgs(2, 4), true, []string{"three", "a", "two"}}, + " | InvalidCount": {"notinrange", RangeArgs(2, 4), false, []string{"a"}}, + "Valid | InvalidCount": {"notinrange", RangeArgs(2, 4), true, []string{"two"}}, + "Valid | InvalidCountInvalid": {"invalid", RangeArgs(2, 4), true, []string{"a"}}, + }) } - -// MinimumNArgs - -func TestMinimumNArgs(t *testing.T) { - o, e := executeCommand(newCommand(MinimumNArgs(2), false), "a", "b", "c") - expectSuccess(o, e, t) -} - -func TestMinimumNArgs_WithValid(t *testing.T) { - o, e := executeCommand(newCommand(MinimumNArgs(2), true), "one", "three") - expectSuccess(o, e, t) -} - -func TestMinimumNArgs_WithValid_WithInvalidArgs(t *testing.T) { - _, e := executeCommand(newCommand(MinimumNArgs(2), true), "a", "b") - expectError(e, t, "valid") -} - -func TestMinimumNArgs_WithLessArgs(t *testing.T) { - _, e := executeCommand(newCommand(MinimumNArgs(2), false), "a") - expectError(e, t, "min") -} - -func TestMinimumNArgs_WithValid_WithLessArgs(t *testing.T) { - _, e := executeCommand(newCommand(MinimumNArgs(2), true), "one") - expectError(e, t, "min") -} - -func TestMinimumNArgs_WithValid_WithLessArgsWithInvalidArgs(t *testing.T) { - _, e := executeCommand(newCommand(MinimumNArgs(2), true), "a") - expectError(e, t, "valid") -} - -// MaximumNArgs - -func TestMaximumNArgs(t *testing.T) { - o, e := executeCommand(newCommand(MaximumNArgs(3), false), "a", "b") - expectSuccess(o, e, t) -} - -func TestMaximumNArgs_WithValid(t *testing.T) { - o, e := executeCommand(newCommand(MaximumNArgs(2), true), "one", "three") - expectSuccess(o, e, t) -} - -func TestMaximumNArgs_WithValid_WithInvalidArgs(t *testing.T) { - _, e := executeCommand(newCommand(MaximumNArgs(2), true), "a", "b") - expectError(e, t, "valid") -} - -func TestMaximumNArgs_WithMoreArgs(t *testing.T) { - _, e := executeCommand(newCommand(MaximumNArgs(2), false), "a", "b", "c") - expectError(e, t, "max") -} - -func TestMaximumNArgs_WithValid_WithMoreArgs(t *testing.T) { - _, e := executeCommand(newCommand(MaximumNArgs(2), true), "one", "three", "two") - expectError(e, t, "max") -} - -func TestMaximumNArgs_WithValid_WithMoreArgsWithInvalidArgs(t *testing.T) { - _, e := executeCommand(newCommand(MaximumNArgs(2), true), "a", "b", "c") - expectError(e, t, "valid") -} - -// ExactArgs - -func TestExactArgs(t *testing.T) { - o, e := executeCommand(newCommand(ExactArgs(3), false), "a", "b", "c") - expectSuccess(o, e, t) -} - -func TestExactArgs_WithValid(t *testing.T) { - o, e := executeCommand(newCommand(ExactArgs(3), true), "three", "one", "two") - expectSuccess(o, e, t) -} - -func TestExactArgs_WithValid_WithInvalidArgs(t *testing.T) { - _, e := executeCommand(newCommand(ExactArgs(3), true), "three", "a", "two") - expectError(e, t, "valid") -} - -func TestExactArgs_WithInvalidCount(t *testing.T) { - _, e := executeCommand(newCommand(ExactArgs(2), false), "a", "b", "c") - expectError(e, t, "exact") -} - -func TestExactArgs_WithValid_WithInvalidCount(t *testing.T) { - _, e := executeCommand(newCommand(ExactArgs(2), true), "three", "one", "two") - expectError(e, t, "exact") -} - -func TestExactArgs_WithValid_WithInvalidCountWithInvalidArgs(t *testing.T) { - _, e := executeCommand(newCommand(ExactArgs(2), true), "three", "a", "two") - expectError(e, t, "valid") -} - -// RangeArgs - -func TestRangeArgs(t *testing.T) { - o, e := executeCommand(newCommand(RangeArgs(2, 4), false), "a", "b", "c") - expectSuccess(o, e, t) -} - -func TestRangeArgs_WithValid(t *testing.T) { - o, e := executeCommand(newCommand(RangeArgs(2, 4), true), "three", "one", "two") - expectSuccess(o, e, t) -} - -func TestRangeArgs_WithValid_WithInvalidArgs(t *testing.T) { - _, e := executeCommand(newCommand(RangeArgs(2, 4), true), "three", "a", "two") - expectError(e, t, "valid") -} - -func TestRangeArgs_WithInvalidCount(t *testing.T) { - _, e := executeCommand(newCommand(RangeArgs(2, 4), false), "a") - expectError(e, t, "range") -} - -func TestRangeArgs_WithValid_WithInvalidCount(t *testing.T) { - _, e := executeCommand(newCommand(RangeArgs(2, 4), true), "two") - expectError(e, t, "range") -} - -func TestRangeArgs_WithValid_WithInvalidCountWithInvalidArgs(t *testing.T) { - _, e := executeCommand(newCommand(RangeArgs(2, 4), true), "a") - expectError(e, t, "valid") +func TestArgs_DEPRECATED(t *testing.T) { + testArgs(t, map[string]argsTestcase{ + "OnlyValid | Valid | Valid": {"", OnlyValidArgs, true, []string{"one", "two"}}, + "OnlyValid | Valid | Invalid": {"invalid", OnlyValidArgs, true, []string{"a"}}, + "ExactValid | Valid | Valid": {"", ExactValidArgs(3), true, []string{"two", "three", "one"}}, + "ExactValid | Valid | InvalidCount": {"notexact", ExactValidArgs(2), true, []string{"two", "three", "one"}}, + "ExactValid | Valid | Invalid": {"invalid", ExactValidArgs(2), true, []string{"two", "a"}}, + }) } // Takes(No)Args @@ -312,36 +234,6 @@ func TestMatchAll(t *testing.T) { } } -// DEPRECATED - -func TestDEPRECATED_OnlyValidArgs(t *testing.T) { - o, e := executeCommand(newCommand(OnlyValidArgs, true), "one", "two") - expectSuccess(o, e, t) -} - -func TestDEPRECATED_OnlyValidArgs_WithInvalidArgs(t *testing.T) { - _, e := executeCommand(newCommand(OnlyValidArgs, true), "a") - expectError(e, t, "valid") -} - -func TestDEPRECATED_ExactValidArgs(t *testing.T) { - // Note that the order is not required to be the same: - // Definition: "one", "two", "three" - // Execution: "two", "three", "one" - o, e := executeCommand(newCommand(ExactValidArgs(3), true), "two", "three", "one") - expectSuccess(o, e, t) -} - -func TestDEPRECATED_ExactValidArgs_WithInvalidCount(t *testing.T) { - _, e := executeCommand(newCommand(ExactValidArgs(2), true), "two", "three", "one") - expectError(e, t, "exact") -} - -func TestDEPRECATED_ExactValidArgs_WithInvalidArgs(t *testing.T) { - _, e := executeCommand(newCommand(ExactValidArgs(2), true), "two", "a") - expectError(e, t, "valid") -} - // This test make sure we keep backwards-compatibility with respect // to the legacyArgs() function. // It makes sure the root command accepts arguments if it does not have