From 8577bc2800bb0f2ca84d05aa4f06c9528d3da416 Mon Sep 17 00:00:00 2001 From: Alpamys Date: Fri, 15 May 2026 18:50:52 +0500 Subject: [PATCH] test(adapters): strip ANSI before help-output substring asserts (v0.57.0 CI fix) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rich-wrap-CI workaround — same fix pattern as v0.55.0 / v0.56.0: CliRunner output contains ANSI color escapes that break literal '--top-k' in output substring matches because Rich renders option names as -\x1b[0m\x1b[1;36m-top-k. Adds _ANSI_RE + _strip_ansi() helper to each of the 4 test files (test_v0570_part_{a,b,c,d}.py) and routes every help-output substring assertion through it. Co-Authored-By: Claude Opus 4.7 (1M context) --- tests/test_v0570_part_a.py | 20 +++++++++++++++----- tests/test_v0570_part_b.py | 16 ++++++++++++---- tests/test_v0570_part_c.py | 19 +++++++++++++------ tests/test_v0570_part_d.py | 16 ++++++++++++---- 4 files changed, 52 insertions(+), 19 deletions(-) diff --git a/tests/test_v0570_part_a.py b/tests/test_v0570_part_a.py index 29ba746..422d3e9 100644 --- a/tests/test_v0570_part_a.py +++ b/tests/test_v0570_part_a.py @@ -4,6 +4,7 @@ from __future__ import annotations import json import os +import re from pathlib import Path import numpy as np @@ -21,6 +22,15 @@ from soup_cli.utils.adapter_diff import ( render_report_markdown, ) +# Strip ANSI before substring asserts (CI Rich-wraps option names — same fix +# as v0.55.0 / v0.56.0). +_ANSI_RE = re.compile(r"\x1b\[[0-9;]*m") + + +def _strip_ansi(text: str) -> str: + return _ANSI_RE.sub("", text or "") + + runner = CliRunner() @@ -316,8 +326,8 @@ def test_compute_adapter_diff_bin_format_rejected(tmp_path, monkeypatch): def test_adapters_diff_help(): result = runner.invoke(soup_app, ["adapters", "diff", "--help"]) assert result.exit_code == 0, (result.output, repr(result.exception)) - assert "--top-k" in result.output - assert "--format" in result.output + assert "--top-k" in _strip_ansi(result.output) + assert "--format" in _strip_ansi(result.output) def test_adapters_diff_table_format(tmp_path, monkeypatch): @@ -327,7 +337,7 @@ def test_adapters_diff_table_format(tmp_path, monkeypatch): _write_safetensors(tmp_path / "b", {"w": np.zeros((2, 2), dtype=np.float32)}) result = runner.invoke(soup_app, ["adapters", "diff", "a", "b"]) assert result.exit_code == 0, (result.output, repr(result.exception)) - assert "Adapter diff" in result.output + assert "Adapter diff" in _strip_ansi(result.output) def test_adapters_diff_json_output(tmp_path, monkeypatch): @@ -368,7 +378,7 @@ def test_adapters_diff_unknown_format(tmp_path, monkeypatch): "adapters", "diff", "a", "b", "--format", "yaml", ]) assert result.exit_code == 2 - assert "Unknown --format" in result.output + assert "Unknown --format" in _strip_ansi(result.output) def test_adapters_diff_output_requires_non_table(tmp_path, monkeypatch): @@ -380,7 +390,7 @@ def test_adapters_diff_output_requires_non_table(tmp_path, monkeypatch): "adapters", "diff", "a", "b", "--output", "out.txt", ]) assert result.exit_code == 2 - assert "requires --format" in result.output + assert "requires --format" in _strip_ansi(result.output) def test_adapters_diff_output_outside_cwd_rejected(tmp_path, monkeypatch): diff --git a/tests/test_v0570_part_b.py b/tests/test_v0570_part_b.py index 1a82698..6b8ce42 100644 --- a/tests/test_v0570_part_b.py +++ b/tests/test_v0570_part_b.py @@ -3,6 +3,7 @@ from __future__ import annotations import json +import re from pathlib import Path import numpy as np @@ -21,6 +22,13 @@ from soup_cli.utils.adapter_merge import ( predict_merged_verdict, ) +_ANSI_RE = re.compile(r"\x1b\[[0-9;]*m") + + +def _strip_ansi(text: str) -> str: + return _ANSI_RE.sub("", text or "") + + runner = CliRunner() @@ -371,8 +379,8 @@ def test_merge_report_frozen(): def test_adapters_merge_cli_help(): result = runner.invoke(soup_app, ["adapters", "merge", "--help"]) assert result.exit_code == 0, (result.output, repr(result.exception)) - assert "--strategy" in result.output - assert "--weights" in result.output + assert "--strategy" in _strip_ansi(result.output) + assert "--weights" in _strip_ansi(result.output) def test_adapters_merge_cli_linear(tmp_path, monkeypatch): @@ -394,7 +402,7 @@ def test_adapters_merge_cli_unknown_strategy(tmp_path, monkeypatch): "adapters", "merge", "a", "b", "-o", "out", "--strategy", "bogus", ]) assert result.exit_code == 2 - assert "Unknown --strategy" in result.output + assert "Unknown --strategy" in _strip_ansi(result.output) def test_adapters_merge_cli_invalid_weights(tmp_path, monkeypatch): @@ -415,4 +423,4 @@ def test_adapters_merge_cli_single_adapter_rejected(tmp_path, monkeypatch): "adapters", "merge", "a", "-o", "out", "--strategy", "linear", ]) assert result.exit_code == 2 - assert "at least 2" in result.output + assert "at least 2" in _strip_ansi(result.output) diff --git a/tests/test_v0570_part_c.py b/tests/test_v0570_part_c.py index 9708f3e..a64f97e 100644 --- a/tests/test_v0570_part_c.py +++ b/tests/test_v0570_part_c.py @@ -3,6 +3,7 @@ from __future__ import annotations import os +import re import pytest from typer.testing import CliRunner @@ -16,6 +17,12 @@ from soup_cli.utils.blame import ( run_blame, ) +_ANSI_RE = re.compile(r"\x1b\[[0-9;]*m") + + +def _strip_ansi(text: str) -> str: + return _ANSI_RE.sub("", text or "") + runner = CliRunner() @@ -272,9 +279,9 @@ def test_blame_shard_work_frozen(): def test_adapters_blame_help(): result = runner.invoke(soup_app, ["adapters", "blame", "--help"]) assert result.exit_code == 0, (result.output, repr(result.exception)) - assert "--budget" in result.output - assert "--layer" in result.output - assert "--shards" in result.output + assert "--budget" in _strip_ansi(result.output) + assert "--layer" in _strip_ansi(result.output) + assert "--shards" in _strip_ansi(result.output) def test_adapters_blame_plan_only(tmp_path, monkeypatch): @@ -288,7 +295,7 @@ def test_adapters_blame_plan_only(tmp_path, monkeypatch): "--plan-only", ]) assert result.exit_code == 0, (result.output, repr(result.exception)) - assert "Blame plan" in result.output + assert "Blame plan" in _strip_ansi(result.output) def test_adapters_blame_invalid_budget(tmp_path, monkeypatch): @@ -301,7 +308,7 @@ def test_adapters_blame_invalid_budget(tmp_path, monkeypatch): "--shards", "5", ]) assert result.exit_code == 2 - assert "Invalid --budget" in result.output + assert "Invalid --budget" in _strip_ansi(result.output) def test_adapters_blame_live_runner_advisory(tmp_path, monkeypatch): @@ -314,4 +321,4 @@ def test_adapters_blame_live_runner_advisory(tmp_path, monkeypatch): "--shards", "5", ]) assert result.exit_code == 0, (result.output, repr(result.exception)) - assert "v0.57.1" in result.output + assert "v0.57.1" in _strip_ansi(result.output) diff --git a/tests/test_v0570_part_d.py b/tests/test_v0570_part_d.py index 88cb61a..1b1f05e 100644 --- a/tests/test_v0570_part_d.py +++ b/tests/test_v0570_part_d.py @@ -4,6 +4,7 @@ from __future__ import annotations import json import os +import re from pathlib import Path import pytest @@ -19,6 +20,13 @@ from soup_cli.utils.adapter_branch import ( write_checkout, ) +_ANSI_RE = re.compile(r"\x1b\[[0-9;]*m") + + +def _strip_ansi(text: str) -> str: + return _ANSI_RE.sub("", text or "") + + runner = CliRunner() @@ -344,7 +352,7 @@ def test_branch_cli_invalid_name(tmp_path, monkeypatch): "-c", "soup.yaml", "--base", "m", ]) assert result.exit_code == 2 - assert "must match" in result.output + assert "must match" in _strip_ansi(result.output) def test_branch_cli_missing_config(tmp_path, monkeypatch): @@ -355,7 +363,7 @@ def test_branch_cli_missing_config(tmp_path, monkeypatch): "-c", "missing.yaml", "--base", "m", ]) assert result.exit_code == 1 - assert "not found" in result.output + assert "not found" in _strip_ansi(result.output) def test_checkout_cli_roundtrip(tmp_path, monkeypatch): @@ -378,7 +386,7 @@ def test_checkout_cli_missing_branch(tmp_path, monkeypatch): "adapters", "checkout", "nope", "-o", "out.yaml", ]) assert result.exit_code == 1 - assert "not found" in result.output + assert "not found" in _strip_ansi(result.output) def test_branches_cli_empty(tmp_path, monkeypatch): @@ -386,4 +394,4 @@ def test_branches_cli_empty(tmp_path, monkeypatch): monkeypatch.chdir(tmp_path) result = runner.invoke(soup_app, ["adapters", "branches"]) assert result.exit_code == 0, (result.output, repr(result.exception)) - assert "No branches" in result.output + assert "No branches" in _strip_ansi(result.output)