revised_holidays 9.0.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.
- checksums.yaml +7 -0
- data/.github/workflows/ruby.yml +25 -0
- data/CHANGELOG.md +446 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +3 -0
- data/LICENSE +21 -0
- data/Makefile +45 -0
- data/README.md +337 -0
- data/Rakefile +109 -0
- data/bin/console +7 -0
- data/bin/setup +6 -0
- data/definitions/.github/workflows/ruby.yml +25 -0
- data/definitions/.gitignore +5 -0
- data/definitions/CHANGELOG.md +352 -0
- data/definitions/Gemfile +6 -0
- data/definitions/LICENSE +21 -0
- data/definitions/METHODS.yml +26 -0
- data/definitions/Makefile +9 -0
- data/definitions/README.md +22 -0
- data/definitions/ar.yaml +268 -0
- data/definitions/at.yaml +116 -0
- data/definitions/au.yaml +907 -0
- data/definitions/be_fr.yaml +153 -0
- data/definitions/be_nl.yaml +153 -0
- data/definitions/bg.yaml +186 -0
- data/definitions/br.yaml +178 -0
- data/definitions/ca.yaml +969 -0
- data/definitions/ch.yaml +277 -0
- data/definitions/cl.yaml +294 -0
- data/definitions/co.yaml +437 -0
- data/definitions/cr.yaml +100 -0
- data/definitions/cz.yaml +137 -0
- data/definitions/de.yaml +401 -0
- data/definitions/dk.yaml +220 -0
- data/definitions/doc/CONTRIBUTING.md +44 -0
- data/definitions/doc/MAINTAINERS.md +39 -0
- data/definitions/doc/SYNTAX.md +435 -0
- data/definitions/doc/architecture/README.md +15 -0
- data/definitions/doc/architecture/adr-001.md +86 -0
- data/definitions/doc/architecture/adr-002.md +64 -0
- data/definitions/ecbtarget.yaml +74 -0
- data/definitions/ee.yaml +123 -0
- data/definitions/es.yaml +495 -0
- data/definitions/federalreserve.yaml +389 -0
- data/definitions/federalreservebanks.yaml +821 -0
- data/definitions/fedex.yaml +102 -0
- data/definitions/fi.yaml +234 -0
- data/definitions/fr.yaml +157 -0
- data/definitions/gb.yaml +565 -0
- data/definitions/ge.yaml +158 -0
- data/definitions/gr.yaml +158 -0
- data/definitions/hk.yaml +287 -0
- data/definitions/hr.yaml +171 -0
- data/definitions/hu.yaml +156 -0
- data/definitions/ie.yaml +172 -0
- data/definitions/index.yaml +80 -0
- data/definitions/is.yaml +247 -0
- data/definitions/it.yaml +246 -0
- data/definitions/jp.yaml +761 -0
- data/definitions/ke.yaml +107 -0
- data/definitions/kr.yaml +166 -0
- data/definitions/kz.yaml +128 -0
- data/definitions/li.yaml +154 -0
- data/definitions/lib/validation/custom_method_validator.rb +38 -0
- data/definitions/lib/validation/definition_validator.rb +35 -0
- data/definitions/lib/validation/error.rb +11 -0
- data/definitions/lib/validation/month_validator.rb +58 -0
- data/definitions/lib/validation/run.rb +66 -0
- data/definitions/lib/validation/test_validator.rb +83 -0
- data/definitions/lt.yaml +198 -0
- data/definitions/lu.yaml +123 -0
- data/definitions/lv.yaml +229 -0
- data/definitions/ma.yaml +96 -0
- data/definitions/mt_en.yaml +131 -0
- data/definitions/mt_mt.yaml +131 -0
- data/definitions/mx.yaml +160 -0
- data/definitions/my.yaml +79 -0
- data/definitions/nerc.yaml +94 -0
- data/definitions/ng.yaml +97 -0
- data/definitions/nl.yaml +127 -0
- data/definitions/no.yaml +169 -0
- data/definitions/northamericainformal.yaml +105 -0
- data/definitions/nyse.yaml +137 -0
- data/definitions/nz.yaml +346 -0
- data/definitions/pe.yaml +208 -0
- data/definitions/ph.yaml +130 -0
- data/definitions/pl.yaml +796 -0
- data/definitions/pt.yaml +187 -0
- data/definitions/ro.yaml +240 -0
- data/definitions/rs_cyrl.yaml +129 -0
- data/definitions/rs_la.yaml +129 -0
- data/definitions/ru.yaml +108 -0
- data/definitions/se.yaml +238 -0
- data/definitions/sg.yaml +89 -0
- data/definitions/si.yaml +162 -0
- data/definitions/sk.yaml +154 -0
- data/definitions/spec/coverage_report.rb +7 -0
- data/definitions/spec/data/invalid/months/malformed/bad.yaml +15 -0
- data/definitions/spec/data/invalid/months/missing/no_months.yaml +9 -0
- data/definitions/spec/data/valid/simple.yaml +15 -0
- data/definitions/spec/spec_helper.rb +7 -0
- data/definitions/spec/validation/custom_method_validator_spec.rb +60 -0
- data/definitions/spec/validation/definition_validator_spec.rb +43 -0
- data/definitions/spec/validation/month_validator_spec.rb +175 -0
- data/definitions/spec/validation/test_validator_spec.rb +169 -0
- data/definitions/th.yaml +111 -0
- data/definitions/tn.yaml +83 -0
- data/definitions/tr.yaml +174 -0
- data/definitions/ua.yaml +161 -0
- data/definitions/unitednations.yaml +189 -0
- data/definitions/ups.yaml +102 -0
- data/definitions/us.yaml +965 -0
- data/definitions/ve.yaml +118 -0
- data/definitions/vi.yaml +54 -0
- data/definitions/za.yaml +139 -0
- data/doc/CONTRIBUTING.md +72 -0
- data/doc/MAINTAINERS.md +81 -0
- data/doc/REFERENCES +19 -0
- data/lib/generated_definitions/MANIFEST +83 -0
- data/lib/generated_definitions/REGIONS.rb +6 -0
- data/lib/generated_definitions/ar.rb +60 -0
- data/lib/generated_definitions/at.rb +37 -0
- data/lib/generated_definitions/au.rb +177 -0
- data/lib/generated_definitions/be.rb +42 -0
- data/lib/generated_definitions/be_fr.rb +36 -0
- data/lib/generated_definitions/be_nl.rb +36 -0
- data/lib/generated_definitions/bg.rb +53 -0
- data/lib/generated_definitions/br.rb +37 -0
- data/lib/generated_definitions/ca.rb +88 -0
- data/lib/generated_definitions/ch.rb +95 -0
- data/lib/generated_definitions/cl.rb +71 -0
- data/lib/generated_definitions/co.rb +121 -0
- data/lib/generated_definitions/cr.rb +35 -0
- data/lib/generated_definitions/cz.rb +37 -0
- data/lib/generated_definitions/de.rb +65 -0
- data/lib/generated_definitions/dk.rb +48 -0
- data/lib/generated_definitions/ecbtarget.rb +30 -0
- data/lib/generated_definitions/ee.rb +36 -0
- data/lib/generated_definitions/el.rb +38 -0
- data/lib/generated_definitions/es.rb +56 -0
- data/lib/generated_definitions/europe.rb +638 -0
- data/lib/generated_definitions/federalreserve.rb +35 -0
- data/lib/generated_definitions/federalreservebanks.rb +35 -0
- data/lib/generated_definitions/fedex.rb +36 -0
- data/lib/generated_definitions/fi.rb +61 -0
- data/lib/generated_definitions/fr.rb +39 -0
- data/lib/generated_definitions/gb.rb +51 -0
- data/lib/generated_definitions/ge.rb +41 -0
- data/lib/generated_definitions/gr.rb +38 -0
- data/lib/generated_definitions/hk.rb +106 -0
- data/lib/generated_definitions/hr.rb +40 -0
- data/lib/generated_definitions/hu.rb +35 -0
- data/lib/generated_definitions/ie.rb +33 -0
- data/lib/generated_definitions/is.rb +60 -0
- data/lib/generated_definitions/it.rb +45 -0
- data/lib/generated_definitions/jp.rb +166 -0
- data/lib/generated_definitions/ke.rb +34 -0
- data/lib/generated_definitions/kr.rb +40 -0
- data/lib/generated_definitions/kz.rb +38 -0
- data/lib/generated_definitions/li.rb +44 -0
- data/lib/generated_definitions/lt.rb +38 -0
- data/lib/generated_definitions/lu.rb +35 -0
- data/lib/generated_definitions/lv.rb +56 -0
- data/lib/generated_definitions/ma.rb +33 -0
- data/lib/generated_definitions/mt_en.rb +38 -0
- data/lib/generated_definitions/mt_mt.rb +38 -0
- data/lib/generated_definitions/mx.rb +54 -0
- data/lib/generated_definitions/my.rb +30 -0
- data/lib/generated_definitions/nerc.rb +30 -0
- data/lib/generated_definitions/ng.rb +33 -0
- data/lib/generated_definitions/nl.rb +37 -0
- data/lib/generated_definitions/no.rb +40 -0
- data/lib/generated_definitions/northamerica.rb +229 -0
- data/lib/generated_definitions/nyse.rb +34 -0
- data/lib/generated_definitions/nz.rb +105 -0
- data/lib/generated_definitions/pe.rb +43 -0
- data/lib/generated_definitions/ph.rb +50 -0
- data/lib/generated_definitions/pl.rb +73 -0
- data/lib/generated_definitions/pt.rb +40 -0
- data/lib/generated_definitions/ro.rb +39 -0
- data/lib/generated_definitions/rs_cyrl.rb +39 -0
- data/lib/generated_definitions/rs_la.rb +39 -0
- data/lib/generated_definitions/ru.rb +37 -0
- data/lib/generated_definitions/scandinavia.rb +166 -0
- data/lib/generated_definitions/se.rb +53 -0
- data/lib/generated_definitions/sg.rb +31 -0
- data/lib/generated_definitions/si.rb +39 -0
- data/lib/generated_definitions/sk.rb +39 -0
- data/lib/generated_definitions/southamerica.rb +248 -0
- data/lib/generated_definitions/th.rb +36 -0
- data/lib/generated_definitions/tn.rb +32 -0
- data/lib/generated_definitions/tr.rb +64 -0
- data/lib/generated_definitions/ua.rb +37 -0
- data/lib/generated_definitions/unitednations.rb +81 -0
- data/lib/generated_definitions/ups.rb +36 -0
- data/lib/generated_definitions/us.rb +153 -0
- data/lib/generated_definitions/ve.rb +36 -0
- data/lib/generated_definitions/vi.rb +29 -0
- data/lib/generated_definitions/za.rb +36 -0
- data/lib/holidays/core_extensions/date.rb +57 -0
- data/lib/holidays/core_extensions/time.rb +23 -0
- data/lib/holidays/date_calculator/day_of_month.rb +68 -0
- data/lib/holidays/date_calculator/easter.rb +91 -0
- data/lib/holidays/date_calculator/lunar_date.rb +371 -0
- data/lib/holidays/date_calculator/weekend_modifier.rb +80 -0
- data/lib/holidays/definition/context/function_processor.rb +91 -0
- data/lib/holidays/definition/context/generator.rb +209 -0
- data/lib/holidays/definition/context/load.rb +29 -0
- data/lib/holidays/definition/context/merger.rb +22 -0
- data/lib/holidays/definition/decorator/custom_method_proc.rb +28 -0
- data/lib/holidays/definition/decorator/custom_method_source.rb +30 -0
- data/lib/holidays/definition/decorator/test.rb +37 -0
- data/lib/holidays/definition/entity/custom_method.rb +11 -0
- data/lib/holidays/definition/entity/test.rb +11 -0
- data/lib/holidays/definition/generator/module.rb +54 -0
- data/lib/holidays/definition/generator/regions.rb +55 -0
- data/lib/holidays/definition/generator/test.rb +51 -0
- data/lib/holidays/definition/parser/custom_method.rb +67 -0
- data/lib/holidays/definition/parser/test.rb +86 -0
- data/lib/holidays/definition/repository/cache.rb +47 -0
- data/lib/holidays/definition/repository/custom_methods.rb +27 -0
- data/lib/holidays/definition/repository/holidays_by_month.rb +57 -0
- data/lib/holidays/definition/repository/proc_result_cache.rb +51 -0
- data/lib/holidays/definition/repository/regions.rb +46 -0
- data/lib/holidays/definition/validator/custom_method.rb +31 -0
- data/lib/holidays/definition/validator/region.rb +36 -0
- data/lib/holidays/definition/validator/test.rb +71 -0
- data/lib/holidays/errors.rb +11 -0
- data/lib/holidays/factory/date_calculator.rb +42 -0
- data/lib/holidays/factory/definition.rb +143 -0
- data/lib/holidays/factory/finder.rb +70 -0
- data/lib/holidays/finder/context/between.rb +45 -0
- data/lib/holidays/finder/context/dates_driver_builder.rb +64 -0
- data/lib/holidays/finder/context/next_holiday.rb +57 -0
- data/lib/holidays/finder/context/parse_options.rb +104 -0
- data/lib/holidays/finder/context/search.rb +111 -0
- data/lib/holidays/finder/context/year_holiday.rb +57 -0
- data/lib/holidays/finder/rules/in_region.rb +31 -0
- data/lib/holidays/finder/rules/year_range.rb +58 -0
- data/lib/holidays/load_all_definitions.rb +56 -0
- data/lib/holidays/version.rb +3 -0
- data/lib/holidays.rb +130 -0
- data/lib/revised_holidays.rb +1 -0
- data/revised_holidays.gemspec +31 -0
- data/test/coverage_report.rb +26 -0
- data/test/data/test_custom_govt_holiday_defs.yaml +5 -0
- data/test/data/test_custom_informal_holidays_defs.yaml +11 -0
- data/test/data/test_custom_year_range_holiday_defs.yaml +31 -0
- data/test/data/test_invalid_region.rb +15 -0
- data/test/data/test_multiple_custom_holiday_defs.yaml +12 -0
- data/test/data/test_multiple_regions_with_conflicts_region_1.yaml +38 -0
- data/test/data/test_multiple_regions_with_conflicts_region_2.yaml +38 -0
- data/test/data/test_region.rb +15 -0
- data/test/data/test_single_custom_holiday_defs.yaml +12 -0
- data/test/data/test_single_custom_holiday_with_custom_procs.yaml +28 -0
- data/test/defs/test_defs_ar.rb +69 -0
- data/test/defs/test_defs_at.rb +31 -0
- data/test/defs/test_defs_au.rb +233 -0
- data/test/defs/test_defs_be_fr.rb +45 -0
- data/test/defs/test_defs_be_nl.rb +45 -0
- data/test/defs/test_defs_bg.rb +41 -0
- data/test/defs/test_defs_br.rb +49 -0
- data/test/defs/test_defs_ca.rb +289 -0
- data/test/defs/test_defs_ch.rb +51 -0
- data/test/defs/test_defs_cl.rb +69 -0
- data/test/defs/test_defs_co.rb +113 -0
- data/test/defs/test_defs_cr.rb +29 -0
- data/test/defs/test_defs_cz.rb +37 -0
- data/test/defs/test_defs_de.rb +89 -0
- data/test/defs/test_defs_dk.rb +47 -0
- data/test/defs/test_defs_ecbtarget.rb +27 -0
- data/test/defs/test_defs_ee.rb +41 -0
- data/test/defs/test_defs_es.rb +137 -0
- data/test/defs/test_defs_europe.rb +1522 -0
- data/test/defs/test_defs_fed_ex.rb +24 -0
- data/test/defs/test_defs_federalreserve.rb +119 -0
- data/test/defs/test_defs_federalreservebanks.rb +251 -0
- data/test/defs/test_defs_fedex.rb +31 -0
- data/test/defs/test_defs_fi.rb +59 -0
- data/test/defs/test_defs_fr.rb +43 -0
- data/test/defs/test_defs_gb.rb +159 -0
- data/test/defs/test_defs_ge.rb +53 -0
- data/test/defs/test_defs_gr.rb +41 -0
- data/test/defs/test_defs_hk.rb +59 -0
- data/test/defs/test_defs_hr.rb +45 -0
- data/test/defs/test_defs_hu.rb +47 -0
- data/test/defs/test_defs_ie.rb +53 -0
- data/test/defs/test_defs_is.rb +51 -0
- data/test/defs/test_defs_it.rb +55 -0
- data/test/defs/test_defs_jp.rb +159 -0
- data/test/defs/test_defs_ke.rb +31 -0
- data/test/defs/test_defs_kr.rb +37 -0
- data/test/defs/test_defs_kz.rb +39 -0
- data/test/defs/test_defs_li.rb +35 -0
- data/test/defs/test_defs_lt.rb +65 -0
- data/test/defs/test_defs_lu.rb +35 -0
- data/test/defs/test_defs_lv.rb +98 -0
- data/test/defs/test_defs_ma.rb +29 -0
- data/test/defs/test_defs_mt_en.rb +41 -0
- data/test/defs/test_defs_mt_mt.rb +41 -0
- data/test/defs/test_defs_mx.rb +49 -0
- data/test/defs/test_defs_my.rb +23 -0
- data/test/defs/test_defs_nerc.rb +29 -0
- data/test/defs/test_defs_ng.rb +29 -0
- data/test/defs/test_defs_nl.rb +33 -0
- data/test/defs/test_defs_no.rb +43 -0
- data/test/defs/test_defs_northamerica.rb +667 -0
- data/test/defs/test_defs_nyse.rb +46 -0
- data/test/defs/test_defs_nz.rb +67 -0
- data/test/defs/test_defs_pe.rb +47 -0
- data/test/defs/test_defs_ph.rb +29 -0
- data/test/defs/test_defs_pl.rb +229 -0
- data/test/defs/test_defs_pt.rb +47 -0
- data/test/defs/test_defs_ro.rb +65 -0
- data/test/defs/test_defs_rs_cyrl.rb +46 -0
- data/test/defs/test_defs_rs_la.rb +46 -0
- data/test/defs/test_defs_ru.rb +34 -0
- data/test/defs/test_defs_scandinavia.rb +215 -0
- data/test/defs/test_defs_se.rb +59 -0
- data/test/defs/test_defs_sg.rb +25 -0
- data/test/defs/test_defs_si.rb +105 -0
- data/test/defs/test_defs_sk.rb +41 -0
- data/test/defs/test_defs_southamerica.rb +327 -0
- data/test/defs/test_defs_th.rb +33 -0
- data/test/defs/test_defs_tn.rb +27 -0
- data/test/defs/test_defs_tr.rb +60 -0
- data/test/defs/test_defs_ua.rb +41 -0
- data/test/defs/test_defs_unitednations.rb +11 -0
- data/test/defs/test_defs_ups.rb +31 -0
- data/test/defs/test_defs_us.rb +387 -0
- data/test/defs/test_defs_ve.rb +35 -0
- data/test/defs/test_defs_vi.rb +22 -0
- data/test/defs/test_defs_za.rb +35 -0
- data/test/holidays/core_extensions/test_date.rb +122 -0
- data/test/holidays/core_extensions/test_date_time.rb +60 -0
- data/test/holidays/date_calculator/test_day_of_month.rb +27 -0
- data/test/holidays/date_calculator/test_easter_gregorian.rb +30 -0
- data/test/holidays/date_calculator/test_easter_julian.rb +36 -0
- data/test/holidays/date_calculator/test_lunar_date.rb +89 -0
- data/test/holidays/date_calculator/test_weekend_modifier.rb +54 -0
- data/test/holidays/definition/context/test_function_processor.rb +199 -0
- data/test/holidays/definition/context/test_generator.rb +226 -0
- data/test/holidays/definition/context/test_load.rb +37 -0
- data/test/holidays/definition/context/test_merger.rb +25 -0
- data/test/holidays/definition/decorator/test_custom_method_proc.rb +113 -0
- data/test/holidays/definition/decorator/test_custom_method_source.rb +96 -0
- data/test/holidays/definition/decorator/test_test.rb +123 -0
- data/test/holidays/definition/generator/test_module.rb +268 -0
- data/test/holidays/definition/generator/test_regions.rb +97 -0
- data/test/holidays/definition/generator/test_test.rb +113 -0
- data/test/holidays/definition/parser/test_custom_method.rb +79 -0
- data/test/holidays/definition/parser/test_test.rb +142 -0
- data/test/holidays/definition/repository/test_cache.rb +123 -0
- data/test/holidays/definition/repository/test_custom_methods.rb +43 -0
- data/test/holidays/definition/repository/test_holidays_by_month.rb +275 -0
- data/test/holidays/definition/repository/test_proc_result_cache.rb +91 -0
- data/test/holidays/definition/repository/test_regions.rb +104 -0
- data/test/holidays/definition/validator/test_custom_method.rb +94 -0
- data/test/holidays/definition/validator/test_region.rb +54 -0
- data/test/holidays/definition/validator/test_test.rb +60 -0
- data/test/holidays/finder/context/test_between.rb +172 -0
- data/test/holidays/finder/context/test_dates_driver_builder.rb +91 -0
- data/test/holidays/finder/context/test_next_holiday.rb +156 -0
- data/test/holidays/finder/context/test_parse_options.rb +141 -0
- data/test/holidays/finder/context/test_search.rb +232 -0
- data/test/holidays/finder/context/test_year_holiday.rb +202 -0
- data/test/holidays/finder/rules/test_in_region.rb +42 -0
- data/test/holidays/finder/rules/test_year_range.rb +166 -0
- data/test/integration/README.md +9 -0
- data/test/integration/test_all_regions.rb +49 -0
- data/test/integration/test_any_holidays_during_work_week.rb +90 -0
- data/test/integration/test_available_regions.rb +23 -0
- data/test/integration/test_custom_holidays.rb +41 -0
- data/test/integration/test_custom_informal_holidays.rb +15 -0
- data/test/integration/test_custom_year_range_holidays.rb +35 -0
- data/test/integration/test_holidays.rb +243 -0
- data/test/integration/test_holidays_between.rb +87 -0
- data/test/integration/test_multiple_regions.rb +71 -0
- data/test/integration/test_multiple_regions_with_conflict.rb +29 -0
- data/test/integration/test_nonstandard_regions.rb +25 -0
- data/test/test_helper.rb +37 -0
- metadata +649 -0
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
require 'yaml'
|
|
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.
|
|
10
|
+
module Holidays
|
|
11
|
+
module Definition
|
|
12
|
+
module Context
|
|
13
|
+
class Generator
|
|
14
|
+
def initialize(custom_method_parser, custom_method_source_decorator, custom_methods_repository, test_parser, test_source_generator, module_source_generator)
|
|
15
|
+
@custom_method_parser = custom_method_parser
|
|
16
|
+
@custom_method_source_decorator = custom_method_source_decorator
|
|
17
|
+
@custom_methods_repository = custom_methods_repository
|
|
18
|
+
@test_parser = test_parser
|
|
19
|
+
@test_source_generator = test_source_generator
|
|
20
|
+
@module_source_generator = module_source_generator
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def parse_definition_files(files)
|
|
24
|
+
raise ArgumentError, "Must have at least one file to parse" if files.nil? || files.empty?
|
|
25
|
+
|
|
26
|
+
all_regions = []
|
|
27
|
+
all_rules_by_month = {}
|
|
28
|
+
all_custom_methods = {}
|
|
29
|
+
all_tests = []
|
|
30
|
+
|
|
31
|
+
files.flatten!
|
|
32
|
+
|
|
33
|
+
files.each do |file|
|
|
34
|
+
definition_file = YAML.load_file(file)
|
|
35
|
+
|
|
36
|
+
custom_methods = @custom_method_parser.call(definition_file['methods'])
|
|
37
|
+
|
|
38
|
+
regions, rules_by_month = parse_month_definitions(definition_file['months'], custom_methods)
|
|
39
|
+
|
|
40
|
+
all_regions << regions.flatten
|
|
41
|
+
|
|
42
|
+
all_rules_by_month.merge!(rules_by_month) { |month, existing, new|
|
|
43
|
+
existing << new
|
|
44
|
+
existing.flatten!
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
#FIXME This is a problem. We will have a 'global' list of methods. That's always bad. What effects will this have?
|
|
48
|
+
# This is an existing problem (just so we are clear). An issue would be extremely rare because we are generally parsing
|
|
49
|
+
# single files/custom files. But it IS possible that we would parse a bunch of things at the same time and step
|
|
50
|
+
# on each other so we need a solution.
|
|
51
|
+
all_custom_methods.merge!(custom_methods)
|
|
52
|
+
|
|
53
|
+
all_tests += @test_parser.call(definition_file['tests'])
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
all_regions.flatten!.uniq!
|
|
57
|
+
|
|
58
|
+
[all_regions, all_rules_by_month, all_custom_methods, all_tests]
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def generate_definition_source(module_name, files, regions, rules_by_month, custom_methods, tests)
|
|
62
|
+
month_strings = generate_month_definition_strings(rules_by_month, custom_methods)
|
|
63
|
+
|
|
64
|
+
# Build the custom methods string
|
|
65
|
+
custom_method_string = ''
|
|
66
|
+
custom_methods.each do |key, code|
|
|
67
|
+
custom_method_string << @custom_method_source_decorator.call(code) + ",\n\n"
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
module_src = @module_source_generator.call(module_name, files, regions, month_strings, custom_method_string)
|
|
71
|
+
test_src = @test_source_generator.call(module_name, files, tests)
|
|
72
|
+
|
|
73
|
+
return module_src, test_src || ''
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
private
|
|
77
|
+
|
|
78
|
+
#FIXME This should be a 'month_definitions_parser' like the above parser
|
|
79
|
+
def parse_month_definitions(month_definitions, parsed_custom_methods)
|
|
80
|
+
regions = []
|
|
81
|
+
rules_by_month = {}
|
|
82
|
+
|
|
83
|
+
if month_definitions
|
|
84
|
+
month_definitions.each do |month, definitions|
|
|
85
|
+
rules_by_month[month] = [] unless rules_by_month[month]
|
|
86
|
+
definitions.each do |definition|
|
|
87
|
+
rule = {}
|
|
88
|
+
|
|
89
|
+
definition.each do |key, val|
|
|
90
|
+
# Ruby 2.4 doesn't have the `transform_keys` method. Once we drop 2.4 support we can
|
|
91
|
+
# use `val.transform_keys!(&:to_sym) if val.is_a?(Hash)` instead of this `if` statement.
|
|
92
|
+
if val.is_a?(Hash)
|
|
93
|
+
val = val.keys.each_with_object({}) do |k, result|
|
|
94
|
+
result[k.to_sym] = val[k]
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
rule[key.to_sym] = val
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
if rule[:year_ranges] && rule[:year_ranges].key?(:between)
|
|
102
|
+
start_year = rule[:year_ranges][:between]["start"].to_i
|
|
103
|
+
end_year = rule[:year_ranges][:between]["end"].to_i
|
|
104
|
+
|
|
105
|
+
rule[:year_ranges][:between] = Range.new(start_year, end_year)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
rule[:regions] = rule[:regions].collect { |r| r.to_sym }
|
|
109
|
+
regions << rule[:regions]
|
|
110
|
+
|
|
111
|
+
exists = false
|
|
112
|
+
rules_by_month[month].each do |ex|
|
|
113
|
+
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]
|
|
114
|
+
ex[:regions] << rule[:regions].flatten
|
|
115
|
+
exists = true
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
unless exists
|
|
120
|
+
# This will add in the custom method arguments so they are immediately
|
|
121
|
+
# available for 'on the fly' def loading.
|
|
122
|
+
if rule[:function]
|
|
123
|
+
rule[:function_arguments] = get_function_arguments(rule[:function], parsed_custom_methods)
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
rules_by_month[month] << rule
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
[regions, rules_by_month]
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
#FIXME This should really be split out and tested with its own unit tests.
|
|
136
|
+
def generate_month_definition_strings(rules_by_month, parsed_custom_methods)
|
|
137
|
+
month_strings = []
|
|
138
|
+
|
|
139
|
+
rules_by_month.each do |month, rules|
|
|
140
|
+
month_string = " #{month.to_s} => ["
|
|
141
|
+
rule_strings = []
|
|
142
|
+
rules.each do |rule|
|
|
143
|
+
string = '{'
|
|
144
|
+
if rule[:mday]
|
|
145
|
+
string << ":mday => #{rule[:mday]}, "
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
if rule[:function]
|
|
149
|
+
string << ":function => \"#{rule[:function].to_s}\", "
|
|
150
|
+
|
|
151
|
+
# We need to add in the arguments so we can know what to send in when calling the custom proc during holiday lookups.
|
|
152
|
+
# NOTE: the allowed arguments are enforced in the custom methods parser.
|
|
153
|
+
string << ":function_arguments => #{get_function_arguments(rule[:function], parsed_custom_methods)}, "
|
|
154
|
+
|
|
155
|
+
if rule[:function_modifier]
|
|
156
|
+
string << ":function_modifier => #{rule[:function_modifier].to_s}, "
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
# This is the 'else'. It is possible for mday AND function
|
|
161
|
+
# to be set but this is the fallback. This whole area
|
|
162
|
+
# needs to be reworked!
|
|
163
|
+
if string == '{'
|
|
164
|
+
string << ":wday => #{rule[:wday]}, :week => #{rule[:week]}, "
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
if rule[:year_ranges] && rule[:year_ranges].is_a?(Hash)
|
|
168
|
+
selector = rule[:year_ranges].keys.first
|
|
169
|
+
value = rule[:year_ranges][selector]
|
|
170
|
+
|
|
171
|
+
string << ":year_ranges => { :#{selector} => #{value} },"
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
if rule[:observed]
|
|
175
|
+
string << ":observed => \"#{rule[:observed].to_s}\", "
|
|
176
|
+
string << ":observed_arguments => #{get_function_arguments(rule[:observed], parsed_custom_methods)}, "
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
if rule[:type]
|
|
180
|
+
string << ":type => :#{rule[:type]}, "
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
# shouldn't allow the same region twice
|
|
184
|
+
string << ":name => \"#{rule[:name]}\", :regions => [:" + rule[:regions].uniq.join(', :') + "]}"
|
|
185
|
+
rule_strings << string
|
|
186
|
+
end
|
|
187
|
+
month_string << rule_strings.join(",\n ") + "]"
|
|
188
|
+
month_strings << month_string
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
return month_strings
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
# This method sucks. The issue here is that the custom methods repo has the 'general' methods (like easter)
|
|
195
|
+
# but the 'parsed_custom_methods' have the recently parsed stuff. We don't load those until they are needed later.
|
|
196
|
+
# This entire file is a refactor target so I am adding some tech debt to get me over the hump.
|
|
197
|
+
# What we should do is ensure that all custom methods are loaded into the repo as soon as they are parsed
|
|
198
|
+
# so we only have one place to look.
|
|
199
|
+
def get_function_arguments(function_id, parsed_custom_methods)
|
|
200
|
+
if method = @custom_methods_repository.find(function_id)
|
|
201
|
+
method.parameters.collect { |arg| arg[1] }
|
|
202
|
+
elsif method = parsed_custom_methods[function_id]
|
|
203
|
+
method.arguments.collect { |arg| arg.to_sym }
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module Holidays
|
|
2
|
+
module Definition
|
|
3
|
+
module Context
|
|
4
|
+
class Load
|
|
5
|
+
def initialize(definition_merger, full_definitions_path)
|
|
6
|
+
@definition_merger = definition_merger
|
|
7
|
+
@full_definitions_path = full_definitions_path
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def call(region)
|
|
11
|
+
region_definition_file = "#{@full_definitions_path}/#{region}"
|
|
12
|
+
require region_definition_file
|
|
13
|
+
|
|
14
|
+
target_region_module = Module.const_get("Holidays").const_get(region.upcase)
|
|
15
|
+
|
|
16
|
+
@definition_merger.call(
|
|
17
|
+
region,
|
|
18
|
+
target_region_module.holidays_by_month,
|
|
19
|
+
target_region_module.custom_methods,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
target_region_module.defined_regions
|
|
23
|
+
rescue NameError, LoadError => e
|
|
24
|
+
raise UnknownRegionError.new(e), "Could not load region prefix: #{region.to_s}"
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module Holidays
|
|
2
|
+
module Definition
|
|
3
|
+
module Context
|
|
4
|
+
# Merge a new set of definitions into the Holidays module.
|
|
5
|
+
class Merger
|
|
6
|
+
def initialize(holidays_by_month_repo, regions_repo, custom_methods_repo)
|
|
7
|
+
@holidays_repo = holidays_by_month_repo
|
|
8
|
+
@regions_repo = regions_repo
|
|
9
|
+
@custom_methods_repo = custom_methods_repo
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def call(target_regions, target_holidays, target_custom_methods)
|
|
13
|
+
#FIXME Does this need to come in this exact order? God I hope not.
|
|
14
|
+
# If not then we should swap the order so it matches the init.
|
|
15
|
+
@regions_repo.add(target_regions)
|
|
16
|
+
@holidays_repo.add(target_holidays)
|
|
17
|
+
@custom_methods_repo.add(target_custom_methods)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module Holidays
|
|
2
|
+
module Definition
|
|
3
|
+
module Decorator
|
|
4
|
+
class CustomMethodProc
|
|
5
|
+
def call(proc)
|
|
6
|
+
validate!(proc)
|
|
7
|
+
|
|
8
|
+
eval("Proc.new { |#{parse_arguments(proc.arguments)}|
|
|
9
|
+
#{proc.source}
|
|
10
|
+
}")
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
private
|
|
14
|
+
|
|
15
|
+
def validate!(proc)
|
|
16
|
+
raise ArgumentError if proc.name.nil? || proc.name.empty?
|
|
17
|
+
raise ArgumentError if proc.arguments.nil? || proc.arguments.empty?
|
|
18
|
+
raise ArgumentError if proc.source.nil? || proc.source.empty?
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def parse_arguments(args)
|
|
22
|
+
a = args.join(", ")
|
|
23
|
+
a[0..-1]
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module Holidays
|
|
2
|
+
module Definition
|
|
3
|
+
module Decorator
|
|
4
|
+
class CustomMethodSource
|
|
5
|
+
def call(proc)
|
|
6
|
+
validate!(proc)
|
|
7
|
+
|
|
8
|
+
method_name = proc.name
|
|
9
|
+
args = args_string(proc.arguments)
|
|
10
|
+
source = proc.source
|
|
11
|
+
|
|
12
|
+
"\"#{method_name.to_s}(#{args})\" => Proc.new { |#{args}|\n#{source}}"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
private
|
|
16
|
+
|
|
17
|
+
def validate!(proc)
|
|
18
|
+
raise ArgumentError if proc.name.nil? || proc.name == ""
|
|
19
|
+
raise ArgumentError if proc.arguments.nil? || !proc.arguments.is_a?(Array) || proc.arguments.empty?
|
|
20
|
+
raise ArgumentError if proc.source.nil? || proc.source == ""
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def args_string(args)
|
|
24
|
+
a = args.join(", ")
|
|
25
|
+
a[0..-1]
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
module Holidays
|
|
2
|
+
module Definition
|
|
3
|
+
module Decorator
|
|
4
|
+
class Test
|
|
5
|
+
def call(t)
|
|
6
|
+
src = ""
|
|
7
|
+
|
|
8
|
+
t.dates.each do |d|
|
|
9
|
+
date = "Date.civil(#{d.year}, #{d.month}, #{d.day})"
|
|
10
|
+
|
|
11
|
+
holiday_call = "Holidays.on(#{date}, #{t.regions}"
|
|
12
|
+
|
|
13
|
+
if t.options
|
|
14
|
+
holiday_call += ", #{decorate_options(t.options)}"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
if t.holiday?
|
|
18
|
+
src += "assert_equal \"#{t.name}\", (#{holiday_call})[0] || {})[:name]\n"
|
|
19
|
+
else
|
|
20
|
+
src += "assert_nil (#{holiday_call})[0] || {})[:name]\n"
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
src
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
def decorate_options(options)
|
|
30
|
+
options.map do |o|
|
|
31
|
+
o.to_sym
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
require 'holidays/errors'
|
|
2
|
+
|
|
3
|
+
module Holidays
|
|
4
|
+
module Definition
|
|
5
|
+
module Generator
|
|
6
|
+
class Module
|
|
7
|
+
def call(module_name, files, regions, month_strings, custom_methods)
|
|
8
|
+
raise ArgumentError.new("module name cannot be nil") if module_name.nil?
|
|
9
|
+
raise ArgumentError.new("module name cannot be blank") if module_name.empty?
|
|
10
|
+
|
|
11
|
+
raise ArgumentError.new("files cannot be nil") if files.nil?
|
|
12
|
+
raise ArgumentError.new("files cannot be empty") if files.empty?
|
|
13
|
+
raise ArgumentError.new("files must all be strings") unless files.all? { |f| f.is_a?(String) }
|
|
14
|
+
|
|
15
|
+
raise ArgumentError.new("regions cannot be nil") if regions.nil?
|
|
16
|
+
raise ArgumentError.new("regions cannot be empty") if regions.empty?
|
|
17
|
+
|
|
18
|
+
raise ArgumentError.new("month strings cannot be nil") if month_strings.nil?
|
|
19
|
+
raise ArgumentError.new("month strings cannot be empty") if month_strings.empty?
|
|
20
|
+
|
|
21
|
+
module_src =<<-EOM
|
|
22
|
+
# encoding: utf-8
|
|
23
|
+
module Holidays
|
|
24
|
+
# This file is generated by the Ruby Holidays gem.
|
|
25
|
+
#
|
|
26
|
+
# Definitions loaded: #{files.join(', ')}
|
|
27
|
+
#
|
|
28
|
+
# All the definitions are available at https://github.com/holidays/holidays
|
|
29
|
+
module #{module_name.to_s.upcase} # :nodoc:
|
|
30
|
+
def self.defined_regions
|
|
31
|
+
[:#{regions.join(', :')}]
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.holidays_by_month
|
|
35
|
+
{
|
|
36
|
+
#{month_strings.join(",\n")}
|
|
37
|
+
}
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def self.custom_methods
|
|
41
|
+
{
|
|
42
|
+
#{custom_methods}
|
|
43
|
+
}
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
EOM
|
|
48
|
+
|
|
49
|
+
module_src
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
module Holidays
|
|
2
|
+
module Definition
|
|
3
|
+
module Generator
|
|
4
|
+
class Regions
|
|
5
|
+
# The "ca", "mx", and "us" holiday definitions include the "northamericainformal"
|
|
6
|
+
# holiday definitions, but that does not make these countries subregions of one another.
|
|
7
|
+
NORTH_AMERICA_REGIONS = %i[ca mx us].freeze
|
|
8
|
+
|
|
9
|
+
def call(regions)
|
|
10
|
+
validate!(regions)
|
|
11
|
+
|
|
12
|
+
<<-EOF
|
|
13
|
+
# encoding: utf-8
|
|
14
|
+
module Holidays
|
|
15
|
+
REGIONS = #{to_array(regions)}
|
|
16
|
+
|
|
17
|
+
PARENT_REGION_LOOKUP = #{generate_parent_lookup(regions)}
|
|
18
|
+
end
|
|
19
|
+
EOF
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def validate!(regions)
|
|
25
|
+
raise ArgumentError.new("regions cannot be missing") if regions.nil?
|
|
26
|
+
raise ArgumentError.new("regions must be a hash") unless regions.is_a?(Hash)
|
|
27
|
+
raise ArgumentError.new("regions cannot be empty") if regions.empty?
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def to_array(regions)
|
|
31
|
+
all_regions = []
|
|
32
|
+
|
|
33
|
+
regions.each do |region, subregions|
|
|
34
|
+
all_regions << subregions
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
all_regions.flatten.uniq
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def generate_parent_lookup(regions)
|
|
41
|
+
lookup = {}
|
|
42
|
+
|
|
43
|
+
regions.each do |region, subregions|
|
|
44
|
+
subregions.each do |subregion|
|
|
45
|
+
parent_region = NORTH_AMERICA_REGIONS.include?(subregion) ? subregion : region
|
|
46
|
+
lookup[subregion] = parent_region unless lookup.has_key?(subregion)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
lookup
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
require 'holidays/errors'
|
|
2
|
+
|
|
3
|
+
module Holidays
|
|
4
|
+
module Definition
|
|
5
|
+
module Generator
|
|
6
|
+
class Test
|
|
7
|
+
def initialize(decorator)
|
|
8
|
+
@decorator = decorator
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def call(module_name, file_names, tests)
|
|
12
|
+
validate!(module_name, file_names, tests)
|
|
13
|
+
|
|
14
|
+
test_src =<<-EndOfTests
|
|
15
|
+
# encoding: utf-8
|
|
16
|
+
require File.expand_path(File.dirname(__FILE__)) + '/../test_helper'
|
|
17
|
+
|
|
18
|
+
# This file is generated by the Ruby Holiday gem.
|
|
19
|
+
#
|
|
20
|
+
# Definitions loaded: #{file_names.join(', ')}
|
|
21
|
+
class #{module_name.to_s.capitalize}DefinitionTests < Test::Unit::TestCase # :nodoc:
|
|
22
|
+
|
|
23
|
+
def test_#{module_name.to_s.downcase}#{decorate(tests)}
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
EndOfTests
|
|
27
|
+
|
|
28
|
+
test_src
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def validate!(module_name, file_names, tests)
|
|
34
|
+
raise ArgumentError.new("module_name cannot be missing") if module_name.nil? || module_name.empty?
|
|
35
|
+
raise ArgumentError.new("file_names for '#{module_name}' cannot be missing") if file_names.nil? || file_names.empty?
|
|
36
|
+
raise ArgumentError.new("tests for '#{module_name}' cannot be missing") if tests.nil?
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def decorate(tests)
|
|
40
|
+
out = ""
|
|
41
|
+
|
|
42
|
+
tests.each do |t|
|
|
43
|
+
out << "\n " + @decorator.call(t)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
out
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
require 'holidays/definition/entity/custom_method'
|
|
2
|
+
|
|
3
|
+
module Holidays
|
|
4
|
+
module Definition
|
|
5
|
+
module Parser
|
|
6
|
+
class CustomMethod
|
|
7
|
+
def initialize(validator)
|
|
8
|
+
@validator = validator
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def call(methods)
|
|
12
|
+
return {} if methods.nil? || methods.empty?
|
|
13
|
+
|
|
14
|
+
validate!(methods)
|
|
15
|
+
|
|
16
|
+
custom_methods = {}
|
|
17
|
+
|
|
18
|
+
methods.each do |name, pieces|
|
|
19
|
+
arguments = parse_arguments!(pieces["arguments"])
|
|
20
|
+
|
|
21
|
+
custom_methods[method_key(name, arguments)] = Entity::CustomMethod.new({
|
|
22
|
+
name: name,
|
|
23
|
+
arguments: arguments,
|
|
24
|
+
source: pieces["ruby"],
|
|
25
|
+
})
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
custom_methods
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def validate!(methods)
|
|
34
|
+
raise ArgumentError unless methods.all? do |name, pieces|
|
|
35
|
+
@validator.valid?(
|
|
36
|
+
{
|
|
37
|
+
:name => name,
|
|
38
|
+
:arguments => pieces["arguments"],
|
|
39
|
+
:source => pieces["ruby"]
|
|
40
|
+
}
|
|
41
|
+
)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def parse_arguments!(arguments)
|
|
46
|
+
splitArgs = arguments.split(",")
|
|
47
|
+
parsedArgs = []
|
|
48
|
+
|
|
49
|
+
splitArgs.each do |arg|
|
|
50
|
+
parsedArgs << arg.strip
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
parsedArgs
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def method_key(name, args)
|
|
57
|
+
"#{name.to_s}(#{args_string(args)})"
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def args_string(args)
|
|
61
|
+
a = args.join(", ")
|
|
62
|
+
a[0..-1]
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|