changeset 262:61145dcd56e0

routing: Better generate URLs according to the site configuration. This fixes problems now that even the chef server generates URLs that are appropriate given the `pretty_urls` and `trailing_slash` settings. Add some tests.
author Ludovic Chabant <ludovic@chabant.com>
date Tue, 24 Feb 2015 08:06:25 -0800
parents b51ddb0c260b
children a68e207ca406
files piecrust/baking/single.py piecrust/routing.py tests/test_baking_baker.py tests/test_routing.py
diffstat 4 files changed, 90 insertions(+), 43 deletions(-) [+]
line wrap: on
line diff
--- a/piecrust/baking/single.py	Tue Feb 24 08:04:49 2015 -0800
+++ b/piecrust/baking/single.py	Tue Feb 24 08:06:25 2015 -0800
@@ -39,14 +39,10 @@
         if self.pretty_urls:
             bake_path.append(decoded_uri)
             bake_path.append('index.html')
+        elif decoded_uri == '':
+            bake_path.append('index.html')
         else:
-            name, ext = os.path.splitext(decoded_uri)
-            if decoded_uri == '':
-                bake_path.append('index.html')
-            elif ext:
-                bake_path.append(decoded_uri)
-            else:
-                bake_path.append(decoded_uri + '.html')
+            bake_path.append(decoded_uri)
 
         return os.path.normpath(os.path.join(*bake_path))
 
--- a/piecrust/routing.py	Tue Feb 24 08:04:49 2015 -0800
+++ b/piecrust/routing.py	Tue Feb 24 08:06:25 2015 -0800
@@ -114,7 +114,7 @@
         suffix = None
         if sub_num > 1:
             # Note that we know the pagination suffix starts with a slash.
-            suffix = self.pagination_suffix_format % sub_num
+            suffix = self.pagination_suffix_format % {'num': sub_num}
 
         if self.pretty_urls:
             # Output will be:
@@ -123,7 +123,10 @@
             # - `subdir/name.ext`
             # - `subdir/name.ext/2`
             if suffix:
-                uri = uri.rstrip('/') + suffix
+                if uri == '':
+                    uri = suffix.lstrip('/')
+                else:
+                    uri = uri.rstrip('/') + suffix
             if self.trailing_slash:
                 uri = uri.rstrip('/') + '/'
         else:
@@ -132,13 +135,17 @@
             # - `subdir/name/2.html`
             # - `subdir/name.ext`
             # - `subdir/name/2.ext`
-            base_uri, ext = os.path.splitext(uri)
-            if not ext:
-                ext = '.html'
-            if suffix:
-                uri = base_uri + suffix + ext
+            if uri == '':
+                if suffix:
+                    uri = suffix.lstrip('/') + '.html'
             else:
-                uri = base_uri + ext
+                base_uri, ext = os.path.splitext(uri)
+                if not ext:
+                    ext = '.html'
+                if suffix:
+                    uri = base_uri + suffix + ext
+                else:
+                    uri = base_uri + ext
 
         if include_site_root:
             uri = self.uri_root + uri
--- a/tests/test_baking_baker.py	Tue Feb 24 08:04:49 2015 -0800
+++ b/tests/test_baking_baker.py	Tue Feb 24 08:06:25 2015 -0800
@@ -2,46 +2,46 @@
 import pytest
 from piecrust.baking.baker import PageBaker, Baker
 from piecrust.baking.records import BakeRecord
+from piecrust.routing import Route
 from .mockutil import get_mock_app, mock_fs, mock_fs_scope
 
 
