| 1 | """provides unit tests for compat module""" |
|---|
| 2 | |
|---|
| 3 | from logilab.common.testlib import TestCase, unittest_main |
|---|
| 4 | import sys |
|---|
| 5 | import types |
|---|
| 6 | import __builtin__ |
|---|
| 7 | import pprint |
|---|
| 8 | |
|---|
| 9 | class CompatTCMixIn: |
|---|
| 10 | MODNAMES = {} |
|---|
| 11 | BUILTINS = [] |
|---|
| 12 | |
|---|
| 13 | def setUp(self): |
|---|
| 14 | self.builtins_backup = {} |
|---|
| 15 | self.modules_backup = {} |
|---|
| 16 | self.remove_builtins() |
|---|
| 17 | self.remove_modules() |
|---|
| 18 | |
|---|
| 19 | def tearDown(self): |
|---|
| 20 | for modname in self.MODNAMES: |
|---|
| 21 | del sys.modules[modname] |
|---|
| 22 | for funcname, func in self.builtins_backup.items(): |
|---|
| 23 | setattr(__builtin__, funcname, func) |
|---|
| 24 | # delattr(__builtin__, 'builtin_%s' % funcname) |
|---|
| 25 | for modname, mod in self.modules_backup.items(): |
|---|
| 26 | sys.modules[modname] = mod |
|---|
| 27 | try: |
|---|
| 28 | del sys.modules['logilab.common.compat'] |
|---|
| 29 | except KeyError: |
|---|
| 30 | pass |
|---|
| 31 | |
|---|
| 32 | def remove_builtins(self): |
|---|
| 33 | for builtin in self.BUILTINS: |
|---|
| 34 | func = getattr(__builtin__, builtin, None) |
|---|
| 35 | if func is not None: |
|---|
| 36 | self.builtins_backup[builtin] = func |
|---|
| 37 | delattr(__builtin__, builtin) |
|---|
| 38 | # setattr(__builtin__, 'builtin_%s' % builtin, func) |
|---|
| 39 | |
|---|
| 40 | def remove_modules(self): |
|---|
| 41 | for modname in self.MODNAMES: |
|---|
| 42 | if modname in sys.modules: |
|---|
| 43 | self.modules_backup[modname] = sys.modules[modname] |
|---|
| 44 | sys.modules[modname] = types.ModuleType('faked%s' % modname) |
|---|
| 45 | |
|---|
| 46 | def test_removed_builtins(self): |
|---|
| 47 | """tests that builtins are actually uncallable""" |
|---|
| 48 | for builtin in self.BUILTINS: |
|---|
| 49 | self.assertRaises(NameError, eval, builtin, {}) |
|---|
| 50 | |
|---|
| 51 | def test_removed_modules(self): |
|---|
| 52 | """tests that builtins are actually emtpy""" |
|---|
| 53 | for modname, funcnames in self.MODNAMES.items(): |
|---|
| 54 | import_stmt = 'from %s import %s' % (modname, ', '.join(funcnames)) |
|---|
| 55 | # FIXME: use __import__ instead |
|---|
| 56 | code = compile(import_stmt, 'foo.py', 'exec') |
|---|
| 57 | self.assertRaises(ImportError, eval, code) |
|---|
| 58 | |
|---|
| 59 | |
|---|
| 60 | class Py23CompatTC(CompatTCMixIn, TestCase): |
|---|
| 61 | BUILTINS = ('enumerate', 'sum') |
|---|
| 62 | MODNAMES = { |
|---|
| 63 | 'sets' : ('Set', 'ImmutableSet'), |
|---|
| 64 | 'itertools' : ('izip', 'chain'), |
|---|
| 65 | } |
|---|
| 66 | |
|---|
| 67 | def test_sum(self): |
|---|
| 68 | from logilab.common.compat import sum |
|---|
| 69 | self.assertEquals(sum(range(5)), 10) |
|---|
| 70 | self.assertRaises(TypeError, sum, 'abc') |
|---|
| 71 | |
|---|
| 72 | def test_enumerate(self): |
|---|
| 73 | from logilab.common.compat import enumerate |
|---|
| 74 | self.assertEquals(list(enumerate([])), []) |
|---|
| 75 | self.assertEquals(list(enumerate('abc')), |
|---|
| 76 | [(0, 'a'), (1, 'b'), (2, 'c')]) |
|---|
| 77 | |
|---|
| 78 | def test_basic_set(self): |
|---|
| 79 | from logilab.common.compat import set |
|---|
| 80 | s = set('abc') |
|---|
| 81 | self.assertEquals(len(s), 3) |
|---|
| 82 | s.remove('a') |
|---|
| 83 | self.assertEquals(len(s), 2) |
|---|
| 84 | s.add('a') |
|---|
| 85 | self.assertEquals(len(s), 3) |
|---|
| 86 | s.add('a') |
|---|
| 87 | self.assertEquals(len(s), 3) |
|---|
| 88 | self.assertRaises(KeyError, s.remove, 'd') |
|---|
| 89 | |
|---|
| 90 | def test_basic_set(self): |
|---|
| 91 | from logilab.common.compat import set |
|---|
| 92 | s = set('abc') |
|---|
| 93 | self.assertEquals(len(s), 3) |
|---|
| 94 | s.remove('a') |
|---|
| 95 | self.assertEquals(len(s), 2) |
|---|
| 96 | s.add('a') |
|---|
| 97 | self.assertEquals(len(s), 3) |
|---|
| 98 | s.add('a') |
|---|
| 99 | self.assertEquals(len(s), 3) |
|---|
| 100 | self.assertRaises(KeyError, s.remove, 'd') |
|---|
| 101 | self.assertRaises(TypeError, dict, [(s, 'foo')]) |
|---|
| 102 | |
|---|
| 103 | |
|---|
| 104 | def test_frozenset(self): |
|---|
| 105 | from logilab.common.compat import frozenset |
|---|
| 106 | s = frozenset('abc') |
|---|
| 107 | self.assertEquals(len(s), 3) |
|---|
| 108 | self.assertRaises(AttributeError, getattr, s, 'remove') |
|---|
| 109 | self.assertRaises(AttributeError, getattr, s, 'add') |
|---|
| 110 | d = {s : 'foo'} # frozenset should be hashable |
|---|
| 111 | d[s] = 'bar' |
|---|
| 112 | self.assertEquals(len(d), 1) |
|---|
| 113 | self.assertEquals(d[s], 'bar') |
|---|
| 114 | |
|---|
| 115 | |
|---|
| 116 | class Py24CompatTC(CompatTCMixIn, TestCase): |
|---|
| 117 | BUILTINS = ('reversed', 'sorted', 'set', 'frozenset',) |
|---|
| 118 | |
|---|
| 119 | def test_sorted(self): |
|---|
| 120 | from logilab.common.compat import sorted |
|---|
| 121 | l = [3, 1, 2, 5, 4] |
|---|
| 122 | s = sorted(l) |
|---|
| 123 | self.assertEquals(s, [1, 2, 3, 4, 5]) |
|---|
| 124 | self.assertEquals(l, [3, 1, 2, 5, 4]) |
|---|
| 125 | self.assertEquals(sorted('FeCBaD'), list('BCDFae')) |
|---|
| 126 | self.assertEquals(sorted('FeCBaD', key=str.lower), list('aBCDeF')) |
|---|
| 127 | self.assertEquals(sorted('FeCBaD', key=str.lower, reverse=True), list('FeDCBa')) |
|---|
| 128 | def strcmp(s1, s2): |
|---|
| 129 | return cmp(s1.lower(), s2.lower()) |
|---|
| 130 | self.assertEquals(sorted('FeCBaD', cmp=strcmp), list('aBCDeF')) |
|---|
| 131 | |
|---|
| 132 | |
|---|
| 133 | def test_reversed(self): |
|---|
| 134 | from logilab.common.compat import reversed |
|---|
| 135 | l = range(5) |
|---|
| 136 | r = reversed(l) |
|---|
| 137 | self.assertEquals(r, [4, 3, 2, 1, 0]) |
|---|
| 138 | self.assertEquals(l, range(5)) |
|---|
| 139 | |
|---|
| 140 | def test_set(self): |
|---|
| 141 | from logilab.common.compat import set |
|---|
| 142 | s1 = set(range(5)) |
|---|
| 143 | s2 = set(range(2, 6)) |
|---|
| 144 | self.assertEquals(len(s1), 5) |
|---|
| 145 | self.assertEquals(s1 & s2, set([2, 3, 4])) |
|---|
| 146 | self.assertEquals(s1 | s2, set(range(6))) |
|---|
| 147 | |
|---|
| 148 | |
|---|
| 149 | |
|---|
| 150 | |
|---|
| 151 | class Py25CompatTC(CompatTCMixIn, TestCase): |
|---|
| 152 | BUILTINS = ('any', 'all',) |
|---|
| 153 | |
|---|
| 154 | def test_any(self): |
|---|
| 155 | from logilab.common.compat import any |
|---|
| 156 | testdata = ([], (), '', 'abc', xrange(0, 10), xrange(0, -10, -1)) |
|---|
| 157 | self.assertEquals(any([]), False) |
|---|
| 158 | self.assertEquals(any(()), False) |
|---|
| 159 | self.assertEquals(any(''), False) |
|---|
| 160 | self.assertEquals(any('abc'), True) |
|---|
| 161 | self.assertEquals(any(xrange(10)), True) |
|---|
| 162 | self.assertEquals(any(xrange(0, -10, -1)), True) |
|---|
| 163 | # python2.5's any consumes iterables |
|---|
| 164 | irange = iter(range(10)) |
|---|
| 165 | self.assertEquals(any(irange), True) |
|---|
| 166 | self.assertEquals(irange.next(), 2) |
|---|
| 167 | |
|---|
| 168 | |
|---|
| 169 | def test_all(self): |
|---|
| 170 | from logilab.common.compat import all |
|---|
| 171 | testdata = ([], (), '', 'abc', xrange(0, 10), xrange(0, -10, -1)) |
|---|
| 172 | self.assertEquals(all([]), True) |
|---|
| 173 | self.assertEquals(all(()), True) |
|---|
| 174 | self.assertEquals(all(''), True) |
|---|
| 175 | self.assertEquals(all('abc'), True) |
|---|
| 176 | self.assertEquals(all(xrange(10)), False) |
|---|
| 177 | self.assertEquals(all(xrange(0, -10, -1)), False) |
|---|
| 178 | # python2.5's all consumes iterables |
|---|
| 179 | irange = iter(range(10)) |
|---|
| 180 | self.assertEquals(all(irange), False) |
|---|
| 181 | self.assertEquals(irange.next(), 1) |
|---|
| 182 | |
|---|
| 183 | |
|---|
| 184 | |
|---|
| 185 | if __name__ == '__main__': |
|---|
| 186 | unittest_main() |
|---|