anodator 1.0.0.pre1 → 1.0.0.pre2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. checksums.yaml +5 -5
  2. data/.codeclimate.yml +3 -0
  3. data/.gitignore +3 -0
  4. data/.travis.yml +11 -0
  5. data/Gemfile +2 -2
  6. data/README.md +9 -4
  7. data/Rakefile +3 -3
  8. data/anodator.gemspec +17 -14
  9. data/bin/console +3 -3
  10. data/bin/console-on-docker +4 -0
  11. data/bin/docker-console +2 -0
  12. data/bin/docker-prompt +2 -0
  13. data/bin/prompt-on-docker +4 -0
  14. data/bin/setup +0 -0
  15. data/example/example_01.rb +88 -61
  16. data/lib/anodator.rb +3 -2
  17. data/lib/anodator/anodator_error.rb +1 -1
  18. data/lib/anodator/check_result.rb +7 -7
  19. data/lib/anodator/checker.rb +33 -26
  20. data/lib/anodator/common.rb +15 -0
  21. data/lib/anodator/data_source.rb +87 -0
  22. data/lib/anodator/data_source_set.rb +36 -0
  23. data/lib/anodator/input_spec.rb +105 -111
  24. data/lib/anodator/input_spec_item.rb +8 -8
  25. data/lib/anodator/message.rb +14 -14
  26. data/lib/anodator/output_spec.rb +40 -43
  27. data/lib/anodator/rule.rb +26 -32
  28. data/lib/anodator/rule_set.rb +6 -12
  29. data/lib/anodator/utils.rb +36 -42
  30. data/lib/anodator/validator.rb +9 -9
  31. data/lib/anodator/validator/base.rb +44 -27
  32. data/lib/anodator/validator/blank_validator.rb +2 -2
  33. data/lib/anodator/validator/complex_validator.rb +12 -12
  34. data/lib/anodator/validator/configuration_error.rb +1 -2
  35. data/lib/anodator/validator/date_validator.rb +93 -103
  36. data/lib/anodator/validator/format_validator.rb +8 -11
  37. data/lib/anodator/validator/inclusion_validator.rb +3 -3
  38. data/lib/anodator/validator/length_validator.rb +6 -6
  39. data/lib/anodator/validator/numeric_validator.rb +13 -13
  40. data/lib/anodator/validator/presence_validator.rb +2 -2
  41. data/lib/anodator/validator/value_proxy.rb +31 -9
  42. data/lib/anodator/version.rb +1 -1
  43. metadata +41 -6
  44. data/VERSION +0 -1
@@ -1,10 +1,10 @@
1
1
  # load validators
2
- require "anodator/validator/base"
3
- require "anodator/validator/blank_validator"
4
- require "anodator/validator/complex_validator"
5
- require "anodator/validator/format_validator"
6
- require "anodator/validator/inclusion_validator"
7
- require "anodator/validator/length_validator"
8
- require "anodator/validator/numeric_validator"
9
- require "anodator/validator/presence_validator"
10
- require "anodator/validator/date_validator"
2
+ require 'anodator/validator/base'
3
+ require 'anodator/validator/blank_validator'
4
+ require 'anodator/validator/complex_validator'
5
+ require 'anodator/validator/format_validator'
6
+ require 'anodator/validator/inclusion_validator'
7
+ require 'anodator/validator/length_validator'
8
+ require 'anodator/validator/numeric_validator'
9
+ require 'anodator/validator/presence_validator'
10
+ require 'anodator/validator/date_validator'
@@ -1,4 +1,4 @@
1
- require "anodator/validator/value_proxy"
1
+ require 'anodator/validator/value_proxy'
2
2
 
3
3
  module Anodator
4
4
  module Validator
@@ -7,16 +7,19 @@ module Anodator
7
7
  # value of target for validation
8
8
  @@values = nil
9
9
 
10
+ # data source set
11
+ @@data_source_set = nil
12
+
10
13
  # valid option keys
11
14
  #
12
15
  # :allow_blank options are all available options in Validator.
13
16
  # In addition, Validator All you need to consider the case of the blank.
14
- @valid_option_keys = [:allow_blank, :description]
17
+ @valid_option_keys = %i[allow_blank description]
15
18
 
16
19
  # default options
17
20
  #
18
21
  # Is used as the initial value was not set when you create a new Validator.
19
- @default_options = { :allow_blank => false }
22
+ @default_options = { allow_blank: false }
20
23
 
21
24
  # target specify value
22
25
  attr_reader :target
