| | """GUI tests for ArchReport features that require a running FreeCAD GUI. |
| | |
| | These tests inherit from the GUI test base `TestArchBaseGui` which skips |
| | the whole class when `FreeCAD.GuiUp` is False. |
| | """ |
| |
|
| | import FreeCAD |
| | import Arch |
| | import FreeCADGui |
| | import ArchReport |
| |
|
| | from bimtests.TestArchBaseGui import TestArchBaseGui |
| |
|
| |
|
| | class TestArchReportGui(TestArchBaseGui): |
| | """GUI-enabled tests ported from TestArchReport. |
| | |
| | These tests rely on Qt widgets and the BIM workbench UI panels. |
| | """ |
| |
|
| | def setUp(self): |
| | super().setUp() |
| | self.doc = self.document |
| | self.panel = None |
| |
|
| | |
| | self.wall_ext = Arch.makeWall(length=1000, name="Exterior Wall") |
| | self.wall_ext.IfcType = "Wall" |
| | self.wall_ext.Height = FreeCAD.Units.Quantity(3000, "mm") |
| |
|
| | self.wall_int = Arch.makeWall(length=500, name="Interior partition wall") |
| | self.wall_int.IfcType = "Wall" |
| | self.wall_int.Height = FreeCAD.Units.Quantity(2500, "mm") |
| |
|
| | self.column = Arch.makeStructure(length=300, width=330, height=2000, name="Main Column") |
| | self.column.IfcType = "Column" |
| |
|
| | self.beam = Arch.makeStructure(length=2000, width=200, height=400, name="Main Beam") |
| | self.beam.IfcType = "Beam" |
| |
|
| | self.window = Arch.makeWindow(name="Living Room Window") |
| | self.window.IfcType = "Window" |
| |
|
| | self.part_box = self.doc.addObject("Part::Box", "Generic Box") |
| |
|
| | |
| | self.spreadsheet = self.doc.addObject("Spreadsheet::Sheet", "ReportTarget") |
| | self.doc.recompute() |
| |
|
| | def tearDown(self): |
| | |
| | if self.panel: |
| | |
| | FreeCADGui.Control.closeDialog() |
| | self.panel = None |
| | super().tearDown() |
| |
|
| | def test_cheatsheet_dialog_creation(self): |
| | """Tests that the Cheatsheet dialog can be created without errors.""" |
| | api_data = Arch.getSqlApiDocumentation() |
| | dialog = ArchReport.CheatsheetDialog(api_data) |
| | self.assertIsNotNone(dialog) |
| |
|
| | def DISABLED_test_preview_pane_toggle_and_refresh(self): |
| | """ |
| | Tests the user workflow for the preview pane: toggling visibility, |
| | refreshing with a valid query, and checking the results. |
| | This replaces the obsolete test_task_panel_on_demand_preview. |
| | """ |
| | |
| | report_obj = Arch.makeReport(name="PreviewToggleTestReport") |
| | self.panel = ArchReport.ReportTaskPanel(report_obj) |
| | |
| | self.panel._start_edit_session(row_index=0) |
| |
|
| | |
| | self.assertFalse( |
| | self.panel.preview_pane.isVisible(), "Preview pane should be hidden by default." |
| | ) |
| |
|
| | |
| | |
| | self.panel.btn_toggle_preview.setChecked(True) |
| | self.pump_gui_events() |
| |
|
| | |
| | self.assertTrue( |
| | self.panel.preview_pane.isVisible(), |
| | "Preview pane should be visible after toggling it on.", |
| | ) |
| | self.assertEqual( |
| | self.panel.btn_toggle_preview.text(), |
| | "Hide Preview", |
| | "Button text should update to 'Hide Preview'.", |
| | ) |
| | self.assertTrue( |
| | self.panel.btn_refresh_preview.isVisible(), |
| | "Refresh button should be visible when pane is open.", |
| | ) |
| |
|
| | |
| | query = "SELECT Label, IfcType FROM document WHERE IfcType = 'Wall' ORDER BY Label" |
| | self.panel.sql_query_edit.setPlainText(query) |
| | self.panel.btn_refresh_preview.click() |
| | self.pump_gui_events() |
| |
|
| | |
| | self.assertEqual( |
| | self.panel.table_preview_results.columnCount(), |
| | 2, |
| | "Preview table should have 2 columns for the valid query.", |
| | ) |
| | self.assertEqual( |
| | self.panel.table_preview_results.rowCount(), |
| | 2, |
| | "Preview table should have 2 rows for the two wall objects.", |
| | ) |
| | |
| | self.assertEqual(self.panel.table_preview_results.item(0, 0).text(), self.wall_ext.Label) |
| | self.assertEqual(self.panel.table_preview_results.item(1, 1).text(), self.wall_int.IfcType) |
| |
|
| | |
| | self.panel.btn_toggle_preview.setChecked(False) |
| | self.pump_gui_events() |
| |
|
| | |
| | self.assertFalse( |
| | self.panel.preview_pane.isVisible(), |
| | "Preview pane should be hidden after toggling it off.", |
| | ) |
| | self.assertEqual( |
| | self.panel.btn_toggle_preview.text(), |
| | "Show Preview", |
| | "Button text should revert to 'Show Preview'.", |
| | ) |
| |
|
| | def DISABLED_test_preview_pane_displays_errors_gracefully(self): |
| | """ |
| | Tests that the preview pane displays a user-friendly error message when |
| | the query is invalid, instead of raising an exception. |
| | This replaces the obsolete test_preview_button_handles_errors_gracefully_in_ui. |
| | """ |
| | |
| | report_obj = Arch.makeReport(name="PreviewErrorTestReport") |
| | self.panel = ArchReport.ReportTaskPanel(report_obj) |
| | self.panel._start_edit_session(row_index=0) |
| | self.panel.btn_toggle_preview.setChecked(True) |
| | self.pump_gui_events() |
| |
|
| | |
| | invalid_query = "SELECT Label FRM document" |
| | self.panel.sql_query_edit.setPlainText(invalid_query) |
| | self.panel.btn_refresh_preview.click() |
| | self.pump_gui_events() |
| |
|
| | |
| | self.assertTrue( |
| | self.panel.table_preview_results.isVisible(), |
| | "Preview table should remain visible to display the error.", |
| | ) |
| | self.assertEqual( |
| | self.panel.table_preview_results.rowCount(), |
| | 1, |
| | "Error display should occupy a single row.", |
| | ) |
| | self.assertEqual( |
| | self.panel.table_preview_results.columnCount(), |
| | 1, |
| | "Error display should occupy a single column.", |
| | ) |
| |
|
| | error_item = self.panel.table_preview_results.item(0, 0) |
| | self.assertIsNotNone(error_item, "An error item should have been placed in the table.") |
| | |
| | self.assertIn( |
| | "Syntax Error", error_item.text(), "The error message should indicate a syntax error." |
| | ) |
| | self.assertIn( |
| | "❌", error_item.text(), "The error message should contain a visual error indicator." |
| | ) |
| |
|
| | def test_hover_tooltips(self): |
| | """Tests that the SQL editor can generate tooltips.""" |
| | editor = ArchReport.SqlQueryEditor() |
| | api_docs = Arch.getSqlApiDocumentation() |
| | editor.set_api_documentation(api_docs) |
| |
|
| | func_tooltip = editor._get_tooltip_for_word("CONVERT") |
| | self.assertIn("CONVERT(quantity, 'unit')", func_tooltip) |
| | self.assertIn("Utility", func_tooltip) |
| |
|
| | clause_tooltip = editor._get_tooltip_for_word("SELECT") |
| | self.assertIn("SQL Clause", clause_tooltip) |
| |
|