Some checks failed
Build and Push Docker Image / build-and-push (push) Has been cancelled
- Fixed dose calculation logic in `_calculate_daily_dose` to correctly parse timestamps with multiple colons. - Added comprehensive test cases for various dose formats and edge cases in `test_dose_calculation.py`. - Enhanced graph legend to display individual medicines with average dosages and track medicines without dose data. - Updated legend styling and positioning for better readability and organization. - Created new tests for enhanced legend functionality, including handling of medicines with and without data. - Improved mocking for matplotlib components in tests to prevent TypeErrors.
96 lines
3.0 KiB
Python
96 lines
3.0 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Simple test script to verify dose calculation functionality without GUI.
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
|
|
# Add the src directory to Python path
|
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "src"))
|
|
|
|
|
|
def calculate_daily_dose(dose_str: str) -> float:
|
|
"""Calculate total daily dose from dose string format."""
|
|
import pandas as pd
|
|
|
|
if not dose_str or pd.isna(dose_str) or str(dose_str).lower() == "nan":
|
|
return 0.0
|
|
|
|
total_dose = 0.0
|
|
# Handle different separators and clean the string
|
|
dose_str = str(dose_str).replace("•", "").strip()
|
|
|
|
# Split by | or by spaces if no | present
|
|
dose_entries = dose_str.split("|") if "|" in dose_str else [dose_str]
|
|
|
|
for entry in dose_entries:
|
|
entry = entry.strip()
|
|
if not entry:
|
|
continue
|
|
|
|
try:
|
|
# Extract dose part after the last colon (timestamp:dose format)
|
|
dose_part = entry.split(":")[-1] if ":" in entry else entry
|
|
|
|
# Extract numeric part from dose (e.g., "150mg" -> 150)
|
|
dose_value = ""
|
|
for char in dose_part:
|
|
if char.isdigit() or char == ".":
|
|
dose_value += char
|
|
elif dose_value: # Stop at first non-digit after finding digits
|
|
break
|
|
|
|
if dose_value:
|
|
total_dose += float(dose_value)
|
|
except (ValueError, IndexError):
|
|
continue
|
|
|
|
return total_dose
|
|
|
|
|
|
def test_dose_calculation():
|
|
"""Test the dose calculation method directly."""
|
|
|
|
# Test cases
|
|
test_cases = [
|
|
# (input, expected_output, description)
|
|
("2025-07-28 18:59:45:150mg", 150.0, "Single dose with timestamp"),
|
|
("2025-07-28 18:59:45:150mg|2025-07-28 19:34:19:75mg", 225.0, "Multiple doses"),
|
|
("• • • • 2025-07-30 07:50:00:300", 300.0, "Dose with bullet symbols"),
|
|
("2025-07-28 18:59:45:12.5mg|2025-07-28 19:34:19:7.5mg", 20.0, "Decimal doses"),
|
|
("100mg|50mg", 150.0, "Doses without timestamps"),
|
|
("• 2025-07-30 22:50:00:10|75mg", 85.0, "Mixed format"),
|
|
("", 0.0, "Empty string"),
|
|
("nan", 0.0, "NaN value"),
|
|
("2025-07-28 18:59:45:10|2025-07-28 19:34:19:5", 15.0, "No units"),
|
|
]
|
|
|
|
print("Testing dose calculation...")
|
|
all_passed = True
|
|
|
|
for input_str, expected, description in test_cases:
|
|
result = calculate_daily_dose(input_str)
|
|
passed = abs(result - expected) < 0.001 # Allow for floating point precision
|
|
|
|
status = "PASS" if passed else "FAIL"
|
|
print(f"{status}: {description}")
|
|
print(f" Input: '{input_str}'")
|
|
print(f" Expected: {expected}, Got: {result}")
|
|
print()
|
|
|
|
if not passed:
|
|
all_passed = False
|
|
|
|
if all_passed:
|
|
print("All dose calculation tests PASSED!")
|
|
else:
|
|
print("Some dose calculation tests FAILED!")
|
|
|
|
return all_passed
|
|
|
|
|
|
if __name__ == "__main__":
|
|
success = test_dose_calculation()
|
|
sys.exit(0 if success else 1)
|