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 - < index.rst' # Should not raise any exception try: result = split_bash_commands(over_escaped_command) # If parsing fails, it should return the original command assert result == [over_escaped_command] except Exception as e: # This is the error we're trying to fix pytest.fail(f'split_bash_commands raised {type(e).__name__} unexpectedly: {e}') @pytest.fixture def sample_commands(): return [ 'ls -l', 'echo "Hello, world!"', 'cd /tmp && touch test.txt', 'echo -e "line1\\nline2\\nline3"', 'grep "pattern" file.txt | sort | uniq', 'for i in {1..5}; do echo $i; done', 'cat < 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}"' )