This commit is contained in:
2022-11-08 21:19:51 +01:00
commit 4c456eafc3
160 changed files with 21472 additions and 0 deletions

View File

@@ -0,0 +1,6 @@
from .alimentation import *
from .decisions import *
from .decorators import *
from .functions import *
from .logging import *
from .predicates import *

View File

@@ -0,0 +1,56 @@
from django.test import SimpleTestCase
from ...utils.alimentation import BOCols as Cols
class BOColsTestCase(SimpleTestCase):
""" tests pour BOCols """
def test_attributes(self):
""" vérifie que les nouveaux attributs sont renseignés correctement """
for col in Cols:
self.assertIsInstance(col.value, str, f"{col} : la valeur n'a pas le bon type")
def test_columns(self):
""" vérifie les colonnes renvoyées """
members = list(Cols)
col_names = [col.value for col in members]
self.assertCountEqual(col_names, Cols.columns(), "les noms de colonnes (sans argument) ne sont pas les bons")
col = members[0]
col_names = [col.value]
self.assertCountEqual(col_names, Cols.columns(col), "les noms de colonnes (un argument) ne sont pas les bons")
col_list = members[0:2]
col_names = [col.value for col in col_list]
self.assertCountEqual(col_names, Cols.columns(*col_list), "les noms de colonnes (plusieurs arguments) ne sont pas les bons")
def test_col_mapping(self):
""" vérifie les correspondances renvoyés """
members = list(Cols)
std_mapping = {'a': 1, 'b': 'test'}
enum_mapping = {members[0]: (2, 3), members[1]: members[1].name}
mapping_before = {**enum_mapping, **std_mapping}
mapping_after = Cols.col_mapping(mapping_before)
self.assertTrue(all(k in mapping_after for k in std_mapping.keys()), "toutes les clés standard doivent faire partie du mapping final")
self.assertTrue(all(v == mapping_after.get(k) for k, v in std_mapping.items()), "les valeurs de clés standard ne doivent pas changer")
self.assertTrue(all(k.value in mapping_after for k in enum_mapping.keys()), f"tous les noms de colonnes de clés de type {Cols.__name__} doivent faire partie du mapping final")
self.assertTrue(all(v == mapping_after.get(k.value) for k, v in enum_mapping.items()), f"les valeurs de clés de type {Cols.__name__} ne doivent pas changer")
def test_converters(self):
""" vérifie les convertisseurs renvoyés """
members = list(Cols)
col_names = [col.value for col in members if col.converter]
self.assertCountEqual(col_names, Cols.converters().keys(), "les convertisseurs (sans argument) ne sont pas les bons")
col = members[0]
col_names = [col.value]
self.assertCountEqual(col_names, Cols.converters(col).keys(), "les convertisseurs (un argument) ne sont pas les bons")
col_list = members[0:2]
col_names = [col.value for col in col_list]
self.assertCountEqual(col_names, Cols.converters(*col_list).keys(), "les convertisseurs (plusieurs arguments) ne sont pas les bons")

View File

