100 lines
3.1 KiB
Python
100 lines
3.1 KiB
Python
"""Unit tests for docker_agent_sandbox.tools._utils — no Docker required."""
|
|
|
|
import pytest
|
|
|
|
from docker_agent_sandbox.tools._utils import (
|
|
_MAX_OUTPUT_CHARS,
|
|
_MAX_OUTPUT_LINES,
|
|
_TRUNCATION_NOTICE,
|
|
_parent,
|
|
truncate_output,
|
|
)
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# truncate_output
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
def test_truncate_output_short_string_unchanged():
|
|
assert truncate_output("hello world") == "hello world"
|
|
|
|
|
|
def test_truncate_output_empty_string():
|
|
assert truncate_output("") == ""
|
|
|
|
|
|
def test_truncate_output_exactly_at_line_limit():
|
|
output = "line\n" * _MAX_OUTPUT_LINES
|
|
assert truncate_output(output) == output
|
|
|
|
|
|
def test_truncate_output_one_over_line_limit():
|
|
output = "line\n" * (_MAX_OUTPUT_LINES + 1)
|
|
result = truncate_output(output)
|
|
assert _TRUNCATION_NOTICE in result
|
|
# 200 "line\n" kept + notice; the 201st "line" must not appear
|
|
assert result.count("line\n") == _MAX_OUTPUT_LINES
|
|
|
|
|
|
def test_truncate_output_line_limit_keeps_first_200():
|
|
output = "line\n" * 250
|
|
result = truncate_output(output)
|
|
assert result.startswith("line\n" * _MAX_OUTPUT_LINES)
|
|
assert _TRUNCATION_NOTICE in result
|
|
|
|
|
|
def test_truncate_output_exactly_at_char_limit():
|
|
output = "x" * _MAX_OUTPUT_CHARS
|
|
assert truncate_output(output) == output
|
|
|
|
|
|
def test_truncate_output_one_over_char_limit():
|
|
output = "x" * (_MAX_OUTPUT_CHARS + 1)
|
|
result = truncate_output(output)
|
|
assert _TRUNCATION_NOTICE in result
|
|
# Exactly _MAX_OUTPUT_CHARS x's are kept before the notice
|
|
assert result.startswith("x" * _MAX_OUTPUT_CHARS)
|
|
assert result[_MAX_OUTPUT_CHARS] != "x"
|
|
|
|
|
|
def test_truncate_output_char_limit_takes_first_20000():
|
|
output = "x" * 25_000
|
|
result = truncate_output(output)
|
|
assert result.startswith("x" * _MAX_OUTPUT_CHARS)
|
|
assert _TRUNCATION_NOTICE in result
|
|
|
|
|
|
def test_truncate_output_line_limit_checked_before_char_limit():
|
|
# 201 lines of 200 chars each = 201 * 201 = ~40k chars (> char limit too).
|
|
# Lines are checked first, so only the line-limit truncation notice appears.
|
|
output = ("x" * 200 + "\n") * 201
|
|
result = truncate_output(output)
|
|
assert _TRUNCATION_NOTICE in result
|
|
# After line truncation the result is 200 * 201 = 40200 chars + notice,
|
|
# which is still > _MAX_OUTPUT_CHARS, so the char truncation fires too.
|
|
# Either way the result must be shorter than the input.
|
|
assert len(result) < len(output)
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# _parent
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"path, expected",
|
|
[
|
|
("/foo/bar/baz.txt", "/foo/bar"),
|
|
("/foo/bar/baz/", "/foo/bar"), # trailing slash stripped before dirname
|
|
("/foo/bar", "/foo"),
|
|
("/foo", "/"),
|
|
("foo/bar/baz", "foo/bar"),
|
|
("foo/bar", "foo"),
|
|
("foo", "."),
|
|
("", "."),
|
|
],
|
|
)
|
|
def test_parent(path, expected):
|
|
assert _parent(path) == expected
|