test_floatfield.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. from __future__ import unicode_literals
  2. from django.forms import FloatField, NumberInput, ValidationError
  3. from django.test import SimpleTestCase
  4. from django.utils import formats, translation
  5. from . import FormFieldAssertionsMixin
  6. class FloatFieldTest(FormFieldAssertionsMixin, SimpleTestCase):
  7. def test_floatfield_1(self):
  8. f = FloatField()
  9. self.assertWidgetRendersTo(f, '<input step="any" type="number" name="f" id="id_f" required />')
  10. with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
  11. f.clean('')
  12. with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
  13. f.clean(None)
  14. self.assertEqual(1.0, f.clean('1'))
  15. self.assertIsInstance(f.clean('1'), float)
  16. self.assertEqual(23.0, f.clean('23'))
  17. self.assertEqual(3.1400000000000001, f.clean('3.14'))
  18. self.assertEqual(3.1400000000000001, f.clean(3.14))
  19. self.assertEqual(42.0, f.clean(42))
  20. with self.assertRaisesMessage(ValidationError, "'Enter a number.'"):
  21. f.clean('a')
  22. self.assertEqual(1.0, f.clean('1.0 '))
  23. self.assertEqual(1.0, f.clean(' 1.0'))
  24. self.assertEqual(1.0, f.clean(' 1.0 '))
  25. with self.assertRaisesMessage(ValidationError, "'Enter a number.'"):
  26. f.clean('1.0a')
  27. self.assertIsNone(f.max_value)
  28. self.assertIsNone(f.min_value)
  29. with self.assertRaisesMessage(ValidationError, "'Enter a number.'"):
  30. f.clean('Infinity')
  31. with self.assertRaisesMessage(ValidationError, "'Enter a number.'"):
  32. f.clean('NaN')
  33. with self.assertRaisesMessage(ValidationError, "'Enter a number.'"):
  34. f.clean('-Inf')
  35. def test_floatfield_2(self):
  36. f = FloatField(required=False)
  37. self.assertIsNone(f.clean(''))
  38. self.assertIsNone(f.clean(None))
  39. self.assertEqual(1.0, f.clean('1'))
  40. self.assertIsNone(f.max_value)
  41. self.assertIsNone(f.min_value)
  42. def test_floatfield_3(self):
  43. f = FloatField(max_value=1.5, min_value=0.5)
  44. self.assertWidgetRendersTo(
  45. f,
  46. '<input step="any" name="f" min="0.5" max="1.5" type="number" id="id_f" required />',
  47. )
  48. with self.assertRaisesMessage(ValidationError, "'Ensure this value is less than or equal to 1.5.'"):
  49. f.clean('1.6')
  50. with self.assertRaisesMessage(ValidationError, "'Ensure this value is greater than or equal to 0.5.'"):
  51. f.clean('0.4')
  52. self.assertEqual(1.5, f.clean('1.5'))
  53. self.assertEqual(0.5, f.clean('0.5'))
  54. self.assertEqual(f.max_value, 1.5)
  55. self.assertEqual(f.min_value, 0.5)
  56. def test_floatfield_widget_attrs(self):
  57. f = FloatField(widget=NumberInput(attrs={'step': 0.01, 'max': 1.0, 'min': 0.0}))
  58. self.assertWidgetRendersTo(
  59. f,
  60. '<input step="0.01" name="f" min="0.0" max="1.0" type="number" id="id_f" required />',
  61. )
  62. def test_floatfield_localized(self):
  63. """
  64. A localized FloatField's widget renders to a text input without any
  65. number input specific attributes.
  66. """
  67. f = FloatField(localize=True)
  68. self.assertWidgetRendersTo(f, '<input id="id_f" name="f" type="text" required />')
  69. def test_floatfield_changed(self):
  70. f = FloatField()
  71. n = 4.35
  72. self.assertFalse(f.has_changed(n, '4.3500'))
  73. with translation.override('fr'), self.settings(USE_L10N=True):
  74. f = FloatField(localize=True)
  75. localized_n = formats.localize_input(n) # -> '4,35' in French
  76. self.assertFalse(f.has_changed(n, localized_n))