File size: 6,151 Bytes
fcf8749 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 | """
Unit tests for workload score calculations.
Tests route difficulty and workload score functions.
"""
import pytest
from app.services.workload import (
calculate_route_difficulty,
estimate_route_time,
calculate_workload,
RouteMetrics,
)
class TestRouteDifficulty:
"""Tests for route difficulty calculation."""
def test_difficulty_base(self):
"""Minimal route should have base difficulty."""
result = calculate_route_difficulty(
total_weight_kg=0.0,
num_stops=0,
avg_fragility=1.0,
)
# Base difficulty is 1.0
assert result >= 1.0
def test_difficulty_increases_with_weight(self):
"""Higher weight should increase difficulty."""
light = calculate_route_difficulty(10.0, 5, 1.0)
heavy = calculate_route_difficulty(50.0, 5, 1.0)
assert heavy > light
def test_difficulty_increases_with_stops(self):
"""More stops should increase difficulty."""
few_stops = calculate_route_difficulty(20.0, 3, 1.0)
many_stops = calculate_route_difficulty(20.0, 15, 1.0)
assert many_stops > few_stops
def test_difficulty_increases_with_fragility(self):
"""Higher fragility should increase difficulty."""
low_fragility = calculate_route_difficulty(20.0, 5, 1.0)
high_fragility = calculate_route_difficulty(20.0, 5, 5.0)
assert high_fragility > low_fragility
def test_difficulty_realistic_route(self):
"""Test realistic route parameters."""
result = calculate_route_difficulty(
total_weight_kg=45.0,
num_stops=12,
avg_fragility=2.5,
)
# Should be a moderate difficulty
assert 1.0 < result < 10.0
class TestEstimateRouteTime:
"""Tests for route time estimation."""
def test_time_base(self):
"""Empty route should have base time."""
result = estimate_route_time(0, 0)
assert result >= 30 # Base time is 30 minutes
def test_time_increases_with_packages(self):
"""More packages should increase time."""
few = estimate_route_time(5, 3)
many = estimate_route_time(25, 3)
assert many > few
def test_time_increases_with_stops(self):
"""More stops should increase time."""
few_stops = estimate_route_time(10, 3)
many_stops = estimate_route_time(10, 12)
assert many_stops > few_stops
def test_time_with_distance(self):
"""Distance should add to time."""
no_distance = estimate_route_time(10, 5, 0.0)
with_distance = estimate_route_time(10, 5, 30.0)
assert with_distance > no_distance
def test_time_realistic_route(self):
"""Test realistic route."""
result = estimate_route_time(
num_packages=20,
num_stops=10,
)
# Should take 2-3 hours
assert 90 < result < 180
class TestWorkloadScore:
"""Tests for workload score calculation."""
def test_workload_dict_input(self):
"""Test with dictionary input."""
route = {
"num_packages": 20,
"total_weight_kg": 40.0,
"route_difficulty_score": 2.0,
"estimated_time_minutes": 120,
}
result = calculate_workload(route)
assert result > 0
def test_workload_dataclass_input(self):
"""Test with RouteMetrics dataclass input."""
route = RouteMetrics(
num_packages=20,
total_weight_kg=40.0,
num_stops=10,
route_difficulty_score=2.0,
estimated_time_minutes=120,
)
result = calculate_workload(route)
assert result > 0
def test_workload_formula(self):
"""Verify workload formula calculation."""
route = {
"num_packages": 10,
"total_weight_kg": 20.0,
"route_difficulty_score": 1.0,
"estimated_time_minutes": 60,
}
# Default weights: a=1.0, b=0.5, c=10.0, d=0.2
# Expected: 1.0*10 + 0.5*20 + 10.0*1 + 0.2*60 = 10 + 10 + 10 + 12 = 42
result = calculate_workload(route)
assert abs(result - 42.0) < 0.1
def test_workload_custom_weights(self):
"""Test with custom weights."""
route = {
"num_packages": 10,
"total_weight_kg": 10.0,
"route_difficulty_score": 1.0,
"estimated_time_minutes": 60,
}
custom_weights = {"a": 2.0, "b": 1.0, "c": 5.0, "d": 0.5}
# Expected: 2.0*10 + 1.0*10 + 5.0*1 + 0.5*60 = 20 + 10 + 5 + 30 = 65
result = calculate_workload(route, custom_weights)
assert abs(result - 65.0) < 0.1
def test_workload_empty_route(self):
"""Empty route should have minimal workload."""
route = {
"num_packages": 0,
"total_weight_kg": 0.0,
"route_difficulty_score": 0.0,
"estimated_time_minutes": 0,
}
result = calculate_workload(route)
assert result == 0.0
def test_workload_heavy_route(self):
"""Heavy route should have high workload."""
route = {
"num_packages": 50,
"total_weight_kg": 100.0,
"route_difficulty_score": 4.0,
"estimated_time_minutes": 300,
}
result = calculate_workload(route)
# Should be significant
assert result > 100
def test_workload_comparison(self):
"""Harder routes should have higher workload."""
easy_route = {
"num_packages": 10,
"total_weight_kg": 15.0,
"route_difficulty_score": 1.0,
"estimated_time_minutes": 60,
}
hard_route = {
"num_packages": 30,
"total_weight_kg": 60.0,
"route_difficulty_score": 3.5,
"estimated_time_minutes": 180,
}
easy_workload = calculate_workload(easy_route)
hard_workload = calculate_workload(hard_route)
assert hard_workload > easy_workload
|