-
Notifications
You must be signed in to change notification settings - Fork 12.4k
Expand file tree
/
Copy pathtest_cli_version.py
More file actions
138 lines (107 loc) · 5.5 KB
/
Copy pathtest_cli_version.py
File metadata and controls
138 lines (107 loc) · 5.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
"""Tests for CLI version reporting."""
import json
import sys
from types import SimpleNamespace
from unittest.mock import patch
import pytest
from typer.testing import CliRunner
from specify_cli import app
runner = CliRunner()
class TestVersionFlag:
"""Test --version / -V flag on the root command."""
def test_version_long_flag(self):
"""specify --version prints version and exits 0."""
with patch("specify_cli.get_speckit_version", return_value="1.2.3"):
result = runner.invoke(app, ["--version"])
assert result.exit_code == 0
assert "specify 1.2.3" in result.output
def test_version_short_flag(self):
"""specify -V prints version and exits 0."""
with patch("specify_cli.get_speckit_version", return_value="1.2.3"):
result = runner.invoke(app, ["-V"])
assert result.exit_code == 0
assert "specify 1.2.3" in result.output
def test_version_flag_takes_precedence_over_subcommand(self):
"""--version should work even when a subcommand follows."""
with patch("specify_cli.get_speckit_version", return_value="0.7.2"):
result = runner.invoke(app, ["--version", "init"])
assert result.exit_code == 0
assert "specify 0.7.2" in result.output
class TestVersionCommand:
"""Test the `specify version` subcommand."""
def test_version_features_text(self):
"""specify version --features prints local capability flags."""
with patch("specify_cli.get_speckit_version", return_value="1.2.3"):
result = runner.invoke(app, ["version", "--features"])
assert result.exit_code == 0
assert "Spec Kit CLI: 1.2.3" in result.output
assert "Features:" in result.output
assert "- controlled multi install integrations: yes" in result.output
assert "- integration use command: yes" in result.output
assert "- self check command: yes" in result.output
def test_version_features_json(self):
"""specify version --features --json prints machine-readable capabilities."""
with patch("specify_cli.get_speckit_version", return_value="1.2.3"):
result = runner.invoke(app, ["version", "--features", "--json"])
assert result.exit_code == 0
payload = json.loads(result.output)
assert payload == {
"version": "1.2.3",
"features": {
"controlled_multi_install_integrations": True,
"integration_use_command": True,
"multi_install_safe_registry_metadata": True,
"integration_upgrade_command": True,
"self_check_command": True,
"workflow_catalog": True,
"bundled_templates": True,
},
}
def test_version_json_requires_features(self):
"""specify version --json is rejected until a JSON surface exists."""
result = runner.invoke(app, ["version", "--json"])
assert result.exit_code != 0
assert "--json requires --features" in result.output
def test_version_reports_openssl_runtime(self):
"""specify version reports the OpenSSL runtime the interpreter loaded.
Regression test for the triage gap in #4433: HTTPS failures on Windows
are commonly blamed on a PATH-preceded OpenSSL DLL, but ``specify
version`` reported no OpenSSL information at all, so a report had no way
to show which runtime was actually in use.
"""
ssl = pytest.importorskip("ssl")
with patch("specify_cli.get_speckit_version", return_value="1.2.3"):
result = runner.invoke(app, ["version"])
assert result.exit_code == 0
expected = ssl.OPENSSL_VERSION
assert expected, "test host reports no ssl.OPENSSL_VERSION to assert against"
assert expected in result.output
def test_version_skips_openssl_row_when_ssl_unavailable(self, monkeypatch):
"""An interpreter built without the ssl extension skips the OpenSSL row.
``sys.modules["ssl"] = None`` makes ``import ssl`` raise ImportError,
simulating a build without ``_ssl``. The command must still succeed —
only the OpenSSL row is omitted.
"""
monkeypatch.setitem(sys.modules, "ssl", None)
with patch("specify_cli.get_speckit_version", return_value="1.2.3"):
result = runner.invoke(app, ["version"])
assert result.exit_code == 0
assert "OpenSSL" not in result.output
def test_version_skips_openssl_row_when_version_attr_missing(self, monkeypatch):
"""An ssl module without OPENSSL_VERSION also skips the row.
The implementation reads ``getattr(ssl, "OPENSSL_VERSION", "")``, so an
importable ssl that lacks the attribute must omit the row rather than
raise AttributeError.
"""
monkeypatch.setitem(sys.modules, "ssl", SimpleNamespace())
with patch("specify_cli.get_speckit_version", return_value="1.2.3"):
result = runner.invoke(app, ["version"])
assert result.exit_code == 0
assert "OpenSSL" not in result.output
def test_version_features_never_touches_ssl(self, monkeypatch):
"""--features/--json return early and must not require ssl at all."""
monkeypatch.setitem(sys.modules, "ssl", None)
with patch("specify_cli.get_speckit_version", return_value="1.2.3"):
result = runner.invoke(app, ["version", "--features", "--json"])
assert result.exit_code == 0
assert json.loads(result.output)["version"] == "1.2.3"