Update test fixtures and snapshots to reflect TileList component and panel widget refactoring. Adjust integration tests for new file browser behavior. Co-Authored-By: Claude <noreply@anthropic.com>
151 lines
5.1 KiB
Python
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
|