diff --git a/net/xeaf/rack/core/__init__.py b/net/xeaf/rack/core/__init__.py index ceee9ef..cb614a1 100644 --- a/net/xeaf/rack/core/__init__.py +++ b/net/xeaf/rack/core/__init__.py @@ -8,4 +8,5 @@ Пакет базовых классов """ +from .core_enum import CoreEnum from .core_test_case import CoreTestCase diff --git a/net/xeaf/rack/core/core_enum.py b/net/xeaf/rack/core/core_enum.py new file mode 100644 index 0000000..f94ea55 --- /dev/null +++ b/net/xeaf/rack/core/core_enum.py @@ -0,0 +1,47 @@ +# DRF Rack +# Библиотека классов расширений для Django REST Framework +# +# Автор: Николай В. Анохин +# Все права защищены. Лицензия: MIT + +""" +Описание класса CoreEnum +""" + +from enum import StrEnum + + +class CoreEnum(StrEnum): + """ + Реализует базовые методы для классов перечислений + """ + + @classmethod + def choices(cls) -> list[tuple[str, str]]: + """ + Возвращает список для организации выбора значения + + :return: Список для выбора значения + """ + + return [(item.value, item.name) for item in cls] + + @classmethod + def keys(cls) -> list[str]: + """ + Возвращает список ключей + + :return: Список ключей + """ + + return [item.name for item in cls] + + @classmethod + def values(cls) -> list[str]: + """ + Возвращает список значений + + :return: Список значений + """ + + return [item.value for item in cls] diff --git a/net/xeaf/rack/enums/__init__.py b/net/xeaf/rack/enums/__init__.py new file mode 100644 index 0000000..d046872 --- /dev/null +++ b/net/xeaf/rack/enums/__init__.py @@ -0,0 +1,11 @@ +# DRF Rack +# Библиотека классов расширений для Django REST Framework +# +# Автор: Николай В. Анохин +# Все права защищены. Лицензия: MIT + +""" +Пакет описания классов перечислений +""" + +from .ui_language import UILanguage diff --git a/net/xeaf/rack/enums/ui_language.py b/net/xeaf/rack/enums/ui_language.py new file mode 100644 index 0000000..e63216a --- /dev/null +++ b/net/xeaf/rack/enums/ui_language.py @@ -0,0 +1,23 @@ +# DRF Rack +# Библиотека классов расширений для Django REST Framework +# +# Автор: Николай В. Анохин +# Все права защищены. Лицензия: MIT + +""" +Описание класса UILanguage +""" + +from net.xeaf.rack.core import CoreEnum + + +class UILanguage(CoreEnum): + """ + Перечисление доступных языков интерфейса + """ + + ENGLISH = 'en' + """ Английский """ + + RUSSIAN = 'ru' + """ Русский """ diff --git a/net/xeaf/rack/tests/core/__init__.py b/net/xeaf/rack/tests/core/__init__.py new file mode 100644 index 0000000..5a6a1f4 --- /dev/null +++ b/net/xeaf/rack/tests/core/__init__.py @@ -0,0 +1,12 @@ +# DRF Rack +# Библиотека классов расширений для Django REST Framework +# +# Автор: Николай В. Анохин +# Все права защищены. Лицензия: MIT + +""" +Пакет описания тестов для базовых классов +""" + +from .core_enum_tests import CoreEnumTests + diff --git a/net/xeaf/rack/tests/core/core_enum_tests.py b/net/xeaf/rack/tests/core/core_enum_tests.py new file mode 100644 index 0000000..0162b00 --- /dev/null +++ b/net/xeaf/rack/tests/core/core_enum_tests.py @@ -0,0 +1,233 @@ +# DRF Rack +# Библиотека классов расширений для Django REST Framework +# +# Автор: Николай В. Анохин +# Все права защищены. Лицензия: MIT + +""" +Описание класса CoreEnumTests +""" + +from net.xeaf.rack.core import CoreEnum +from net.xeaf.rack.core import CoreTestCase + + +class TestColorEnum(CoreEnum): + """ + Тестовое перечисление для проверки + """ + + RED = "red" + GREEN = "green" + BLUE = "blue" + + +class TestStatusEnum(CoreEnum): + """ + Еще одно тестовое перечисление + """ + + ACTIVE = "active" + INACTIVE = "inactive" + PENDING = "pending" + + +class TestEmptyEnum(CoreEnum): + """ + Пустое перечисление для граничных случаев + """ + + pass + + +class CoreEnumTests(CoreTestCase): + """ + Тесты для класса CoreEnum + """ + + def test_choices_returns_list_of_tuples(self): + """ + Проверяет, что choices() возвращает список кортежей (value, name) + """ + + expected = [ + ("red", "RED"), + ("green", "GREEN"), + ("blue", "BLUE"), + ] + self.assertEqual(TestColorEnum.choices(), expected) + + def test_choices_contains_all_members(self): + """ + Проверяет, что choices() содержит все элементы перечисления + """ + + choices = TestColorEnum.choices() + self.assertEqual(len(choices), 3) + self.assertIn(("red", "RED"), choices) + self.assertIn(("green", "GREEN"), choices) + self.assertIn(("blue", "BLUE"), choices) + + def test_choices_order_matches_definition(self): + """ + Проверяет, что порядок элементов сохраняется + """ + + choices = TestColorEnum.choices() + self.assertEqual(choices[0][0], "red") + self.assertEqual(choices[1][0], "green") + self.assertEqual(choices[2][0], "blue") + + def test_keys_returns_list_of_names(self): + """ + Проверяет, что keys() возвращает список имен + """ + + expected = ["RED", "GREEN", "BLUE"] + self.assertEqual(TestColorEnum.keys(), expected) + + def test_keys_contains_all_names(self): + """ + Проверяет, что keys() содержит все имена элементов + """ + + keys = TestColorEnum.keys() + self.assertEqual(len(keys), 3) + self.assertIn("RED", keys) + self.assertIn("GREEN", keys) + self.assertIn("BLUE", keys) + + def test_values_returns_list_of_values(self): + """ + Проверяет, что values() возвращает список значений + """ + + expected = ["red", "green", "blue"] + self.assertEqual(TestColorEnum.values(), expected) + + def test_values_contains_all_values(self): + """ + Проверяет, что values() содержит все значения элементов + """ + + values = TestColorEnum.values() + self.assertEqual(len(values), 3) + self.assertIn("red", values) + self.assertIn("green", values) + self.assertIn("blue", values) + + def test_choices_with_different_enum(self): + """ + Проверяет работу choices() с другим перечислением + """ + + expected = [ + ("active", "ACTIVE"), + ("inactive", "INACTIVE"), + ("pending", "PENDING"), + ] + self.assertEqual(TestStatusEnum.choices(), expected) + + def test_keys_with_different_enum(self): + """ + Проверяет работу keys() с другим перечислением + """ + + expected = ["ACTIVE", "INACTIVE", "PENDING"] + self.assertEqual(TestStatusEnum.keys(), expected) + + def test_values_with_different_enum(self): + """ + Проверяет работу values() с другим перечислением + """ + + expected = ["active", "inactive", "pending"] + self.assertEqual(TestStatusEnum.values(), expected) + + def test_empty_enum_choices(self): + """ + Проверяет поведение choices() для пустого перечисления + """ + + self.assertEqual(TestEmptyEnum.choices(), []) + + def test_empty_enum_keys(self): + """ + Проверяет поведение keys() для пустого перечисления + """ + + self.assertEqual(TestEmptyEnum.keys(), []) + + def test_empty_enum_values(self): + """ + Проверяет поведение values() для пустого перечисления + """ + + self.assertEqual(TestEmptyEnum.values(), []) + + def test_choices_returns_different_type(self): + """ + Проверяет, что choices() возвращает list, а не tuple + """ + + self.assertIsInstance(TestColorEnum.choices(), list) + self.assertIsInstance(TestColorEnum.choices()[0], tuple) + + def test_keys_returns_list(self): + """ + Проверяет, что keys() возвращает list + """ + + self.assertIsInstance(TestColorEnum.keys(), list) + + def test_values_returns_list(self): + """ + Проверяет, что values() возвращает list + """ + + self.assertIsInstance(TestColorEnum.values(), list) + + def test_choices_values_match(self): + """ + Проверяет согласованность choices() и values() + """ + + choices_values = [choice[0] for choice in TestColorEnum.choices()] + self.assertEqual(choices_values, TestColorEnum.values()) + + def test_choices_keys_match(self): + """ + Проверяет согласованность choices() и keys() + """ + + choices_keys = [choice[1] for choice in TestColorEnum.choices()] + self.assertEqual(choices_keys, TestColorEnum.keys()) + + def test_keys_and_values_length_match(self): + """ + Проверяет, что keys() и values() имеют одинаковую длину + """ + + self.assertEqual(len(TestColorEnum.keys()), len(TestColorEnum.values())) + + def test_choices_length_matches_members(self): + """ + Проверяет, что количество choices совпадает с количеством элементов + """ + + self.assertEqual(len(TestColorEnum.choices()), len(TestColorEnum.__members__)) + + def test_all_elements_are_strings(self): + """ + Проверяет, что все значения являются строками (StrEnum) + """ + + for value in TestColorEnum.values(): + self.assertIsInstance(value, str) + + for key in TestColorEnum.keys(): + self.assertIsInstance(key, str) + + for choice in TestColorEnum.choices(): + self.assertIsInstance(choice[0], str) + self.assertIsInstance(choice[1], str) diff --git a/net/xeaf/rack/tests/enums/__init__.py b/net/xeaf/rack/tests/enums/__init__.py new file mode 100644 index 0000000..1893610 --- /dev/null +++ b/net/xeaf/rack/tests/enums/__init__.py @@ -0,0 +1,11 @@ +# DRF Rack +# Библиотека классов расширений для Django REST Framework +# +# Автор: Николай В. Анохин +# Все права защищены. Лицензия: MIT + +""" +Пакет описания тестов для классов перечислений +""" + +from .ui_language_tests import * diff --git a/net/xeaf/rack/tests/enums/ui_language_tests.py b/net/xeaf/rack/tests/enums/ui_language_tests.py new file mode 100644 index 0000000..55a1512 --- /dev/null +++ b/net/xeaf/rack/tests/enums/ui_language_tests.py @@ -0,0 +1,36 @@ +# DRF Rack +# Библиотека классов расширений для Django REST Framework +# +# Автор: Николай В. Анохин +# Все права защищены. Лицензия: MIT + +""" +Описание класса UILanguageTests +""" + +from django.test import TestCase + +from net.xeaf.rack.enums import UILanguage + + +class UILanguageTest(TestCase): + """ + Тесты для перечисления UILanguage + """ + + def test_has_expected_values(self): + """ + Проверяем, что в enum есть ожидаемые языки + """ + + expected = {"en", "ru"} + self.assertEqual(set(UILanguage.values()), expected) + + def test_values_format(self): + """ + Проверяем формат значений + """ + + for code in UILanguage.values(): + self.assertEqual(len(code), 2) + self.assertTrue(code.islower()) diff --git a/net/xeaf/rack/tests/util/__init__.py b/net/xeaf/rack/tests/utils/__init__.py similarity index 70% rename from net/xeaf/rack/tests/util/__init__.py rename to net/xeaf/rack/tests/utils/__init__.py index 44dbc4d..1228f12 100644 --- a/net/xeaf/rack/tests/util/__init__.py +++ b/net/xeaf/rack/tests/utils/__init__.py @@ -5,7 +5,7 @@ # Все права защищены. Лицензия: MIT """ -Пакет описания классов тестов для служебных классов и утилит +Пакет описания тестов для служебных классов и утилит """ from .crypto_tests import CryptoTests \ No newline at end of file diff --git a/net/xeaf/rack/tests/util/crypto_tests.py b/net/xeaf/rack/tests/utils/crypto_tests.py similarity index 97% rename from net/xeaf/rack/tests/util/crypto_tests.py rename to net/xeaf/rack/tests/utils/crypto_tests.py index 3b9b9b4..22d3e45 100644 --- a/net/xeaf/rack/tests/util/crypto_tests.py +++ b/net/xeaf/rack/tests/utils/crypto_tests.py @@ -9,12 +9,12 @@ """ from net.xeaf.rack.core import CoreTestCase -from net.xeaf.rack.util import Crypto +from net.xeaf.rack.utils import Crypto class CryptoTests(CoreTestCase): """ - Тесты для Crypto + Тесты для класса Crypto """ def test_gen_token(self): diff --git a/net/xeaf/rack/util/__init__.py b/net/xeaf/rack/utils/__init__.py similarity index 100% rename from net/xeaf/rack/util/__init__.py rename to net/xeaf/rack/utils/__init__.py diff --git a/net/xeaf/rack/util/crypto.py b/net/xeaf/rack/utils/crypto.py similarity index 100% rename from net/xeaf/rack/util/crypto.py rename to net/xeaf/rack/utils/crypto.py diff --git a/net/xeaf/rack/util/settings/__init__.py b/net/xeaf/rack/utils/settings/__init__.py similarity index 100% rename from net/xeaf/rack/util/settings/__init__.py rename to net/xeaf/rack/utils/settings/__init__.py