Chris McDonough
2013-07-31 5fc0d36724a6197c8c0106e846d8e78e1219b1fe
commit | author | age
5bf23f 1 import unittest
586401 2 from pyramid.compat import text_
5bf23f 3
9c8ec5 4 class TestPredicateList(unittest.TestCase):
CM 5
6     def _makeOne(self):
7         from pyramid.config.util import PredicateList
8         from pyramid.config import predicates
9         inst = PredicateList()
10         for name, factory in (
11             ('xhr', predicates.XHRPredicate),
12             ('request_method', predicates.RequestMethodPredicate),
13             ('path_info', predicates.PathInfoPredicate),
14             ('request_param', predicates.RequestParamPredicate),
15             ('header', predicates.HeaderPredicate),
16             ('accept', predicates.AcceptPredicate),
17             ('containment', predicates.ContainmentPredicate),
18             ('request_type', predicates.RequestTypePredicate),
19             ('match_param', predicates.MatchParamPredicate),
20             ('custom', predicates.CustomPredicate),
21             ('traverse', predicates.TraversePredicate),
22             ):
23             inst.add(name, factory)
24         return inst
25
5bf23f 26     def _callFUT(self, **kw):
9c8ec5 27         inst = self._makeOne()
CM 28         config = DummyConfigurator()
29         return inst.make(config, **kw)
5bf23f 30
CM 31     def test_ordering_xhr_and_request_method_trump_only_containment(self):
32         order1, _, _ = self._callFUT(xhr=True, request_method='GET')
33         order2, _, _ = self._callFUT(containment=True)
34         self.assertTrue(order1 < order2)
35
36     def test_ordering_number_of_predicates(self):
9c8ec5 37         from pyramid.config.util import predvalseq
5bf23f 38         order1, _, _ = self._callFUT(
CM 39             xhr='xhr',
40             request_method='request_method',
41             path_info='path_info',
42             request_param='param',
718a44 43             match_param='foo=bar',
5bf23f 44             header='header',
CM 45             accept='accept',
46             containment='containment',
47             request_type='request_type',
9c8ec5 48             custom=predvalseq([DummyCustomPredicate()]),
5bf23f 49             )
CM 50         order2, _, _ = self._callFUT(
51             xhr='xhr',
52             request_method='request_method',
53             path_info='path_info',
54             request_param='param',
718a44 55             match_param='foo=bar',
5bf23f 56             header='header',
CM 57             accept='accept',
58             containment='containment',
59             request_type='request_type',
9c8ec5 60             custom=predvalseq([DummyCustomPredicate()]),
5bf23f 61             )
CM 62         order3, _, _ = self._callFUT(
63             xhr='xhr',
64             request_method='request_method',
65             path_info='path_info',
66             request_param='param',
718a44 67             match_param='foo=bar',
5bf23f 68             header='header',
CM 69             accept='accept',
70             containment='containment',
71             request_type='request_type',
72             )
73         order4, _, _ = self._callFUT(
74             xhr='xhr',
75             request_method='request_method',
76             path_info='path_info',
77             request_param='param',
718a44 78             match_param='foo=bar',
5bf23f 79             header='header',
CM 80             accept='accept',
81             containment='containment',
82             )
83         order5, _, _ = self._callFUT(
84             xhr='xhr',
85             request_method='request_method',
86             path_info='path_info',
87             request_param='param',
718a44 88             match_param='foo=bar',
5bf23f 89             header='header',
CM 90             accept='accept',
91             )
92         order6, _, _ = self._callFUT(
93             xhr='xhr',
94             request_method='request_method',
95             path_info='path_info',
96             request_param='param',
718a44 97             match_param='foo=bar',
5bf23f 98             header='header',
CM 99             )
100         order7, _, _ = self._callFUT(
101             xhr='xhr',
102             request_method='request_method',
103             path_info='path_info',
104             request_param='param',
718a44 105             match_param='foo=bar',
5bf23f 106             )
CM 107         order8, _, _ = self._callFUT(
108             xhr='xhr',
109             request_method='request_method',
110             path_info='path_info',
718a44 111             request_param='param',
5bf23f 112             )
CM 113         order9, _, _ = self._callFUT(
114             xhr='xhr',
115             request_method='request_method',
718a44 116             path_info='path_info',
5bf23f 117             )
CM 118         order10, _, _ = self._callFUT(
119             xhr='xhr',
718a44 120             request_method='request_method',
5bf23f 121             )
CM 122         order11, _, _ = self._callFUT(
718a44 123             xhr='xhr',
MM 124             )
125         order12, _, _ = self._callFUT(
5bf23f 126             )
CM 127         self.assertEqual(order1, order2)
128         self.assertTrue(order3 > order2)
129         self.assertTrue(order4 > order3)
130         self.assertTrue(order5 > order4)
131         self.assertTrue(order6 > order5)
132         self.assertTrue(order7 > order6)
133         self.assertTrue(order8 > order7)
134         self.assertTrue(order9 > order8)
135         self.assertTrue(order10 > order9)
136         self.assertTrue(order11 > order10)
718a44 137         self.assertTrue(order12 > order10)
5bf23f 138
CM 139     def test_ordering_importance_of_predicates(self):
9c8ec5 140         from pyramid.config.util import predvalseq
5bf23f 141         order1, _, _ = self._callFUT(
CM 142             xhr='xhr',
143             )
144         order2, _, _ = self._callFUT(
145             request_method='request_method',
146             )
147         order3, _, _ = self._callFUT(
148             path_info='path_info',
149             )
150         order4, _, _ = self._callFUT(
151             request_param='param',
152             )
153         order5, _, _ = self._callFUT(
154             header='header',
155             )
156         order6, _, _ = self._callFUT(
157             accept='accept',
158             )
159         order7, _, _ = self._callFUT(
160             containment='containment',
161             )
162         order8, _, _ = self._callFUT(
163             request_type='request_type',
164             )
165         order9, _, _ = self._callFUT(
718a44 166             match_param='foo=bar',
MM 167             )
168         order10, _, _ = self._callFUT(
9c8ec5 169             custom=predvalseq([DummyCustomPredicate()]),
5bf23f 170             )
CM 171         self.assertTrue(order1 > order2)
172         self.assertTrue(order2 > order3)
173         self.assertTrue(order3 > order4)
174         self.assertTrue(order4 > order5)
175         self.assertTrue(order5 > order6)
176         self.assertTrue(order6 > order7)
177         self.assertTrue(order7 > order8)
178         self.assertTrue(order8 > order9)
718a44 179         self.assertTrue(order9 > order10)
5bf23f 180
CM 181     def test_ordering_importance_and_number(self):
9c8ec5 182         from pyramid.config.util import predvalseq
5bf23f 183         order1, _, _ = self._callFUT(
CM 184             xhr='xhr',
185             request_method='request_method',
186             )
187         order2, _, _ = self._callFUT(
9c8ec5 188             custom=predvalseq([DummyCustomPredicate()]),
5bf23f 189             )
CM 190         self.assertTrue(order1 < order2)
191
192         order1, _, _ = self._callFUT(
193             xhr='xhr',
194             request_method='request_method',
195             )
196         order2, _, _ = self._callFUT(
197             request_method='request_method',
9c8ec5 198             custom=predvalseq([DummyCustomPredicate()]),
5bf23f 199             )
CM 200         self.assertTrue(order1 > order2)
201
202         order1, _, _ = self._callFUT(
203             xhr='xhr',
204             request_method='request_method',
205             path_info='path_info',
206             )
207         order2, _, _ = self._callFUT(
208             request_method='request_method',
9c8ec5 209             custom=predvalseq([DummyCustomPredicate()]),
5bf23f 210             )
CM 211         self.assertTrue(order1 < order2)
212
213         order1, _, _ = self._callFUT(
214             xhr='xhr',
215             request_method='request_method',
216             path_info='path_info',
217             )
218         order2, _, _ = self._callFUT(
219             xhr='xhr',
220             request_method='request_method',
9c8ec5 221             custom=predvalseq([DummyCustomPredicate()]),
5bf23f 222             )
CM 223         self.assertTrue(order1 > order2)
224
225     def test_different_custom_predicates_with_same_hash(self):
9c8ec5 226         from pyramid.config.util import predvalseq
5bf23f 227         class PredicateWithHash(object):
CM 228             def __hash__(self):
229                 return 1
230         a = PredicateWithHash()
231         b = PredicateWithHash()
9c8ec5 232         _, _, a_phash = self._callFUT(custom=predvalseq([a]))
CM 233         _, _, b_phash = self._callFUT(custom=predvalseq([b]))
5bf23f 234         self.assertEqual(a_phash, b_phash)
CM 235
236     def test_traverse_has_remainder_already(self):
237         order, predicates, phash = self._callFUT(traverse='/1/:a/:b')
238         self.assertEqual(len(predicates), 1)
239         pred = predicates[0]
240         info = {'traverse':'abc'}
241         request = DummyRequest()
242         result = pred(info, request)
243         self.assertEqual(result, True)
244         self.assertEqual(info, {'traverse':'abc'})
245
246     def test_traverse_matches(self):
247         order, predicates, phash = self._callFUT(traverse='/1/:a/:b')
248         self.assertEqual(len(predicates), 1)
249         pred = predicates[0]
250         info = {'match':{'a':'a', 'b':'b'}}
251         request = DummyRequest()
252         result = pred(info, request)
253         self.assertEqual(result, True)
254         self.assertEqual(info, {'match':
255                                 {'a':'a', 'b':'b', 'traverse':('1', 'a', 'b')}})
256
586401 257     def test_traverse_matches_with_highorder_chars(self):
CM 258         order, predicates, phash = self._callFUT(
403dc9 259             traverse=text_(b'/La Pe\xc3\xb1a/{x}', 'utf-8'))
586401 260         self.assertEqual(len(predicates), 1)
CM 261         pred = predicates[0]
262         info = {'match':{'x':text_(b'Qu\xc3\xa9bec', 'utf-8')}}
263         request = DummyRequest()
264         result = pred(info, request)
265         self.assertEqual(result, True)
266         self.assertEqual(
267             info['match']['traverse'],
268             (text_(b'La Pe\xc3\xb1a', 'utf-8'),
269              text_(b'Qu\xc3\xa9bec', 'utf-8'))
270              )
271
c81dbd 272     def test_custom_predicates_can_affect_traversal(self):
9c8ec5 273         from pyramid.config.util import predvalseq
c81dbd 274         def custom(info, request):
MM 275             m = info['match']
276             m['dummy'] = 'foo'
277             return True
9c8ec5 278         _, predicates, _ = self._callFUT(
CM 279             custom=predvalseq([custom]),
280             traverse='/1/:dummy/:a')
c81dbd 281         self.assertEqual(len(predicates), 2)
MM 282         info = {'match':{'a':'a'}}
283         request = DummyRequest()
284         self.assertTrue(all([p(info, request) for p in predicates]))
285         self.assertEqual(info, {'match':
286                                 {'a':'a', 'dummy':'foo',
287                                  'traverse':('1', 'foo', 'a')}})
288
5bf23f 289     def test_predicate_text_is_correct(self):
9c8ec5 290         from pyramid.config.util import predvalseq
5bf23f 291         _, predicates, _ = self._callFUT(
CM 292             xhr='xhr',
293             request_method='request_method',
294             path_info='path_info',
295             request_param='param',
296             header='header',
297             accept='accept',
298             containment='containment',
299             request_type='request_type',
9c8ec5 300             custom=predvalseq(
CM 301                 [
302                     DummyCustomPredicate(),
5bf23f 303                     DummyCustomPredicate.classmethod_predicate,
9c8ec5 304                     DummyCustomPredicate.classmethod_predicate_no_text,
CM 305                 ]
306             ),
718a44 307             match_param='foo=bar')
9c8ec5 308         self.assertEqual(predicates[0].text(), 'xhr = True')
CM 309         self.assertEqual(predicates[1].text(),
310                          "request_method = request_method")
311         self.assertEqual(predicates[2].text(), 'path_info = path_info')
312         self.assertEqual(predicates[3].text(), 'request_param param')
313         self.assertEqual(predicates[4].text(), 'header header')
314         self.assertEqual(predicates[5].text(), 'accept = accept')
315         self.assertEqual(predicates[6].text(), 'containment = containment')
316         self.assertEqual(predicates[7].text(), 'request_type = request_type')
317         self.assertEqual(predicates[8].text(), "match_param foo=bar")
318         self.assertEqual(predicates[9].text(), 'custom predicate')
319         self.assertEqual(predicates[10].text(), 'classmethod predicate')
320         self.assertTrue(predicates[11].text().startswith('custom predicate'))
718a44 321
MM 322     def test_match_param_from_string(self):
323         _, predicates, _ = self._callFUT(match_param='foo=bar')
324         request = DummyRequest()
325         request.matchdict = {'foo':'bar', 'baz':'bum'}
326         self.assertTrue(predicates[0](Dummy(), request))
327
328     def test_match_param_from_string_fails(self):
329         _, predicates, _ = self._callFUT(match_param='foo=bar')
330         request = DummyRequest()
331         request.matchdict = {'foo':'bum', 'baz':'bum'}
332         self.assertFalse(predicates[0](Dummy(), request))
333
334     def test_match_param_from_dict(self):
835d48 335         _, predicates, _ = self._callFUT(match_param=('foo=bar','baz=bum'))
718a44 336         request = DummyRequest()
MM 337         request.matchdict = {'foo':'bar', 'baz':'bum'}
338         self.assertTrue(predicates[0](Dummy(), request))
339
340     def test_match_param_from_dict_fails(self):
835d48 341         _, predicates, _ = self._callFUT(match_param=('foo=bar','baz=bum'))
718a44 342         request = DummyRequest()
MM 343         request.matchdict = {'foo':'bar', 'baz':'foo'}
344         self.assertFalse(predicates[0](Dummy(), request))
5bf23f 345
49f082 346     def test_request_method_sequence(self):
CM 347         _, predicates, _ = self._callFUT(request_method=('GET', 'HEAD'))
348         request = DummyRequest()
349         request.method = 'HEAD'
350         self.assertTrue(predicates[0](Dummy(), request))
351         request.method = 'GET'
352         self.assertTrue(predicates[0](Dummy(), request))
353         request.method = 'POST'
354         self.assertFalse(predicates[0](Dummy(), request))
355
356     def test_request_method_ordering_hashes_same(self):
357         hash1, _, __= self._callFUT(request_method=('GET', 'HEAD'))
358         hash2, _, __= self._callFUT(request_method=('HEAD', 'GET'))
359         self.assertEqual(hash1, hash2)
360         hash1, _, __= self._callFUT(request_method=('GET',))
361         hash2, _, __= self._callFUT(request_method='GET')
362         self.assertEqual(hash1, hash2)
363
adf323 364     def test_unknown_predicate(self):
CM 365         from pyramid.exceptions import ConfigurationError
366         self.assertRaises(ConfigurationError, self._callFUT, unknown=1)
32333e 367
5fc0d3 368     def test_notted_configerror(self):
CM 369         from pyramid.exceptions import ConfigurationError
32333e 370         from pyramid.config import not_
5fc0d3 371         self.assertRaises(ConfigurationError, self._callFUT,
32333e 372             xhr='xhr',
CM 373             request_method=not_('POST'),
374             header=not_('header'),
375             )
5fc0d3 376
CM 377     def test_notted_ok(self):
378         from pyramid.config import not_
379         _, predicates, _ = self._callFUT(
380             xhr='xhr',
381             path_info=not_('/path_info'),
382             header=not_('header'),
383             )
384         from pyramid.testing import DummyRequest
385         request = DummyRequest()
386         request.upath_info = request.path_info
387         request.is_xhr = False
32333e 388         self.assertEqual(predicates[0].text(), 'xhr = True')
5fc0d3 389         self.assertEqual(predicates[1].text(), '!path_info = /path_info')
CM 390         self.assertEqual(predicates[2].text(),
391                          "!header header")
392         self.assertEqual(predicates[0](None, request), False)
32333e 393         self.assertEqual(predicates[1](None, request), True)
CM 394         self.assertEqual(predicates[2](None, request), True)
395         
adf323 396         
28fc3d 397 class Test_takes_one_arg(unittest.TestCase):
CM 398     def _callFUT(self, view, attr=None, argname=None):
399         from pyramid.config.util import takes_one_arg
400         return takes_one_arg(view, attr=attr, argname=argname)
401
402     def test_requestonly_newstyle_class_no_init(self):
403         class foo(object):
404             """ """
405         self.assertFalse(self._callFUT(foo))
406
407     def test_requestonly_newstyle_class_init_toomanyargs(self):
408         class foo(object):
409             def __init__(self, context, request):
410                 """ """
411         self.assertFalse(self._callFUT(foo))
412
413     def test_requestonly_newstyle_class_init_onearg_named_request(self):
414         class foo(object):
415             def __init__(self, request):
416                 """ """
417         self.assertTrue(self._callFUT(foo))
418
419     def test_newstyle_class_init_onearg_named_somethingelse(self):
420         class foo(object):
421             def __init__(self, req):
422                 """ """
423         self.assertTrue(self._callFUT(foo))
424
425     def test_newstyle_class_init_defaultargs_firstname_not_request(self):
426         class foo(object):
427             def __init__(self, context, request=None):
428                 """ """
429         self.assertFalse(self._callFUT(foo))
430
431     def test_newstyle_class_init_defaultargs_firstname_request(self):
432         class foo(object):
433             def __init__(self, request, foo=1, bar=2):
434                 """ """
435         self.assertTrue(self._callFUT(foo, argname='request'))
436
437     def test_newstyle_class_init_firstname_request_with_secondname(self):
438         class foo(object):
439             def __init__(self, request, two):
440                 """ """
441         self.assertFalse(self._callFUT(foo))
442
443     def test_newstyle_class_init_noargs(self):
444         class foo(object):
445             def __init__():
446                 """ """
447         self.assertFalse(self._callFUT(foo))
448
449     def test_oldstyle_class_no_init(self):
450         class foo:
451             """ """
452         self.assertFalse(self._callFUT(foo))
453
454     def test_oldstyle_class_init_toomanyargs(self):
455         class foo:
456             def __init__(self, context, request):
457                 """ """
458         self.assertFalse(self._callFUT(foo))
459
460     def test_oldstyle_class_init_onearg_named_request(self):
461         class foo:
462             def __init__(self, request):
463                 """ """
464         self.assertTrue(self._callFUT(foo))
465
466     def test_oldstyle_class_init_onearg_named_somethingelse(self):
467         class foo:
468             def __init__(self, req):
469                 """ """
470         self.assertTrue(self._callFUT(foo))
471
472     def test_oldstyle_class_init_defaultargs_firstname_not_request(self):
473         class foo:
474             def __init__(self, context, request=None):
475                 """ """
476         self.assertFalse(self._callFUT(foo))
477
478     def test_oldstyle_class_init_defaultargs_firstname_request(self):
479         class foo:
480             def __init__(self, request, foo=1, bar=2):
481                 """ """
482         self.assertTrue(self._callFUT(foo, argname='request'), True)
483
484     def test_oldstyle_class_init_noargs(self):
485         class foo:
486             def __init__():
487                 """ """
488         self.assertFalse(self._callFUT(foo))
489
490     def test_function_toomanyargs(self):
491         def foo(context, request):
492             """ """
493         self.assertFalse(self._callFUT(foo))
494
495     def test_function_with_attr_false(self):
496         def bar(context, request):
497             """ """
498         def foo(context, request):
499             """ """
500         foo.bar = bar
501         self.assertFalse(self._callFUT(foo, 'bar'))
502
503     def test_function_with_attr_true(self):
504         def bar(context, request):
505             """ """
506         def foo(request):
507             """ """
508         foo.bar = bar
509         self.assertTrue(self._callFUT(foo, 'bar'))
510
511     def test_function_onearg_named_request(self):
512         def foo(request):
513             """ """
514         self.assertTrue(self._callFUT(foo))
515
516     def test_function_onearg_named_somethingelse(self):
517         def foo(req):
518             """ """
519         self.assertTrue(self._callFUT(foo))
520
521     def test_function_defaultargs_firstname_not_request(self):
522         def foo(context, request=None):
523             """ """
524         self.assertFalse(self._callFUT(foo))
525
526     def test_function_defaultargs_firstname_request(self):
527         def foo(request, foo=1, bar=2):
528             """ """
529         self.assertTrue(self._callFUT(foo, argname='request'))
530
531     def test_function_noargs(self):
532         def foo():
533             """ """
534         self.assertFalse(self._callFUT(foo))
535
536     def test_instance_toomanyargs(self):
537         class Foo:
538             def __call__(self, context, request):
539                 """ """
540         foo = Foo()
541         self.assertFalse(self._callFUT(foo))
542
543     def test_instance_defaultargs_onearg_named_request(self):
544         class Foo:
545             def __call__(self, request):
546                 """ """
547         foo = Foo()
548         self.assertTrue(self._callFUT(foo))
549
550     def test_instance_defaultargs_onearg_named_somethingelse(self):
551         class Foo:
552             def __call__(self, req):
553                 """ """
554         foo = Foo()
555         self.assertTrue(self._callFUT(foo))
556
557     def test_instance_defaultargs_firstname_not_request(self):
558         class Foo:
559             def __call__(self, context, request=None):
560                 """ """
561         foo = Foo()
562         self.assertFalse(self._callFUT(foo))
563
564     def test_instance_defaultargs_firstname_request(self):
565         class Foo:
566             def __call__(self, request, foo=1, bar=2):
567                 """ """
568         foo = Foo()
569         self.assertTrue(self._callFUT(foo, argname='request'), True)
570
571     def test_instance_nocall(self):
572         class Foo: pass
573         foo = Foo()
574         self.assertFalse(self._callFUT(foo))
575     
576     def test_method_onearg_named_request(self):
577         class Foo:
578             def method(self, request):
579                 """ """
580         foo = Foo()
581         self.assertTrue(self._callFUT(foo.method))
582
32333e 583 class TestNotted(unittest.TestCase):
CM 584     def _makeOne(self, predicate):
585         from pyramid.config.util import Notted
586         return Notted(predicate)
ac0ece 587
32333e 588     def test_it_with_phash_val(self):
CM 589         pred = DummyPredicate('val')
590         inst = self._makeOne(pred)
591         self.assertEqual(inst.text(), '!val')
592         self.assertEqual(inst.phash(), '!val')
593         self.assertEqual(inst(None, None), False)
594
595     def test_it_without_phash_val(self):
596         pred = DummyPredicate('')
597         inst = self._makeOne(pred)
598         self.assertEqual(inst.text(), '')
599         self.assertEqual(inst.phash(), '')
600         self.assertEqual(inst(None, None), True)
601         
602 class DummyPredicate(object):
603     def __init__(self, result):
604         self.result = result
605         
606     def text(self):
607         return self.result
608
609     phash = text
610
611     def __call__(self, context, request):
612         return True
613     
5bf23f 614 class DummyCustomPredicate(object):
CM 615     def __init__(self):
616         self.__text__ = 'custom predicate'
617
618     def classmethod_predicate(*args): pass
619     classmethod_predicate.__text__ = 'classmethod predicate'
620     classmethod_predicate = classmethod(classmethod_predicate)
621
622     @classmethod
623     def classmethod_predicate_no_text(*args): pass # pragma: no cover
624
718a44 625 class Dummy:
MM 626     pass
627
5bf23f 628 class DummyRequest:
CM 629     subpath = ()
630     matchdict = None
631     def __init__(self, environ=None):
632         if environ is None:
633             environ = {}
634         self.environ = environ
635         self.params = {}
636         self.cookies = {}
637
9c8ec5 638 class DummyConfigurator(object):
CM 639     def maybe_dotted(self, thing):
640         return thing
641