"""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"])