package main import ( "reflect" "testing" ) // These inputs are used in scan and parse tests. var gTests = []struct { inp string toks []string exprs []Expr }{ { "", []string{}, nil, }, { "# comments start with '#'", []string{}, nil, }, { "echo hello", []string{"echo", "hello", "\n"}, []Expr{&CallExpr{"echo", []string{"hello"}}}, }, { "echo hello world", []string{"echo", "hello", "world", "\n"}, []Expr{&CallExpr{"echo", []string{"hello", "world"}}}, }, { "echo 'hello world'", []string{"echo", "hello world", "\n"}, []Expr{&CallExpr{"echo", []string{"hello world"}}}, }, { `echo hello\ world`, []string{"echo", "hello world", "\n"}, []Expr{&CallExpr{"echo", []string{"hello world"}}}, }, { `echo hello\ world`, []string{"echo", "hello\tworld", "\n"}, []Expr{&CallExpr{"echo", []string{"hello\tworld"}}}, }, { "echo hello\\\nworld", []string{"echo", "hello\nworld", "\n"}, []Expr{&CallExpr{"echo", []string{"hello\nworld"}}}, }, { `echo hello\aworld`, []string{"echo", "helloworld", "\n"}, []Expr{&CallExpr{"echo", []string{"helloworld"}}}, }, { "set hidden # trailing comments are allowed", []string{"set", "hidden", "\n"}, []Expr{&SetExpr{"hidden", ""}}, }, { "set hidden; set preview", []string{"set", "hidden", ";", "set", "preview", "\n"}, []Expr{&SetExpr{"hidden", ""}, &SetExpr{"preview", ""}}, }, { "set hidden\nset preview", []string{"set", "hidden", "\n", "set", "preview", "\n"}, []Expr{&SetExpr{"hidden", ""}, &SetExpr{"preview", ""}}, }, { "set ratios 1:2:3", []string{"set", "ratios", "1:2:3", "\n"}, []Expr{&SetExpr{"ratios", "1:2:3"}}, }, { "set ratios 1:2:3;", []string{"set", "ratios", "1:2:3", ";"}, []Expr{&SetExpr{"ratios", "1:2:3"}}, }, { ":set ratios 1:2:3", []string{":", "set", "ratios", "1:2:3", "\n", "\n"}, []Expr{&ListExpr{[]Expr{&SetExpr{"ratios", "1:2:3"}}}}, }, { ":set ratios 1:2:3\nset hidden", []string{":", "set", "ratios", "1:2:3", "\n", "\n", "set", "hidden", "\n"}, []Expr{&ListExpr{[]Expr{&SetExpr{"ratios", "1:2:3"}}}, &SetExpr{"hidden", ""}}, }, { ":set ratios 1:2:3;", []string{":", "set", "ratios", "1:2:3", ";", "\n"}, []Expr{&ListExpr{[]Expr{&SetExpr{"ratios", "1:2:3"}}}}, }, { ":set ratios 1:2:3;\nset hidden", []string{":", "set", "ratios", "1:2:3", ";", "\n", "set", "hidden", "\n"}, []Expr{&ListExpr{[]Expr{&SetExpr{"ratios", "1:2:3"}}}, &SetExpr{"hidden", ""}}, }, { "map gh cd ~", []string{"map", "gh", "cd", "~", "\n"}, []Expr{&MapExpr{"gh", &CallExpr{"cd", []string{"~"}}}}, }, { "map gh cd ~;", []string{"map", "gh", "cd", "~", ";"}, []Expr{&MapExpr{"gh", &CallExpr{"cd", []string{"~"}}}}, }, { "map gh :cd ~", []string{"map", "gh", ":", "cd", "~", "\n", "\n"}, []Expr{&MapExpr{"gh", &ListExpr{[]Expr{&CallExpr{"cd", []string{"~"}}}}}}, }, { "map gh :cd ~;", []string{"map", "gh", ":", "cd", "~", ";", "\n"}, []Expr{&MapExpr{"gh", &ListExpr{[]Expr{&CallExpr{"cd", []string{"~"}}}}}}, }, { "cmd usage $du -h . | less", []string{"cmd", "usage", "$", "du -h . | less", "\n"}, []Expr{&CmdExpr{"usage", &ExecExpr{"$", "du -h . | less"}}}, }, { "cmd 世界 $echo 世界", []string{"cmd", "世界", "$", "echo 世界", "\n"}, []Expr{&CmdExpr{"世界", &ExecExpr{"$", "echo 世界"}}}, }, { "map u usage", []string{"map", "u", "usage", "\n"}, []Expr{&MapExpr{"u", &CallExpr{"usage", nil}}}, }, { "map u usage;", []string{"map", "u", "usage", ";"}, []Expr{&MapExpr{"u", &CallExpr{"usage", nil}}}, }, { "map u :usage", []string{"map", "u", ":", "usage", "\n", "\n"}, []Expr{&MapExpr{"u", &ListExpr{[]Expr{&CallExpr{"usage", nil}}}}}, }, { "map u :usage;", []string{"map", "u", ":", "usage", ";", "\n"}, []Expr{&MapExpr{"u", &ListExpr{[]Expr{&CallExpr{"usage", nil}}}}}, }, { "map r push :rename", []string{"map", "r", "push", ":rename", "\n"}, []Expr{&MapExpr{"r", &CallExpr{"push", []string{":rename"}}}}, }, { "map r push :rename;", []string{"map", "r", "push", ":rename;", "\n"}, []Expr{&MapExpr{"r", &CallExpr{"push", []string{":rename;"}}}}, }, { "map r push :rename # trailing comments are allowed after a space", []string{"map", "r", "push", ":rename", "\n"}, []Expr{&MapExpr{"r", &CallExpr{"push", []string{":rename"}}}}, }, { "map r :push :rename", []string{"map", "r", ":", "push", ":rename", "\n", "\n"}, []Expr{&MapExpr{"r", &ListExpr{[]Expr{&CallExpr{"push", []string{":rename"}}}}}}, }, { "map r :push :rename ; set hidden", []string{"map", "r", ":", "push", ":rename", ";", "set", "hidden", "\n", "\n"}, []Expr{&MapExpr{"r", &ListExpr{[]Expr{&CallExpr{"push", []string{":rename"}}, &SetExpr{"hidden", ""}}}}}, }, { "map u $du -h . | less", []string{"map", "u", "$", "du -h . | less", "\n"}, []Expr{&MapExpr{"u", &ExecExpr{"$", "du -h . | less"}}}, }, { "cmd usage $du -h \"$1\" | less", []string{"cmd", "usage", "$", `du -h "$1" | less`, "\n"}, []Expr{&CmdExpr{"usage", &ExecExpr{"$", `du -h "$1" | less`}}}, }, { "map u usage /", []string{"map", "u", "usage", "/", "\n"}, []Expr{&MapExpr{"u", &CallExpr{"usage", []string{"/"}}}}, }, { "map ss :set sortby size; set showinfo size", []string{"map", "ss", ":", "set", "sortby", "size", ";", "set", "showinfo", "size", "\n", "\n"}, []Expr{&MapExpr{"ss", &ListExpr{[]Expr{&SetExpr{"sortby", "size"}, &SetExpr{"showinfo", "size"}}}}}, }, { "map ss :set sortby size; set showinfo size;", []string{"map", "ss", ":", "set", "sortby", "size", ";", "set", "showinfo", "size", ";", "\n"}, []Expr{&MapExpr{"ss", &ListExpr{[]Expr{&SetExpr{"sortby", "size"}, &SetExpr{"showinfo", "size"}}}}}, }, { `cmd gohome :{{ cd ~ set hidden }}`, []string{"cmd", "gohome", ":", "{{", "cd", "~", "\n", "set", "hidden", "\n", "}}", "\n"}, []Expr{&CmdExpr{"gohome", &ListExpr{[]Expr{ &CallExpr{"cd", []string{"~"}}, &SetExpr{"hidden", ""}}}, }}, }, { `map gh :{{ cd ~ set hidden }}`, []string{"map", "gh", ":", "{{", "cd", "~", "\n", "set", "hidden", "\n", "}}", "\n"}, []Expr{&MapExpr{"gh", &ListExpr{[]Expr{ &CallExpr{"cd", []string{"~"}}, &SetExpr{"hidden", ""}}}, }}, }, { `map c ${{ mkdir foo IFS=':'; cp ${fs} foo tar -czvf "foo.tar.gz" foo rm -rf foo }}`, []string{"map", "c", "$", "{{", ` mkdir foo IFS=':'; cp ${fs} foo tar -czvf "foo.tar.gz" foo rm -rf foo `, "}}", "\n"}, []Expr{&MapExpr{"c", &ExecExpr{"$", ` mkdir foo IFS=':'; cp ${fs} foo tar -czvf "foo.tar.gz" foo rm -rf foo `}}}, }, { `cmd compress ${{ mkdir "$1" IFS=':'; cp ${fs} "$1" tar -czvf "$1.tar.gz" "$1" rm -rf "$1" }}`, []string{"cmd", "compress", "$", "{{", ` mkdir "$1" IFS=':'; cp ${fs} "$1" tar -czvf "$1.tar.gz" "$1" rm -rf "$1" `, "}}", "\n"}, []Expr{&CmdExpr{"compress", &ExecExpr{"$", ` mkdir "$1" IFS=':'; cp ${fs} "$1" tar -czvf "$1.tar.gz" "$1" rm -rf "$1" `}}}, }, } func TestSplitKeys(t *testing.T) { inps := []struct { s string keys []string }{ {"", nil}, {"j", []string{"j"}}, {"jk", []string{"j", "k"}}, {"1j", []string{"1", "j"}}, {"42j", []string{"4", "2", "j"}}, {"", []string{""}}, {"j", []string{"j", ""}}, {"jk", []string{"j", "", "k"}}, {"1jk", []string{"1", "j", "", "k"}}, {"1j1k", []string{"1", "j", "", "1", "k"}}, {"<>", []string{"<>"}}, {"", []string{""}}, {">", []string{">", ""}}, {">>", []string{">", "", ">"}}, } for _, inp := range inps { if keys := splitKeys(inp.s); !reflect.DeepEqual(keys, inp.keys) { t.Errorf("at input '%s' expected '%v' but got '%v'", inp.s, inp.keys, keys) } } }