holidays 3.3.0 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (188) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +44 -0
  3. data/CONTRIBUTING.md +37 -0
  4. data/README.md +16 -25
  5. data/REFERENCES +4 -1
  6. data/Rakefile +38 -8
  7. data/benchmark.rb +8 -0
  8. data/definitions/README.md +187 -8
  9. data/definitions/ar.yaml +2 -1
  10. data/definitions/at.yaml +17 -13
  11. data/definitions/au.yaml +65 -60
  12. data/definitions/be_fr.yaml +14 -10
  13. data/definitions/be_nl.yaml +8 -4
  14. data/definitions/bg.yaml +12 -6
  15. data/definitions/br.yaml +6 -3
  16. data/definitions/ca.yaml +8 -6
  17. data/definitions/ch.yaml +21 -15
  18. data/definitions/cl.yaml +4 -2
  19. data/definitions/cr.yaml +5 -3
  20. data/definitions/cz.yaml +4 -2
  21. data/definitions/de.yaml +25 -14
  22. data/definitions/dk.yaml +26 -17
  23. data/definitions/ecb_target.yaml +4 -2
  24. data/definitions/el.yaml +23 -18
  25. data/definitions/es.yaml +31 -28
  26. data/definitions/federal_reserve.yaml +12 -12
  27. data/definitions/fedex.yaml +6 -6
  28. data/definitions/fi.yaml +26 -25
  29. data/definitions/fr.yaml +8 -4
  30. data/definitions/gb.yaml +9 -7
  31. data/definitions/hr.yaml +8 -6
  32. data/definitions/hu.yaml +8 -6
  33. data/definitions/ie.yaml +17 -16
  34. data/definitions/index.yaml +1 -1
  35. data/definitions/is.yaml +29 -19
  36. data/definitions/it.yaml +10 -9
  37. data/definitions/jp.yaml +92 -44
  38. data/definitions/li.yaml +25 -20
  39. data/definitions/lt.yaml +2 -1
  40. data/definitions/ma.yaml +7 -7
  41. data/definitions/mx.yaml +11 -11
  42. data/definitions/nerc.yaml +6 -6
  43. data/definitions/nl.yaml +22 -18
  44. data/definitions/no.yaml +19 -11
  45. data/definitions/north_america_informal.yaml +6 -6
  46. data/definitions/nyse.yaml +9 -8
  47. data/definitions/nz.yaml +33 -29
  48. data/definitions/ph.yaml +15 -8
  49. data/definitions/pl.yaml +27 -17
  50. data/definitions/pt.yaml +4 -2
  51. data/definitions/ro.yaml +21 -18
  52. data/definitions/se.yaml +24 -18
  53. data/definitions/sg.yaml +10 -9
  54. data/definitions/si.yaml +4 -2
  55. data/definitions/sk.yaml +4 -2
  56. data/definitions/united_nations.yaml +12 -12
  57. data/definitions/ups.yaml +6 -6
  58. data/definitions/us.yaml +12 -11
  59. data/definitions/ve.yaml +8 -4
  60. data/definitions/vi.yaml +6 -6
  61. data/definitions/za.yaml +26 -24
  62. data/holidays.gemspec +3 -1
  63. data/lib/generated_definitions/MANIFEST +1 -1
  64. data/lib/generated_definitions/ar.rb +8 -6
  65. data/lib/generated_definitions/at.rb +11 -9
  66. data/lib/generated_definitions/au.rb +75 -99
  67. data/lib/generated_definitions/be.rb +12 -10
  68. data/lib/generated_definitions/be_fr.rb +12 -10
  69. data/lib/generated_definitions/be_nl.rb +12 -10
  70. data/lib/generated_definitions/bg.rb +14 -13
  71. data/lib/generated_definitions/br.rb +11 -9
  72. data/lib/generated_definitions/ca.rb +20 -20
  73. data/lib/generated_definitions/ch.rb +41 -44
  74. data/lib/generated_definitions/cl.rb +9 -7
  75. data/lib/generated_definitions/cr.rb +9 -7
  76. data/lib/generated_definitions/cz.rb +9 -6
  77. data/lib/generated_definitions/de.rb +25 -25
  78. data/lib/generated_definitions/dk.rb +17 -15
  79. data/lib/generated_definitions/ecb_target.rb +9 -7
  80. data/lib/generated_definitions/el.rb +13 -11
  81. data/lib/generated_definitions/es.rb +35 -33
  82. data/lib/generated_definitions/europe.rb +234 -247
  83. data/lib/generated_definitions/federal_reserve.rb +11 -9
  84. data/lib/generated_definitions/fedex.rb +42 -0
  85. data/lib/generated_definitions/fi.rb +32 -36
  86. data/lib/generated_definitions/fr.rb +12 -10
  87. data/lib/generated_definitions/gb.rb +15 -13
  88. data/lib/generated_definitions/hr.rb +10 -8
  89. data/lib/generated_definitions/hu.rb +9 -7
  90. data/lib/generated_definitions/ie.rb +17 -17
  91. data/lib/generated_definitions/is.rb +26 -26
  92. data/lib/generated_definitions/it.rb +9 -7
  93. data/lib/generated_definitions/jp.rb +112 -89
  94. data/lib/generated_definitions/li.rb +14 -12
  95. data/lib/generated_definitions/lt.rb +9 -7
  96. data/lib/generated_definitions/ma.rb +7 -5
  97. data/lib/generated_definitions/mx.rb +7 -5
  98. data/lib/generated_definitions/nerc.rb +10 -8
  99. data/lib/generated_definitions/nl.rb +15 -13
  100. data/lib/generated_definitions/no.rb +16 -14
  101. data/lib/generated_definitions/north_america.rb +34 -37
  102. data/lib/generated_definitions/nyse.rb +10 -8
  103. data/lib/generated_definitions/nz.rb +40 -40
  104. data/lib/generated_definitions/ph.rb +17 -13
  105. data/lib/generated_definitions/pl.rb +25 -27
  106. data/lib/generated_definitions/pt.rb +10 -8
  107. data/lib/generated_definitions/ro.rb +11 -9
  108. data/lib/generated_definitions/scandinavia.rb +92 -102
  109. data/lib/generated_definitions/se.rb +25 -27
  110. data/lib/generated_definitions/sg.rb +11 -9
  111. data/lib/generated_definitions/si.rb +10 -8
  112. data/lib/generated_definitions/sk.rb +9 -7
  113. data/lib/generated_definitions/united_nations.rb +7 -5
  114. data/lib/generated_definitions/ups.rb +13 -12
  115. data/lib/generated_definitions/us.rb +20 -21
  116. data/lib/generated_definitions/ve.rb +11 -9
  117. data/lib/generated_definitions/vi.rb +7 -5
  118. data/lib/generated_definitions/za.rb +19 -17
  119. data/lib/holidays.rb +20 -83
  120. data/lib/holidays/date_calculator/weekend_modifier.rb +22 -5
  121. data/lib/holidays/definition/context/generator.rb +67 -29
  122. data/lib/holidays/definition/context/merger.rb +8 -8
  123. data/lib/holidays/definition/decorator/custom_method_proc.rb +28 -0
  124. data/lib/holidays/definition/decorator/custom_method_source.rb +30 -0
  125. data/lib/holidays/definition/entity/custom_method.rb +11 -0
  126. data/lib/holidays/definition/parser/custom_method.rb +69 -0
  127. data/lib/holidays/definition/repository/custom_methods.rb +27 -0
  128. data/lib/holidays/definition/repository/holidays_by_month.rb +1 -1
  129. data/lib/holidays/definition/repository/{proc_cache.rb → proc_result_cache.rb} +19 -4
  130. data/lib/holidays/definition/validator/custom_method.rb +31 -0
  131. data/lib/holidays/definition_factory.rb +42 -6
  132. data/lib/holidays/errors.rb +6 -0
  133. data/lib/holidays/load_all_definitions.rb +57 -0
  134. data/lib/holidays/option/context/parse_options.rb +26 -16
  135. data/lib/holidays/option_factory.rb +1 -0
  136. data/lib/holidays/use_case/context/between.rb +41 -14
  137. data/lib/holidays/use_case_factory.rb +2 -1
  138. data/lib/holidays/version.rb +1 -1
  139. data/test/data/test_single_custom_holiday_with_custom_procs.yaml +24 -0
  140. data/test/defs/test_defs_at.rb +1 -1
  141. data/test/defs/test_defs_au.rb +3 -2
  142. data/test/defs/test_defs_cr.rb +1 -0
  143. data/test/defs/test_defs_cz.rb +1 -0
  144. data/test/defs/test_defs_dk.rb +2 -2
  145. data/test/defs/test_defs_el.rb +7 -6
  146. data/test/defs/test_defs_europe.rb +40 -33
  147. data/test/defs/test_defs_fedex.rb +24 -0
  148. data/test/defs/test_defs_fi.rb +4 -3
  149. data/test/defs/test_defs_hr.rb +2 -2
  150. data/test/defs/test_defs_hu.rb +2 -2
  151. data/test/defs/test_defs_is.rb +2 -1
  152. data/test/defs/test_defs_it.rb +2 -1
  153. data/test/defs/test_defs_jp.rb +1 -1
  154. data/test/defs/test_defs_li.rb +1 -1
  155. data/test/defs/test_defs_ma.rb +2 -1
  156. data/test/defs/test_defs_mx.rb +4 -3
  157. data/test/defs/test_defs_nl.rb +7 -6
  158. data/test/defs/test_defs_no.rb +1 -0
  159. data/test/defs/test_defs_north_america.rb +4 -3
  160. data/test/defs/test_defs_nyse.rb +2 -1
  161. data/test/defs/test_defs_pl.rb +1 -0
  162. data/test/defs/test_defs_ro.rb +11 -11
  163. data/test/defs/test_defs_scandinavia.rb +12 -8
  164. data/test/defs/test_defs_se.rb +3 -2
  165. data/test/defs/test_defs_sg.rb +2 -1
  166. data/test/defs/test_defs_vi.rb +1 -1
  167. data/test/defs/test_defs_za.rb +3 -2
  168. data/test/holidays/date_calculator/test_weekend_modifier.rb +11 -0
  169. data/test/holidays/definition/context/test_generator.rb +64 -5
  170. data/test/holidays/definition/context/test_merger.rb +5 -2
  171. data/test/holidays/definition/decorator/test_custom_method_proc.rb +113 -0
  172. data/test/holidays/definition/decorator/test_custom_method_source.rb +96 -0
  173. data/test/holidays/definition/parser/test_custom_method.rb +79 -0
  174. data/test/holidays/definition/repository/test_custom_methods.rb +43 -0
  175. data/test/holidays/definition/repository/test_holidays_by_month.rb +0 -32
  176. data/test/holidays/definition/repository/test_proc_result_cache.rb +84 -0
  177. data/test/holidays/definition/validator/test_custom_method.rb +89 -0
  178. data/test/holidays/option/context/test_parse_options.rb +5 -0
  179. data/test/holidays/test_definition_factory.rb +17 -2
  180. data/test/holidays/use_case/context/test_between.rb +2 -0
  181. data/test/test_all_regions.rb +7 -49
  182. data/test/test_custom_holidays.rb +8 -2
  183. data/test/test_helper.rb +9 -2
  184. data/test/test_holidays.rb +9 -29
  185. metadata +46 -11
  186. data/lib/generated_definitions/fed_ex.rb +0 -41
  187. data/test/holidays/definition/repository/test_proc_cache.rb +0 -29
  188. data/test/test_parse_definitions.rb +0 -30
