예제 #1
0
def test_platform_status():
    with config_context('platform', 'darwin'):
        assert 0 == platform_status(0, 1)(0)
        assert 1 == platform_status(42, 42)(1)
    with config_context('platform', 'linux'):
        assert 0 == platform_status(0, 1)(1)
        assert 42 == platform_status(0, 1)(42)
    with config_context('platform', 'foo'):
        assert 0 == platform_status(42, 42)(0)
예제 #2
0
def suite_or(test):
    """ `||` tests """
    test("echo bonjour|| echo je")
    test("echo bonjour ||echo je")
    test("echo bonjour || echo je")
    test("echo bonjour||", hook=discard, hook_status=platform_status(2, 1))
    test("echo|| ", hook=discard, hook_status=platform_status(2, 1))
    test("echo || ", hook=discard, hook_status=platform_status(2, 1))
    test("echo ||", hook=discard, hook_status=platform_status(2, 1))
    test("||echo", hook=error_line0, hook_status=platform_status(2, 1))
    test("|| echo", hook=error_line0, hook_status=platform_status(2, 1))
    test(" || echo", hook=error_line0, hook_status=platform_status(2, 1))
    test(
        "echo a|| echo b|| echo c|| echo d|| echo e|| echo f|| echo g|| echo h|| echo i||"
        "echo j|| echo k|| echo l|| echo m|| echo c|| echo c|| echo c|| echo c|| echo c||"
        "echo c|| echo c|| echo c|| echo v|| echo w|| echo x|| echo y|| echo z"
    )
    test(
        "echo a || echo b|| echo c ||echo d     ||   echo e   ||echo f||        echo g  ||echo h|| echo i||"
        "echo j  || echo k|| echo l|| echo m|| echo c    || echo c|| echo c    || echo c|| echo c||"
        "echo c|| echo c   || echo c|| echo v   || echo w||    echo x|| echo y    || echo z"
    )
    test("ls doesnotexists || echo bonjour")
    test("ls doesnotexists|| echo bonjour")
    test("echo bonjour|| ls doesnotexists")
    test("ls asdf" + 40 * " || ls asdf", setup="touch a b c")
    test("ls asdf" + 80 * " || ls asdf", setup="touch a b c")
예제 #3
0
def suite_and(test):
    """ `&&` tests """
    test("echo bonjour&& echo je")
    test("echo bonjour &&echo je")
    test("echo bonjour && echo je")
    test("echo bonjour&&", hook=discard, hook_status=platform_status(2, 1))
    test("echo&& ", hook=discard, hook_status=platform_status(2, 1))
    test("echo && ", hook=discard, hook_status=platform_status(2, 1))
    test("echo &&", hook=discard, hook_status=platform_status(2, 1))
    test("&&echo", hook=error_line0, hook_status=platform_status(2, 1))
    test("&& echo", hook=error_line0, hook_status=platform_status(2, 1))
    test(" && echo", hook=error_line0, hook_status=platform_status(2, 1))
    test(
        "echo a&& echo b&& echo c&& echo d&& echo e&& echo f&& echo g&& echo h&& echo i&&"
        "echo j&& echo k&& echo l&& echo m&& echo c&& echo c&& echo c&& echo c&& echo c&&"
        "echo c&& echo c&& echo c&& echo v&& echo w&& echo x&& echo y&& echo z"
    )
    test(
        "echo a && echo b&& echo c &&echo d     &&   echo e   &&echo f&&        echo g  &&echo h&& echo i&&"
        "echo j  && echo k&& echo l&& echo m&& echo c    && echo c&& echo c    && echo c&& echo c&&"
        "echo c&& echo c   && echo c&& echo v   && echo w&&    echo x&& echo y    && echo z"
    )
    test("ls doesnotexists && echo bonjour")
    test("ls doesnotexists&& echo bonjour")
    test("echo bonjour&& ls doesnotexists")
    test("ls " + 40 * " && ls", setup="touch a b c")
    test("ls " + 80 * " && ls", setup="touch a b c")
