rest_my_case 1.7.0 → 1.7.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4fbc100a76e2fe8ef3a5b546121c072662e41864
4
- data.tar.gz: 335942040cc881c507bf65a3a437f50f1436c3b0
3
+ metadata.gz: 4686d3176a531d96c52e66d6b2b512746a102762
4
+ data.tar.gz: d1c4f92042481db02d456e7ffecc42f40d813557
5
5
  SHA512:
6
- metadata.gz: 2872b4f50c0d422921083b393fda8d3d81010a7e7268985d966bcab5961aa5c398506af5494f2fd6889bcebeb551f2a3ecac4c09e74df57a3d4012914952254c
7
- data.tar.gz: b464f45b1152e7916cc847d0b8c34e3e26a57ee0393b6b33896c831ce950e7f3b3ea4d65abba3e1ead99ee3d5c042bc0e341b0532698c147a87eeb0da8ad87df
6
+ metadata.gz: 308e0eb453f14fa551d35a41a8ea93a95211ef34497be4a101ac05b60a87fff2e5bf90063a5a8af05943c5e286310cad7a1696ca39b84dca5286ae020a696faa
7
+ data.tar.gz: c6eb0b3bc987c0b66e713ddffbdf6b831eec559bd678444d278be3551b5c0a41d9ca7eabaf85350ec0cd0c04fed7271077d3bd00ffa3d44757bda70e39d508d2
data/.rubocop.yml CHANGED
@@ -19,7 +19,6 @@ AllCops:
19
19
  - 'tmp/**/*'
20
20
  - 'pkg/**/*'
21
21
  - 'lib/rest_my_case/accusation_attorneys/**/*'
22
- - 'lib/rest_my_case/validator/errors.rb'
23
22
 
24
23
  Documentation:
25
24
  Enabled: false
@@ -1,5 +1,5 @@
1
1
  module RestMyCase
2
- module Validator
2
+ module AccusationAttorneys
3
3
 
4
4
  class Errors
5
5
  include Enumerable
