From f27eb77d0bbbffaa2317f90b790be3b0491aa464 Mon Sep 17 00:00:00 2001 From: Parker Moore Date: Thu, 10 Nov 2016 15:20:11 -0800 Subject: [PATCH 1/7] Add failing test for permalink templates with trailing underscores --- test/helper.rb | 15 +++++++++++++++ test/test_url.rb | 34 +++++++++++----------------------- 2 files changed, 26 insertions(+), 23 deletions(-) diff --git a/test/helper.rb b/test/helper.rb index ad88b5d0..0c6935a0 100644 --- a/test/helper.rb +++ b/test/helper.rb @@ -103,6 +103,21 @@ class JekyllUnitTest < Minitest::Test RSpec::Mocks.teardown end + def fixture_document(relative_path) + site = fixture_site({ + "collections" => { + "methods" => { + "output" => true + } + } + }) + site.read + matching_doc = site.collections["methods"].docs.find do |doc| + doc.relative_path == relative_path + end + [site, matching_doc] + end + def fixture_site(overrides = {}) Jekyll::Site.new(site_configuration(overrides)) end diff --git a/test/test_url.rb b/test/test_url.rb index 1a447116..c39e51f2 100644 --- a/test/test_url.rb +++ b/test/test_url.rb @@ -54,17 +54,7 @@ class TestURL < JekyllUnitTest end should "handle UrlDrop as a placeholder in addition to a hash" do - site = fixture_site({ - "collections" => { - "methods" => { - "output" => true - } - } - }) - site.read - matching_doc = site.collections["methods"].docs.find do |doc| - doc.relative_path == "_methods/escape-+ #%20[].md" - end + _, matching_doc = fixture_document("_methods/escape-+ #%20[].md") assert_equal "/methods/escape-+-20/escape-20.html", URL.new( :template => "/methods/:title/:name:output_ext", :placeholders => matching_doc.url_placeholders @@ -81,18 +71,16 @@ class TestURL < JekyllUnitTest end end - should "ignore NoMethodErrors when a placeholder is not found" do - site = fixture_site({ - "collections" => { - "methods" => { - "output" => true - } - } - }) - site.read - matching_doc = site.collections["methods"].docs.find do |doc| - doc.relative_path == "_methods/escape-+ #%20[].md" - end + should "check for key without trailing underscore" do + _, matching_doc = fixture_document("_methods/configuration.md") + assert_equal "/lol", URL.new( + :template => "/:year-:month-:day_:title", + :placeholders => matching_doc.url_placeholders + ).to_s + end + + should "raise custom error when URL placeholder doesn't have key" do + _, matching_doc = fixture_document("_methods/escape-+ #%20[].md") assert_raises NoMethodError do URL.new( :template => "/methods/:headline", From 9f8f0314693c61f516af7fe68e1022acb508b2d0 Mon Sep 17 00:00:00 2001 From: Parker Moore Date: Thu, 10 Nov 2016 15:30:51 -0800 Subject: [PATCH 2/7] Whoops, an *actually useful* failing test. --- test/test_url.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test_url.rb b/test/test_url.rb index c39e51f2..4c0320a7 100644 --- a/test/test_url.rb +++ b/test/test_url.rb @@ -73,8 +73,8 @@ class TestURL < JekyllUnitTest should "check for key without trailing underscore" do _, matching_doc = fixture_document("_methods/configuration.md") - assert_equal "/lol", URL.new( - :template => "/:year-:month-:day_:title", + assert_equal "/methods/2016-11-10_configuration", URL.new( + :template => "/methods/:year-:month-:day_:title", :placeholders => matching_doc.url_placeholders ).to_s end From 347651e5716c768efbc4f613b242bd55ed55bfea Mon Sep 17 00:00:00 2001 From: Parker Moore Date: Thu, 10 Nov 2016 15:34:03 -0800 Subject: [PATCH 3/7] URL#generate_url_from_drop: be smarter about replacing *just* the keys --- lib/jekyll/url.rb | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/lib/jekyll/url.rb b/lib/jekyll/url.rb index 291f6e58..e4a93fba 100644 --- a/lib/jekyll/url.rb +++ b/lib/jekyll/url.rb @@ -84,17 +84,29 @@ module Jekyll end end + def possible_keys(key) + if key.end_with?("_") + [key, key.chomp("_")] + else + [key] + end + end + def generate_url_from_drop(template) template.gsub(%r!:([a-z_]+)!) do |match| - key = match.sub(":".freeze, "".freeze) - unless @placeholders.key?(key) - raise NoMethodError, "The URL template key #{key} doesn't exist!" - end - if @placeholders[key].nil? - "".freeze - else - self.class.escape_path(@placeholders[key]) + pool = possible_keys(match.sub(":".freeze, "".freeze)) + + winner = pool.find { |key| @placeholders.key?(key) } + if winner.nil? + raise NoMethodError, + "The URL template doesn't have #{pool.join(" or ")} keys. Check your permalink template!" end + + value = @placeholders[winner] + value = "" if value.nil? + replacement = self.class.escape_path(value) + + match.sub(":#{winner}", replacement) end.gsub(%r!//!, "/".freeze) end From d50ef0e3dd00a39fd9b3e19049ca2f52d06ac43a Mon Sep 17 00:00:00 2001 From: Parker Moore Date: Thu, 10 Nov 2016 15:36:05 -0800 Subject: [PATCH 4/7] Add useful comment. --- lib/jekyll/url.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/jekyll/url.rb b/lib/jekyll/url.rb index e4a93fba..9e49cc40 100644 --- a/lib/jekyll/url.rb +++ b/lib/jekyll/url.rb @@ -84,6 +84,12 @@ module Jekyll end end + # We include underscores in keys to allow for 'i_month' and so forth. + # This poses a problem for keys which are followed by and underscore + # but the underscore is not part of the key, e.g. '/:month_:day'. + # That should be :month and :day, but our key extraction regexp isn't + # smart enough to know that so we have to make it an explicit + # possibility. def possible_keys(key) if key.end_with?("_") [key, key.chomp("_")] From ff012e795aabad96cb7d124061acc278d5888f8a Mon Sep 17 00:00:00 2001 From: Parker Moore Date: Thu, 10 Nov 2016 15:57:45 -0800 Subject: [PATCH 5/7] Fix fmt error. --- lib/jekyll/url.rb | 3 ++- test/test_url.rb | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/jekyll/url.rb b/lib/jekyll/url.rb index 9e49cc40..404b2728 100644 --- a/lib/jekyll/url.rb +++ b/lib/jekyll/url.rb @@ -105,7 +105,8 @@ module Jekyll winner = pool.find { |key| @placeholders.key?(key) } if winner.nil? raise NoMethodError, - "The URL template doesn't have #{pool.join(" or ")} keys. Check your permalink template!" + "The URL template doesn't have #{pool.join(" or ")} keys. "\ + "Check your permalink template!" end value = @placeholders[winner] diff --git a/test/test_url.rb b/test/test_url.rb index 4c0320a7..e9987b15 100644 --- a/test/test_url.rb +++ b/test/test_url.rb @@ -74,7 +74,7 @@ class TestURL < JekyllUnitTest should "check for key without trailing underscore" do _, matching_doc = fixture_document("_methods/configuration.md") assert_equal "/methods/2016-11-10_configuration", URL.new( - :template => "/methods/:year-:month-:day_:title", + :template => "/methods/:year-:month-:day_:title", :placeholders => matching_doc.url_placeholders ).to_s end From cb6724046de0dbae828d609edea11e796979cb37 Mon Sep 17 00:00:00 2001 From: Parker Moore Date: Fri, 11 Nov 2016 16:30:44 -0800 Subject: [PATCH 6/7] Dates are _the worst_ --- test/test_url.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test_url.rb b/test/test_url.rb index e9987b15..fc3678d7 100644 --- a/test/test_url.rb +++ b/test/test_url.rb @@ -73,8 +73,8 @@ class TestURL < JekyllUnitTest should "check for key without trailing underscore" do _, matching_doc = fixture_document("_methods/configuration.md") - assert_equal "/methods/2016-11-10_configuration", URL.new( - :template => "/methods/:year-:month-:day_:title", + assert_equal "/methods/configuration-configuration_methods_configuration", URL.new( + :template => "/methods/:name-:slug_:collection_:title", :placeholders => matching_doc.url_placeholders ).to_s end From d3e387d14628cdec6863c2ee4ce55852eb7e4bc5 Mon Sep 17 00:00:00 2001 From: Parker Moore Date: Mon, 14 Nov 2016 13:30:14 -0800 Subject: [PATCH 7/7] Fix typo. --- lib/jekyll/url.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/jekyll/url.rb b/lib/jekyll/url.rb index 404b2728..4504574f 100644 --- a/lib/jekyll/url.rb +++ b/lib/jekyll/url.rb @@ -85,7 +85,7 @@ module Jekyll end # We include underscores in keys to allow for 'i_month' and so forth. - # This poses a problem for keys which are followed by and underscore + # This poses a problem for keys which are followed by an underscore # but the underscore is not part of the key, e.g. '/:month_:day'. # That should be :month and :day, but our key extraction regexp isn't # smart enough to know that so we have to make it an explicit