예제 #4
0
def suite_pipe(test):
    """ `|` tests """
    test("cat /etc/shells | head -c 10")
    test("cat -e /etc/shells | head -c 10")
    test("cat -e /etc/shells | cat -e | head -c 10")
    test("cat -e /etc/shells | cat -e | cat -e | head -c 10")
    test("cat -e /dev/random | head -c 10", hook=discard)
    test("cat -e /dev/random | cat -e | head -c 10", hook=discard)
    test("cat -e /dev/random | cat -e | cat -e | head -c 10", hook=discard)
    test("echo bonjour | cat")
    test("echo bonjour | cat -e")
    test(
        "echo bonjour | cat -e | cat -e | cat -e | cat -e | cat -e | cat -e | cat -e"
    )
    test("ls | cat -e", setup="touch a b c d; mkdir m1 m2 m3")
    test("ls -l | cat -e", setup="touch a b c d; mkdir m1 m2 m3")
    test("ls -l | cat -e | cat | cat | cat",
         setup="touch a b c d; mkdir m1 m2 m3")
    test("ls -l | cat -e | cat -e | cat -e | cat -e",
         setup="touch a b c d; mkdir m1 m2 m3")
    test("ls -l | cat -e < a",
         setup="touch a b c d; mkdir m1 m2 m3; echo bonjour > a")
    test("echo|", hook=discard, hook_status=platform_status(2, 1))
    test("echo |", hook=discard, hook_status=platform_status(2, 1))
    test("echo | ", hook=discard, hook_status=platform_status(2, 1))
    test("|cat", hook=error_line0, hook_status=platform_status(2, 1))
    test("| cat", hook=error_line0, hook_status=platform_status(2, 1))
    test(" | cat", hook=error_line0, hook_status=platform_status(2, 1))
    test("echo a | export A=a; echo $A")
    test("export A=a | cat; echo $A")
    test("echo bonjour | | cat -e",
         hook=error_line0,
         hook_status=platform_status(2, 1))
    test("echo bonjour | asdf")
    test("asdf | echo bonjour")
    test("echo a ||| echo b",
         hook=error_line0,
         hook_status=platform_status(2, 1))
    test("ls " + 40 * " | ls", setup="touch a b c")
    test("ls " + 80 * " | ls", setup="touch a b c")
    test("echo bonjour " + 40 * " | cat -e")
    test("echo bonjour " + 80 * " | cat -e")
    test("ls asdfasdf | echo a")
    test("echo a | ls asdfasdf")
    test("ls asdfasdf | echo a; echo b")
    test("echo a | ls asdfasdf; echo b")
    test("echo a > foo | cat -e", files=["foo"])
    test("echo a >> foo | cat -e", files=["foo"])
    test("echo a | cat -e < foo", setup="echo b > foo")
    test("echo a > bar | cat -e < foo", setup="echo b > foo", files=["bar"])
