holidays 4.6.0 → 4.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +5 -0
  3. data/CONTRIBUTING.md +5 -5
  4. data/Makefile +29 -0
  5. data/README.md +13 -1
  6. data/Rakefile +2 -2
  7. data/definitions/au.yaml +12 -9
  8. data/definitions/ca.yaml +17 -2
  9. data/definitions/ch.yaml +1 -1
  10. data/definitions/index.yaml +3 -0
  11. data/definitions/is.yaml +1 -1
  12. data/definitions/jp.yaml +19 -14
  13. data/definitions/kr.yaml +282 -0
  14. data/definitions/lu.yaml +56 -0
  15. data/definitions/my.yaml +51 -0
  16. data/definitions/ups.yaml +1 -1
  17. data/definitions/us.yaml +1 -1
  18. data/lib/generated_definitions/MANIFEST +3 -0
  19. data/lib/generated_definitions/REGIONS.rb +1 -1
  20. data/lib/generated_definitions/au.rb +11 -8
  21. data/lib/generated_definitions/ca.rb +1 -1
  22. data/lib/generated_definitions/ch.rb +1 -1
  23. data/lib/generated_definitions/europe.rb +2 -2
  24. data/lib/generated_definitions/is.rb +1 -1
  25. data/lib/generated_definitions/jp.rb +13 -15
  26. data/lib/generated_definitions/kr.rb +248 -0
  27. data/lib/generated_definitions/lu.rb +39 -0
  28. data/lib/generated_definitions/my.rb +36 -0
  29. data/lib/generated_definitions/north_america.rb +2 -2
  30. data/lib/generated_definitions/scandinavia.rb +1 -1
  31. data/lib/generated_definitions/ups.rb +1 -1
  32. data/lib/generated_definitions/us.rb +1 -1
  33. data/lib/holidays.rb +29 -51
  34. data/lib/holidays/core_extensions/date.rb +1 -1
  35. data/lib/holidays/definition/context/function_processor.rb +86 -0
  36. data/lib/holidays/definition/context/generator.rb +31 -6
  37. data/lib/holidays/definition/parser/custom_method.rb +1 -3
  38. data/lib/holidays/definition/repository/holidays_by_month.rb +1 -1
  39. data/lib/holidays/definition/validator/region.rb +1 -3
  40. data/lib/holidays/errors.rb +1 -0
  41. data/lib/holidays/factory/date_calculator.rb +37 -0
  42. data/lib/holidays/factory/definition.rb +96 -0
  43. data/lib/holidays/factory/finder.rb +70 -0
  44. data/lib/holidays/finder/context/between.rb +43 -0
  45. data/lib/holidays/{use_case → finder}/context/dates_driver_builder.rb +6 -4
  46. data/lib/holidays/finder/context/next_holiday.rb +57 -0
  47. data/lib/holidays/{option → finder}/context/parse_options.rb +6 -8
  48. data/lib/holidays/finder/context/search.rb +86 -0
  49. data/lib/holidays/finder/context/year_holiday.rb +57 -0
  50. data/lib/holidays/finder/rules/in_region.rb +23 -0
  51. data/lib/holidays/finder/rules/year_range.rb +82 -0
  52. data/lib/holidays/load_all_definitions.rb +7 -5
  53. data/lib/holidays/version.rb +1 -1
  54. data/test/coverage_report.rb +7 -0
  55. data/test/defs/test_defs_au.rb +1 -1
  56. data/test/defs/test_defs_ca.rb +16 -1
  57. data/test/defs/test_defs_jp.rb +4 -0
  58. data/test/defs/test_defs_kr.rb +26 -0
  59. data/test/defs/test_defs_lu.rb +24 -0
  60. data/test/defs/test_defs_my.rb +20 -0
  61. data/test/defs/test_defs_north_america.rb +16 -1
  62. data/test/holidays/core_extensions/test_date_time.rb +7 -7
  63. data/test/holidays/definition/context/test_function_processor.rb +175 -0
  64. data/test/holidays/definition/context/test_generator.rb +18 -11
  65. data/test/holidays/definition/parser/test_custom_method.rb +2 -2
  66. data/test/holidays/definition/repository/test_proc_result_cache.rb +1 -1
  67. data/test/holidays/{test_date_calculator_factory.rb → factory/test_date_calculator.rb} +3 -3
  68. data/test/holidays/factory/test_definition.rb +53 -0
  69. data/test/holidays/factory/test_finder.rb +25 -0
  70. data/test/holidays/finder/context/test_between.rb +172 -0
  71. data/test/holidays/{use_case → finder}/context/test_dates_driver_builder.rb +2 -2
  72. data/test/holidays/finder/context/test_next_holiday.rb +156 -0
  73. data/test/holidays/{option → finder}/context/test_parse_options.rb +9 -9
  74. data/test/holidays/finder/context/test_search.rb +203 -0
  75. data/test/holidays/finder/context/test_year_holiday.rb +202 -0
  76. data/test/holidays/finder/rules/test_in_region.rb +38 -0
  77. data/test/holidays/finder/rules/test_year_range.rb +170 -0
  78. data/test/integration/README.md +9 -0
  79. data/test/{test_all_regions.rb → integration/test_all_regions.rb} +16 -2
  80. data/test/{test_custom_holidays.rb → integration/test_custom_holidays.rb} +2 -2
  81. data/test/{test_custom_year_range_holidays.rb → integration/test_custom_year_range_holidays.rb} +1 -1
  82. data/test/{test_holidays.rb → integration/test_holidays.rb} +43 -32
  83. data/test/{test_holidays_between.rb → integration/test_holidays_between.rb} +8 -16
  84. data/test/{test_multiple_regions.rb → integration/test_multiple_regions.rb} +1 -1
  85. data/test/test_helper.rb +3 -4
  86. metadata +67 -39
  87. data/benchmark.rb +0 -8
  88. data/lib/holidays/date_calculator_factory.rb +0 -35
  89. data/lib/holidays/definition_factory.rb +0 -86
  90. data/lib/holidays/option_factory.rb +0 -15
  91. data/lib/holidays/use_case/context/between.rb +0 -45
  92. data/lib/holidays/use_case/context/context_common.rb +0 -123
  93. data/lib/holidays/use_case/context/next_holiday.rb +0 -54
  94. data/lib/holidays/use_case/context/year_holiday.rb +0 -51
  95. data/lib/holidays/use_case_factory.rb +0 -41
  96. data/test/holidays/test_definition_factory.rb +0 -49
  97. data/test/holidays/test_option_factory.rb +0 -9
  98. data/test/holidays/test_use_case_factory.rb +0 -13
  99. data/test/holidays/use_case/context/test_between.rb +0 -77