@@ -0,0 +1,60 @@
1
+ module RestMyCase
2
+ module AccusationAttorneys
3
+
4
+ class Format < Each
5
+ def validate_each(record, attribute, value)
6
+ if options[:with]
7
+ regexp = option_call(record, :with)
8
+ record_error(record, attribute, :with, value) if value.to_s !~ regexp
9
+ elsif options[:without]
10
+ regexp = option_call(record, :without)
11
+ record_error(record, attribute, :without, value) if value.to_s =~ regexp
12
+ end
13
+ end
14
+
15
+ def check_validity!
16
+ unless options.include?(:with) ^ options.include?(:without) # ^ == xor, or "exclusive or"
17
+ raise ArgumentError, "Either :with or :without must be supplied (but not both)"
18
+ end
19
+
20
+ check_options_validity(options, :with)
21
+ check_options_validity(options, :without)
22
+ end
23
+
24
+ private
25
+
26
+ def option_call(record, name)
27
+ option = options[name]
28
+ option.respond_to?(:call) ? option.call(record) : option
29
+ end
30
+
31
+ def record_error(record, attribute, name, value)
32
+ record.errors.add(attribute, :invalid, Helpers.except(options, name).merge!(value: value))
33
+ end
34
+
35
+ def regexp_using_multiline_anchors?(regexp)
36
+ regexp.source.start_with?("^") ||
37
+ (regexp.source.end_with?("$") && !regexp.source.end_with?("\\$"))
38
+ end
39
+
40
+ def check_options_validity(options, name)
41
+ option = options[name]
42
+ if option && !option.is_a?(Regexp) && !option.respond_to?(:call)
43
+ raise ArgumentError, "A regular expression or a proc or lambda must be supplied as :#{name}"
44
+ elsif option && option.is_a?(Regexp) &&
45
+ regexp_using_multiline_anchors?(option) && options[:multiline] != true
46
+ raise ArgumentError, "The provided regular expression is using multiline anchors (^ or $), " \
47
+ "which may present a security risk. Did you mean to use \\A and \\z, or forgot to add the " \
48
+ ":multiline => true option?"
49
+ end
50
+ end
51
+ end
52
+
53
+ module HelperMethods
54
+ def validates_format_of(*attr_names)
55
+ validates_with Format, _merge_attributes(attr_names)
56
+ end
57
+ end
58
+
59
+ end
60
+ end
@@ -0,0 +1,82 @@
1
+ module RestMyCase
2
+ module AccusationAttorneys
3
+
4
+ class Length < Each
5
+ MESSAGES = { is: :wrong_length, minimum: :too_short, maximum: :too_long }.freeze
6
+ CHECKS = { is: :==, minimum: :>=, maximum: :<= }.freeze
7
+
8
+ RESERVED_OPTIONS = [:minimum, :maximum, :within, :is, :tokenizer, :too_short, :too_long]
9
+
10
+ def initialize(options)
11
+ if range = (options.delete(:in) || options.delete(:within))
12
+ raise ArgumentError, ":in and :within must be a Range" unless range.is_a?(Range)
13
+ options[:minimum], options[:maximum] = range.min, range.max
14
+ end
15
+
16
+ if options[:allow_blank] == false && options[:minimum].nil? && options[:is].nil?
17
+ options[:minimum] = 1
18
+ end
19
+
20
+ super
21
+ end
22
+
23
+ def check_validity!
24
+ keys = CHECKS.keys & options.keys
25
+
26
+ if keys.empty?
27
+ raise ArgumentError, 'Range unspecified. Specify the :in, :within, :maximum, :minimum, or :is option.'
28
+ end
29
+
30
+ keys.each do |key|
31
+ value = options[key]
32
+
33
+ unless (value.is_a?(Integer) && value >= 0) || value == Float::INFINITY
34
+ raise ArgumentError, ":#{key} must be a nonnegative Integer or Infinity"
35
+ end
36
+ end
37
+ end
38
+
39
+ def validate_each(record, attribute, value)
40
+ value = tokenize(value)
41
+ value_length = value.respond_to?(:length) ? value.length : value.to_s.length
42
+ errors_options = Helpers.except(options, *RESERVED_OPTIONS)
43
+
44
+ CHECKS.each do |key, validity_check|
45
+ next unless check_value = options[key]
46
+
47
+ if !value.nil? || skip_nil_check?(key)
48
+ next if value_length.send(validity_check, check_value)
49
+ end
50
+
51
+ errors_options[:count] = check_value
52
+
53
+ default_message = options[MESSAGES[key]]
54
+ errors_options[:message] ||= default_message if default_message
55
+
56
+ record.errors.add(attribute, MESSAGES[key], errors_options)
57
+ end
58
+ end
59
+
60
+ private
61
+
62
+ def tokenize(value)
63
+ if options[:tokenizer] && value.kind_of?(String)
64
+ options[:tokenizer].call(value)
65
+ end || value
66
+ end
67
+
68
+ def skip_nil_check?(key)
69
+ key == :maximum && options[:allow_nil].nil? && options[:allow_blank].nil?
70
+ end
71
+ end
72
+
73
+ module HelperMethods
74
+ def validates_length_of(*attr_names)
75
+ validates_with Length, _merge_attributes(attr_names)
76
+ end
77
+
78
+ alias_method :validates_size_of, :validates_length_of
79
+ end
80
+
81
+ end
82
+ end
@@ -0,0 +1,90 @@
1
+ module RestMyCase
2
+ module AccusationAttorneys
3
+
4
+ class Numericality < Each
5
+ CHECKS = { :greater_than => :>, :greater_than_or_equal_to => :>=,
6
+ :equal_to => :==, :less_than => :<, :less_than_or_equal_to => :<=,
7
+ :odd => :odd?, :even => :even? }.freeze
8
+
9
+ RESERVED_OPTIONS = CHECKS.keys + [:only_integer]
10
+
11
+ def check_validity!
12
+ keys = CHECKS.keys - [:odd, :even]
13
+
14
+ Helpers.slice(options, *keys).each do |option, value|
15
+ next if value.nil? || value.is_a?(Numeric) || value.is_a?(Proc) || value.is_a?(Symbol)
16
+ raise ArgumentError, ":#{option} must be a number, a symbol or a proc"
17
+ end
18
+ end
19
+
20
+ def validate_each(record, attr_name, value)
21
+ before_type_cast = "#{attr_name}_before_type_cast"
22
+
23
+ raw_value = record.send(before_type_cast) if record.respond_to?(before_type_cast.to_sym)
24
+ raw_value ||= value
25
+
26
+ return if options[:allow_nil] && raw_value.nil?
27
+
28
+ unless value = parse_raw_value_as_a_number(raw_value)
29
+ record.errors.add(attr_name, :not_a_number, filtered_options(raw_value))
30
+ return
31
+ end
32
+
33
+ if options[:only_integer]
34
+ unless value = parse_raw_value_as_an_integer(raw_value)
35
+ record.errors.add(attr_name, :not_an_integer, filtered_options(raw_value))
36
+ return
37
+ end
38
+ end
39
+
40
+ Helpers.slice(options, *CHECKS.keys).each do |option, option_value|
41
+ next if option_value.nil?
42
+
43
+ case option
44
+ when :odd, :even
45
+ unless value.to_i.send(CHECKS[option])
46
+ record.errors.add(attr_name, option, filtered_options(value))
47
+ end
48
+ else
49
+ option_value = option_value.call(record) if option_value.is_a?(Proc)
50
+ option_value = record.send(option_value) if option_value.is_a?(Symbol)
51
+
52
+ unless value.send(CHECKS[option], option_value)
53
+ record.errors.add(attr_name, option, filtered_options(value).merge(:count => option_value))
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+ protected
60
+
61
+ def parse_raw_value_as_a_number(raw_value)
62
+ case raw_value
63
+ when /\A0[xX]/
64
+ nil
65
+ else
66
+ begin
67
+ Kernel.Float(raw_value)
68
+ rescue ArgumentError, TypeError
69
+ nil
70
+ end
71
+ end
72
+ end
73
+
74
+ def parse_raw_value_as_an_integer(raw_value)
75
+ raw_value.to_i if raw_value.to_s =~ /\A[+-]?\d+\Z/
76
+ end
77
+
78
+ def filtered_options(value)
79
+ Helpers.except(options, *RESERVED_OPTIONS).merge!(:value => value)
80
+ end
81
+ end
82
+
83
+ module HelperMethods
84
+ def validates_numericality_of(*attr_names)
85
+ validates_with Numericality, _merge_attributes(attr_names)
86
+ end
87
+ end
88
+
89
+ end
90
+ end
@@ -3,7 +3,8 @@ module RestMyCase
3
3
 
