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
@@ -1,6 +1,6 @@
1
1
  require File.expand_path(File.dirname(__FILE__)) + '/../../../test_helper'
2
2
 
3
- require 'holidays/option/context/parse_options'
3
+ require 'holidays/finder/context/parse_options'
4
4
 
5
5
  #TODO This set of tests need love. Since the class itself requires actual
6
6
  # definition files we have real defs in here, meaning that these tests
@@ -17,9 +17,9 @@ class ParseOptionsTests < Test::Unit::TestCase
17
17
 
18
18
  # As mentioned above, this set of tests is NOT isolated. We need
19
19
  # the real merger code here.
20
- @definition_merger = Holidays::DefinitionFactory.merger
20
+ @definition_merger = Holidays::Factory::Definition.merger
21
21
 
22
- @subject = Holidays::Option::Context::ParseOptions.new(
22
+ @subject = Holidays::Finder::Context::ParseOptions.new(
23
23
  @regions_repo,
24
24
  @region_validator,
25
25
  @definition_merger,
@@ -28,30 +28,30 @@ class ParseOptionsTests < Test::Unit::TestCase
28
28
 
29
29
  def test_returns_observed_true_if_options_contains_observed_flag
30
30
  @regions_repo.expects(:exists?).returns(false)
31
- regions, observed, informal = @subject.call([:ca, :observed])
31
+ observed = @subject.call([:ca, :observed])[1]
32
32
  assert_equal(true, observed)
33
33
  end
34
34
 
35
35
  def test_returns_observed_false_if_options_contains_observed_flag
36
36
  @regions_repo.expects(:exists?).returns(false)
37
- regions, observed, informal = @subject.call([:ca])
37
+ observed = @subject.call([:ca])[1]
38
38
  assert_equal(false, observed)
39
39
  end
40
40
 
41
41
  def test_returns_informal_true_if_options_contains_informal_flag
42
42
  @regions_repo.expects(:exists?).returns(false)
43
- regions, observed, informal = @subject.call([:ca, :informal])
43
+ informal = @subject.call([:ca, :informal])[2]
44
44
  assert_equal(true, informal)
45
45
  end
46
46
 
47
47
  def test_returns_informal_false_if_options_contains_informal_flag
48
48
  @regions_repo.expects(:exists?).returns(false)
49
- regions, observed, informal = @subject.call([:ca])
49
+ informal = @subject.call([:ca])[2]
50
50
  assert_equal(false, informal)
51
51
  end
52
52
 
53
53
  def test_returns_any_if_no_regions_are_provided
54
- regions, observed, informal = @subject.call(:informal)
54
+ regions = @subject.call(:informal)[0]
55
55
  assert_equal([:any], regions)
56
56
  end
57
57
 
@@ -60,7 +60,7 @@ class ParseOptionsTests < Test::Unit::TestCase
60
60
  @regions_repo.expects(:exists?).with(:ch_zh).returns(true)
61
61
  @regions_repo.expects(:search).with('ch_').returns([:ch_zh])
62
62
 
63
- regions, observed, informal = @subject.call([:ch_])
63
+ regions = @subject.call([:ch_])[0]
64
64
  assert_equal(false, regions.include?(:ch_))
65
65
  end
66
66
 
@@ -0,0 +1,203 @@
1
+ require File.expand_path(File.dirname(__FILE__)) + '/../../../test_helper'
2
+
3
+ require 'holidays/finder/context/search'
4
+
5
+ class FinderSearchTests < Test::Unit::TestCase
6
+ def setup
7
+ @holidays_by_month_repo = mock()
8
+ @custom_method_processor = mock()
9
+ @day_of_month_calculator = mock()
10
+
11
+ @in_region_rule = mock()
12
+ @year_range_rule = mock()
13
+ @rules = {:in_region => @in_region_rule, :year_range => @year_range_rule}
14
+
15
+ @custom_method_repo = mock()
16
+ @proc_cache_repo = mock()
17
+
18
+ @subject = Holidays::Finder::Context::Search.new(
19
+ @holidays_by_month_repo,
20
+ @custom_method_processor,
21
+ @day_of_month_calculator,
22
+ @rules,
23
+ )
24
+
25
+ @start_date = Date.civil(2015, 1, 1)
26
+ @end_date = Date.civil(2015, 1, 1)
27
+ @dates_driver = {2015 => [1]}
28
+ @regions = [:us]
29
+ @options = []
30
+
31
+ @holidays_by_month_repo.expects(:find_by_month).at_most_once.returns([:mday => 1, :name => "Test", :regions=>@regions])
32
+ @in_region_rule.expects(:call).at_most_once.returns(true)
33
+ @year_range_rule.expects(:call).at_most_once.returns(false)
34
+ end
35
+
36
+ def test_raises_error_if_dates_driver_is_empty
37
+ @dates_driver = {}
38
+ assert_raises ArgumentError do
39
+ @subject.call(@dates_driver, @regions, @options)
40
+ end
41
+ end
42
+
43
+ def test_raises_error_if_dates_driver_contains_bad_month
44
+ @dates_driver = {2015 => [100]}
45
+ assert_raises ArgumentError do
46
+ @subject.call(@dates_driver, @regions, @options)
47
+ end
48
+ end
49
+
50
+ def test_raises_error_if_dates_driver_contains_bad_month_mixed_with_valid_months
51
+ @dates_driver = {2015 => [1, 12], 2020 => [1, 200]}
52
+ assert_raises ArgumentError do
53
+ @subject.call(@dates_driver, @regions, @options)
54
+ end
55
+ end
56
+
57
+ def test_returns_nothing_if_holidays_repo_returns_nil
58
+ @holidays_by_month_repo.expects(:find_by_month).with(1).returns(nil)
59
+ assert_equal([], @subject.call(@dates_driver, @regions, @options))
60
+ end
61
+
62
+ def test_returns_nothing_if_holidays_repo_returns_empty_array
63
+ @holidays_by_month_repo.expects(:find_by_month).with(1).returns([])
64
+ assert_equal([], @subject.call(@dates_driver, @regions, @options))
65
+ end
66
+
67
+ def test_returns_nothing_if_holidays_not_in_region
68
+ @holidays_by_month_repo.expects(:find_by_month).returns([:regions=>[:other_region]])
69
+ @in_region_rule.expects(:call).with(@regions, [:other_region]).returns(false)
70
+ assert_equal([], @subject.call(@dates_driver, @regions, @options))
71
+ end
72
+
73
+ def test_returns_nothing_if_only_informal_holidays_are_returned_and_no_informal_flag_set
74
+ @holidays_by_month_repo.expects(:find_by_month).returns([:type => :informal, :regions=>@regions])
75
+ assert_equal([], @subject.call(@dates_driver, @regions, @options))
76
+ end
77
+
78
+ def test_year_rule_set_but_not_in_required_years_returns_nothing
79
+ @holidays_by_month_repo.expects(:find_by_month).at_most_once.returns([:mday => 1, :name => "Test", :regions=>@regions, :year_ranges => [:after => 2000]])
80
+ assert_equal([], @subject.call(@dates_driver, @regions, @options))
81
+ end
82
+
83
+ def test_function_present_returns_date
84
+ @holidays_by_month_repo.expects(:find_by_month).at_most_once.returns([:mday => 1, :name => "Test", :regions=> @regions, :function => "func-id", :function_arguments => [:year], :function_modifier => 1])
85
+
86
+ returned_date = Date.civil(2015, 3, 10)
87
+ @custom_method_processor.expects(:call).with(
88
+ 2015,
89
+ 1,
90
+ 1,
91
+ "func-id",
92
+ [:year],
93
+ 1,
94
+ ).returns(returned_date)
95
+
96
+ assert_equal(
97
+ [{
98
+ :date => Date.civil(2015, 3, 10),
99
+ :name => "Test",
100
+ :regions => [:us],
101
+ }],
102
+ @subject.call(@dates_driver, @regions, @options)
103
+ )
104
+ end
105
+
106
+ #FIXME This is a test that reflects how the current system works
107
+ # but this is NOT valid. See https://github.com/holidays/holidays/issues/204
108
+ def test_function_returns_nil_date_should_not_be_returned
109
+ @holidays_by_month_repo.expects(:find_by_month).at_most_once.returns([:mday => 1, :name => "Test", :regions=> @regions, :function => "func-id", :function_arguments => [:year], :function_modifier => 1])
110
+
111
+ @custom_method_processor.expects(:call).with(
112
+ 2015,
113
+ 1,
114
+ 1,
115
+ "func-id",
116
+ [:year],
117
+ 1,
118
+ ).returns(nil)
119
+
120
+ assert_equal([], @subject.call(@dates_driver, @regions, @options))
121
+ end
122
+
123
+ def test_function_not_present_mday_set
124
+ @holidays_by_month_repo.expects(:find_by_month).at_most_once.returns([:mday => 15, :name => "Test", :regions=> @regions])
125
+
126
+ assert_equal(
127
+ [{
128
+ :date => Date.civil(2015, 1, 15),
129
+ :name => "Test",
130
+ :regions => [:us],
131
+ }],
132
+ @subject.call(@dates_driver, @regions, @options)
133
+ )
134
+ end
135
+
136
+ def test_function_not_present_mday_not_set
137
+ @holidays_by_month_repo.expects(:find_by_month).at_most_once.returns([:name => "Test", :week => 1, :wday => 1, :regions=> @regions])
138
+
139
+ @day_of_month_calculator.expects(:call).with(2015, 1, 1, 1).returns(20)
140
+
141
+ assert_equal(
142
+ [{
143
+ :date => Date.civil(2015, 1, 20),
144
+ :name => "Test",
145
+ :regions => [:us],
146
+ }],
147
+ @subject.call(@dates_driver, @regions, @options)
148
+ )
149
+ end
150
+
151
+ def test_returns_holiday_if_informal_and_informal_flag_set
152
+ @holidays_by_month_repo.expects(:find_by_month).at_most_once.returns([:mday => 13, :name => "Test", :type => :informal, :regions=>@regions])
153
+
154
+ assert_equal(
155
+ [{
156
+ :date => Date.civil(2015, 1, 13),
157
+ :name => "Test",
158
+ :regions => [:us],
159
+ }],
160
+ @subject.call(@dates_driver, @regions, [:informal])
161
+ )
162
+ end
163
+
164
+ def test_does_not_return_holiday_if_informal_and_informal_flag_not_set
165
+ @holidays_by_month_repo.expects(:find_by_month).at_most_once.returns([:mday => 13, :name => "Test", :type => :informal, :regions=>@regions])
166
+
167
+ assert_equal([], @subject.call(@dates_driver, @regions, @options))
168
+ end
169
+
170
+ def test_returns_observed_result_if_observed_set_and_observed_function_present
171
+ @holidays_by_month_repo.expects(:find_by_month).at_most_once.returns([:mday => 8, :name => "Test", :type => :observed, :observed => "SOME_OBSERVED_FUNC_ID", :regions=>@regions])
172
+
173
+ @custom_method_processor.expects(:call).with(
174
+ 2015,
175
+ 1,
176
+ 8,
177
+ "SOME_OBSERVED_FUNC_ID",
178
+ [:date],
179
+ ).returns(Date.civil(2015, 10, 1))
180
+
181
+ assert_equal(
182
+ [{
183
+ :date => Date.civil(2015, 10, 1),
184
+ :name => "Test",
185
+ :regions => [:us],
186
+ }],
187
+ @subject.call(@dates_driver, @regions, [:observed])
188
+ )
189
+ end
190
+
191
+ def test_returns_unobserved_date_if_observed_method_not_set_but_flag_is_present
192
+ @holidays_by_month_repo.expects(:find_by_month).at_most_once.returns([:mday => 14, :name => "Test", :type => :observed, :observed => "SOME_OBSERVED_FUNC_ID", :regions=>@regions])
193
+
194
+ assert_equal(
195
+ [{
196
+ :date => Date.civil(2015, 1, 14),
197
+ :name => "Test",
198
+ :regions => [:us],
199
+ }],
200
+ @subject.call(@dates_driver, @regions, @options)
201
+ )
202
+ end
203
+ end
@@ -0,0 +1,202 @@
1
+ require File.expand_path(File.dirname(__FILE__)) + '/../../../test_helper'
2
+
3
+ require 'holidays/finder/context/year_holiday'
4
+
5
+ class YearHolidayTests < Test::Unit::TestCase
6
+ def setup
7
+ @regions = [:us]
8
+ @observed = false
9
+ @informal = false
10
+
11
+ @definition_search = mock()
12
+ @dates_driver_builder = mock()
13
+ @options_parser = mock()
14
+
15
+ @subject = Holidays::Finder::Context::YearHoliday.new(
16
+ @definition_search,
17
+ @dates_driver_builder,
18
+ @options_parser,
19
+ )
20
+
21
+ @from_date= Date.civil(2015, 1, 1)
22
+ @dates_driver = {2015 => [0, 1, 2], 2014 => [0, 12]}
23
+ @options = [@regions, @observed, @informal]
24
+
25
+ @definition_search.expects(:call).at_most_once.with(
26
+ @dates_driver,
27
+ @regions,
28
+ [],
29
+ ).returns([{
30
+ :date => Date.civil(2015, 1, 1),
31
+ :name => "Test",
32
+ :regions => [:us],
33
+ }])
34
+
35
+ @dates_driver_builder.expects(:call).at_most_once.with(
36
+ @from_date, @from_date >> 12,
37
+ ).returns(
38
+ @dates_driver,
39
+ )
40
+
41
+ @options_parser.expects(:call).at_most_once.with(@options).returns(@options)
42
+ end
43
+
44
+ def test_returns_error_if_from_date_is_missing
45
+ assert_raise ArgumentError do
46
+ @subject.call(nil, @options)
47
+ end
48
+ end
49
+
50
+ def test_returns_error_if_from_date_is_not_a_date
51
+ assert_raise ArgumentError do
52
+ @subject.call("2015-1-1", @options)
53
+ end
54
+ end
55
+
56
+ def test_returns_single_holiday
57
+ assert_equal(
58
+ [
59
+ {
60
+ :date => Date.civil(2015, 1, 1),
61
+ :name => "Test",
62
+ :regions => [:us],
63
+ }
64
+ ],
65
+ @subject.call(@from_date, @options)
66
+ )
67
+ end
68
+
69
+ def test_returns_multiple_holidays_in_a_year
70
+ @definition_search.expects(:call).at_most_once.with(
71
+ @dates_driver,
72
+ @regions,
73
+ [],
74
+ ).returns([
75
+ {
76
+ :date => Date.civil(2015, 1, 1),
77
+ :name => "Test",
78
+ :regions => [:us],
79
+ },
80
+ {
81
+ :date => Date.civil(2015, 2, 1),
82
+ :name => "Test",
83
+ :regions => [:us],
84
+ },
85
+ {
86
+ :date => Date.civil(2015, 12, 1),
87
+ :name => "Test",
88
+ :regions => [:us],
89
+ },
90
+ ]
91
+ )
92
+
93
+ assert_equal(
94
+ [
95
+ {
96
+ :date => Date.civil(2015, 1, 1),
97
+ :name => "Test",
98
+ :regions => [:us],
99
+ },
100
+ {
101
+ :date => Date.civil(2015, 2, 1),
102
+ :name => "Test",
103
+ :regions => [:us],
104
+ },
105
+ {
106
+ :date => Date.civil(2015, 12, 1),
107
+ :name => "Test",
108
+ :regions => [:us],
109
+ }
110
+ ],
111
+ @subject.call(@from_date, @options)
112
+ )
113
+ end
114
+
115
+ def test_returns_multiple_holidays_filters_dates_outside_of_year
116
+ @definition_search.expects(:call).at_most_once.with(
117
+ @dates_driver,
118
+ @regions,
119
+ [],
120
+ ).returns([
121
+ {
122
+ :date => Date.civil(2015, 1, 1),
123
+ :name => "Test",
124
+ :regions => [:us],
125
+ },
126
+ {
127
+ :date => Date.civil(2015, 2, 1),
128
+ :name => "Test",
129
+ :regions => [:us],
130
+ },
131
+ {
132
+ :date => Date.civil(2016, 12, 1),
133
+ :name => "Test",
134
+ :regions => [:us],
135
+ },
136
+ ]
137
+ )
138
+
139
+ assert_equal(
140
+ [
141
+ {
142
+ :date => Date.civil(2015, 1, 1),
143
+ :name => "Test",
144
+ :regions => [:us],
145
+ },
146
+ {
147
+ :date => Date.civil(2015, 2, 1),
148
+ :name => "Test",
149
+ :regions => [:us],
150
+ },
151
+ ],
152
+ @subject.call(@from_date, @options)
153
+ )
154
+ end
155
+
156
+ def test_returns_sorted_multiple_holidays
157
+ @definition_search.expects(:call).at_most_once.with(
158
+ @dates_driver,
159
+ @regions,
160
+ [],
161
+ ).returns(
162
+ [
163
+ {
164
+ :date => Date.civil(2015, 1, 1),
165
+ :name => "Test",
166
+ :regions => [:us],
167
+ },
168
+ {
169
+ :date => Date.civil(2015, 12, 1),
170
+ :name => "Test",
171
+ :regions => [:us],
172
+ },
173
+ {
174
+ :date => Date.civil(2015, 2, 1),
175
+ :name => "Test",
176
+ :regions => [:us],
177
+ },
178
+ ]
179
+ )
180
+
181
+ assert_equal(
182
+ [
183
+ {
184
+ :date => Date.civil(2015, 1, 1),
185
+ :name => "Test",
186
+ :regions => [:us],
187
+ },
188
+ {
189
+ :date => Date.civil(2015, 2, 1),
190
+ :name => "Test",
191
+ :regions => [:us],
192
+ },
193
+ {
194
+ :date => Date.civil(2015, 12, 1),
195
+ :name => "Test",
196
+ :regions => [:us],
197
+ }
198
+ ],
199
+ @subject.call(@from_date, @options)
200
+ )
201
+ end
202
+ end