1. from decimal import Decimal
    
  2. from sys import float_info
    
  3. 
    
  4. from django.test import SimpleTestCase
    
  5. from django.utils.numberformat import format as nformat
    
  6. 
    
  7. 
    
  8. class TestNumberFormat(SimpleTestCase):
    
  9.     def test_format_number(self):
    
  10.         self.assertEqual(nformat(1234, "."), "1234")
    
  11.         self.assertEqual(nformat(1234.2, "."), "1234.2")
    
  12.         self.assertEqual(nformat(1234, ".", decimal_pos=2), "1234.00")
    
  13.         self.assertEqual(nformat(1234, ".", grouping=2, thousand_sep=","), "1234")
    
  14.         self.assertEqual(
    
  15.             nformat(1234, ".", grouping=2, thousand_sep=",", force_grouping=True),
    
  16.             "12,34",
    
  17.         )
    
  18.         self.assertEqual(nformat(-1234.33, ".", decimal_pos=1), "-1234.3")
    
  19.         # The use_l10n parameter can force thousand grouping behavior.
    
  20.         with self.settings(USE_THOUSAND_SEPARATOR=True):
    
  21.             self.assertEqual(
    
  22.                 nformat(1234, ".", grouping=3, thousand_sep=",", use_l10n=False), "1234"
    
  23.             )
    
  24.             self.assertEqual(
    
  25.                 nformat(1234, ".", grouping=3, thousand_sep=",", use_l10n=True), "1,234"
    
  26.             )
    
  27. 
    
  28.     def test_format_string(self):
    
  29.         self.assertEqual(nformat("1234", "."), "1234")
    
  30.         self.assertEqual(nformat("1234.2", "."), "1234.2")
    
  31.         self.assertEqual(nformat("1234", ".", decimal_pos=2), "1234.00")
    
  32.         self.assertEqual(nformat("1234", ".", grouping=2, thousand_sep=","), "1234")
    
  33.         self.assertEqual(
    
  34.             nformat("1234", ".", grouping=2, thousand_sep=",", force_grouping=True),
    
  35.             "12,34",
    
  36.         )
    
  37.         self.assertEqual(nformat("-1234.33", ".", decimal_pos=1), "-1234.3")
    
  38.         self.assertEqual(
    
  39.             nformat(
    
  40.                 "10000", ".", grouping=3, thousand_sep="comma", force_grouping=True
    
  41.             ),
    
  42.             "10comma000",
    
  43.         )
    
  44. 
    
  45.     def test_large_number(self):
    
  46.         most_max = (
    
  47.             "{}179769313486231570814527423731704356798070567525844996"
    
  48.             "598917476803157260780028538760589558632766878171540458953"
    
  49.             "514382464234321326889464182768467546703537516986049910576"
    
  50.             "551282076245490090389328944075868508455133942304583236903"
    
  51.             "222948165808559332123348274797826204144723168738177180919"
    
  52.             "29988125040402618412485836{}"
    
  53.         )
    
  54.         most_max2 = (
    
  55.             "{}35953862697246314162905484746340871359614113505168999"
    
  56.             "31978349536063145215600570775211791172655337563430809179"
    
  57.             "07028764928468642653778928365536935093407075033972099821"
    
  58.             "15310256415249098018077865788815173701691026788460916647"
    
  59.             "38064458963316171186642466965495956524082894463374763543"
    
  60.             "61838599762500808052368249716736"
    
  61.         )
    
  62.         int_max = int(float_info.max)
    
  63.         self.assertEqual(nformat(int_max, "."), most_max.format("", "8"))
    
  64.         self.assertEqual(nformat(int_max + 1, "."), most_max.format("", "9"))
    
  65.         self.assertEqual(nformat(int_max * 2, "."), most_max2.format(""))
    
  66.         self.assertEqual(nformat(0 - int_max, "."), most_max.format("-", "8"))
    
  67.         self.assertEqual(nformat(-1 - int_max, "."), most_max.format("-", "9"))
    
  68.         self.assertEqual(nformat(-2 * int_max, "."), most_max2.format("-"))
    
  69. 
    
  70.     def test_float_numbers(self):
    
  71.         tests = [
    
  72.             (9e-10, 10, "0.0000000009"),
    
  73.             (9e-19, 2, "0.00"),
    
  74.             (0.00000000000099, 0, "0"),
    
  75.             (0.00000000000099, 13, "0.0000000000009"),
    
  76.             (1e16, None, "10000000000000000"),
    
  77.             (1e16, 2, "10000000000000000.00"),
    
  78.             # A float without a fractional part (3.) results in a ".0" when no
    
  79.             # decimal_pos is given. Contrast that with the Decimal('3.') case
    
  80.             # in test_decimal_numbers which doesn't return a fractional part.
    
  81.             (3.0, None, "3.0"),
    
  82.         ]
    
  83.         for value, decimal_pos, expected_value in tests:
    
  84.             with self.subTest(value=value, decimal_pos=decimal_pos):
    
  85.                 self.assertEqual(nformat(value, ".", decimal_pos), expected_value)
    
  86.         # Thousand grouping behavior.
    
  87.         self.assertEqual(
    
  88.             nformat(1e16, ".", thousand_sep=",", grouping=3, force_grouping=True),
    
  89.             "10,000,000,000,000,000",
    
  90.         )
    
  91.         self.assertEqual(
    
  92.             nformat(
    
  93.                 1e16,
    
  94.                 ".",
    
  95.                 decimal_pos=2,
    
  96.                 thousand_sep=",",
    
  97.                 grouping=3,
    
  98.                 force_grouping=True,
    
  99.             ),
    
  100.             "10,000,000,000,000,000.00",
    
  101.         )
    
  102. 
    
  103.     def test_decimal_numbers(self):
    
  104.         self.assertEqual(nformat(Decimal("1234"), "."), "1234")
    
  105.         self.assertEqual(nformat(Decimal("1234.2"), "."), "1234.2")
    
  106.         self.assertEqual(nformat(Decimal("1234"), ".", decimal_pos=2), "1234.00")
    
  107.         self.assertEqual(
    
  108.             nformat(Decimal("1234"), ".", grouping=2, thousand_sep=","), "1234"
    
  109.         )
    
  110.         self.assertEqual(
    
  111.             nformat(
    
  112.                 Decimal("1234"), ".", grouping=2, thousand_sep=",", force_grouping=True
    
  113.             ),
    
  114.             "12,34",
    
  115.         )
    
  116.         self.assertEqual(nformat(Decimal("-1234.33"), ".", decimal_pos=1), "-1234.3")
    
  117.         self.assertEqual(
    
  118.             nformat(Decimal("0.00000001"), ".", decimal_pos=8), "0.00000001"
    
  119.         )
    
  120.         self.assertEqual(nformat(Decimal("9e-19"), ".", decimal_pos=2), "0.00")
    
  121.         self.assertEqual(nformat(Decimal(".00000000000099"), ".", decimal_pos=0), "0")
    
  122.         self.assertEqual(
    
  123.             nformat(
    
  124.                 Decimal("1e16"), ".", thousand_sep=",", grouping=3, force_grouping=True
    
  125.             ),
    
  126.             "10,000,000,000,000,000",
    
  127.         )
    
  128.         self.assertEqual(
    
  129.             nformat(
    
  130.                 Decimal("1e16"),
    
  131.                 ".",
    
  132.                 decimal_pos=2,
    
  133.                 thousand_sep=",",
    
  134.                 grouping=3,
    
  135.                 force_grouping=True,
    
  136.             ),
    
  137.             "10,000,000,000,000,000.00",
    
  138.         )
    
  139.         self.assertEqual(nformat(Decimal("3."), "."), "3")
    
  140.         self.assertEqual(nformat(Decimal("3.0"), "."), "3.0")
    
  141.         # Very large & small numbers.
    
  142.         tests = [
    
  143.             ("9e9999", None, "9e+9999"),
    
  144.             ("9e9999", 3, "9.000e+9999"),
    
  145.             ("9e201", None, "9e+201"),
    
  146.             ("9e200", None, "9e+200"),
    
  147.             ("1.2345e999", 2, "1.23e+999"),
    
  148.             ("9e-999", None, "9e-999"),
    
  149.             ("1e-7", 8, "0.00000010"),
    
  150.             ("1e-8", 8, "0.00000001"),
    
  151.             ("1e-9", 8, "0.00000000"),
    
  152.             ("1e-10", 8, "0.00000000"),
    
  153.             ("1e-11", 8, "0.00000000"),
    
  154.             ("1" + ("0" * 300), 3, "1.000e+300"),
    
  155.             ("0.{}1234".format("0" * 299), 3, "0.000"),
    
  156.         ]
    
  157.         for value, decimal_pos, expected_value in tests:
    
  158.             with self.subTest(value=value):
    
  159.                 self.assertEqual(
    
  160.                     nformat(Decimal(value), ".", decimal_pos), expected_value
    
  161.                 )
    
  162. 
    
  163.     def test_decimal_subclass(self):
    
  164.         class EuroDecimal(Decimal):
    
  165.             """
    
  166.             Wrapper for Decimal which prefixes each amount with the € symbol.
    
  167.             """
    
  168. 
    
  169.             def __format__(self, specifier, **kwargs):
    
  170.                 amount = super().__format__(specifier, **kwargs)
    
  171.                 return "{}".format(amount)
    
  172. 
    
  173.         price = EuroDecimal("1.23")
    
  174.         self.assertEqual(nformat(price, ","), "€ 1,23")