From eaac869a79c4d065d457da98491e84bcaa09506d Mon Sep 17 00:00:00 2001 From: Florian Thomas Date: Thu, 11 Jan 2018 22:29:50 +0000 Subject: [PATCH 1/6] add failing tests for #5963 it fails with ruby 2.4 onwards and passes up to ruby 2.3 --- test/helper.rb | 4 ++- test/source/_dates/date_without_time.md | 4 +++ test/source/_dates/time_with_timezone.md | 4 +++ test/source/_dates/time_without_timezone.md | 4 +++ test/test_document.rb | 39 +++++++++++++++++++++ 5 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 test/source/_dates/date_without_time.md create mode 100644 test/source/_dates/time_with_timezone.md create mode 100644 test/source/_dates/time_without_timezone.md diff --git a/test/helper.rb b/test/helper.rb index aa94be13e61..2b6b7253a83 100644 --- a/test/helper.rb +++ b/test/helper.rb @@ -149,7 +149,9 @@ def site_configuration(overrides = {}) })) Configuration.from(full_overrides.merge({ "source" => source_dir, - })) + })).tap do |obj| + Jekyll.set_timezone(obj["timezone"]) if obj["timezone"] + end end def clear_dest diff --git a/test/source/_dates/date_without_time.md b/test/source/_dates/date_without_time.md new file mode 100644 index 00000000000..7e5ee003808 --- /dev/null +++ b/test/source/_dates/date_without_time.md @@ -0,0 +1,4 @@ +--- +date: 2015-10-01 +--- +Here is the content. diff --git a/test/source/_dates/time_with_timezone.md b/test/source/_dates/time_with_timezone.md new file mode 100644 index 00000000000..5a7c9277bc0 --- /dev/null +++ b/test/source/_dates/time_with_timezone.md @@ -0,0 +1,4 @@ +--- +date: 2015-10-01 01:00:00 +0800 +--- +Here is the content. diff --git a/test/source/_dates/time_without_timezone.md b/test/source/_dates/time_without_timezone.md new file mode 100644 index 00000000000..ae0423e10cb --- /dev/null +++ b/test/source/_dates/time_without_timezone.md @@ -0,0 +1,4 @@ +--- +date: 2015-10-01 01:00:00 +--- +Here is the content. diff --git a/test/test_document.rb b/test/test_document.rb index 6ce71230680..ae5d58b3e00 100644 --- a/test/test_document.rb +++ b/test/test_document.rb @@ -16,6 +16,15 @@ def setup_encoded_document(filename) }).tap(&:read) end + def setup_document_with_dates(filename) + site = fixture_site("collections" => ["dates"], "timezone" => "UTC") + site.process + Document.new(site.in_source_dir(File.join("_dates", filename)), { + :site => site, + :collection => site.collections["dates"], + }).tap(&:read) + end + context "a document in a collection" do setup do @site = fixture_site({ @@ -558,4 +567,34 @@ def setup_encoded_document(filename) Jekyll::Renderer.new(@document.site, @document).render_document end end + + context "a document with a date with timezone" do + setup do + @document = setup_document_with_dates "time_with_timezone.md" + end + + should "have the expected date" do + assert_equal "2015/09/30", @document.data['date'].strftime("%Y/%m/%d") + end + end + + context "a document with a date with time but without timezone" do + setup do + @document = setup_document_with_dates "time_without_timezone.md" + end + + should "have the expected date" do + assert_equal "2015/10/01", @document.data['date'].strftime("%Y/%m/%d") + end + end + + context "a document with a date without time" do + setup do + @document = setup_document_with_dates "date_without_time.md" + end + + should "have the expected date" do + assert_equal "2015/10/01", @document.data['date'].strftime("%Y/%m/%d") + end + end end From ac021acdc4c98beadeed73da44bbfacb412c7fca Mon Sep 17 00:00:00 2001 From: Florian Thomas Date: Tue, 16 Jan 2018 22:15:20 +0000 Subject: [PATCH 2/6] make sure timezone is rolled back after test ran --- test/helper.rb | 4 +--- test/test_document.rb | 14 +++++++++----- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/test/helper.rb b/test/helper.rb index 2b6b7253a83..aa94be13e61 100644 --- a/test/helper.rb +++ b/test/helper.rb @@ -149,9 +149,7 @@ def site_configuration(overrides = {}) })) Configuration.from(full_overrides.merge({ "source" => source_dir, - })).tap do |obj| - Jekyll.set_timezone(obj["timezone"]) if obj["timezone"] - end + })) end def clear_dest diff --git a/test/test_document.rb b/test/test_document.rb index ae5d58b3e00..e32fd0f72bd 100644 --- a/test/test_document.rb +++ b/test/test_document.rb @@ -17,12 +17,16 @@ def setup_encoded_document(filename) end def setup_document_with_dates(filename) - site = fixture_site("collections" => ["dates"], "timezone" => "UTC") + site = fixture_site("collections" => ["dates"]) site.process - Document.new(site.in_source_dir(File.join("_dates", filename)), { - :site => site, - :collection => site.collections["dates"], - }).tap(&:read) + docs = nil + with_env('TZ', 'UTC') do + docs = Document.new(site.in_source_dir(File.join("_dates", filename)), { + :site => site, + :collection => site.collections["dates"], + }).tap(&:read) + end + docs end context "a document in a collection" do From 5365355662f332b526c03e32cb77d5d6f357f6fc Mon Sep 17 00:00:00 2001 From: Florian Thomas Date: Tue, 16 Jan 2018 22:16:15 +0000 Subject: [PATCH 3/6] date should be a date, not a string In a real application this would have already been read as a date so make sure our scenario replicates that behaviour. --- features/step_definitions.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/features/step_definitions.rb b/features/step_definitions.rb index c69cc0891d3..587cc4cc817 100644 --- a/features/step_definitions.rb +++ b/features/step_definitions.rb @@ -85,6 +85,7 @@ if status == "post" parsed_date = Time.xmlschema(input_hash["date"]) rescue Time.parse(input_hash["date"]) + input_hash["date"] = parsed_date filename = "#{parsed_date.strftime("%Y-%m-%d")}-#{title}.#{ext}" end From 2130da7ced21aaa4ce9c8850e206a47668a8943f Mon Sep 17 00:00:00 2001 From: Florian Thomas Date: Wed, 17 Jan 2018 13:38:05 +0000 Subject: [PATCH 4/6] fix rubocop offenses --- test/test_document.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/test_document.rb b/test/test_document.rb index e32fd0f72bd..213271c8b87 100644 --- a/test/test_document.rb +++ b/test/test_document.rb @@ -20,7 +20,7 @@ def setup_document_with_dates(filename) site = fixture_site("collections" => ["dates"]) site.process docs = nil - with_env('TZ', 'UTC') do + with_env("TZ", "UTC") do docs = Document.new(site.in_source_dir(File.join("_dates", filename)), { :site => site, :collection => site.collections["dates"], @@ -578,7 +578,7 @@ def setup_document_with_dates(filename) end should "have the expected date" do - assert_equal "2015/09/30", @document.data['date'].strftime("%Y/%m/%d") + assert_equal "2015/09/30", @document.data["date"].strftime("%Y/%m/%d") end end @@ -588,7 +588,7 @@ def setup_document_with_dates(filename) end should "have the expected date" do - assert_equal "2015/10/01", @document.data['date'].strftime("%Y/%m/%d") + assert_equal "2015/10/01", @document.data["date"].strftime("%Y/%m/%d") end end @@ -598,7 +598,7 @@ def setup_document_with_dates(filename) end should "have the expected date" do - assert_equal "2015/10/01", @document.data['date'].strftime("%Y/%m/%d") + assert_equal "2015/10/01", @document.data["date"].strftime("%Y/%m/%d") end end end From 84a1ae211f34d71e16938ade7f5955d52a778fa5 Mon Sep 17 00:00:00 2001 From: Florian Thomas Date: Wed, 17 Jan 2018 22:08:22 +0000 Subject: [PATCH 5/6] always convert `date` to localtime as set by ENV['TZ'] This makes sure we don't have inconsistencies between different ruby versions. --- lib/jekyll/document.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/jekyll/document.rb b/lib/jekyll/document.rb index 1eb8418605e..f7a05a12d0f 100644 --- a/lib/jekyll/document.rb +++ b/lib/jekyll/document.rb @@ -426,7 +426,7 @@ def merge_categories!(other) private def merge_date!(source) - if data.key?("date") && !data["date"].is_a?(Time) + if data.key?("date") data["date"] = Utils.parse_date( data["date"].to_s, "Document '#{relative_path}' does not have a valid date in the #{source}." From e3b32f3a28de85e85bb054513d36063f0fe97d0a Mon Sep 17 00:00:00 2001 From: Florian Thomas Date: Sat, 20 Jan 2018 20:20:55 +0900 Subject: [PATCH 6/6] make sure timezone setting is applied before reading post In a real world example the post frontmatter would only be read during the build step after the configuration has already been applied. In a cucumber scenario though the frontmatter is read outside of any configuration so in this case the `timezone` setting of `UTC` wasn't applied. --- features/permalinks.feature | 10 +++++----- features/step_definitions.rb | 3 +++ 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/features/permalinks.feature b/features/permalinks.feature index ca0482fce90..a69e059bf94 100644 --- a/features/permalinks.feature +++ b/features/permalinks.feature @@ -71,14 +71,14 @@ Feature: Fancy permalinks And I should see "Totally custom." in "_site/03-27-2009/custom-permalink-schema.html" Scenario: Use custom permalink schema with date and time - Given I have a _posts directory + Given I have a configuration file with: + | key | value | + | permalink | "/:year:month:day:hour:minute:second.html" | + | timezone | UTC | + And I have a _posts directory And I have the following post: | title | category | date | content | | Custom Permalink Schema | stuff | 2009-03-27 22:31:07 | Totally custom. | - And I have a configuration file with: - | key | value | - | permalink | "/:year:month:day:hour:minute:second.html" | - | timezone | UTC | When I run jekyll build Then I should get a zero exit status And the _site directory should exist diff --git a/features/step_definitions.rb b/features/step_definitions.rb index 587cc4cc817..f4e80e770d9 100644 --- a/features/step_definitions.rb +++ b/features/step_definitions.rb @@ -4,6 +4,7 @@ FileUtils.rm_rf(Paths.test_dir) if Paths.test_dir.exist? FileUtils.mkdir_p(Paths.test_dir) unless Paths.test_dir.directory? Dir.chdir(Paths.test_dir) + @timezone_before_scenario = ENV["TZ"] end # @@ -13,6 +14,7 @@ Paths.output_file.delete if Paths.output_file.exist? Paths.status_file.delete if Paths.status_file.exist? Dir.chdir(Paths.test_dir.parent) + ENV["TZ"] = @timezone_before_scenario end # @@ -117,6 +119,7 @@ {} end config[key] = YAML.load(value) + Jekyll.set_timezone(value) if key == "timezone" File.write("_config.yml", YAML.dump(config)) end