예제 #5
0
def suite_exit(test):
    """ exit builtin tests """
    test("exit")
    test("exit 1")
    test("exit 2")
    test("exit 3")
    test("exit ' 3'")
    test("exit '\t3'")
    test("exit '\t\f\r 3'")
    test("exit '3 '")
    test("exit '3\t'")
    test("exit '3\r'", hook_status=hooks.platform_status(255, 2))
    test("exit '3\t\f\r '", hook_status=hooks.platform_status(255, 2))
    test("exit '3     a'", hook_status=hooks.platform_status(255, 2))
    test("exit '3\t\t\ta'", hook_status=hooks.platform_status(255, 2))
    test("exit 0")
    test("exit -0")
    test("exit -1")
    test("exit 255")
    test("exit 256")
    test("exit 2000000")
    test("exit -2000000")
    test("exit 2147483647")
    test("exit -2147483648")
    test("exit 2147483648")
    test("exit -2147483649")
    test("exit 3147483648")
    test("exit -3147483649")
    test("exit 4294967295")
    test("exit 4294967296")
    test("exit -9223372036854775808")
    test("exit 9223372036854775807")
    test("exit -9223372036854775809",
         hook_status=hooks.platform_status(255, 2))
    test("exit 9223372036854775808", hook_status=hooks.platform_status(255, 2))
    test("exit 18446744073709551615",
         hook_status=hooks.platform_status(255, 2))
    test("exit 18446744073709551616",
         hook_status=hooks.platform_status(255, 2))
    test("exit +1")
    test("exit +2")
    test("exit +3")
    test("exit +0")
    test("exit +255")
    test("exit +256")
    test("exit +2000000")
    test("exit +2147483647")
    test("exit ++1", hook_status=hooks.platform_status(255, 2))
    test("exit ++2", hook_status=hooks.platform_status(255, 2))
    test("exit ++3", hook_status=hooks.platform_status(255, 2))
    test("exit ++0", hook_status=hooks.platform_status(255, 2))
    test("exit ++255", hook_status=hooks.platform_status(255, 2))
    test("exit ++256", hook_status=hooks.platform_status(255, 2))
    test("exit ++2000000", hook_status=hooks.platform_status(255, 2))
    test("exit ++2147483647", hook_status=hooks.platform_status(255, 2))
    test("exit --1", hook_status=hooks.platform_status(255, 2))
    test("exit --2", hook_status=hooks.platform_status(255, 2))
    test("exit --3", hook_status=hooks.platform_status(255, 2))
    test("exit --0", hook_status=hooks.platform_status(255, 2))
    test("exit --255", hook_status=hooks.platform_status(255, 2))
    test("exit --256", hook_status=hooks.platform_status(255, 2))
    test("exit --2000000", hook_status=hooks.platform_status(255, 2))
    test("exit --2147483647", hook_status=hooks.platform_status(255, 2))
    test("exit bonjour", hook_status=hooks.platform_status(255, 2))
    test("exit 0_", hook_status=hooks.platform_status(255, 2))
    test("exit _0", hook_status=hooks.platform_status(255, 2))
    test("exit 0123456789")
    test("exit -0123456789")
    test("exit 00000000000000000000000000000000000000000000001")
    test("exit 00000000000000000000000000000000000000000000000"
         "00000000000000000000000000000000000000000000001")
    test("exit 00000000000000000000000000000000000000000000000"
         "00000000000000000000000000000000000000000000000")
    test("exit -00000000000000000000000000000000000000000000000"
         "00000000000000000000000000000000000000000000001")
    test(
        "exit -99999999999999999999999999999999999999999999"
        "99999999999999999999999999999999999999999999",
        hook_status=hooks.platform_status(255, 2))
    test(
        "exit 99999999999999999999999999999999999999999999"
        "99999999999999999999999999999999999999999999",
        hook_status=hooks.platform_status(255, 2))
    test("exit 0 bonjour")
    test("exit bonjour 0", hook_status=hooks.platform_status(255, 2))
    test("exit 0 1")
    test("exit 0 1 2 3 4 5 6 7 8 9")
    test("exit " + Config.lorem, hook_status=hooks.platform_status(255, 2))
    test("exit bonjoru; echo should have exited",
         hook_status=hooks.platform_status(255, 2))
    test(
        "exit 99999999999999999999999999999999999999999999999999999; echo should have exited",
        hook_status=hooks.platform_status(255, 2))
    test("exit 9999; echo should have exited")
    test("Exit; echo a")
    test("exiT; echo a")
    test("Exit; echo a", exports={"PATH": "/bin:/usr/bin"})
    test("exiT; echo a", exports={"PATH": "/bin:/usr/bin"})