@@ -0,0 +1,39 @@
1
+ # encoding: utf-8
2
+ module Holidays
3
+ # This file is generated by the Ruby Holidays gem.
4
+ #
5
+ # Definitions loaded: definitions/lu.yaml
6
+ #
7
+ # To use the definitions in this file, load it right after you load the
8
+ # Holiday gem:
9
+ #
10
+ # require 'holidays'
11
+ # require 'generated_definitions/lu'
12
+ #
13
+ # All the definitions are available at https://github.com/holidays/holidays
14
+ module LU # :nodoc:
15
+ def self.defined_regions
16
+ [:lu]
17
+ end
18
+
19
+ def self.holidays_by_month
20
+ {
21
+ 0 => [{:function => "easter(year)", :function_arguments => [:year], :function_modifier => 1, :name => "Ouschterméindeg", :regions => [:lu]},
22
+ {:function => "easter(year)", :function_arguments => [:year], :function_modifier => 39, :name => "Christi Himmelfaart", :regions => [:lu]},
23
+ {:function => "easter(year)", :function_arguments => [:year], :function_modifier => 49, :name => "Péngschtméindeg", :regions => [:lu]}],
24
+ 1 => [{:mday => 1, :name => "Neijoerschdag", :regions => [:lu]}],
25
+ 6 => [{:mday => 23, :name => "Nationalfeierdag", :regions => [:lu]}],
26
+ 8 => [{:mday => 15, :name => "Léiffrawëschdag", :regions => [:lu]}],
27
+ 11 => [{:mday => 1, :name => "Allerhellgen", :regions => [:lu]}],
28
+ 12 => [{:mday => 25, :name => "Chrëschtdag", :regions => [:lu]},
29
+ {:mday => 26, :name => "Stiefesdag", :regions => [:lu]}]
30
+ }
31
+ end
32
+
33
+ def self.custom_methods
34
+ {
35
+
36
+ }
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,36 @@
1
+ # encoding: utf-8
2
+ module Holidays
3
+ # This file is generated by the Ruby Holidays gem.
4
+ #
5
+ # Definitions loaded: definitions/my.yaml
6
+ #
7
+ # To use the definitions in this file, load it right after you load the
8
+ # Holiday gem:
9
+ #
10
+ # require 'holidays'
11
+ # require 'generated_definitions/my'
12
+ #
13
+ # All the definitions are available at https://github.com/holidays/holidays
14
+ module MY # :nodoc:
15
+ def self.defined_regions
16
+ [:my]
17
+ end
18
+
19
+ def self.holidays_by_month
20
+ {
21
+ 1 => [{:mday => 1, :observed => "to_weekday_if_weekend(date)", :observed_arguments => [:date], :name => "New Year's Day", :regions => [:my]}],
22
+ 5 => [{:mday => 1, :name => "Labour Day", :regions => [:my]}],
23
+ 6 => [{:mday => 4, :observed => "to_weekday_if_weekend(date)", :observed_arguments => [:date], :name => "Agong's Birthday", :regions => [:my]}],
24
+ 8 => [{:mday => 31, :observed => "to_weekday_if_weekend(date)", :observed_arguments => [:date], :name => "Independence Day", :regions => [:my]}],
25
+ 9 => [{:mday => 16, :observed => "to_weekday_if_weekend(date)", :observed_arguments => [:date], :name => "Malaysia Day", :regions => [:my]}],
26
+ 12 => [{:mday => 25, :observed => "to_weekday_if_weekend(date)", :observed_arguments => [:date], :name => "Christmas Day", :regions => [:my]}]
27
+ }
28
+ end
29
+
30
+ def self.custom_methods
31
+ {
32
+
33
+ }
34
+ end
35
+ end
36
+ end
@@ -79,7 +79,7 @@ module Holidays
79
79
  {:mday => 12, :type => :informal, :name => "Día de la Raza", :regions => [:mx]},
