Mercurial > piecrust2
comparison tests/test_routing.py @ 792:58ebf50235a5
routing: Simplify how routes are defined.
* No more declaring the type of route parameters -- the sources and generators
already know what type each parameter is supposed to be.
* Same for variadic parameters -- we know already.
* Update cache version to force a clear reload of the config.
* Update tests.
TODO: simplify code in the `Route` class to use source or generator transparently.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Wed, 07 Sep 2016 08:58:41 -0700 |
parents | f6f9a284a5f3 |
children | 72f17534d58e |
comparison
equal
deleted
inserted
replaced
791:504d6817352d | 792:58ebf50235a5 |
---|---|
1 import urllib.parse | 1 import urllib.parse |
2 import mock | |
2 import pytest | 3 import pytest |
3 from piecrust.routing import Route | 4 from piecrust.routing import Route, RouteParameter |
5 from piecrust.sources.base import PageSource | |
4 from .mockutil import get_mock_app | 6 from .mockutil import get_mock_app |
5 | 7 |
6 | 8 |
7 @pytest.mark.parametrize( | 9 def _getMockSource(name, params): |
8 'config, metadata, expected', | 10 route_params = [] |
11 for p in params: | |
12 if isinstance(p, tuple): | |
13 if p[1] == 'path': | |
14 t = RouteParameter.TYPE_PATH | |
15 elif p[1] == 'int2': | |
16 t = RouteParameter.TYPE_INT2 | |
17 elif p[2] == 'int4': | |
18 t = RouteParameter.TYPE_INT4 | |
19 route_params.append(RouteParameter(p[0], t)) | |
20 else: | |
21 route_params.append(RouteParameter(p, RouteParameter.TYPE_STRING)) | |
22 | |
23 src = mock.MagicMock(spec=PageSource) | |
24 src.name = name | |
25 src.getSupportedRouteParameters = lambda: route_params | |
26 return src | |
27 | |
28 | |
29 @pytest.mark.parametrize( | |
30 'config, metadata, params, expected', | |
9 [ | 31 [ |
10 ({'url': '/%foo%'}, | 32 ({'url': '/%foo%'}, |
11 {'foo': 'bar'}, True), | 33 {'foo': 'bar'}, ['foo'], True), |
12 ({'url': '/%foo%'}, | 34 ({'url': '/%foo%'}, |
13 {'zoo': 'zar', 'foo': 'bar'}, True), | 35 {'zoo': 'zar', 'foo': 'bar'}, ['foo'], True), |
14 ({'url': '/%foo%'}, | 36 ({'url': '/%foo%'}, |
15 {'zoo': 'zar'}, False), | 37 {'zoo': 'zar'}, ['foo'], False), |
16 ({'url': '/%foo%/%zoo%'}, | 38 ({'url': '/%foo%/%zoo%'}, |
17 {'zoo': 'zar'}, False) | 39 {'zoo': 'zar'}, ['foo', 'zoo'], False) |
18 ]) | 40 ]) |
19 def test_matches_metadata(config, metadata, expected): | 41 def test_matches_metadata(config, metadata, params, expected): |
20 app = get_mock_app() | 42 app = get_mock_app() |
21 app.config.set('site/root', '/') | 43 app.config.set('site/root', '/') |
44 app.sources = [_getMockSource('blah', params)] | |
45 | |
22 config.setdefault('source', 'blah') | 46 config.setdefault('source', 'blah') |
23 route = Route(app, config) | 47 route = Route(app, config) |
24 m = route.matchesMetadata(metadata) | 48 m = route.matchesMetadata(metadata) |
25 assert m == expected | 49 assert m == expected |
26 | 50 |
27 | 51 |
28 @pytest.mark.parametrize( | 52 @pytest.mark.parametrize( |
29 'site_root, route_pattern, expected_func_parameters', | 53 'site_root, route_pattern, params, expected_func_parameters', |
30 [ | 54 [ |
31 ('/', '/%foo%', ['foo']), | 55 ('/', '/%foo%', ['foo'], ['foo']), |
32 ('/', '/%path:foo%', ['foo']), | 56 ('/', '/%foo%', [('foo', 'path')], ['foo']), |
33 ('/', '/%foo%/%bar%', ['foo', 'bar']), | 57 ('/', '/%foo%/%bar%', ['foo', 'bar'], ['foo', 'bar']), |
34 ('/', '/%foo%/%path:bar%', ['foo', 'bar']), | 58 ('/', '/%foo%/%bar%', ['foo', ('bar', 'path')], ['foo', 'bar']), |
35 ('/something', '/%foo%', ['foo']), | 59 ('/something', '/%foo%', ['foo'], ['foo']), |
36 ('/something', '/%path:foo%', ['foo']), | 60 ('/something', '/%foo%', [('foo', 'path')], ['foo']), |
37 ('/something', '/%foo%/%bar%', ['foo', 'bar']), | 61 ('/something', '/%foo%/%bar%', ['foo', 'bar'], ['foo', 'bar']), |
38 ('/something', '/%foo%/%path:bar%', ['foo', 'bar']), | 62 ('/something', '/%foo%/%bar%', ['foo', ('bar', 'path')], ['foo', 'bar']), |
39 ('/~johndoe', '/%foo%', ['foo']), | 63 ('/~johndoe', '/%foo%', ['foo'], ['foo']), |
40 ('/~johndoe', '/%path:foo%', ['foo']), | 64 ('/~johndoe', '/%foo%', [('foo', 'path')], ['foo']), |
41 ('/~johndoe', '/%foo%/%bar%', ['foo', 'bar']), | 65 ('/~johndoe', '/%foo%/%bar%', ['foo', 'bar'], ['foo', 'bar']), |
42 ('/~johndoe', '/%foo%/%path:bar%', ['foo', 'bar']) | 66 ('/~johndoe', '/%foo%/%bar%', ['foo', ('bar', 'path')], ['foo', 'bar']) |
43 ]) | 67 ]) |
44 def test_required_metadata(site_root, route_pattern, | 68 def test_required_metadata(site_root, route_pattern, params, |
45 expected_func_parameters): | 69 expected_func_parameters): |
46 app = get_mock_app() | 70 app = get_mock_app() |
47 app.config.set('site/root', site_root.rstrip('/') + '/') | 71 app.config.set('site/root', site_root.rstrip('/') + '/') |
72 app.sources = [_getMockSource('blah', params)] | |
73 | |
48 config = {'url': route_pattern, 'source': 'blah'} | 74 config = {'url': route_pattern, 'source': 'blah'} |
49 route = Route(app, config) | 75 route = Route(app, config) |
50 assert route.func_parameters == expected_func_parameters | 76 assert route.uri_params == expected_func_parameters |
51 | 77 |
52 | 78 |
53 @pytest.mark.parametrize( | 79 @pytest.mark.parametrize( |
54 'site_root, config, uri, expected_match', | 80 'site_root, config, params, uri, expected_match', |
55 [ | 81 [ |
56 ('/', {'url': '/%foo%'}, | 82 ('/', {'url': '/%foo%'}, |
83 ['foo'], | |
57 'something', | 84 'something', |
58 {'foo': 'something'}), | 85 {'foo': 'something'}), |
59 ('/', {'url': '/%foo%'}, | 86 ('/', {'url': '/%foo%'}, |
87 ['foo'], | |
60 'something/other', | 88 'something/other', |
61 None), | 89 None), |
62 ('/', {'url': '/%path:foo%'}, | 90 ('/', {'url': '/%foo%'}, |
63 'something/other', | 91 [('foo', 'path')], |
64 {'foo': 'something/other'}), | 92 'something/other', |
65 ('/', {'url': '/%path:foo%'}, | 93 {'foo': 'something/other'}), |
94 ('/', {'url': '/%foo%'}, | |
95 [('foo', 'path')], | |
66 '', | 96 '', |
67 {'foo': ''}), | 97 {'foo': ''}), |
68 ('/', {'url': '/prefix/%path:foo%'}, | 98 ('/', {'url': '/prefix/%foo%'}, |
99 [('foo', 'path')], | |
69 'prefix/something/other', | 100 'prefix/something/other', |
70 {'foo': 'something/other'}), | 101 {'foo': 'something/other'}), |
71 ('/', {'url': '/prefix/%path:foo%'}, | 102 ('/', {'url': '/prefix/%foo%'}, |
103 [('foo', 'path')], | |
72 'prefix/', | 104 'prefix/', |
73 {'foo': ''}), | 105 {'foo': ''}), |
74 ('/', {'url': '/prefix/%path:foo%'}, | 106 ('/', {'url': '/prefix/%foo%'}, |
107 [('foo', 'path')], | |
75 'prefix', | 108 'prefix', |
76 {'foo': ''}), | 109 {'foo': ''}), |
77 | 110 |
78 ('/blah', {'url': '/%foo%'}, | 111 ('/blah', {'url': '/%foo%'}, |
112 ['foo'], | |
79 'something', | 113 'something', |
80 {'foo': 'something'}), | 114 {'foo': 'something'}), |
81 ('/blah', {'url': '/%foo%'}, | 115 ('/blah', {'url': '/%foo%'}, |
116 ['foo'], | |
82 'something/other', | 117 'something/other', |
83 None), | 118 None), |
84 ('/blah', {'url': '/%path:foo%'}, | 119 ('/blah', {'url': '/%foo%'}, |
85 'something/other', | 120 [('foo', 'path')], |
86 {'foo': 'something/other'}), | 121 'something/other', |
87 ('/blah', {'url': '/%path:foo%'}, | 122 {'foo': 'something/other'}), |
123 ('/blah', {'url': '/%foo%'}, | |
124 [('foo', 'path')], | |
88 '', | 125 '', |
89 {'foo': ''}), | 126 {'foo': ''}), |
90 ('/blah', {'url': '/prefix/%path:foo%'}, | 127 ('/blah', {'url': '/prefix/%foo%'}, |
128 [('foo', 'path')], | |
91 'prefix/something/other', | 129 'prefix/something/other', |
92 {'foo': 'something/other'}), | 130 {'foo': 'something/other'}), |
93 ('/blah', {'url': '/prefix/%path:foo%'}, | 131 ('/blah', {'url': '/prefix/%foo%'}, |
132 [('foo', 'path')], | |
94 'prefix/', | 133 'prefix/', |
95 {'foo': ''}), | 134 {'foo': ''}), |
96 ('/blah', {'url': '/prefix/%path:foo%'}, | 135 ('/blah', {'url': '/prefix/%foo%'}, |
136 [('foo', 'path')], | |
97 'prefix', | 137 'prefix', |
98 {'foo': ''}), | 138 {'foo': ''}), |
99 | 139 |
100 ('/~johndoe', {'url': '/%foo%'}, | 140 ('/~johndoe', {'url': '/%foo%'}, |
141 ['foo'], | |
101 'something', | 142 'something', |
102 {'foo': 'something'}), | 143 {'foo': 'something'}), |
103 ('/~johndoe', {'url': '/%foo%'}, | 144 ('/~johndoe', {'url': '/%foo%'}, |
145 ['foo'], | |
104 'something/other', | 146 'something/other', |
105 None), | 147 None), |
106 ('/~johndoe', {'url': '/%path:foo%'}, | 148 ('/~johndoe', {'url': '/%foo%'}, |
107 'something/other', | 149 [('foo', 'path')], |
108 {'foo': 'something/other'}), | 150 'something/other', |
109 ('/~johndoe', {'url': '/%path:foo%'}, | 151 {'foo': 'something/other'}), |
152 ('/~johndoe', {'url': '/%foo%'}, | |
153 [('foo', 'path')], | |
110 '', | 154 '', |
111 {'foo': ''}), | 155 {'foo': ''}), |
112 ('/~johndoe', {'url': '/prefix/%path:foo%'}, | 156 ('/~johndoe', {'url': '/prefix/%foo%'}, |
157 [('foo', 'path')], | |
113 'prefix/something/other', | 158 'prefix/something/other', |
114 {'foo': 'something/other'}), | 159 {'foo': 'something/other'}), |
115 ('/~johndoe', {'url': '/prefix/%path:foo%'}, | 160 ('/~johndoe', {'url': '/prefix/%foo%'}, |
161 [('foo', 'path')], | |
116 'prefix/', | 162 'prefix/', |
117 {'foo': ''}), | 163 {'foo': ''}), |
118 ('/~johndoe', {'url': '/prefix/%path:foo%'}, | 164 ('/~johndoe', {'url': '/prefix/%foo%'}, |
165 [('foo', 'path')], | |
119 'prefix', | 166 'prefix', |
120 {'foo': ''}), | 167 {'foo': ''}), |
121 ]) | 168 ]) |
122 def test_match_uri(site_root, config, uri, expected_match): | 169 def test_match_uri(site_root, config, params, uri, expected_match): |
123 site_root = site_root.rstrip('/') + '/' | 170 site_root = site_root.rstrip('/') + '/' |
124 app = get_mock_app() | 171 app = get_mock_app() |
125 app.config.set('site/root', urllib.parse.quote(site_root)) | 172 app.config.set('site/root', urllib.parse.quote(site_root)) |
173 app.sources = [_getMockSource('blah', params)] | |
174 | |
126 config.setdefault('source', 'blah') | 175 config.setdefault('source', 'blah') |
127 route = Route(app, config) | 176 route = Route(app, config) |
128 assert route.uri_pattern == config['url'].lstrip('/') | 177 assert route.uri_pattern == config['url'].lstrip('/') |
129 m = route.matchUri(urllib.parse.quote(site_root) + uri) | 178 m = route.matchUri(urllib.parse.quote(site_root) + uri) |
130 assert m == expected_match | 179 assert m == expected_match |
131 | 180 |
132 | 181 |
133 @pytest.mark.parametrize( | 182 @pytest.mark.parametrize( |
134 'site_root', | 183 'site_root', |
135 [ | 184 [ |
136 ('/'), ('/whatever'), ('/~johndoe') | 185 ('/'), |
186 ('/whatever'), | |
187 ('/~johndoe') | |
137 ]) | 188 ]) |
138 def test_match_uri_requires_absolute_uri(site_root): | 189 def test_match_uri_requires_absolute_uri(site_root): |
139 with pytest.raises(Exception): | 190 with pytest.raises(Exception): |
140 app = get_mock_app() | 191 app = get_mock_app() |
141 app.config.set('site/root', site_root.rstrip('/') + '/') | 192 app.config.set('site/root', site_root.rstrip('/') + '/') |
142 config = {'url': '/%path:slug%', 'source': 'blah'} | 193 app.sources = [_getMockSource('blah', [('slug', 'path')])] |
194 | |
195 config = {'url': '/%slug%', 'source': 'blah'} | |
143 route = Route(app, config) | 196 route = Route(app, config) |
144 route.matchUri('notabsuri') | 197 route.matchUri('notabsuri') |
145 | 198 |
146 | 199 |
147 @pytest.mark.parametrize( | 200 @pytest.mark.parametrize( |
179 app = get_mock_app() | 232 app = get_mock_app() |
180 app.config.set('site/root', urllib.parse.quote(root)) | 233 app.config.set('site/root', urllib.parse.quote(root)) |
181 app.config.set('site/pretty_urls', pretty) | 234 app.config.set('site/pretty_urls', pretty) |
182 app.config.set('site/trailing_slash', False) | 235 app.config.set('site/trailing_slash', False) |
183 app.config.set('__cache/pagination_suffix_format', '/%(num)d') | 236 app.config.set('__cache/pagination_suffix_format', '/%(num)d') |
184 | 237 app.sources = [_getMockSource('blah', [('slug', 'path')])] |
185 config = {'url': '/%path:slug%', 'source': 'blah'} | 238 |
239 config = {'url': '/%slug%', 'source': 'blah'} | |
186 route = Route(app, config) | 240 route = Route(app, config) |
187 uri = route.getUri({'slug': slug}, sub_num=page_num) | 241 uri = route.getUri({'slug': slug}, sub_num=page_num) |
188 assert uri == (urllib.parse.quote(root) + expected) | 242 assert uri == (urllib.parse.quote(root) + expected) |
189 | 243 |