diff options
Diffstat (limited to 'tests/test_subcmds_info.py')
| -rw-r--r-- | tests/test_subcmds_info.py | 118 |
1 files changed, 116 insertions, 2 deletions
diff --git a/tests/test_subcmds_info.py b/tests/test_subcmds_info.py index 922b1088c..aa69b7b48 100644 --- a/tests/test_subcmds_info.py +++ b/tests/test_subcmds_info.py | |||
| @@ -208,7 +208,7 @@ def test_get_project_data_uses_head_revision() -> None: | |||
| 208 | project.name = "foo" | 208 | project.name = "foo" |
| 209 | project.worktree = "/path/to/foo" | 209 | project.worktree = "/path/to/foo" |
| 210 | project.revisionExpr = "refs/heads/main" | 210 | project.revisionExpr = "refs/heads/main" |
| 211 | project.GetBranches.return_value = [] | 211 | project.GetBranches.return_value = {} |
| 212 | 212 | ||
| 213 | # GetHeadRevisionId() returns a SHA, it should be used. | 213 | # GetHeadRevisionId() returns a SHA, it should be used. |
| 214 | project.GetHeadRevisionId.return_value = "head_sha_12345" | 214 | project.GetHeadRevisionId.return_value = "head_sha_12345" |
| @@ -235,7 +235,9 @@ def test_json_with_projects(capsys) -> None: | |||
| 235 | project.name = "foo" | 235 | project.name = "foo" |
| 236 | project.worktree = "/path/to/foo" | 236 | project.worktree = "/path/to/foo" |
| 237 | project.revisionExpr = "refs/heads/main" | 237 | project.revisionExpr = "refs/heads/main" |
| 238 | project.GetBranches.return_value = {"branch1": mock.MagicMock()} | 238 | branch = mock.MagicMock() |
| 239 | branch.current = True | ||
| 240 | project.GetBranches.return_value = {"branch1": branch} | ||
| 239 | project.GetHeadRevisionId.return_value = "head_sha_12345" | 241 | project.GetHeadRevisionId.return_value = "head_sha_12345" |
| 240 | project.CurrentBranch = "branch1" | 242 | project.CurrentBranch = "branch1" |
| 241 | 243 | ||
| @@ -253,3 +255,115 @@ def test_json_with_projects(capsys) -> None: | |||
| 253 | assert project_data["manifest_revision"] == "refs/heads/main" | 255 | assert project_data["manifest_revision"] == "refs/heads/main" |
| 254 | assert project_data["local_branches"] == ["branch1"] | 256 | assert project_data["local_branches"] == ["branch1"] |
| 255 | assert project_data["current_branch"] == "branch1" | 257 | assert project_data["current_branch"] == "branch1" |
| 258 | |||
| 259 | |||
| 260 | def test_diff_commits_uses_one_left_right_walk() -> None: | ||
| 261 | """Local and remote commits are partitioned from one rev-list.""" | ||
| 262 | project = mock.MagicMock() | ||
| 263 | project.work_git.rev_list.return_value = [ | ||
| 264 | "<11111111 local commit", | ||
| 265 | ">22222222 remote commit", | ||
| 266 | ] | ||
| 267 | |||
| 268 | local, remote = info.Info._GetDiffCommits(project, "refs/remotes/m/main") | ||
| 269 | |||
| 270 | assert local == ["11111111 local commit"] | ||
| 271 | assert remote == ["22222222 remote commit"] | ||
| 272 | project.work_git.rev_list.assert_called_once_with( | ||
| 273 | "--left-right", | ||
| 274 | "--abbrev=8", | ||
| 275 | "--abbrev-commit", | ||
| 276 | "--pretty=oneline", | ||
| 277 | "HEAD...refs/remotes/m/main", | ||
| 278 | "--", | ||
| 279 | ) | ||
| 280 | |||
| 281 | |||
| 282 | def test_diff_commits_falls_back_to_bare_git_when_no_worktree() -> None: | ||
| 283 | """Bare or worktree-less projects fall back to bare_git for history walk.""" | ||
| 284 | project = mock.MagicMock() | ||
| 285 | project.work_git = None | ||
| 286 | project.bare_git.rev_list.return_value = [ | ||
| 287 | "<11111111 local commit", | ||
| 288 | ">22222222 remote commit", | ||
| 289 | ] | ||
| 290 | |||
| 291 | local, remote = info.Info._GetDiffCommits(project, "refs/remotes/m/main") | ||
| 292 | |||
| 293 | assert local == ["11111111 local commit"] | ||
| 294 | assert remote == ["22222222 remote commit"] | ||
| 295 | project.bare_git.rev_list.assert_called_once_with( | ||
| 296 | "--left-right", | ||
| 297 | "--abbrev=8", | ||
| 298 | "--abbrev-commit", | ||
| 299 | "--pretty=oneline", | ||
| 300 | "HEAD...refs/remotes/m/main", | ||
| 301 | "--", | ||
| 302 | ) | ||
| 303 | |||
| 304 | |||
| 305 | def test_diff_commits_empty_output() -> None: | ||
| 306 | """Empty rev-list output produces empty local and remote commit lists.""" | ||
| 307 | project = mock.MagicMock() | ||
| 308 | project.work_git.rev_list.return_value = [] | ||
| 309 | |||
| 310 | local, remote = info.Info._GetDiffCommits(project, "refs/remotes/m/main") | ||
| 311 | |||
| 312 | assert local == [] | ||
| 313 | assert remote == [] | ||
| 314 | |||
| 315 | |||
| 316 | def test_get_current_branch() -> None: | ||
| 317 | """_GetCurrentBranch identifies the branch with current=True.""" | ||
| 318 | b1 = mock.MagicMock(current=False) | ||
| 319 | b2 = mock.MagicMock(current=True) | ||
| 320 | assert info.Info._GetCurrentBranch({"b1": b1, "b2": b2}) == "b2" | ||
| 321 | assert info.Info._GetCurrentBranch({"b1": b1}) is None | ||
| 322 | assert info.Info._GetCurrentBranch({}) is None | ||
| 323 | |||
| 324 | |||
| 325 | def test_overview_helper_current_branch_filters_before_uploadable( | ||
| 326 | monkeypatch: pytest.MonkeyPatch, | ||
| 327 | ) -> None: | ||
| 328 | """_OverviewHelper only checks uploadable state for the current branch.""" | ||
| 329 | project = mock.MagicMock() | ||
| 330 | project.RelPath.return_value = "proj" | ||
| 331 | b1 = mock.MagicMock(current=False) | ||
| 332 | b2 = mock.MagicMock(current=True) | ||
| 333 | project.GetBranches.return_value = {"b1": b1, "b2": b2} | ||
| 334 | uploadable = mock.MagicMock(commits=["c1"], date="2026-09-21") | ||
| 335 | uploadable.name = "b2" | ||
| 336 | project.GetUploadableBranch.return_value = uploadable | ||
| 337 | monkeypatch.setattr( | ||
| 338 | info.Info, | ||
| 339 | "get_parallel_context", | ||
| 340 | lambda: {"projects": [project]}, | ||
| 341 | ) | ||
| 342 | opt = mock.MagicMock(current_branch=True, this_manifest_only=False) | ||
| 343 | |||
| 344 | result = info.Info._OverviewHelper(0, opt) | ||
| 345 | |||
| 346 | project.GetUploadableBranch.assert_called_once_with("b2") | ||
| 347 | assert len(result) == 1 | ||
| 348 | assert result[0].name == "b2" | ||
| 349 | assert result[0].is_current is True | ||
| 350 | |||
| 351 | |||
| 352 | def test_overview_helper_current_branch_detached_head_skips_uploadable( | ||
| 353 | monkeypatch: pytest.MonkeyPatch, | ||
| 354 | ) -> None: | ||
| 355 | """_OverviewHelper skips GetUploadableBranch when detached with -b.""" | ||
| 356 | project = mock.MagicMock() | ||
| 357 | b1 = mock.MagicMock(current=False) | ||
| 358 | project.GetBranches.return_value = {"b1": b1} | ||
| 359 | monkeypatch.setattr( | ||
| 360 | info.Info, | ||
| 361 | "get_parallel_context", | ||
| 362 | lambda: {"projects": [project]}, | ||
| 363 | ) | ||
| 364 | opt = mock.MagicMock(current_branch=True, this_manifest_only=False) | ||
| 365 | |||
| 366 | result = info.Info._OverviewHelper(0, opt) | ||
| 367 | |||
| 368 | project.GetUploadableBranch.assert_not_called() | ||
| 369 | assert result == [] | ||
