Skip to content

Commit ca1cfa4

Browse files
committed
FEATURE: add frontend_tkinter_directory_selection tests
1 parent b5750ac commit ca1cfa4

File tree

1 file changed

+222
-0
lines changed

1 file changed

+222
-0
lines changed
Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
#!/usr/bin/env python3
2+
3+
"""
4+
Tests for the frontend_tkinter_directory_selection.py file.
5+
6+
This file is part of Ardupilot methodic configurator. https://github.com/ArduPilot/MethodicConfigurator
7+
8+
SPDX-FileCopyrightText: 2024-2025 Amilcar do Carmo Lucas <[email protected]>
9+
10+
SPDX-License-Identifier: GPL-3.0-or-later
11+
"""
12+
13+
import tkinter as tk
14+
import unittest
15+
from tkinter import ttk
16+
from unittest.mock import MagicMock, patch
17+
18+
from ardupilot_methodic_configurator.frontend_tkinter_base import BaseWindow
19+
from ardupilot_methodic_configurator.frontend_tkinter_directory_selection import (
20+
DirectoryNameWidgets,
21+
DirectorySelectionWidgets,
22+
VehicleDirectorySelectionWidgets,
23+
)
24+
25+
26+
class TestDirectorySelectionWidgets(unittest.TestCase):
27+
"""Test cases for the DirectorySelectionWidgets class."""
28+
29+
def setUp(self) -> None:
30+
self.root = tk.Tk()
31+
self.root.withdraw() # Hide the main window during tests
32+
self.parent = BaseWindow(self.root)
33+
self.parent_frame = ttk.Frame(self.root)
34+
self.initialdir = "/test/dir"
35+
self.widget = DirectorySelectionWidgets(
36+
parent=self.parent,
37+
parent_frame=self.parent_frame,
38+
initialdir=self.initialdir,
39+
label_text="Test Directory",
40+
autoresize_width=True,
41+
dir_tooltip="Directory tooltip",
42+
button_tooltip="Button tooltip",
43+
is_template_selection=False,
44+
)
45+
46+
def tearDown(self) -> None:
47+
self.root.destroy()
48+
49+
def test_initialization(self) -> None:
50+
"""Test that widgets are properly initialized."""
51+
assert self.widget.directory == self.initialdir
52+
assert isinstance(self.widget.container_frame, ttk.Frame)
53+
assert isinstance(self.widget.directory_entry, tk.Entry)
54+
assert self.widget.directory_entry.cget("state") == "readonly"
55+
56+
def test_directory_selection_with_button(self) -> None:
57+
"""Test directory selection with button."""
58+
with patch("tkinter.filedialog.askdirectory", return_value="/new/dir") as mock_dialog:
59+
result = self.widget.on_select_directory()
60+
mock_dialog.assert_called_once()
61+
assert result
62+
assert self.widget.directory == "/new/dir"
63+
assert self.widget.directory_entry.get() == "/new/dir"
64+
65+
def test_directory_selection_cancelled(self) -> None:
66+
"""Test when directory selection is cancelled."""
67+
with patch("tkinter.filedialog.askdirectory", return_value="") as mock_dialog:
68+
result = self.widget.on_select_directory()
69+
mock_dialog.assert_called_once()
70+
assert not result
71+
assert self.widget.directory == self.initialdir
72+
73+
def test_without_button(self) -> None:
74+
"""Test widget creation without button."""
75+
widget = DirectorySelectionWidgets(
76+
parent=self.parent,
77+
parent_frame=self.parent_frame,
78+
initialdir=self.initialdir,
79+
label_text="Test Directory",
80+
autoresize_width=True,
81+
dir_tooltip="Directory tooltip",
82+
button_tooltip="", # Empty tooltip means no button
83+
is_template_selection=False,
84+
)
85+
# No button should be present in the widget's children
86+
buttons = [child for child in widget.container_frame.winfo_children() if isinstance(child, ttk.Button)]
87+
assert len(buttons) == 0
88+
89+
def test_get_selected_directory(self) -> None:
90+
"""Test getting the selected directory."""
91+
assert self.widget.get_selected_directory() == self.initialdir
92+
self.widget.directory = "/another/dir"
93+
assert self.widget.get_selected_directory() == "/another/dir"
94+
95+
96+
class TestDirectoryNameWidgets(unittest.TestCase):
97+
"""Test cases for the DirectoryNameWidgets class."""
98+
99+
def setUp(self) -> None:
100+
self.root = tk.Tk()
101+
self.root.withdraw() # Hide the main window during tests
102+
self.master = ttk.Labelframe(self.root)
103+
self.initial_dir = "test_dir"
104+
self.label_text = "Test Label"
105+
self.dir_tooltip = "Test Tooltip"
106+
self.widget = DirectoryNameWidgets(
107+
master=self.master,
108+
initial_dir=self.initial_dir,
109+
label_text=self.label_text,
110+
dir_tooltip=self.dir_tooltip,
111+
)
112+
113+
def tearDown(self) -> None:
114+
self.root.destroy()
115+
116+
def test_initialization(self) -> None:
117+
"""Test that widgets are properly initialized."""
118+
# Check if the container frame was created
119+
assert isinstance(self.widget.container_frame, ttk.Frame)
120+
121+
# Check if the frame contains the expected widgets
122+
children = self.widget.container_frame.winfo_children()
123+
assert len(children) == 2 # Should have a label and an entry
124+
assert isinstance(children[0], ttk.Label) # First child should be a label
125+
assert isinstance(children[1], ttk.Entry) # Second child should be an entry
126+
127+
# Check if the label has the correct text
128+
assert children[0].cget("text") == self.label_text
129+
130+
# Check if the entry has the correct initial value
131+
assert self.widget.dir_var.get() == self.initial_dir
132+
133+
def test_get_selected_directory(self) -> None:
134+
"""Test getting the selected directory name."""
135+
# Test initial value
136+
assert self.widget.get_selected_directory() == self.initial_dir
137+
138+
# Test after changing the value
139+
new_dir = "new_test_dir"
140+
self.widget.dir_var.set(new_dir)
141+
assert self.widget.get_selected_directory() == new_dir
142+
143+
def test_entry_width(self) -> None:
144+
"""Test that the entry width is set correctly based on initial directory length."""
145+
entry = self.widget.container_frame.winfo_children()[1]
146+
assert isinstance(entry, ttk.Entry)
147+
expected_width = max(4, len(self.initial_dir))
148+
assert int(entry.cget("width")) == expected_width
149+
150+
151+
class TestVehicleDirectorySelectionWidgets(unittest.TestCase):
152+
"""Test cases for the VehicleDirectorySelectionWidgets class."""
153+
154+
def setUp(self) -> None:
155+
self.root = tk.Tk()
156+
self.root.withdraw()
157+
self.parent = BaseWindow(self.root)
158+
self.parent_frame = ttk.Frame(self.root)
159+
self.local_filesystem = MagicMock()
160+
self.initial_dir = "/test/vehicle/dir"
161+
self.widget = VehicleDirectorySelectionWidgets(
162+
parent=self.parent,
163+
parent_frame=self.parent_frame,
164+
local_filesystem=self.local_filesystem,
165+
initial_dir=self.initial_dir,
166+
destroy_parent_on_open=True,
167+
)
168+
169+
def tearDown(self) -> None:
170+
self.root.destroy()
171+
172+
def test_initialization(self) -> None:
173+
"""Test that widgets are properly initialized."""
174+
assert isinstance(self.widget.container_frame, ttk.Frame)
175+
assert isinstance(self.widget.directory_entry, tk.Entry)
176+
assert self.widget.directory == self.initial_dir
177+
assert self.widget.directory_entry.cget("state") == "readonly"
178+
179+
@patch("tkinter.filedialog.askdirectory")
180+
@patch("tkinter.messagebox.showerror")
181+
def test_directory_selection_template_not_allowed(self, mock_error, mock_askdir) -> None:
182+
"""Test selecting a directory in templates when not allowed."""
183+
mock_askdir.return_value = "/vehicle_templates/some_dir"
184+
self.local_filesystem.allow_editing_template_files = False
185+
result = self.widget.on_select_directory()
186+
assert not result
187+
mock_error.assert_called_once()
188+
189+
@patch("tkinter.filedialog.askdirectory")
190+
@patch("tkinter.messagebox.showerror")
191+
def test_directory_selection_invalid_vehicle_dir(self, mock_error, mock_askdir) -> None:
192+
"""Test selecting an invalid vehicle directory."""
193+
mock_askdir.return_value = "/some/dir"
194+
self.local_filesystem.vehicle_configuration_files_exist.return_value = False
195+
result = self.widget.on_select_directory()
196+
assert not result
197+
mock_error.assert_called_once()
198+
199+
@patch("tkinter.filedialog.askdirectory")
200+
def test_directory_selection_success(self, mock_askdir) -> None:
201+
"""Test successful directory selection."""
202+
mock_askdir.return_value = "/valid/vehicle/dir"
203+
self.local_filesystem.vehicle_configuration_files_exist.return_value = True
204+
self.local_filesystem.file_parameters = {"file1.param": {}}
205+
206+
result = self.widget.on_select_directory()
207+
208+
assert result
209+
assert self.widget.directory == "/valid/vehicle/dir"
210+
self.local_filesystem.re_init.assert_called_once_with("/valid/vehicle/dir", self.local_filesystem.vehicle_type)
211+
212+
@patch("tkinter.filedialog.askdirectory")
213+
def test_directory_selection_cancelled(self, mock_askdir) -> None:
214+
"""Test cancelling directory selection."""
215+
mock_askdir.return_value = ""
216+
result = self.widget.on_select_directory()
217+
assert not result
218+
assert self.widget.directory == self.initial_dir
219+
220+
221+
if __name__ == "__main__":
222+
unittest.main()

0 commit comments

Comments
 (0)