4
4
  module Base
5
5
 
6
- attr_accessor :silence_dependencies_abort
6
+ attr_accessor :parent_dependencies_first,
7
+ :silence_dependencies_abort
7
8
 
8
9
  end
9
10
 
@@ -6,6 +6,7 @@ module RestMyCase
6
6
  include Base
7
7
 
8
8
  def initialize
9
+ @parent_dependencies_first = false
9
10
  @silence_dependencies_abort = false
10
11
  end
11
12
 
@@ -4,36 +4,35 @@ module RestMyCase
4
4
  class Base
5
5
 
6
6
  def initialize(trial_case)
7
- @trial_case = trial_case
7
+ @trial_case = trial_case
8
+ @trial_case.use_cases = []
8
9
  end
9
10
 
10
11
  def build_case_for_the_defendant
11
- @trial_case.use_cases =
12
- @trial_case.use_case_classes.map do |use_case_class|
13
- all_dependencies(use_case_class)
14
- end.flatten
12
+ dependencies(@trial_case.defendant_class).map do |dependency|
13
+ gather_all_use_cases dependency, @trial_case.defendant
14
+ end
15
15
  end
16
16
 
17
17
  protected ######################## PROTECTED #############################
18
18
 
19
- def all_dependencies(use_case_class)
20
- return [] if use_case_class == @trial_case.last_ancestor
21
-
22
- all_dependencies(use_case_class.superclass) |
23
- dependencies_including_itself(use_case_class, @trial_case.defendant)
24
- end
25
-
26
- private ########################### PRIVATE ##############################
19
+ def gather_all_use_cases(use_case_class, dependent)
20
+ use_case = use_case_class.new(@trial_case.context, dependent)
27
21
 
28
- def dependencies_including_itself(use_case_class, dependent_use_case)
29
- use_case = use_case_class.new(@trial_case.context, dependent_use_case)
22
+ dependencies(use_case_class).map do |dependency|
23
+ gather_all_use_cases dependency, use_case
24
+ end
30
25
 
31
- dependencies(use_case).push use_case
26
+ @trial_case.use_cases.push use_case
32
27
  end
33
28
 
34
- def dependencies(use_case)
35
- use_case.class.dependencies.map do |dependency|
36
- dependencies_including_itself dependency, use_case
29
+ def dependencies(use_case_class)
30
+ return [] if use_case_class == @trial_case.last_ancestor
31
+
32
+ if RestMyCase.get_config :parent_dependencies_first, use_case_class
33
+ dependencies(use_case_class.superclass) | use_case_class.dependencies
34
+ else
35
+ use_case_class.dependencies | dependencies(use_case_class.superclass)
37
36
  end
38
37
  end
39
38
 
@@ -5,13 +5,13 @@ module RestMyCase
5
5
 
6
6
  attr_accessor :use_cases, :should_abort
7
7
 
8
- attr_reader :context, :defendant, :last_ancestor, :use_case_classes
8
+ attr_reader :context, :defendant, :last_ancestor, :defendant_class
9
9
 
10
10
  def initialize(last_ancestor, use_case_classes, attributes)
11
- @context = build_context attributes
12
- @defendant = build_defendant(last_ancestor, use_case_classes)
13
- @last_ancestor = last_ancestor
14
- @use_case_classes = use_case_classes
11
+ @context = build_context attributes
12
+ @last_ancestor = last_ancestor
13
+ @defendant_class = build_defendant(last_ancestor, use_case_classes)
14
+ @defendant = @defendant_class.new @context
15
15
  end
16
16
 
17
17
  def aborted
@@ -26,10 +26,8 @@ module RestMyCase
26
26
  Context::Base.new attributes
27
27
  end
28
28
 
29
- def build_defendant(defendant_class, use_case_classes)
30
- Class.new(defendant_class) do
31
- depends(*use_case_classes)
32
- end.new(@context)
29
+ def build_defendant(last_ancestor, use_case_classes)
30
+ Class.new(last_ancestor) { depends(*use_case_classes) }
33
31
  end
34
32
 
35
33
  end
