"""クラス定義のテスト(SPEC_01「クラス定義」・TEST_01「フォルダ構成とラベル対応」)."""
import pytest
from tias_judge_model.data.classes import (
ALL_DIR_NAMES,
CLASS_DISPLAY_NAMES,
CLASS_SLUGS,
NUM_CLASSES,
id_to_label,
is_valid_combination,
label_to_id,
make_dir_name,
parse_dir_name,
)
# SPEC_01 の固定表(ID・slug・表示名)
SPEC_CLASSES = [
(0, "pale", "淡白"),
(1, "light_red", "淡紅"),
(2, "red", "紅"),
(3, "dark_red", "暗赤紅"),
(4, "purple", "紫"),
]
# TEST_01 の対応表(ディレクトリ名は SPEC_01 の `<label>_<severity>` スラッグ)
SPEC_DIRS = {
"light_red_normal": ("light_red", "normal"),
"dark_red_strong": ("dark_red", "strong"),
"dark_red_mild": ("dark_red", "mild"),
"purple_mild": ("purple", "mild"),
"red_strong": ("red", "strong"),
"red_mild": ("red", "mild"),
"purple_strong": ("purple", "strong"),
"pale_strong": ("pale", "strong"),
"pale_mild": ("pale", "mild"),
}
def test_class_ids_follow_fixed_spec_order() -> None:
assert CLASS_SLUGS == tuple(slug for _, slug, _ in SPEC_CLASSES)
assert NUM_CLASSES == 5
@pytest.mark.parametrize(("class_id", "slug", "display"), SPEC_CLASSES)
def test_label_id_mapping_matches_spec(class_id: int, slug: str, display: str) -> None:
assert label_to_id(slug) == class_id
assert id_to_label(class_id) == slug
assert CLASS_DISPLAY_NAMES[slug] == display
@pytest.mark.parametrize("label", ["", "Pale", "orange", "淡白", "light-red"])
def test_label_to_id_rejects_unknown_label(label: str) -> None:
with pytest.raises(ValueError):
label_to_id(label)
@pytest.mark.parametrize("class_id", [-1, 5, 100])
def test_id_to_label_rejects_out_of_range(class_id: int) -> None:
with pytest.raises(ValueError):
id_to_label(class_id)
def test_all_dir_names_are_exactly_the_nine_spec_dirs() -> None:
assert len(ALL_DIR_NAMES) == 9
assert set(ALL_DIR_NAMES) == set(SPEC_DIRS)
@pytest.mark.parametrize(("name", "expected"), sorted(SPEC_DIRS.items()))
def test_parse_dir_name_follows_test01_table(name: str, expected: tuple[str, str]) -> None:
assert parse_dir_name(name) == expected
@pytest.mark.parametrize(("name", "expected"), sorted(SPEC_DIRS.items()))
def test_make_dir_name_is_inverse_of_parse(name: str, expected: tuple[str, str]) -> None:
assert make_dir_name(*expected) == name
@pytest.mark.parametrize(
"name",
[
"light_red_strong", # 淡紅は normal のみ
"light_red_mild",
"pale_normal", # normal は淡紅のみ
"dark_red_normal",
"red",
"light_red",
"",
"_",
"orange_strong",
"red_Strong",
"purple_mild_extra",
"淡紅(正常)", # 日本語のフォルダ名はスラッグ化してから置く
"暗赤紅_あり",
],
)
def test_parse_dir_name_rejects_invalid_name(name: str) -> None:
with pytest.raises(ValueError):
parse_dir_name(name)
@pytest.mark.parametrize(
("label", "severity"),
[("light_red", "strong"), ("pale", "normal"), ("orange", "mild"), ("red", "weak")],
)
def test_make_dir_name_rejects_invalid_combination(label: str, severity: str) -> None:
with pytest.raises(ValueError):
make_dir_name(label, severity)
def test_is_valid_combination_matches_test01_table() -> None:
valid = set(SPEC_DIRS.values())
for label in CLASS_SLUGS:
for severity in ("strong", "mild", "normal"):
assert is_valid_combination(label, severity) == ((label, severity) in valid)
assert not is_valid_combination("orange", "strong")
assert not is_valid_combination("red", "weak")