feat: Add coverage, iniconfig, pluggy, pygments, pytest, pytest-cov, and pytest-mock as dependencies
- Added coverage version 7.10.1 with multiple wheel distributions. - Added iniconfig version 2.1.0 with its wheel distribution. - Added pluggy version 1.6.0 with its wheel distribution. - Added pygments version 2.19.2 with its wheel distribution. - Added pytest version 8.4.1 with its wheel distribution and dependencies. - Added pytest-cov version 6.2.1 with its wheel distribution and dependencies. - Added pytest-mock version 3.14.1 with its wheel distribution and dependencies. - Updated dev-dependencies to include coverage, pytest, pytest-cov, and pytest-mock. - Updated requires-dist to specify minimum versions for coverage, pytest, pytest-cov, and pytest-mock.
This commit is contained in:
307
tests/test_ui_manager.py
Normal file
307
tests/test_ui_manager.py
Normal file
@@ -0,0 +1,307 @@
|
||||
"""
|
||||
Tests for the UIManager class.
|
||||
"""
|
||||
import os
|
||||
import pytest
|
||||
import tkinter as tk
|
||||
from tkinter import ttk
|
||||
from unittest.mock import Mock, patch, MagicMock
|
||||
from datetime import datetime
|
||||
|
||||
import sys
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'src'))
|
||||
|
||||
from ui_manager import UIManager
|
||||
|
||||
|
||||
class TestUIManager:
|
||||
"""Test cases for the UIManager class."""
|
||||
|
||||
@pytest.fixture
|
||||
def root_window(self):
|
||||
"""Create a root window for testing."""
|
||||
root = tk.Tk()
|
||||
yield root
|
||||
root.destroy()
|
||||
|
||||
@pytest.fixture
|
||||
def ui_manager(self, root_window, mock_logger):
|
||||
"""Create a UIManager instance for testing."""
|
||||
return UIManager(root_window, mock_logger)
|
||||
|
||||
def test_init(self, root_window, mock_logger):
|
||||
"""Test UIManager initialization."""
|
||||
ui = UIManager(root_window, mock_logger)
|
||||
assert ui.root == root_window
|
||||
assert ui.logger == mock_logger
|
||||
|
||||
@patch('os.path.exists')
|
||||
@patch('PIL.Image.open')
|
||||
def test_setup_icon_success(self, mock_image_open, mock_exists, ui_manager):
|
||||
"""Test successful icon setup."""
|
||||
mock_exists.return_value = True
|
||||
mock_image = Mock()
|
||||
mock_image.resize.return_value = mock_image
|
||||
mock_image_open.return_value = mock_image
|
||||
|
||||
with patch('PIL.ImageTk.PhotoImage') as mock_photo:
|
||||
mock_photo_instance = Mock()
|
||||
mock_photo.return_value = mock_photo_instance
|
||||
|
||||
result = ui_manager.setup_icon("test_icon.png")
|
||||
|
||||
assert result is True
|
||||
mock_image_open.assert_called_once_with("test_icon.png")
|
||||
mock_image.resize.assert_called_once_with(size=(32, 32), resample=Mock())
|
||||
ui_manager.logger.info.assert_called_with("Trying to load icon from: test_icon.png")
|
||||
|
||||
@patch('os.path.exists')
|
||||
def test_setup_icon_file_not_found(self, mock_exists, ui_manager):
|
||||
"""Test icon setup when file is not found."""
|
||||
mock_exists.return_value = False
|
||||
|
||||
result = ui_manager.setup_icon("nonexistent_icon.png")
|
||||
|
||||
assert result is False
|
||||
ui_manager.logger.warning.assert_called_with("Icon file not found at nonexistent_icon.png")
|
||||
|
||||
@patch('os.path.exists')
|
||||
@patch('PIL.Image.open')
|
||||
def test_setup_icon_exception(self, mock_image_open, mock_exists, ui_manager):
|
||||
"""Test icon setup with exception."""
|
||||
mock_exists.return_value = True
|
||||
mock_image_open.side_effect = Exception("Test error")
|
||||
|
||||
result = ui_manager.setup_icon("test_icon.png")
|
||||
|
||||
assert result is False
|
||||
ui_manager.logger.error.assert_called_with("Error setting up icon: Test error")
|
||||
|
||||
@patch('sys._MEIPASS', '/test/bundle/path', create=True)
|
||||
@patch('os.path.exists')
|
||||
@patch('PIL.Image.open')
|
||||
def test_setup_icon_pyinstaller_bundle(self, mock_image_open, mock_exists, ui_manager):
|
||||
"""Test icon setup in PyInstaller bundle."""
|
||||
# Mock exists to return False for original path, True for bundle path
|
||||
def mock_exists_side_effect(path):
|
||||
if 'test_icon.png' in path and '/test/bundle/path' in path:
|
||||
return True
|
||||
return False
|
||||
|
||||
mock_exists.side_effect = mock_exists_side_effect
|
||||
mock_image = Mock()
|
||||
mock_image.resize.return_value = mock_image
|
||||
mock_image_open.return_value = mock_image
|
||||
|
||||
with patch('PIL.ImageTk.PhotoImage') as mock_photo:
|
||||
mock_photo_instance = Mock()
|
||||
mock_photo.return_value = mock_photo_instance
|
||||
|
||||
result = ui_manager.setup_icon("test_icon.png")
|
||||
|
||||
assert result is True
|
||||
ui_manager.logger.info.assert_called_with("Found icon in PyInstaller bundle: /test/bundle/path/test_icon.png")
|
||||
|
||||
def test_create_graph_frame(self, ui_manager, root_window):
|
||||
"""Test creation of graph frame."""
|
||||
main_frame = ttk.Frame(root_window)
|
||||
|
||||
graph_frame = ui_manager.create_graph_frame(main_frame)
|
||||
|
||||
assert isinstance(graph_frame, ttk.LabelFrame)
|
||||
assert graph_frame.winfo_parent() == str(main_frame)
|
||||
|
||||
def test_create_input_frame(self, ui_manager, root_window):
|
||||
"""Test creation of input frame."""
|
||||
main_frame = ttk.Frame(root_window)
|
||||
|
||||
input_ui = ui_manager.create_input_frame(main_frame)
|
||||
|
||||
assert isinstance(input_ui, dict)
|
||||
assert "frame" in input_ui
|
||||
assert "symptom_vars" in input_ui
|
||||
assert "medicine_vars" in input_ui
|
||||
assert "note_var" in input_ui
|
||||
assert "date_var" in input_ui
|
||||
|
||||
assert isinstance(input_ui["frame"], ttk.LabelFrame)
|
||||
assert isinstance(input_ui["symptom_vars"], dict)
|
||||
assert isinstance(input_ui["medicine_vars"], dict)
|
||||
assert isinstance(input_ui["note_var"], tk.StringVar)
|
||||
assert isinstance(input_ui["date_var"], tk.StringVar)
|
||||
|
||||
def test_create_input_frame_symptom_vars(self, ui_manager, root_window):
|
||||
"""Test that symptom variables are created correctly."""
|
||||
main_frame = ttk.Frame(root_window)
|
||||
|
||||
input_ui = ui_manager.create_input_frame(main_frame)
|
||||
symptom_vars = input_ui["symptom_vars"]
|
||||
|
||||
expected_symptoms = ["depression", "anxiety", "sleep", "appetite"]
|
||||
for symptom in expected_symptoms:
|
||||
assert symptom in symptom_vars
|
||||
assert isinstance(symptom_vars[symptom], tk.IntVar)
|
||||
|
||||
def test_create_input_frame_medicine_vars(self, ui_manager, root_window):
|
||||
"""Test that medicine variables are created correctly."""
|
||||
main_frame = ttk.Frame(root_window)
|
||||
|
||||
input_ui = ui_manager.create_input_frame(main_frame)
|
||||
medicine_vars = input_ui["medicine_vars"]
|
||||
|
||||
expected_medicines = ["bupropion", "hydroxyzine", "gabapentin", "propranolol"]
|
||||
for medicine in expected_medicines:
|
||||
assert medicine in medicine_vars
|
||||
assert isinstance(medicine_vars[medicine], list)
|
||||
assert len(medicine_vars[medicine]) == 2 # IntVar and Spinbox
|
||||
assert isinstance(medicine_vars[medicine][0], tk.IntVar)
|
||||
assert isinstance(medicine_vars[medicine][1], ttk.Spinbox)
|
||||
|
||||
@patch('ui_manager.datetime')
|
||||
def test_create_input_frame_default_date(self, mock_datetime, ui_manager, root_window):
|
||||
"""Test that default date is set to today."""
|
||||
mock_datetime.now.return_value.strftime.return_value = "2024-01-15"
|
||||
|
||||
main_frame = ttk.Frame(root_window)
|
||||
input_ui = ui_manager.create_input_frame(main_frame)
|
||||
|
||||
assert input_ui["date_var"].get() == "2024-01-15"
|
||||
|
||||
def test_create_table_frame(self, ui_manager, root_window):
|
||||
"""Test creation of table frame."""
|
||||
main_frame = ttk.Frame(root_window)
|
||||
|
||||
table_ui = ui_manager.create_table_frame(main_frame)
|
||||
|
||||
assert isinstance(table_ui, dict)
|
||||
assert "tree" in table_ui
|
||||
assert isinstance(table_ui["tree"], ttk.Treeview)
|
||||
|
||||
def test_create_table_frame_columns(self, ui_manager, root_window):
|
||||
"""Test that table columns are set up correctly."""
|
||||
main_frame = ttk.Frame(root_window)
|
||||
|
||||
table_ui = ui_manager.create_table_frame(main_frame)
|
||||
tree = table_ui["tree"]
|
||||
|
||||
expected_columns = [
|
||||
"date", "depression", "anxiety", "sleep", "appetite",
|
||||
"bupropion", "hydroxyzine", "gabapentin", "propranolol", "note"
|
||||
]
|
||||
|
||||
# Check that columns are configured
|
||||
assert tree["columns"] == tuple(expected_columns)
|
||||
|
||||
def test_add_buttons(self, ui_manager, root_window):
|
||||
"""Test adding buttons to a frame."""
|
||||
frame = ttk.Frame(root_window)
|
||||
|
||||
buttons_config = [
|
||||
{"text": "Test Button 1", "command": lambda: None},
|
||||
{"text": "Test Button 2", "command": lambda: None, "fill": "x"},
|
||||
]
|
||||
|
||||
ui_manager.add_buttons(frame, buttons_config)
|
||||
|
||||
# Check that buttons were added (basic structure test)
|
||||
children = frame.winfo_children()
|
||||
assert len(children) >= 2
|
||||
|
||||
def test_create_edit_window(self, ui_manager):
|
||||
"""Test creation of edit window."""
|
||||
values = ("2024-01-01", "3", "2", "4", "3", "1", "0", "2", "1", "Test note")
|
||||
callbacks = {
|
||||
"save": lambda win, *args: None,
|
||||
"delete": lambda win: None
|
||||
}
|
||||
|
||||
edit_window = ui_manager.create_edit_window(values, callbacks)
|
||||
|
||||
assert isinstance(edit_window, tk.Toplevel)
|
||||
assert edit_window.title() == "Edit Entry"
|
||||
|
||||
def test_create_edit_window_widgets(self, ui_manager):
|
||||
"""Test that edit window contains expected widgets."""
|
||||
values = ("2024-01-01", "3", "2", "4", "3", "1", "0", "2", "1", "Test note")
|
||||
callbacks = {
|
||||
"save": lambda win, *args: None,
|
||||
"delete": lambda win: None
|
||||
}
|
||||
|
||||
edit_window = ui_manager.create_edit_window(values, callbacks)
|
||||
|
||||
# Check that window has children (widgets)
|
||||
children = edit_window.winfo_children()
|
||||
assert len(children) > 0
|
||||
|
||||
def test_create_edit_window_initial_values(self, ui_manager):
|
||||
"""Test that edit window is populated with initial values."""
|
||||
values = ("2024-01-01", "3", "2", "4", "3", "1", "0", "2", "1", "Test note")
|
||||
callbacks = {
|
||||
"save": lambda win, *args: None,
|
||||
"delete": lambda win: None
|
||||
}
|
||||
|
||||
edit_window = ui_manager.create_edit_window(values, callbacks)
|
||||
|
||||
# The window should be created successfully
|
||||
assert edit_window is not None
|
||||
# More detailed testing would require examining the internal widgets
|
||||
|
||||
def test_create_scale_with_var(self, ui_manager, root_window):
|
||||
"""Test creation of scale widget with variable."""
|
||||
frame = ttk.Frame(root_window)
|
||||
var = tk.IntVar()
|
||||
|
||||
scale = ui_manager._create_scale_with_var(frame, var, "Test Label", 0, 0)
|
||||
|
||||
assert isinstance(scale, ttk.Scale)
|
||||
|
||||
def test_create_spinbox_with_var(self, ui_manager, root_window):
|
||||
"""Test creation of spinbox widget with variable."""
|
||||
frame = ttk.Frame(root_window)
|
||||
var = tk.IntVar()
|
||||
|
||||
result = ui_manager._create_spinbox_with_var(frame, var, "Test Label", 0, 0)
|
||||
|
||||
assert isinstance(result, list)
|
||||
assert len(result) == 2
|
||||
assert isinstance(result[0], tk.IntVar)
|
||||
assert isinstance(result[1], ttk.Spinbox)
|
||||
|
||||
def test_frame_positioning(self, ui_manager, root_window):
|
||||
"""Test that frames are positioned correctly."""
|
||||
main_frame = ttk.Frame(root_window)
|
||||
|
||||
# Create multiple frames
|
||||
graph_frame = ui_manager.create_graph_frame(main_frame)
|
||||
input_ui = ui_manager.create_input_frame(main_frame)
|
||||
table_ui = ui_manager.create_table_frame(main_frame)
|
||||
|
||||
# All frames should be created successfully
|
||||
assert graph_frame is not None
|
||||
assert input_ui["frame"] is not None
|
||||
assert table_ui["tree"] is not None
|
||||
|
||||
def test_widget_configuration(self, ui_manager, root_window):
|
||||
"""Test that widgets are configured with appropriate properties."""
|
||||
main_frame = ttk.Frame(root_window)
|
||||
input_ui = ui_manager.create_input_frame(main_frame)
|
||||
|
||||
# Check that variables have default values
|
||||
for var in input_ui["symptom_vars"].values():
|
||||
assert var.get() == 0
|
||||
|
||||
for medicine_data in input_ui["medicine_vars"].values():
|
||||
assert medicine_data[0].get() == 0
|
||||
|
||||
@patch('tkinter.messagebox.showerror')
|
||||
def test_error_handling_in_setup_icon(self, mock_showerror, ui_manager):
|
||||
"""Test error handling in setup_icon method."""
|
||||
with patch('PIL.Image.open') as mock_open:
|
||||
mock_open.side_effect = Exception("Image error")
|
||||
|
||||
result = ui_manager.setup_icon("test.png")
|
||||
|
||||
assert result is False
|
||||
ui_manager.logger.error.assert_called()
|
||||
Reference in New Issue
Block a user