@@ -1228,9 +1228,18 @@ def test_returns_version_when_tag_matches(self):
12281228 from flameconnect import __version__
12291229
12301230 tag_result = MagicMock (returncode = 0 , stdout = f"v{ __version__ } \n " )
1231- with patch ("flameconnect.tui.app.subprocess.run" , return_value = tag_result ):
1231+ with patch (
1232+ "flameconnect.tui.app.subprocess.run" , return_value = tag_result
1233+ ) as mock_run :
12321234 result = _resolve_version ()
12331235 assert result == f"v{ __version__ } "
1236+ # Verify exact subprocess call
1237+ mock_run .assert_called_once_with (
1238+ ["git" , "describe" , "--tags" , "--exact-match" , "HEAD" ],
1239+ capture_output = True ,
1240+ text = True ,
1241+ timeout = 2 ,
1242+ )
12341243
12351244 def test_returns_short_hash_when_no_tag (self ):
12361245 """When no matching tag, return the short git hash."""
@@ -1241,9 +1250,30 @@ def test_returns_short_hash_when_no_tag(self):
12411250 with patch (
12421251 "flameconnect.tui.app.subprocess.run" ,
12431252 side_effect = [tag_result , hash_result , status_result ],
1244- ):
1253+ ) as mock_run :
12451254 result = _resolve_version ()
12461255 assert result == "abc1234"
1256+ # Verify all three subprocess calls
1257+ assert mock_run .call_count == 3
1258+ calls = mock_run .call_args_list
1259+ assert calls [0 ].args [0 ] == [
1260+ "git" ,
1261+ "describe" ,
1262+ "--tags" ,
1263+ "--exact-match" ,
1264+ "HEAD" ,
1265+ ]
1266+ assert calls [1 ].args [0 ] == [
1267+ "git" ,
1268+ "rev-parse" ,
1269+ "--short" ,
1270+ "HEAD" ,
1271+ ]
1272+ assert calls [2 ].args [0 ] == ["git" , "status" , "--porcelain" ]
1273+ for c in calls :
1274+ assert c .kwargs ["capture_output" ] is True
1275+ assert c .kwargs ["text" ] is True
1276+ assert c .kwargs ["timeout" ] == 2
12471277
12481278 def test_returns_dirty_hash_when_uncommitted (self ):
12491279 """When working tree is dirty, append -dirty to the hash."""
@@ -1258,6 +1288,33 @@ def test_returns_dirty_hash_when_uncommitted(self):
12581288 result = _resolve_version ()
12591289 assert result == "abc1234-dirty"
12601290
1291+ def test_clean_status_no_dirty_suffix (self ):
1292+ """Clean status output should NOT append -dirty."""
1293+ tag_result = MagicMock (returncode = 128 , stdout = "" )
1294+ hash_result = MagicMock (returncode = 0 , stdout = "abc1234\n " )
1295+ status_result = MagicMock (returncode = 0 , stdout = "" )
1296+
1297+ with patch (
1298+ "flameconnect.tui.app.subprocess.run" ,
1299+ side_effect = [tag_result , hash_result , status_result ],
1300+ ):
1301+ result = _resolve_version ()
1302+ assert result == "abc1234"
1303+ assert "-dirty" not in result
1304+
1305+ def test_status_nonzero_returncode_no_dirty (self ):
1306+ """Non-zero status returncode should not append -dirty."""
1307+ tag_result = MagicMock (returncode = 128 , stdout = "" )
1308+ hash_result = MagicMock (returncode = 0 , stdout = "abc1234\n " )
1309+ status_result = MagicMock (returncode = 1 , stdout = "M some_file.py\n " )
1310+
1311+ with patch (
1312+ "flameconnect.tui.app.subprocess.run" ,
1313+ side_effect = [tag_result , hash_result , status_result ],
1314+ ):
1315+ result = _resolve_version ()
1316+ assert result == "abc1234"
1317+
12611318 def test_returns_version_when_hash_fails (self ):
12621319 """When git rev-parse fails, fall back to v{version}."""
12631320 from flameconnect import __version__
@@ -1283,6 +1340,45 @@ def test_returns_version_on_exception(self):
12831340 result = _resolve_version ()
12841341 assert result == f"v{ __version__ } "
12851342
1343+ def test_tag_returncode_nonzero_falls_through (self ):
1344+ """Non-zero tag returncode means no tag match, proceed to hash."""
1345+ tag_result = MagicMock (returncode = 1 , stdout = "" )
1346+ hash_result = MagicMock (returncode = 0 , stdout = "def5678\n " )
1347+ status_result = MagicMock (returncode = 0 , stdout = "" )
1348+
1349+ with patch (
1350+ "flameconnect.tui.app.subprocess.run" ,
1351+ side_effect = [tag_result , hash_result , status_result ],
1352+ ):
1353+ result = _resolve_version ()
1354+ assert result == "def5678"
1355+
1356+ def test_tag_matches_but_version_not_in_output (self ):
1357+ """Tag returncode=0 but version not in stdout falls through."""
1358+ tag_result = MagicMock (returncode = 0 , stdout = "v99.99.99\n " )
1359+ hash_result = MagicMock (returncode = 0 , stdout = "aaa1111\n " )
1360+ status_result = MagicMock (returncode = 0 , stdout = "" )
1361+
1362+ with patch (
1363+ "flameconnect.tui.app.subprocess.run" ,
1364+ side_effect = [tag_result , hash_result , status_result ],
1365+ ):
1366+ result = _resolve_version ()
1367+ assert result == "aaa1111"
1368+
1369+ def test_stdout_stripped (self ):
1370+ """Trailing whitespace/newlines in stdout are stripped."""
1371+ tag_result = MagicMock (returncode = 128 , stdout = "" )
1372+ hash_result = MagicMock (returncode = 0 , stdout = " bbb2222 \n " )
1373+ status_result = MagicMock (returncode = 0 , stdout = "" )
1374+
1375+ with patch (
1376+ "flameconnect.tui.app.subprocess.run" ,
1377+ side_effect = [tag_result , hash_result , status_result ],
1378+ ):
1379+ result = _resolve_version ()
1380+ assert result == "bbb2222"
1381+
12861382
12871383# ---------------------------------------------------------------------------
12881384# FireplaceCommandsProvider
0 commit comments