Skip to content

Commit

Permalink
added unit tests for qualifier
Browse files Browse the repository at this point in the history
small refactoring of qualifier variable names
fixed some stuff in racetime_obs to use info from rtgg_obs
  • Loading branch information
ssbm-oro committed Dec 17, 2020
1 parent b2363b3 commit f4eebaa
Show file tree
Hide file tree
Showing 6 changed files with 151 additions and 46 deletions.
4 changes: 2 additions & 2 deletions src/gadgets/coop.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ class Coop:
partner = None
opponent2 = None
opponent1 = None
source_name = None
label_source_name = None
source = None
label_source = None
text = " "
label_text = "Race still in progress"

Expand Down
14 changes: 7 additions & 7 deletions src/gadgets/qualifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
import logging

class Qualifier:
logger: logging.Logger = None
logger: logging.Logger = logging.Logger("racetime-obs")
enabled = False
qualifier_cutoff = 3
qualifier_par_source = ""
qualifier_score_source = ""
qualifier_par_text = " "
par_source = ""
score_source = ""
par_text = " "
entrant_score = " "

def update_qualifier_text(self, race: Race, full_name: str):
Expand All @@ -22,7 +22,7 @@ def update_qualifier_text(self, race: Race, full_name: str):
entrant = race.get_entrant_by_name(full_name)
self.logger.debug(entrant)

self.qualifier_par_text = " "
self.par_text = " "
self.entrant_score = " "
if race.entrants_count_finished >= self.qualifier_cutoff:
par_time = timedelta(microseconds=0)
Expand All @@ -35,8 +35,8 @@ def update_qualifier_text(self, race: Race, full_name: str):
par_time += race.get_entrant_by_place(i).finish_time
par_time = par_time / self.qualifier_cutoff
self.logger.debug(par_time)
self.qualifier_par_text = Timer.timer_to_str(par_time)
self.par_text = Timer.timer_to_str(par_time)