@@ -0,0 +1,144 @@
1
+ module RestMyCase
2
+
3
+ class Validator < RestMyCase::Base
4
+
5
+ module ClassMethods
6
+
7
+ attr_writer :validators
8
+
9
+ attr_reader :clear_errors
10
+
11
+ def trial_court
12
+ @trial_court ||= Trial::Court.new \
13
+ Judge::Base, DefenseAttorney::Base, RestMyCase::Validator
14
+ end
15
+
16
+ def target_name
17
+ @target_name || Helpers.super_method(self, :target_name)
18
+ end
19
+
20
+ def target(target_name)
21
+ @target_name = target_name
22
+ end
23
+
24
+ def clear_errors!
25
+ @clear_errors = true
26
+ end
27
+
28
+ def validators
29
+ @validators ||= Hash.new { |hash, key| hash[key] = [] }
30
+ end
31
+
32
+ def validate(*args, &block)
33
+ validators[nil] << CustomValidator.new(args, &block)
34
+ end
35
+
36
+ def validates_with(*args, &block)
37
+ options = Helpers.extract_options!(args)
38
+
39
+ options[:class] = self
40
+
41
+ args.each do |klass|
42
+ store_validators_by_attribute klass.new(options, &block)
43
+ end
44
+ end
45
+
46
+ protected ######################## PROTECTED #############################
47
+
48
+ def store_validators_by_attribute(validator)
49
+ if validator.respond_to?(:attributes) && !validator.attributes.empty?
50
+ validator.attributes.each do |attribute|
51
+ validators[attribute.to_sym] << validator
52
+ end
53
+ else
54
+ validators[nil] << validator
55
+ end
56
+ end
57
+
58
+ # Copy validators on inheritance.
59
+ def inherited(base)
60
+ dup = validators.dup
61
+ base.validators = dup.each { |k, v| dup[k] = v.dup }
62
+ super
63
+ end
64
+
65
+ end
66
+
67
+ ######################## INSTANCE METHODS BELLOW ###########################
68
+
69
+ extend ClassMethods
70
+
71
+ self.silence_dependencies_abort = true
72
+
73
+ extend AccusationAttorneys::HelperMethods
74
+
75
+ def target_name
76
+ self.class.target_name
77
+ end
78
+
79
+ def target
80
+ respond_to?(target_name) ? send(target_name) : context.send(target_name)
81
+ end
82
+
83
+ def perform
84
+ targets = [*target]
85
+
86
+ skip! if targets.empty?
87
+
88
+ if target.nil?
89
+ error('no target to validate!')
90
+ else
91
+ error('unprocessable_entity') unless all_validations_green? targets
92
+ end
93
+ end
94
+
95
+ protected ######################## PROTECTED ###############################
96
+
97
+ def all_validations_green?(targets)
98
+ targets.map do |object_to_validate|
99
+ if Helpers.marked_for_destruction?(object_to_validate)
100
+ true
101
+ else
102
+ extend_errors_and_run_validations(object_to_validate)
103
+
104
+ object_to_validate.errors.empty?
105
+ end
106
+ end.all?
107
+ end
108
+
109
+ private ########################### PRIVATE ################################
110
+
111
+ def extend_errors_and_run_validations(object_to_validate)
112
+ extend_errors_if_necessary object_to_validate
113
+
114
+ object_to_validate.errors.clear if self.class.clear_errors
115
+
116
+ self.class.validators.values.flatten.uniq.each do |validator|
117
+ next if validator_condition_fails(validator, object_to_validate)
118
+
119
+ validator.base = self
120
+
121
+ validator.validate object_to_validate
122
+ end
123
+ end
124
+
125
+ def extend_errors_if_necessary(object_to_validate)
126
+ return true if object_to_validate.respond_to?(:errors)
127
+
128
+ object_to_validate.instance_eval do
129
+ def errors
130
+ @errors ||= AccusationAttorneys::Errors.new(self)
131
+ end
132
+ end
133
+ end
134
+
135
+ def validator_condition_fails(validator, object_to_validate)
136
+ return false unless validator.options.key?(:if)
137
+
138
+ !Helpers.call_proc_or_method \
139
+ self, validator.options[:if], object_to_validate
140
+ end
141
+
142
+ end
143
+
144
+ end
@@ -1,5 +1,5 @@
1
1
  module RestMyCase
2
2
 
3
- VERSION = '1.7.0'
3
+ VERSION = '1.7.4'
4
4
 
5
5
  end
data/lib/rest_my_case.rb CHANGED
@@ -11,20 +11,18 @@ require 'rest_my_case/judge/base'
11
11
  require 'rest_my_case/trial/case'
12
12
  require 'rest_my_case/trial/court'
13
13
 
14
- require 'rest_my_case/base'
15
-
16
14
  require 'rest_my_case/accusation_attorneys/helper_methods'
17
15
  require 'rest_my_case/accusation_attorneys/base'
18
16
  require 'rest_my_case/accusation_attorneys/each'
19
17
  require 'rest_my_case/accusation_attorneys/custom'
18
+ require 'rest_my_case/accusation_attorneys/errors'
20
19
  # require 'rest_my_case/accusation_attorneys/format'
21
20
  # require 'rest_my_case/accusation_attorneys/length'
22
21
  require 'rest_my_case/accusation_attorneys/presence'
23
22
  # require 'rest_my_case/accusation_attorneys/numericality'
24
23
 
25
- require 'rest_my_case/validator/class_methods'
26
- require 'rest_my_case/validator/errors'
27
- require 'rest_my_case/validator/base'
24
+ require 'rest_my_case/base'
25
+ require 'rest_my_case/validator'
28
26
 
29
27
  module RestMyCase
