Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add testing #43

Merged
merged 15 commits into from
Jun 28, 2020
8 changes: 8 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[run]
source =
cogs/
the_mines/
utils/

[report]
fail_under = 65.0
2 changes: 1 addition & 1 deletion .github/workflows/pythonappci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ jobs:
pip install -r requirements.txt -r test_requirements.txt
- name: Test with pytest
run: |
pytest -v tests/
pytest -m "not online" -v --cov tests/
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ tests/__pycache__
/the_mines/process/fussballdaten/matchday30.html
/the_mines/process/fussballdaten/test.html
/the_mines/process/fussballdaten/test.py
.coverage
3 changes: 3 additions & 0 deletions pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[pytest]
markers =
online: marks tests that use online resources (deselect with '-m "not online"')
1 change: 1 addition & 0 deletions test_requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
pytest==5.3.5
pytest-cov==2.10.0
2 changes: 1 addition & 1 deletion tests/test_dummy_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ def test_get_dummy_data():
for result in get_dummy_data():
result_count += 1
if isinstance(result, int):
assert result > 0
assert result >= 0
elif isinstance(result, str):
assert len(result) == 2

Expand Down
62 changes: 62 additions & 0 deletions tests/test_misc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import pytest
import re
from utils.misc import (
umlaut,
unumlaut,
format_date,
open_default_html,
get_default_matchday,
get_default_season,
)


@pytest.mark.parametrize(
("word", "expected"),
[("f\\xc3\\xb6\\xc3\\xb6", "föö"), ("bar", "bar"), ("f\\xc3\\xbctbol", "fütbol"),],
)
def test_umlaut(word, expected):
assert umlaut(word) == expected


@pytest.mark.parametrize(
("word", "expected"),
[
("föö", "foo"),
("bär", "bar"),
("fütbol", "futbol"),
("áēïōü", "aeiou"),
("test", "test"),
],
)
def test_unumlaut(word, expected):
assert unumlaut(word) == expected


@pytest.mark.parametrize(
("date", "expected"),
[("10.10.2010", "October 10, 2010"), ("1.2.2012", "February 1, 2012"),],
)
def test_format_date(date, expected):
assert format_date(date) == expected


@pytest.mark.online
@pytest.mark.parametrize(
("pattern"),
[("Die aktuelle Bundesliga 20\d\d/20\d\d - Der \d*\. Spieltag - Fussballdaten")],
)
def test_open_default_html(pattern):
assert re.match(pattern, open_default_html())


@pytest.mark.online
@pytest.mark.parametrize(("earliest", "latest"), [(1, 34)])
def test_get_default_matchday(earliest, latest):
result = int(get_default_matchday())
assert result >= earliest and result <= latest


@pytest.mark.online
@pytest.mark.parametrize(("pattern"), [("20\d\d")])
def test_get_default_season(pattern):
assert re.match(pattern, get_default_season())
125 changes: 125 additions & 0 deletions tests/test_process_blurb.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import pytest

from the_mines.process.fussballdaten.process_blurb import (
build_matchup,
get_team_str,
get_glance_schedule,
get_glance_table_stats,
get_blurb,
)


@pytest.mark.parametrize(
("title", "score", "expected"),
[
(
"Blah: Bayern gegen Dortmund (1.1.2001, DFB-Pokal)",
"2:2",
{"January 1, 2001 (DFB-Pokal)": "Bayern 2:2 Dortmund"},
),
(
"Blah: Bayern gegen Dortmund (2.2.2002, Bundesliga)",
None,
{"February 2, 2002 (Bundesliga)": "Bayern vs Dortmund"},
),
],
)
def test_build_matchup(title, score, expected):
assert build_matchup(title, score) == expected


@pytest.mark.parametrize(
("target", "expected"),
[
("bayern", "fc-bayern-muenchen"),
("leipzig", "rb-leipzig"),
("mainz", "1-fsv-mainz-05"),
],
)
def test_get_team_str(target, expected):
assert get_team_str(target) == expected


@pytest.mark.online
@pytest.mark.parametrize(
("team", "season", "expected"),
[
(
"bayern",
"2020",
{
"June 20, 2020 (Bundesliga)": "Bayern 3:1 Freiburg",
"June 27, 2020 (Bundesliga)": "Wolfsburg 0:4 Bayern",
},
),
(
"dortmund",
"2020",
{
"June 20, 2020 (Bundesliga)": "RB Leipzig 0:2 Dortmund",
"June 27, 2020 (Bundesliga)": "Dortmund 0:4 Hoffenheim",
},
),
],
)
def test_get_glance_schedule(team, season, expected):
assert get_glance_schedule(team, season) == expected


@pytest.mark.online
@pytest.mark.parametrize(
("team", "season", "expected"),
[
(
"bayern",
"2020",
{"title": "Bayern", "fields": {"Pos": "1", "W-T-L": "26-4-4", "Pts": "82"}},
),
(
"dortmund",
"2020",
{
"title": "Dortmund",
"fields": {"Pos": "2", "W-T-L": "21-6-7", "Pts": "69"},
},
),
],
)
def test_get_glance_table_stats(team, season, expected):
assert get_glance_table_stats(team, season) == expected