예제 #6
0
def suite_syntax_error_bonus(test):
    """ separator syntax error bonus test """
    test("< && a", hook=error_line0, hook_status=platform_status(2, 1))
    test("> && a", hook=error_line0, hook_status=platform_status(2, 1))
    test(">> && a", hook=error_line0, hook_status=platform_status(2, 1))
    test("< || a", hook=error_line0, hook_status=platform_status(2, 1))
    test("> || a", hook=error_line0, hook_status=platform_status(2, 1))
    test(">> || a", hook=error_line0, hook_status=platform_status(2, 1))
    test("< ( a", hook=error_line0, hook_status=platform_status(2, 1))
    test("> ( a", hook=error_line0, hook_status=platform_status(2, 1))
    test(">> ( a", hook=error_line0, hook_status=platform_status(2, 1))
    test("< ) a", hook=error_line0, hook_status=platform_status(2, 1))
    test("> ) a", hook=error_line0, hook_status=platform_status(2, 1))
    test(">> ) a", hook=error_line0, hook_status=platform_status(2, 1))
    test("&& < a", hook=error_line0, hook_status=platform_status(2, 1))
    test("&& > a", hook=error_line0, hook_status=platform_status(2, 1))
    test("&& >> a", hook=error_line0, hook_status=platform_status(2, 1))
    test("&& || a", hook=error_line0, hook_status=platform_status(2, 1))
    test("&& ( a", hook=error_line0, hook_status=platform_status(2, 1))
    test("&& ) a", hook=error_line0, hook_status=platform_status(2, 1))
    test("|| < a", hook=error_line0, hook_status=platform_status(2, 1))
    test("|| > a", hook=error_line0, hook_status=platform_status(2, 1))
    test("|| >> a", hook=error_line0, hook_status=platform_status(2, 1))
    test("|| && a", hook=error_line0, hook_status=platform_status(2, 1))
    test("|| ( a", hook=error_line0, hook_status=platform_status(2, 1))
    test("|| ) a", hook=error_line0, hook_status=platform_status(2, 1))
    test("( < a",
         hook=[error_line0, error_eof_to_expected_token],
         hook_status=platform_status(2, 1))
    test("( > a",
         hook=[error_line0, error_eof_to_expected_token],
         hook_status=platform_status(2, 1))
    test("( >> a",
         hook=[error_line0, error_eof_to_expected_token],
         hook_status=platform_status(2, 1))
    test(") < a", hook=error_line0, hook_status=platform_status(2, 1))
    test(") > a", hook=error_line0, hook_status=platform_status(2, 1))
    test(") >> a", hook=error_line0, hook_status=platform_status(2, 1))
    test("( && a", hook=error_line0, hook_status=platform_status(2, 1))
    test("( || a", hook=error_line0, hook_status=platform_status(2, 1))
    test("( ) a", hook=error_line0, hook_status=platform_status(2, 1))
    test(") && a", hook=error_line0, hook_status=platform_status(2, 1))
    test(") || a", hook=error_line0, hook_status=platform_status(2, 1))
    test(") ( a", hook=error_line0, hook_status=platform_status(2, 1))
    test("() a", hook=error_line0, hook_status=platform_status(2, 1))
    test("( a",
         hook=[error_line0, error_eof_to_expected_token],
         hook_status=platform_status(2, 1))
    test(") a", hook=error_line0, hook_status=platform_status(2, 1))
    test(Config.lorem + " && &&" + Config.lorem,
         hook=error_line0,
         hook_status=platform_status(2, 1))
    test(Config.lorem + " || ||" + Config.lorem,
         hook=error_line0,
         hook_status=platform_status(2, 1))
    test(Config.lorem + " ( (" + Config.lorem,
         hook=error_line0,
         hook_status=platform_status(2, 1))
    test(Config.lorem + " ) )" + Config.lorem,
         hook=error_line0,
         hook_status=platform_status(2, 1))
    test("(); () ;() ;() ;() ;() ;() ;() ;() ;() ;a",
         hook=error_line0,
         hook_status=platform_status(2, 1))
