test(adapters): strip ANSI before help-output substring asserts (v0.57.0 CI fix)

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) <noreply@anthropic.com>
This commit is contained in:
Alpamys 2026-05-15 18:50:52 +05:00
parent 7da82d355a
commit 8577bc2800
4 changed files with 52 additions and 19 deletions

View File

@ -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):

View File

@ -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)

View File

@ -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)

View File

@ -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)