From 25df66265aadc3b4cfb4b4c22ae9b055cf3c9481 Mon Sep 17 00:00:00 2001 From: Robert Haines Date: Sat, 24 Jun 2023 19:08:24 +0100 Subject: [PATCH] Always treat dates as Ruby Date objects. If the date in the YAML is quoted, e.g., `"2023-06-24"`, then the Ruby YAML parser - quite reasonably - assumed that they *must* be strings, so does not parse them into Ruby Date objects. We always want certain fields to be treated as Date objects, so this commit ensures that those fields always return a Date object, or `''` if the date is invalid or empty. Fixes #122. --- lib/cff/formatters/formatter.rb | 15 ++------ lib/cff/model_part.rb | 64 +++++++++++++++++++++++-------- test/formatters/formatter_test.rb | 10 ++--- 3 files changed, 56 insertions(+), 33 deletions(-) diff --git a/lib/cff/formatters/formatter.rb b/lib/cff/formatters/formatter.rb index 88b47fa..02731d4 100644 --- a/lib/cff/formatters/formatter.rb +++ b/lib/cff/formatters/formatter.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -# Copyright (c) 2018-2022 The Ruby Citation File Format Developers. +# Copyright (c) 2018-2023 The Ruby Citation File Format Developers. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -67,16 +67,9 @@ def self.month_and_year_from_model(model) # rubocop:disable Metrics end def self.month_and_year_from_date(value) - if value.is_a?(Date) - [value.month, value.year].map(&:to_s) - else - begin - date = Date.parse(value.to_s) - [date.month, date.year].map(&:to_s) - rescue ArgumentError - ['', ''] - end - end + return ['', ''] unless value.is_a?(Date) + + [value.month, value.year].map(&:to_s) end # CFF 'pages' is the number of pages, which has no equivalent in BibTeX diff --git a/lib/cff/model_part.rb b/lib/cff/model_part.rb index 1100f6b..6441234 100644 --- a/lib/cff/model_part.rb +++ b/lib/cff/model_part.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -# Copyright (c) 2018-2022 The Ruby Citation File Format Developers. +# Copyright (c) 2018-2023 The Ruby Citation File Format Developers. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -59,23 +59,57 @@ def self.attr_date(*symbols) # :nodoc: symbols.each do |symbol| field = symbol.to_s.tr('_', '-') - class_eval( - # def date_end=(date) - # date = (date.is_a?(Date) ? date.dup : Date.parse(date)) - # - # @fields['date-end'] = date - # end - <<-END_SETTER, __FILE__, __LINE__ + 1 - def #{symbol}=(date) - date = (date.is_a?(Date) ? date.dup : Date.parse(date)) - - @fields['#{field}'] = date - end - END_SETTER - ) + date_getter(symbol, field) + date_setter(symbol, field) end end + def self.date_getter(symbol, field) + class_eval( + # def date_end + # date = @fields['date-end'] + # return date if date.is_a?(Date) + # + # begin + # Date.parse(date) + # rescue + # '' + # end + # end + <<-END_GETTER, __FILE__, __LINE__ + 1 + def #{symbol} + date = @fields['#{field}'] + return date if date.is_a?(Date) + + begin + Date.parse(date) + rescue + '' + end + end + END_GETTER + ) + end + + def self.date_setter(symbol, field) + class_eval( + # def date_end=(date) + # date = (date.is_a?(Date) ? date.dup : Date.parse(date)) + # + # @fields['date-end'] = date + # end + <<-END_SETTER, __FILE__, __LINE__ + 1 + def #{symbol}=(date) + date = (date.is_a?(Date) ? date.dup : Date.parse(date)) + + @fields['#{field}'] = date + end + END_SETTER + ) + end + + private_class_method :date_getter, :date_setter + private def method_to_field(name) diff --git a/test/formatters/formatter_test.rb b/test/formatters/formatter_test.rb index 7104a2f..63c6ba0 100644 --- a/test/formatters/formatter_test.rb +++ b/test/formatters/formatter_test.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -# Copyright (c) 2018-2022 The Ruby Citation File Format Developers. +# Copyright (c) 2018-2023 The Ruby Citation File Format Developers. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -25,13 +25,9 @@ def test_month_and_year_from_date assert_equal(['', ''], CFF::Formatters::Formatter.month_and_year_from_date(date)) end - date_str = '2021-08-05' - date = Date.parse(date_str) assert_equal( - ['8', '2021'], CFF::Formatters::Formatter.month_and_year_from_date(date_str) - ) - assert_equal( - ['8', '2021'], CFF::Formatters::Formatter.month_and_year_from_date(date) + ['8', '2021'], + CFF::Formatters::Formatter.month_and_year_from_date(Date.parse('2021-08-05')) ) end