@@ -32,43 +35,41 @@ module Anodator
32
35
  def valid_option_keys(*option_keys)
33
36
  # initialize from superclass
34
37
  if @valid_option_keys.nil?
35
- @valid_option_keys = self.superclass.valid_option_keys
38
+ @valid_option_keys = superclass.valid_option_keys
36
39
  end
37
40
 
38
41
  unless option_keys.size.zero?
39
42
  option_keys.each do |key|
40
43
  if @valid_option_keys.include?(key)
41
- raise ArgumentError.new("Validator already has option for '#{key}'")
44
+ raise ArgumentError, "Validator already has option for '#{key}'"
42
45
  else
43
46
  @valid_option_keys << key
44
47
  end
45
48
  end
46
49
  end
47
50
 
48
- return @valid_option_keys.dup
51
+ @valid_option_keys.dup
49
52
  end
50
53
 
51
54
  # set and/or get default options
52
55
  def default_options(options = nil)
53
56
  # initialize from superclass
54
- if @default_options.nil?
55
- @default_options = self.superclass.default_options
56
- end
57
+ @default_options = superclass.default_options if @default_options.nil?
57
58
 
58
59
  unless options.nil?
59
60
  unless options.is_a? Hash
60
- raise ArgumentError.new("default_options must call with Hash")
61
+ raise ArgumentError, 'default_options must call with Hash'
61
62
  end
62
63
  options.each do |option, default_value|
63
64
  if @valid_option_keys.include?(option)
64
65
  @default_options[option] = default_value
65
66
  else
66
- raise ArgumentError.new("Unknown option '#{option}'")
67
+ raise ArgumentError, "Unknown option '#{option}'"
67
68
  end
68
69
  end
69
70
  end
70
71
 
71
- return @default_options.dup
72
+ @default_options.dup
72
73
  end
73
74
 
74
75
  # Set the data to be checked.
@@ -78,13 +79,25 @@ module Anodator
78
79
  if values.respond_to?(:[])
79
80
  @@values = values
80
81
  else
81
- raise ArgumentError.new("values must be respond to [] method for validations.")
82
+ raise ArgumentError, 'values must be respond to [] method for validations.'
82
83
  end
83
84
  end
84
85
 
85
86
  # Get the data to be checked
86
87
  def values
87
- return @@values
88
+ @@values
89
+ end
90
+
91
+ # Set the data source with check.
92
+ def data_source_set=(data_source_set)
93
+ msg = 'data_source_set must be Anodator::DataSourceSet'
94
+ raise ArgumentError, msg unless data_source_set.is_a? DataSourceSet
95
+
96
+ @@data_source_set = data_source_set
97
+ end
98
+
99
+ def data_source_set
100
+ @@data_source_set
88
101
  end
89
102
  end
90
103
 
@@ -97,13 +110,13 @@ module Anodator
97
110
  # +valid_option_keys+.
98
111
  # If necessary add additional parameters for the new validator is defined
99
112
  # in the inherited class to add.
100
- def initialize(target_expression, options = { })
113
+ def initialize(target_expression, options = {})
101
114
  if target_expression.to_s.length.zero?
102
- raise ArgumentError.new("target cannot be nil or blank")
115
+ raise ArgumentError, 'target cannot be nil or blank'
103
116
  else
104
117
  @target = target_expression.to_s
105
118
  end
106
- @options = { }
119
+ @options = {}
107
120
  merge_options!(self.class.default_options)
108
121
  merge_options!(options)
109
122
  end
@@ -115,7 +128,7 @@ module Anodator
115
128
  # Can be implemented to return a boolean value to the final,
116
129
  # +valid?+ The method used is called.
117
130
  def validate
118
- raise NoMethodError.new("must define method 'validate'")
131
+ raise NoMethodError, "must define method 'validate'"
119
132
  end
120
133
 
121
134
  # Call the +validate+ method to return a boolean value accordingly
@@ -123,7 +136,7 @@ module Anodator
123
136
  # If any exception occurs in the +validate+ method displays the contents
124
137
  # to standard error. Then raise same error.
125
138
  def valid?
126
- return validate
139
+ validate
127
140
  end
128
141
 
129
142
  # merge options
@@ -134,7 +147,7 @@ module Anodator
134
147
  if self.class.valid_option_keys.include?(key)
135
148
  @options[key] = value
136
149
  else
137
- raise ArgumentError.new("Unknown option key '#{key}'.")
150
+ raise ArgumentError, "Unknown option key '#{key}'."
138
151
  end
