def test_break(): up = 0 down = 3 def count_down(*args, env=None, stdin=None, stdout=None, stderr=None): nonlocal down stdout.write(b"DOWN\n") if down <= 0: return 0 down -= 1 return 1 def count_up(*args, env=None, stdin=None, stdout=None, stderr=None): nonlocal up stdout.write(b"UP\n") up += 1 return 0 cmd = While( Command([Word([Id("up")])]), If([(Command([Word([Id("down")])]), Command([Word([Id("break")])]))])) env = make_env() env.builtins.update({"up": count_up, "down": count_down}) out = io.BytesIO() assert cmd.execute(env, output=out) == 0 assert up == 4 assert out.getvalue().decode( "utf-8") == "UP\nDOWN\nUP\nDOWN\nUP\nDOWN\nUP\nDOWN\n"
def test_run_a_command(): cmd = Command([ Word([Id("echo")]), Word([STAR]), ]) env = make_env() with make_dirs("a", "b", "c", "d", "e") as d: with cwd(d): assert cmd.evaluate(env) == "a b c d e"
def test_fixed_pieces(): cmd = Command([ Word([Id("echo")]), Word([STAR, ConstantString("/..")]), ]) env = make_env() with make_dirs("a", "b", "c", "d", TOUCH, "e", "f", "g") as d: with cwd(d): assert cmd.evaluate(env) == "a/.. b/.. c/.. d/.."
def test_invoke_a_function(): env = make_env() env.functions["f"] = Function( Id("f"), CommandSequence([Command([Word([Id("echo")]), Word([VarRef("1")])])])) cmd = CommandSequence([ Command([Word([Id("f")]), Word([ConstantString("hello world")])]), ]) assert cmd.evaluate(env) == "hello world"
def test_while(): for i, o in (("0</dev/null while a; do b; done >>/tmp/x", CommandSequence([ While( CommandSequence( [Command([Word([ConstantString("a")])])]), CommandSequence( [Command([Word([ConstantString("b")])])]), ).with_redirect(RedirectFrom(0, devnull), RedirectTo(1, w("/tmp/x"), append=True)) ])), ): cmd = command_sequence.parse(i) assert cmd == o assert cmd.redirects == o.redirects
def test_if(): for i, o in (("0</dev/null if a; then b; fi >>/tmp/x", CommandSequence([ If([ (CommandSequence( [Command([Word([ConstantString("a")])])]), CommandSequence( [Command([Word([ConstantString("b")])])])) ]).with_redirect(RedirectFrom(0, devnull), RedirectTo(1, w("/tmp/x"), append=True)) ])), ): cmd = command_sequence.parse(i) assert cmd == o assert cmd.redirects == o.redirects
def test_return(): env = make_env() env['x'] = "30" env.functions["f"] = Function( Id("f"), CommandSequence([ Command([Word([Id("return")]), Word([VarRef("x")])]), ])) cmd = CommandSequence([ Command([Word([Id("f")]), Word([ConstantString("hello world")])]), ]) assert cmd.evaluate(env) == "" assert env['?'] == "30"
def test_more_dots(): word = Word([ConstantString("."), STAR]) env = make_env() with make_dirs("a", "b", ".c", ".d", TOUCH, "e", ".f") as d: with cwd(d): ans = expand(env, word, ".") assert ans == [".c", ".d", ".f"]
def test_word_expand_rec(): word = Word([ConstantString("a/"), STARSTAR, ConstantString("/e")]) env = make_env() with make_dirs("a/b*/cfood/e", "a/b*/cd/e/f") as d: with cwd(d): ans = expand(env, word, ".") assert ans == ["a/b*/cd/e", "a/b*/cfood/e"]
def test_files_too(): word = Word([STAR]) env = make_env() with make_dirs("a", "b", ".c", ".d", TOUCH, "e", ".f") as d: with cwd(d): ans = expand(env, word, ".") assert ans == ["a", "b", "e"]
def test_no_dots(): word = Word([STAR, ConstantString("/..")]) env = make_env() with make_dirs("a", "b", ".c", ".d", TOUCH, "e", ".f") as d: with cwd(d): ans = expand(env, word, ".") assert ans == ["a/..", "b/.."]
def test_locals(): env = make_env() env['x'] = "1" env.functions["f"] = Function( Id("f"), CommandSequence([ Command([ Word([Id("local")]), Word([Id("x"), Token("="), VarRef("1")]) ]), Command([Word([Id("echo")]), Word([VarRef("x")])]), ])) cmd = CommandSequence([ Command([Word([Id("f")]), Word([ConstantString("hello world")])]), ]) assert cmd.evaluate(env) == "hello world" assert env['x'] == "1"
import pytest from psh.model import Word, ConstantString, VarRef, Id, VarOp from psh.glob import STAR from psh.local import make_env @pytest.mark.parametrize(("pattern", "value", "expected"), ( (Word([VarRef(ConstantString("a"))]), "xx", "xx"), (Word([VarRef(ConstantString("a"), double_quoted=True)], double_quoted=True), "xx yy", "xx yy"), (Word([VarOp(VarRef(ConstantString("a")), '#', Word([Id("x")]))]), "xx123xx", "x123xx"), (Word([VarOp(VarRef(ConstantString("a")), '#', Word([STAR, Id("x")]))]), "xx123xx", "x123xx"), (Word([VarOp(VarRef(ConstantString("a")), '#', Word([Id("x"), STAR]))]), "xx123xx", "x123xx"), (Word([VarOp(VarRef(ConstantString("a")), '#', Word([STAR, Id("x"), STAR]))]), "xx123xx", "x123xx"), (Word([VarOp(VarRef(ConstantString("a")), '##', Word([Id("x")]))]), "xx123xx", "x123xx"), (Word([VarOp(VarRef(ConstantString("a")), '##', Word([STAR, Id("x")]))]), "xx123xx", ""), (Word([VarOp(VarRef(ConstantString("a")), '##', Word([Id("x"), STAR]))]), "xx123xx", ""), (Word([VarOp(VarRef(ConstantString("a")), '##', Word([STAR, Id("x"), STAR]))]), "xx123xx", ""), (Word([VarOp(VarRef(ConstantString("a")), '%', Word([Id("x")]))]), "xx123xx", "xx123x"), (Word([VarOp(VarRef(ConstantString("a")), '%', Word([STAR, Id("x")]))]), "xx123xx", "xx123x"), (Word([VarOp(VarRef(ConstantString("a")), '%', Word([Id("x"), STAR]))]), "xx123xx", "xx123x"), (Word([VarOp(VarRef(ConstantString("a")), '%', Word([STAR, Id("x"), STAR]))]), "xx123xx", "xx123x"), (Word([VarOp(VarRef(ConstantString("a")), '%%', Word([Id("x")]))]), "xx123xx", "xx123x"), (Word([VarOp(VarRef(ConstantString("a")), '%%', Word([STAR, Id("x")]))]), "xx123xx", ""), (Word([VarOp(VarRef(ConstantString("a")), '%%', Word([Id("x"), STAR]))]), "xx123xx", ""), (Word([VarOp(VarRef(ConstantString("a")), '%%', Word([STAR, Id("x"), STAR]))]), "xx123xx", ""),
import pytest from psh.parser import command_sequence from psh.model import Word, ConstantString, Command, CommandSequence from psh.glob import STAR, STARSTAR @pytest.mark.parametrize(("text", "expected"), ( ('"*"', CommandSequence( [Command([Word([ConstantString("*")], double_quoted=True)])])), ("'*'", CommandSequence( [Command([Word([ConstantString("*")], double_quoted=False)])])), ('\\*', CommandSequence( [Command([Word([ConstantString("*")], double_quoted=False)])])), ('*', CommandSequence([Command([Word([STAR], double_quoted=False)])])), ), ids=lambda x: x.replace(" ", "_").replace('"', '%') if isinstance(x, str) else None) def test_dq(text, expected): assert command_sequence.parse(text) == expected
import pytest from psh.parser import command_sequence from psh.model import Word, Id, Token, ConstantString, CommandSequence, Command, For, VarRef, RedirectTo, RedirectFrom w = lambda w: Word([Id(w)]) i = Id("i") cmds = lambda *cs: CommandSequence([Command([c]) for c in cs]) devnull = Word([ConstantString("/dev/null")]) @pytest.mark.parametrize(("text", "expected"), ( ("for i; do done", CommandSequence([ For(i, [VarRef(Token("@"))], CommandSequence([])) ])), ("for i\ndo\ndone", CommandSequence([ For(i, [VarRef(Token("@"))], CommandSequence([])) ])), ("for i in a b c; do foo; done", CommandSequence([ For(i, [w("a"), w("b"), w("c")], cmds(w("foo"))) ])), (">/dev/null for i in a b c\n\ndo\n\nfoo\n\nbar\n\ndone </dev/null", CommandSequence([ For(i, [w("a"), w("b"), w("c")], cmds(w("foo"), w("bar"))) .with_redirect(RedirectTo(1, devnull), RedirectFrom(0, devnull)) ])), ), ids=lambda x: x.replace(" ", "_") if isinstance(x, str) else x) def test_basic(text, expected): cmd = command_sequence.parse(text) assert cmd == expected
import pytest from psh.parser import command_sequence from psh.model import Word, ConstantString, Command, VarRef, Id, Token, CommandSequence, CommandPipe, While, If while_ab_cd = CommandSequence([ While( CommandSequence([ Command([Word([Id("a")])]), Command([Word([Id("b")])]), ]), CommandSequence([ Command([Word([Id("c")])]), Command([Word([Id("d")])]), ])), ]) if_seq = CommandSequence([ If([ (CommandSequence([ Command([Word([Id("a")])]), Command([Word([Id("b")])]), ]), CommandSequence([ Command([Word([Id("c")])]), Command([Word([Id("d")])]), ])), (CommandSequence([ Command([Word([Id("e")])]), Command([Word([Id("f")])]), ]),
import pytest from psh.parser import command_sequence from psh.model import Word, Id, CommandSequence, Command, Case from psh.glob import STAR w = lambda w: Word([Id(w)]) a = w("a") x = w("x") cmd = lambda *cs: CommandSequence([Command([*cs])]) @pytest.mark.parametrize(("text", "expected"), ( ("case a in esac", CommandSequence([Case(a)])), ("case a in (x) ;; esac", CommandSequence([Case(a).with_case(x, CommandSequence([]))])), ("case a in x) foo ;; *) bar;; esac", CommandSequence([ Case(a).with_case(x, cmd(w("foo"))).with_case(Word([STAR]), cmd(w("bar"))) ])), ("case a in\nx)\nfoo\n;;\n*)\nbar;;\nesac", CommandSequence([ Case(a).with_case(x, cmd(w("foo"))).with_case(Word([STAR]), cmd(w("bar"))) ])), ), ids=lambda x: x.replace(" ", "_") if isinstance(x, str) else x) def test_basic(text, expected): cmd = command_sequence.parse(text)
import pytest from psh.parser import command, command_sequence, ParseError from psh.model import (Word, ConstantString, Command, VarRef, Id, Token, CommandSequence, CommandPipe, While, If, RedirectFrom, RedirectTo, RedirectDup, RedirectHere) cat = lambda: Command([Word([Id("cat")])]) w = lambda w: Word([ConstantString(w)]) devnull = w("/dev/null") @pytest.mark.parametrize(("text", "expected"), ( ("0</dev/null cat", cat().with_redirect(RedirectFrom(0, devnull))), ("1>/dev/null cat", cat().with_redirect(RedirectTo(1, devnull))), ("2>>/dev/null cat", cat().with_redirect( RedirectTo(2, devnull, append=True))), ("3>&- cat", cat().with_redirect(RedirectDup(3, w("-")))), ("0<&- cat", cat().with_redirect(RedirectDup(0, w("-")))), ("2>&1 cat", cat().with_redirect(RedirectDup(2, w("1")))), ("0<&6 cat", cat().with_redirect(RedirectDup(0, w("6")))), ("</dev/null cat", cat().with_redirect(RedirectFrom(0, devnull))), (">/dev/null cat", cat().with_redirect(RedirectTo(1, devnull))), (">>/dev/null cat", cat().with_redirect(RedirectTo(1, devnull, append=True))), (">&- cat", cat().with_redirect(RedirectDup(1, w("-")))), ("<&- cat", cat().with_redirect(RedirectDup(0, w("-")))), (">&2 cat", cat().with_redirect(RedirectDup(1, w("2")))), ("<&6 cat", cat().with_redirect(RedirectDup(0, w("6")))), ("cat <<'EOF'\nhello $world\nEOF\n", cat().with_redirect( RedirectHere(
import pytest from psh.parser import command, command_sequence from psh.model import Word, ConstantString, Command, VarRef, Id, Token, CommandSequence, CommandPipe, While, If @pytest.mark.parametrize(("text", "expected"), ( ('"hello world"', CommandSequence([ Command([Word([ConstantString("hello world")], double_quoted=True)]) ])), ('hello" world"', CommandSequence([ Command([ Word([ Id('hello'), Word([ConstantString(' world')], double_quoted=True) ], double_quoted=False) ]) ])), ("", CommandSequence([Command([])])), ('""', CommandSequence( [Command([Word([ConstantString('')], double_quoted=True)])])), ('"$a $b"', CommandSequence([ Command([ Word([ VarRef(ConstantString("a"), double_quoted=True), ConstantString(" "),
import pytest from psh.parser import command_sequence from psh.model import Word, ConstantString, Command, VarRef, Id, CommandSequence, VarOp cmd = lambda *ws: CommandSequence([Command([*ws])]) cat = Word([Id("cat")]) @pytest.mark.parametrize(("text", "expected"), ( ("cat $a", cmd( cat, Word([VarRef(ConstantString("a"))]), )), ('cat "$a"', cmd( cat, Word([VarRef(ConstantString("a"), double_quoted=True)], double_quoted=True), )), ('cat ${a}', cmd( cat, Word([VarRef(ConstantString("a"))]), )), ("cat '$a'", cmd( cat, Word([ConstantString("$a")]), )), ("cat '${a}'", cmd( cat, Word([ConstantString("${a}")]),
import parsy import pytest from psh.parser import command, command_sequence, backtick from psh.model import Word, ConstantString, Assignment, Command, VarRef, Id, Token, CommandSequence, CommandPipe, While, If from psh.local import make_env foo = Word([ConstantString("foo")]) tick = lambda content: Word([CommandSequence([Command([content])])]) @pytest.mark.parametrize(("text", "expected"), ( ("`foo`", Command([tick(foo)])), (r"`\`foo\``", Command([tick(tick(foo))])), )) def test_backtick(text, expected): cmd = command.parse(text) assert cmd == expected assert cmd.assignments == expected.assignments cmd = command_sequence.parse(text) assert cmd == CommandSequence([expected]) def test_basic(): backtick.parse("``")
import pytest from psh.parser import command_sequence from psh.model import Word, ConstantString, Command, VarRef, Id, Token, CommandSequence, Function @pytest.mark.parametrize( ("text", "expected"), (("f() { echo }", CommandSequence([ Function(Id("f"), CommandSequence([Command([Word([Id("echo")])])])) ])), ), ids=lambda x: x.replace(" ", "_").replace("\n", "%") if isinstance(x, str) else None) def test_basic(text, expected): cmd = command_sequence.parse(text) assert cmd == expected
import parsy import pytest from psh.parser import command, command_sequence from psh.model import Word, ConstantString, Assignment, Command, VarRef, Id, Token, CommandSequence, CommandPipe, While, If from psh.local import make_env @pytest.mark.parametrize(("text", "expected"), ( ("cat foo bar", Command([ Word([ConstantString("cat")]), Word([ConstantString("foo")]), Word([ConstantString("bar")]), ])), ("'hello'", Command([Word([ConstantString("hello")])])), ("'hel\nlo'", Command([Word([ConstantString("hel\nlo")])])), ("'hello'' world'", Command([Word([ConstantString("hello"), ConstantString(" world")])])), ("$(cat $foo $bar)", Command([ Word([ CommandSequence([ Command([ Word([ConstantString("cat")]), Word([VarRef(ConstantString("foo"))]), Word([VarRef(ConstantString("bar"))]) ]) ]) ])
import pytest from psh.model import Word, Id, CommandSequence, Command, Case, VarRef, ConstantString from psh.glob import STAR from psh.local import make_env w = lambda w: Word([Id(w)]) a = Word([VarRef(Id("a"))]) echo = lambda out: CommandSequence( [Command([Word([Id("echo")]), Word([ConstantString(out)])])]) x = w("x") cmd = lambda *cs: CommandSequence([Command([*cs])]) star = Word([STAR]) @pytest.mark.parametrize(("cmd", "variable", "expected"), ( (CommandSequence([Case(a)]), "", ""), (CommandSequence([Case(a).with_case(x, echo("foo"))]), "", ""), (CommandSequence([Case(a).with_case(x, echo("foo"))]), "y", ""), (CommandSequence([Case(a).with_case(x, echo("foo"))]), "x", "foo"), (CommandSequence([ Case(a).with_case(x, echo("foo")).with_case(star, echo("bar")) ]), "", "bar"), (CommandSequence([ Case(a).with_case(x, echo("foo")).with_case(star, echo("bar")) ]), "y", "bar"), (CommandSequence([ Case(a).with_case(x, echo("foo")).with_case(star, echo("bar")) ]), "x", "foo"), ),