@@ -0,0 +1,96 @@
1
+ require File.expand_path(File.dirname(__FILE__)) + '/../../../test_helper'
2
+
3
+ require 'holidays/definition/decorator/custom_method_source'
4
+ require 'holidays/definition/entity/custom_method'
5
+
6
+ class DecoratorCustomMethodSourceTests < Test::Unit::TestCase
7
+ def setup
8
+ @decorator = Holidays::Definition::Decorator::CustomMethodSource.new
9
+ end
10
+
11
+ def test_call_generates_source_from_entity
12
+ entity = Holidays::Definition::Entity::CustomMethod.new(
13
+ name: "test",
14
+ arguments: ["year"],
15
+ source: "Date.civil(year, 1, 1)"
16
+ )
17
+
18
+ source = @decorator.call(entity)
19
+ expected_source = "\"#{entity.name}(#{entity.arguments[0]})\" => Proc.new { |year|\n#{entity.source}}"
20
+
21
+ assert_equal expected_source, source
22
+ end
23
+
24
+ def test_call_generates_source_from_entity_with_multiple_arguments
25
+ entity = Holidays::Definition::Entity::CustomMethod.new(
26
+ name: "test",
27
+ arguments: ["year", "month"],
28
+ source: "Date.civil(year, month, 1)"
29
+ )
30
+
31
+ source = @decorator.call(entity)
32
+ expected_args = "#{entity.arguments[0]}, #{entity.arguments[1]}"
33
+
34
+ expected_source = "\"#{entity.name}(#{expected_args})\" => Proc.new { |#{expected_args}|\n#{entity.source}}"
35
+
36
+ assert_equal expected_source, source
37
+ end
38
+
39
+ def test_call_generates_source_from_entity_when_source_is_multiple_lines
40
+ entity = Holidays::Definition::Entity::CustomMethod.new(
41
+ name: "test",
42
+ arguments: ["year"],
43
+ source: "d = Date.civil(year, 1, 1)\nd + 2"
44
+ )
45
+
46
+ source = @decorator.call(entity)
47
+ expected_source = "\"#{entity.name}(#{entity.arguments[0]})\" => Proc.new { |year|\n#{entity.source}}"
48
+
49
+ assert_equal expected_source, source
50
+ end
51
+
52
+ def test_call_raises_error_if_missing_name
53
+ entity = Holidays::Definition::Entity::CustomMethod.new(
54
+ arguments: ["year", "month"],
55
+ source: "Date.civil(year, month, 1)"
56
+ )
57
+
58
+ assert_raises ArgumentError do
59
+ @decorator.call(entity)
60
+ end
61
+ end
62
+
63
+ def test_call_raises_error_if_missing_arguments
64
+ entity = Holidays::Definition::Entity::CustomMethod.new(
65
+ name: "test",
66
+ source: "Date.civil(year, month, 1)"
67
+ )
68
+
69
+ assert_raises ArgumentError do
70
+ @decorator.call(entity)
71
+ end
72
+ end
73
+
74
+ def test_call_raises_error_if_arguments_is_not_an_array
75
+ entity = Holidays::Definition::Entity::CustomMethod.new(
76
+ name: "test",
77
+ arguments: "test",
78
+ source: "Date.civil(year, month, 1)"
79
+ )
80
+
81
+ assert_raises ArgumentError do
82
+ @decorator.call(entity)
83
+ end
84
+ end
85
+
86
+ def test_call_raises_error_if_missing_source
87
+ entity = Holidays::Definition::Entity::CustomMethod.new(
88
+ name: "test",
89
+ arguments: ["year", "month"],
90
+ )
91
+
92
+ assert_raises ArgumentError do
93
+ @decorator.call(entity)
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,79 @@
1
+ require File.expand_path(File.dirname(__FILE__)) + '/../../../test_helper'
2
+
3
+ require 'holidays/definition/parser/custom_method'
4
+ require 'holidays/definition/entity/custom_method'
5
+
6
+ class ParserCustomMethodTests < Test::Unit::TestCase
7
+ def setup
8
+ @validator = mock()
9
+
10
+ @parser = Holidays::Definition::Parser::CustomMethod.new(@validator)
11
+ end
12
+
13
+ def test_parse_happy_single_method
14
+ input = {"custom_method"=>{"arguments"=>"year", "source"=>"d = Date.civil(year, 1, 1)\nd + 2\n"}}
15
+ @validator.expects(:valid?).with({:name => "custom_method", :arguments => "year", :source => "d = Date.civil(year, 1, 1)\nd + 2\n"}).returns(true)
16
+
17
+ result = @parser.call(input)
18
+
19
+ assert_equal(1, result.size)
20
+
21
+ custom_method = result["custom_method(year)"]
22
+ assert(custom_method)
23
+
24
+ assert(custom_method.is_a?(Holidays::Definition::Entity::CustomMethod))
25
+ assert_equal("custom_method", custom_method.name)
26
+ assert_equal(["year"], custom_method.arguments)
27
+ assert_equal("d = Date.civil(year, 1, 1)\nd + 2\n", custom_method.source)
28
+ end
29
+
30
+ def test_call_happy_with_multiple_methods
31
+ input = {"custom_method"=>{"arguments"=>"year", "source"=>"d = Date.civil(year, 1, 1)\nd + 2\n"}, "second_method"=>{"arguments"=>"month","source"=>"source"}}
32
+ @validator.expects(:valid?).with({:name => "custom_method", :arguments => "year", :source => "d = Date.civil(year, 1, 1)\nd + 2\n"}).returns(true)
33
+ @validator.expects(:valid?).with({:name => "second_method", :arguments => "month", :source => "source"}).returns(true)
34
+
35
+ result = @parser.call(input)
36
+
37
+ assert_equal(2, result.size)
38
+
39
+ custom_method = result["custom_method(year)"]
40
+ assert(custom_method)
41
+
42
+ assert(custom_method.is_a?(Holidays::Definition::Entity::CustomMethod))
43
+ assert_equal("custom_method", custom_method.name)
44
+ assert_equal(["year"], custom_method.arguments)
45
+ assert_equal("d = Date.civil(year, 1, 1)\nd + 2\n", custom_method.source)
46
+
47
+ second_method= result["second_method(month)"]
48
+ assert(second_method)
49
+
50
+ assert(second_method.is_a?(Holidays::Definition::Entity::CustomMethod))
51
+ assert_equal("second_method", second_method.name)
52
+ assert_equal(["month"], second_method.arguments)
53
+ assert_equal("source", second_method.source)
54
+ end
55
+
56
+ def test_call_returns_empty_hash_if_methods_are_missing
57
+ assert_equal({}, @parser.call(nil))
58
+ assert_equal({}, @parser.call({}))
59
+ end
60
+
61
+ def test_call_raises_error_if_validator_returns_false_for_single_method
62
+ input = {"custom_method"=>{"arguments"=>"year", "source"=>"d = Date.civil(year, 1, 1)\nd + 2\n"}}
63
+ @validator.expects(:valid?).with({:name => "custom_method", :arguments => "year", :source => "d = Date.civil(year, 1, 1)\nd + 2\n"}).returns(false)
64
+
65
+ assert_raises ArgumentError do
66
+ result = @parser.call(input)
67
+ end
68
+ end
69
+
70
+ def test_call_raises_error_if_validator_returns_false_for_one_of_multiple_methods
71
+ input = {"custom_method"=>{"arguments"=>"year", "source"=>"d = Date.civil(year, 1, 1)\nd + 2\n"}, "second_method"=>{"arguments"=>"month","source"=>"source"}}
72
+ @validator.expects(:valid?).with({:name => "custom_method", :arguments => "year", :source => "d = Date.civil(year, 1, 1)\nd + 2\n"}).returns(true)
73
+ @validator.expects(:valid?).with({:name => "second_method", :arguments => "month", :source => "source"}).returns(false)
74
+
75
+ assert_raises ArgumentError do
76
+ result = @parser.call(input)
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,43 @@
1
+ require File.expand_path(File.dirname(__FILE__)) + '/../../../test_helper'
2
+
3
+ require 'holidays/definition/repository/custom_methods'
4
+
5
+ class CustomMethodsRepoTests < Test::Unit::TestCase
6
+ def setup
7
+ @subject = Holidays::Definition::Repository::CustomMethods.new
8
+ end
9
+
10
+ def test_add_raises_error_if_input_is_nil
11
+ assert_raise ArgumentError do
12
+ @subject.add(nil)
13
+ end
14
+ end
15
+
16
+ def test_find_returns_nil_if_method_id_does_not_exist
17
+ assert_nil @subject.find("some-method-id")
18
+ end
19
+
20
+ def test_add_successfully_adds_new_custom_methods
21
+ new_custom_methods = {
22
+ "some-method-id" => Proc.new { |year|
23
+ Date.civil(year, 1, 1)
24
+ }
25
+ }
26
+
27
+ @subject.add(new_custom_methods)
28
+
29
+ target_method = @subject.find("some-method-id")
30
+
31
+ assert_equal new_custom_methods["some-method-id"], target_method
32
+ end
33
+
34
+ def test_find_raises_error_if_target_method_id_is_nil_or_empty
35
+ assert_raise ArgumentError do
36
+ @subject.find(nil)
37
+ end
38
+
39
+ assert_raise ArgumentError do
40
+ @subject.find("")
41
+ end
42
+ end
43
+ end
@@ -93,22 +93,6 @@ class HolidaysByMonthRepoTests < Test::Unit::TestCase
93
93
  assert_equal(expected, @subject.all)