예제 #7
0
def suite_syntax_error(test):
    """ separator syntax error test """
    test("< | a", hook=error_line0, hook_status=platform_status(2, 1))
    test("> | a", hook=error_line0, hook_status=platform_status(2, 1))
    test(">> | a", hook=error_line0, hook_status=platform_status(2, 1))
    test("< ; a", hook=error_line0, hook_status=platform_status(2, 1))
    test("> ; a", hook=error_line0, hook_status=platform_status(2, 1))
    test(">> ; a", hook=error_line0, hook_status=platform_status(2, 1))
    test("; | a", hook=error_line0, hook_status=platform_status(2, 1))
    test("; < a", hook=error_line0, hook_status=platform_status(2, 1))
    test("; > a", hook=error_line0, hook_status=platform_status(2, 1))
    test("; >> a", hook=error_line0, hook_status=platform_status(2, 1))
    test("| ; a", hook=error_line0, hook_status=platform_status(2, 1))
    test("| < a", hook=error_line0, hook_status=platform_status(2, 1))
    test("| > a", hook=error_line0, hook_status=platform_status(2, 1))
    test("| >> a", hook=error_line0, hook_status=platform_status(2, 1))
    test("> a ; a", hook=error_line0)
    test("< a ; a", hook=error_line0)
    test(">> a ; a", hook=error_line0)
    test(Config.lorem + " > >" + Config.lorem,
         hook=error_line0,
         hook_status=platform_status(2, 1))
    test(Config.lorem + " < <" + Config.lorem,
         hook=error_line0,
         hook_status=platform_status(2, 1))
    test(Config.lorem + " ; |" + Config.lorem,
         hook=error_line0,
         hook_status=platform_status(2, 1))
    test(Config.lorem + " | ;" + Config.lorem,
         hook=error_line0,
         hook_status=platform_status(2, 1))
예제 #8
0
def suite_end(test):
    """ `;` tests """
    test("echo bonjour; echo je")
    test("echo bonjour ;echo je")
    test("echo bonjour ; echo je")
    test("echo bonjour;")
    test("echo; ")
    test("echo ; ")
    test("echo ;")
    test("; echo", hook=error_line0, hook_status=platform_status(2, 1))
    test(" ;echo", hook=error_line0, hook_status=platform_status(2, 1))
    test(" ; echo", hook=error_line0, hook_status=platform_status(2, 1))
    test(
        "echo a; echo b; echo c; echo d; echo e; echo f; echo g; echo h; echo i;"
        "echo j; echo k; echo l; echo m; echo c; echo c; echo c; echo c; echo c;"
        "echo c; echo c; echo c; echo v; echo w; echo x; echo y; echo z")
    test(
        "echo a ; echo b; echo c ;echo d     ;   echo e   ;echo f;        echo g  ;echo h; echo i;"
        "echo j  ; echo k; echo l; echo m; echo c    ; echo c; echo c    ; echo c; echo c;"
        "echo c; echo c   ; echo c; echo v   ; echo w;    echo x; echo y    ; echo z"
    )
    test("ls doesnotexists ; echo bonjour")
    test("ls doesnotexists; echo bonjour")
    test("echo bonjour; ls doesnotexists")
    test("echo a ; ;", hook=error_line0, hook_status=platform_status(2, 1))
    test("echo a ; ;", hook=error_line0, hook_status=platform_status(2, 1))
    test(";", hook=error_line0, hook_status=platform_status(2, 1))
    test("; ;", hook=error_line0, hook_status=platform_status(2, 1))
    test("; ; ;", hook=error_line0, hook_status=platform_status(2, 1))
    test("echo a ; ; echo b",
         hook=error_line0,
         hook_status=platform_status(2, 1))
    test(";;",
         hook=[error_line0, replace_double(";")],
         hook_status=platform_status(2, 1))
    test(";;;",
         hook=[error_line0, replace_double(";")],
         hook_status=platform_status(2, 1))
    test(";;;;;",
         hook=[error_line0, replace_double(";")],
         hook_status=platform_status(2, 1))
    test("echo a ;; echo b",
         hook=[error_line0, replace_double(";")],
         hook_status=platform_status(2, 1))
    test("echo a ;;;;; echo b",
         hook=[error_line0, replace_double(";")],
         hook_status=platform_status(2, 1))
    test("ls " + 40 * " ; ls", setup="touch a b c")
    test("ls " + 80 * " ; ls", setup="touch a b c")
    test("ls " + 40 * " ; ls" + ";", setup="touch a b c")
    test("ls " + 80 * " ; ls" + ";", setup="touch a b c")