@pytest.mark.online
@pytest.mark.parametrize(
("team", "expected"),
[
(
"bayern",
{
"title": "Bayern",
"fields": {
"Pos": "1",
"W-T-L": "26-4-4",
"Pts": "82",
"June 20, 2020 (Bundesliga)": "Bayern 3:1 Freiburg",
"June 27, 2020 (Bundesliga)": "Wolfsburg 0:4 Bayern",
},
},
),
(
"dortmund",
{
"title": "Dortmund",
"fields": {
"Pos": "2",
"W-T-L": "21-6-7",
"Pts": "69",
"June 20, 2020 (Bundesliga)": "RB Leipzig 0:2 Dortmund",
"June 27, 2020 (Bundesliga)": "Dortmund 0:4 Hoffenheim",
},
},
),
],
)
def test_get_blurb(team, expected):
assert get_blurb(team) == expected
37 changes: 37 additions & 0 deletions tests/test_process_matchday.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import pytest

from the_mines.process.fussballdaten.process_matchday import (
live_match,
future_match,
past_match,
create_initial_dict,
get_initial_data,
process_results,
)


@pytest.mark.online
@pytest.mark.parametrize(
("matchday", "season", "expected"),
[
(
"34",
"2020",
[
[("Frankfurt", "3"), ("Paderborn", "2")],
[("Bremen", "6"), ("Köln", "1")],
[("Freiburg", "4"), ("Schalke", "0")],
[("Augsburg", "1"), ("RB Leipzig", "2")],
[("Union Berlin", "3"), ("Düsseldorf", "0")],
[("Dortmund", "0"), ("Hoffenheim", "4")],
[("Leverkusen", "1"), ("Mainz", "0")],
[("M\\'gladbach", "2"), ("Hertha BSC", "1")],
[("Wolfsburg", "0"), ("Bayern", "4")],
],
)
],
)
def test_process_results(matchday, season, expected):
results = process_results(matchday, season)["27.06.2020"]
for match in expected:
assert match in results
70 changes: 70 additions & 0 deletions tests/test_table_handler.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import pytest
from tempfile import TemporaryFile
from bs4 import BeautifulSoup

from utils.table_handler import (
tables_from_soup,
get_table,
find_team_in_table,
extract_full_table_stats,
)
from the_mines.download.get_html import download_raw_html


def get_soup(url="https://www.fussballdaten.de/bundesliga/tabelle/2019"):
with TemporaryFile("w+") as tmp:
tmp.write(download_raw_html(url))
tmp.seek(0)
return BeautifulSoup(tmp, "html.parser")


@pytest.mark.online
@pytest.mark.parametrize("expected", [(4)])
def test_tables_from_soup(expected):
assert len(tables_from_soup(get_soup())) == expected


@pytest.mark.online
@pytest.mark.parametrize(
("full", "form", "home", "away", "expected"),
[
(True, False, False, False, 19),
(False, True, False, False, 4),
(False, False, True, False, 4),
(False, False, False, True, 4),
],
)
def test_get_table(full, form, home, away, expected):
assert (
len(
get_table(
tables_from_soup(get_soup()), full=full, form=form, home=home, away=away
)
)
== expected
)


@pytest.mark.online
@pytest.mark.parametrize(
("team", "table", "expected"),
[("bayern", get_table(tables_from_soup(get_soup()), full=True), 10)],
)
def test_find_team_in_table(team, table, expected):
assert len(find_team_in_table(team, table)) == expected


@pytest.mark.online
@pytest.mark.parametrize(
("row", "expected"),
[
(
find_team_in_table(
"bayern", get_table(tables_from_soup(get_soup()), full=True)
),
("1", "Bayern", "34", "24", "6", "4", "88:32", "56", "78"),
)
],
)
def test_extract_full_table_stats(row, expected):
assert extract_full_table_stats(row) == expected
37 changes: 21 additions & 16 deletions the_mines/process/fussballdaten/process_blurb.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ def get_team_str(target):

def get_glance_schedule(team, season=get_default_season()):
team = get_team_str(team)
results = {}

# Get previous and current match
url = f"https://www.fussballdaten.de/vereine/{team}/{season}/spielplan/"
Expand All @@ -94,23 +95,27 @@ def get_glance_schedule(team, season=get_default_season()):
prev_score, _ = prev.find_all("span")
curr_score, _ = curr.find_all("span")

# Get next match
url = f"https://www.fussballdaten.de/vereine/{team}/{season}/"
with TemporaryFile("w+") as tmp:
tmp.write(download_raw_html(url))
tmp.seek(0)
soup = BeautifulSoup(tmp, "html.parser")

(upcoming,) = soup.find_all("div", attrs={"class": "naechste-spiele"})

# The list of upcoming matches depends on how many matches are left
# in the season. We can't reliably list decompose so we'll have to pop
next = upcoming.find_all("a").pop(0)
results.update(build_matchup(prev.attrs["title"], prev_score.get_text()))
results.update(build_matchup(curr.attrs["title"], curr_score.get_text()))

results = {}
results.update(build_matchup(prev.attrs["title"], prev_score.get_text()))
results.update(build_matchup(curr.attrs["title"], curr_score.get_text()))
results.update(build_matchup(next.attrs["title"]))
# Get next match
# This needs a rework. We can't get next matches at the end of the season.
try:
url = f"https://www.fussballdaten.de/vereine/{team}/{season}/"
with TemporaryFile("w+") as tmp:
tmp.write(download_raw_html(url))
tmp.seek(0)
soup = BeautifulSoup(tmp, "html.parser")

(upcoming,) = soup.find_all("div", attrs={"class": "naechste-spiele"})

# The list of upcoming matches depends on how many matches are left
# in the season. We can't reliably list decompose so we'll have to pop
next = upcoming.find_all("a").pop(0)
results.update(build_matchup(next.attrs["title"]))
except:
logger.debug("No upcoming matches")
pass

return results

Expand Down