1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
|
"""String formatting tests
Made for Jython.
"""
from test import test_support
import unittest
class FormatSubclass(unittest.TestCase):
# Custom __int__ and __float__ should be respected by %-formatting
def test_int_conversion_support(self):
class Foo(object):
def __init__(self, x): self.x = x
def __int__(self): return self. x
self.assertEqual('1', '%d' % Foo(1))
self.assertEqual('1', '%d' % Foo(1L)) # __int__ can return a long, but
# it should be accepted too
def test_float_conversion_support(self):
class Foo(object):
def __init__(self, x): self.x = x
def __float__(self): return self. x
self.assertEqual('1.0', '%.1f' % Foo(1.0))
def test_formatting_int_min_value_as_decimal(self):
# Test for http://bugs.jython.org/issue2672
x = int(-(1<<31))
self.assertEqual('-2147483648', '%d' % x)
self.assertEqual('-2147483648', '%i' % x)
def test_formatting_int_min_value_as_hex(self):
# Test for http://bugs.jython.org/issue2672
x = int(-(1<<31))
self.assertEqual('-80000000', '%x' % x)
self.assertEqual('-80000000', '%X' % x)
def test_formatting_int_min_value_as_octal(self):
# Test for http://bugs.jython.org/issue2672
x = int(-(1<<31))
self.assertEqual('-20000000000', '%o' % x)
def test_formatting_int_min_value_as_binary(self):
# Test for http://bugs.jython.org/issue2672
x = int(-(1<<31))
self.assertEqual('-10000000000000000000000000000000', '{0:b}'.format(x))
class FormatUnicodeBase(unittest.TestCase):
# Test padding non-BMP result
def test_pad_string(self):
self.padcheck(u"architect")
self.padcheck(u'a\U00010001cde')
class FormatUnicodeClassic(FormatUnicodeBase):
# Check using %-formatting
def padcheck(self, s):
self.assertEqual(10, len('%10.4s' % s))
self.assertEqual(u' '*6 + s[0:4], '%10.4s' % s)
self.assertEqual(u' '*6 + s[0:4], '% 10.4s' % s)
self.assertEqual(u' '*6 + s[0:4], '%010.4s' % s)
self.assertEqual(s[0:3] + u' '*5, '%-8.3s' % s)
class FormatUnicodeModern(FormatUnicodeBase):
# Check using __format__
def padcheck(self, s):
self.assertEqual(10, len(format(s, '10.4s')))
self.assertEqual(s[0:3] + u' '*7, format(s, '10.3s'))
self.assertEqual(s[0:3] + u'~'*7, format(s, '~<10.3s'))
self.assertEqual(s[0:3] + u'~'*7, format(s, '~<10.3'))
self.assertEqual(u' '*6 + s[0:4], format(s, '>10.4s'))
self.assertEqual(u'*'*6 + s[0:4], format(s, '*>10.4s'))
self.assertEqual(u'*'*6 + s[0:4], format(s, '*>10.4'))
class FormatMisc(unittest.TestCase):
# Odd tests Jython used to fail
def test_str_format_unicode(self):
# Check unicode is down-converted to str silently if possible
self.assertEqual("full half hour", "full {:s} hour".format(u"half"))
self.assertEqual("full \xbd hour", "full {:s} hour".format("\xbd"))
self.assertRaises(UnicodeEncodeError, "full {:s} hour".format, u"\xbd")
self.assertEqual(u"full \xbd hour", u"full {:s} hour".format(u"\xbd"))
def test_mixtures(self) :
# Check formatting to a common buffer in PyString
result = 'The cube of 0.5 -0.866j is -1 to 0.01%.'
self.assertEqual(result, 'The %s of %.3g -%.3fj is -%d to %.2f%%.' %
('cube', 0.5, 0.866, 1, 0.01))
self.assertEqual(result, 'The %s of %.3g %.3fj is %d to %.2f%%.' %
('cube', 0.5, -0.866, -1, 0.01))
self.assertEqual(result, 'The%5s of%4.3g%7.3fj is%3d to%5.2f%%.' %
('cube', 0.5, -0.866, -1, 0.01))
self.assertEqual(result, 'The %-5.4sof %-4.3g%.3fj is %-3dto %.4g%%.' %
('cubensis', 0.5, -0.866, -1, 0.01))
def test_percent_padded(self) :
self.assertEqual('%hello', '%%%s' % 'hello')
self.assertEqual(u' %hello', '%6%%s' % u'hello')
self.assertEqual(u'% hello', u'%-6%%s' % 'hello')
self.assertEqual(' %', '%6%' % ())
self.assertEqual(' %', '%06%' % ())
self.assertEqual(' %', '%*%' % 4)
self.assertEqual('% ', '%-6%' % ())
self.assertEqual('% ', '%-06%' % ())
self.assertEqual('% ', '%*%' % -4)
def test_formatter_parser(self):
def check_parse(fmt, expected):
fmt_list = list(fmt._formatter_parser())
#print repr(fmt_list)
self.assertListEqual(fmt_list, expected)
# Tuples elements are strings with type matching fmt or are None
t = (type(fmt), type(None))
for tup in fmt_list :
for s in tup :
self.assertIsInstance(s, t)
# Verify str._formatter_parser()
check_parse('{a:8.2f}', [('', 'a', '8.2f', None)])
check_parse('{a!r}', [('', 'a', '', 'r')])
check_parse('{a.b[2]!r}', [('', 'a.b[2]', '', 'r')])
check_parse('A={a:#12x}', [('A=', 'a', '#12x', None)])
check_parse('Hello {2!r:9s} world!',
[('Hello ', '2', '9s', 'r'), (' world!', None, None, None)])
# Verify unicode._formatter_parser()
check_parse(u'{a:8.2f}', [(u'', u'a', u'8.2f', None)])
check_parse(u'{a!r}', [(u'', u'a', u'', u'r')])
check_parse(u'{a.b[2]!r}', [(u'', u'a.b[2]', u'', u'r')])
check_parse(u'A={a:#12x}', [(u'A=', u'a', u'#12x', None)])
check_parse(u'Hello {2!r:9s} world!',
[(u'Hello ', u'2', u'9s', u'r'), (u' world!', None, None, None)])
# Differs from CPython: Jython str._formatter_parser generates the
# automatic argument number, while CPython leaves it to the client.
check_parse('hello {:{}d} and {:{}.{}f}',
[('hello ', '0', '{}d', None), (' and ', '1', '{}.{}f', None)] )
check_parse('hello {[2]:{}d} and {.xx:{}.{}f}',
[('hello ', '0[2]', '{}d', None), (' and ', '1.xx', '{}.{}f', None)] )
# The result is the same, however, of:
self.assertEqual('hello {:{}d} and {:{}.{}f}'.format(20, 16, 12, 8, 4),
'hello 20 and 12.0000' )
def test_formatter_field_name_split(self):
def check_split(name, xfirst, xrest):
first, r = name._formatter_field_name_split()
rest = list(r)
#print repr(first), repr(rest)
self.assertEqual(first, xfirst)
self.assertListEqual(rest, xrest)
# Types ought to match the original if not numeric
self.assertIsInstance(first, (type(name), int, long))
for is_attr, i in rest :
if is_attr :
self.assertIsInstance(i, type(name))
else :
self.assertIsInstance(i, (int, long))
# Verify str._formatter_field_name_split()
check_split('a', 'a', [])
check_split('2', 2, [])
check_split('.b', '', [(True, 'b')])
check_split('a.b[2]', 'a', [(True, 'b'), (False, 2)])
check_split('a.b[2].c[7]', 'a', [(True, 'b'), (False, 2), (True, 'c'), (False, 7)])
check_split('.b[2].c[7]', '', [(True, 'b'), (False, 2), (True, 'c'), (False, 7)])
check_split('[3].b[2].c[7]', '',
[(False, 3), (True, 'b'), (False, 2), (True, 'c'), (False, 7)])
# Verify unicode._formatter_field_name_split()
check_split(u'a', 'a', [])
check_split(u'2', 2, [])
check_split(u'.b', '', [(True, 'b')])
check_split(u'a.b[2]', 'a', [(True, 'b'), (False, 2)])
check_split(u'a.b[2].c[7]', 'a', [(True, 'b'), (False, 2), (True, 'c'), (False, 7)])
check_split(u'.b[2].c[7]', '', [(True, 'b'), (False, 2), (True, 'c'), (False, 7)])
check_split(u'[3].b[2].c[7]', '',
[(False, 3), (True, 'b'), (False, 2), (True, 'c'), (False, 7)])
def test_main():
test_support.run_unittest(
FormatSubclass,
FormatUnicodeClassic,
FormatUnicodeModern,
FormatMisc,
)
if __name__ == '__main__':
test_main()
|