80
80
  {:wday => 1, :week => 2, :name => "Columbus Day", :regions => [:us]},
81
81
  {:mday => 31, :type => :informal, :name => "Halloween", :regions => [:us, :ca]}],
82
- 11 => [{:mday => 11, :name => "Remembrance Day", :regions => [:ca]},
82
+ 11 => [{:mday => 11, :name => "Remembrance Day", :regions => [:ca_ab, :ca_sk, :ca_bc, :ca_pe, :ca_nf, :ca_nt, :ca_nu, :ca_nb, :ca_yk]},
83
83
  {:mday => 1, :type => :informal, :name => "Todos los Santos", :regions => [:mx]},
84
84
  {:mday => 2, :type => :informal, :name => "Los Fieles Difuntos", :regions => [:mx]},
85
85
  {:wday => 1, :week => 3, :name => "Día de la Revolución", :regions => [:mx]},
@@ -116,7 +116,7 @@ year % 4 == 1 ? 20 : nil
116
116
  },
117
117
 
118
118
  "day_after_thanksgiving(year)" => Proc.new { |year|
119
- Holidays::DateCalculatorFactory.day_of_month_calculator.call(year, 11, 4, 4) + 1
119
+ Holidays::Factory::DateCalculator.day_of_month_calculator.call(year, 11, 4, 4) + 1
120
120
  },
121
121
 
122
122
 
@@ -125,7 +125,7 @@ module Holidays
125
125
  date = Date.civil(year,4,18)
126
126
  if date.wday < 4
127
127
  date += (4 - date.wday)
128
- else date
128
+ else
129
129
  date += (11 - date.wday)
130
130
  end
131
131
  date
@@ -32,7 +32,7 @@ module Holidays
32
32
  def self.custom_methods
33
33
  {
34
34
  "day_after_thanksgiving(year)" => Proc.new { |year|
35
- Holidays::DateCalculatorFactory.day_of_month_calculator.call(year, 11, 4, 4) + 1
35
+ Holidays::Factory::DateCalculator.day_of_month_calculator.call(year, 11, 4, 4) + 1
36
36
  },
37
37
 
38
38
 
@@ -52,7 +52,7 @@ year % 4 == 1 ? 20 : nil
52
52
  },
53
53
 
54
54
  "day_after_thanksgiving(year)" => Proc.new { |year|
55
- Holidays::DateCalculatorFactory.day_of_month_calculator.call(year, 11, 4, 4) + 1
55
+ Holidays::Factory::DateCalculator.day_of_month_calculator.call(year, 11, 4, 4) + 1
56
56
  },
57
57
 
58
58
 
@@ -3,10 +3,9 @@ $:.unshift File.dirname(__FILE__)
3
3
 
4
4
  require 'date'
5
5
  require 'digest/md5'
6
- require 'holidays/definition_factory'
7
- require 'holidays/date_calculator_factory'
8
- require 'holidays/option_factory'
9
- require 'holidays/use_case_factory'
6
+ require 'holidays/factory/definition'
7
+ require 'holidays/factory/date_calculator'
8
+ require 'holidays/factory/finder'
10
9
  require 'holidays/errors'
11
10
  require 'holidays/load_all_definitions'
12
11
 
@@ -57,19 +56,6 @@ module Holidays
57
56
  FULL_DEFINITIONS_PATH = File.expand_path(File.dirname(__FILE__) + "/#{DEFINITIONS_PATH}")
58
57
 
59
58
  class << self
60
- # Get all holidays on a given date.
61
- #
62
- # [<tt>date</tt>] A Date object.
63
- # [<tt>:options</tt>] One or more region symbols, <tt>:informal</tt> and/or <tt>:observed</tt>.
64
- #
65
- # Returns an array of hashes or nil. See Holidays#between for the output
66
- # format.
67
- #
68
- # Also available via Date#holidays.
69
- def on(date, *options)
70
- between(date, date, options)
71
- end
72
-
73
59
  # Does the given work-week have any holidays?
74
60
  #
75
61
  # [<tt>date</tt>] A Date object.
@@ -87,6 +73,19 @@ module Holidays
87
73
  between(start_date, end_date, options).empty?
88
74
  end
89
75
 
76
+ # Get all holidays on a given date.
77
+ #
78
+ # [<tt>date</tt>] A Date object.
79
+ # [<tt>:options</tt>] One or more region symbols, <tt>:informal</tt> and/or <tt>:observed</tt>.
80
+ #
81
+ # Returns an array of hashes or nil. See Holidays#between for the output
82
+ # format.
83
+ #
84
+ # Also available via Date#holidays.
85
+ def on(date, *options)
86
+ between(date, date, options)
87
+ end
88
+
90
89
  # Get all holidays occuring between two dates, inclusively.
91
90
  #
92
91
  # Returns an array of hashes or nil.
@@ -112,14 +111,11 @@ module Holidays
112
111
 
113
112
  start_date, end_date = get_date(start_date), get_date(end_date)
114
113
 
115
- if cached_holidays = definition_cache_repository.find(start_date, end_date, options)
114
+ if cached_holidays = Factory::Definition.cache_repository.find(start_date, end_date, options)
116
115
  return cached_holidays
117
116
  end
118
117
 
119
- regions, observed, informal = OptionFactory.parse_options.call(options)
120
- date_driver_hash = UseCaseFactory.dates_driver_builder.call(start_date, end_date)
121
-
122
- UseCaseFactory.between.call(start_date, end_date, date_driver_hash, regions, observed, informal)
118
+ Factory::Finder.between.call(start_date, end_date, options)
123
119
  end
124
120
 
125
121
  # Get next holidays occuring from date, inclusively.
@@ -150,30 +146,24 @@ module Holidays
150
146
  from_date = from_date.new_offset(0) + from_date.offset if from_date.respond_to?(:new_offset)
151
147
 
152
148
  from_date = get_date(from_date)
153
- regions, observed, informal = OptionFactory.parse_options.call(options)
154
149
 
155
- # This could be smarter but I don't have any evidence that just checking for
156
- # the next 12 months will cause us issues. If it does we can implement something
157
- # smarter here to check in smaller increments.
158
- date_driver_hash = UseCaseFactory.dates_driver_builder.call(from_date, from_date >> 12)
159
-
160
- UseCaseFactory.next_holiday.call(holidays_count, from_date, date_driver_hash, regions, observed, informal)
150
+ Factory::Finder.next_holiday.call(holidays_count, from_date, options)
161
151
  end
162
152
 
163
- # Get all holidays occuring from date to end of year, inclusively.
153
+ # Get all holidays occuring from date to end of year, inclusively.
164
154
  #
165
- # Returns an array of hashes or nil.
155
+ # Returns an array of hashes or nil.
166
156
  #
167
- # Incoming arguments are below:
157
+ # Incoming arguments are below:
168
158
  # [<tt>options</tt>] One or more region symbols, <tt>:informal</tt> and/or <tt>:observed</tt>.
169
159
  # [<tt>from_date</tt>] Ruby Date object. This is an optional param, defaulted today.
170
160
  #
171
161
  # ==== Example
172
162
  # Date.today
173
163
  # => Tue, 23 Feb 2016
174
- #
164
+ #
175
165
  # regions = [:ca_on]
176
- #
166
+ #
177
167
  # Holidays.year_holidays(regions)
178
168
  # => [{:name=>"Good Friday",...},
179
169
  # {name=>"Easter Sunday",...},
@@ -191,17 +181,9 @@ module Holidays
191
181
 
192
182
  # remove the timezone
193
183
  from_date = from_date.new_offset(0) + from_date.offset if from_date.respond_to?(:new_offset)
194
-
195
184
  from_date = get_date(from_date)
196
- to_date = Date.new(from_date.year, 12, 31)
197
- regions, observed, informal = OptionFactory.parse_options.call(options)
198
-
199
- # This could be smarter but I don't have any evidence that just checking for
200
- # the next 12 months will cause us issues. If it does we can implement something
201
- # smarter here to check in smaller increments.
202
- date_driver_hash = UseCaseFactory.dates_driver_builder.call(from_date, from_date >> 12)
203
185
 
204
- UseCaseFactory.year_holiday.call(from_date, to_date, date_driver_hash, regions, observed, informal)
186
+ Factory::Finder.year_holiday.call(from_date, options)
205
187
  end
206
188
 
207
189
  # Allows a developer to explicitly calculate and cache holidays within a given period
@@ -209,7 +191,7 @@ module Holidays
209
191
  start_date, end_date = get_date(start_date), get_date(end_date)
210
192
  cache_data = between(start_date, end_date, *options)
211
193
 
212
- definition_cache_repository.cache_between(start_date, end_date, cache_data, options)
194
+ Factory::Definition.cache_repository.cache_between(start_date, end_date, cache_data, options)
213
195
  end
214
196
 
215
197
  # Returns an array of symbols of all the available holiday regions.
@@ -219,13 +201,13 @@ module Holidays
219
201
 
220
202
  # Parses provided holiday definition file(s) and loads them so that they are immediately available.
221
203
  def load_custom(*files)
222
- regions, rules_by_month, custom_methods, tests = DefinitionFactory.file_parser.parse_definition_files(files)
204
+ regions, rules_by_month, custom_methods, _ = Factory::Definition.file_parser.parse_definition_files(files)
223
205
 
224
206
  custom_methods.each do |method_key, method_entity|
225
- custom_methods[method_key] = Holidays::DefinitionFactory.custom_method_proc_decorator.call(method_entity)
207
+ custom_methods[method_key] = Factory::Definition.custom_method_proc_decorator.call(method_entity)
226
208
  end
227
209
 
228
- DefinitionFactory.merger.call(regions, rules_by_month, custom_methods)
210
+ Factory::Definition.merger.call(regions, rules_by_month, custom_methods)
229
211
 
230
212
  rules_by_month
231
213
  end
@@ -239,10 +221,6 @@ module Holidays
239
221
  Date.civil(date.year, date.mon, date.mday)
240
222
  end
241
223
  end
242
-
243
- def definition_cache_repository
244
- DefinitionFactory.cache_repository
245
- end
246
224
  end
247
225
  end
248
226
 
@@ -49,7 +49,7 @@ module Holidays
49
49
 
50
50
  module ClassMethods
51
51
  def calculate_mday(year, month, week, wday)
52
- Holidays::DateCalculatorFactory.day_of_month_calculator.call(year, month, week, wday)
52
+ Holidays::Factory::DateCalculator.day_of_month_calculator.call(year, month, week, wday)
53
53
  end
54
54
  end
55
55
  end
@@ -0,0 +1,86 @@
1
+ require 'holidays/errors'
2
+
3
+ module Holidays
4
+ module Definition
5
+ module Context
6
+ class FunctionProcessor
7
+ def initialize(custom_methods_repo, proc_result_cache_repo)
8
+ @custom_methods_repo = custom_methods_repo
9
+ @proc_result_cache_repo = proc_result_cache_repo
10
+ end
11
+
12
+ def call(year, month, day, func_id, desired_func_args, func_modifier = nil)
13
+ validate!(year, month, day, func_id, desired_func_args)
14
+
15
+ function = @custom_methods_repo.find(func_id)
16
+ raise Holidays::FunctionNotFound.new("Unable to find function with id '#{func_id}'") if function.nil?
17
+
18
+ calculate(year, month, function, parse_arguments(year, month, day, desired_func_args), func_modifier)
19
+ end
20
+
21
+ private
22
+
23
+ VALID_ARGUMENTS = [:year, :month, :day, :date]
24
+
25
+ def validate!(year, month, day, func_id, desired_func_args)
26
+ raise ArgumentError if desired_func_args.nil? || desired_func_args.empty?
27
+
28
+ desired_func_args.each do |name|
29
+ raise ArgumentError unless VALID_ARGUMENTS.include?(name)
30
+ end
31
+
32
+ raise ArgumentError if desired_func_args.include?(:year) && !year.is_a?(Integer)
33
+ raise ArgumentError if desired_func_args.include?(:month) && (month < 0 || month > 12)
34
+ raise ArgumentError if desired_func_args.include?(:day) && (day < 1 || day > 31)
35
+ end
36
+
37
+ def parse_arguments(year, month, day, target_args)
38
+ args = []
39
+
40
+ if target_args.include?(:year)
41
+ args << year
42
+ end
43
+
44
+ if target_args.include?(:month)
45
+ args << month
46
+ end
47
+
48
+ if target_args.include?(:day)
49
+ args << day
50
+ end
51
+
52
+ if target_args.include?(:date)
53
+ args << Date.civil(year, month, day)
54
+ end
55
+
56
+ args
57
+ end
58
+
59
+ def calculate(year, month, id, args, modifier)
60
+ result = @proc_result_cache_repo.lookup(id, *args)
61
+ if result.kind_of?(Date)
62
+ if modifier
63
+ result = result + modifier # NOTE: This could be a positive OR negative number.
64
+ end
65
+ elsif result.is_a?(Integer)
66
+ begin
67
+ result = Date.civil(year, month, result)
68
+ rescue ArgumentError
69
+ raise Holidays::InvalidFunctionResponse.new("invalid day response from custom method call resulting in invalid date. Result: '#{result}'")
70
+ end
71
+ elsif result.nil?
72
+ # Do nothing. This is because some functions can return 'nil' today.
73
+ # I want to change this and so rather than come up with a clean
74
+ # implementation I'll do this so we don't throw an error in this specific
75
+ # situation. This should be removed once we have changed the existing
76
+ # custom definition functions. See https://github.com/holidays/holidays/issues/204
77
+ else
78
+ raise Holidays::InvalidFunctionResponse.new("invalid response from custom method call, must be a 'date' or 'integer' representing the day. Result: '#{result}'")
79
+ end
80
+
81
+ result
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
@@ -1,5 +1,12 @@
1
1
  require 'yaml'
2
2
 
3
+ #FIXME This whole file is my next refactor target. We do wayyyyy too much by
4
+ # convention here. We need hard and fast rules and explicit errors when you
5
+ # try to parse something that isn't allowed. So if you are a dev recognize
6
+ # that a lot of the guard statements in here are to codify existing legacy
7
+ # logic. The fact is that we already require these guards, we just don't
8
+ # enforce it explicitly. Now we will. And by doing so things will begin
9
+ # to look very, very messy.
3
10
  module Holidays
4
11
  module Definition
5
12
  module Context
@@ -23,7 +30,7 @@ module Holidays
23
30
  files.each do |file|
24
31
  definition_file = YAML.load_file(file)
25
32
 
26
- custom_methods = custom_method_parser.call(definition_file['methods'])
33
+ custom_methods = @custom_method_parser.call(definition_file['methods'])
27
34
 
28
35
  regions, rules_by_month = parse_month_definitions(definition_file['months'], custom_methods)
29
36
 
@@ -54,7 +61,7 @@ module Holidays
54
61
  # Build the custom methods string
55
62
  custom_method_string = ''
56
63
  custom_methods.each do |key, code|
57
- custom_method_string << custom_method_source_decorator.call(code) + ",\n\n"
64
+ custom_method_string << @custom_method_source_decorator.call(code) + ",\n\n"
58
65
  end
59
66
 
60
67
  module_src = generate_module_src(module_name, files, regions, month_strings, custom_method_string)
@@ -65,8 +72,6 @@ module Holidays
65
72
 
66
73
  private
67
74
 
68
- attr_reader :custom_method_parser, :custom_method_source_decorator, :custom_methods_repository
69
-
70
75
  #FIXME This should be a 'month_definitions_parser' like the above parser
71
76
  def parse_month_definitions(month_definitions, parsed_custom_methods)
72
77
  regions = []
@@ -83,9 +88,12 @@ module Holidays
83
88
  end
84
89
 
85
90
  rule[:regions] = rule[:regions].collect { |r| r.to_sym }
86
-
87
91
  regions << rule[:regions]
88
92
 
93
+ if rule[:year_ranges]
94
+ rule[:year_ranges] = clean_year_ranges(rule[:year_ranges])
95
+ end
96
+
89
97
  exists = false
90
98
  rules_by_month[month].each do |ex|
91
99
  if ex[:name] == rule[:name] and ex[:wday] == rule[:wday] and ex[:mday] == rule[:mday] and ex[:week] == rule[:week] and ex[:type] == rule[:type] and ex[:function] == rule[:function] and ex[:observed] == rule[:observed] and ex[:year_ranges] == rule[:year_ranges]
@@ -110,6 +118,23 @@ module Holidays
110
118
  [regions, rules_by_month]
111
119
  end
112
120
 
121
+ # In this case we end up parsing a range as "2006..2008" a string. This is codifying
122
+ # what we already do...today we parse as a string but when writing out to our final
123
+ # generated files it comes out as a range that Ruby interprets. This just puts it in stone
124
+ # what we want to do.
125
+ def clean_year_ranges(year_ranges)
126
+ year_ranges.collect do |year_range|
127
+ if year_range["between"]
128
+ range = year_range["between"]
129
+ if range.is_a?(String)
130
+ year_range["between"] = Range.new(*range.split("..").map(&:to_i))
131
+ end
132
+ end
133
+
134
+ year_range
135
+ end
136
+ end
137
+
113
138
  def parse_test_definitions(tests)
114
139
  test_strings = []
115
140
 
@@ -193,7 +218,7 @@ module Holidays
193
218
  # What we should do is ensure that all custom methods are loaded into the repo as soon as they are parsed
194
219
  # so we only have one place to look.
195
220
  def get_function_arguments(function_id, parsed_custom_methods)
196
- if method = custom_methods_repository.find(function_id)
221
+ if method = @custom_methods_repository.find(function_id)
197
222
  method.parameters.collect { |arg| arg[1] }
198
223
  elsif method = parsed_custom_methods[function_id]
199
224
  method.arguments.collect { |arg| arg.to_sym }