development-hub/tests/test_draggable_tabs.py

215 lines
6.3 KiB
Python

"""Tests for draggable tab functionality."""
import json
import pytest
from development_hub.draggable_tab_widget import (
DraggableTabBar,
DraggableTabWidget,
TAB_MIME_TYPE,
)
class TestDraggableTabBar:
"""Tests for DraggableTabBar."""
def test_create_with_pane_id(self, qtbot):
"""Tab bar stores pane ID."""
bar = DraggableTabBar("test-pane-123")
qtbot.addWidget(bar)
assert bar.pane_id == "test-pane-123"
def test_accepts_drops(self, qtbot):
"""Tab bar accepts drops."""
bar = DraggableTabBar("test")
qtbot.addWidget(bar)
assert bar.acceptDrops() == True
class TestDraggableTabWidget:
"""Tests for DraggableTabWidget."""
def test_create_with_pane_id(self, qtbot):
"""Tab widget stores pane ID."""
widget = DraggableTabWidget(pane_id="my-pane")
qtbot.addWidget(widget)
assert widget.pane_id == "my-pane"
def test_auto_generates_pane_id(self, qtbot):
"""Tab widget auto-generates pane ID if not provided."""
widget = DraggableTabWidget()
qtbot.addWidget(widget)
assert widget.pane_id is not None
assert len(widget.pane_id) > 0
def test_pane_id_setter(self, qtbot):
"""Pane ID can be set after creation."""
widget = DraggableTabWidget()
qtbot.addWidget(widget)
widget.pane_id = "new-pane-id"
assert widget.pane_id == "new-pane-id"
def test_accepts_drops(self, qtbot):
"""Tab widget accepts drops."""
widget = DraggableTabWidget()
qtbot.addWidget(widget)
assert widget.acceptDrops() == True
def test_tabs_closable(self, qtbot):
"""Tabs are closable."""
widget = DraggableTabWidget()
qtbot.addWidget(widget)
assert widget.tabsClosable() == True
def test_tabs_movable(self, qtbot):
"""Tabs are movable."""
widget = DraggableTabWidget()
qtbot.addWidget(widget)
assert widget.isMovable() == True
def test_drop_index_empty(self, qtbot):
"""Drop index at end when no tabs."""
widget = DraggableTabWidget()
qtbot.addWidget(widget)
from PySide6.QtCore import QPoint
index = widget._get_drop_index(QPoint(0, 0))
assert index == 0
def test_custom_tab_bar(self, qtbot):
"""Uses custom DraggableTabBar."""
widget = DraggableTabWidget(pane_id="test")
qtbot.addWidget(widget)
assert isinstance(widget.tabBar(), DraggableTabBar)
assert widget.tabBar().pane_id == "test"
class TestMimeData:
"""Tests for MIME data format."""
def test_mime_type_constant(self):
"""MIME type constant is defined."""
assert TAB_MIME_TYPE == "application/x-devhub-tab"
def test_drag_data_format(self):
"""Drag data includes required fields."""
data = {
"pane_id": "source-pane",
"tab_index": 2,
"tab_text": "Terminal",
}
encoded = json.dumps(data).encode('utf-8')
decoded = json.loads(encoded.decode('utf-8'))
assert decoded["pane_id"] == "source-pane"
assert decoded["tab_index"] == 2
assert decoded["tab_text"] == "Terminal"
class TestPaneWidgetTabOperations:
"""Tests for PaneWidget tab operations used in cross-pane drag."""
def test_take_tab_at_valid_index(self, qtbot):
"""take_tab_at removes and returns tab at index."""
from PySide6.QtWidgets import QLabel
from development_hub.pane_widget import PaneWidget
pane = PaneWidget()
qtbot.addWidget(pane)
# Add some tabs
label1 = QLabel("Tab 1")
label2 = QLabel("Tab 2")
pane.tab_widget.addTab(label1, "First")
pane.tab_widget.addTab(label2, "Second")
assert pane.tab_count() == 2
result = pane.take_tab_at(0)
assert result is not None
widget, title = result
assert title == "First"
assert pane.tab_count() == 1
def test_take_tab_at_invalid_index(self, qtbot):
"""take_tab_at returns None for invalid index."""
from development_hub.pane_widget import PaneWidget
pane = PaneWidget()
qtbot.addWidget(pane)
result = pane.take_tab_at(99)
assert result is None
result = pane.take_tab_at(-1)
assert result is None
def test_insert_widget_tab(self, qtbot):
"""insert_widget_tab inserts at correct position."""
from PySide6.QtWidgets import QLabel
from development_hub.pane_widget import PaneWidget
pane = PaneWidget()
qtbot.addWidget(pane)
label1 = QLabel("Tab 1")
label2 = QLabel("Tab 2")
label3 = QLabel("Tab 3")
pane.tab_widget.addTab(label1, "First")
pane.tab_widget.addTab(label2, "Second")
# Insert in middle
pane.insert_widget_tab(1, label3, "Inserted")
assert pane.tab_count() == 3
assert pane.tab_widget.tabText(0) == "First"
assert pane.tab_widget.tabText(1) == "Inserted"
assert pane.tab_widget.tabText(2) == "Second"
def test_pane_has_unique_id(self, qtbot):
"""Each pane has a unique ID."""
from development_hub.pane_widget import PaneWidget
pane1 = PaneWidget()
pane2 = PaneWidget()
qtbot.addWidget(pane1)
qtbot.addWidget(pane2)
assert pane1.pane_id != pane2.pane_id
assert len(pane1.pane_id) > 0
assert len(pane2.pane_id) > 0
class TestWorkspaceTabDropHandling:
"""Tests for workspace manager tab drop handling."""
def test_find_pane_by_id(self, qtbot):
"""Workspace can find pane by ID."""
from development_hub.workspace_manager import WorkspaceManager
manager = WorkspaceManager()
qtbot.addWidget(manager)
panes = manager.find_panes()
assert len(panes) == 1
pane = panes[0]
found = manager._find_pane_by_id(pane.pane_id)
assert found == pane
def test_find_pane_by_id_not_found(self, qtbot):
"""Returns None for unknown pane ID."""
from development_hub.workspace_manager import WorkspaceManager
manager = WorkspaceManager()
qtbot.addWidget(manager)
found = manager._find_pane_by_id("nonexistent-id")
assert found is None
if __name__ == "__main__":
pytest.main([__file__, "-v"])