@@ -0,0 +1,283 @@
from typing import Callable, List, Optional, Tuple, Union
from unittest import mock
from django.test import TestCase
from ...models import Administre
from ...models import AvisPosteChoices as AvisPoste
from ...models import CustomUser, Decision, DecisionChoices, Poste, SousVivier
from ...models import StatutPamChoices as StatutPam
from ...utils.decisions import (DECISIONS, KEY_CHOICES, KEY_CREATE,
KEY_PROFILES, KEY_UPDATE, ExtraDecisions,
get_all_decisions, get_available_decisions)
from ...utils.permissions import (KEY_READ, KEY_WRITE, Profiles,
get_profiles_by_adm)
class DecisionsTest(TestCase):
def setUp(self):
""" vérifie qu'il n'existe aucun administré ou poste avant le test """
self.assertEqual(Administre.objects.exists(), False, "pas d'administré avant un test")
self.assertEqual(Poste.objects.exists(), False, "pas de poste avant un test")
def tearDown(self):
""" supprime tous les administrés, les postes, les décisions en fin de test """
Decision.objects.all().delete()
Poste.objects.all().delete()
Administre.objects.all().delete()
def __load_administres(self) -> List[Administre]:
""" charge les administrés de la base à partir des IDs """
self.assertTrue(self.adm_ids, "il est nécessaire de renseigner des IDs d'administrés pour le chargement")
return list(Administre.objects.filter(pk__in=self.adm_ids or ()))
def __setup_decisions(self, decision: Optional[Union[DecisionChoices, ExtraDecisions]]) -> None:
""" supprime et recrée (si nécessaire) les postes et les décisions des administrés """
Decision.objects.all().delete()
Poste.objects.all().delete()
if decision and decision != ExtraDecisions.EMPTY:
for adm_id in self.adm_ids:
poste = Poste.objects.create(pk=str(adm_id), p_avis=AvisPoste.P1)
Decision.objects.create(administre_id=adm_id, poste=poste, de_decision=decision)
def __do_for_profiles(self, action: Callable[[Profiles], None], profiles: Tuple[Profiles], decisions: Tuple[Union[DecisionChoices, ExtraDecisions]] = ()) -> None:
"""
exécute une action (un test) avec un sous-test :
- soit pour chaque profil (utilise un mock)
- soit pour chaque profil et chaque statut de décision (utilise un mock)
implicite : self.adm_ids
"""
def run_subTest(profile: Profiles, decision: Optional[Union[DecisionChoices, ExtraDecisions]] = None) -> None:
with self.subTest(profile=profile.name, **({'decision': decision.name} if decision else {})):
@mock.patch(
f'{get_available_decisions.__module__}.{get_profiles_by_adm.__name__}',
return_value={adm_id: {KEY_READ: (), KEY_WRITE: (profile,)} for adm_id in self.adm_ids}
)
def do_with_profile(mock):
action(profile, decision)
do_with_profile()
for p in profiles:
if decisions:
for decision in decisions:
self.__setup_decisions(decision)
run_subTest(p, decision)
else:
run_subTest(p)
def __assert_common(self, decisions_by_adm):
"""
assertions communes à propos des décisions renvoyées pour les administrés
implicite : self.adm_ids
"""
self.assertIsInstance(decisions_by_adm, dict, "le résultat n'est jamais None")
for adm_id in self.adm_ids:
self.assertTrue(adm_id in decisions_by_adm, "tous les administrés doivent être présents dans le résultat")
decisions = decisions_by_adm.get(adm_id)
self.assertIsInstance(decisions, dict, "le format des décisions est un dictionnaire")
for key in (KEY_CREATE, KEY_UPDATE):
self.assertTrue(key in decisions, f"les décisions doivent contenir la clé {key}")
self.assertIsInstance(decisions.get(key), tuple, f"la valeur de {key} des décisions n'a pas le type attendu")
def test_tree_attribute(self):
""" vérifie que le comportement reste correct avec l'ajout de nouveaux attributs """
attr_trees = 'trees'
for choice in DecisionChoices:
self.assertIsInstance(choice.label, str, f"{choice} : le libellé n'a pas le bon type")
self.assertIsInstance(choice.value, str, f"{choice} : la valeur n'a pas le bon type")
self.assertEqual(choice.value, choice, f"{choice} : n'est pas égal à sa valeur")
self.assertIsInstance(getattr(choice, attr_trees), tuple, f"{choice} : l'attribut {attr_trees} n'a pas le bon type")
def test_champ_decisions(self):
""" vérifie la structure de DECISIONS """
to_test = DECISIONS
self.assertIsInstance(to_test, dict, "la structure n'a pas le type attendu")
self.assertTrue(to_test, "la structure ne doit pas être vide")
for key, value in to_test.items():
self.assertTrue(key is None or isinstance(key, DecisionChoices), f"la décision {key} n'a pas le type attendu")
self.assertIsInstance(value, dict, f"la valeur pour la décision {key} n'a pas le type attendu")
profiles = value.get(KEY_PROFILES)
self.assertTrue(profiles is None or isinstance(profiles, tuple), f"la valeur de {KEY_PROFILES} de la valeur pour la décision {key} n'a pas le type attendu")
for p in profiles:
self.assertIsInstance(p, Profiles, f"un élément de la clé {KEY_PROFILES} de la valeur pour la décision {key} n'a pas le type attendu")
choices = value.get(KEY_CHOICES)
self.assertTrue(choices is None or isinstance(choices, tuple), f"la valeur de {KEY_CHOICES} de la valeur pour la décision {key} n'a pas le type attendu")
for c in choices:
self.assertIsInstance(c, (DecisionChoices, ExtraDecisions), f"un élément de la clé {KEY_CHOICES} de la valeur pour la décision {key} n'a pas le type attendu")
def test_get_all_decisions(self):
""" vérifie les valeurs de get_all_decisions """
to_test = get_all_decisions()
self.assertIsInstance(to_test, tuple, "le résultat n'a pas le type attendu")
self.assertTrue(to_test, "le résultat ne doit pas être vide")
for value in to_test:
self.assertIsInstance(value, DecisionChoices, f"la valeur {value} n'a pas le type attendu")
def test_pam_wihout_choice(self):
""" pour ces statuts PAM il n'y a aucun choix """
user = CustomUser()
self.adm_ids = tuple(a.a_id_sap for a in (
Administre.objects.create(pk=i + 1, a_statut_pam=status) for i, status in enumerate(StatutPam) if not status.dec_enabled
))
def action(_p, _d):
decisions_by_adm = get_available_decisions(self.__load_administres(), user=user)
self.__assert_common(decisions_by_adm)
for adm_id in self.adm_ids:
decisions = decisions_by_adm.get(adm_id)
self.assertFalse(decisions.get(KEY_CREATE))
self.assertFalse(decisions.get(KEY_UPDATE))
self.__do_for_profiles(action, profiles=tuple(Profiles))
def test_pam_with_choices(self):
""" pour ces statuts PAM c'est l'arbre de décision qui est utilisé """
user = CustomUser()
self.adm_ids = tuple(a.a_id_sap for a in (
Administre.objects.create(pk=i + 1, a_statut_pam=status) for i, status in enumerate(StatutPam) if status.dec_enabled
))
D = DecisionChoices
EX = ExtraDecisions
def action(p, d):
decisions_by_adm = get_available_decisions(self.__load_administres(), user=user)
self.__assert_common(decisions_by_adm)
for adm_id in self.adm_ids:
decisions = decisions_by_adm.get(adm_id)
# create
decisions_create = decisions.get(KEY_CREATE)
if p == Profiles.FILIERE:
self.assertCountEqual(decisions_create, (D.PROPOSITION_FE, D.HME_PROPOSITION_VIVIER))
else:
self.assertFalse(decisions_create)
# update
decisions_update = decisions.get(KEY_UPDATE)
if not d and p == Profiles.FILIERE:
self.assertCountEqual(decisions_update, (D.PROPOSITION_FE, D.HME_PROPOSITION_VIVIER))
elif d == D.PROPOSITION_FE and p in (Profiles.PCP, Profiles.PCP_ACTUEL):
self.assertCountEqual(decisions_update, (D.DIALOGUE_EN_COURS, D.FOREMP_EN_COURS))
elif d == D.DIALOGUE_EN_COURS and p in (Profiles.PCP, Profiles.PCP_ACTUEL):
self.assertCountEqual(decisions_update, (D.DIALOGUE_TERMINE, D.DIALOGUE_INFRUCTUEUX))
elif d == D.DIALOGUE_TERMINE and p in (Profiles.PCP, Profiles.PCP_ACTUEL):
self.assertCountEqual(decisions_update, (D.FOREMP_EN_COURS,))
elif d == D.DIALOGUE_INFRUCTUEUX and p in (Profiles.PCP, Profiles.PCP_ACTUEL):
self.assertCountEqual(decisions_update, (D.FOREMP_EN_COURS, D.REMIS_A_DISPOSITION))
elif d == D.FOREMP_EN_COURS and p in (Profiles.PCP, Profiles.PCP_ACTUEL):
self.assertCountEqual(decisions_update, (D.FOREMP_TERMINE,))
elif d == D.FOREMP_TERMINE and p in (Profiles.PCP, Profiles.PCP_ACTUEL):
self.assertCountEqual(decisions_update, (D.PREPOSITIONNE, D.REMIS_A_DISPOSITION))
elif d == D.PREPOSITIONNE and p in (Profiles.PCP, Profiles.PCP_FUTUR):
self.assertCountEqual(decisions_update, (D.POSITIONNE, D.REMIS_A_DISPOSITION))
elif d == D.POSITIONNE and p in (Profiles.PCP, Profiles.PCP_FUTUR):
self.assertCountEqual(decisions_update, (D.OMIP_EN_COURS, D.OMI_EN_COURS, D.REMIS_A_DISPOSITION))
elif d == D.OMIP_EN_COURS and p in (Profiles.PCP, Profiles.PCP_FUTUR):
self.assertCountEqual(decisions_update, (D.OMIP_TERMINE, D.REMIS_A_DISPOSITION))
elif d == D.OMIP_TERMINE and p in (Profiles.PCP, Profiles.PCP_FUTUR):
self.assertCountEqual(decisions_update, (D.ATTENTE_AVIONAGE, D.OMI_EN_COURS, D.REMIS_A_DISPOSITION))
elif d == D.ATTENTE_AVIONAGE and p in (Profiles.PCP, Profiles.PCP_FUTUR):
self.assertCountEqual(decisions_update, (D.OMI_EN_COURS,))
elif d == D.OMI_EN_COURS and p in (Profiles.PCP, Profiles.PCP_FUTUR):
self.assertCountEqual(decisions_update, (D.OMI_ACTIVE, D.REMIS_A_DISPOSITION))
elif d == D.OMI_ACTIVE and p in (Profiles.PCP, Profiles.PCP_FUTUR):
self.assertCountEqual(decisions_update, (D.OMI_ANNULE,))
elif d == D.OMI_ANNULE and p in (Profiles.PCP, Profiles.PCP_FUTUR):
self.assertCountEqual(decisions_update, (D.REMIS_A_DISPOSITION,))
elif d == D.REMIS_A_DISPOSITION and p == Profiles.FILIERE:
self.assertCountEqual(decisions_update, (EX.EMPTY,))
elif d == D.HME_PROPOSITION_VIVIER and p in (Profiles.PCP, Profiles.PCP_ACTUEL, Profiles.PCP_FUTUR):
self.assertCountEqual(decisions_update, (D.HME_DIALOGUE_INITIE,))
elif d == D.HME_ETUDE_DESISTEMENT and p in (Profiles.PCP, Profiles.PCP_ACTUEL, Profiles.PCP_FUTUR):
self.assertCountEqual(decisions_update, (D.HME_DESISTEMENT,))
elif d == D.HME_DESISTEMENT and p in (Profiles.PCP, Profiles.PCP_ACTUEL, Profiles.PCP_FUTUR):
self.assertCountEqual(decisions_update, (D.REMIS_A_DISPOSITION,))
elif d == D.HME_DIALOGUE_INITIE and p in (Profiles.PCP, Profiles.PCP_ACTUEL, Profiles.PCP_FUTUR):
self.assertCountEqual(decisions_update, (D.HME_DIALOGUE_EN_COURS,))
elif d == D.HME_DIALOGUE_EN_COURS and p in (Profiles.PCP, Profiles.PCP_ACTUEL, Profiles.PCP_FUTUR):
self.assertCountEqual(decisions_update, (D.HME_DIALOGUE_TERMINE, D.HME_DIALOGUE_INFRUCTUEUX))
elif d == D.HME_DIALOGUE_TERMINE and p in (Profiles.PCP, Profiles.PCP_ACTUEL, Profiles.PCP_FUTUR):
self.assertCountEqual(decisions_update, (D.HME_PREPOSITIONNE,))
elif d == D.HME_DIALOGUE_INFRUCTUEUX and p in (Profiles.PCP, Profiles.PCP_ACTUEL, Profiles.PCP_FUTUR):
self.assertCountEqual(decisions_update, (D.HME_ETUDE_DESISTEMENT, D.HME_PREPOSITIONNE, D.REMIS_A_DISPOSITION))
elif d == D.HME_FOREMP_EN_COURS and p in (Profiles.PCP, Profiles.PCP_ACTUEL, Profiles.PCP_FUTUR):
self.assertCountEqual(decisions_update, (D.HME_FOREMP_TERMINE, D.HME_OMI_EN_COURS))
elif d == D.HME_FOREMP_TERMINE and p in (Profiles.PCP, Profiles.PCP_ACTUEL, Profiles.PCP_FUTUR):
self.assertCountEqual(decisions_update, (D.HME_OMIP_EN_COURS, D.HME_OMI_EN_COURS))
elif d == D.HME_PREPOSITIONNE and p == Profiles.HME:
self.assertCountEqual(decisions_update, (D.HME_VALIDATION_EXPERT, D.HME_REFUS_EXPERT))
elif d == D.HME_POSITIONNE and p in (Profiles.PCP, Profiles.PCP_ACTUEL, Profiles.PCP_FUTUR):
self.assertCountEqual(decisions_update, (D.HME_OMIP_EN_COURS, D.HME_OMI_EN_COURS, D.HME_FOREMP_EN_COURS))
elif d == D.HME_VALIDATION_EXPERT and p in (Profiles.PCP, Profiles.PCP_ACTUEL, Profiles.PCP_FUTUR):
self.assertCountEqual(decisions_update, (D.HME_POSITIONNE,))
elif d == D.HME_REFUS_EXPERT and p in (Profiles.PCP, Profiles.PCP_ACTUEL, Profiles.PCP_FUTUR):
self.assertCountEqual(decisions_update, (D.HME_PREPOSITIONNE, D.REMIS_A_DISPOSITION))
elif d == D.HME_OMIP_EN_COURS and p in (Profiles.PCP, Profiles.PCP_ACTUEL, Profiles.PCP_FUTUR):
self.assertCountEqual(decisions_update, (D.HME_OMIP_TERMINE,))
elif d == D.HME_OMIP_TERMINE and p in (Profiles.PCP, Profiles.PCP_ACTUEL, Profiles.PCP_FUTUR):
self.assertCountEqual(decisions_update, (D.HME_ATTENTE_AVIONAGE, D.HME_OMI_EN_COURS))
elif d == D.HME_ATTENTE_AVIONAGE and p in (Profiles.PCP, Profiles.PCP_ACTUEL, Profiles.PCP_FUTUR):
self.assertCountEqual(decisions_update, (D.HME_OMI_EN_COURS,))
elif d == D.HME_OMI_EN_COURS and p in (Profiles.PCP, Profiles.PCP_ACTUEL, Profiles.PCP_FUTUR):
self.assertCountEqual(decisions_update, (D.HME_OMI_ACTIVE,))
elif d == D.HME_OMI_ACTIVE and p in (Profiles.PCP, Profiles.PCP_ACTUEL, Profiles.PCP_FUTUR):
self.assertCountEqual(decisions_update, ())
else:
self.assertFalse(decisions_update)
self.__do_for_profiles(action, profiles=tuple(Profiles), decisions=(EX.EMPTY, *get_all_decisions()))

