stage/unstage all actions added

This commit is contained in:
Vaclav Tvrdik
2026-10-10 10:19:06 +02:00
parent fe915178c5
commit 904b941be7
8 changed files with 98 additions and 18 deletions

View File

@@ -578,6 +578,27 @@ def test_unstage_and_discard_do_not_move(monkeypatch):
assert press(monkeypatch, "discard", files, "f1.py", flagged(True, False, False)) == ["f1.py"]
def test_stage_all_and_unstage_all_stay_on_the_file(monkeypatch):
messages = []
monkeypatch.setattr(commands, "status", messages.append)
assert press(monkeypatch, "stage_all", flagged(True, False, False), "f1.py", flagged(True, True, True)) == ["f1.py"]
assert messages[0] == "staged 2 files"
assert press(monkeypatch, "unstage_all", flagged(True, False, True), "f1.py", flagged(False, False, False)) == ["f1.py"]
assert messages[-1] == "unstaged 2 files"
def test_stage_all_and_unstage_all_need_something_to_do(monkeypatch):
messages = []
monkeypatch.setattr(commands, "status", messages.append)
assert press(monkeypatch, "stage_all", flagged(True, True), "f0.py", []) == []
assert press(monkeypatch, "unstage_all", flagged(False, False), "f0.py", []) == []
assert messages == ["nothing to stage", "nothing to unstage"]
view, window, st = at_file(flagged(False), "f0.py")
st.enter("abc", git.CommitInfo("abc", "abc1234", "Ann", "2026-09-23 10:00", "Fix things", ""))
commands.ACTIONS["stage_all"](view, window, st)
assert messages[-1] == "stage all works on uncommitted changes only"
def test_staging_the_only_file_leaves_an_empty_listing(monkeypatch):
messages = []
monkeypatch.setattr(commands.render, "render_message", lambda view, st, text: messages.append(text))

View File

@@ -84,6 +84,19 @@ def test_stage_unstage_discard(repo):
assert git.changed_files(repo) == []
def test_stage_all_unstage_all(repo):
write(repo, "a.py", "changed\n")
os.remove(os.path.join(repo, "gone.py"))
write(repo, "sub/n.py", "new\n")
git.stage_all(repo)
changes = {c.path: c for c in git.changed_files(repo)}
assert set(changes) == {"a.py", "gone.py", "sub/n.py"} and all(c.staged for c in changes.values())
git.unstage_all(repo)
changes = {c.path: c for c in git.changed_files(repo)}
assert set(changes) == {"a.py", "gone.py", "sub/n.py"} and not any(c.staged for c in changes.values())
assert changes["sub/n.py"].status == "?"
def test_commits(repo):
write(repo, "a.py", "def f():\n return 10\n\n\ndef g():\n return 2\n")
write(repo, "c.py", "c\n")
@@ -154,6 +167,10 @@ def test_no_head_repo(tmp_path):
assert [l.kind for l in diff.lines] == ["+"]
git.unstage(repo, changes[0])
assert git.changed_files(repo)[0].status == "?"
git.stage_all(repo)
assert git.changed_files(repo)[0].staged
git.unstage_all(repo)
assert git.changed_files(repo)[0].status == "?"
def test_rename_in_commit(repo):

View File

@@ -154,14 +154,14 @@ def test_help_popup_lists_every_key():
assert view.is_popup_visible()
for group in ("Navigate", "Actions", "View"):
assert f">{group}<" in html
for keys in ("] [", "n p", "o ⏎", "j k", "f", "c", "s", "u", "d", "C", "m", "r", "z", "esc"):
for keys in ("] [", "n p", "o ⏎", "j k", "f", "c", "s / S", "u / U", "d", "C", "m", "r", "z", "esc"):
assert f">{keys}<" in html
assert "next / previous change" in html and "open the real file at this line" in html
# working-tree mode: nothing dimmed, every single-action row is a link
assert 'class="dim"' not in html and "uncommitted only" not in html
assert 'href="stage"' in html and 'href="files"' in html and 'href="close"' in html
assert 'href="discard"' in html and 'href="files"' in html and 'href="close"' in html
# rows covering two actions stay plain text
assert 'href="next_change"' not in html
assert 'href="next_change"' not in html and 'href="stage"' not in html
# the popup does not list the key that opens it
assert ">?<" not in html
@@ -173,6 +173,8 @@ def test_help_popup_dims_file_actions_in_commit_mode():
assert "uncommitted only" in html
assert html.count('class="dim"') == 5
# dimmed rows keep their keys orange
assert 'class="kdim"' not in html and '<span class="k">C</span>' in html
assert 'href="stage"' not in html and 'href="unstage"' not in html and 'href="discard"' not in html
assert 'href="commit"' not in html and 'href="amend"' not in html
# everything that still applies stays clickable
@@ -215,7 +217,7 @@ def test_keymap_matches_help_table():
# rebinding a key without updating the table would leave the popup and status bar lying
bound_keys = {DISPLAY_KEYS.get(key, key) for b in bindings for key in b["keys"]}
assert bound_keys == {token for k in render.KEYS for token in k.keys.split()} | {"?"}
assert bound_keys == {token for k in render.KEYS for token in k.keys.split() if token != "/"} | {"?"}
def test_no_binding_yields_to_vintage_command_mode():