college-bot-v1/tests/test_timetable.py

100 lines
3.3 KiB
Python
Raw Normal View History

2022-10-14 21:27:37 +01:00
import pytest
from pathlib import Path
from utils import Tutors
from typing import Union
import warnings
import json
file = (Path(__file__).parent.parent / "utils" / "timetable.json").resolve()
def is_sane_time(time: list[int, int]) -> Union[bool, AssertionError]:
def inner():
hour, minute = time
assert hour >= 9, "We aren't in college before 9am"
assert hour <= 5, "We aren't in college after 5pm"
assert minute in range(0, 60), "Invalid minute range - must be between (inclusive) 0 & 59"
if minute % 15 != 0:
warnings.warn(
2022-10-30 16:31:38 +00:00
UserWarning("Time '%s:%s' is probably not a valid timetable time, as lessons are every 15 minutes.")
2022-10-14 21:27:37 +01:00
)
return True
2022-10-30 16:31:38 +00:00
2022-10-14 21:27:37 +01:00
try:
return inner()
except AssertionError as e:
return e
def get_lesson_times() -> list[list[int, int]]:
data = json.loads(file.read_text())
master = []
for day, lessons in data.items():
for lesson in lessons:
master.append(lesson["start"])
master.append(lesson["end"])
return master
@pytest.mark.dependency()
def test_exists():
assert file.exists()
assert file.is_file()
@pytest.mark.dependency(depends=["test_exists"])
def test_can_read():
try:
file.read_text()
except (IOError, OSError):
assert 0, "Unable to read file."
@pytest.mark.dependency(depends=["test_exists", "test_can_read"])
def test_valid_json():
try:
data = json.loads(file.read_text())
except (IOError, OSError, json.JSONDecodeError):
data = None
assert data is not None
@pytest.mark.dependency(depends=["test_exists", "test_can_read", "test_valid_json"])
def test_valid_structure():
data = json.loads(file.read_text())
assert isinstance(data, dict)
assert len(data) == 5, "insufficient days"
for key, value in data.items():
assert isinstance(key, str)
assert key.islower()
assert isinstance(value, list)
for entry in value:
assert isinstance(entry, dict)
required_keys = {"name": 0, "start": 0, "end": 0, "tutor": 0, "room": 0}
for entry_key, entry_value in entry.items():
assert isinstance(entry_key, str)
assert entry_key in required_keys, f"unknown key {entry_key!r}"
required_keys[entry_key] = 1
if isinstance(entry_value, list):
assert len(entry_value) == 2
assert [isinstance(x, int) for x in entry_value]
else:
assert isinstance(entry_value, str)
assert all(required_keys[k] for k in required_keys.keys())
@pytest.mark.dependency(depends=["test_exists", "test_can_read", "test_valid_json", "test_valid_structure"])
@pytest.mark.parametrize("time", get_lesson_times())
def test_sane_times(time: list[int, int]):
assert is_sane_time(time), "insane lesson time: %s:%s" % time
@pytest.mark.dependency(depends=["test_exists", "test_can_read", "test_valid_json"])
def test_sane_tutors():
data = json.loads(file.read_text())
for day, lessons in data.items():
for lesson in lessons:
exists = getattr(Tutors, lesson["tutor"].upper(), None) is not None
assert exists, "Tutor %s is invalid" % lesson["tutor"]