View File

@@ -0,0 +1,85 @@
from .samples import MyClass
from ...utils.decorators import class_logger, decorate_functions, CLASS_ATTR_LOGGER
from ...utils.functions import find_class
from ...utils.logging import get_logger_name
from ...utils.predicates import func_name_is_in
from django.test import SimpleTestCase
from typing import Tuple
import functools
def double_result(func):
""" décorateur pour doubler les résultats """
@functools.wraps(func)
def inner(*args, **kwargs):
return 2 * func(*args, **kwargs)
return inner
class DecoratorTest(SimpleTestCase):
def test_decorate_functions(self):
num = 5
a = 1
b = 2
res = a + b
res_x2 = res * 2
def given():
msg = 'le résultat initial est bien celui attendu'
self.assertEqual(MyClass.class_met(a, b), res, msg)
self.assertEqual(MyClass.static_met(a, b), res, msg)
self.assertEqual(MyClass(num).std_met(a, b), res, msg)
given()
# tout est décoré
Type = decorate_functions(double_result, lambda func: True)(MyClass)
self.assertEqual(Type.class_met(a, b), res_x2)
self.assertEqual(Type.static_met(a, b), res_x2)
self.assertEqual(Type(num).std_met(a, b), res_x2)
# une seule méthode est décorée (1ère)
Type = decorate_functions(double_result, func_name_is_in(MyClass.class_met.__name__,))(MyClass)
self.assertEqual(Type.class_met(a, b), res_x2)
self.assertEqual(Type.static_met(a, b), res)
self.assertEqual(Type(num).std_met(a, b), res)
# une seule méthode est décorée (2ème)
Type = decorate_functions(double_result, func_name_is_in(MyClass.static_met.__name__,))(MyClass)
self.assertEqual(Type.class_met(a, b), res)
self.assertEqual(Type.static_met(a, b), res_x2)
self.assertEqual(Type(num).std_met(a, b), res)
# une seule méthode est décorée (3ème)
Type = decorate_functions(double_result, func_name_is_in(MyClass.std_met.__name__,))(MyClass)
self.assertEqual(Type.class_met(a, b), res)
self.assertEqual(Type.static_met(a, b), res)
self.assertEqual(Type(num).std_met(a, b), res_x2)
# une seule méthode est décorée deux fois (3ème)
Type = decorate_functions(double_result, func_name_is_in(MyClass.std_met.__name__,))(Type)
self.assertEqual(Type.class_met(a, b), res)
self.assertEqual(Type.static_met(a, b), res)
self.assertEqual(Type(num).std_met(a, b), 2 * res_x2)
# pas de changement au niveau de la classe d'origine
self.assertEqual(MyClass.class_met(a, b), res)
self.assertEqual(MyClass.static_met(a, b), res)
self.assertEqual(MyClass(num).std_met(a, b), res)
def test_class_logger(self):
def given():
self.assertEqual(hasattr(MyClass, CLASS_ATTR_LOGGER), False, "la classe initiale n'a pas de logger")
given()
Type = class_logger(MyClass)
self.assertEqual(hasattr(Type, CLASS_ATTR_LOGGER), True)
self.assertEqual(getattr(Type, CLASS_ATTR_LOGGER).name, get_logger_name(MyClass))
# 2ème décoration
Type = class_logger(Type)
self.assertEqual(hasattr(Type, CLASS_ATTR_LOGGER), True)
self.assertEqual(getattr(Type, CLASS_ATTR_LOGGER).name, get_logger_name(MyClass))
# pas de changement au niveau de la classe d'origine
self.assertEqual(hasattr(MyClass, CLASS_ATTR_LOGGER), False)

