Branches view initial version
This commit is contained in:
@@ -4,6 +4,7 @@ import pytest
|
||||
|
||||
import sublime # the stub, via conftest
|
||||
|
||||
from conftest import put_caret # noqa: E402
|
||||
from vdiff import commands, git, state, utils
|
||||
|
||||
|
||||
@@ -163,6 +164,58 @@ def test_on_cancel_goes_back_to_commit_list(monkeypatch):
|
||||
assert back == [1] and st.sha is None
|
||||
|
||||
|
||||
def test_esc_from_the_reopened_commit_list_returns_to_the_branches_view(monkeypatch):
|
||||
loads = []
|
||||
monkeypatch.setattr(commands.branches, "load", lambda view, st, keep_caret=False: loads.append(st.mode))
|
||||
window = sublime.Window()
|
||||
view = sublime.View()
|
||||
st = state.ViewState("/repo")
|
||||
st.mode = state.MODE_BRANCHES
|
||||
commit = git.Commit("a" * 40, "a" * 7, "me", "today", "subject", 1, 1, 0)
|
||||
# Esc on the list opened straight over the branches view: nothing to put back
|
||||
st.drawn, st.rendered_token = st.describe(), st.token
|
||||
commands.VdiffCommitsCommand(window).show_commits(view, st, [commit], 0)
|
||||
window.panel[1](-1)
|
||||
assert loads == []
|
||||
# reopened after a commit's files were cancelled: the state says branches, the screen still shows the commit
|
||||
st.drawn = (state.MODE_DIFF, "a" * 40, False, "x.py")
|
||||
commands.VdiffCommitsCommand(window).show_commits(view, st, [commit], 0)
|
||||
window.panel[1](-1)
|
||||
assert loads == [state.MODE_BRANCHES]
|
||||
# the same holds for a diff the list was reopened over: the kept working-tree file is shown again
|
||||
shown = []
|
||||
monkeypatch.setattr(commands, "show_file", lambda view, st, c: shown.append(c.path))
|
||||
st.mode, st.change = state.MODE_DIFF, change("kept.py")
|
||||
commands.VdiffCommitsCommand(window).show_commits(view, st, [commit], 0)
|
||||
window.panel[1](-1)
|
||||
assert shown == ["kept.py"]
|
||||
|
||||
|
||||
def test_files_on_a_clean_tree_leave_the_branches_view_in_place(monkeypatch):
|
||||
view, st = sublime.View(), state.ViewState("/repo")
|
||||
messages, notices = [], []
|
||||
monkeypatch.setattr(commands, "open_review", lambda window: (view, st))
|
||||
monkeypatch.setattr(commands, "status", messages.append)
|
||||
monkeypatch.setattr(commands.render, "render_message", lambda view, st, text: notices.append(text))
|
||||
monkeypatch.setattr(commands.git, "changed_files", lambda repo: [])
|
||||
window = sublime.Window()
|
||||
st.mode = state.MODE_BRANCHES
|
||||
commands.VdiffFilesCommand(window).run()
|
||||
assert messages == ["no uncommitted changes"] and notices == [] and st.in_branches and window.panel is None
|
||||
# with changes the panel comes up as usual; in a diff view the notice is shown
|
||||
monkeypatch.setattr(commands.git, "changed_files", lambda repo: [change("a.py")])
|
||||
commands.VdiffFilesCommand(window).run()
|
||||
assert window.panel is not None
|
||||
# nor does a commit under review give way to it
|
||||
st.mode, st.sha = state.MODE_DIFF, "a" * 40
|
||||
monkeypatch.setattr(commands.git, "changed_files", lambda repo: [])
|
||||
commands.VdiffFilesCommand(window).run()
|
||||
assert notices == [] and st.sha == "a" * 40
|
||||
st.sha = None
|
||||
commands.VdiffFilesCommand(window).run()
|
||||
assert notices == ["No uncommitted changes in /repo"]
|
||||
|
||||
|
||||
def test_step_change_uses_blocks(rings):
|
||||
view, st = at_change([(2, 4), (7, 8)], 0)
|
||||
commands.ACTIONS["next_change"](view, None, st)
|
||||
@@ -476,14 +529,6 @@ def test_esc_rewinds_the_file_navigation_counts_from(loading):
|
||||
# --- cycling past the ends --------------------------------------------------
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def rings(monkeypatch):
|
||||
"""Record visual bells instead of drawing them"""
|
||||
bells = []
|
||||
monkeypatch.setattr(commands.render, "flash", lambda view: bells.append(view))
|
||||
return bells
|
||||
|
||||
|
||||
def at_file(files, path):
|
||||
"""A loaded working-tree view sitting on `path`"""
|
||||
view, window = sublime.View(), sublime.Window()
|
||||
@@ -600,6 +645,9 @@ def test_next_unstaged_scans_forward_and_wraps():
|
||||
assert commands._next_unstaged(files, 2) == 2 # the slot we count from counts itself
|
||||
assert commands._next_unstaged(files, 3) == 0 # wraps past the end
|
||||
assert commands._next_unstaged(flagged(True, True), 0) == -1
|
||||
# a partially staged file still has hunks to stage
|
||||
partial = git.FileChange("p.py", "M", True, 1, 1, None, unstaged=True)
|
||||
assert commands._next_unstaged(flagged(True, True) + [partial], 0) == 2
|
||||
|
||||
|
||||
def test_staging_moves_to_the_next_unstaged_file(monkeypatch):
|
||||
@@ -653,6 +701,10 @@ def test_stage_all_and_unstage_all_need_something_to_do(monkeypatch):
|
||||
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"]
|
||||
# a partially staged file is something to stage
|
||||
partial = git.FileChange("p.py", "M", True, 1, 1, None, unstaged=True)
|
||||
assert press(monkeypatch, "stage_all", flagged(True) + [partial], "f0.py", flagged(True, True)) == ["f0.py"]
|
||||
assert messages[-1] == "staged 1 file"
|
||||
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)
|
||||
@@ -744,9 +796,31 @@ def heading_row(st, path):
|
||||
return next(i for i, (c, _, section) in enumerate(st.all_rows) if section and c.path == path)
|
||||
|
||||
|
||||
def put_caret(view, row):
|
||||
view.sel().clear()
|
||||
view.sel().add(sublime.Region(commands.render.index_point(view, row)))
|
||||
def test_the_header_follows_the_caret_from_file_to_file():
|
||||
from vdiff import listeners
|
||||
view, st = all_files_view()
|
||||
st.files[1] = git.FileChange("b.py", "M", False, 0, 4, None)
|
||||
commands.render.render_all(view, st)
|
||||
st.rendered_token = st.token
|
||||
commands.render.init_view(view)
|
||||
state.put(view, st)
|
||||
title = lambda: view.phantoms[commands.render.PHANTOM_KEY][0].content.split("</div>", 1)[1] # noqa: E731
|
||||
listener = listeners.VdiffEventListener()
|
||||
put_caret(view, heading_row(st, "b.py") + 1)
|
||||
listener.on_selection_modified(view)
|
||||
assert st.change.path == "b.py" and ">b.py<" in title() and '<span class="del">-4</span> <span class="ins">+0</span>' in title()
|
||||
# within the same file nothing is redrawn; back in a.py the header is a.py's again
|
||||
shown = view.phantoms[commands.render.PHANTOM_KEY]
|
||||
listener.on_selection_modified(view)
|
||||
assert view.phantoms[commands.render.PHANTOM_KEY] is shown
|
||||
put_caret(view, heading_row(st, "a.py"))
|
||||
listener.on_selection_modified(view)
|
||||
assert ">a.py<" in title() and '<span class="del">-1</span> <span class="ins">+1</span>' in title()
|
||||
# not while a render is pending: the rows describe the old text
|
||||
st.token += 1
|
||||
put_caret(view, heading_row(st, "b.py"))
|
||||
listener.on_selection_modified(view)
|
||||
assert st.change.path == "a.py"
|
||||
|
||||
|
||||
def test_all_files_step_change_from_a_heading_lands_on_its_first_hunk():
|
||||
|
||||
Reference in New Issue
Block a user