lct-hack/backend/tests/test_timing_score.py

82 lines
3.9 KiB
Python
Raw Normal View History

import pytest
from app.domain.events import Metric
from app.domain.taxonomy import Competency, ErrorCode, FindingSource
from app.scoring.competency import radar
from app.scoring.gost import GostResult
from app.scoring.timing import CARD_FILL_TIME, DDS_WORK_TIME, time_credit, time_metric
@pytest.mark.parametrize(
("elapsed_ms", "expected"),
[(0, 1.0), (90_000, 0.75), (180_000, 0.5), (360_000, 0.0), (400_000, 0.0),
(None, 0.0)],
)
def test_time_credit_reduces_linearly_against_the_norm(elapsed_ms, expected):
assert time_credit(elapsed_ms, 180_000) == expected
def test_fractional_timing_credit_affects_total_and_competency_scores():
metric = Metric(
key="card_fill_time", title="Время заполнения карточки", fact="90 с",
norm="180 с", passed=True, weight=2.0, credit=0.75,
)
result = GostResult(metrics=[metric])
assert result.score == 75.0
assert radar([metric])[0].value == 0.75
@pytest.mark.parametrize(
("elapsed_ms", "completed", "fact", "passed"),
[
(200_000, True, "200 с (+20 с сверх норматива)", False),
(61_000, True, "61 с (на 119 с быстрее норматива)", True),
(180_000, True, "180 с (точно в норматив)", True),
(None, True, "время не зафиксировано", False),
(30_000, False, "карточка не сдана; 30 с (на 150 с быстрее норматива)", False),
],
)
def test_card_fill_time_metric_texts(elapsed_ms, completed, fact, passed):
metric, finding = time_metric(CARD_FILL_TIME, elapsed_ms, 180_000, completed=completed)
assert metric.key == "card_fill_time"
assert metric.title == "Время заполнения карточки"
assert metric.fact == fact
assert metric.norm == "сдать карточку за 180 с"
assert metric.ref == "ТЗ задачи № 9; сессия вопросов и ответов 16.09.2026"
assert metric.passed is passed
assert metric.credit == (time_credit(elapsed_ms, 180_000) if completed else 0.0)
if passed:
assert finding is None
else:
assert finding.code is ErrorCode.E3
assert finding.source is FindingSource.TIMERS
assert finding.competency is Competency.NORMS
assert finding.summary == "Время заполнения карточки: норматив не выполнен"
assert (finding.fact, finding.norm) == (fact, "сдать карточку за 180 с")
@pytest.mark.parametrize(
("elapsed_ms", "completed", "fact", "passed"),
[
(605_000, True, "605 с (+425 с сверх норматива)", False),
(25_000, True, "25 с (на 155 с быстрее норматива)", True),
(180_000, True, "180 с (точно в норматив)", True),
(None, False, "первая запись не добавлена; карточка не открыта", False),
(25_000, False, "первая запись не добавлена; 25 с (на 155 с быстрее норматива)", False),
],
)
def test_dds_work_time_metric_texts(elapsed_ms, completed, fact, passed):
metric, finding = time_metric(DDS_WORK_TIME, elapsed_ms, 180_000, completed=completed)
assert metric.key == "dds_work_time"
assert metric.title == "Первая запись по карточке ДДС"
assert metric.fact == fact
assert metric.norm == "открыть карточку и добавить первую запись (статус и текст) за 180 с"
assert metric.passed is passed
assert (finding is None) is passed
if finding is not None:
assert finding.summary == "ДДС: первая запись по карточке позже норматива"
assert (finding.fact, finding.norm) == (
fact, "открыть карточку и добавить первую запись (статус и текст) за 180 с"
)