139
152
  end
140
153
  end
@@ -145,19 +158,23 @@ module Anodator
145
158
  #
146
159
  # always return String object use to_s method
147
160
  def target_value
148
- return @@values[target].to_s
161
+ @@values[target].to_s
149
162
  end
150
163
 
151
164
  def argument_value_at(name_or_index)
152
- return @@values[name_or_index].to_s
165
+ @@values[name_or_index].to_s
166
+ end
167
+
168
+ def data_source_at(identifier, key, column)
169
+ @@data_source_set.fetch(identifier, key, column)
153
170
  end
154
171
 
155
172
  def allow_blank?
156
- return @options[:allow_blank]
173
+ @options[:allow_blank]
157
174
  end
158
175
 
159
176
  def description
160
- return @options[:description]
177
+ @options[:description]
161
178
  end
162
179
 
163
180
  def proxy_value(target)
@@ -165,14 +182,14 @@ module Anodator
165
182
  end
166
183
  private :proxy_value
167
184
 
168
- def to_s(level = 4, step = 2)
169
- (" " * level) + "- #{self.class}(#{self.description})"
185
+ def to_s(level = 4, _step = 2)
186
+ (' ' * level) + "- #{self.class}(#{description})"
170
187
  end
171
188
 
172
189
  def validate_configuration
173
190
  @@values.spec_item_by_expression(@target)
174
191
  rescue UnknownTargetExpressionError => e
175
- raise InvalidConfiguration.new(e.to_s)
192
+ raise InvalidConfiguration, e.to_s
176
193
  end
177
194
  end
178
195
  end
@@ -1,4 +1,4 @@
1
- require "anodator/validator/base"
1
+ require 'anodator/validator/base'
2
2
 
3
3
  module Anodator
4
4
  module Validator
@@ -7,7 +7,7 @@ module Anodator
7
7
  # This is the Validator to validate whether the value is not present.
8
8
  class BlankValidator < Base
9
9
  def validate