94
94
  end
95
95
 
96
- def test_add_is_successful_if_function_id_is_different
97
- target_holidays = {0 => [:mday => 1, :name => "Test", :function_id => 'test', :regions => [:test]]}
98
-
99
- @subject.add(@existing_holidays_by_month)
100
- @subject.add(target_holidays)
101
-
102
- expected = {
103
- 0 => [
104
- {:mday=>1, :name=>"Test", :regions=>[:test]},
105
- {:mday=>1, :name=>"Test", :function_id => 'test', :regions=>[:test]}
106
- ]
107
- }
108
-
109
- assert_equal(expected, @subject.all)
110
- end
111
-
112
96
  def test_add_is_successful_if_type_is_different
113
97
  target_holidays = {0 => [:mday => 1, :name => "Test", :type => :informal, :regions => [:test]]}
114
98
 
@@ -125,22 +109,6 @@ class HolidaysByMonthRepoTests < Test::Unit::TestCase
125
109
  assert_equal(expected, @subject.all)
126
110
  end
127
111
 
128
- def test_add_is_successful_if_observed_id_is_different
129
- target_holidays = {0 => [:mday => 1, :name => "Test", :observed_id => :informal, :regions => [:test]]}
130
-
131
- @subject.add(@existing_holidays_by_month)
132
- @subject.add(target_holidays)
133
-
134
- expected = {
135
- 0 => [
136
- {:mday=>1, :name=>"Test", :regions=>[:test]},
137
- {:mday=>1, :name=>"Test", :observed_id => :informal, :regions=>[:test]}
138
- ]
139
- }
140
-
141
- assert_equal(expected, @subject.all)
142
- end
143
-
144
112
  def test_add_is_successful_and_updates_regions_to_existing_matching_definitions
