holidays 4.6.0 → 4.7.0

Sign up to get free protection for your applications and to get access to all the features.
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 }