Files
clide/legacy/tests/integration/test_files_view.py
T
jpmschweitzerandClaude Opus 4.7 a355751437 move python clide to legacy/
Clide is being rebuilt as a Flutter desktop app. The Python Textual
implementation moves wholesale into legacy/ rather than being deleted:
its pane model, panel set, git skills, and panel communication design
are real thought that should remain readable next to the new code
while the rebuild finds its shape. Git's rename tracking preserves
history, so `git log -- legacy/` still works.

The Flutter rebuild lives at the repo root alongside a Go sidecar
(the architecture claudian was heading toward, which folds into
clide as a core component rather than a separate plugin project).
Bootstrap of the new shape lands in subsequent commits.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 20:30:51 +02:00

151 lines
5.1 KiB
Python

"""Integration tests for FilesView widget."""
from pathlib import Path
import pytest
from textual.app import App, ComposeResult
from clide.widgets.components.files_view import FilesView
class FilesViewTestApp(App):
"""Test app for FilesView."""
def __init__(self, path: Path) -> None:
super().__init__()
self.test_path = path
self.selected_files: list[Path] = []
self.selected_dirs: list[Path] = []
def compose(self) -> ComposeResult:
yield FilesView(self.test_path, id="files")
def on_files_view_file_selected(self, event: FilesView.FileSelected) -> None:
self.selected_files.append(event.path)
def on_files_view_directory_selected(self, event: FilesView.DirectorySelected) -> None:
self.selected_dirs.append(event.path)
@pytest.fixture
def test_directory(tmp_path: Path) -> Path:
"""Create a test directory structure."""
# Create directories
(tmp_path / "src").mkdir()
(tmp_path / "src" / "components").mkdir()
(tmp_path / "tests").mkdir()
# Create files
(tmp_path / "README.md").write_text("# Test")
(tmp_path / "src" / "main.py").write_text("print('hello')")
(tmp_path / "src" / "components" / "button.py").write_text("class Button: pass")
(tmp_path / "tests" / "test_main.py").write_text("def test_main(): pass")
return tmp_path
async def test_files_view_renders(test_directory: Path):
"""Test that FilesView renders without errors."""
app = FilesViewTestApp(test_directory)
async with app.run_test():
files_view = app.query_one("#files", FilesView)
assert files_view is not None
assert files_view.path == test_directory
async def test_files_view_shows_files(test_directory: Path):
"""Test that FilesView shows files in the directory."""
app = FilesViewTestApp(test_directory)
async with app.run_test():
files_view = app.query_one("#files", FilesView)
# The root should be loaded
assert files_view.root is not None
async def test_directory_click_expands(test_directory: Path):
"""Test that clicking a directory expands it and emits event."""
app = FilesViewTestApp(test_directory)
async with app.run_test() as pilot:
files_view = app.query_one("#files", FilesView)
# Wait for initial load
await pilot.pause()
# Find the src directory node and click it
for node in files_view.root.children:
if node.data and node.data.path.name == "src":
files_view.select_node(node)
await pilot.pause()
break
# Check that directory was selected
assert len(app.selected_dirs) >= 1
assert any(p.name == "src" for p in app.selected_dirs)
async def test_file_click_emits_event(test_directory: Path):
"""Test that clicking a file emits FileSelected event."""
app = FilesViewTestApp(test_directory)
async with app.run_test() as pilot:
files_view = app.query_one("#files", FilesView)
# Wait for initial load
await pilot.pause()
# Find and click README.md
for node in files_view.root.children:
if node.data and node.data.path.name == "README.md":
files_view.select_node(node)
await pilot.pause()
break
# Check that file was selected
assert len(app.selected_files) >= 1
assert any(p.name == "README.md" for p in app.selected_files)
async def test_filter_paths_hides_noisy_dirs(test_directory: Path):
"""Test that noisy directories are filtered but hidden files are shown."""
# Create hidden files/dirs and noisy dirs
(test_directory / ".git").mkdir()
(test_directory / ".hidden_file").write_text("hidden")
(test_directory / "__pycache__").mkdir()
app = FilesViewTestApp(test_directory)
async with app.run_test() as pilot:
files_view = app.query_one("#files", FilesView)
# Wait for initial load
await pilot.pause()
# Get visible items in the tree
visible_names = {node.data.path.name for node in files_view.root.children if node.data}
# Noisy directories should be filtered out
assert ".git" not in visible_names
assert "__pycache__" not in visible_names
# Hidden files are shown (they'll be dimmed in the UI)
assert ".hidden_file" in visible_names
# Regular files/dirs are shown
assert "src" in visible_names
assert "README.md" in visible_names
async def test_render_label_shows_icons(test_directory: Path):
"""Test that render_label produces proper icons."""
app = FilesViewTestApp(test_directory)
async with app.run_test() as pilot:
files_view = app.query_one("#files", FilesView)
# Wait for initial load
await pilot.pause()
# Check that nodes have labels rendered (icons are part of label)
for node in files_view.root.children:
if node.data:
# The label should contain the filename
label_text = str(node.label)
assert node.data.path.name in label_text