145
113
  target_holidays = {0 => [:mday => 1, :name => "Test", :regions => [:test2]]}
146
114
 
@@ -0,0 +1,84 @@
1
+ require File.expand_path(File.dirname(__FILE__)) + '/../../../test_helper'
2
+
3
+ require 'holidays/definition/repository/proc_result_cache'
4
+
5
+ class ProcResultCacheRepoTests < Test::Unit::TestCase
6
+ def setup
7
+ @subject = Holidays::Definition::Repository::ProcResultCache.new
8
+ end
9
+
10
+ def test_lookup_stores_and_returns_result_of_function_if_it_is_not_present
11
+ function = lambda { |year| Date.civil(year, 2, 1) - 1 }
12
+ function_argument = 2015
13
+
14
+ assert_equal(Date.civil(2015, 1, 31), @subject.lookup(function, function_argument))
15
+ end
16
+
17
+ #FIXME This test stinks. I don't know how to show that the second invocation
18
+ # doesn't call the function. In rspec I could just do an expect().not_to
19
+ # but it doesn't seem like Mocha can do that? I'm punting.
20
+ def test_lookup_simply_returns_result_of_cache_if_present_after_first_call
21
+ function = lambda { |year| Date.civil(year, 2, 1) - 1 }
22
+ function_argument = 2015
23
+
24
+ assert_equal(Date.civil(2015, 1, 31), @subject.lookup(function, function_argument))
25
+ end
26
+
27
+ def test_lookup_raises_error_if_function_is_not_a_proc
28
+ function = "Holidays.easter(year)"
29
+ function_argument = 2015
30
+
31
+ assert_raise ArgumentError do
32
+ @subject.lookup(function, function_argument)
33
+ end
34
+ end
35
+
36
+ def test_lookup_accepts_date_as_function_argument
37
+ function = lambda { |date| date - 1 }
38
+ function_argument = Date.civil(2015, 2, 1)
39
+
40
+ assert_equal(Date.civil(2015, 1, 31), @subject.lookup(function, function_argument))
41
+ end
42
+
43
+ def test_accepts_multiple_arguments_for_functions
44
+ function = lambda { |year, month, day| Date.civil(year, month, day) + 1 }
45
+ year = 2016
46
+ month = 1
47
+ day = 1
48
+
49
+ assert_equal(Date.civil(2016, 1, 2), @subject.lookup(function, year, month, day))
50
+ end
51
+
52
+ def test_raises_error_if_one_of_multiple_arguments_is_not_an_int_or_date
53
+ function = lambda { |year, month, day| Date.civil(year, month, day) + 1 }
54
+ year = 2016
55
+ month = 1
56
+ day = "1"
57
+
58
+ assert_raise ArgumentError do
59
+ @subject.lookup(function, year, month, day)
60
+ end
61
+ end
62
+
63
+ def test_accepts_mix_of_integers_and_dates_for_multiple_function_arguments
64
+ function = lambda { |date, modifier| date + modifier }
65
+ date = Date.civil(2016, 1, 1)
66
+ modifier = 5
67
+
68
+ assert_equal(Date.civil(2016, 1, 6), @subject.lookup(function, date, modifier))
69
+ end
70
+
71
+ def test_lookup_raises_error_if_function_argument_is_not_valid
72
+ function = lambda { |year| Date.civil(year, 2, 1) - 1 }
73
+ function_argument = "2015"
74
+
75
+ assert_raise ArgumentError do
76
+ @subject.lookup(function, function_argument)
77
+ end
78
+
79
+ funtion_argument = Proc.new { |arg1| "arg1" + "something"}
80
+ assert_raise ArgumentError do
81
+ @subject.lookup(function, function_argument)
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,89 @@
1
+ require File.expand_path(File.dirname(__FILE__)) + '/../../../test_helper'
2
+
3
+ require 'holidays/definition/validator/custom_method'
4
+
5
+ class CustomMethodValidatorTests < Test::Unit::TestCase
6
+ def setup
7
+ @subject = Holidays::Definition::Validator::CustomMethod.new
8
+ end
9
+
10
+ def test_valid_returns_true_if_valid
11
+ m = {:name => "good_method", :arguments => "year", :source => "source"}
12
+ assert @subject.valid?(m)
13
+ end
14
+
15
+ def test_valid_returns_true_with_multiple_arguments
16
+ m = {:name => "good_method", :arguments => "year,month", :source => "source"}
17
+ assert @subject.valid?(m)
18
+ end
19
+
20
+ def test_valid_returns_true_with_date_argument
21
+ m = {:name => "good_method", :arguments => "date", :source => "source"}
22
+ assert @subject.valid?(m)
23
+ end
24
+
25
+ def test_valid_returns_true_with_year_argument
26
+ m = {:name => "good_method", :arguments => "year", :source => "source"}
27
+ assert @subject.valid?(m)
28
+ end
29
+
30
+ def test_valid_returns_true_with_month_argument
31
+ m = {:name => "good_method", :arguments => "month", :source => "source"}
32
+ assert @subject.valid?(m)
33
+ end
34
+
35
+ def test_valid_returns_true_with_day_argument
36
+ m = {:name => "good_method", :arguments => "day", :source => "source"}
37
+ assert @subject.valid?(m)
38
+ end
39
+
40
+ def test_valid_returns_true_multiple_arguments_with_whitespace
41
+ m = {:name => "good_method", :arguments => "year , month", :source => "source"}
42
+ assert @subject.valid?(m)
43
+ end
44
+
45
+ def test_valid_returns_false_if_single_argument_contain_carriage_return
46
+ m = {:name => "bad_method", :arguments =>"year\n", :source =>"d = Date.civil(year, 1, 1)\nd + 2\n"}
47
+ assert_false @subject.valid?(m)
48
+ end
49
+
50
+ def test_valid_returns_false_if_multiple_arguments_contain_carriage_return
51
+ m = {:name => "bad_method", :arguments =>"year,month\n", :source =>"d = Date.civil(year, 1, 1)\nd + 2\n"}
52
+ assert_false @subject.valid?(m)
53
+ end
54
+
55
+ def test_valid_returns_false_if_multiple_arguments_contain_carriage_return_with_whitespace
56
+ m = {:name => "bad_method", :arguments =>"year , month\n", :source =>"d = Date.civil(year, 1, 1)\nd + 2\n"}
57
+ assert_false @subject.valid?(m)
58
+ end
59
+
60
+ def test_valid_returns_false_if_no_source
61
+ m = {:name => "bad_method", :arguments => "day"}
62
+ assert_false @subject.valid?(m)
63
+ end
64
+
65
+ def test_valid_returns_false_if_source_is_empty
66
+ m = {:name => "bad_method", :arguments => "day", :source => ""}
67
+ assert_false @subject.valid?(m)
68
+ end
69
+
70
+ def test_valid_returns_false_if_name_is_missing
71
+ m = {:arguments => "day", :source => "source"}
72
+ assert_false @subject.valid?(m)
73
+ end
74
+
75
+ def test_valid_returns_false_if_name_is_empty
76
+ m = {:name => "", :arguments => "day", :source => "source"}
77
+ assert_false @subject.valid?(m)
78
+ end
79
+
80
+ def test_returns_false_if_multiple_arguments_contain_unrecognized_value
81
+ m = {:name => "bad_method", :arguments => "year,month,day,date,unknown", :source => "source"}
82
+ assert_false @subject.valid?(m)
83
+ end
84
+
85
+ def test_returns_false_if_single_argument_contains_unrecognized_value
86
+ m = {:name => "bad_method", :arguments => "unknown", :source => "source"}
87
+ assert_false @subject.valid?(m)
88
+ end
89
+ end
@@ -15,9 +15,14 @@ class ParseOptionsTests < Test::Unit::TestCase
15
15
  @region_validator = mock()
16
16
  @region_validator.stubs(:valid?).returns(true)
17
17
 
18
+ # As mentioned above, this set of tests is NOT isolated. We need
19
+ # the real merger code here.
20
+ @definition_merger = Holidays::DefinitionFactory.merger
21
+
18
22
  @subject = Holidays::Option::Context::ParseOptions.new(
19
23
  @regions_repo,
20
24
  @region_validator,
25
+ @definition_merger,
21
26
  )
22
27
  end
23
28