Add ESC data and improve scoring system functionality

This commit is contained in:
2025-06-10 22:30:08 +02:00
parent a9ab9ff75a
commit 2fd9d7f548
7 changed files with 269 additions and 113 deletions

0
tests/__init__.py Normal file
View File

118
tests/esc_data.json Normal file
View File

@@ -0,0 +1,118 @@
{
"2025": {
"jury": {
"Austria": 258,
"Switzerland": 214,
"France": 180,
"Italy": 159,
"Netherlands": 133,
"Sweden": 126,
"Latvia": 116,
"Greece": 105,
"Estonia": 98,
"United Kingdom": 88,
"Finland": 88,
"Malta": 83,
"Germany": 77,
"Ukraine": 60,
"Israel": 60,
"Albania": 45,
"Denmark": 45,
"Armenia": 42,
"Portugal": 37,
"Lithuania": 34,
"Spain": 27,
"Luxembourg": 23,
"Norway": 22,
"Poland": 17,
"San Marino": 9,
"Iceland": 0
},
"televote": {
"Israel": 297,
"Estonia": 258,
"Sweden": 195,
"Austria": 178,
"Albania": 173,
"Ukraine": 158,
"Poland": 139,
"Greece": 126,
"Finland": 108,
"Italy": 97,
"Germany": 74,
"Norway": 67,
"Lithuania": 62,
"France": 50,
"Latvia": 42,
"Netherlands": 42,
"Iceland": 33,
"Armenia": 30,
"Luxembourg": 24,
"San Marino": 18,
"Portugal": 13,
"Spain": 10,
"Malta": 8,
"Denmark": 2,
"United Kingdom": 0,
"Switzerland": 0
},
"winner": "Austria"
},
"2024": {
"jury": {
"Switzerland": 365,
"France": 218,
"Croatia": 210,
"Italy": 164,
"Ukraine": 146,
"Ireland": 142,
"Portugal": 139,
"Sweden": 125,
"Armenia": 101,
"Germany": 99,
"Luxembourg": 83,
"Israel": 52,
"United Kingdom": 46,
"Greece": 41,
"Latvia": 36,
"Cyprus": 34,
"Lithuania": 32,
"Serbia": 22,
"Spain": 19,
"Austria": 19,
"Georgia": 15,
"Slovenia": 15,
"Norway": 12,
"Finland": 7,
"Estonia": 4
},
"televote": {
"Croatia": 337,
"Israel": 323,
"Ukraine": 307,
"France": 227,
"Switzerland": 226,
"Ireland": 136,
"Italy": 104,
"Greece": 85,
"Armenia": 82,
"Lithuania": 58,
"Sweden": 49,
"Cyprus": 44,
"Estonia": 33,
"Serbia": 32,
"Finland": 31,
"Latvia": 28,
"Luxembourg": 20,
"Georgia": 19,
"Germany": 18,
"Portugal": 13,
"Slovenia": 12,
"Spain": 11,
"Austria": 5,
"Norway": 4,
"United Kingdom": 0
},
"winner": "Switzerland"
}
}

61
tests/test_esc.py Normal file
View File

@@ -0,0 +1,61 @@
import os
import sys
import orjson
sys.path.append(os.path.join(os.path.dirname(__file__), "..")) # noqa: PTH120, PTH118
import tempfile
from pathlib import Path
from typing import TypedDict
import pytest
from typer.testing import CliRunner
from src.__main__ import app
data_path = Path(__file__).parent / "esc_data.json"
class ESCData(TypedDict):
"""TypedDict for ESC data."""
jury: dict[str, int]
televote: dict[str, int]
winner: str
with data_path.open("r", encoding="utf-8") as f:
data = orjson.loads(f.read())
ESC_DATA: dict[int, "ESCData"] = {int(year): value for year, value in data.items()}
TADA = "🎉"
@pytest.mark.parametrize(("year", "data"), ESC_DATA.items())
def test_esc_grand_final(year: int, data: ESCData) -> None:
"""Test the ESC grand final for a given year."""
jury_scores: dict[str, int] = data["jury"]
televote_scores: dict[str, int] = data["televote"]
expected_winner: str = data["winner"]
with tempfile.NamedTemporaryFile("w", delete=False, encoding="utf-8") as f:
for country, score in jury_scores.items():
f.write(f"{country} {score}\n")
inputs: list[str] = []
for country in reversed(list(jury_scores.keys())):
inputs.append(str(televote_scores[country])) # noqa: PERF401
inputs.append("y") # to confirm the winner
runner = CliRunner()
result = runner.invoke(app, ["--jury-path", f.name], input="\n".join(inputs))
try:
actual = result.output.split(TADA)[1].strip().split()[0]
except Exception:
pytest.fail(f"Could not parse winner from output:\n{result.output}", pytrace=False)
assert actual == expected_winner, f"For {year}, expected winner {expected_winner} but got {actual!r}"

View File

@@ -1,85 +0,0 @@
import os
import sys
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
import tempfile
from typer.testing import CliRunner
from src.__main__ import app
# 2025 Eurovision Grand Final jury scores
JURY_SCORES = {
"Austria": 258,
"Switzerland": 214,
"France": 180,
"Italy": 159,
"Netherlands": 133,
"Sweden": 126,
"Latvia": 116,
"Greece": 105,
"Estonia": 98,
"United Kingdom": 88,
"Finland": 88,
"Malta": 83,
"Germany": 77,
"Ukraine": 60,
"Israel": 60,
"Albania": 45,
"Denmark": 45,
"Armenia": 42,
"Portugal": 37,
"Lithuania": 34,
"Spain": 27,
"Luxembourg": 23,
"Norway": 22,
"Poland": 17,
"San Marino": 9,
"Iceland": 0,
}
# 2025 Eurovision Grand Final televoting scores
TELEVOTE_SCORES = {
"Israel": 297,
"Estonia": 258,
"Sweden": 195,
"Austria": 178,
"Albania": 173,
"Ukraine": 158,
"Poland": 139,
"Greece": 126,
"Finland": 108,
"Italy": 97,
"Germany": 74,
"Norway": 67,
"Lithuania": 62,
"France": 50,
"Latvia": 42,
"Netherlands": 42,
"Iceland": 33,
"Armenia": 30,
"Luxembourg": 24,
"San Marino": 18,
"Portugal": 13,
"Spain": 10,
"Malta": 8,
"Denmark": 2,
"United Kingdom": 0,
"Switzerland": 0,
}
RETURN = """
╭──────────────────────────── Winner Announcement ─────────────────────────────╮
│ This year's winner is: 🎉 Austria 🎉 │
╰────────────────────────────── Congratulations! ──────────────────────────────╯
"""
def test_esc_2025():
with tempfile.NamedTemporaryFile(delete=False, mode='w', encoding='utf-8') as jury_file:
jury_file.write("\n".join(f"{country} {score}" for country, score in JURY_SCORES.items()))
runner = CliRunner()
i: str = ""
for country in reversed(list(JURY_SCORES.keys())):
i += f"{TELEVOTE_SCORES[country]}\n"
i += "y\n"
result = runner.invoke(app, ["--jury-path", jury_file.name], input=i)
assert result.stdout.strip().endswith(RETURN), f"Expected output to end with {RETURN.strip()}, got {result.output.strip()}"