30
28
 
@@ -111,10 +111,10 @@ describe RestMyCase::Base do
111
111
  end
112
112
 
113
113
  it "context prove that only the correct method have ran" do
114
- expect(@context.setup.length).to be 3
114
+ expect(@context.setup.length).to be 4
115
115
  expect(@context.perform.length).to be 0
116
116
  expect(@context.rollback.length).to be 0
117
- expect(@context.final.length).to be 7
117
+ expect(@context.final.length).to be 12
118
118
  end
119
119
  end
120
120
 
@@ -133,10 +133,10 @@ describe RestMyCase::Base do
133
133
  end
134
134
 
135
135
  it "context prove that only the correct method have ran" do
136
- expect(@context.setup.length).to be 2
136
+ expect(@context.setup.length).to be 3
137
137
  expect(@context.perform.length).to be 0
138
138
  expect(@context.rollback.length).to be 0
139
- expect(@context.final.length).to be 7
139
+ expect(@context.final.length).to be 12
140
140
  end
141
141
  end
142
142
 
@@ -151,10 +151,10 @@ describe RestMyCase::Base do
151
151
  end
152
152
 
153
153
  it "context prove that only the correct method have ran" do
154
- expect(@context.setup.length).to be 2
154
+ expect(@context.setup.length).to be 3
155
155
  expect(@context.perform.length).to be 0
156
156
  expect(@context.rollback.length).to be 0
157
- expect(@context.final.length).to be 7
157
+ expect(@context.final.length).to be 12
158
158
  end
159
159
  end
160
160
 
@@ -169,10 +169,10 @@ describe RestMyCase::Base do
169
169
  end
170
170
 
171
171
  it "context prove that only the correct method have ran" do
172
- expect(@context.setup.length).to be 7
173
- expect(@context.perform.length).to be 2
174
- expect(@context.rollback.length).to be 3
175
- expect(@context.final.length).to be 7
172
+ expect(@context.setup.length).to be 12
173
+ expect(@context.perform.length).to be 3
174
+ expect(@context.rollback.length).to be 4
175
+ expect(@context.final.length).to be 12
176
176
  end
177
177
  end
178
178
 
@@ -187,10 +187,10 @@ describe RestMyCase::Base do
187
187
  end
188
188
 
189
189
  it "context prove that only the correct method have ran" do
190
- expect(@context.setup.length).to be 7
191
- expect(@context.perform.length).to be 6
190
+ expect(@context.setup.length).to be 12
191
+ expect(@context.perform.length).to be 11
192
192
  expect(@context.rollback.length).to be 0
193
- expect(@context.final.length).to be 7
193
+ expect(@context.final.length).to be 12
194
194
  end
195
195
  end
196
196
 
@@ -206,10 +206,10 @@ describe RestMyCase::Base do
206
206
  end
207
207
 
208
208
  it "context prove that only the correct method have ran" do
209
- expect(@context.setup.length).to be 6
210
- expect(@context.perform.length).to be 6
209
+ expect(@context.setup.length).to be 11
210
+ expect(@context.perform.length).to be 11
211
211
  expect(@context.rollback.length).to be 0
212
- expect(@context.final.length).to be 7
212
+ expect(@context.final.length).to be 12
213
213
  end
214
214
 
215
215
  end
@@ -234,10 +234,10 @@ describe RestMyCase::Base do
234
234
  end
235
235
 
236
236
  it "context prove that only the correct method have ran" do
237
- expect(@context.setup.length).to be 5
237
+ expect(@context.setup.length).to be 8
238
238
  expect(@context.perform.length).to be 0
239
239
  expect(@context.rollback.length).to be 0
240
- expect(@context.final.length).to be 7
240
+ expect(@context.final.length).to be 12
241
241
  end
242
242
 
243
243
  end
@@ -258,10 +258,10 @@ describe RestMyCase::Base do
258
258
  end
259
259
 
260
260
  it "context prove that only the correct method have ran" do
261
- expect(@context.setup.length).to be 7
262
- expect(@context.perform.length).to be 5
263
- expect(@context.rollback.length).to be 5
264
- expect(@context.final.length).to be 7
261
+ expect(@context.setup.length).to be 12
262
+ expect(@context.perform.length).to be 8
263
+ expect(@context.rollback.length).to be 8
264
+ expect(@context.final.length).to be 12
265
265
  end
266
266
 
267
267
  end
@@ -293,10 +293,10 @@ describe RestMyCase::Base do
293
293
  end
294
294
 
295
295
  it "context prove that only the correct method have ran" do
296
- expect(@context.setup.length).to be 7
297
- expect(@context.perform.length).to be 7
296
+ expect(@context.setup.length).to be 12
297
+ expect(@context.perform.length).to be 12
298
298
  expect(@context.rollback.length).to be 0
299
- expect(@context.final.length).to be 7
299
+ expect(@context.final.length).to be 12
300
300
  end
301
301
 
302
302
  end
@@ -340,40 +340,46 @@ describe RestMyCase::Base do
340
340
  @context = Perform::ScreammingInvoker.perform
341
341
 
