Gateprep / backend /tests /test_answer_utils.py
banu4prasad's picture
add: tests and code cleanup
05b4327
Raw
History Blame Contribute Delete
3.85 kB
import math
import pytest
from enum import Enum
from app.services.answer_utils import (
normalize_question_type,
parse_float,
parse_nat_range,
split_answer_tokens,
is_valid_nat_answer,
normalize_choice_answer,
)
class DummyEnum(Enum):
MCQ = "MCQ"
NAT = "QuestionType.NAT"
def test_normalize_question_type():
assert normalize_question_type(" MCQ ") == "mcq"
assert normalize_question_type("NAT") == "nat"
assert normalize_question_type("QuestionType.MSQ") == "msq"
assert normalize_question_type(DummyEnum.MCQ) == "mcq"
assert normalize_question_type(DummyEnum.NAT) == "nat"
assert normalize_question_type(None) == ""
assert normalize_question_type("") == ""
def test_parse_float():
assert parse_float("1.23") == 1.23
assert parse_float("-0.5") == -0.5
assert parse_float("1e-5") == 1e-5
assert parse_float(42) == 42.0
# Invalid strings
assert parse_float("abc") is None
assert parse_float("1.2.3") is None
assert parse_float("") is None
assert parse_float(None) is None
# Non-finite values
assert parse_float(float("inf")) is None
assert parse_float(float("-inf")) is None
assert parse_float(float("nan")) is None
def test_parse_nat_range():
assert parse_nat_range("1-2") == (1.0, 2.0)
assert parse_nat_range("1.5 : 2.5") == (1.5, 2.5)
assert parse_nat_range(" 10 to 20 ") == (10.0, 20.0)
assert parse_nat_range("-2--1") == (-2.0, -1.0)
assert parse_nat_range("-5 : -3.5") == (-5.0, -3.5)
# Invalid ranges (lo > hi)
assert parse_nat_range("2-1") is None
assert parse_nat_range("5 to 3") is None
# Invalid formats
assert parse_nat_range("1-2-3") is None
assert parse_nat_range("abc-def") is None
assert parse_nat_range("1") is None
assert parse_nat_range(None) is None
def test_split_answer_tokens():
assert split_answer_tokens("A, B, C") == ["A", "B", "C"]
assert split_answer_tokens("A ; B / C") == ["A", "B", "C"]
assert split_answer_tokens(" word1 , word2 ") == ["word1", "word2"]
assert split_answer_tokens("A") == ["A"]
assert split_answer_tokens("") == []
assert split_answer_tokens(" ") == []
assert split_answer_tokens(None) == []
assert split_answer_tokens(",;/") == []
def test_is_valid_nat_answer():
assert is_valid_nat_answer("1.5") is True
assert is_valid_nat_answer("1.5:2.5") is True
assert is_valid_nat_answer("-10 to -5") is True
assert is_valid_nat_answer("1.5, 2.5:3.5, 4") is True
assert is_valid_nat_answer("abc") is False
assert is_valid_nat_answer("1.5, abc") is False
assert is_valid_nat_answer("") is False
assert is_valid_nat_answer(None) is False
assert is_valid_nat_answer("2-1") is False # Invalid range (lo > hi)
assert is_valid_nat_answer("1.5-2.5-3.5") is False
def test_normalize_choice_answer():
assert normalize_choice_answer("a, b, c") == "A,B,C"
assert normalize_choice_answer(" a ; B / c ") == "A,B,C"
assert normalize_choice_answer("option1") == "OPTION1"
assert normalize_choice_answer(" ") == ""
assert normalize_choice_answer(None) == ""
from app.models.models import Question
from app.services.scoring import evaluate_answer
def test_nat_colon_range_scores_boundary_values():
question = Question(
question_type="nat",
question_text="Probability",
options=[],
correct_answer="0.44:0.45",
marks=2.0,
negative_marks=0.0,
)
for selected in ("0.44", "0.445", "0.45"):
assert evaluate_answer(question, selected) == (True, 2.0)
assert evaluate_answer(question, "0.46") == (False, 0.0)
def test_nat_hyphen_negative_range_still_works():
assert parse_nat_range("-2--1") == (-2.0, -1.0)
assert is_valid_nat_answer("-2--1") is True