scripts/tests/reproduction_utils/test_infra_helpers.py
scripts/tests/reproduction_utils/test_infra_helpers.pyBrowse 41 files
1,344 tokens
5,459 bytes
Token encoding: o200k_base
Snapshot a9fb1c3
← Back to SKILL.md
1import subprocess2import sys3from pathlib import Path4 5import pytest6 7sys.path.insert(0, str(Path(__file__).resolve().parents[2]))8 9import mechanical_refactor_reproduction_utils as rr10from mechanical_refactor_reproduction_utils import (11 Repro,12 _def_span,13 _find_class,14 _find_def,15 _replace_span,16 _slice_span,17 dedent,18 exec_command,19 git_add_and_commit,20 verify_mechanical_refactor,21)22from reproduction_testlib import _apply, _commit, _git, _write # noqa: F40123 24# --- exec_command --------------------------------------------------------------25 26 27def test_exec_command_returns_stripped_stdout_on_success() -> None:28 """A successful command returns its stdout with surrounding whitespace stripped."""29 assert exec_command("echo hello") == "hello"30 31 32def test_exec_command_respects_cwd(tmp_path: Path) -> None:33 """The command runs in the supplied working directory."""34 sub = tmp_path / "workdir"35 sub.mkdir()36 assert exec_command("pwd", cwd=str(sub)) == str(sub.resolve())37 38 39def test_exec_command_check_true_raises_on_failure() -> None:40 """With check=True a non-zero exit status raises RuntimeError with the command."""41 with pytest.raises(RuntimeError, match="exit 7"):42 exec_command("exit 7", check=True)43 44 45def test_exec_command_check_false_returns_stdout_without_exiting() -> None:46 """With check=False a failing command returns its stdout and does not exit."""47 assert exec_command("echo partial; exit 3", check=False) == "partial"48 49 50# --- git_add_and_commit --------------------------------------------------------51 52 53# --- git_add_and_commit --------------------------------------------------------54 55 56def test_git_add_and_commit_stages_and_commits(repo: Path) -> None:57 """It stages every change in the cwd and records a commit with the message."""58 _write(repo, **{"file.txt": "content\n"})59 git_add_and_commit("add file", cwd=str(repo))60 assert _git(repo, "log", "-1", "--format=%s") == "add file"61 assert _git(repo, "status", "--porcelain") == ""62 63 64@pytest.mark.parametrize(65 "message",66 [67 "subject with spaces",68 "has 'single' and \"double\" quotes",69 "shell $HOME && rm -rf / ; metacharacters",70 "trailing parens (a, b) and pipe | semicolon ;",71 ],72)73def test_git_add_and_commit_message_round_trips_with_metacharacters(74 repo: Path, message: str75) -> None:76 """Messages with shell metacharacters are quoted safely and survive verbatim."""77 _write(repo, **{"file.txt": "content\n"})78 git_add_and_commit(message, cwd=str(repo))79 assert _git(repo, "log", "-1", "--format=%B") == message80 81 82# --- dedent --------------------------------------------------------------------83 84 85# --- dedent --------------------------------------------------------------------86 87 88def test_dedent_with_zero_leaves_text_unchanged() -> None:89 """Dedenting by zero spaces returns the text untouched."""90 text = " indented\nplain\n"91 assert dedent(text, 0) == text92 93 94def test_dedent_removes_exactly_n_leading_spaces() -> None:95 """Exactly n leading spaces are removed from each qualifying line."""96 assert dedent(" four\n eight\n", 4) == "four\n eight\n"97 98 99def test_dedent_leaves_lines_with_fewer_than_n_spaces_unchanged() -> None:100 """A line with fewer than n leading spaces is not modified at all."""101 assert dedent(" four\n two\nzero\n", 4) == "four\n two\nzero\n"102 103 104def test_dedent_does_not_strip_tabs() -> None:105 """Tab characters are never treated as the spaces dedent removes."""106 assert dedent("\t\ttabbed\n", 2) == "\t\ttabbed\n"107 108 109def test_dedent_preserves_blank_lines_and_trailing_newline() -> None:110 """Blank lines and a final newline are preserved across line boundaries."""111 assert dedent(" a\n\n b\n", 4) == "a\n\nb\n"112 113 114def test_dedent_preserves_absence_of_trailing_newline() -> None:115 """A text without a trailing newline keeps it absent after dedenting."""116 assert dedent(" a\n b", 4) == "a\nb"117 118 119# --- span / call helpers -------------------------------------------------------120 121 122# --- span / call helpers -------------------------------------------------------123 124 125def test_replace_span_single_line() -> None:126 """A span within one line is replaced in place."""127 assert _replace_span("ab cd ef\n", 1, 3, 1, 5, "XY") == "ab XY ef\n"128 129 130def test_replace_span_across_lines() -> None:131 """A span crossing lines collapses to the replacement between the kept prefix/suffix."""132 text = "a = foo(\n x,\n) + 1\n"133 assert _replace_span(text, 1, 4, 3, 1, "bar()") == "a = bar() + 1\n"134 135 136def test_slice_span_returns_the_overwritten_text() -> None:137 """_slice_span returns exactly the region _replace_span would overwrite."""138 text = "a = foo(\n x,\n) + 1\n"139 assert _slice_span(text, 1, 4, 3, 1) == "foo(\n x,\n)"140 141 142def test_find_def_span_includes_decorators() -> None:143 """A def's span starts at its first decorator and ends at its last body line."""144 src = "class C:\n @staticmethod\n def foo(self):\n return 1\n"145 node = _find_def(rr.ast.parse(src), "foo")146 assert node is not None and _def_span(node) == (2, 4)147 148 149def test_find_class_returns_named_class_or_none() -> None:150 """_find_class locates a class by name and returns None when absent."""151 tree = rr.ast.parse("class A:\n pass\nclass B:\n pass\n")152 assert _find_class(tree, "B").name == "B"153 assert _find_class(tree, "Z") is None154