-@pytest.mark.parametrize('uri, page_num, pretty, expected', [
+@pytest.mark.parametrize('uri, pretty, expected', [
         # Pretty URLs
-        ('', 1, True, 'index.html'),
-        ('', 2, True, '2/index.html'),
-        ('foo', 1, True, 'foo/index.html'),
-        ('foo', 2, True, 'foo/2/index.html'),
-        ('foo/bar', 1, True, 'foo/bar/index.html'),
-        ('foo/bar', 2, True, 'foo/bar/2/index.html'),
-        ('foo.ext', 1, True, 'foo.ext/index.html'),
-        ('foo.ext', 2, True, 'foo.ext/2/index.html'),
-        ('foo/bar.ext', 1, True, 'foo/bar.ext/index.html'),
-        ('foo/bar.ext', 2, True, 'foo/bar.ext/2/index.html'),
-        ('foo.bar.ext', 1, True, 'foo.bar.ext/index.html'),
-        ('foo.bar.ext', 2, True, 'foo.bar.ext/2/index.html'),
+        ('', True, 'index.html'),
+        ('2', True, '2/index.html'),
+        ('foo', True, 'foo/index.html'),
+        ('foo/2', True, 'foo/2/index.html'),
+        ('foo/bar', True, 'foo/bar/index.html'),
+        ('foo/bar/2', True, 'foo/bar/2/index.html'),
+        ('foo.ext', True, 'foo.ext/index.html'),
+        ('foo.ext/2', True, 'foo.ext/2/index.html'),
+        ('foo/bar.ext', True, 'foo/bar.ext/index.html'),
+        ('foo/bar.ext/2', True, 'foo/bar.ext/2/index.html'),
+        ('foo.bar.ext', True, 'foo.bar.ext/index.html'),
+        ('foo.bar.ext/2', True, 'foo.bar.ext/2/index.html'),
         # Ugly URLs
-        ('', 1, False, 'index.html'),
-        ('', 2, False, '2.html'),
-        ('foo', 1, False, 'foo.html'),
-        ('foo', 2, False, 'foo/2.html'),
-        ('foo/bar', 1, False, 'foo/bar.html'),
-        ('foo/bar', 2, False, 'foo/bar/2.html'),
-        ('foo.ext', 1, False, 'foo.ext'),
-        ('foo.ext', 2, False, 'foo/2.ext'),
-        ('foo/bar.ext', 1, False, 'foo/bar.ext'),
-        ('foo/bar.ext', 2, False, 'foo/bar/2.ext'),
-        ('foo.bar.ext', 1, False, 'foo.bar.ext'),
-        ('foo.bar.ext', 2, False, 'foo.bar/2.ext')
+        ('', False, 'index.html'),
+        ('2.html', False, '2.html'),
+        ('foo.html', False, 'foo.html'),
+        ('foo/2.html', False, 'foo/2.html'),
+        ('foo/bar.html', False, 'foo/bar.html'),
+        ('foo/bar/2.html', False, 'foo/bar/2.html'),
+        ('foo.ext', False, 'foo.ext'),
+        ('foo/2.ext', False, 'foo/2.ext'),
+        ('foo/bar.ext', False, 'foo/bar.ext'),
+        ('foo/bar/2.ext', False, 'foo/bar/2.ext'),
+        ('foo.bar.ext', False, 'foo.bar.ext'),
+        ('foo.bar/2.ext', False, 'foo.bar/2.ext')
         ])
-def test_get_output_path(uri, page_num, pretty, expected):
+def test_get_output_path(uri, pretty, expected):
     app = get_mock_app()
     if pretty:
         app.config.set('site/pretty_urls', True)
     assert app.config.get('site/pretty_urls') == pretty
 
     baker = PageBaker(app, '/destination')
-    sub_uri = baker.getOutputUri(uri, page_num)
-    path = baker.getOutputPath(sub_uri)
+    path = baker.getOutputPath(uri)
     expected = os.path.normpath(
             os.path.join('/destination', expected))
     assert expected == path
--- a/tests/test_routing.py	Tue Feb 24 08:04:49 2015 -0800
+++ b/tests/test_routing.py	Tue Feb 24 08:06:25 2015 -0800
@@ -1,6 +1,7 @@
 import mock
 import pytest
 from piecrust.routing import Route
+from .mockutil import get_mock_app
 
 
 @pytest.mark.parametrize(
@@ -58,3 +59,46 @@
     m = route.matchUri(uri)
     assert m == expected_match
 
+
+@pytest.mark.parametrize(
+        'slug, page_num, pretty, expected',
+        [
+            # Pretty URLs
+            ('', 1, True, ''),
+            ('', 2, True, '2'),
+            ('foo', 1, True, 'foo'),
+            ('foo', 2, True, 'foo/2'),
+            ('foo/bar', 1, True, 'foo/bar'),
+            ('foo/bar', 2, True, 'foo/bar/2'),
+            ('foo.ext', 1, True, 'foo.ext'),
+            ('foo.ext', 2, True, 'foo.ext/2'),
+            ('foo/bar.ext', 1, True, 'foo/bar.ext'),
+            ('foo/bar.ext', 2, True, 'foo/bar.ext/2'),
+            ('foo.bar.ext', 1, True, 'foo.bar.ext'),
+            ('foo.bar.ext', 2, True, 'foo.bar.ext/2'),
+            # Ugly URLs
+            ('', 1, False, ''),
+            ('', 2, False, '2.html'),
+            ('foo', 1, False, 'foo.html'),
+            ('foo', 2, False, 'foo/2.html'),
+            ('foo/bar', 1, False, 'foo/bar.html'),
+            ('foo/bar', 2, False, 'foo/bar/2.html'),
+            ('foo.ext', 1, False, 'foo.ext'),
+            ('foo.ext', 2, False, 'foo/2.ext'),
+            ('foo/bar.ext', 1, False, 'foo/bar.ext'),
+            ('foo/bar.ext', 2, False, 'foo/bar/2.ext'),
+            ('foo.bar.ext', 1, False, 'foo.bar.ext'),
+            ('foo.bar.ext', 2, False, 'foo.bar/2.ext')
+            ])
+def test_get_uri(slug, page_num, pretty, expected):
+    app = get_mock_app()
+    app.config.set('site/root', '/blah')
+    app.config.set('site/pretty_urls', pretty)
+    app.config.set('site/trailing_slash', False)
+    app.config.set('__cache/pagination_suffix_format', '/%(num)d')
+
+    config = {'url': '/%path:slug%', 'source': 'blah'}
+    route = Route(app, config)
+    uri = route.getUri({'slug': slug}, sub_num=page_num)
+    assert uri == ('/blah/' + expected)
+