aboutsummaryrefslogtreecommitdiffstats
path: root/commands/parser_test.go
diff options
context:
space:
mode:
authorKoni Marti <koni.marti@gmail.com>2023-05-10 23:56:23 +0200
committerRobin Jarry <robin@jarry.cc>2023-05-16 13:39:17 +0200
commit5c9d22bb84eb8a6ddd4477bae3c081964d6e7b51 (patch)
tree263083c1f55d60d55d2b005d6504c64393432186 /commands/parser_test.go
parentcd68adc4630ed834eeac33f09ef58891c18c2dee (diff)
downloadaerc-5c9d22bb84eb8a6ddd4477bae3c081964d6e7b51.tar.gz
commands: add OptionsProvider and OptionCompleter
Improve command completion by supporting option flags and option arguments completion. Option completion is activated when the command implements the OptionsProvider interface. Implementing the OptionCompleter allows the completion of individual option arguments. The completion interfaces harmonizes the completion behavior in aerc, makes the completion code clearer and simplifies the completion functionality. With this patch, the Complete method on commands will only have to deal with the actual completion, i.e. paths, folders, etc and not worry about options. To remove all options and its mandatory arguments from args, use commands.Operands(). Signed-off-by: Koni Marti <koni.marti@gmail.com> Acked-by: Robin Jarry <robin@jarry.cc>
Diffstat (limited to 'commands/parser_test.go')
-rw-r--r--commands/parser_test.go258
1 files changed, 258 insertions, 0 deletions
diff --git a/commands/parser_test.go b/commands/parser_test.go
new file mode 100644
index 00000000..d6ccd385
--- /dev/null
+++ b/commands/parser_test.go
@@ -0,0 +1,258 @@
+package commands
+
+import (
+ "testing"
+)
+
+var parserTests = []struct {
+ name string
+ cmd string
+ wantType completionType
+ wantFlag string
+ wantArg string
+ wantOptind int
+}{
+ {
+ name: "empty command",
+ cmd: "",
+ wantType: COMMAND,
+ wantFlag: "",
+ wantArg: "",
+ wantOptind: 0,
+ },
+ {
+ name: "command only",
+ cmd: "cmd",
+ wantType: COMMAND,
+ wantFlag: "",
+ wantArg: "",
+ wantOptind: 1,
+ },
+ {
+ name: "with space",
+ cmd: "cmd ",
+ wantType: OPERAND,
+ wantFlag: "",
+ wantArg: "",
+ wantOptind: 1,
+ },
+ {
+ name: "with two spaces",
+ cmd: "cmd ",
+ wantType: OPERAND,
+ wantFlag: "",
+ wantArg: "",
+ wantOptind: 1,
+ },
+ {
+ name: "with single option flag",
+ cmd: "cmd -",
+ wantType: SHORT_OPTION,
+ wantFlag: "",
+ wantArg: "",
+ wantOptind: 2,
+ },
+ {
+ name: "with single option flag two spaces",
+ cmd: "cmd -",
+ wantType: SHORT_OPTION,
+ wantFlag: "",
+ wantArg: "",
+ wantOptind: 2,
+ },
+ {
+ name: "with single option flag completed",
+ cmd: "cmd -a",
+ wantType: SHORT_OPTION,
+ wantFlag: "a",
+ wantArg: "",
+ wantOptind: 2,
+ },
+ {
+ name: "with single option flag completed and space",
+ cmd: "cmd -a ",
+ wantType: OPERAND,
+ wantFlag: "a",
+ wantArg: "",
+ wantOptind: 2,
+ },
+ {
+ name: "with single option flag completed and two spaces",
+ cmd: "cmd -a ",
+ wantType: OPERAND,
+ wantFlag: "a",
+ wantArg: "",
+ wantOptind: 2,
+ },
+ {
+ name: "with two single option flag completed",
+ cmd: "cmd -b -a",
+ wantType: SHORT_OPTION,
+ wantFlag: "a",
+ wantArg: "",
+ wantOptind: 3,
+ },
+ {
+ name: "with two single option flag combined",
+ cmd: "cmd -ab",
+ wantType: SHORT_OPTION,
+ wantFlag: "ab",
+ wantArg: "",
+ wantOptind: 2,
+ },
+ {
+ name: "with two single option flag and space",
+ cmd: "cmd -ab ",
+ wantType: OPERAND,
+ wantFlag: "ab",
+ wantArg: "",
+ wantOptind: 2,
+ },
+ {
+ name: "with mandatory option flag",
+ cmd: "cmd -f",
+ wantType: OPTION_ARGUMENT,
+ wantFlag: "f",
+ wantArg: "",
+ wantOptind: 2,
+ },
+ {
+ name: "with mandatory option flag and space",
+ cmd: "cmd -f ",
+ wantType: OPTION_ARGUMENT,
+ wantFlag: "f",
+ wantArg: "",
+ wantOptind: 2,
+ },
+ {
+ name: "with mandatory option flag and two spaces",
+ cmd: "cmd -f ",
+ wantType: OPTION_ARGUMENT,
+ wantFlag: "f",
+ wantArg: "",
+ wantOptind: 2,
+ },
+ {
+ name: "with mandatory option flag and completed",
+ cmd: "cmd -f a",
+ wantType: OPTION_ARGUMENT,
+ wantFlag: "f",
+ wantArg: "a",
+ wantOptind: 3,
+ },
+ {
+ name: "with mandatory option flag and completed quote",
+ cmd: "cmd -f 'a b'",
+ wantType: OPTION_ARGUMENT,
+ wantFlag: "f",
+ wantArg: "a b",
+ wantOptind: 3,
+ },
+ {
+ name: "with mandatory option flag and operand",
+ cmd: "cmd -f 'a b' hello",
+ wantType: OPERAND,
+ wantFlag: "f",
+ wantArg: "a b",
+ wantOptind: 3,
+ },
+ {
+ name: "with mandatory option flag and two spaces between",
+ cmd: "cmd -f a",
+ wantType: OPTION_ARGUMENT,
+ wantFlag: "f",
+ wantArg: "a",
+ wantOptind: 3,
+ },
+ {
+ name: "with mandatory option flag and more spaces",
+ cmd: "cmd -f a ",
+ wantType: OPERAND,
+ wantFlag: "f",
+ wantArg: "a",
+ wantOptind: 3,
+ },
+ {
+ name: "with template data",
+ cmd: "cmd -a {{if .Size}} hello {{else}} {{end}}",
+ wantType: OPERAND,
+ wantFlag: "a",
+ wantArg: "",
+ wantOptind: 2,
+ },
+ {
+ name: "with operand",
+ cmd: "cmd -ab /tmp/aerc-",
+ wantType: OPERAND,
+ wantFlag: "ab",
+ wantArg: "",
+ wantOptind: 2,
+ },
+ {
+ name: "with operand indicator",
+ cmd: "cmd -ab -- /tmp/aerc-",
+ wantType: OPERAND,
+ wantFlag: "ab",
+ wantArg: "",
+ wantOptind: 3,
+ },
+ {
+ name: "hyphen connected command",
+ cmd: "cmd-dmc",
+ wantType: COMMAND,
+ wantFlag: "",
+ wantArg: "",
+ wantOptind: 1,
+ },
+ {
+ name: "incomplete hyphen connected command",
+ cmd: "cmd-",
+ wantType: COMMAND,
+ wantFlag: "",
+ wantArg: "",
+ wantOptind: 1,
+ },
+ {
+ name: "hyphen connected command with option",
+ cmd: "cmd-dmc -a",
+ wantType: SHORT_OPTION,
+ wantFlag: "a",
+ wantArg: "",
+ wantOptind: 2,
+ },
+}
+
+func TestCommands_Parser(t *testing.T) {
+ for i, test := range parserTests {
+ n := len(test.cmd)
+ spaceTerminated := n > 0 && test.cmd[n-1] == ' '
+ parser, err := newParser(test.cmd, "abf:", spaceTerminated)
+ if err != nil {
+ t.Errorf("parser error: %v", err)
+ }
+
+ if test.wantType != parser.kind {
+ t.Errorf("test %d '%s': completion type does not match: "+
+ "want %d, but got %d", i, test.cmd, test.wantType,
+ parser.kind)
+ }
+
+ if test.wantFlag != parser.flag {
+ t.Errorf("test %d '%s': flag does not match: "+
+ "want %s, but got %s", i, test.cmd, test.wantFlag,
+ parser.flag)
+ }
+
+ if test.wantArg != parser.arg {
+ t.Errorf("test %d '%s': arg does not match: "+
+ "want %s, but got %s", i, test.cmd, test.wantArg,
+ parser.arg)
+ }
+
+ if test.wantOptind != parser.optind {
+ t.Errorf("test %d '%s': optind does not match: "+
+ "want %d, but got %d", i, test.cmd, test.wantOptind,
+ parser.optind)
+ }
+ }
+}