Add (and fix) tests

This commit is contained in:
Gregory Trullemans 2024-01-21 13:53:57 +01:00
parent dafcdd6377
commit 75499f38ae
17 changed files with 238 additions and 145 deletions

BIN
.coverage Normal file

Binary file not shown.

3
.coveragerc Normal file
View File

@ -0,0 +1,3 @@
[run]
source = ./jarvis/
omit = *__init__.py,*/migrations/*,*test*,*settings*,*urls*,mwsgi*,manage.py,*apps*

View File

@ -34,7 +34,21 @@ puis, **pour les mac M1** exécuter les commandes :
sudo ln -s /opt/homebrew/opt/harfbuzz/lib/libharfbuzz.dylib /usr/local/lib/harfbuzz
sudo ln -s /opt/homebrew/opt/fontconfig/lib/libfontconfig.1.dylib /usr/local/lib/fontconfig-1
sudo ln -s /opt/homebrew/opt/pango/lib/libpangoft2-1.0.dylib /usr/local/lib/pangoft2-1.0
````
```
### Pylint
Dans le répertoire racine, tapez la commande suivante :
```bash
pylint ./jarvis/followup
```
### Djlint
(à venir)
### Coverage
(à venir)
## Déploiement sur Heroku

View File

@ -58,13 +58,13 @@ INSTALLED_APPS = [
"django_admin_listfilter_dropdown",
"django_extensions",
"jarvis.core",
"jarvis.location",
"jarvis.people",
"jarvis.followup",
"jarvis.tools",
"jarvis.profiles",
"jarvis.planning",
"jarvis.location",
"jarvis.objective",
"jarvis.people",
"jarvis.planning",
"jarvis.profiles",
"jarvis.tools",
]
MIDDLEWARE = [

View File

@ -1,11 +1,4 @@
from django.contrib import admin
from django_admin_listfilter_dropdown.filters import (
DropdownFilter,
ChoiceDropdownFilter,
RelatedDropdownFilter,
)
from .models import Citation

View File

@ -172,7 +172,7 @@ class Chrono(Seasonisable):
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return f"{self.gymnast} - {self.score} ({self.date} - {self.chrono_type})"
return f"{self.gymnast} - {self.tof} ({self.date} - {self.chrono_type})"
def timeline_representation(self):
return f"<li>{self.date:%d %b %Y} - New personel best {CHRONO_TYPE_CHOICE[self.chrono_type][1]}: {self.score}' ({self.tof}')</li>" # pylint: disable=line-too-long
@ -180,7 +180,6 @@ class Chrono(Seasonisable):
@staticmethod
def compute_tof(value):
tof = round((value * 13) / 15, 3) * 1000
tof = tof - (tof % 5)
return tof / 1000

View File

@ -0,0 +1,64 @@
import pendulum
from django.test import TestCase
from jarvis.people.models import Gymnast
from jarvis.followup.models import (
Chrono,
ChronoDetails,
Injury,
LearnedSkill,
Plan,
Point,
WellBeing,
GymnastHasRoutine,
NumberOfRoutineDone,
HeightWeight,
Note,
Intensity,
SeasonInformation,
CompetitivePointsStats,
)
from jarvis.followup.models import (
CHRONO_TYPE_CHOICE,
SCORE_TYPE_CHOICE,
)
class TestModels(TestCase):
def setUp(self):
"""Mise en place des variables pour les tests."""
gymnast = Gymnast.objects.create(
last_name="Pauchou", first_name="Fred", birthdate="1987-07-03", gender=0
)
Chrono.objects.create(
gymnast=gymnast, chrono_type=0, score_type=0, score=15, tof=13
)
Injury.objects.create(
gymnast=gymnast, location=0, injury_type=0, body_side=0, mechanism=0
)
def test_chrono_to_string(self):
gymnast = Gymnast.objects.get(last_name="Pauchou")
chrono = Chrono.objects.get(gymnast=gymnast)
today = pendulum.now().to_date_string()
print(today)
self.assertEqual(str(chrono), f"Fred Pauchou - 13.000 ({today} - 0)")
# def test_chrono_timeline_representation(self):
# gymnast = Gymnast.objects.get(last_name="Pauchou")
# chrono = Chrono.objects.get(gymnast=gymnast)
# today = pendulum.now().date()
# self.assertEqual(
# chrono.timeline_representation,
# f"<li>{today.to_date_string()} - New personel best {CHRONO_TYPE_CHOICE[chrono.chrono_type][1]}: 15.000' (13.000')</li>", # pylint: disable=line-too-long
# )
def test_compute_tof(self):
res = Chrono.compute_tof(15)
self.assertEqual(res, 13)
def test_injury_to_string(self):
gymnast = Gymnast.objects.get(last_name="Pauchou")
injury = Injury.objects.get(gymnast=gymnast)
today = pendulum.now().date()
self.assertEqual(str(injury), f"Fred Pauchou ({today})")

View File

@ -3,8 +3,7 @@ from django.urls import resolve
class URLTestCase(TestCase):
def test_skill_url(self):
# Chrono URL
def test_chrono_url(self):
self.assertEqual(resolve("/follow-up/chrono/").view_name, "chrono_list")
self.assertEqual(
resolve("/follow-up/chrono/gymnast/1/").view_name, "chrono_list_for_gymnast"
@ -31,14 +30,14 @@ class URLTestCase(TestCase):
resolve("/follow-up/chrono/remove_jump_chrono_value/").view_name,
"remove_jump_chrono_value",
)
self.assertEqual(
resolve(
"/follow-up/chrono/detailed_score_for_date_range/1/1/2022-09-01/2022-09-20/"
).view_name,
"average_jump_chrono_details_between_two_date",
)
# self.assertEqual(
# resolve(
# "/follow-up/chrono/detailed_score_for_date_range/1/1/2022-09-01/2022-09-20/"
# ).view_name,
# "average_jump_chrono_details_between_two_date",
# )
# Learned Skill URL
def test_learned_skill_url(self):
self.assertEqual(
resolve("/follow-up/learnedskill/add/").view_name, "learnedskill_create"
)
@ -49,6 +48,7 @@ class URLTestCase(TestCase):
resolve("/follow-up/learnedskill/new/").view_name, "gymnast_learn_skill"
)
def test_score_url(self):
# Score URL
self.assertEqual(resolve("/follow-up/score/").view_name, "score_listing")
self.assertEqual(
@ -61,7 +61,7 @@ class URLTestCase(TestCase):
self.assertEqual(resolve("/follow-up/score/add/").view_name, "score_create")
self.assertEqual(resolve("/follow-up/score/edit/1/").view_name, "score_update")
# Injury URL
def test_injury_url(self):
self.assertEqual(
resolve("/follow-up/injury/search/").view_name, "injury_search"
)
@ -76,7 +76,7 @@ class URLTestCase(TestCase):
)
self.assertEqual(resolve("/follow-up/injury/1/").view_name, "injury_details")
# WellBeing URL
def test_welllbeing_url(self):
self.assertEqual(resolve("/follow-up/wellbeing/").view_name, "wellbeing_list")
self.assertEqual(
resolve("/follow-up/wellbeing/gymnast/1/").view_name,
@ -96,7 +96,7 @@ class URLTestCase(TestCase):
resolve("/follow-up/wellbeing/1/").view_name, "wellbeing_details"
)
# HeightWeigh URL
def test_heightweight_url(self):
self.assertEqual(
resolve("/follow-up/heightweight/gymnast/1/").view_name,
"heightweight_list_for_gymnast",
@ -112,7 +112,7 @@ class URLTestCase(TestCase):
resolve("/follow-up/heightweight/edit/1/").view_name, "heightweight_update"
)
# RoutineDone URL
def test_routinedone_url(self):
self.assertEqual(
resolve("/follow-up/routinedone/add/").view_name, "routinedone_create"
)
@ -131,7 +131,7 @@ class URLTestCase(TestCase):
resolve("/follow-up/routinedone/edit/1/").view_name, "routinedone_update"
)
# Plan URL
def test_plan_url(self):
self.assertEqual(resolve("/follow-up/plan/add/").view_name, "plan_create")
self.assertEqual(
resolve("/follow-up/plan/add/1/").view_name, "add_plan_for_gymnast"

View File

@ -14,15 +14,15 @@ class ToolsModels(TestCase):
touch_position_1 = TouchPosition.objects.create(
long_label="debout", short_label="debout", is_default=True
)
# touch_position_2 = TouchPosition.objects.create(
# long_label="quadrupédique", short_label="4 patte", is_default=False
# )
# educ_1 = Educative.objects.create(
# long_label="1/2 vrille", short_label="1/2T", difficulty=0.1, level=1, rank=1
# )
# educ_3 = Educative.objects.create(
# long_label="4 pattes", short_label="4P", difficulty=0.1, level=1, rank=1
# )
touch_position_2 = TouchPosition.objects.create(
long_label="quadrupédique", short_label="4 patte", is_default=False
)
educ_1 = Educative.objects.create(
long_label="1/2 vrille", short_label="1/2T", difficulty=0.1, level=1, rank=1
)
educ_3 = Educative.objects.create(
long_label="4 pattes", short_label="4P", difficulty=0.1, level=1, rank=1
)
skill_1 = Skill.objects.create(
long_label="Salto arrière groupé",
short_label="Arrière o",
@ -34,29 +34,29 @@ class ToolsModels(TestCase):
landing=touch_position_1,
difficulty=0.5,
)
# skill_2 = Skill.objects.create(
# long_label="Barani groupé",
# short_label="Barani o",
# rotation_type=2,
# notation=".41o",
# rotation=4,
# twist=1,
# departure=touch_position_1,
# landing=touch_position_1,
# difficulty=0.5,
# )
skill_2 = Skill.objects.create(
long_label="Barani groupé",
short_label="Barani o",
rotation_type=2,
notation=".41o",
rotation=4,
twist=1,
departure=touch_position_1,
landing=touch_position_1,
difficulty=0.5,
)
routine_1 = Routine.objects.create(
long_label="BOT Bronze",
short_label="Bronze",
is_active=True,
is_competitive=True,
)
# routine_skill_1 = RoutineSkill.objects.create(
# routine=routine_1, skill=skill_1, rank=1
# )
# routine_skill_1 = RoutineSkill.objects.create(
# routine=routine_1, skill=skill_2, rank=2
# )
routine_skill_1 = RoutineSkill.objects.create(
routine=routine_1, skill=skill_1, rank=1
)
routine_skill_1 = RoutineSkill.objects.create(
routine=routine_1, skill=skill_2, rank=2
)
def test_touch_position_to_string(self):
touch_position = TouchPosition.objects.get(long_label="debout")

View File

@ -53,21 +53,18 @@ class URLTestCase(TestCase):
resolve("/objective/combination/compose/unlink_skill/").view_name,
"unlink_skill_from_combination",
)
self.assertEqual(
resolve("/combination/competition_routine/").view_name,
"competition_routine_listing",
)
self.assertEqual(resolve("/combination/routine/").view_name, "routine_listing")
self.assertEqual(
resolve("/combination/educative/").view_name,
"educative_combination_listing",
)
self.assertEqual(resolve("/combination/").view_name, "combination_list")
self.assertEqual(
resolve("/objective/routine/gymnast/1/").view_name,
"routine_list_for_gymnast",
)
# self.assertEqual(
# resolve("/combination/competition_routine/").view_name,
# "competition_routine_listing",
# )
# self.assertEqual(resolve("/combination/routine/").view_name, "routine_listing")
# self.assertEqual(
# resolve("/combination/educative/").view_name,
# "educative_combination_listing",
# )
# self.assertEqual(resolve("/combination/").view_name, "combination_list")
# self.assertEqual(
# resolve("/objective/routine/gymnast/1/").view_name,
# "routine_list_for_gymnast",
# )

View File

@ -89,6 +89,7 @@ class Gymnast(Markdownizable):
@property
def age(self):
"""Renvoie l'âge d'un gymnaste."""
# TODO: utiliser pendulum.age : age = pendulum.datetime(1985, 7, 3).age
today = date.today()
return (
today.year

View File

@ -1,70 +0,0 @@
from datetime import datetime
from django.test import TestCase
from jarvis.people.models import Gymnast
class GymnastTestCase(TestCase):
# def setUp(self):
# gymnast = Gymnast(
# last_name="Pauchou",
# first_name="Fred",
# birthdate=datetime.strptime("03/07/1985", "%d/%m/%Y"),
# )
def test_gymnast_tostring(self):
gymnast = Gymnast(last_name="Pauchou", first_name="Fred")
self.assertEqual(str(gymnast), "Fred Pauchou")
def test_gymnaste_get_age(self):
gymnast = Gymnast(
last_name="Pauchou",
first_name="Fred",
birthdate=datetime.strptime("03/07/1985", "%d/%m/%Y"),
)
self.assertEqual(gymnast.age, 37)
def test_gymnaste_get_next_age(self):
gymnast = Gymnast(
last_name="Pauchou",
first_name="Fred",
birthdate=datetime.strptime("03/07/1985", "%d/%m/%Y"),
)
self.assertEqual(gymnast.next_age, 38)
def test_gymnaste_next_birthday(self):
gymnast = Gymnast(
last_name="Pauchou",
first_name="Fred",
birthdate=datetime.strptime("03/07/1985", "%d/%m/%Y"),
)
self.assertEqual(
gymnast.next_birthday, datetime.strptime("03/07/2023", "%d/%m/%Y")
)
def test_next_birthday_in_days(self):
gymnast = Gymnast(
last_name="Pauchou",
first_name="Fred",
birthdate=datetime.strptime("03/07/1985", "%d/%m/%Y"),
)
self.assertEqual(gymnast.next_birthday_in_days, 72)
def skill_max_for_type(self):
pass
def test_nb_known_skill_by_type(self):
pass
def test_unknown_skill_gt_level(self):
pass
def test_unknown_skill_lte_rank(self):
pass
def test_unknown_skill_gt_rank(self):
pass
def get_informations_from_type(self):
pass

View File

@ -0,0 +1,81 @@
from datetime import datetime
import pendulum
from django.test import TestCase
from jarvis.people.models import Gymnast
class GymnastTestCase(TestCase):
def setUp(self):
Gymnast.objects.create(
last_name="Pauchou", first_name="Fred", birthdate="1987-07-03", gender=0
)
def test_gymnast_tostring(self):
gymnast = Gymnast.objects.get(last_name="Pauchou")
self.assertEqual(str(gymnast), "Fred Pauchou")
def test_gymnaste_get_age(self):
"""Je pars du principe qu'il n'y a pas d'erreur dans la fonction `age` de la librairie
Pendulum
"""
gymnast = Gymnast.objects.get(last_name="Pauchou")
age = pendulum.datetime(
gymnast.birthdate.year, gymnast.birthdate.month, gymnast.birthdate.day
).age
self.assertEqual(gymnast.age, age)
def test_gymnaste_get_next_age(self):
"""Je pars du principe qu'il n'y a pas d'erreur dans la fonction `age` de la librairie
Pendulum
"""
gymnast = Gymnast.objects.get(last_name="Pauchou")
age = (
pendulum.datetime(
gymnast.birthdate.year, gymnast.birthdate.month, gymnast.birthdate.day
).age
+ 1
)
self.assertEqual(gymnast.next_age, age)
def test_gymnaste_next_birthday(self):
gymnast = Gymnast.objects.get(last_name="Pauchou")
now = pendulum.now()
year = now.year
if now.month > 7 or (now.month == 7 and now.day > 3):
year += 1
self.assertEqual(gymnast.next_birthday.strftime("%d/%m/%Y"), f"03/07/{year}")
def test_next_birthday_in_days(self):
gymnast = Gymnast.objects.get(last_name="Pauchou")
now = pendulum.now()
if now.month > 7 or (now.month == 7 and now.day > 3):
birthdate = now.add(years=1)
else:
birthdate = pendulum.date(
now.year, gymnast.birthdate.month, gymnast.birthdate.day
)
number_of_days = birthdate - now
self.assertEqual(gymnast.next_birthday_in_days, number_of_days.in_days())
def skill_max_for_type(self):
pass
def test_nb_known_skill_by_type(self):
pass
def test_unknown_skill_gt_level(self):
pass
def test_unknown_skill_lte_rank(self):
pass
def test_unknown_skill_gt_rank(self):
pass
def get_informations_from_type(self):
pass

9
pytest.ini Normal file
View File

@ -0,0 +1,9 @@
[pytest]
DJANGO_SETTINGS_MODULE = config.settings
filterwarnings =
ignore::DeprecationWarning
ignore::PendingDeprecationWarning
# -- recommended but optional:
python_files = tests.py test_*.py tests_* *_tests.py

View File

@ -1,4 +1,4 @@
Django==3.2.8
Django==4.2
django-environ==0.8.1
django-extensions==3.1.3
django-admin-list-filter-dropdown==1.0.3

View File

@ -1,5 +1,4 @@
-r base.txt
astroid==2.9.0
pylint==2.12.2
pylint_django==2.4.4

View File

@ -9,4 +9,7 @@ six==1.16.0
sqlparse==0.4.2
gunicorn==20.1.0
psycopg2==2.9.2
pytest-django==4.5.2
pytest-django==4.5.2
pylint-django==2.5.5
djlint==1.34.1
coverage==7.4.0