|
1 | 1 | """Tests for the per-integration `SPECIFY_<KEY>_EXTRA_ARGS` env-var hook |
2 | 2 | in `SkillsIntegration.build_exec_args`. See issue #2595.""" |
3 | 3 |
|
| 4 | +import os |
| 5 | + |
4 | 6 | import pytest |
5 | 7 |
|
6 | 8 | from specify_cli.integrations.base import SkillsIntegration |
@@ -72,7 +74,7 @@ class _NoCliStub(SkillsIntegration): |
72 | 74 | def _clean_extra_args_env(monkeypatch): |
73 | 75 | """Strip any leaked SPECIFY_*_EXTRA_ARGS from the test env so a |
74 | 76 | developer's shell setting doesn't pollute results.""" |
75 | | - for key in list(__import__("os").environ): |
| 77 | + for key in list(os.environ): |
76 | 78 | if key.startswith("SPECIFY_") and key.endswith("_EXTRA_ARGS"): |
77 | 79 | monkeypatch.delenv(key, raising=False) |
78 | 80 |
|
@@ -161,3 +163,74 @@ def test_requires_cli_false_returns_none(monkeypatch): |
161 | 163 | hook is never reached and no argv is built.""" |
162 | 164 | monkeypatch.setenv("SPECIFY_NO_CLI_EXTRA_ARGS", "--should-not-appear") |
163 | 165 | assert _NoCliStub().build_exec_args("p") is None |
| 166 | + |
| 167 | + |
| 168 | +# --------------------------------------------------------------------------- |
| 169 | +# Override-integration coverage |
| 170 | +# |
| 171 | +# CodexIntegration, DevinIntegration, OpencodeIntegration and |
| 172 | +# CopilotIntegration each override `build_exec_args` rather than using the |
| 173 | +# base implementations. The env-var hook must be wired into every override |
| 174 | +# so the documented behaviour ("works for every requires_cli integration") |
| 175 | +# is honoured. These tests lock that contract per integration. |
| 176 | +# --------------------------------------------------------------------------- |
| 177 | + |
| 178 | + |
| 179 | +def test_codex_integration_honours_extra_args(monkeypatch): |
| 180 | + from specify_cli.integrations.codex import CodexIntegration |
| 181 | + |
| 182 | + monkeypatch.setenv("SPECIFY_CODEX_EXTRA_ARGS", "--sandbox read-only") |
| 183 | + args = CodexIntegration().build_exec_args("p", model="gpt-5") |
| 184 | + assert args == [ |
| 185 | + "codex", |
| 186 | + "exec", |
| 187 | + "p", |
| 188 | + "--sandbox", |
| 189 | + "read-only", |
| 190 | + "--model", |
| 191 | + "gpt-5", |
| 192 | + "--json", |
| 193 | + ] |
| 194 | + |
| 195 | + |
| 196 | +def test_devin_integration_honours_extra_args(monkeypatch): |
| 197 | + from specify_cli.integrations.devin import DevinIntegration |
| 198 | + |
| 199 | + monkeypatch.setenv("SPECIFY_DEVIN_EXTRA_ARGS", "--no-confirm") |
| 200 | + args = DevinIntegration().build_exec_args("p") |
| 201 | + assert args == ["devin", "-p", "p", "--no-confirm"] |
| 202 | + |
| 203 | + |
| 204 | +def test_opencode_integration_honours_extra_args(monkeypatch): |
| 205 | + from specify_cli.integrations.opencode import OpencodeIntegration |
| 206 | + |
| 207 | + monkeypatch.setenv("SPECIFY_OPENCODE_EXTRA_ARGS", "--quiet") |
| 208 | + args = OpencodeIntegration().build_exec_args("p") |
| 209 | + assert args == [ |
| 210 | + "opencode", |
| 211 | + "run", |
| 212 | + "--quiet", |
| 213 | + "--format", |
| 214 | + "json", |
| 215 | + "p", |
| 216 | + ] |
| 217 | + |
| 218 | + |
| 219 | +def test_copilot_integration_honours_extra_args(monkeypatch): |
| 220 | + from specify_cli.integrations.copilot import CopilotIntegration |
| 221 | + |
| 222 | + # Disable --yolo so the argv shape stays deterministic. |
| 223 | + monkeypatch.setenv("SPECKIT_COPILOT_ALLOW_ALL_TOOLS", "0") |
| 224 | + monkeypatch.setenv( |
| 225 | + "SPECIFY_COPILOT_EXTRA_ARGS", "--allow-tool 'shell(echo)'" |
| 226 | + ) |
| 227 | + args = CopilotIntegration().build_exec_args("p") |
| 228 | + assert args == [ |
| 229 | + "copilot", |
| 230 | + "-p", |
| 231 | + "p", |
| 232 | + "--allow-tool", |
| 233 | + "shell(echo)", |
| 234 | + "--output-format", |
| 235 | + "json", |
| 236 | + ] |
0 commit comments