View File

@@ -0,0 +1,30 @@
from .samples import my_func, MyClass
from ...utils.functions import find_class
from django.test import SimpleTestCase
class FunctionsTest(SimpleTestCase):
def test_find_class(self):
MainType = MyClass
main_type = MainType(11)
SubType = MyClass.MySubClass
sub_type = SubType(13)
def local_func(a: int, b: int):
return a + b
# fonction native : None
self.assertIsNone(find_class(str.join))
# fonctions : None
self.assertIsNone(find_class(local_func))
self.assertIsNone(find_class(my_func))
# méthodes
self.assertEqual(find_class(MainType.class_met), MainType)
self.assertEqual(find_class(MainType.static_met), MainType)
self.assertEqual(find_class(main_type.std_met), MainType)
self.assertEqual(find_class(SubType.sub_class_met), SubType)
self.assertEqual(find_class(SubType.sub_static_met), SubType)
self.assertEqual(find_class(sub_type.sub_std_met), SubType)

View File

@@ -0,0 +1,104 @@
import random
import string
from unittest import mock
from django.test import SimpleTestCase
from ...utils.logging import (TAG_DATA_FEED, TAG_PERF, get_logger,
get_logger_name)
from .samples import MyClass, my_func
class LoggingTest(SimpleTestCase):
def test_get_logger_name(self):
module_name = __name__
ext_module_name = my_func.__module__
MainType = MyClass
main_type = MainType(11)
main_type_logger = f'{ext_module_name}.{MainType.__qualname__}'
SubType = MyClass.MySubClass
sub_type = SubType(13)
sub_type_logger = f'{ext_module_name}.{SubType.__qualname__}'
def local_func(a: int, b: int):
return a + b
# None
self.assertIsNone(get_logger_name())
self.assertIsNone(get_logger_name(None))
# classes natives
self.assertIsNone(get_logger_name(str))
self.assertIsNone(get_logger_name(int))
self.assertIsNone(get_logger_name(dict))
self.assertIsNone(get_logger_name(list))
self.assertIsNone(get_logger_name(tuple))
# instances de classes natives (mais pas str)
self.assertIsNone(get_logger_name(1))
self.assertIsNone(get_logger_name({'a': 'b'}))
self.assertIsNone(get_logger_name(['c']))
self.assertIsNone(get_logger_name(('d',)))
# fonctions natives
self.assertIsNone(get_logger_name(str.join))
# str
self.assertEqual(get_logger_name('test'), 'test')
self.assertEqual(get_logger_name(''), None)
# classes
self.assertEqual(get_logger_name(MainType), main_type_logger)
self.assertEqual(get_logger_name(SubType), sub_type_logger)
# instances de classes
self.assertEqual(get_logger_name(main_type), main_type_logger)
self.assertEqual(get_logger_name(sub_type), sub_type_logger)
# fonctions et méthodes
self.assertEqual(get_logger_name(local_func), module_name)
self.assertEqual(get_logger_name(my_func), ext_module_name)
self.assertEqual(get_logger_name(MainType.class_met), main_type_logger)
self.assertEqual(get_logger_name(MainType.static_met), main_type_logger)
self.assertEqual(get_logger_name(main_type.std_met), main_type_logger)
self.assertEqual(get_logger_name(SubType.sub_class_met), sub_type_logger)
self.assertEqual(get_logger_name(SubType.sub_static_met), sub_type_logger)
self.assertEqual(get_logger_name(sub_type.sub_std_met), sub_type_logger)
def test_get_logger_without_tags(self):
func_1 = MyClass.class_met
func_2 = MyClass.static_met
def given():
self.assertEqual(get_logger_name(func_1), get_logger_name(func_2), 'le nom de logger doit être le même')
given()
msg = "l'instance doit être la même"
logger_name = ''.join(random.choice(string.ascii_lowercase) for i in range(10))
self.assertIs(get_logger(logger_name), get_logger(logger_name), msg)
self.assertIs(get_logger(func_1), get_logger(func_2), msg)
def test_get_logger_with_tags(self):
func_1 = MyClass.class_met
func_2 = MyClass.static_met
def given():
self.assertEqual(get_logger_name(func_1), get_logger_name(func_2), 'le nom de logger doit être le même')
given()
msg = "l'instance doit être la même"
for tags in [TAG_PERF, TAG_DATA_FEED, ('1', '2'), ['3', '4'], set(['5', '6'])]:
with self.subTest(tags=tags):
logger_name = ''.join(random.choice(string.ascii_lowercase) for i in range(10))
self.assertIs(get_logger(logger_name, tags), get_logger(logger_name, tags), msg)
self.assertIs(get_logger(func_1, tags), get_logger(func_2, tags), msg)
prev_logger = None
logger_name = ''.join(random.choice(string.ascii_lowercase) for i in range(10))
for i, tags in enumerate([('1', '2', '3', '4'), ['3', '4', '1', '2'], set(['2', '1', '3', '4', '1'])]):
curr_logger = get_logger(logger_name, tags)
if i > 0:
self.assertIs(curr_logger, prev_logger, msg)
prev_logger = get_logger(logger_name, tags)

