checkpoint: 0.3.0 ui header, history persistence and history filter
This commit is contained in:
@@ -2,7 +2,7 @@ from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from app.history import SessionHistory
|
||||
from app.history import SessionHistory, default_history_path
|
||||
|
||||
|
||||
def test_visit_records_current_directory(tmp_path: Path) -> None:
|
||||
@@ -82,3 +82,48 @@ def test_select_raises_for_invalid_index() -> None:
|
||||
|
||||
with pytest.raises(IndexError):
|
||||
history.select(0)
|
||||
|
||||
|
||||
def test_persistent_history_loads_entries_from_disk(tmp_path: Path) -> None:
|
||||
first = tmp_path / "first"
|
||||
second = tmp_path / "second"
|
||||
for directory in (first, second):
|
||||
directory.mkdir()
|
||||
history_file = tmp_path / "history.txt"
|
||||
history_file.write_text(f"{first}\n{second}\n", encoding="utf-8")
|
||||
|
||||
history = SessionHistory.persistent(storage_path=history_file)
|
||||
|
||||
assert history.entries() == (first.resolve(), second.resolve())
|
||||
assert history.current == second.resolve()
|
||||
|
||||
|
||||
def test_persistent_history_visit_writes_to_disk_and_applies_limit(
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
first = tmp_path / "first"
|
||||
second = tmp_path / "second"
|
||||
third = tmp_path / "third"
|
||||
for directory in (first, second, third):
|
||||
directory.mkdir()
|
||||
history_file = tmp_path / "state" / "history.txt"
|
||||
|
||||
history = SessionHistory.persistent(storage_path=history_file, max_entries=2)
|
||||
history.visit(first)
|
||||
history.visit(second)
|
||||
history.visit(third)
|
||||
|
||||
assert history.entries() == (second.resolve(), third.resolve())
|
||||
assert history_file.read_text(encoding="utf-8").splitlines() == [
|
||||
str(second.resolve()),
|
||||
str(third.resolve()),
|
||||
]
|
||||
|
||||
|
||||
def test_default_history_path_uses_override_env(
|
||||
monkeypatch: pytest.MonkeyPatch, tmp_path: Path
|
||||
) -> None:
|
||||
override = tmp_path / "custom-history.txt"
|
||||
monkeypatch.setenv("CD_BROWSER_HISTORY_FILE", str(override))
|
||||
|
||||
assert default_history_path() == override
|
||||
|
||||
@@ -5,11 +5,13 @@ import pytest
|
||||
|
||||
from app.navigator import Navigator, VisibleEntry
|
||||
from app.ui import (
|
||||
ESCAPE_KEY,
|
||||
HistoryLine,
|
||||
RenderLine,
|
||||
TerminalUI,
|
||||
build_history_lines,
|
||||
build_render_lines,
|
||||
build_status_line,
|
||||
clamp_scroll_offset,
|
||||
format_entry,
|
||||
move_selection,
|
||||
@@ -147,6 +149,62 @@ def test_history_mode_enter_selects_entry_and_exits(tmp_path: Path) -> None:
|
||||
assert navigator.selected_index == 0
|
||||
|
||||
|
||||
def test_history_mode_slash_activates_history_filter() -> None:
|
||||
ui = TerminalUI()
|
||||
navigator = Navigator(Path.cwd())
|
||||
ui._history_mode = True
|
||||
|
||||
ui._handle_history_key(ord("/"), navigator)
|
||||
|
||||
assert ui._history_filter_mode is True
|
||||
assert ui._history_filter_query == ""
|
||||
|
||||
|
||||
def test_history_filter_enter_selects_filtered_entry_and_exits_history(
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
root = tmp_path / "root"
|
||||
alpha = root / "alpha"
|
||||
beta = root / "beta"
|
||||
root.mkdir()
|
||||
alpha.mkdir()
|
||||
beta.mkdir()
|
||||
|
||||
navigator = Navigator(root)
|
||||
navigator.set_selected_index(1)
|
||||
navigator.enter_selected_directory()
|
||||
navigator.go_to_parent_directory()
|
||||
navigator.set_selected_index(2)
|
||||
navigator.enter_selected_directory()
|
||||
|
||||
ui = TerminalUI()
|
||||
ui._toggle_history_mode(navigator)
|
||||
ui._history_filter_mode = True
|
||||
ui._history_filter_query = "alpha"
|
||||
|
||||
ui._handle_history_key(10, navigator)
|
||||
|
||||
assert navigator.current_path == alpha.resolve()
|
||||
assert ui._history_mode is False
|
||||
assert ui._history_filter_mode is False
|
||||
|
||||
|
||||
def test_history_filter_escape_disables_only_history_filter(tmp_path: Path) -> None:
|
||||
root = tmp_path / "root"
|
||||
root.mkdir()
|
||||
navigator = Navigator(root)
|
||||
ui = TerminalUI()
|
||||
ui._toggle_history_mode(navigator)
|
||||
ui._history_filter_mode = True
|
||||
ui._history_filter_query = "ro"
|
||||
|
||||
ui._handle_history_key(ESCAPE_KEY, navigator)
|
||||
|
||||
assert ui._history_mode is True
|
||||
assert ui._history_filter_mode is False
|
||||
assert ui._history_filter_query == ""
|
||||
|
||||
|
||||
def test_history_mode_toggle_off_keeps_current_directory(tmp_path: Path) -> None:
|
||||
root = tmp_path / "root"
|
||||
root.mkdir()
|
||||
@@ -264,6 +322,30 @@ def test_filter_matching_is_case_insensitive(tmp_path: Path) -> None:
|
||||
assert matches == [1]
|
||||
|
||||
|
||||
def test_build_status_line_shows_filter_off_when_filter_mode_is_disabled(
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
root = tmp_path / "root"
|
||||
root.mkdir()
|
||||
navigator = Navigator(root)
|
||||
|
||||
status_line = build_status_line(navigator, filter_mode=False, filter_query="")
|
||||
|
||||
assert "filter: off" in status_line
|
||||
|
||||
|
||||
def test_build_status_line_shows_empty_filter_without_off_when_filter_is_active(
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
root = tmp_path / "root"
|
||||
root.mkdir()
|
||||
navigator = Navigator(root)
|
||||
|
||||
status_line = build_status_line(navigator, filter_mode=True, filter_query="")
|
||||
|
||||
assert "filter: |" in status_line
|
||||
|
||||
|
||||
def test_filter_mode_uses_g_and_g_upper_as_query_characters(tmp_path: Path) -> None:
|
||||
root = tmp_path / "root"
|
||||
root.mkdir()
|
||||
|
||||
Reference in New Issue
Block a user