if entrant and entrant.finish_time is not None:
self.entrant_score = str(2 - (entrant.finish_time / par_time))[:4]
self.entrant_score = "{:04.2f}".format(2 - (entrant.finish_time / par_time))
self.logger.debug(self.entrant_score)
62 changes: 31 additions & 31 deletions src/racetime_obs.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,18 +34,18 @@ def script_update_qualifier_settings(settings):
rtgg_obs.qualifier.enabled = obs.obs_data_get_bool(settings, "use_qualifier")
rtgg_obs.qualifier.qualifier_cutoff = obs.obs_data_get_int(settings, "qualifier_cutoff")
rtgg_obs.logger.debug(f"qualifier_cutoff is {rtgg_obs.qualifier.qualifier_cutoff}")
rtgg_obs.qualifier.qualifier_par_source = obs.obs_data_get_string(
rtgg_obs.qualifier.par_source = obs.obs_data_get_string(
settings, "qualifier_par_source")
rtgg_obs.qualifier.qualifier_score_source = obs.obs_data_get_string(
rtgg_obs.qualifier.score_source = obs.obs_data_get_string(
settings, "qualifier_score_source")

def script_update_coop_settings(settings):
rtgg_obs.coop.enabled = obs.obs_data_get_bool(settings, "use_coop")
rtgg_obs.coop.partner = obs.obs_data_get_string(settings, "coop_partner")
rtgg_obs.coop.opponent1 = obs.obs_data_get_string(settings, "coop_opponent1")
rtgg_obs.coop.opponent2 = obs.obs_data_get_string(settings, "coop_opponent2")
rtgg_obs.coop.source_name = obs.obs_data_get_string(settings, "coop_source")
rtgg_obs.coop.label_source_name = obs.obs_data_get_string(settings, "coop_label")
rtgg_obs.coop.source = obs.obs_data_get_string(settings, "coop_source")
rtgg_obs.coop.label_source = obs.obs_data_get_string(settings, "coop_label")

def script_update_timer_settings(settings):
obs.timer_remove(update_sources)
Expand Down Expand Up @@ -107,10 +107,10 @@ def script_qualifier_settings(props):
qualifier_group, "qualifier_cutoff", "Use Top X as par time, where X=", 3, 10, 1)
p = obs.obs_properties_add_list(qualifier_group, "qualifier_par_source",
"Qualifier Par Time Source", obs.OBS_COMBO_TYPE_EDITABLE, obs.OBS_COMBO_FORMAT_STRING)
rtgg_obs.fill_source_list(p)
fill_source_list(p)
p = obs.obs_properties_add_list(qualifier_group, "qualifier_score_source",
"Qualifier Score Source", obs.OBS_COMBO_TYPE_EDITABLE, obs.OBS_COMBO_FORMAT_STRING)
rtgg_obs.fill_source_list(p)
fill_source_list(p)

def script_coop_settings(props):
p = obs.obs_properties_add_bool(
Expand All @@ -127,17 +127,17 @@ def script_coop_settings(props):
coop_group, "coop_opponent1", "Co-op Opponent 1", obs.OBS_COMBO_TYPE_LIST, obs.OBS_COMBO_FORMAT_STRING)
p = obs.obs_properties_add_list(
coop_group, "coop_opponent2", "Co-op Opponent 2", obs.OBS_COMBO_TYPE_LIST, obs.OBS_COMBO_FORMAT_STRING)
rtgg_obs.fill_coop_entrant_lists(props)
fill_coop_entrant_lists(props)
p = obs.obs_properties_add_list(coop_group, "coop_source", "Coop Text Source",
obs.OBS_COMBO_TYPE_EDITABLE, obs.OBS_COMBO_FORMAT_STRING)
obs.obs_property_set_long_description(
p, "This text source will display the time that the last racer needs to finish for their team to win")
rtgg_obs.fill_source_list(p)
fill_source_list(p)
p = obs.obs_properties_add_list(coop_group, "coop_label", "Coop Label Text Source",
obs.OBS_COMBO_TYPE_EDITABLE, obs.OBS_COMBO_FORMAT_STRING)
obs.obs_property_set_long_description(
p, "This text source will be use to display a label such as \'<PartnerName> needs to finish before\' based on who the last racer is")
rtgg_obs.fill_source_list(p)
fill_source_list(p)

def script_timer_settings(props):
p = obs.obs_properties_add_bool(props, "use_podium", "Use custom color for podium finishes?")
Expand All @@ -161,7 +161,7 @@ def script_setup(props):
props, "initial_setup", "Initial setup - Check to make changes", obs.OBS_GROUP_CHECKABLE, setup_group)
p = obs.obs_properties_add_list(
setup_group, "source", "Text Source", obs.OBS_COMBO_TYPE_EDITABLE, obs.OBS_COMBO_FORMAT_STRING)
rtgg_obs.fill_source_list(p)
fill_source_list(p)
obs.obs_properties_add_text(
setup_group, "username", "Username", obs.OBS_TEXT_DEFAULT)
logging = obs.obs_properties_add_bool(
Expand Down Expand Up @@ -191,12 +191,12 @@ def script_setup(props):
obs.obs_property_set_modified_callback(refresh, refresh_pressed)

def refresh_pressed(props, prop, *args, **kwargs):
rtgg_obs.fill_source_list(obs.obs_properties_get(props, "source"))
rtgg_obs.fill_source_list(obs.obs_properties_get(props, "coop_label"))
rtgg_obs.fill_source_list(obs.obs_properties_get(props, "coop_text"))
rtgg_obs.fill_source_list(obs.obs_properties_get(props, "qualifier_par_source"))
rtgg_obs.fill_source_list(obs.obs_properties_get(props, "qualifier_score_source"))
rtgg_obs.fill_race_list(obs.obs_properties_get(props, "race"),
fill_source_list(obs.obs_properties_get(props, "source"))
fill_source_list(obs.obs_properties_get(props, "coop_label"))
fill_source_list(obs.obs_properties_get(props, "coop_text"))
fill_source_list(obs.obs_properties_get(props, "qualifier_par_source"))
fill_source_list(obs.obs_properties_get(props, "qualifier_score_source"))
fill_race_list(obs.obs_properties_get(props, "race"),
obs.obs_properties_get(props, "category_filter"))
if rtgg_obs.race is not None:
rtgg_obs.coop.update_coop_text(rtgg_obs.race, rtgg_obs.full_name)
Expand All @@ -213,7 +213,7 @@ def new_race_selected(props, prop, settings):
rtgg_obs.qualifier.update_qualifier_text(rtgg_obs.race, rtgg_obs.full_name)
rtgg_obs.logger.info(f"new race selected: {rtgg_obs.race}")
obs.obs_data_set_default_string(settings, "race_info", r.info)
rtgg_obs.fill_coop_entrant_lists(props)
fill_coop_entrant_lists(props)
else:
obs.obs_data_set_default_string(
settings, "race_info", "Race not found")
Expand All @@ -225,7 +225,7 @@ def new_race_selected(props, prop, settings):
def new_category_selected(props, prop, settings):
rtgg_obs.category = obs.obs_data_get_string(settings, "category_filter")
rtgg_obs.logger.info(f"new category selected: {rtgg_obs.category}")
rtgg_obs.fill_race_list(obs.obs_properties_get(props, "race"), prop)
fill_race_list(obs.obs_properties_get(props, "race"), prop)
return True


Expand Down Expand Up @@ -255,11 +255,11 @@ def update_sources():
color, time = rtgg_obs.timer.get_timer_text(rtgg_obs.race, rtgg_obs.full_name)
set_source_text(rtgg_obs.timer.source_name, time, color)
if rtgg_obs.coop.enabled:
set_source_text(rtgg_obs.coop.source_name, rtgg_obs.coop.text, None)
set_source_text(rtgg_obs.coop.label_source_name, rtgg_obs.coop.label_text, None)
set_source_text(rtgg_obs.coop.source, rtgg_obs.coop.text, None)
set_source_text(rtgg_obs.coop.label_source, rtgg_obs.coop.label_text, None)
if rtgg_obs.qualifier.enabled:
set_source_text(rtgg_obs.qualifier.qualifier_par_source, rtgg_obs.qualifier.qualifier_par_text, None)
set_source_text(rtgg_obs.qualifier.qualifier_score_source, rtgg_obs.qualifier.entrant_score, None)
set_source_text(rtgg_obs.qualifier.par_source, rtgg_obs.qualifier.par_text, None)
set_source_text(rtgg_obs.qualifier.score_source, rtgg_obs.qualifier.entrant_score, None)
pass

def fill_source_list(p):
Expand All @@ -273,7 +273,7 @@ def fill_source_list(p):
name = obs.obs_source_get_name(source)
obs.obs_property_list_add_string(p, name, name)

def fill_race_list(self, race_list, category_list):
def fill_race_list(race_list, category_list):
obs.obs_property_list_clear(race_list)
obs.obs_property_list_clear(category_list)
obs.obs_property_list_add_string(category_list, "All", "All")
Expand All @@ -283,7 +283,7 @@ def fill_race_list(self, race_list, category_list):
if races is not None:
categories = []
for race in races:
if self.category == "" or self.category == "All" or race.category.name == self.category:
if rtgg_obs.category == "" or rtgg_obs.category == "All" or race.category.name == rtgg_obs.category:
obs.obs_property_list_add_string(
race_list, race.name, race.name)
if not race.category.name in categories:
Expand All @@ -292,17 +292,17 @@ def fill_race_list(self, race_list, category_list):
category_list, race.category.name, race.category.name)


def fill_coop_entrant_lists(self, props):
self.fill_entrant_list(obs.obs_properties_get(props, "coop_partner"))
self.fill_entrant_list(obs.obs_properties_get(props, "coop_opponent1"))
self.fill_entrant_list(obs.obs_properties_get(props, "coop_opponent2"))
def fill_coop_entrant_lists(props):
fill_entrant_list(rtgg_obs.race, obs.obs_properties_get(props, "coop_partner"))
fill_entrant_list(rtgg_obs.race, obs.obs_properties_get(props, "coop_opponent1"))
fill_entrant_list(rtgg_obs.race, obs.obs_properties_get(props, "coop_opponent2"))


def fill_entrant_list(self, entrant_list):
def fill_entrant_list(race, entrant_list):
obs.obs_property_list_clear(entrant_list)
obs.obs_property_list_add_string(entrant_list, "", "")
if self.race is not None:
for entrant in self.race.entrants:
if race is not None:
for entrant in race.entrants:
obs.obs_property_list_add_string(
entrant_list, entrant.user.full_name, entrant.user.full_name)

Expand Down
3 changes: 3 additions & 0 deletions tests/races_for_testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
from users_for_testing import get_test_user, get_test_entrant
from categories_for_testing import get_test_race_category

def time_ago(**kwargs):
return datetime.now(timezone.utc)-timedelta(**kwargs)

def get_test_race(status_value="in_progress", version=1, entrants_count=2, started_at=datetime.now(timezone.utc),
start_delay=timedelta(seconds=-15), opened_at=datetime.now(timezone.utc), ended_at=None,
cancelled_at: datetime = None, entrant: Entrant = None, entrants: List[Entrant] = None) -> Race:
Expand Down
5 changes: 1 addition & 4 deletions tests/test_coop.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from datetime import datetime, timedelta, timezone
from gadgets.coop import Coop
from users_for_testing import get_test_entrant
from races_for_testing import get_test_race
from races_for_testing import get_test_race, time_ago

def test_coop_no_one_finished():
entrant = get_test_entrant(status_value="in_progress")
Expand Down Expand Up @@ -179,9 +179,6 @@ def test_entrant_and_partner_and_opponent1_finished_race_over():
assert coop.label_text == f"{entrant.user.name} and {partner.user.name} won"
assert coop.text == "1:30:00.0"

def time_ago(**kwargs):
return datetime.now(timezone.utc)-timedelta(**kwargs)

def test_opponents_and_entrant_finished_race_ongoing():
entrant = get_test_entrant(status_value="finished", finished_at=datetime.now(timezone.utc), finish_time=timedelta(hours=1, microseconds=1))
partner = get_test_entrant(status_value="in_progress", users_used=[entrant.user.id])
Expand Down
109 changes: 107 additions & 2 deletions tests/test_qualifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,111 @@
from models.race import Entrant, Goal, Race, Status
from users_for_testing import get_test_user, get_test_entrant
from categories_for_testing import get_test_race_category
from races_for_testing import get_test_race, time_ago

def test_not_written_yet():
assert True
def test_no_one_finished():
entrant = get_test_entrant(status_value="in_progress")
race = get_test_race(entrants_count=20, entrant=entrant)
qualifier = Qualifier()
qualifier.enabled = True
qualifier.qualifier_cutoff = 3
qualifier.par_source = "par source"
qualifier.score_source = "score source"
qualifier.update_qualifier_text(race, entrant.user.full_name)
assert qualifier.entrant_score == " "
assert qualifier.par_text == " "

def test_some_finished():
entrant = get_test_entrant(status_value="in_progress")
first_place = get_test_entrant(status_value="finished", finished_at=time_ago(minutes=20), finish_time=timedelta(hours=1, minutes=30, microseconds=1), place=1, users_used=[entrant.user.id])
second_place = get_test_entrant(status_value="finished", finished_at=time_ago(minutes=15), finish_time=timedelta(hours=1, minutes=35, microseconds=1), place=2, users_used=[entrant.user.id, first_place.user.id])
entrants = [ first_place, second_place, entrant ]
for i in range(3, 20):
users_used = (x.user for x in entrants)
entrants.append(get_test_entrant(users_used=users_used))
race = get_test_race(entrants=entrants)
qualifier = Qualifier()
qualifier.enabled = True
qualifier.qualifier_cutoff = 3
qualifier.par_source = "par source"
qualifier.score_source = "score source"
qualifier.update_qualifier_text(race, entrant.user.full_name)
assert qualifier.entrant_score == " "
assert qualifier.par_text == " "

def test_cutoff_finished():
entrant = get_test_entrant(status_value="in_progress")
first_place = get_test_entrant(status_value="finished", finished_at=time_ago(minutes=20), finish_time=timedelta(hours=1, minutes=30, microseconds=1), place=1, users_used=[entrant.user.id])
second_place = get_test_entrant(status_value="finished", finished_at=time_ago(minutes=15), finish_time=timedelta(hours=1, minutes=35, microseconds=1), place=2, users_used=[entrant.user.id, first_place.user.id])
third_place = get_test_entrant(status_value="finished", finished_at=time_ago(minutes=10), finish_time=timedelta(hours=1, minutes=40, microseconds=1), place=3, users_used=[entrant.user.id, first_place.user.id, second_place.user.id])
entrants = [ first_place, second_place, third_place, entrant ]
for i in range(4, 20):
users_used = (x.user for x in entrants)
entrants.append(get_test_entrant(users_used=users_used))
race = get_test_race(entrants=entrants)
qualifier = Qualifier()
qualifier.enabled = True
qualifier.qualifier_cutoff = 3
qualifier.par_source = "par source"
qualifier.score_source = "score source"
qualifier.update_qualifier_text(race, entrant.user.full_name)
assert qualifier.entrant_score == " "
assert qualifier.par_text == "1:35:00.0"

def test_cutoff_and_entrant_finished():
entrant = get_test_entrant(status_value="finished", finished_at=time_ago(minutes=5), finish_time=timedelta(hours=1, minutes=45, microseconds=1))
first_place = get_test_entrant(status_value="finished", finished_at=time_ago(minutes=20), finish_time=timedelta(hours=1, minutes=30, microseconds=1), place=1, users_used=[entrant.user.id])
second_place = get_test_entrant(status_value="finished", finished_at=time_ago(minutes=15), finish_time=timedelta(hours=1, minutes=35, microseconds=1), place=2, users_used=[entrant.user.id, first_place.user.id])
third_place = get_test_entrant(status_value="finished", finished_at=time_ago(minutes=10), finish_time=timedelta(hours=1, minutes=40, microseconds=1), place=3, users_used=[entrant.user.id, first_place.user.id, second_place.user.id])
entrants = [ first_place, second_place, third_place, entrant ]
for i in range(4, 20):
users_used = (x.user for x in entrants)
entrants.append(get_test_entrant(users_used=users_used))
race = get_test_race(entrants=entrants)
qualifier = Qualifier()
qualifier.enabled = True
qualifier.qualifier_cutoff = 3
qualifier.par_source = "par source"
qualifier.score_source = "score source"
qualifier.update_qualifier_text(race, entrant.user.full_name)
# par is 95 minutes, entrant's time is 105 minutes. 2-(105/95) ~= 0.89
assert qualifier.entrant_score == "0.89"
assert qualifier.par_text == "1:35:00.0"

def test_cutoff_and_entrant_finished_in_top():
entrant = get_test_entrant(status_value="finished", finished_at=time_ago(minutes=15), finish_time=timedelta(hours=1, minutes=35, microseconds=1), place=2)
first_place = get_test_entrant(status_value="finished", finished_at=time_ago(minutes=20), finish_time=timedelta(hours=1, minutes=30, microseconds=1), place=1, users_used=[entrant.user.id])
third_place = get_test_entrant(status_value="finished", finished_at=time_ago(minutes=10), finish_time=timedelta(hours=1, minutes=40, microseconds=1), place=3, users_used=[entrant.user.id, first_place.user.id])
entrants = [ first_place, entrant, third_place ]
for i in range(4, 20):
users_used = (x.user for x in entrants)
entrants.append(get_test_entrant(users_used=users_used))
race = get_test_race(entrants=entrants)
qualifier = Qualifier()
qualifier.enabled = True
qualifier.qualifier_cutoff = 3
qualifier.par_source = "par source"
qualifier.score_source = "score source"
qualifier.update_qualifier_text(race, entrant.user.full_name)
# par is 95 minutes, entrant's time is 95 minutes. 2-(95/95) = 1.00
assert qualifier.entrant_score == "1.00"
assert qualifier.par_text == "1:35:00.0"

def test_cutoff_and_entrant_finished_in_first():
entrant = get_test_entrant(status_value="finished", finished_at=time_ago(minutes=20), finish_time=timedelta(hours=1, minutes=30, microseconds=1), place=2)
second_place = get_test_entrant(status_value="finished", finished_at=time_ago(minutes=15), finish_time=timedelta(hours=1, minutes=35, microseconds=1), place=1, users_used=[entrant.user.id])
third_place = get_test_entrant(status_value="finished", finished_at=time_ago(minutes=10), finish_time=timedelta(hours=1, minutes=40, microseconds=1), place=3, users_used=[entrant.user.id, second_place.user.id])
entrants = [ entrant, second_place, third_place ]
for i in range(4, 20):
users_used = (x.user for x in entrants)
entrants.append(get_test_entrant(users_used=users_used))
race = get_test_race(entrants=entrants)
qualifier = Qualifier()
qualifier.enabled = True
qualifier.qualifier_cutoff = 3
qualifier.par_source = "par source"
qualifier.score_source = "score source"
qualifier.update_qualifier_text(race, entrant.user.full_name)
# par is 95 minutes, entrant's time is 90 minutes. 2-(90/95) ""= 1.05
assert qualifier.entrant_score == "1.05"
assert qualifier.par_text == "1:35:00.0"

0 comments on commit f4eebaa

Please sign in to comment.