View File

@@ -0,0 +1,127 @@
from .samples import my_func, _my_private_func, MyClass
from ...utils.predicates import func_class_name_is_in, func_class_name_is_not_in, func_name_is_in, func_name_is_not_in, func_is_public
from django.test import SimpleTestCase
class PredicatesTest(SimpleTestCase):
def __test_func_class_name_is_in(self, negation: bool = False):
""" teste func_class_name_is_in et func_class_name_is_not_in """
func = func_class_name_is_not_in if negation else func_class_name_is_in
result = negation is not True
own_name = self.__class__.__name__
MainType = MyClass
main_type = MainType(11)
main_type_name = MainType.__name__
SubType = MyClass.MySubClass
sub_type = SubType(13)
sub_type_name = SubType.__name__
def local_func(a: int, b: int):
return a + b
# fonction native : None
self.assertEqual(func(str.__name__)(str.join), False)
# fonction locale : None
self.assertEqual(func(own_name)(local_func), False)
# méthodes
predicate = func(main_type_name)
self.assertEqual(predicate(MainType.class_met), result)
self.assertEqual(predicate(MainType.static_met), result)
self.assertEqual(predicate(main_type.std_met), result)
self.assertEqual(predicate(SubType.sub_class_met), not result)
self.assertEqual(predicate(SubType.sub_static_met), not result)
self.assertEqual(predicate(sub_type.sub_std_met), not result)
predicate = func(sub_type_name)
self.assertEqual(predicate(MainType.class_met), not result)
self.assertEqual(predicate(MainType.static_met), not result)
self.assertEqual(predicate(main_type.std_met), not result)
self.assertEqual(predicate(SubType.sub_class_met), result)
self.assertEqual(predicate(SubType.sub_static_met), result)
self.assertEqual(predicate(sub_type.sub_std_met), result)
def __test_func_name_is_in(self, negation: bool = False):
""" teste func_name_is_in et func_name_is_not_in """
func = func_name_is_not_in if negation else func_name_is_in
result = negation is not True
MainType = MyClass
main_type = MainType(11)
SubType = MyClass.MySubClass
sub_type = SubType(13)
def local_func(a: int, b: int):
return a + b
# fonction native
self.assertEqual(func('join')(str.join), result)
self.assertEqual(func('other', 'join')(str.join), result)
# autre fonction, fonction locale
self.assertEqual(func('local_func')(local_func), result)
self.assertEqual(func('other', 'local_func')(local_func), result)
self.assertEqual(func('my_func')(my_func), result)
self.assertEqual(func('other', 'my_func')(my_func), result)
# méthodes
predicate = func('class_met', 'std_met', 'sub_static_met')
self.assertEqual(predicate(MainType.class_met), result)
self.assertEqual(predicate(MainType.static_met), not result)
self.assertEqual(predicate(main_type.std_met), result)
self.assertEqual(predicate(SubType.sub_class_met), not result)
self.assertEqual(predicate(SubType.sub_static_met), result)
self.assertEqual(predicate(sub_type.sub_std_met), not result)
predicate = func('static_met', 'sub_class_met', 'sub_std_met')
self.assertEqual(predicate(MainType.class_met), not result)
self.assertEqual(predicate(MainType.static_met), result)
self.assertEqual(predicate(main_type.std_met), not result)
self.assertEqual(predicate(SubType.sub_class_met), result)
self.assertEqual(predicate(SubType.sub_static_met), not result)
self.assertEqual(predicate(sub_type.sub_std_met), result)
def test_func_class_name_is_in(self):
self.__test_func_class_name_is_in()
def test_func_class_name_is_not_in(self):
self.__test_func_class_name_is_in(negation=True)
def test_func_name_is_in(self):
self.__test_func_name_is_in()
def test_func_name_is_not_in(self):
self.__test_func_name_is_in(negation=True)
def test_func_is_public(self):
MainType = MyClass
main_type = MainType(11)
SubType = MyClass.MySubClass
sub_type = SubType(13)
def local_func(a: int, b: int):
return a + b
# fonction native
self.assertEqual(func_is_public(str.join), True)
# autre fonction, fonction locale
self.assertEqual(func_is_public(local_func), True)
self.assertEqual(func_is_public(my_func), True)
self.assertEqual(func_is_public(_my_private_func), False)
# méthodes
self.assertEqual(func_is_public(MainType._protected_met), False)
self.assertEqual(func_is_public(MainType.class_met), True)
self.assertEqual(func_is_public(MainType.static_met), True)
self.assertEqual(func_is_public(main_type.std_met), True)
self.assertEqual(func_is_public(SubType.sub_class_met), True)
self.assertEqual(func_is_public(SubType.sub_static_met), True)
self.assertEqual(func_is_public(sub_type.sub_std_met), True)

View File

@@ -0,0 +1,58 @@
# quelques définitions pour les tests ==>
def my_func(a: int, b: int):
""" fonction sans classe """
return a + b
def _my_private_func(a: int, b: int):
""" fonction sans classe (non importée par défaut avec import *) """
return a + b
class MyClass():
""" classe pour tests """
num = None
def __init__(self, num):
""" la classe est paramétrée """
self.num = num
def _protected_met(self, a: int, b: int):
""" méthode standard (protected par convention) """
return a + b
class MySubClass():
sub_num = None
def __init__(self, num):
""" la classe est paramétrée """
self.sub_num = num
@classmethod
def sub_class_met(cls):
""" méthode de classe """
return True
@staticmethod
def sub_static_met():
""" méthode statique """
return True
def sub_std_met():
""" méthode standard """
return True
@classmethod
def class_met(cls, a: int, b: int):
""" méthode de classe """
return a + b
@staticmethod
def static_met(a: int, b: int):
""" méthode statique """
return a + b
def std_met(self, a: int, b: int):
""" méthode standard """
return a + b