import pytest from openhands.runtime.utils.bash import escape_bash_special_chars, split_bash_commands def test_split_commands_util(): cmds = [ 'ls -l', 'echo -e "hello\nworld"', """ echo -e "hello it\\'s me" """.strip(), """ echo \\ -e 'hello' \\ -v """.strip(), """ echo -e 'hello\\nworld\\nare\\nyou\\nthere?' """.strip(), """ echo -e 'hello world are you\\n there?' """.strip(), """ echo -e 'hello world " ' """.strip(), """ kubectl apply -f - < output.txt', 'cat file \\\\> output.txt'), ('cat \\< input.txt', 'cat \\\\< input.txt'), # Quoted strings should remain unchanged ('echo "test \\; unchanged"', 'echo "test \\; unchanged"'), ("echo 'test \\| unchanged'", "echo 'test \\| unchanged'"), # Mixed quoted and unquoted ( 'echo "quoted \\;" \\; "more" \\| grep', 'echo "quoted \\;" \\\\; "more" \\\\| grep', ), # Multiple escapes in sequence ('cmd1 \\;\\|\\& cmd2', 'cmd1 \\\\;\\\\|\\\\& cmd2'), # Commands with other backslashes ('echo test\\ntest', 'echo test\\ntest'), ('echo "test\\ntest"', 'echo "test\\ntest"'), # Edge cases ('', ''), # Empty string ('\\\\', '\\\\'), # Double backslash ('\\"', '\\"'), # Escaped quote ] for input_cmd, expected in test_cases: result = escape_bash_special_chars(input_cmd) assert ( result == expected ), f'Failed on input "{input_cmd}"\nExpected: "{expected}"\nGot: "{result}"' def test_escape_bash_special_chars_with_invalid_syntax(): invalid_inputs = [ 'echo "unclosed quote', "echo 'unclosed quote", 'cat < out.txt', 'echo "$(pwd)" && cat file \\\\> out.txt', ), # Multiple chains ('cmd1 && cmd2 && cmd3', 'cmd1 && cmd2 && cmd3'), ( 'cmd1 \\; ls && cmd2 \\| grep && cmd3', 'cmd1 \\\\; ls && cmd2 \\\\| grep && cmd3', ), ] for input_cmd, expected in test_cases: result = escape_bash_special_chars(input_cmd) assert ( result == expected ), f'Failed on input "{input_cmd}"\nExpected: "{expected}"\nGot: "{result}"'