342
342
  expect(@context.setup).to eq [
343
- "Perform::UseCaseWrapper",
343
+ "Perform::Logger",
344
344
  "Perform::ScreammingInvoker",
345
- "Perform::UseCaseWrapper",
345
+ "Perform::Logger",
346
346
  "Perform::BuildPost",
347
- "Perform::UseCaseWrapper",
347
+ "Perform::Logger",
348
348
  "Perform::ValidateName",
349
+ "Perform::Logger",
349
350
  "Perform::ValidateBody",
351
+ "Perform::Logger",
350
352
  "Perform::Validations",
351
- "Perform::UseCaseWrapper",
353
+ "Perform::Logger",
352
354
  "Perform::SavePost"
353
355
  ]
354
356
  expect(@context.perform).to eq [
355
- "Perform::UseCaseWrapper",
357
+ "Perform::Logger",
356
358
  "Perform::ScreammingInvoker",
357
- "Perform::UseCaseWrapper",
359
+ "Perform::Logger",
358
360
  "Perform::BuildPost",
359
- "Perform::UseCaseWrapper",
361
+ "Perform::Logger",
360
362
  "Perform::ValidateName",
363
+ "Perform::Logger",
361
364
  "Perform::ValidateBody",
365
+ "Perform::Logger",
362
366
  "Perform::Validations",
363
- "Perform::UseCaseWrapper",
367
+ "Perform::Logger",
364
368
  "Perform::SavePost"
365
369
  ]
366
370
  expect(@context.rollback).to eq []
367
371
  expect(@context.final).to eq [
368
- "Perform::UseCaseWrapper",
372
+ "Perform::Logger",
369
373
  "Perform::BuildPost",
370
- "Perform::UseCaseWrapper",
374
+ "Perform::Logger",
371
375
  "Perform::ValidateName",
376
+ "Perform::Logger",
372
377
  "Perform::ValidateBody",
378
+ "Perform::Logger",
373
379
  "Perform::Validations",
374
- "Perform::UseCaseWrapper",
380
+ "Perform::Logger",
375
381
  "Perform::SavePost",
376
- "Perform::UseCaseWrapper",
382
+ "Perform::Logger",
377
383
  "Perform::ScreammingInvoker"
378
384
  ]
379
385
  end
@@ -401,39 +407,47 @@ describe RestMyCase::Base do
401
407
 
402
408
  it "invoker should abort the process it his invokees have also aborted" do
403
409
  expect(@context.setup).to eq [
404
- "Perform::UseCaseWrapper",
410
+ "Perform::Logger",
405
411
  "Perform::BuildPost",
412
+ "Perform::Logger",
406
413
  "Perform::Validations2",
414
+ "Perform::Logger",
407
415
  "Perform::SavePost",
416
+ "Perform::Logger",
408
417
  "Perform::CreatePost2",
409
- "Perform::UseCaseWrapper",
418
+ "Perform::Logger",
410
419
  "Perform::ValidateName",
411
- "Perform::UseCaseWrapper",
420
+ "Perform::Logger",
412
421
  "Perform::ValidateBody"
413
422
  ]
414
423
  expect(@context.perform).to eq [
415
- "Perform::UseCaseWrapper",
424
+ "Perform::Logger",
416
425
  "Perform::BuildPost",
426
+ "Perform::Logger",
417
427
  "Perform::Validations2",
418
- "Perform::UseCaseWrapper",
428
+ "Perform::Logger",
419
429
  "Perform::ValidateName"
420
430
  ]
421
431
  expect(@context.rollback).to eq [
422
432
  "Perform::ValidateName",
423
- "Perform::UseCaseWrapper",
433
+ "Perform::Logger",
424
434
  "Perform::Validations2",
435
+ "Perform::Logger",
425
436
  "Perform::BuildPost",
426
- "Perform::UseCaseWrapper"
437
+ "Perform::Logger"
427
438
  ]
428
439
  expect(@context.final).to eq [
429
- "Perform::UseCaseWrapper",
440
+ "Perform::Logger",
430
441
  "Perform::ValidateName",
431
- "Perform::UseCaseWrapper",
442
+ "Perform::Logger",
432
443
  "Perform::ValidateBody",
433
- "Perform::UseCaseWrapper",
444
+ "Perform::Logger",
434
445
  "Perform::BuildPost",
446
+ "Perform::Logger",
435
447
  "Perform::Validations2",
448
+ "Perform::Logger",
436
449
  "Perform::SavePost",
450
+ "Perform::Logger",
437
451
  "Perform::CreatePost2"
438
452
  ]
439
453
  end
@@ -48,21 +48,83 @@ describe RestMyCase::DefenseAttorney::Base do
48
48
  let(:use_case_classes) { [DefenseAttorney::CreatePostWithComments] }
49
49
 
