CAM: Replace complete tool management (PR 21425)
This commit is contained in:
151
src/Mod/CAM/CAMTests/TestPathToolBitBrowserWidget.py
Normal file
151
src/Mod/CAM/CAMTests/TestPathToolBitBrowserWidget.py
Normal file
@@ -0,0 +1,151 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# ***************************************************************************
|
||||
# * Copyright (c) 2024 FreeCAD Team *
|
||||
# * *
|
||||
# * This program is free software; you can redistribute it and/or modify *
|
||||
# * it under the terms of the GNU Lesser General Public License (LGPL) *
|
||||
# * as published by the Free Software Foundation; either version 2 of *
|
||||
# * the License, or (at your option) any later version. *
|
||||
# * for detail see the LICENSE text file. *
|
||||
# * *
|
||||
# * This program is distributed in the hope that it will be useful, *
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
# * GNU Library General Public License for more details. *
|
||||
# * *
|
||||
# * You should have received a copy of the GNU Library General Public *
|
||||
# * License along with this program; if not, write to the FreeCAD *
|
||||
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
# * USA *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
|
||||
"""Unit tests for the ToolBitBrowserWidget."""
|
||||
|
||||
import unittest
|
||||
from unittest.mock import MagicMock
|
||||
from typing import cast
|
||||
from Path.Tool.toolbit.ui.browser import ToolBitBrowserWidget, ToolBitUriRole
|
||||
from Path.Tool.toolbit.ui.tablecell import TwoLineTableCell
|
||||
from Path.Tool.toolbit.models.base import ToolBit
|
||||
from .PathTestUtils import PathTestWithAssets
|
||||
|
||||
|
||||
class TestToolBitBrowserWidget(PathTestWithAssets):
|
||||
"""Tests for ToolBitBrowserWidget using real assets and widgets."""
|
||||
|
||||
def setUp(self):
|
||||
super().setUp() # Call the base class setUp to initialize assets
|
||||
# The browser widget uses the global cam_assets, which is set up
|
||||
# by PathTestWithAssets.
|
||||
self.widget = ToolBitBrowserWidget(self.assets)
|
||||
|
||||
def test_initial_fetch(self):
|
||||
# Verify that the list widget is populated after initialization
|
||||
# The default test assets include some toolbits.
|
||||
self.assertGreater(self.widget._tool_list_widget.count(), 0)
|
||||
|
||||
# Verify apply_filter was called on the list widget with empty string
|
||||
# We can check the search_highlight property on the cell widgets
|
||||
# as apply_filter sets this.
|
||||
for i in range(self.widget._tool_list_widget.count()):
|
||||
item = self.widget._tool_list_widget.item(i)
|
||||
cell = self.widget._tool_list_widget.itemWidget(item)
|
||||
self.assertIsInstance(cell, TwoLineTableCell)
|
||||
self.assertEqual(cell.search_highlight, "")
|
||||
|
||||
def test_search_filtering(self):
|
||||
# Simulate typing in the search box
|
||||
search_term = "Endmill"
|
||||
self.widget._search_edit.setText(search_term)
|
||||
|
||||
# Directly trigger the fetch and filtering logic
|
||||
self.widget._trigger_fetch()
|
||||
|
||||
# Verify that the filter was applied to the list widget
|
||||
# We can check if items are hidden/shown based on the filter term
|
||||
# This requires knowing the content of the test assets.
|
||||
# Assuming '5mm_Endmill' and '10mm_Endmill' contain "Endmill"
|
||||
# and 'BallEndmill_3mm' does not.
|
||||
|
||||
# Re-fetch assets to know their labels/names for verification
|
||||
all_assets = self.assets.fetch(asset_type="toolbit", depth=0)
|
||||
expected_visible_uris = set()
|
||||
for asset in all_assets:
|
||||
tb = cast(ToolBit, asset)
|
||||
is_expected = (
|
||||
search_term.lower() in tb.label.lower() or search_term.lower() in tb.summary.lower()
|
||||
)
|
||||
if is_expected:
|
||||
expected_visible_uris.add(str(tb.get_uri()))
|
||||
|
||||
actual_visible_uris = set()
|
||||
for i in range(self.widget._tool_list_widget.count()):
|
||||
item = self.widget._tool_list_widget.item(i)
|
||||
cell = self.widget._tool_list_widget.itemWidget(item)
|
||||
self.assertIsInstance(cell, TwoLineTableCell)
|
||||
item_uri = item.data(ToolBitUriRole)
|
||||
|
||||
# Verify highlight was called on all cells
|
||||
self.assertEqual(cell.search_highlight, search_term)
|
||||
|
||||
if not item.isHidden():
|
||||
actual_visible_uris.add(item_uri)
|
||||
|
||||
self.assertEqual(actual_visible_uris, expected_visible_uris)
|
||||
|
||||
def test_lazy_loading_on_scroll(self):
|
||||
# This test requires more than self._batch_size toolbits to be effective.
|
||||
# The default test assets might not have enough.
|
||||
# We'll assume there are enough for the test structure.
|
||||
|
||||
initial_count = self.widget._tool_list_widget.count()
|
||||
if initial_count < self.widget._batch_size:
|
||||
self.skipTest("Not enough toolbits for lazy loading test.")
|
||||
|
||||
# Simulate scrolling to the bottom by emitting the signal
|
||||
scrollbar = self.widget._tool_list_widget.verticalScrollBar()
|
||||
# Set the scrollbar value to its maximum to simulate reaching the end
|
||||
scrollbar.valueChanged.emit(scrollbar.maximum())
|
||||
|
||||
# Verify that more items were loaded
|
||||
new_count = self.widget._tool_list_widget.count()
|
||||
self.assertGreater(new_count, initial_count)
|
||||
# Verify that the number of new items is approximately the batch size
|
||||
self.assertAlmostEqual(
|
||||
new_count - initial_count, self.widget._batch_size, delta=5
|
||||
) # Allow small delta
|
||||
|
||||
def test_tool_selected_signal(self):
|
||||
mock_slot = MagicMock()
|
||||
self.widget.toolSelected.connect(mock_slot)
|
||||
|
||||
# Select the first item in the list widget
|
||||
if self.widget._tool_list_widget.count() == 0:
|
||||
self.skipTest("Not enough toolbits for selection test.")
|
||||
first_item = self.widget._tool_list_widget.item(0)
|
||||
self.widget._tool_list_widget.setCurrentItem(first_item)
|
||||
|
||||
# Verify signal was emitted with the correct URI
|
||||
expected_uri = first_item.data(ToolBitUriRole)
|
||||
mock_slot.assert_called_once_with(expected_uri)
|
||||
|
||||
def test_tool_edit_requested_signal(self):
|
||||
mock_slot = MagicMock()
|
||||
self.widget.itemDoubleClicked.connect(mock_slot)
|
||||
|
||||
# Double-click the first item in the list widget
|
||||
if self.widget._tool_list_widget.count() == 0:
|
||||
self.skipTest("Not enough toolbits for double-click test.")
|
||||
|
||||
first_item = self.widget._tool_list_widget.item(0)
|
||||
# Simulate double-click signal emission from the list widget
|
||||
self.widget._tool_list_widget.itemDoubleClicked.emit(first_item)
|
||||
|
||||
# Verify signal was emitted with the correct URI
|
||||
expected_uri = first_item.data(ToolBitUriRole)
|
||||
mock_slot.assert_called_once_with(expected_uri)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user