fix: обновить тесты distance_service под канон B5 (3e2692f)
Тесты проверяли старые бэкендовские скорости (1.0–5.5 км/ч), тогда как B5 перенёс в живую копию services/distance_service.py каноничные displacement-скорости фронта (0.3–2.5 км/ч, априоры ПСО «Экстремум», 94% в 3 км) и сумерки 0.7. Обновлены ожидания (пересчитаны все кейсы): - TestBaseSpeed: 0.3/0.7/1.2/1.5/2.0/2.5/2.5/1.5 по возрастам - 5 кейсов calculate_max_distance пересчитаны (5.12→1.92 и т.д.) - test_twilight: 0.5 → 0.7 - test_statistics_values: base_speed 4.0 → 1.5 - test_fatigue_minimum: 27.0 → 13.5 - Добавлена контрольная точка B5: bike 8yo 2h лес = 5.4 км Коэффициенты в services/ НЕ тронуты (B1-safe) — только тесты. 201 passed, 0 failed.
This commit is contained in:
@@ -18,12 +18,18 @@ from services.distance_service import (
|
||||
|
||||
|
||||
class TestCalculateMaxDistance:
|
||||
"""Test the main distance calculation function."""
|
||||
"""Test the main distance calculation function.
|
||||
|
||||
Ожидания соответствуют каноничным displacement-скоростям B5 (3e2692f):
|
||||
get_base_speed 0.3–2.5 км/ч по априорам ПСО «Экстремум» (94% в 3 км).
|
||||
Контрольная точка B5: bike 8yo 2h лес = 5.4 км.
|
||||
"""
|
||||
|
||||
def test_boy_10_years_4_hours_forest_rain(self):
|
||||
"""
|
||||
Test case from requirements:
|
||||
Мальчик 10 лет, 4 часа, лес, дождь → ~5 км
|
||||
Мальчик 10 лет, 4 часа, лес, дождь.
|
||||
Пересчитано под канон B5: НормС(10)=1.5
|
||||
Distance = 4 * 1.5 * 0.5 * 0.8 * 1.0 * 0.8 = 1.92 km
|
||||
"""
|
||||
case_data = {
|
||||
'age': 10,
|
||||
@@ -35,17 +41,7 @@ class TestCalculateMaxDistance:
|
||||
|
||||
distance = calculate_max_distance(case_data)
|
||||
|
||||
# Expected calculation:
|
||||
# Time = 4 hours
|
||||
# НормС (age 10) = 4.0 km/h
|
||||
# СП (лес) = 0.5
|
||||
# СУТ (4 hours) = 1.0 - (0.05 * 4) = 0.8
|
||||
# ВВС (день) = 1.0
|
||||
# ВП (дождь) = 0.8
|
||||
# Distance = 4 * 4.0 * 0.5 * 0.8 * 1.0 * 0.8 = 5.12 km
|
||||
|
||||
assert 4.5 <= distance <= 5.5, f"Expected ~5 km, got {distance} km"
|
||||
assert distance == pytest.approx(5.12, rel=0.01)
|
||||
assert distance == pytest.approx(1.92, rel=0.01)
|
||||
|
||||
def test_young_child_short_time(self):
|
||||
"""Test for young child (3 years) with short elapsed time."""
|
||||
@@ -59,8 +55,8 @@ class TestCalculateMaxDistance:
|
||||
|
||||
distance = calculate_max_distance(case_data)
|
||||
|
||||
# Expected: 1 * 2.0 * 0.5 * 0.95 * 1.0 * 1.0 = 0.95 km
|
||||
assert distance == pytest.approx(0.95, rel=0.01)
|
||||
# 1 * 0.7 * 0.5 * 0.95 * 1.0 * 1.0 = 0.33 km
|
||||
assert distance == pytest.approx(0.33, rel=0.01)
|
||||
|
||||
def test_teenager_long_time_road(self):
|
||||
"""Test for teenager on road with longer elapsed time."""
|
||||
@@ -74,8 +70,8 @@ class TestCalculateMaxDistance:
|
||||
|
||||
distance = calculate_max_distance(case_data)
|
||||
|
||||
# Expected: 6 * 5.0 * 0.8 * 0.7 * 1.0 * 1.0 = 16.8 km
|
||||
assert distance == pytest.approx(16.8, rel=0.01)
|
||||
# 6 * 2.0 * 0.8 * 0.7 * 1.0 * 1.0 = 6.72 km
|
||||
assert distance == pytest.approx(6.72, rel=0.01)
|
||||
|
||||
def test_elderly_night_swamp(self):
|
||||
"""Test for elderly person at night in swamp."""
|
||||
@@ -89,8 +85,8 @@ class TestCalculateMaxDistance:
|
||||
|
||||
distance = calculate_max_distance(case_data)
|
||||
|
||||
# Expected: 3 * 3.0 * 0.2 * 0.85 * 0.5 * 0.7 = 0.54 km
|
||||
assert distance == pytest.approx(0.54, rel=0.01)
|
||||
# 3 * 1.5 * 0.2 * 0.85 * 0.5 * 0.7 = 0.27 km
|
||||
assert distance == pytest.approx(0.27, rel=0.01)
|
||||
|
||||
def test_adult_heavy_rain_field(self):
|
||||
"""Test for adult in heavy rain on field."""
|
||||
@@ -104,43 +100,59 @@ class TestCalculateMaxDistance:
|
||||
|
||||
distance = calculate_max_distance(case_data)
|
||||
|
||||
# Expected: 2 * 5.0 * 0.9 * 0.9 * 1.0 * 0.6 = 4.86 km
|
||||
assert distance == pytest.approx(4.86, rel=0.01)
|
||||
# 2 * 2.5 * 0.9 * 0.9 * 1.0 * 0.6 = 2.43 km
|
||||
assert distance == pytest.approx(2.43, rel=0.01)
|
||||
|
||||
def test_bike_8yo_canonical_b5(self):
|
||||
"""Контрольная точка B5: bike 8yo 2h лес = 5.4 км (СУ bike ×5)."""
|
||||
case_data = {
|
||||
'age': 8,
|
||||
'elapsed_hours': 2.0,
|
||||
'terrain_primary': 'лес',
|
||||
'time_of_day': 'день',
|
||||
'weather': 'нет',
|
||||
'has_transport': 'bike',
|
||||
'diagnosis_type': [],
|
||||
}
|
||||
|
||||
distance = calculate_max_distance(case_data)
|
||||
|
||||
assert distance == pytest.approx(5.4, rel=0.01)
|
||||
|
||||
|
||||
class TestBaseSpeed:
|
||||
"""Test НормС (base speed) by age."""
|
||||
"""Test НормС (base speed) by age — каноничные displacement-скорости B5."""
|
||||
|
||||
def test_infant(self):
|
||||
assert get_base_speed(1) == 1.0
|
||||
assert get_base_speed(2) == 1.0
|
||||
assert get_base_speed(1) == 0.3
|
||||
assert get_base_speed(2) == 0.3
|
||||
|
||||
def test_preschool(self):
|
||||
assert get_base_speed(3) == 2.0
|
||||
assert get_base_speed(5) == 2.0
|
||||
assert get_base_speed(3) == 0.7
|
||||
assert get_base_speed(5) == 0.7
|
||||
|
||||
def test_young_child(self):
|
||||
assert get_base_speed(6) == 3.0
|
||||
assert get_base_speed(8) == 3.0
|
||||
assert get_base_speed(6) == 1.2
|
||||
assert get_base_speed(8) == 1.2
|
||||
|
||||
def test_preteen(self):
|
||||
assert get_base_speed(10) == 4.0
|
||||
assert get_base_speed(12) == 4.0
|
||||
assert get_base_speed(10) == 1.5
|
||||
assert get_base_speed(12) == 1.5
|
||||
|
||||
def test_teenager(self):
|
||||
assert get_base_speed(13) == 5.0
|
||||
assert get_base_speed(15) == 5.0
|
||||
assert get_base_speed(16) == 5.5
|
||||
assert get_base_speed(17) == 5.5
|
||||
assert get_base_speed(13) == 2.0
|
||||
assert get_base_speed(15) == 2.0
|
||||
assert get_base_speed(16) == 2.5
|
||||
assert get_base_speed(17) == 2.5
|
||||
|
||||
def test_adult(self):
|
||||
assert get_base_speed(25) == 5.0
|
||||
assert get_base_speed(50) == 5.0
|
||||
assert get_base_speed(64) == 5.0
|
||||
assert get_base_speed(25) == 2.5
|
||||
assert get_base_speed(50) == 2.5
|
||||
assert get_base_speed(64) == 2.5
|
||||
|
||||
def test_elderly(self):
|
||||
assert get_base_speed(65) == 3.0
|
||||
assert get_base_speed(80) == 3.0
|
||||
assert get_base_speed(65) == 1.5
|
||||
assert get_base_speed(80) == 1.5
|
||||
|
||||
|
||||
class TestTerrainCoefficient:
|
||||
@@ -184,8 +196,9 @@ class TestTimeOfDayCoefficient:
|
||||
assert get_time_of_day_coefficient('ночь') == 0.5
|
||||
|
||||
def test_twilight(self):
|
||||
assert get_time_of_day_coefficient('сумерки') == 0.5
|
||||
assert get_time_of_day_coefficient('вечер') == 0.5
|
||||
# B5: сумерки/вечер = 0.7 (было 0.5 — канон фронта)
|
||||
assert get_time_of_day_coefficient('сумерки') == 0.7
|
||||
assert get_time_of_day_coefficient('вечер') == 0.7
|
||||
|
||||
|
||||
class TestWeatherCoefficient:
|
||||
@@ -294,7 +307,7 @@ class TestDistanceStatistics:
|
||||
terrain='лес'
|
||||
)
|
||||
|
||||
assert stats['base_speed_kmh'] == 4.0
|
||||
assert stats['base_speed_kmh'] == 1.5
|
||||
assert stats['terrain_coefficient'] == 0.5
|
||||
assert stats['max_distance_km'] > 0
|
||||
assert 0 <= stats['zone_probability'] <= 1.0
|
||||
@@ -337,5 +350,5 @@ class TestFatigueCoefficient:
|
||||
|
||||
distance = calculate_max_distance(case_data)
|
||||
|
||||
# 20 * 5.0 * 0.9 * 0.3 * 1.0 * 1.0 = 27.0
|
||||
assert distance == pytest.approx(27.0, rel=0.01)
|
||||
# 20 * 2.5 * 0.9 * 0.3 * 1.0 * 1.0 = 13.5
|
||||
assert distance == pytest.approx(13.5, rel=0.01)
|
||||
|
||||
Reference in New Issue
Block a user