50
50
  it_behaves_like "a porper shepherd", [
51
+ DefenseAttorney::BuildComments,
52
+ DefenseAttorney::SaveComments,
53
+ DefenseAttorney::CreateComments,
54
+ DefenseAttorney::AssignAttributes,
55
+ DefenseAttorney::BuildSomething,
56
+ DefenseAttorney::BuildPost,
57
+ DefenseAttorney::SavePost,
51
58
  DefenseAttorney::BuilEvent,
52
59
  DefenseAttorney::SaveEvent,
53
60
  DefenseAttorney::CreateEvent,
54
61
  DefenseAttorney::LogEvents,
55
62
  DefenseAttorney::AnalyseEvents,
56
- DefenseAttorney::UseCaseWrapper,
57
- DefenseAttorney::BuildPost,
58
- DefenseAttorney::SavePost,
59
- DefenseAttorney::CreatePost,
60
- DefenseAttorney::BuildComments,
61
- DefenseAttorney::SaveComments,
62
- DefenseAttorney::CreateComments,
63
63
  DefenseAttorney::CreatePostWithComments
64
64
  ]
65
65
 
66
66
  end
67
67
 
68
+ context "When general config has parent_dependencies_first = true" do
69
+
70
+ before do
71
+ RestMyCase.configure do |config|
72
+ config.parent_dependencies_first = true
73
+ end
74
+ end
75
+ after { RestMyCase.reset_config }
76
+
77
+ context "When a use case inherits from another that also has dependencies" do
78
+
79
+ let(:use_case_classes) { [DefenseAttorney::CreatePostWithComments] }
80
+
81
+ it_behaves_like "a porper shepherd", [
82
+ DefenseAttorney::BuilEvent,
83
+ DefenseAttorney::SaveEvent,
84
+ DefenseAttorney::CreateEvent,
85
+ DefenseAttorney::LogEvents,
86
+ DefenseAttorney::AnalyseEvents,
87
+ DefenseAttorney::BuildSomething,
88
+ DefenseAttorney::AssignAttributes,
89
+ DefenseAttorney::BuildPost,
90
+ DefenseAttorney::SavePost,
91
+ DefenseAttorney::BuildComments,
92
+ DefenseAttorney::SaveComments,
93
+ DefenseAttorney::CreateComments,
94
+ DefenseAttorney::CreatePostWithComments
95
+ ]
96
+
97
+ end
98
+
99
+ end
100
+
101
+ context "When dependent use_case has parent_dependencies_first = true" do
102
+
103
+ before { DefenseAttorney::BuildPost.parent_dependencies_first = true }
104
+ after { DefenseAttorney::BuildPost.parent_dependencies_first = nil }
105
+
106
+ context "When a use case inherits from another that also has dependencies" do
107
+
108
+ let(:use_case_classes) { [DefenseAttorney::CreatePostWithComments] }
109
+
110
+ it_behaves_like "a porper shepherd", [
111
+ DefenseAttorney::BuildComments,
112
+ DefenseAttorney::SaveComments,
113
+ DefenseAttorney::CreateComments,
114
+ DefenseAttorney::BuildSomething,
115
+ DefenseAttorney::AssignAttributes,
116
+ DefenseAttorney::BuildPost,
117
+ DefenseAttorney::SavePost,
118
+ DefenseAttorney::BuilEvent,
119
+ DefenseAttorney::SaveEvent,
120
+ DefenseAttorney::CreateEvent,
121
+ DefenseAttorney::LogEvents,
122
+ DefenseAttorney::AnalyseEvents,
123
+ DefenseAttorney::CreatePostWithComments
124
+ ]
125
+
126
+ end
127
+
128
+ end
129
+
68
130
  end
@@ -14,7 +14,17 @@ module DefenseAttorney
14
14
 
15
15
  class AnalyseEvents < RestMyCase::Base; end
16
16
 
17
- class BuildPost < RestMyCase::Base; end
17
+ class BuildSomething < RestMyCase::Base; end
18
+
19
+ class AssignAttributes < RestMyCase::Base; end
20
+
21
+ class Builder < RestMyCase::Base
22
+ depends BuildSomething
23
+ end
24
+
25
+ class BuildPost < Builder
26
+ depends AssignAttributes
27
+ end
18
28
 
19
29
  class SavePost < RestMyCase::Base; end
20
30
 
@@ -1,6 +1,6 @@
1
1
  module Perform
2
2
 
3
- class UseCaseWrapper < RestMyCase::Base
3
+ class Test < RestMyCase::Base
4
4
  def flow_control(method)
5
5
  id = "#{self.class.name}_#{method}"
6
6
 
@@ -42,6 +42,12 @@ module Perform
42
42
  end
43
43
  end
44
44
 
45
+ class Logger < Test; end
46
+
47
+ class UseCaseWrapper < Test
48
+ depends Logger
49
+ end
50
+
45
51
  class ValidateName < UseCaseWrapper; end
46
52
 
47
53
  class ValidateBody < UseCaseWrapper; end
@@ -1,6 +1,6 @@
1
1
  module HierarchyValidation
2
2
 
3
- class Father < RestMyCase::Validator::Base
3
+ class Father < RestMyCase::Validator
4
4
 
5
5
  target :post
6
6
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rest_my_case
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.0
4
+ version: 1.7.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - goncalvesjoao
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-17 00:00:00.000000000 Z
11
+ date: 2015-04-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pry
@@ -115,7 +115,11 @@ files:
115
115
  - lib/rest_my_case/accusation_attorneys/base.rb