10
- return target_value.split(//).size.zero?
10
+ target_value.split(//).size.zero?
11
11
  end
12
12
  end
13
13
  end
@@ -1,4 +1,4 @@
1
- require "anodator/validator/configuration_error"
1
+ require 'anodator/validator/configuration_error'
2
2
 
3
3
  module Anodator
4
4
  module Validator
@@ -6,20 +6,20 @@ module Anodator
6
6
  # Validators.
7
7
  class ComplexValidator < Base
8
8
  # Combine logical OR of each Validators
9
- LOGIC_OR = "OR"
9
+ LOGIC_OR = 'OR'.freeze
10
10
  # Combine logical AND of each Validators
11
- LOGIC_AND = "AND"
11
+ LOGIC_AND = 'AND'.freeze
12
12
 
13
13
  valid_option_keys :validators, :logic
14
- default_options :logic => LOGIC_AND
14
+ default_options logic: LOGIC_AND
15
15
 
16
- def initialize(options = { })
17
- super("dummy", options)
16
+ def initialize(options = {})
17
+ super('dummy', options)
18
18
  end
19
19
 
20
20
  def validate
21
21
  if @options[:validators].nil?
22
- raise ConfigurationError.new("ComplexValidator must have validators option")
22
+ raise ConfigurationError, 'ComplexValidator must have validators option'
23
23
  end
24
24
  case @options[:logic]
25
25
  when LOGIC_OR
@@ -33,15 +33,15 @@ module Anodator
33
33
  end
34
34
  return true
35
35
  else
36
- raise ConfigurationError.new("Unknown logic option '#{@options[:logic]}")
36
+ raise ConfigurationError, "Unknown logic option '#{@options[:logic]}"
37
37
  end
38
38
  end
39
39
 
40
40
  def logic_expression
41
41
  if @options[:logic] == LOGIC_OR
42
- return "OR"
42
+ 'OR'
43
43
  elsif @options[:logic] == LOGIC_AND
44
- return "AND"
44
+ 'AND'
45
45
  end
46
46
  end
47
47
 
@@ -51,9 +51,9 @@ module Anodator
51
51
 
52
52
  def to_s(level = 2, step = 2)
53
53
  buf = "#{super(level, step)} LOGIC: #{logic_expression}\n"
54
- buf += @options[:validators].map { |validator|
54
+ buf += @options[:validators].map do |validator|
55
55
  validator.to_s(level + step, step)
56
- }.join("\n")
56
+ end.join("\n")
57
57
  end
58
58
  end
59
59
  end
@@ -1,8 +1,7 @@
1
- require "anodator/anodator_error"
1
+ require 'anodator/anodator_error'
2
2
 
3
3
  module Anodator
4
4
  module Validator
5
5
  class ConfigurationError < AnodatorError; end
6
6
  end
7
7
  end
8
-
@@ -1,148 +1,138 @@
1
- require "anodator/validator/base"
2
- require "date"
1
+ require 'anodator/validator/base'
2
+ require 'date'
3
3
 
4
4
  module Anodator
5
5
  module Validator
6
+ # Validator for Date expression.
6
7
  class DateValidator < Base
7
- FORMAT_SCANNER_REGEXP = /((YY(?:YY)?)|(M(?![YMD]))|(MM)|(D(?![YMD]))|(DD))/
8
+ FORMAT_SCANNER_REGEXP =
9
+ /((YY(?:YY)?)|(M(?![YMD]))|(MM)|(D(?![YMD]))|(DD))/
10
+ HOLDER_DEFS = {
11
+ 'YYYY' => :year,
12
+ 'YY' => :short_year,
13
+ 'MM' => :month,
14
+ 'M' => :month,
15
+ 'DD' => :day,
16
+ 'D' => :day
17
+ }.freeze
18
+ HOLDERS = %w[YYYY YY MM M DD D].freeze
19
+ REGEXPS = %w[(\d{4}) (\d{2}) (\d{2}) (\d{1,2}) (\d{2}) (\d{1,2})].freeze
8
20
 
9
21
  valid_option_keys :from, :to, :format, :base_year
10
- default_options :format => "YYYY-MM-DD", :base_year => 2000
22
+ default_options format: 'YYYY-MM-DD', base_year: 2000
11
23
 
12
- def initialize(target_expression, options = { })
24
+ def initialize(target_expression, options = {})
13
25
  super(target_expression, options)
14
26
 
15
- # format check
16
- date_regexp_holders
17
-
18
- [:from, :to].each do |key|
19
- if !@options[key].nil?
20
- @options[key] = proxy_value(@options[key])
21
- if @options[key].direct? && !@options[key].value.is_a?(Date)
22
- date = parse_date(@options[key].value.to_s)
23
- if date.nil?
24
- raise ArgumentError.new("Invalid date expression '#{@options[key].value}'")
25
- else
26
- @options[key] = proxy_value(date)
27
- end
28
- end
29
- end
30
- end
27
+ check_format
28
+ setup_period_options
31
29
  end
32
30
 
33
31
  def validate
34
- if allow_blank?
35
- return true if target_value.split(//).size.zero?
36
- end
32
+ return true if allow_blank? && target_value.split(//).size.zero?
33
+ date = parse_date(target_value)
34
+ return false unless date
37
35
 
36
+ validate_period(date)
37
+ rescue ArgumentError # invalid date expression
38
+ return false
39
+ end
38
40
 
39
- begin
40
- # check format
41
- return false unless date = parse_date(target_value)
42
-
43
- @options.each do |option, configuration|
44
- case option
45
- when :from
46
- return false if parse_date(configuration.value) > date
47
- when :to
48
- return false if parse_date(configuration.value) < date
49
- end
50
- end
41
+ def validate_period(date)
42
+ valid_from = from ? from_date <= date : true
43
+ valid_to = to ? to_date >= date : true
51
44
 
52
- return true
53
- rescue ArgumentError
54
- # invalid date expression
55
- return false
56
- end
45
+ valid_from && valid_to
57
46
  end
58
47
 
59
48
  def from
60
- if @options[:from]
61
- return @options[:from].dup
62
- else
63
- return nil
64
- end
49
+ @options[:from].dup
65
50
  end
66
51
 
67
52
  def to
68
- if @options[:to]
69
- return @options[:to].dup
70
- else
71
- return nil
72
- end
53
+ @options[:to].dup
73
54
  end
74
55
 
75
56
  def format
76
- return @options[:format].dup
57
+ @options[:format].dup
77
58
  end
78
59
 
79
- # parse string with :format option
80
- #
81
- # not matched return nil
82
- def parse_date(date_expression)
83
- return date_expression if date_expression.is_a? Date
84
- return nil unless match_data = date_regexp.match(date_expression)
60
+ def base_year
61
+ @options[:base_year].to_i
62
+ end
63
+
64
+ def from_date
65
+ from ? parse_date(from.value) : nil
66
+ end
85
67
 
86
- index = 0
87
- date_hash = date_regexp_holders.inject({ }) do |hash, key|
88
- index += 1
89
- hash[key] = match_data[index].to_i
68
+ def to_date
69
+ to ? parse_date(to.value) : nil
70
+ end
71
+
72
+ private
90
73
 
91
- next hash
74
+ def setup_period_options
75
+ %i[from to].each do |key|
76
+ setup_date_option(key) if @options.key?(key)
92
77
  end
93
- # for short year
94
- if date_hash.keys.include?(:short_year)
95
- date_hash[:year] = @options[:base_year].to_i + date_hash[:short_year]
78
+ end
79
+
80
+ def setup_date_option(key)
81
+ option = proxy_value(@options[key])
82
+ if option.direct? && !option.value.is_a?(Date)
83
+ date = parse_date(option.value.to_s)
84
+ msg = "Invalid date expression '#{option.value}'"
85
+ raise ArgumentError, msg if date.nil?
86
+
87
+ option = proxy_value(date)
96
88
  end
97
89
 
98
- return Date.new(date_hash[:year], date_hash[:month], date_hash[:day])
90
+ @options[key] = option
99
91
  end
100
- private :parse_date
101
92
 
102
- def date_regexp
103
- date_regexp_holders # check format string
93
+ def parse_date(date_expression)
94
+ return date_expression if date_expression.is_a? Date
95
+ return nil unless date_regexp.match(date_expression)
104
96
 
105
- regexp_string = @options[:format].dup
106
- regexp_string.sub!(/YYYY/, '(\d{4})')
107
- regexp_string.sub!(/YY/, '(\d{2})')
108
- regexp_string.sub!(/MM/, '(\d{2})')
109
- regexp_string.sub!(/M/, '(\d{1,2})')
110
- regexp_string.sub!(/DD/, '(\d{2})')
111
- regexp_string.sub!(/D/, '(\d{1,2})')
97
+ date_hash = date_regexp_holders.each_with_object({})
98
+ .with_index(1) do |(key, hash), i|
99
+ hash[key] = Regexp.last_match[i].to_i
100
+ end
101
+ convert_short_year(date_hash)
102
+ Date.new(date_hash[:year], date_hash[:month], date_hash[:day])
103
+ end
112
104
 
113
- return Regexp.new("^#{regexp_string}$")
105
+ def convert_short_year(hash)
106
+ hash[:year] = base_year + hash[:short_year] if hash.key?(:short_year)
114
107
  end
115
- private :date_regexp
116
108
 
117
- def date_regexp_holders
118
- scans = @options[:format].scan FORMAT_SCANNER_REGEXP
119
- year_count, month_count, day_count = 0, 0, 0
120
- holders = scans.map do |scan|
121
- case scan.first
122
- when "YYYY"
123
- year_count += 1
124
- :year
125
- when "YY"
126
- year_count += 1
127
- :short_year
128
- when "MM", "M"
129
- month_count += 1
130
- :month
131
- when "DD", "D"
132
- day_count += 1
133
- :day
134
- end
109
+ def date_regexp
110
+ regexp_string = HOLDERS.each_with_index.inject(format) do |s, (h, i)|
111
+ s.sub(/#{h}/, REGEXPS[i])
135
112
  end
136
- unless holders.size == 3
137
- raise ArgumentError.new("date format must be contained year(YYYY or YY), month(MM or M) and day(DD or D).")
113
+
114
+ /^#{regexp_string}$/
115
+ end
116
+
117
+ def date_regexp_holders
118
+ format.scan(FORMAT_SCANNER_REGEXP).map do |scan|
119
+ HOLDER_DEFS[scan.first]
138
120
  end
139
- unless year_count == 1 && month_count == 1 && day_count == 1
140
- raise ArgumentError.new("date format must be contained year(YYYY or YY), month(MM or M) and day(DD or D).")
121
+ end
122
+
123
+ def check_format
124
+ msg = 'date format must be contained year(YYYY or YY), ' \
125
+ 'month(MM or M) and day(DD or D).'
126
+ hash = { year: :year, month: :month, day: :day, short_year: :year }
127
+
128
+ checked_holders = date_regexp_holders.inject([]) do |array, holder|
129
+ array << hash[holder]
141
130
  end
142
131
 
143
- return holders
132
+ raise ArgumentError, msg if checked_holders.include?(nil)
133
+ raise ArgumentError, msg unless checked_holders.size == 3
134
+ raise ArgumentError, msg unless checked_holders.uniq!.nil?
144
135
  end
145
- private :date_regexp_holders
146
136
  end
147
137
  end
148
138
  end