|
16 | 16 | from django_enum import TextChoices
|
17 | 17 | from django_enum.choices import choices, labels, names, values
|
18 | 18 | from django_enum.forms import EnumChoiceField # dont remove this
|
| 19 | +from django.forms import Form, ModelForm |
19 | 20 | # from django_enum.tests.djenum.enums import (
|
20 | 21 | # BigIntEnum,
|
21 | 22 | # BigPosIntEnum,
|
@@ -414,6 +415,28 @@ def test_basic_save(self):
|
414 | 415 | )
|
415 | 416 | self.MODEL_CLASS.objects.all().delete()
|
416 | 417 |
|
| 418 | + def test_coerce_to_primitive(self): |
| 419 | + |
| 420 | + create_params = { |
| 421 | + **self.create_params, |
| 422 | + 'no_coerce': '32767' |
| 423 | + } |
| 424 | + |
| 425 | + tester = self.MODEL_CLASS.objects.create(**create_params) |
| 426 | + |
| 427 | + self.assertIsInstance(tester.no_coerce, int) |
| 428 | + self.assertEqual(tester.no_coerce, 32767) |
| 429 | + |
| 430 | + def test_coerce_to_primitive_error(self): |
| 431 | + |
| 432 | + create_params = { |
| 433 | + **self.create_params, |
| 434 | + 'no_coerce': 'Value 32767' |
| 435 | + } |
| 436 | + |
| 437 | + with self.assertRaises(ValueError): |
| 438 | + self.MODEL_CLASS.objects.create(**create_params) |
| 439 | + |
417 | 440 | def test_to_python_deferred_attribute(self):
|
418 | 441 | obj = self.MODEL_CLASS.objects.create(**self.create_params)
|
419 | 442 | with self.assertNumQueries(1):
|
@@ -1813,6 +1836,109 @@ def test_bulk_update(self):
|
1813 | 1836 | )
|
1814 | 1837 |
|
1815 | 1838 |
|
| 1839 | +class FormTests(EnumTypeMixin, TestCase): |
| 1840 | + """ |
| 1841 | + Some more explicit form tests that allow easier access to other internal workflows. |
| 1842 | + """ |
| 1843 | + |
| 1844 | + MODEL_CLASS = EnumTester |
| 1845 | + |
| 1846 | + @property |
| 1847 | + def model_form_class(self): |
| 1848 | + |
| 1849 | + class EnumTesterForm(ModelForm): |
| 1850 | + |
| 1851 | + class Meta: |
| 1852 | + model = self.MODEL_CLASS |
| 1853 | + fields = '__all__' |
| 1854 | + |
| 1855 | + return EnumTesterForm |
| 1856 | + |
| 1857 | + @property |
| 1858 | + def basic_form_class(self): |
| 1859 | + from django.core.validators import MinValueValidator, MaxValueValidator |
| 1860 | + |
| 1861 | + class BasicForm(Form): |
| 1862 | + |
| 1863 | + small_pos_int = EnumChoiceField(self.SmallPosIntEnum) |
| 1864 | + small_int = EnumChoiceField(self.SmallIntEnum) |
| 1865 | + pos_int = EnumChoiceField(self.PosIntEnum) |
| 1866 | + int = EnumChoiceField(self.IntEnum) |
| 1867 | + big_pos_int = EnumChoiceField(self.BigPosIntEnum) |
| 1868 | + big_int = EnumChoiceField(self.BigIntEnum) |
| 1869 | + constant = EnumChoiceField(self.Constants) |
| 1870 | + text = EnumChoiceField(self.TextEnum) |
| 1871 | + extern = EnumChoiceField(self.ExternEnum) |
| 1872 | + dj_int_enum = EnumChoiceField(self.DJIntEnum) |
| 1873 | + dj_text_enum = EnumChoiceField(self.DJTextEnum) |
| 1874 | + non_strict_int = EnumChoiceField(self.SmallPosIntEnum, strict=False) |
| 1875 | + non_strict_text = EnumChoiceField(self.TextEnum, strict=False) |
| 1876 | + no_coerce = EnumChoiceField( |
| 1877 | + self.SmallPosIntEnum, |
| 1878 | + validators=[MinValueValidator(0), MaxValueValidator(32767)] |
| 1879 | + ) |
| 1880 | + |
| 1881 | + return BasicForm |
| 1882 | + |
| 1883 | + @property |
| 1884 | + def test_params(self): |
| 1885 | + return { |
| 1886 | + 'small_pos_int': self.SmallPosIntEnum.VAL2, |
| 1887 | + 'small_int': self.SmallIntEnum.VALn1, |
| 1888 | + 'pos_int': self.PosIntEnum.VAL3, |
| 1889 | + 'int': self.IntEnum.VALn1, |
| 1890 | + 'big_pos_int': self.BigPosIntEnum.VAL3, |
| 1891 | + 'big_int': self.BigIntEnum.VAL2, |
| 1892 | + 'constant': self.Constants.GOLDEN_RATIO, |
| 1893 | + 'text': self.TextEnum.VALUE2, |
| 1894 | + 'extern': self.ExternEnum.TWO, |
| 1895 | + 'dj_int_enum': self.DJIntEnum.THREE, |
| 1896 | + 'dj_text_enum': self.DJTextEnum.A, |
| 1897 | + 'non_strict_int': '15', |
| 1898 | + 'non_strict_text': 'arbitrary', |
| 1899 | + 'no_coerce': self.SmallPosIntEnum.VAL3 |
| 1900 | + } |
| 1901 | + |
| 1902 | + @property |
| 1903 | + def test_data_strings(self): |
| 1904 | + return {key: str(value) for key, value in self.test_params.items()} |
| 1905 | + |
| 1906 | + @property |
| 1907 | + def expected(self): |
| 1908 | + return { |
| 1909 | + **self.test_params, |
| 1910 | + 'non_strict_int': int(self.test_params['non_strict_int']), |
| 1911 | + } |
| 1912 | + |
| 1913 | + def test_modelform_binding(self): |
| 1914 | + form = self.model_form_class(data=self.test_data_strings) |
| 1915 | + |
| 1916 | + form.full_clean() |
| 1917 | + self.assertTrue(form.is_valid()) |
| 1918 | + |
| 1919 | + for key, value in self.expected.items(): |
| 1920 | + self.assertEqual(form.cleaned_data[key], value) |
| 1921 | + |
| 1922 | + self.assertIsInstance(form.cleaned_data['no_coerce'], int) |
| 1923 | + self.assertIsInstance(form.cleaned_data['non_strict_int'], int) |
| 1924 | + |
| 1925 | + obj = form.save() |
| 1926 | + |
| 1927 | + for key, value in self.expected.items(): |
| 1928 | + self.assertEqual(getattr(obj, key), value) |
| 1929 | + |
| 1930 | + def test_basicform_binding(self): |
| 1931 | + form = self.basic_form_class(data=self.test_data_strings) |
| 1932 | + form.full_clean() |
| 1933 | + self.assertTrue(form.is_valid()) |
| 1934 | + |
| 1935 | + for key, value in self.expected.items(): |
| 1936 | + self.assertEqual(form.cleaned_data[key], value) |
| 1937 | + |
| 1938 | + self.assertIsInstance(form.cleaned_data['no_coerce'], int) |
| 1939 | + self.assertIsInstance(form.cleaned_data['non_strict_int'], int) |
| 1940 | + |
| 1941 | + |
1816 | 1942 | if ENUM_PROPERTIES_INSTALLED:
|
1817 | 1943 |
|
1818 | 1944 | from django_enum.forms import EnumChoiceField
|
@@ -1843,6 +1969,9 @@ def test_bulk_update(self):
|
1843 | 1969 | )
|
1844 | 1970 | from enum_properties import EnumProperties, s
|
1845 | 1971 |
|
| 1972 | + class EnumPropertiesFormTests(FormTests): |
| 1973 | + |
| 1974 | + MODEL_CLASS = EnumTester |
1846 | 1975 |
|
1847 | 1976 | class TestEnumPropertiesIntegration(TestCase):
|
1848 | 1977 |
|
@@ -3362,6 +3491,22 @@ def test_validate(self):
|
3362 | 3491 | self.assertTrue(tester._meta.get_field('dj_text_enum').validate('A', tester) is None)
|
3363 | 3492 | self.assertTrue(tester._meta.get_field('non_strict_int').validate(20, tester) is None)
|
3364 | 3493 |
|
| 3494 | + def test_coerce_to_primitive_error(self): |
| 3495 | + """ |
| 3496 | + Override this base class test because this should work with symmetrical enum. |
| 3497 | + """ |
| 3498 | + create_params = { |
| 3499 | + **self.create_params, |
| 3500 | + 'no_coerce': 'Value 32767' |
| 3501 | + } |
| 3502 | + |
| 3503 | + tester = self.MODEL_CLASS.objects.create(**create_params) |
| 3504 | + self.assertEqual(tester.no_coerce, self.SmallPosIntEnum.VAL3) |
| 3505 | + self.assertEqual(tester.no_coerce, 'Value 32767') |
| 3506 | + |
| 3507 | + tester.refresh_from_db() |
| 3508 | + self.assertEqual(tester.no_coerce, 32767) |
| 3509 | + |
3365 | 3510 | class PerformanceTest(TestCase):
|
3366 | 3511 | """
|
3367 | 3512 | We intentionally test bulk operations performance because thats what
|
@@ -3660,7 +3805,6 @@ def test_color(self):
|
3660 | 3805 | ).first() == instance
|
3661 | 3806 | )
|
3662 | 3807 |
|
3663 |
| - from django.forms import ModelForm |
3664 | 3808 | from django_enum import EnumChoiceField
|
3665 | 3809 |
|
3666 | 3810 | class TextChoicesExampleForm(ModelForm):
|
@@ -3728,4 +3872,3 @@ def test_no_coerce(self):
|
3728 | 3872 |
|
3729 | 3873 | else: # pragma: no cover
|
3730 | 3874 | pass
|
3731 |
| - |
|
0 commit comments