remove time graph visualiser. More tests. Other fixes
This commit is contained in:
parent
0b3249c7ef
commit
985541a1d8
18 changed files with 4087 additions and 971 deletions
|
|
@ -1,10 +1,14 @@
|
|||
import datetime as _dt
|
||||
|
||||
from PySide6.QtWidgets import QLabel
|
||||
|
||||
from bouquin.statistics_dialog import StatisticsDialog
|
||||
from bouquin import strings
|
||||
|
||||
from datetime import date
|
||||
from PySide6.QtCore import Qt, QPoint
|
||||
from PySide6.QtWidgets import QLabel
|
||||
from PySide6.QtTest import QTest
|
||||
|
||||
from bouquin.statistics_dialog import DateHeatmap, StatisticsDialog
|
||||
|
||||
|
||||
class FakeStatsDB:
|
||||
"""Minimal stub that returns a fixed stats payload."""
|
||||
|
|
@ -104,3 +108,312 @@ def test_statistics_dialog_no_data_shows_placeholder(qtbot):
|
|||
# When there's no data, the heatmap and metric combo shouldn't exist
|
||||
assert not hasattr(dlg, "metric_combo")
|
||||
assert not hasattr(dlg, "_heatmap")
|
||||
|
||||
|
||||
def _date(year, month, day):
|
||||
return date(year, month, day)
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# DateHeatmapTests - Missing Coverage
|
||||
# ============================================================================
|
||||
|
||||
|
||||
def test_activity_heatmap_empty_data(qtbot):
|
||||
"""Test heatmap with empty data dict."""
|
||||
strings.load_strings("en")
|
||||
heatmap = DateHeatmap()
|
||||
qtbot.addWidget(heatmap)
|
||||
heatmap.show()
|
||||
|
||||
# Set empty data
|
||||
heatmap.set_data({})
|
||||
|
||||
# Should handle empty data gracefully
|
||||
assert heatmap._start is None
|
||||
assert heatmap._end is None
|
||||
assert heatmap._max_value == 0
|
||||
|
||||
# Size hint should return default dimensions
|
||||
size = heatmap.sizeHint()
|
||||
assert size.width() > 0
|
||||
assert size.height() > 0
|
||||
|
||||
# Paint should not crash
|
||||
heatmap.update()
|
||||
qtbot.wait(10)
|
||||
|
||||
|
||||
def test_activity_heatmap_none_data(qtbot):
|
||||
"""Test heatmap with None data."""
|
||||
strings.load_strings("en")
|
||||
heatmap = DateHeatmap()
|
||||
qtbot.addWidget(heatmap)
|
||||
heatmap.show()
|
||||
|
||||
# Set None data
|
||||
heatmap.set_data(None)
|
||||
|
||||
assert heatmap._start is None
|
||||
assert heatmap._end is None
|
||||
|
||||
# Paint event should return early
|
||||
heatmap.update()
|
||||
qtbot.wait(10)
|
||||
|
||||
|
||||
def test_activity_heatmap_click_when_no_data(qtbot):
|
||||
"""Test clicking heatmap when there's no data."""
|
||||
heatmap = DateHeatmap()
|
||||
qtbot.addWidget(heatmap)
|
||||
heatmap.show()
|
||||
|
||||
heatmap.set_data({})
|
||||
|
||||
# Simulate click - should not crash or emit signal
|
||||
clicked_dates = []
|
||||
heatmap.date_clicked.connect(clicked_dates.append)
|
||||
|
||||
# Click in the middle of widget
|
||||
pos = QPoint(100, 100)
|
||||
QTest.mouseClick(heatmap, Qt.LeftButton, pos=pos)
|
||||
|
||||
# Should not have clicked any date
|
||||
assert len(clicked_dates) == 0
|
||||
|
||||
|
||||
def test_activity_heatmap_click_outside_grid(qtbot):
|
||||
"""Test clicking outside the grid area."""
|
||||
heatmap = DateHeatmap()
|
||||
qtbot.addWidget(heatmap)
|
||||
heatmap.show()
|
||||
|
||||
# Set some data
|
||||
data = {
|
||||
date(2024, 1, 1): 5,
|
||||
date(2024, 1, 2): 10,
|
||||
}
|
||||
heatmap.set_data(data)
|
||||
|
||||
clicked_dates = []
|
||||
heatmap.date_clicked.connect(clicked_dates.append)
|
||||
|
||||
# Click in top-left margin (before grid starts)
|
||||
pos = QPoint(5, 5)
|
||||
QTest.mouseClick(heatmap, Qt.LeftButton, pos=pos)
|
||||
|
||||
assert len(clicked_dates) == 0
|
||||
|
||||
|
||||
def test_activity_heatmap_click_beyond_end_date(qtbot):
|
||||
"""Test clicking on trailing empty cells beyond the last date."""
|
||||
heatmap = DateHeatmap()
|
||||
qtbot.addWidget(heatmap)
|
||||
heatmap.show()
|
||||
|
||||
# Set data that doesn't fill a complete week
|
||||
data = {
|
||||
date(2024, 1, 1): 5, # Monday
|
||||
date(2024, 1, 2): 10, # Tuesday
|
||||
}
|
||||
heatmap.set_data(data)
|
||||
|
||||
clicked_dates = []
|
||||
heatmap.date_clicked.connect(clicked_dates.append)
|
||||
|
||||
# Try clicking far to the right (beyond end date)
|
||||
# This is tricky to target precisely, but we can simulate
|
||||
pos = QPoint(1000, 50) # Far right
|
||||
QTest.mouseClick(heatmap, Qt.LeftButton, pos=pos)
|
||||
|
||||
# Should either not click or only click valid dates
|
||||
# If it did click, it should be a valid date within range
|
||||
if clicked_dates:
|
||||
assert clicked_dates[0] <= date(2024, 1, 2)
|
||||
|
||||
|
||||
def test_activity_heatmap_click_invalid_row(qtbot):
|
||||
"""Test clicking below the 7 weekday rows."""
|
||||
heatmap = DateHeatmap()
|
||||
qtbot.addWidget(heatmap)
|
||||
heatmap.show()
|
||||
|
||||
data = {
|
||||
date(2024, 1, 1): 5,
|
||||
date(2024, 1, 8): 10,
|
||||
}
|
||||
heatmap.set_data(data)
|
||||
|
||||
clicked_dates = []
|
||||
heatmap.date_clicked.connect(clicked_dates.append)
|
||||
|
||||
# Click below the grid (row 8 or higher)
|
||||
pos = QPoint(100, 500) # Very low Y
|
||||
QTest.mouseClick(heatmap, Qt.LeftButton, pos=pos)
|
||||
|
||||
assert len(clicked_dates) == 0
|
||||
|
||||
|
||||
def test_activity_heatmap_right_click_ignored(qtbot):
|
||||
"""Test that right-click is ignored."""
|
||||
heatmap = DateHeatmap()
|
||||
qtbot.addWidget(heatmap)
|
||||
heatmap.show()
|
||||
|
||||
data = {date(2024, 1, 1): 5}
|
||||
heatmap.set_data(data)
|
||||
|
||||
clicked_dates = []
|
||||
heatmap.date_clicked.connect(clicked_dates.append)
|
||||
|
||||
# Right click should be ignored
|
||||
pos = QPoint(100, 100)
|
||||
QTest.mouseClick(heatmap, Qt.RightButton, pos=pos)
|
||||
|
||||
assert len(clicked_dates) == 0
|
||||
|
||||
|
||||
def test_activity_heatmap_month_label_rendering(qtbot):
|
||||
"""Test heatmap spanning multiple months renders month labels."""
|
||||
heatmap = DateHeatmap()
|
||||
qtbot.addWidget(heatmap)
|
||||
heatmap.show()
|
||||
|
||||
# Data spanning multiple months
|
||||
data = {
|
||||
date(2024, 1, 1): 5,
|
||||
date(2024, 1, 15): 10,
|
||||
date(2024, 2, 1): 8,
|
||||
date(2024, 2, 15): 12,
|
||||
date(2024, 3, 1): 6,
|
||||
}
|
||||
heatmap.set_data(data)
|
||||
|
||||
# Should calculate proper size
|
||||
size = heatmap.sizeHint()
|
||||
assert size.width() > 0
|
||||
assert size.height() > 0
|
||||
|
||||
# Paint should work without crashing
|
||||
heatmap.update()
|
||||
qtbot.wait(10)
|
||||
|
||||
|
||||
def test_activity_heatmap_same_month_continues(qtbot):
|
||||
"""Test that month labels skip weeks in the same month."""
|
||||
heatmap = DateHeatmap()
|
||||
qtbot.addWidget(heatmap)
|
||||
heatmap.show()
|
||||
|
||||
# Multiple dates in same month
|
||||
data = {}
|
||||
for day in range(1, 29): # January 1-28
|
||||
data[date(2024, 1, day)] = day
|
||||
|
||||
heatmap.set_data(data)
|
||||
|
||||
# Should render without issues
|
||||
heatmap.update()
|
||||
qtbot.wait(10)
|
||||
|
||||
|
||||
def test_activity_heatmap_data_with_zero_values(qtbot):
|
||||
"""Test heatmap with zero values in data."""
|
||||
heatmap = DateHeatmap()
|
||||
qtbot.addWidget(heatmap)
|
||||
heatmap.show()
|
||||
|
||||
data = {
|
||||
date(2024, 1, 1): 0,
|
||||
date(2024, 1, 2): 5,
|
||||
date(2024, 1, 3): 0,
|
||||
}
|
||||
heatmap.set_data(data)
|
||||
|
||||
assert heatmap._max_value == 5
|
||||
|
||||
heatmap.update()
|
||||
qtbot.wait(10)
|
||||
|
||||
|
||||
def test_activity_heatmap_single_day(qtbot):
|
||||
"""Test heatmap with just one day of data."""
|
||||
heatmap = DateHeatmap()
|
||||
qtbot.addWidget(heatmap)
|
||||
heatmap.show()
|
||||
|
||||
data = {date(2024, 1, 15): 10}
|
||||
heatmap.set_data(data)
|
||||
|
||||
# Should handle single day
|
||||
assert heatmap._start is not None
|
||||
assert heatmap._end is not None
|
||||
|
||||
clicked_dates = []
|
||||
heatmap.date_clicked.connect(clicked_dates.append)
|
||||
|
||||
# Click should work
|
||||
pos = QPoint(100, 100)
|
||||
QTest.mouseClick(heatmap, Qt.LeftButton, pos=pos)
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# StatisticsDialog Tests
|
||||
# ============================================================================
|
||||
|
||||
|
||||
def test_statistics_dialog_with_empty_database(qtbot, fresh_db):
|
||||
"""Test statistics dialog with an empty database."""
|
||||
strings.load_strings("en")
|
||||
|
||||
dialog = StatisticsDialog(fresh_db)
|
||||
qtbot.addWidget(dialog)
|
||||
dialog.show()
|
||||
|
||||
# Should handle empty database gracefully
|
||||
assert dialog.isVisible()
|
||||
|
||||
# Heatmap should be empty
|
||||
heatmap = dialog.findChild(DateHeatmap)
|
||||
if heatmap:
|
||||
# No crash when displaying empty heatmap
|
||||
qtbot.wait(10)
|
||||
|
||||
|
||||
def test_statistics_dialog_with_data(qtbot, fresh_db):
|
||||
"""Test statistics dialog with actual data."""
|
||||
strings.load_strings("en")
|
||||
|
||||
# Add some content
|
||||
fresh_db.save_new_version("2024-01-01", "Hello world", "test")
|
||||
fresh_db.save_new_version("2024-01-02", "More content here", "test")
|
||||
fresh_db.save_new_version("2024-01-03", "Even more text", "test")
|
||||
|
||||
dialog = StatisticsDialog(fresh_db)
|
||||
qtbot.addWidget(dialog)
|
||||
dialog.show()
|
||||
|
||||
# Should display statistics
|
||||
assert dialog.isVisible()
|
||||
qtbot.wait(10)
|
||||
|
||||
|
||||
def test_statistics_dialog_gather_stats_exception_handling(
|
||||
qtbot, fresh_db, monkeypatch
|
||||
):
|
||||
"""Test that gather_stats handles exceptions gracefully."""
|
||||
strings.load_strings("en")
|
||||
|
||||
# Make dates_with_content raise an exception
|
||||
def bad_dates_with_content():
|
||||
raise RuntimeError("Simulated DB error")
|
||||
|
||||
monkeypatch.setattr(fresh_db, "dates_with_content", bad_dates_with_content)
|
||||
|
||||
# Should still create dialog without crashing
|
||||
dialog = StatisticsDialog(fresh_db)
|
||||
qtbot.addWidget(dialog)
|
||||
dialog.show()
|
||||
|
||||
# Should handle error gracefully
|
||||
assert dialog.isVisible()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue