rest_my_case 1.7.0 → 1.7.4

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 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