anodator 1.0.0.pre1 → 1.0.0.pre2

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