예제 #9
0
def suite_parenthesis(test):
    """ `(`, `)` tests """
    test("(echo bonjour)")
    test("(echo bonjour )")
    test("( echo bonjour )")
    test("(echo a && echo b) && echo c")
    test("(echo a || echo b) || echo c")
    test("(ls doesnotexist || echo b) || echo c")
    test("(echo a || ls doesnotexist) || echo c")
    test("echo aa && (echo b && echo c)")
    test("ls doesnotexist || (echo b && echo c)")
    test("(echo bonjour > f1)", files=["f1"])
    test("(echo bonjour > f1 > f2 > f3)", files=["f1", "f2", "f3"])
    test("(echo bonjour > f1 > f2 > f3 > f4 > f5 > f6 > f7 > f8 > f9)",
         files=["f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9"])
    test("(echo bonjour) > f1", files=["f1"])
    test("(echo bonjour) > f1 > f2 > f3", files=["f1", "f2", "f3"])
    test("(echo bonjour) > f1 > f2 > f3 > f4 > f5 > f6 > f7 > f8 > f9",
         files=["f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9"])
    test("(cat -e < f1)", setup="echo bonjour > f1")
    test("(cat -e < f1 < f2 < f3)",
         setup="touch f1 f2 f3 f4; echo bonjour > f3")
    test("(cat -e < f1 < f2 < f3 < f4 < f5 < f6 < f7 < f8 < f9)",
         setup="touch f1 f2 f3 f4 f5 f6 f7 f8 f9; echo bonjour > f9")
    test("(cat -e) < f1", setup="echo bonjour > f1")
    test("(cat -e) < f1 < f2 < f3",
         setup="touch f1 f2 f3 f4; echo bonjour > f3")
    test("(cat -e) < f1 < f2 < f3 < f4 < f5 < f6 < f7 < f8 < f9",
         setup="touch f1 f2 f3 f4 f5 f6 f7 f8 f9; echo bonjour > f9")
    test("(echo bonjour > f1 > f2 > f3 > f4) > f5 > f6 > f7 > f8 > f9",
         files=["f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9"])
    test("(cat -e < f1 < f2 < f3 < f4) < f5 < f6 < f7 < f8 < f9",
         setup="touch f1 f2 f3 f4 f5 f6 f7 f8 f9; echo bonjour > f4")
    test("(echo bonjour > f1) > f2", files=["f1", "f2"])
    test("(cat -e > f1) < f2", setup="ls -l / > f2", files=["f1"])
    test("(exit); echo bonjour")
    test("(echo bonjour; exit; echo aurevoir)")
    test("(ls && ls)")
    test("(ls doesntexist || ls)")
    test("(ls doesntexist && ls)")
    test("(ls && ls) && echo $?")
    test("(echo a; echo b) | cat -e")
    test("echo bonjour | (cat -e; echo a)")
    test("echo bonjour | (echo a; cat -e)")
    test("(echo a) | (cat -e)")
    test("(echo a; echo b) | (cat -e)")
    test("(echo a) | (cat -e | cat -e)")
    test("(echo a; echo b) | (cat -e | cat -e)")
    test("(echo a; echo b) | cat -e | cat -e")
    test("(echo a); (echo b) | (cat -e) | (cat -e)")
    test("echo a | (cat -e | cat -e | cat -e)")
    test("echo a | (cat -e | cat -e | cat -e) | cat -e")
    test("(echo a) | (cat -e | cat -e | cat -e) | cat -e")
    test("(echo a) | (cat -e | cat -e | cat -e) | (cat -e)")
    test("(echo bonjour ; echo aurevoir) | (cat -e | cat -e) | cat -e")
    test("(    echo salut && echo bonjours )   ; echo comment ca va")
    test("(cd /; echo $PWD; pwd); echo $PWD; pwd")
    test("(export A=a; echo $A); echo $A")
    test("(cat /etc/shells) | (cat -e) | (cat -e) | (cat -e)")
    test(
        "(cat /etc/shells) | (cat -e) | (cat -e) | (cat -e) | (cat -e) | (cat -e) | (cat -e) | (cat -e) | (cat -e)"
    )
    test("(cat /etc/shells | (cat -e) | (cat -e) | (cat -e)",
         hook=[error_line0, error_eof_to_expected_token],
         hook_status=platform_status(2, 1))
    test("(cat /etc/shells) | (cat -e) | (cat -e | (cat -e)",
         hook=[error_line0, error_eof_to_expected_token],
         hook_status=platform_status(2, 1))
