Michael Merickel
2018-10-18 f28dbb0ba8d276fad10a3cd25e4d60b298702d83
commit | author | age
a9f17c 1 import unittest
0c29cf 2 from pyramid.compat import PY2, text_, bytes_
a9f17c 3
fd8402 4
04cc91 5 class Test_InstancePropertyHelper(unittest.TestCase):
MM 6     def _makeOne(self):
7         cls = self._getTargetClass()
8         return cls()
9
10     def _getTargetClass(self):
11         from pyramid.util import InstancePropertyHelper
0c29cf 12
04cc91 13         return InstancePropertyHelper
MM 14
15     def test_callable(self):
16         def worker(obj):
17             return obj.bar
0c29cf 18
04cc91 19         foo = Dummy()
MM 20         helper = self._getTargetClass()
21         helper.set_property(foo, worker)
22         foo.bar = 1
23         self.assertEqual(1, foo.worker)
24         foo.bar = 2
25         self.assertEqual(2, foo.worker)
26
27     def test_callable_with_name(self):
28         def worker(obj):
29             return obj.bar
0c29cf 30
04cc91 31         foo = Dummy()
MM 32         helper = self._getTargetClass()
33         helper.set_property(foo, worker, name='x')
34         foo.bar = 1
35         self.assertEqual(1, foo.x)
36         foo.bar = 2
37         self.assertEqual(2, foo.x)
38
39     def test_callable_with_reify(self):
40         def worker(obj):
41             return obj.bar
0c29cf 42
04cc91 43         foo = Dummy()
MM 44         helper = self._getTargetClass()
45         helper.set_property(foo, worker, reify=True)
46         foo.bar = 1
47         self.assertEqual(1, foo.worker)
48         foo.bar = 2
49         self.assertEqual(1, foo.worker)
50
51     def test_callable_with_name_reify(self):
52         def worker(obj):
53             return obj.bar
0c29cf 54
04cc91 55         foo = Dummy()
MM 56         helper = self._getTargetClass()
57         helper.set_property(foo, worker, name='x')
58         helper.set_property(foo, worker, name='y', reify=True)
59         foo.bar = 1
60         self.assertEqual(1, foo.y)
61         self.assertEqual(1, foo.x)
62         foo.bar = 2
63         self.assertEqual(2, foo.x)
64         self.assertEqual(1, foo.y)
65
66     def test_property_without_name(self):
10ddb6 67         def worker(obj):  # pragma: no cover
0c29cf 68             pass
MM 69
04cc91 70         foo = Dummy()
MM 71         helper = self._getTargetClass()
0c29cf 72         self.assertRaises(
MM 73             ValueError, helper.set_property, foo, property(worker)
74         )
04cc91 75
MM 76     def test_property_with_name(self):
77         def worker(obj):
78             return obj.bar
0c29cf 79
04cc91 80         foo = Dummy()
MM 81         helper = self._getTargetClass()
82         helper.set_property(foo, property(worker), name='x')
83         foo.bar = 1
84         self.assertEqual(1, foo.x)
85         foo.bar = 2
86         self.assertEqual(2, foo.x)
87
88     def test_property_with_reify(self):
10ddb6 89         def worker(obj):  # pragma: no cover
0c29cf 90             pass
MM 91
04cc91 92         foo = Dummy()
MM 93         helper = self._getTargetClass()
0c29cf 94         self.assertRaises(
MM 95             ValueError,
96             helper.set_property,
97             foo,
98             property(worker),
99             name='x',
100             reify=True,
101         )
04cc91 102
MM 103     def test_override_property(self):
10ddb6 104         def worker(obj):  # pragma: no cover
0c29cf 105             pass
MM 106
04cc91 107         foo = Dummy()
MM 108         helper = self._getTargetClass()
109         helper.set_property(foo, worker, name='x')
0c29cf 110
04cc91 111         def doit():
MM 112             foo.x = 1
0c29cf 113
04cc91 114         self.assertRaises(AttributeError, doit)
MM 115
116     def test_override_reify(self):
10ddb6 117         def worker(obj):  # pragma: no cover
0c29cf 118             pass
MM 119
04cc91 120         foo = Dummy()
MM 121         helper = self._getTargetClass()
122         helper.set_property(foo, worker, name='x', reify=True)
123         foo.x = 1
124         self.assertEqual(1, foo.x)
125         foo.x = 2
126         self.assertEqual(2, foo.x)
127
128     def test_reset_property(self):
129         foo = Dummy()
130         helper = self._getTargetClass()
131         helper.set_property(foo, lambda _: 1, name='x')
132         self.assertEqual(1, foo.x)
133         helper.set_property(foo, lambda _: 2, name='x')
134         self.assertEqual(2, foo.x)
135
136     def test_reset_reify(self):
137         """ This is questionable behavior, but may as well get notified
138         if it changes."""
139         foo = Dummy()
140         helper = self._getTargetClass()
141         helper.set_property(foo, lambda _: 1, name='x', reify=True)
142         self.assertEqual(1, foo.x)
143         helper.set_property(foo, lambda _: 2, name='x', reify=True)
144         self.assertEqual(1, foo.x)
145
146     def test_make_property(self):
147         from pyramid.decorator import reify
0c29cf 148
04cc91 149         helper = self._getTargetClass()
MM 150         name, fn = helper.make_property(lambda x: 1, name='x', reify=True)
151         self.assertEqual(name, 'x')
152         self.assertTrue(isinstance(fn, reify))
153
154     def test_apply_properties_with_iterable(self):
155         foo = Dummy()
156         helper = self._getTargetClass()
157         x = helper.make_property(lambda _: 1, name='x', reify=True)
158         y = helper.make_property(lambda _: 2, name='y')
159         helper.apply_properties(foo, [x, y])
160         self.assertEqual(1, foo.x)
161         self.assertEqual(2, foo.y)
162
163     def test_apply_properties_with_dict(self):
164         foo = Dummy()
165         helper = self._getTargetClass()
166         x_name, x_fn = helper.make_property(lambda _: 1, name='x', reify=True)
167         y_name, y_fn = helper.make_property(lambda _: 2, name='y')
168         helper.apply_properties(foo, {x_name: x_fn, y_name: y_fn})
169         self.assertEqual(1, foo.x)
170         self.assertEqual(2, foo.y)
171
172     def test_make_property_unicode(self):
173         from pyramid.compat import text_
174         from pyramid.exceptions import ConfigurationError
175
176         cls = self._getTargetClass()
bc37a5 177         if PY2:
04cc91 178             name = text_(b'La Pe\xc3\xb1a', 'utf-8')
bc37a5 179         else:
MM 180             name = b'La Pe\xc3\xb1a'
04cc91 181
MM 182         def make_bad_name():
183             cls.make_property(lambda x: 1, name=name, reify=True)
184
185         self.assertRaises(ConfigurationError, make_bad_name)
186
187     def test_add_property(self):
188         helper = self._makeOne()
189         helper.add_property(lambda obj: obj.bar, name='x', reify=True)
190         helper.add_property(lambda obj: obj.bar, name='y')
191         self.assertEqual(len(helper.properties), 2)
192         foo = Dummy()
193         helper.apply(foo)
194         foo.bar = 1
195         self.assertEqual(foo.x, 1)
196         self.assertEqual(foo.y, 1)
197         foo.bar = 2
198         self.assertEqual(foo.x, 1)
199         self.assertEqual(foo.y, 2)
200
201     def test_apply_multiple_times(self):
202         helper = self._makeOne()
203         helper.add_property(lambda obj: 1, name='x')
204         foo, bar = Dummy(), Dummy()
205         helper.apply(foo)
206         self.assertEqual(foo.x, 1)
207         helper.add_property(lambda obj: 2, name='x')
208         helper.apply(bar)
209         self.assertEqual(foo.x, 1)
210         self.assertEqual(bar.x, 2)
211
0c29cf 212
577db9 213 class Test_InstancePropertyMixin(unittest.TestCase):
MM 214     def _makeOne(self):
49a358 215         cls = self._getTargetClass()
fd8402 216
577db9 217         class Foo(cls):
MM 218             pass
0c29cf 219
577db9 220         return Foo()
MM 221
49a358 222     def _getTargetClass(self):
577db9 223         from pyramid.util import InstancePropertyMixin
0c29cf 224
577db9 225         return InstancePropertyMixin
MM 226
227     def test_callable(self):
228         def worker(obj):
229             return obj.bar
0c29cf 230
577db9 231         foo = self._makeOne()
MM 232         foo.set_property(worker)
233         foo.bar = 1
234         self.assertEqual(1, foo.worker)
235         foo.bar = 2
236         self.assertEqual(2, foo.worker)
237
238     def test_callable_with_name(self):
239         def worker(obj):
240             return obj.bar
0c29cf 241
577db9 242         foo = self._makeOne()
MM 243         foo.set_property(worker, name='x')
244         foo.bar = 1
245         self.assertEqual(1, foo.x)
246         foo.bar = 2
247         self.assertEqual(2, foo.x)
248
249     def test_callable_with_reify(self):
250         def worker(obj):
251             return obj.bar
0c29cf 252
577db9 253         foo = self._makeOne()
MM 254         foo.set_property(worker, reify=True)
255         foo.bar = 1
256         self.assertEqual(1, foo.worker)
257         foo.bar = 2
258         self.assertEqual(1, foo.worker)
259
260     def test_callable_with_name_reify(self):
261         def worker(obj):
262             return obj.bar
0c29cf 263
577db9 264         foo = self._makeOne()
MM 265         foo.set_property(worker, name='x')
266         foo.set_property(worker, name='y', reify=True)
267         foo.bar = 1
268         self.assertEqual(1, foo.y)
269         self.assertEqual(1, foo.x)
270         foo.bar = 2
271         self.assertEqual(2, foo.x)
272         self.assertEqual(1, foo.y)
273
274     def test_property_without_name(self):
10ddb6 275         def worker(obj):  # pragma: no cover
0c29cf 276             pass
MM 277
577db9 278         foo = self._makeOne()
MM 279         self.assertRaises(ValueError, foo.set_property, property(worker))
280
281     def test_property_with_name(self):
282         def worker(obj):
283             return obj.bar
0c29cf 284
577db9 285         foo = self._makeOne()
MM 286         foo.set_property(property(worker), name='x')
287         foo.bar = 1
288         self.assertEqual(1, foo.x)
289         foo.bar = 2
290         self.assertEqual(2, foo.x)
291
292     def test_property_with_reify(self):
10ddb6 293         def worker(obj):  # pragma: no cover
0c29cf 294             pass
MM 295
577db9 296         foo = self._makeOne()
0c29cf 297         self.assertRaises(
MM 298             ValueError,
299             foo.set_property,
300             property(worker),
301             name='x',
302             reify=True,
303         )
577db9 304
MM 305     def test_override_property(self):
10ddb6 306         def worker(obj):  # pragma: no cover
0c29cf 307             pass
MM 308
577db9 309         foo = self._makeOne()
MM 310         foo.set_property(worker, name='x')
0c29cf 311
577db9 312         def doit():
MM 313             foo.x = 1
0c29cf 314
577db9 315         self.assertRaises(AttributeError, doit)
MM 316
317     def test_override_reify(self):
10ddb6 318         def worker(obj):  # pragma: no cover
0c29cf 319             pass
MM 320
577db9 321         foo = self._makeOne()
MM 322         foo.set_property(worker, name='x', reify=True)
323         foo.x = 1
324         self.assertEqual(1, foo.x)
325         foo.x = 2
326         self.assertEqual(2, foo.x)
327
328     def test_reset_property(self):
329         foo = self._makeOne()
330         foo.set_property(lambda _: 1, name='x')
331         self.assertEqual(1, foo.x)
332         foo.set_property(lambda _: 2, name='x')
333         self.assertEqual(2, foo.x)
334
335     def test_reset_reify(self):
336         """ This is questionable behavior, but may as well get notified
337         if it changes."""
338         foo = self._makeOne()
339         foo.set_property(lambda _: 1, name='x', reify=True)
340         self.assertEqual(1, foo.x)
341         foo.set_property(lambda _: 2, name='x', reify=True)
342         self.assertEqual(1, foo.x)
735987 343
0b9360 344     def test_new_class_keeps_parent_module_name(self):
MM 345         foo = self._makeOne()
dd3cc8 346         self.assertEqual(foo.__module__, 'tests.test_util')
MM 347         self.assertEqual(foo.__class__.__module__, 'tests.test_util')
0b9360 348         foo.set_property(lambda _: 1, name='x', reify=True)
dd3cc8 349         self.assertEqual(foo.__module__, 'tests.test_util')
MM 350         self.assertEqual(foo.__class__.__module__, 'tests.test_util')
0b9360 351
0c29cf 352
91cd7e 353 class Test_WeakOrderedSet(unittest.TestCase):
MM 354     def _makeOne(self):
355         from pyramid.config import WeakOrderedSet
0c29cf 356
91cd7e 357         return WeakOrderedSet()
MM 358
c38aaf 359     def test_ctor(self):
91cd7e 360         wos = self._makeOne()
MM 361         self.assertEqual(len(wos), 0)
362         self.assertEqual(wos.last, None)
363
364     def test_add_item(self):
365         wos = self._makeOne()
366         reg = Dummy()
367         wos.add(reg)
368         self.assertEqual(list(wos), [reg])
8e606d 369         self.assertTrue(reg in wos)
91cd7e 370         self.assertEqual(wos.last, reg)
MM 371
372     def test_add_multiple_items(self):
373         wos = self._makeOne()
374         reg1 = Dummy()
375         reg2 = Dummy()
376         wos.add(reg1)
377         wos.add(reg2)
378         self.assertEqual(len(wos), 2)
379         self.assertEqual(list(wos), [reg1, reg2])
8e606d 380         self.assertTrue(reg1 in wos)
CM 381         self.assertTrue(reg2 in wos)
91cd7e 382         self.assertEqual(wos.last, reg2)
MM 383
384     def test_add_duplicate_items(self):
385         wos = self._makeOne()
386         reg = Dummy()
387         wos.add(reg)
388         wos.add(reg)
389         self.assertEqual(len(wos), 1)
390         self.assertEqual(list(wos), [reg])
8e606d 391         self.assertTrue(reg in wos)
91cd7e 392         self.assertEqual(wos.last, reg)
MM 393
394     def test_weakref_removal(self):
395         wos = self._makeOne()
396         reg = Dummy()
397         wos.add(reg)
eff1cb 398         wos.remove(reg)
91cd7e 399         self.assertEqual(len(wos), 0)
MM 400         self.assertEqual(list(wos), [])
401         self.assertEqual(wos.last, None)
402
403     def test_last_updated(self):
404         wos = self._makeOne()
405         reg = Dummy()
406         reg2 = Dummy()
407         wos.add(reg)
408         wos.add(reg2)
eff1cb 409         wos.remove(reg2)
91cd7e 410         self.assertEqual(len(wos), 1)
MM 411         self.assertEqual(list(wos), [reg])
412         self.assertEqual(wos.last, reg)
413
eff1cb 414     def test_empty(self):
MM 415         wos = self._makeOne()
416         reg = Dummy()
417         reg2 = Dummy()
418         wos.add(reg)
419         wos.add(reg2)
420         wos.empty()
421         self.assertEqual(len(wos), 0)
422         self.assertEqual(list(wos), [])
423         self.assertEqual(wos.last, None)
424
0c29cf 425
716a20 426 class Test_strings_differ(unittest.TestCase):
MM 427     def _callFUT(self, *args, **kw):
428         from pyramid.util import strings_differ
0c29cf 429
716a20 430         return strings_differ(*args, **kw)
MM 431
682a9b 432     def test_it_bytes(self):
716a20 433         self.assertFalse(self._callFUT(b'foo', b'foo'))
MM 434         self.assertTrue(self._callFUT(b'123', b'345'))
435         self.assertTrue(self._callFUT(b'1234', b'123'))
436         self.assertTrue(self._callFUT(b'123', b'1234'))
437
682a9b 438     def test_it_native_str(self):
MM 439         self.assertFalse(self._callFUT('123', '123'))
440         self.assertTrue(self._callFUT('123', '1234'))
441
716a20 442     def test_it_with_internal_comparator(self):
MM 443         result = self._callFUT(b'foo', b'foo', compare_digest=None)
444         self.assertFalse(result)
445
446         result = self._callFUT(b'123', b'abc', compare_digest=None)
447         self.assertTrue(result)
448
449     def test_it_with_external_comparator(self):
450         class DummyComparator(object):
451             called = False
0c29cf 452
716a20 453             def __init__(self, ret_val):
MM 454                 self.ret_val = ret_val
455
456             def __call__(self, a, b):
457                 self.called = True
458                 return self.ret_val
459
460         dummy_compare = DummyComparator(True)
461         result = self._callFUT(b'foo', b'foo', compare_digest=dummy_compare)
462         self.assertTrue(dummy_compare.called)
463         self.assertFalse(result)
464
465         dummy_compare = DummyComparator(False)
466         result = self._callFUT(b'123', b'345', compare_digest=dummy_compare)
467         self.assertTrue(dummy_compare.called)
468         self.assertTrue(result)
469
470         dummy_compare = DummyComparator(False)
471         result = self._callFUT(b'abc', b'abc', compare_digest=dummy_compare)
472         self.assertTrue(dummy_compare.called)
473         self.assertTrue(result)
474
0c29cf 475
e49638 476 class Test_object_description(unittest.TestCase):
CM 477     def _callFUT(self, object):
478         from pyramid.util import object_description
0c29cf 479
e49638 480         return object_description(object)
CM 481
482     def test_string(self):
483         self.assertEqual(self._callFUT('abc'), 'abc')
484
485     def test_int(self):
486         self.assertEqual(self._callFUT(1), '1')
487
488     def test_bool(self):
489         self.assertEqual(self._callFUT(True), 'True')
490
491     def test_None(self):
492         self.assertEqual(self._callFUT(None), 'None')
493
494     def test_float(self):
495         self.assertEqual(self._callFUT(1.2), '1.2')
496
497     def test_tuple(self):
498         self.assertEqual(self._callFUT(('a', 'b')), "('a', 'b')")
499
500     def test_set(self):
bc37a5 501         if PY2:
82ba10 502             self.assertEqual(self._callFUT(set(['a'])), "set(['a'])")
bc37a5 503         else:
MM 504             self.assertEqual(self._callFUT(set(['a'])), "{'a'}")
e49638 505
CM 506     def test_list(self):
507         self.assertEqual(self._callFUT(['a']), "['a']")
508
509     def test_dict(self):
0c29cf 510         self.assertEqual(self._callFUT({'a': 1}), "{'a': 1}")
e49638 511
CM 512     def test_nomodule(self):
513         o = object()
514         self.assertEqual(self._callFUT(o), 'object %s' % str(o))
515
516     def test_module(self):
517         import pyramid
0c29cf 518
e49638 519         self.assertEqual(self._callFUT(pyramid), 'module pyramid')
CM 520
521     def test_method(self):
522         self.assertEqual(
523             self._callFUT(self.test_method),
dd3cc8 524             'method test_method of class tests.test_util.'
0c29cf 525             'Test_object_description',
MM 526         )
e49638 527
CM 528     def test_class(self):
529         self.assertEqual(
530             self._callFUT(self.__class__),
0c29cf 531             'class tests.test_util.Test_object_description',
MM 532         )
e49638 533
CM 534     def test_function(self):
535         self.assertEqual(
0c29cf 536             self._callFUT(dummyfunc), 'function tests.test_util.dummyfunc'
MM 537         )
e49638 538
CM 539     def test_instance(self):
540         inst = Dummy()
0c29cf 541         self.assertEqual(self._callFUT(inst), "object %s" % str(inst))
32cb80 542
e49638 543     def test_shortened_repr(self):
CM 544         inst = ['1'] * 1000
0c29cf 545         self.assertEqual(self._callFUT(inst), str(inst)[:100] + ' ... ]')
MM 546
e49638 547
66fe1d 548 class TestTopologicalSorter(unittest.TestCase):
CM 549     def _makeOne(self, *arg, **kw):
550         from pyramid.util import TopologicalSorter
0c29cf 551
66fe1d 552         return TopologicalSorter(*arg, **kw)
CM 553
554     def test_remove(self):
555         inst = self._makeOne()
556         inst.names.append('name')
557         inst.name2val['name'] = 1
558         inst.req_after.add('name')
559         inst.req_before.add('name')
560         inst.name2after['name'] = ('bob',)
561         inst.name2before['name'] = ('fred',)
562         inst.order.append(('bob', 'name'))
563         inst.order.append(('name', 'fred'))
564         inst.remove('name')
565         self.assertFalse(inst.names)
566         self.assertFalse(inst.req_before)
567         self.assertFalse(inst.req_after)
568         self.assertFalse(inst.name2before)
569         self.assertFalse(inst.name2after)
570         self.assertFalse(inst.name2val)
571         self.assertFalse(inst.order)
572
573     def test_add(self):
574         from pyramid.util import LAST
0c29cf 575
66fe1d 576         sorter = self._makeOne()
CM 577         sorter.add('name', 'factory')
578         self.assertEqual(sorter.names, ['name'])
0c29cf 579         self.assertEqual(sorter.name2val, {'name': 'factory'})
66fe1d 580         self.assertEqual(sorter.order, [('name', LAST)])
CM 581         sorter.add('name2', 'factory2')
0c29cf 582         self.assertEqual(sorter.names, ['name', 'name2'])
MM 583         self.assertEqual(
584             sorter.name2val, {'name': 'factory', 'name2': 'factory2'}
585         )
586         self.assertEqual(sorter.order, [('name', LAST), ('name2', LAST)])
66fe1d 587         sorter.add('name3', 'factory3', before='name2')
0c29cf 588         self.assertEqual(sorter.names, ['name', 'name2', 'name3'])
MM 589         self.assertEqual(
590             sorter.name2val,
591             {'name': 'factory', 'name2': 'factory2', 'name3': 'factory3'},
592         )
593         self.assertEqual(
594             sorter.order, [('name', LAST), ('name2', LAST), ('name3', 'name2')]
595         )
66fe1d 596
CM 597     def test_sorted_ordering_1(self):
598         sorter = self._makeOne()
599         sorter.add('name1', 'factory1')
600         sorter.add('name2', 'factory2')
0c29cf 601         self.assertEqual(
MM 602             sorter.sorted(), [('name1', 'factory1'), ('name2', 'factory2')]
603         )
66fe1d 604
CM 605     def test_sorted_ordering_2(self):
606         from pyramid.util import FIRST
0c29cf 607
66fe1d 608         sorter = self._makeOne()
CM 609         sorter.add('name1', 'factory1')
610         sorter.add('name2', 'factory2', after=FIRST)
0c29cf 611         self.assertEqual(
MM 612             sorter.sorted(), [('name2', 'factory2'), ('name1', 'factory1')]
613         )
66fe1d 614
CM 615     def test_sorted_ordering_3(self):
616         from pyramid.util import FIRST
0c29cf 617
66fe1d 618         sorter = self._makeOne()
CM 619         add = sorter.add
620         add('auth', 'auth_factory', after='browserid')
0c29cf 621         add('dbt', 'dbt_factory')
66fe1d 622         add('retry', 'retry_factory', before='txnmgr', after='exceptionview')
CM 623         add('browserid', 'browserid_factory')
624         add('txnmgr', 'txnmgr_factory', after='exceptionview')
625         add('exceptionview', 'excview_factory', after=FIRST)
0c29cf 626         self.assertEqual(
MM 627             sorter.sorted(),
628             [
629                 ('exceptionview', 'excview_factory'),
630                 ('retry', 'retry_factory'),
631                 ('txnmgr', 'txnmgr_factory'),
632                 ('dbt', 'dbt_factory'),
633                 ('browserid', 'browserid_factory'),
634                 ('auth', 'auth_factory'),
635             ],
636         )
66fe1d 637
CM 638     def test_sorted_ordering_4(self):
639         from pyramid.util import FIRST
0c29cf 640
66fe1d 641         sorter = self._makeOne()
CM 642         add = sorter.add
643         add('exceptionview', 'excview_factory', after=FIRST)
644         add('auth', 'auth_factory', after='browserid')
645         add('retry', 'retry_factory', before='txnmgr', after='exceptionview')
646         add('browserid', 'browserid_factory')
647         add('txnmgr', 'txnmgr_factory', after='exceptionview')
0c29cf 648         add('dbt', 'dbt_factory')
MM 649         self.assertEqual(
650             sorter.sorted(),
651             [
652                 ('exceptionview', 'excview_factory'),
653                 ('retry', 'retry_factory'),
654                 ('txnmgr', 'txnmgr_factory'),
655                 ('browserid', 'browserid_factory'),
656                 ('auth', 'auth_factory'),
657                 ('dbt', 'dbt_factory'),
658             ],
659         )
66fe1d 660
CM 661     def test_sorted_ordering_5(self):
662         from pyramid.util import LAST, FIRST
0c29cf 663
66fe1d 664         sorter = self._makeOne()
CM 665         add = sorter.add
666         add('exceptionview', 'excview_factory')
667         add('auth', 'auth_factory', after=FIRST)
668         add('retry', 'retry_factory', before='txnmgr', after='exceptionview')
669         add('browserid', 'browserid_factory', after=FIRST)
670         add('txnmgr', 'txnmgr_factory', after='exceptionview', before=LAST)
0c29cf 671         add('dbt', 'dbt_factory')
MM 672         self.assertEqual(
673             sorter.sorted(),
674             [
675                 ('browserid', 'browserid_factory'),
676                 ('auth', 'auth_factory'),
677                 ('exceptionview', 'excview_factory'),
678                 ('retry', 'retry_factory'),
679                 ('txnmgr', 'txnmgr_factory'),
680                 ('dbt', 'dbt_factory'),
681             ],
682         )
66fe1d 683
CM 684     def test_sorted_ordering_missing_before_partial(self):
685         from pyramid.exceptions import ConfigurationError
0c29cf 686
66fe1d 687         sorter = self._makeOne()
CM 688         add = sorter.add
689         add('dbt', 'dbt_factory')
690         add('auth', 'auth_factory', after='browserid')
691         add('retry', 'retry_factory', before='txnmgr', after='exceptionview')
692         add('browserid', 'browserid_factory')
693         self.assertRaises(ConfigurationError, sorter.sorted)
694
695     def test_sorted_ordering_missing_after_partial(self):
696         from pyramid.exceptions import ConfigurationError
0c29cf 697
66fe1d 698         sorter = self._makeOne()
CM 699         add = sorter.add
700         add('dbt', 'dbt_factory')
701         add('auth', 'auth_factory', after='txnmgr')
702         add('retry', 'retry_factory', before='dbt', after='exceptionview')
703         add('browserid', 'browserid_factory')
704         self.assertRaises(ConfigurationError, sorter.sorted)
705
706     def test_sorted_ordering_missing_before_and_after_partials(self):
707         from pyramid.exceptions import ConfigurationError
0c29cf 708
66fe1d 709         sorter = self._makeOne()
CM 710         add = sorter.add
711         add('dbt', 'dbt_factory')
712         add('auth', 'auth_factory', after='browserid')
713         add('retry', 'retry_factory', before='foo', after='txnmgr')
714         add('browserid', 'browserid_factory')
715         self.assertRaises(ConfigurationError, sorter.sorted)
716
717     def test_sorted_ordering_missing_before_partial_with_fallback(self):
718         from pyramid.util import LAST
0c29cf 719
66fe1d 720         sorter = self._makeOne()
CM 721         add = sorter.add
722         add('exceptionview', 'excview_factory', before=LAST)
723         add('auth', 'auth_factory', after='browserid')
0c29cf 724         add(
MM 725             'retry',
726             'retry_factory',
727             before=('txnmgr', LAST),
728             after='exceptionview',
729         )
66fe1d 730         add('browserid', 'browserid_factory')
0c29cf 731         add('dbt', 'dbt_factory')
MM 732         self.assertEqual(
733             sorter.sorted(),
734             [
735                 ('exceptionview', 'excview_factory'),
736                 ('retry', 'retry_factory'),
737                 ('browserid', 'browserid_factory'),
738                 ('auth', 'auth_factory'),
739                 ('dbt', 'dbt_factory'),
740             ],
741         )
66fe1d 742
CM 743     def test_sorted_ordering_missing_after_partial_with_fallback(self):
744         from pyramid.util import FIRST
0c29cf 745
66fe1d 746         sorter = self._makeOne()
CM 747         add = sorter.add
748         add('exceptionview', 'excview_factory', after=FIRST)
0c29cf 749         add('auth', 'auth_factory', after=('txnmgr', 'browserid'))
66fe1d 750         add('retry', 'retry_factory', after='exceptionview')
CM 751         add('browserid', 'browserid_factory')
752         add('dbt', 'dbt_factory')
0c29cf 753         self.assertEqual(
MM 754             sorter.sorted(),
755             [
756                 ('exceptionview', 'excview_factory'),
757                 ('retry', 'retry_factory'),
758                 ('browserid', 'browserid_factory'),
759                 ('auth', 'auth_factory'),
760                 ('dbt', 'dbt_factory'),
761             ],
762         )
66fe1d 763
CM 764     def test_sorted_ordering_with_partial_fallbacks(self):
765         from pyramid.util import LAST
0c29cf 766
66fe1d 767         sorter = self._makeOne()
CM 768         add = sorter.add
769         add('exceptionview', 'excview_factory', before=('wontbethere', LAST))
770         add('retry', 'retry_factory', after='exceptionview')
0c29cf 771         add(
MM 772             'browserid', 'browserid_factory', before=('wont2', 'exceptionview')
773         )
774         self.assertEqual(
775             sorter.sorted(),
776             [
777                 ('browserid', 'browserid_factory'),
778                 ('exceptionview', 'excview_factory'),
779                 ('retry', 'retry_factory'),
780             ],
781         )
66fe1d 782
CM 783     def test_sorted_ordering_with_multiple_matching_fallbacks(self):
784         from pyramid.util import LAST
0c29cf 785
66fe1d 786         sorter = self._makeOne()
CM 787         add = sorter.add
788         add('exceptionview', 'excview_factory', before=LAST)
789         add('retry', 'retry_factory', after='exceptionview')
0c29cf 790         add(
MM 791             'browserid', 'browserid_factory', before=('retry', 'exceptionview')
792         )
793         self.assertEqual(
794             sorter.sorted(),
795             [
796                 ('browserid', 'browserid_factory'),
797                 ('exceptionview', 'excview_factory'),
798                 ('retry', 'retry_factory'),
799             ],
800         )
66fe1d 801
CM 802     def test_sorted_ordering_with_missing_fallbacks(self):
803         from pyramid.exceptions import ConfigurationError
804         from pyramid.util import LAST
0c29cf 805
66fe1d 806         sorter = self._makeOne()
CM 807         add = sorter.add
808         add('exceptionview', 'excview_factory', before=LAST)
809         add('retry', 'retry_factory', after='exceptionview')
810         add('browserid', 'browserid_factory', before=('txnmgr', 'auth'))
811         self.assertRaises(ConfigurationError, sorter.sorted)
812
813     def test_sorted_ordering_conflict_direct(self):
814         from pyramid.exceptions import CyclicDependencyError
0c29cf 815
66fe1d 816         sorter = self._makeOne()
CM 817         add = sorter.add
818         add('browserid', 'browserid_factory')
819         add('auth', 'auth_factory', before='browserid', after='browserid')
820         self.assertRaises(CyclicDependencyError, sorter.sorted)
821
822     def test_sorted_ordering_conflict_indirect(self):
823         from pyramid.exceptions import CyclicDependencyError
0c29cf 824
66fe1d 825         sorter = self._makeOne()
CM 826         add = sorter.add
827         add('browserid', 'browserid_factory')
828         add('auth', 'auth_factory', before='browserid')
829         add('dbt', 'dbt_factory', after='browserid', before='auth')
830         self.assertRaises(CyclicDependencyError, sorter.sorted)
831
0c29cf 832
66fe1d 833 class TestSentinel(unittest.TestCase):
CM 834     def test_repr(self):
835         from pyramid.util import Sentinel
0c29cf 836
66fe1d 837         r = repr(Sentinel('ABC'))
CM 838         self.assertEqual(r, 'ABC')
839
d8d3a9 840
1e0d64 841 class TestCallableName(unittest.TestCase):
JA 842     def test_valid_ascii(self):
843         from pyramid.util import get_callable_name
bc37a5 844         from pyramid.compat import text_
fd8402 845
bc37a5 846         if PY2:
fd8402 847             name = text_(b'hello world', 'utf-8')
bc37a5 848         else:
MM 849             name = b'hello world'
fd8402 850
04cc91 851         self.assertEqual(get_callable_name(name), 'hello world')
1e0d64 852
JA 853     def test_invalid_ascii(self):
854         from pyramid.util import get_callable_name
bc37a5 855         from pyramid.compat import text_
1e0d64 856         from pyramid.exceptions import ConfigurationError
JA 857
858         def get_bad_name():
bc37a5 859             if PY2:
1e0d64 860                 name = text_(b'La Pe\xc3\xb1a', 'utf-8')
bc37a5 861             else:
MM 862                 name = b'La Pe\xc3\xb1a'
1e0d64 863
JA 864             get_callable_name(name)
865
866         self.assertRaises(ConfigurationError, get_bad_name)
867
868
19016b 869 class Test_hide_attrs(unittest.TestCase):
MM 870     def _callFUT(self, obj, *attrs):
871         from pyramid.util import hide_attrs
0c29cf 872
19016b 873         return hide_attrs(obj, *attrs)
MM 874
875     def _makeDummy(self):
876         from pyramid.decorator import reify
0c29cf 877
19016b 878         class Dummy(object):
MM 879             x = 1
880
881             @reify
882             def foo(self):
883                 return self.x
0c29cf 884
19016b 885         return Dummy()
MM 886
887     def test_restores_attrs(self):
888         obj = self._makeDummy()
889         obj.bar = 'asdf'
890         orig_foo = obj.foo
891         with self._callFUT(obj, 'foo', 'bar'):
892             obj.foo = object()
893             obj.bar = 'nope'
894         self.assertEqual(obj.foo, orig_foo)
895         self.assertEqual(obj.bar, 'asdf')
896
897     def test_restores_attrs_on_exception(self):
898         obj = self._makeDummy()
899         orig_foo = obj.foo
900         try:
901             with self._callFUT(obj, 'foo'):
902                 obj.foo = object()
903                 raise RuntimeError()
904         except RuntimeError:
905             self.assertEqual(obj.foo, orig_foo)
0c29cf 906         else:  # pragma: no cover
19016b 907             self.fail("RuntimeError not raised")
MM 908
909     def test_restores_attrs_to_none(self):
910         obj = self._makeDummy()
911         obj.foo = None
912         with self._callFUT(obj, 'foo'):
913             obj.foo = object()
914         self.assertEqual(obj.foo, None)
915
916     def test_deletes_attrs(self):
917         obj = self._makeDummy()
918         with self._callFUT(obj, 'foo'):
919             obj.foo = object()
920         self.assertTrue('foo' not in obj.__dict__)
921
922     def test_does_not_delete_attr_if_no_attr_to_delete(self):
923         obj = self._makeDummy()
924         with self._callFUT(obj, 'foo'):
925             pass
926         self.assertTrue('foo' not in obj.__dict__)
927
928
10ddb6 929 def dummyfunc():  # pragma: no cover
0c29cf 930     pass
e49638 931
1e0d64 932
91cd7e 933 class Dummy(object):
MM 934     pass
65dee6 935
DS 936
937 class Test_is_same_domain(unittest.TestCase):
938     def _callFUT(self, *args, **kw):
939         from pyramid.util import is_same_domain
0c29cf 940
65dee6 941         return is_same_domain(*args, **kw)
DS 942
943     def test_it(self):
944         self.assertTrue(self._callFUT("example.com", "example.com"))
945         self.assertFalse(self._callFUT("evil.com", "example.com"))
946         self.assertFalse(self._callFUT("evil.example.com", "example.com"))
947         self.assertFalse(self._callFUT("example.com", ""))
948
949     def test_with_wildcard(self):
950         self.assertTrue(self._callFUT("example.com", ".example.com"))
951         self.assertTrue(self._callFUT("good.example.com", ".example.com"))
952
953     def test_with_port(self):
954         self.assertTrue(self._callFUT("example.com:8080", "example.com:8080"))
955         self.assertFalse(self._callFUT("example.com:8080", "example.com"))
956         self.assertFalse(self._callFUT("example.com", "example.com:8080"))
990fb0 957
MM 958
959 class Test_make_contextmanager(unittest.TestCase):
960     def _callFUT(self, *args, **kw):
961         from pyramid.util import make_contextmanager
0c29cf 962
990fb0 963         return make_contextmanager(*args, **kw)
MM 964
965     def test_with_None(self):
966         mgr = self._callFUT(None)
967         with mgr() as ctx:
968             self.assertIsNone(ctx)
969
970     def test_with_generator(self):
971         def mygen(ctx):
972             yield ctx
0c29cf 973
990fb0 974         mgr = self._callFUT(mygen)
MM 975         with mgr('a') as ctx:
976             self.assertEqual(ctx, 'a')
977
978     def test_with_multiple_yield_generator(self):
979         def mygen():
980             yield 'a'
981             yield 'b'
0c29cf 982
990fb0 983         mgr = self._callFUT(mygen)
MM 984         try:
985             with mgr() as ctx:
986                 self.assertEqual(ctx, 'a')
987         except RuntimeError:
988             pass
989         else:  # pragma: no cover
990             raise AssertionError('expected raise from multiple yields')
991
992     def test_with_regular_fn(self):
993         def mygen():
994             return 'a'
0c29cf 995
990fb0 996         mgr = self._callFUT(mygen)
MM 997         with mgr() as ctx:
998             self.assertEqual(ctx, 'a')
52fde9 999
MM 1000
1001 class Test_takes_one_arg(unittest.TestCase):
1002     def _callFUT(self, view, attr=None, argname=None):
1003         from pyramid.util import takes_one_arg
0c29cf 1004
52fde9 1005         return takes_one_arg(view, attr=attr, argname=argname)
MM 1006
1007     def test_requestonly_newstyle_class_no_init(self):
1008         class foo(object):
1009             """ """
0c29cf 1010
52fde9 1011         self.assertFalse(self._callFUT(foo))
MM 1012
1013     def test_requestonly_newstyle_class_init_toomanyargs(self):
1014         class foo(object):
1015             def __init__(self, context, request):
1016                 """ """
0c29cf 1017
52fde9 1018         self.assertFalse(self._callFUT(foo))
MM 1019
1020     def test_requestonly_newstyle_class_init_onearg_named_request(self):
1021         class foo(object):
1022             def __init__(self, request):
1023                 """ """
0c29cf 1024
52fde9 1025         self.assertTrue(self._callFUT(foo))
MM 1026
1027     def test_newstyle_class_init_onearg_named_somethingelse(self):
1028         class foo(object):
1029             def __init__(self, req):
1030                 """ """
0c29cf 1031
52fde9 1032         self.assertTrue(self._callFUT(foo))
MM 1033
1034     def test_newstyle_class_init_defaultargs_firstname_not_request(self):
1035         class foo(object):
1036             def __init__(self, context, request=None):
1037                 """ """
0c29cf 1038
52fde9 1039         self.assertFalse(self._callFUT(foo))
MM 1040
1041     def test_newstyle_class_init_defaultargs_firstname_request(self):
1042         class foo(object):
1043             def __init__(self, request, foo=1, bar=2):
1044                 """ """
0c29cf 1045
52fde9 1046         self.assertTrue(self._callFUT(foo, argname='request'))
MM 1047
1048     def test_newstyle_class_init_firstname_request_with_secondname(self):
1049         class foo(object):
1050             def __init__(self, request, two):
1051                 """ """
0c29cf 1052
52fde9 1053         self.assertFalse(self._callFUT(foo))
MM 1054
1055     def test_newstyle_class_init_noargs(self):
1056         class foo(object):
1057             def __init__():
1058                 """ """
0c29cf 1059
52fde9 1060         self.assertFalse(self._callFUT(foo))
MM 1061
1062     def test_oldstyle_class_no_init(self):
1063         class foo:
1064             """ """
0c29cf 1065
52fde9 1066         self.assertFalse(self._callFUT(foo))
MM 1067
1068     def test_oldstyle_class_init_toomanyargs(self):
1069         class foo:
1070             def __init__(self, context, request):
1071                 """ """
0c29cf 1072
52fde9 1073         self.assertFalse(self._callFUT(foo))
MM 1074
1075     def test_oldstyle_class_init_onearg_named_request(self):
1076         class foo:
1077             def __init__(self, request):
1078                 """ """
0c29cf 1079
52fde9 1080         self.assertTrue(self._callFUT(foo))
MM 1081
1082     def test_oldstyle_class_init_onearg_named_somethingelse(self):
1083         class foo:
1084             def __init__(self, req):
1085                 """ """
0c29cf 1086
52fde9 1087         self.assertTrue(self._callFUT(foo))
MM 1088
1089     def test_oldstyle_class_init_defaultargs_firstname_not_request(self):
1090         class foo:
1091             def __init__(self, context, request=None):
1092                 """ """
0c29cf 1093
52fde9 1094         self.assertFalse(self._callFUT(foo))
MM 1095
1096     def test_oldstyle_class_init_defaultargs_firstname_request(self):
1097         class foo:
1098             def __init__(self, request, foo=1, bar=2):
1099                 """ """
0c29cf 1100
52fde9 1101         self.assertTrue(self._callFUT(foo, argname='request'), True)
MM 1102
1103     def test_oldstyle_class_init_noargs(self):
1104         class foo:
1105             def __init__():
1106                 """ """
0c29cf 1107
52fde9 1108         self.assertFalse(self._callFUT(foo))
MM 1109
1110     def test_function_toomanyargs(self):
1111         def foo(context, request):
1112             """ """
0c29cf 1113
52fde9 1114         self.assertFalse(self._callFUT(foo))
MM 1115
1116     def test_function_with_attr_false(self):
1117         def bar(context, request):
1118             """ """
0c29cf 1119
52fde9 1120         def foo(context, request):
MM 1121             """ """
0c29cf 1122
52fde9 1123         foo.bar = bar
MM 1124         self.assertFalse(self._callFUT(foo, 'bar'))
1125
1126     def test_function_with_attr_true(self):
1127         def bar(context, request):
1128             """ """
0c29cf 1129
52fde9 1130         def foo(request):
MM 1131             """ """
0c29cf 1132
52fde9 1133         foo.bar = bar
MM 1134         self.assertTrue(self._callFUT(foo, 'bar'))
1135
1136     def test_function_onearg_named_request(self):
1137         def foo(request):
1138             """ """
0c29cf 1139
52fde9 1140         self.assertTrue(self._callFUT(foo))
MM 1141
1142     def test_function_onearg_named_somethingelse(self):
1143         def foo(req):
1144             """ """
0c29cf 1145
52fde9 1146         self.assertTrue(self._callFUT(foo))
MM 1147
1148     def test_function_defaultargs_firstname_not_request(self):
1149         def foo(context, request=None):
1150             """ """
0c29cf 1151
52fde9 1152         self.assertFalse(self._callFUT(foo))
MM 1153
1154     def test_function_defaultargs_firstname_request(self):
1155         def foo(request, foo=1, bar=2):
1156             """ """
0c29cf 1157
52fde9 1158         self.assertTrue(self._callFUT(foo, argname='request'))
MM 1159
1160     def test_function_noargs(self):
1161         def foo():
1162             """ """
0c29cf 1163
52fde9 1164         self.assertFalse(self._callFUT(foo))
MM 1165
1166     def test_instance_toomanyargs(self):
1167         class Foo:
1168             def __call__(self, context, request):
1169                 """ """
0c29cf 1170
52fde9 1171         foo = Foo()
MM 1172         self.assertFalse(self._callFUT(foo))
1173
1174     def test_instance_defaultargs_onearg_named_request(self):
1175         class Foo:
1176             def __call__(self, request):
1177                 """ """
0c29cf 1178
52fde9 1179         foo = Foo()
MM 1180         self.assertTrue(self._callFUT(foo))
1181
1182     def test_instance_defaultargs_onearg_named_somethingelse(self):
1183         class Foo:
1184             def __call__(self, req):
1185                 """ """
0c29cf 1186
52fde9 1187         foo = Foo()
MM 1188         self.assertTrue(self._callFUT(foo))
1189
1190     def test_instance_defaultargs_firstname_not_request(self):
1191         class Foo:
1192             def __call__(self, context, request=None):
1193                 """ """
0c29cf 1194
52fde9 1195         foo = Foo()
MM 1196         self.assertFalse(self._callFUT(foo))
1197
1198     def test_instance_defaultargs_firstname_request(self):
1199         class Foo:
1200             def __call__(self, request, foo=1, bar=2):
1201                 """ """
0c29cf 1202
52fde9 1203         foo = Foo()
MM 1204         self.assertTrue(self._callFUT(foo, argname='request'), True)
1205
1206     def test_instance_nocall(self):
0c29cf 1207         class Foo:
MM 1208             pass
1209
52fde9 1210         foo = Foo()
MM 1211         self.assertFalse(self._callFUT(foo))
1212
1213     def test_method_onearg_named_request(self):
1214         class Foo:
1215             def method(self, request):
1216                 """ """
0c29cf 1217
52fde9 1218         foo = Foo()
MM 1219         self.assertTrue(self._callFUT(foo.method))
1220
1221     def test_function_annotations(self):
1222         def foo(bar):
1223             """ """
0c29cf 1224
52fde9 1225         # avoid SyntaxErrors in python2, this if effectively nop
MM 1226         getattr(foo, '__annotations__', {}).update({'bar': 'baz'})
1227         self.assertTrue(self._callFUT(foo))
1228
1229
1230 class TestSimpleSerializer(unittest.TestCase):
1231     def _makeOne(self):
1232         from pyramid.util import SimpleSerializer
0c29cf 1233
52fde9 1234         return SimpleSerializer()
MM 1235
1236     def test_loads(self):
1237         inst = self._makeOne()
1238         self.assertEqual(inst.loads(b'abc'), text_('abc'))
1239
1240     def test_dumps(self):
1241         inst = self._makeOne()
1242         self.assertEqual(inst.dumps('abc'), bytes_('abc'))