various fixes found during review

This commit is contained in:
Vaclav Tvrdik
2026-10-14 11:01:07 +02:00
parent ff820a09d7
commit 25f8098314
6 changed files with 232 additions and 58 deletions

View File

@@ -111,28 +111,28 @@ def test_two_columns_are_laid_out_as_in_the_mockup():
lines = rows(view)
# the left column is as wide as its longest cell plus the padding; the gap follows it
width = len(" feature") + branches.LEFT_PAD
assert all(line[width:width + 2] == "| " for line in lines)
assert all(line[width:width + 2] == ("├─" if line.endswith("─") else "│ ") for line in lines)
right = 100 - width - 2
# the working tree comes first, five rows like a commit; nothing changed here
assert lines[0] == f"{'BRANCHES':<{width}}| No Changes"
assert lines[1] == f"{' feature':<{width}}| "
assert lines[0] == f"{'BRANCHES':<{width}}│ No Changes"
assert lines[1] == f"{' feature':<{width}}│ "
# main is one commit ahead of its upstream: the count sits on the right edge of its cell
assert lines[2] == f"{'* main':<{width - 3}}↑1 | "
assert lines[3] == f"{'REMOTES':<{width}}| "
assert lines[4] == f"{'origin':<{width}}| " + "-" * right
assert lines[5] == f"{' main':<{width}}| default file view mode and some colors now configurable in settings"
assert lines[6].startswith(f"{'github':<{width}}| Author: vtvrdik")
assert lines[2] == f"{'* main':<{width - 3}}↑1 │ "
assert lines[3] == f"{'REMOTES':<{width}}│ "
assert lines[4] == f"{'origin':<{width}}├─" + "─" * right
assert lines[5] == f"{' main':<{width}}│ default file view mode and some colors now configurable in settings"
assert lines[6].startswith(f"{'github':<{width}}│ Author: vtvrdik")
# the tag sits on the right edge of the author row
assert lines[6].endswith("v1.1.0") and len(lines[6]) == width + 2 + right
assert lines[7] == f"{' main':<{width}}| Date: 20.12.2025"
assert lines[7] == f"{' main':<{width}}│ Date: 20.12.2025"
# the left column ran out, so the cells are blank
assert lines[8] == f"{'':<{width}}| Stats: 8 files changed -58 +260"
assert lines[9] == f"{'':<{width}}| " + "-" * right
assert lines[10] == f"{'':<{width}}| next commit message"
assert lines[11].rstrip() == f"{'':<{width}}| Author: vtvrdik"
assert lines[8] == f"{'':<{width}}│ Stats: 8 files changed -58 +260"
assert lines[9] == f"{'':<{width}}├─" + "─" * right
assert lines[10] == f"{'':<{width}}│ next commit message"
assert lines[11].rstrip() == f"{'':<{width}}│ Author: vtvrdik"
# no diffstat for a merge or an empty commit
assert lines[13] == f"{'':<{width}}| Stats: (no diffstat)"
assert lines[14] == f"{'':<{width}}| " + "-" * right
assert lines[13] == f"{'':<{width}}│ Stats: (no diffstat)"
assert lines[14] == f"{'':<{width}}├─" + "─" * right
assert len(lines) == 15
assert view.syntax == "scope:text.plain"
assert view.name_ == "⟐ branches"
@@ -152,20 +152,20 @@ def test_the_working_tree_entry_counts_the_staged_and_unstaged_files_and_their_d
view, st = rendered(st)
lines = rows(view)
width = len(" feature") + branches.LEFT_PAD
assert lines[0] == f"{'BRANCHES':<{width}}| 3 staged files, 2 unstaged files"
assert lines[1] == f"{' feature':<{width}}| Stats: 4 files changed -1 +4"
assert lines[2] == f"{'* main':<{width - 3}}↑1 | " and lines[3] == f"{'REMOTES':<{width}}| "
assert lines[4].endswith("-" * 10) and lines[5].endswith("| default file view mode and some colors now configurable in settings")
assert lines[0] == f"{'BRANCHES':<{width}}│ 3 staged files, 2 unstaged files"
assert lines[1] == f"{' feature':<{width}}│ Stats: 4 files changed -1 +4"
assert lines[2] == f"{'* main':<{width - 3}}↑1 │ " and lines[3] == f"{'REMOTES':<{width}}│ "
assert lines[4].endswith("─" * 10) and lines[5].endswith("│ default file view mode and some colors now configurable in settings")
# its counts are coloured like the commits', in row order
assert [view.text[r.a:r.b] for r in view.regions[render.KEY_BRANCH_DEL][0]] == ["-1", "-58"]
assert [view.text[r.a:r.b] for r in view.regions[render.KEY_BRANCH_INS][0]] == ["+4", "v1.1.0", "+260"]
# the singular
st.branch_changes = [CHANGES[0]]
branches.render_branches(view, st)
assert rows(view)[0] == f"{'BRANCHES':<{width}}| 0 staged files, 1 unstaged file"
assert rows(view)[0] == f"{'BRANCHES':<{width}}│ 0 staged files, 1 unstaged file"
st.branch_changes = [CHANGES[1]]
branches.render_branches(view, st)
assert rows(view)[0] == f"{'BRANCHES':<{width}}| 1 staged file, 0 unstaged files"
assert rows(view)[0] == f"{'BRANCHES':<{width}}│ 1 staged file, 0 unstaged files"
def test_local_branches_show_their_standing_against_the_upstream():
@@ -173,8 +173,8 @@ def test_local_branches_show_their_standing_against_the_upstream():
ref("both", upstream="origin/both", ahead=12, behind=4), ref("lost", upstream="origin/lost", gone=True),
ref("untracked"), ref("origin/level", remote="origin")]
view, st = rendered(make_state(refs=refs, selected="ahead", remotes=("origin",)))
cells = [line.split("| ")[0] for line in rows(view)]
width = len(" both ↑12 ↓4") + branches.LEFT_PAD
cells = [line[:width] for line in rows(view)]
# in the listing's order; level and untracked branches carry nothing, nor do remote ones
assert cells[1:6] == [f"{' level':<{width}}", f"{'* ahead':<{width - 3}}↑3 ", f"{' both':<{width - 7}}↑12 ↓4 ",
f"{' lost':<{width - 5}}gone ", f"{' untracked':<{width}}"]
@@ -210,7 +210,7 @@ def test_rows_know_their_branch_and_commit():
def test_a_remote_without_fetched_branches_keeps_its_row():
view, st = rendered(make_state(refs=[ref("main", current=True)], remotes=("origin", "gitea")))
names = [line.split("|")[0].rstrip() for line in rows(view)]
names = [line[:st.branch_width].rstrip() for line in rows(view)]
assert names[:5] == ["BRANCHES", "* main", "REMOTES", "origin", "gitea"]
@@ -218,7 +218,7 @@ def test_long_branch_names_are_clipped_at_the_cap():
long = "feature/" + "x" * 60
view, st = rendered(make_state(refs=[ref("main", current=True), ref(long)], selected="main"))
width = branches.LEFT_MAX
assert rows(view)[2].startswith(f"{' ' + long[:width - 4]}…" + " | ") or rows(view)[2][width:width + 2] == "| "
assert rows(view)[2].startswith(f"{' ' + long[:width - 4]}…" + " │ ") or rows(view)[2][width:width + 2] == "│ "
assert rows(view)[2][:width].rstrip().endswith("…")
@@ -263,9 +263,9 @@ def test_caret_starts_on_the_working_tree_entry_and_stays_on_its_item_across_a_r
def test_no_commits_and_no_branches_still_draw():
view, st = rendered(make_state(refs=[], commits=[], selected=None, remotes=()))
rule = "-" * (100 - len("BRANCHES | "))
assert rows(view) == ["BRANCHES | No Changes", "REMOTES | ", " | ", " | ", " | " + rule,
" | (no commits)"]
rule = "─" * (100 - len("BRANCHES │ "))
assert rows(view) == ["BRANCHES │ No Changes", "REMOTES │ ", " │ ", " │ ", " ├─" + rule,
" │ (no commits)"]
# the one item to step through is the working tree
assert view.sel()[0].a == render.index_point(view, 0)
branches.ACTIONS["next_commit"](view, None, st)
@@ -380,7 +380,7 @@ def test_J_and_K_select_branches_skipping_headings_and_reload_the_log(monkeypatc
branches.ACTIONS["next_branch"](view, None, st)
assert st.branch_ref == "origin/main" and len(rings) == 2
# the stub runs the worker at once, so the log was redrawn with the new selection
assert rows(view)[5].endswith("| next commit message")
assert rows(view)[5].endswith("│ next commit message")
selected = view.regions[render.KEY_BRANCH_SEL][0]
assert view.text[selected[0].a:selected[0].b].strip() == "main"
# the caret went back to the working-tree entry
@@ -398,10 +398,10 @@ def test_a_stale_log_is_dropped(monkeypatch):
# the older answer lands first, but the token moved on
work, done = pending[0]
done(work())
assert "| feature" not in view.text
assert "│ feature" not in view.text
work, done = pending[1]
done(work())
assert rows(view)[5].endswith("| main")
assert rows(view)[5].endswith("│ main")
def test_load_lists_everything_and_picks_the_branch(monkeypatch):
@@ -417,8 +417,8 @@ def test_load_lists_everything_and_picks_the_branch(monkeypatch):
st = state.ViewState("/repo/vdiff")
branches.load(view, st)
# nothing wanted: the checked-out branch; the working tree above its log
assert st.branch_ref == "main" and rows(view)[5].endswith("| log of main")
assert rows(view)[0].endswith("| 1 staged file, 1 unstaged file") and rows(view)[1].endswith("| Stats: 1 file changed -0 +2")
assert st.branch_ref == "main" and rows(view)[5].endswith("│ log of main")
assert rows(view)[0].endswith("│ 1 staged file, 1 unstaged file") and rows(view)[1].endswith("│ Stats: 1 file changed -0 +2")
assert st.branch_changes == [CHANGES[2]]
assert st.branch_remotes == ["origin", "github"] and st.branch_head_sha == "abc1234"
assert st.token == st.rendered_token
@@ -428,7 +428,7 @@ def test_load_lists_everything_and_picks_the_branch(monkeypatch):
assert st.branch_ref == "main"
st.branch_ref = "origin/main"
branches.load(view, st)
assert st.branch_ref == "origin/main" and rows(view)[5].endswith("| log of origin/main")
assert st.branch_ref == "origin/main" and rows(view)[5].endswith("│ log of origin/main")
def test_pick_prefers_the_wanted_then_the_current_then_the_first_local_then_the_first():
@@ -681,7 +681,7 @@ def test_load_worktree_relists_only_the_changes_and_keeps_the_caret(monkeypatch)
branches.ACTIONS["next_commit"](view, None, st)
branches.load_worktree(view, st)
assert listed == ["/repo/vdiff"] and st.branch_changes == [CHANGES[1]]
assert rows(view)[0].endswith("| 1 staged file, 0 unstaged files") and rows(view)[5].endswith("| default file view mode and some colors now configurable in settings")
assert rows(view)[0].endswith("│ 1 staged file, 0 unstaged files") and rows(view)[5].endswith("│ default file view mode and some colors now configurable in settings")
assert render.caret_index(view) == 5 and st.token == st.rendered_token
# a later load wins over a slower relisting
pending = []