Home | History | Annotate | Download | only in test
      1 """
      2   Test cases for the repr module
      3   Nick Mathewson
      4 """
      5 
      6 import sys
      7 import os
      8 import shutil
      9 import unittest
     10 
     11 from test.test_support import run_unittest, check_py3k_warnings
     12 from repr import repr as r # Don't shadow builtin repr
     13 from repr import Repr
     14 
     15 
     16 def nestedTuple(nesting):
     17     t = ()
     18     for i in range(nesting):
     19         t = (t,)
     20     return t
     21 
     22 class ReprTests(unittest.TestCase):
     23 
     24     def test_string(self):
     25         eq = self.assertEqual
     26         eq(r("abc"), "'abc'")
     27         eq(r("abcdefghijklmnop"),"'abcdefghijklmnop'")
     28 
     29         s = "a"*30+"b"*30
     30         expected = repr(s)[:13] + "..." + repr(s)[-14:]
     31         eq(r(s), expected)
     32 
     33         eq(r("\"'"), repr("\"'"))
     34         s = "\""*30+"'"*100
     35         expected = repr(s)[:13] + "..." + repr(s)[-14:]
     36         eq(r(s), expected)
     37 
     38     def test_tuple(self):
     39         eq = self.assertEqual
     40         eq(r((1,)), "(1,)")
     41 
     42         t3 = (1, 2, 3)
     43         eq(r(t3), "(1, 2, 3)")
     44 
     45         r2 = Repr()
     46         r2.maxtuple = 2
     47         expected = repr(t3)[:-2] + "...)"
     48         eq(r2.repr(t3), expected)
     49 
     50     def test_container(self):
     51         from array import array
     52         from collections import deque
     53 
     54         eq = self.assertEqual
     55         # Tuples give up after 6 elements
     56         eq(r(()), "()")
     57         eq(r((1,)), "(1,)")
     58         eq(r((1, 2, 3)), "(1, 2, 3)")
     59         eq(r((1, 2, 3, 4, 5, 6)), "(1, 2, 3, 4, 5, 6)")
     60         eq(r((1, 2, 3, 4, 5, 6, 7)), "(1, 2, 3, 4, 5, 6, ...)")
     61 
     62         # Lists give up after 6 as well
     63         eq(r([]), "[]")
     64         eq(r([1]), "[1]")
     65         eq(r([1, 2, 3]), "[1, 2, 3]")
     66         eq(r([1, 2, 3, 4, 5, 6]), "[1, 2, 3, 4, 5, 6]")
     67         eq(r([1, 2, 3, 4, 5, 6, 7]), "[1, 2, 3, 4, 5, 6, ...]")
     68 
     69         # Sets give up after 6 as well
     70         eq(r(set([])), "set([])")
     71         eq(r(set([1])), "set([1])")
     72         eq(r(set([1, 2, 3])), "set([1, 2, 3])")
     73         eq(r(set([1, 2, 3, 4, 5, 6])), "set([1, 2, 3, 4, 5, 6])")
     74         eq(r(set([1, 2, 3, 4, 5, 6, 7])), "set([1, 2, 3, 4, 5, 6, ...])")
     75 
     76         # Frozensets give up after 6 as well
     77         eq(r(frozenset([])), "frozenset([])")
     78         eq(r(frozenset([1])), "frozenset([1])")
     79         eq(r(frozenset([1, 2, 3])), "frozenset([1, 2, 3])")
     80         eq(r(frozenset([1, 2, 3, 4, 5, 6])), "frozenset([1, 2, 3, 4, 5, 6])")
     81         eq(r(frozenset([1, 2, 3, 4, 5, 6, 7])), "frozenset([1, 2, 3, 4, 5, 6, ...])")
     82 
     83         # collections.deque after 6
     84         eq(r(deque([1, 2, 3, 4, 5, 6, 7])), "deque([1, 2, 3, 4, 5, 6, ...])")
     85 
     86         # Dictionaries give up after 4.
     87         eq(r({}), "{}")
     88         d = {'alice': 1, 'bob': 2, 'charles': 3, 'dave': 4}
     89         eq(r(d), "{'alice': 1, 'bob': 2, 'charles': 3, 'dave': 4}")
     90         d['arthur'] = 1
     91         eq(r(d), "{'alice': 1, 'arthur': 1, 'bob': 2, 'charles': 3, ...}")
     92 
     93         # array.array after 5.
     94         eq(r(array('i')), "array('i', [])")
     95         eq(r(array('i', [1])), "array('i', [1])")
     96         eq(r(array('i', [1, 2])), "array('i', [1, 2])")
     97         eq(r(array('i', [1, 2, 3])), "array('i', [1, 2, 3])")
     98         eq(r(array('i', [1, 2, 3, 4])), "array('i', [1, 2, 3, 4])")
     99         eq(r(array('i', [1, 2, 3, 4, 5])), "array('i', [1, 2, 3, 4, 5])")
    100         eq(r(array('i', [1, 2, 3, 4, 5, 6])),
    101                    "array('i', [1, 2, 3, 4, 5, ...])")
    102 
    103     def test_numbers(self):
    104         eq = self.assertEqual
    105         eq(r(123), repr(123))
    106         eq(r(123L), repr(123L))
    107         eq(r(1.0/3), repr(1.0/3))
    108 
    109         n = 10L**100
    110         expected = repr(n)[:18] + "..." + repr(n)[-19:]
    111         eq(r(n), expected)
    112 
    113     def test_instance(self):
    114         eq = self.assertEqual
    115         i1 = ClassWithRepr("a")
    116         eq(r(i1), repr(i1))
    117 
    118         i2 = ClassWithRepr("x"*1000)
    119         expected = repr(i2)[:13] + "..." + repr(i2)[-14:]
    120         eq(r(i2), expected)
    121 
    122         i3 = ClassWithFailingRepr()
    123         eq(r(i3), ("<ClassWithFailingRepr instance at %x>"%id(i3)))
    124 
    125         s = r(ClassWithFailingRepr)
    126         self.assertTrue(s.startswith("<class "))
    127         self.assertTrue(s.endswith(">"))
    128         self.assertTrue(s.find("...") == 8)
    129 
    130     def test_file(self):
    131         fp = open(unittest.__file__)
    132         self.assertTrue(repr(fp).startswith(
    133             "<open file %r, mode 'r' at 0x" % unittest.__file__))
    134         fp.close()
    135         self.assertTrue(repr(fp).startswith(
    136             "<closed file %r, mode 'r' at 0x" % unittest.__file__))
    137 
    138     def test_lambda(self):
    139         self.assertTrue(repr(lambda x: x).startswith(
    140             "<function <lambda"))
    141         # XXX anonymous functions?  see func_repr
    142 
    143     def test_builtin_function(self):
    144         eq = self.assertEqual
    145         # Functions
    146         eq(repr(hash), '<built-in function hash>')
    147         # Methods
    148         self.assertTrue(repr(''.split).startswith(
    149             '<built-in method split of str object at 0x'))
    150 
    151     def test_xrange(self):
    152         eq = self.assertEqual
    153         eq(repr(xrange(1)), 'xrange(1)')
    154         eq(repr(xrange(1, 2)), 'xrange(1, 2)')
    155         eq(repr(xrange(1, 2, 3)), 'xrange(1, 4, 3)')
    156 
    157     def test_nesting(self):
    158         eq = self.assertEqual
    159         # everything is meant to give up after 6 levels.
    160         eq(r([[[[[[[]]]]]]]), "[[[[[[[]]]]]]]")
    161         eq(r([[[[[[[[]]]]]]]]), "[[[[[[[...]]]]]]]")
    162 
    163         eq(r(nestedTuple(6)), "(((((((),),),),),),)")
    164         eq(r(nestedTuple(7)), "(((((((...),),),),),),)")
    165 
    166         eq(r({ nestedTuple(5) : nestedTuple(5) }),
    167            "{((((((),),),),),): ((((((),),),),),)}")
    168         eq(r({ nestedTuple(6) : nestedTuple(6) }),
    169            "{((((((...),),),),),): ((((((...),),),),),)}")
    170 
    171         eq(r([[[[[[{}]]]]]]), "[[[[[[{}]]]]]]")
    172         eq(r([[[[[[[{}]]]]]]]), "[[[[[[[...]]]]]]]")
    173 
    174     def test_buffer(self):
    175         # XXX doesn't test buffers with no b_base or read-write buffers (see
    176         # bufferobject.c).  The test is fairly incomplete too.  Sigh.
    177         with check_py3k_warnings():
    178             x = buffer('foo')
    179         self.assertTrue(repr(x).startswith('<read-only buffer for 0x'))
    180 
    181     def test_cell(self):
    182         # XXX Hmm? How to get at a cell object?
    183         pass
    184 
    185     def test_descriptors(self):
    186         eq = self.assertEqual
    187         # method descriptors
    188         eq(repr(dict.items), "<method 'items' of 'dict' objects>")
    189         # XXX member descriptors
    190         # XXX attribute descriptors
    191         # XXX slot descriptors
    192         # static and class methods
    193         class C:
    194             def foo(cls): pass
    195         x = staticmethod(C.foo)
    196         self.assertTrue(repr(x).startswith('<staticmethod object at 0x'))
    197         x = classmethod(C.foo)
    198         self.assertTrue(repr(x).startswith('<classmethod object at 0x'))
    199 
    200     def test_unsortable(self):
    201         # Repr.repr() used to call sorted() on sets, frozensets and dicts
    202         # without taking into account that not all objects are comparable
    203         x = set([1j, 2j, 3j])
    204         y = frozenset(x)
    205         z = {1j: 1, 2j: 2}
    206         r(x)
    207         r(y)
    208         r(z)
    209 
    210 def touch(path, text=''):
    211     fp = open(path, 'w')
    212     fp.write(text)
    213     fp.close()
    214 
    215 class LongReprTest(unittest.TestCase):
    216     def setUp(self):
    217         longname = 'areallylongpackageandmodulenametotestreprtruncation'
    218         self.pkgname = os.path.join(longname)
    219         self.subpkgname = os.path.join(longname, longname)
    220         # Make the package and subpackage
    221         shutil.rmtree(self.pkgname, ignore_errors=True)
    222         os.mkdir(self.pkgname)
    223         touch(os.path.join(self.pkgname, '__init__'+os.extsep+'py'))
    224         shutil.rmtree(self.subpkgname, ignore_errors=True)
    225         os.mkdir(self.subpkgname)
    226         touch(os.path.join(self.subpkgname, '__init__'+os.extsep+'py'))
    227         # Remember where we are
    228         self.here = os.getcwd()
    229         sys.path.insert(0, self.here)
    230 
    231     def tearDown(self):
    232         actions = []
    233         for dirpath, dirnames, filenames in os.walk(self.pkgname):
    234             for name in dirnames + filenames:
    235                 actions.append(os.path.join(dirpath, name))
    236         actions.append(self.pkgname)
    237         actions.sort()
    238         actions.reverse()
    239         for p in actions:
    240             if os.path.isdir(p):
    241                 os.rmdir(p)
    242             else:
    243                 os.remove(p)
    244         del sys.path[0]
    245 
    246     def test_module(self):
    247         eq = self.assertEqual
    248         touch(os.path.join(self.subpkgname, self.pkgname + os.extsep + 'py'))
    249         from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import areallylongpackageandmodulenametotestreprtruncation
    250         eq(repr(areallylongpackageandmodulenametotestreprtruncation),
    251            "<module '%s' from '%s'>" % (areallylongpackageandmodulenametotestreprtruncation.__name__, areallylongpackageandmodulenametotestreprtruncation.__file__))
    252         eq(repr(sys), "<module 'sys' (built-in)>")
    253 
    254     def test_type(self):
    255         eq = self.assertEqual
    256         touch(os.path.join(self.subpkgname, 'foo'+os.extsep+'py'), '''\
    257 class foo(object):
    258     pass
    259 ''')
    260         from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import foo
    261         eq(repr(foo.foo),
    262                "<class '%s.foo'>" % foo.__name__)
    263 
    264     def test_object(self):
    265         # XXX Test the repr of a type with a really long tp_name but with no
    266         # tp_repr.  WIBNI we had ::Inline? :)
    267         pass
    268 
    269     def test_class(self):
    270         touch(os.path.join(self.subpkgname, 'bar'+os.extsep+'py'), '''\
    271 class bar:
    272     pass
    273 ''')
    274         from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import bar
    275         # Module name may be prefixed with "test.", depending on how run.
    276         self.assertTrue(repr(bar.bar).startswith(
    277             "<class %s.bar at 0x" % bar.__name__))
    278 
    279     def test_instance(self):
    280         touch(os.path.join(self.subpkgname, 'baz'+os.extsep+'py'), '''\
    281 class baz:
    282     pass
    283 ''')
    284         from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import baz
    285         ibaz = baz.baz()
    286         self.assertTrue(repr(ibaz).startswith(
    287             "<%s.baz instance at 0x" % baz.__name__))
    288 
    289     def test_method(self):
    290         eq = self.assertEqual
    291         touch(os.path.join(self.subpkgname, 'qux'+os.extsep+'py'), '''\
    292 class aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:
    293     def amethod(self): pass
    294 ''')
    295         from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import qux
    296         # Unbound methods first
    297         eq(repr(qux.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod),
    298         '<unbound method aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod>')
    299         # Bound method next
    300         iqux = qux.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()
    301         self.assertTrue(repr(iqux.amethod).startswith(
    302             '<bound method aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod of <%s.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa instance at 0x' \
    303             % (qux.__name__,) ))
    304 
    305     def test_builtin_function(self):
    306         # XXX test built-in functions and methods with really long names
    307         pass
    308 
    309 class ClassWithRepr:
    310     def __init__(self, s):
    311         self.s = s
    312     def __repr__(self):
    313         return "ClassWithLongRepr(%r)" % self.s
    314 
    315 
    316 class ClassWithFailingRepr:
    317     def __repr__(self):
    318         raise Exception("This should be caught by Repr.repr_instance")
    319 
    320 
    321 def test_main():
    322     run_unittest(ReprTests)
    323     run_unittest(LongReprTest)
    324 
    325 
    326 if __name__ == "__main__":
    327     test_main()
    328