예제 #10
0
def suite_quote(test):
    """ double and single quote test, escape in quotes, quote missmatch """
    test("'echo' 'bonjour'")
    test("'echo' 'je' 'suis' 'charles'")
    test('"echo" "bonjour"')
    test('"echo" "je" "suis" "charles"')
    test('echo je\'suis\'"charles"')
    test('echo "je"suis\'charles\'')
    test('echo \'je\'"suis"charles')
    test('echo "\\""')
    test('echo "\\$"')
    test('echo "\\\\"')
    test('echo "\\a"')
    test('echo "\\A"')
    test('ls ""')
    test("ls ''")
    test('ls "" "" "" \'\' """"')
    test("ls '' '' '''' ''")
    test("'     echo' bonjour")
    test("'echo     ' bonjour")
    test('"     echo" bonjour')
    test('"echo     " bonjour')
    test("''echo bonjour")
    test('""echo bonjour')
    test(
        "''''''''''''''''''''''''''''''''''''''''''''''''''''''''''echo bonjour"
    )
    test(
        '""""""""""""""""""""""""""""""""""""""""""""""""""""""""""echo bonjour'
    )
    test("echo'' bonjour")
    test('echo"" bonjour')
    test(
        "echo'''''''''''''''''''''''''''''''''''''''''''''''''''''''''' bonjour"
    )
    test(
        'echo"""""""""""""""""""""""""""""""""""""""""""""""""""""""""" bonjour'
    )
    test("ec''ho bonjour")
    test('ec""ho bonjour')
    test(
        "ec''''''''''''''''''''''''''''''''''''''''''''''''''''''''''ho bonjour"
    )
    test(
        'ec""""""""""""""""""""""""""""""""""""""""""""""""""""""""""ho bonjour'
    )
    test(
        "'''''''e''''''''''c''''''''''''h''''''''o''''''''''''''''''''' bonjour"
    )
    test(
        '"""""""e""""""""""c""""""""""""h""""""""o""""""""""""""""""""" bonjour'
    )
    test("echo '\"'")
    test("echo '\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"'")
    test('echo "\'"')
    test('echo "\'\'\'\'\'\'\'\'\'\'\'\'\'\'\'\'\'\'\'\'\'\'\'\'\'\'"')
    test("echo '",
         hook=hooks.error_line0,
         hook_status=hooks.platform_status(2, 1))
    test('echo "',
         hook=hooks.error_line0,
         hook_status=hooks.platform_status(2, 1))
    test("echo '''",
         hook=hooks.error_line0,
         hook_status=hooks.platform_status(2, 1))
    test('echo """',
         hook=hooks.error_line0,
         hook_status=hooks.platform_status(2, 1))
    test("echo '''''''''''''''''''''''''''''''''''''''''''",
         hook=hooks.error_line0,
         hook_status=hooks.platform_status(2, 1))
    test('echo """""""""""""""""""""""""""""""""""""""""""',
         hook=hooks.error_line0,
         hook_status=hooks.platform_status(2, 1))
    test("echo 'AH\\'")
    test('echo "AH\\"',
         hook=hooks.error_line0,
         hook_status=hooks.platform_status(2, 1))
    test('echo "AH\\""')
    test("echo '\\''",
         hook=hooks.error_line0,
         hook_status=hooks.platform_status(2, 1))
    test('echo "\\""')
    test('echo "\\\\""',
         hook=hooks.error_line0,
         hook_status=hooks.platform_status(2, 1))
    test('echo bonjour > "fi le"', files=['fi le'])
    test("echo bonjour > 'fi le'", files=['fi le'])