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