116
116
  - lib/rest_my_case/accusation_attorneys/custom.rb
117
117
  - lib/rest_my_case/accusation_attorneys/each.rb
118
+ - lib/rest_my_case/accusation_attorneys/errors.rb
119
+ - lib/rest_my_case/accusation_attorneys/format.rb
118
120
  - lib/rest_my_case/accusation_attorneys/helper_methods.rb
121
+ - lib/rest_my_case/accusation_attorneys/length.rb
122
+ - lib/rest_my_case/accusation_attorneys/numericality.rb
119
123
  - lib/rest_my_case/accusation_attorneys/presence.rb
120
124
  - lib/rest_my_case/base.rb
121
125
  - lib/rest_my_case/config/base.rb
@@ -127,9 +131,7 @@ files:
127
131
  - lib/rest_my_case/judge/base.rb
128
132
  - lib/rest_my_case/trial/case.rb
129
133
  - lib/rest_my_case/trial/court.rb
130
- - lib/rest_my_case/validator/base.rb
131
- - lib/rest_my_case/validator/class_methods.rb
132
- - lib/rest_my_case/validator/errors.rb
134
+ - lib/rest_my_case/validator.rb
133
135
  - lib/rest_my_case/version.rb
134
136
  - rest_my_case.gemspec
135
137
  - spec/rest_my_case/base_spec.rb
@@ -1,82 +0,0 @@
1
- module RestMyCase
2
- module Validator
3
-
4
- class Base < RestMyCase::Base
5
-
6
- extend ClassMethods
7
-
8
- self.silence_dependencies_abort = true
9
-
10
- extend AccusationAttorneys::HelperMethods
11
-
12
- def target_name
13
- self.class.target_name
14
- end
15
-
16
- def target
17
- respond_to?(target_name) ? send(target_name) : context.send(target_name)
18
- end
19
-
20
- def perform
21
- targets = [*target]
22
-
23
- skip! if targets.empty?
24
-
25
- if target.nil?
26
- error('no target to validate!')
27
- else
28
- error('unprocessable_entity') unless all_validations_green? targets
29
- end
30
- end
31
-
32
- protected ######################## PROTECTED #############################
33
-
34
- def all_validations_green?(targets)
35
- targets.map do |object_to_validate|
36
- if Helpers.marked_for_destruction?(object_to_validate)
37
- true
38
- else
39
- extend_errors_and_run_validations(object_to_validate)
40
-
41
- object_to_validate.errors.empty?
42
- end
43
- end.all?
44
- end
45
-
46
- private ########################### PRIVATE ##############################
47
-
48
- def extend_errors_and_run_validations(object_to_validate)
49
- extend_errors_if_necessary object_to_validate
50
-
51
- object_to_validate.errors.clear if self.class.clear_errors
52
-
53
- self.class.validators.values.flatten.uniq.each do |validator|
54
- next if validator_condition_fails(validator, object_to_validate)
55
-
56
- validator.base = self
57
-
58
- validator.validate object_to_validate
59
- end
60
- end
61
-
62
- def extend_errors_if_necessary(object_to_validate)
63
- return true if object_to_validate.respond_to?(:errors)
64
-
65
- object_to_validate.instance_eval do
66
- def errors
67
- @errors ||= Errors.new(self)
68
- end
69
- end
70
- end
71
-
72
- def validator_condition_fails(validator, object_to_validate)
73
- return false unless validator.options.key?(:if)
74
-
75
- !Helpers.call_proc_or_method \
76
- self, validator.options[:if], object_to_validate
77
- end
78
-
79
- end
80
-
81
- end
82
- end
@@ -1,58 +0,0 @@
1
- module RestMyCase
2
- module Validator
3
-
4
- module ClassMethods
5
-
6
- attr_reader :validators, :clear_errors
7
-
8
- def trial_court
9
- @trial_court ||= Trial::Court.new \
10
- Judge::Base, DefenseAttorney::Base, RestMyCase::Validator::Base
11
- end
12
-
13
- def target_name
14
- @target_name || Helpers.super_method(self, :target_name)
15
- end
16
-
17
- def target(target_name)
18
- @target_name = target_name
19
- end
20
-
21
- def clear_errors!
22
- @clear_errors = true
23
- end
24
-
25
- def validators
26
- @validators ||= Hash.new { |hash, key| hash[key] = [] }
27
- end
28
-
29
- def validate(*args, &block)
30
- validators[nil] << CustomValidator.new(args, &block)
31
- end
32
-
33
- def validates_with(*args, &block)
34
- options = Helpers.extract_options!(args)
35
-
36
- options[:class] = self
37
-
38
- args.each do |klass|
39
- store_validators_by_attribute klass.new(options, &block)
40
- end
41
- end
42
-
43
- protected ######################## PROTECTED #############################
44
-
45
- def store_validators_by_attribute(validator)
46
- if validator.respond_to?(:attributes) && !validator.attributes.empty?
47
- validator.attributes.each do |attribute|
48
- validators[attribute.to_sym] << validator
49
- end
50
- else
51
- validators[nil] << validator
52
- end
53
- end
54
-
55
- end
56
-
57
- end
58
- end