diff --git a/CHANGELOG.md b/CHANGELOG.md index 51470e6..04f9246 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Holiday definitions +## 2.5.2 + +* Fix `de` issue cause by undefined `year_ranges` behavior in syntax + ## 2.5.1 * Fix Federal Reserve Independence Day tests diff --git a/SYNTAX.md b/SYNTAX.md index 3a4388a..573b283 100644 --- a/SYNTAX.md +++ b/SYNTAX.md @@ -139,9 +139,12 @@ Holidays.on(Date.civil(2016, 7, 1), :jp) #### `after` + The 'after' selector will only find a match if the supplied date takes place after or equal to the holiday. +A single number *must* be supplied. An array of integers will result in an error. + Example: ```yaml diff --git a/de.yaml b/de.yaml index 3b8f2c9..afa4827 100644 --- a/de.yaml +++ b/de.yaml @@ -111,7 +111,7 @@ months: regions: [de_hb, de_hh, de_ni, de_sh] mday: 31 year_ranges: - - after: [2018] + - after: 2018 11: - name: Allerheiligen regions: [de_bw, de_by, de_nw, de_rp, de_sl] diff --git a/lib/validation/month_validator.rb b/lib/validation/month_validator.rb index 505751a..ce548cd 100644 --- a/lib/validation/month_validator.rb +++ b/lib/validation/month_validator.rb @@ -12,10 +12,31 @@ def call(months) month_defs.each do |month_def| raise Errors::InvalidMonth.new("All months must have a name, received: #{months}") if month_def['name'].nil? || month_def['name'].empty? + raise Errors::InvalidRegions.new("A month must contain at least one region, received: #{months}") if month_def['regions'].nil? || month_def['regions'].empty? + month_def['regions'].each do |region| raise Errors::InvalidRegions.new("A month must contain at least one region, received: #{months}") if region.nil? || region.empty? end + + if month_def.key?("year_ranges") + month_def["year_ranges"].each do |yr| + yr.each_pair do |k, v| + raise Errors::InvalidMonth.new("The :year_ranges value only accepts the following: :before, :after, :limited, :between, received: #{months}") unless [:before, :after, :limited, :between].include?(k.to_sym) + + case k + when "after" + raise Errors::InvalidMonth.new("The year_ranges.after value must contain a single 'year' integer, ex. 2018, received: #{months}") unless v.is_a?(Integer) + when "limited" + raise Errors::InvalidMonth.new("The year_ranges.limited value must contain an array of 'year' integers, ex. [2018], received: #{months}") unless v.is_a?(Array) + + v.each do |j| + raise Errors::InvalidMonth.new("The year_ranges.limited value must contain an array of 'year' integers, ex. [2018], received: #{months}") unless j.is_a?(Integer) + end + end + end + end + end end end diff --git a/spec/validation/month_validator_spec.rb b/spec/validation/month_validator_spec.rb index 53ff06c..1069b95 100644 --- a/spec/validation/month_validator_spec.rb +++ b/spec/validation/month_validator_spec.rb @@ -67,5 +67,33 @@ expect(e.message).to eq("A month must contain at least one region, received: #{months}") } end + + it 'returns error if year_ranges contains unknown subkey' do + months = { 1 => [{"name"=>"Test Holiday", "regions"=>["test"], "mday"=>1, "year_ranges" => [{"blah" => [2018]}] }] } + expect { subject.call(months) }.to raise_error(Definitions::Errors::InvalidMonth) { |e| + expect(e.message).to eq("The :year_ranges value only accepts the following: :before, :after, :limited, :between, received: #{months}") + } + end + + it 'returns error if :after value is not a single integer' do + months = { 1 => [{"name"=>"Test Holiday", "regions"=>["test"], "mday"=>1, "year_ranges" => [{"after" => [2018]}] }] } + expect { subject.call(months) }.to raise_error(Definitions::Errors::InvalidMonth) { |e| + expect(e.message).to eq("The year_ranges.after value must contain a single 'year' integer, ex. 2018, received: #{months}") + } + end + + it 'returns error if :limited value is not an array' do + months = { 1 => [{"name"=>"Test Holiday", "regions"=>["test"], "mday"=>1, "year_ranges" => [{"limited" => 2018}] }] } + expect { subject.call(months) }.to raise_error(Definitions::Errors::InvalidMonth) { |e| + expect(e.message).to eq("The year_ranges.limited value must contain an array of 'year' integers, ex. [2018], received: #{months}") + } + end + + it 'returns error if :limited value is not an array of integers' do + months = { 1 => [{"name"=>"Test Holiday", "regions"=>["test"], "mday"=>1, "year_ranges" => [{"limited" => ["blah"]}] }] } + expect { subject.call(months) }.to raise_error(Definitions::Errors::InvalidMonth) { |e| + expect(e.message).to eq("The year_ranges.limited value must contain an array of 'year' integers, ex. [2018], received: #{months}") + } + end end end