rest_my_case 1.6.0 → 1.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +2 -7
- data/lib/rest_my_case.rb +14 -4
- data/lib/rest_my_case/accusation_attorneys/base.rb +23 -0
- data/lib/rest_my_case/accusation_attorneys/custom.rb +21 -0
- data/lib/rest_my_case/accusation_attorneys/each.rb +34 -0
- data/lib/rest_my_case/accusation_attorneys/helper_methods.rb +16 -0
- data/lib/rest_my_case/accusation_attorneys/presence.rb +17 -0
- data/lib/rest_my_case/base.rb +13 -5
- data/lib/rest_my_case/config/general.rb +15 -1
- data/lib/rest_my_case/defense_attorney/base.rb +5 -7
- data/lib/rest_my_case/helpers.rb +63 -0
- data/lib/rest_my_case/judge/base.rb +1 -1
- data/lib/rest_my_case/trial/case.rb +17 -7
- data/lib/rest_my_case/trial/court.rb +2 -2
- data/lib/rest_my_case/validator/base.rb +82 -0
- data/lib/rest_my_case/validator/class_methods.rb +58 -0
- data/lib/rest_my_case/validator/errors.rb +366 -0
- data/lib/rest_my_case/version.rb +1 -1
- data/spec/rest_my_case/base_spec.rb +1 -1
- data/spec/rest_my_case/defense_attorney/base_spec.rb +1 -1
- data/spec/rest_my_case/trial_case/court_spec.rb +4 -2
- data/spec/rest_my_case/validator/hierarchy_spec.rb +23 -0
- data/spec/support/validator/models/ruby_post.rb +9 -0
- data/spec/support/validator/models/ruby_post_with_comments.rb +28 -0
- data/spec/support/validator/usecases/hierarchy_validation.rb +17 -0
- metadata +19 -3
- data/lib/rest_my_case/trial/defendant.rb +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4fbc100a76e2fe8ef3a5b546121c072662e41864
|
4
|
+
data.tar.gz: 335942040cc881c507bf65a3a437f50f1436c3b0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2872b4f50c0d422921083b393fda8d3d81010a7e7268985d966bcab5961aa5c398506af5494f2fd6889bcebeb551f2a3ecac4c09e74df57a3d4012914952254c
|
7
|
+
data.tar.gz: b464f45b1152e7916cc847d0b8c34e3e26a57ee0393b6b33896c831ce950e7f3b3ea4d65abba3e1ead99ee3d5c042bc0e341b0532698c147a87eeb0da8ad87df
|
data/.rubocop.yml
CHANGED
@@ -10,13 +10,6 @@ Style/EmptyLinesAroundModuleBody:
|
|
10
10
|
Style/EmptyLinesAroundClassBody:
|
11
11
|
Enabled: false
|
12
12
|
|
13
|
-
Style/DotPosition:
|
14
|
-
Enabled: false
|
15
|
-
|
16
|
-
Style/Encoding:
|
17
|
-
Enabled: true
|
18
|
-
EnforcedStyle: when_needed
|
19
|
-
|
20
13
|
AllCops:
|
21
14
|
Exclude:
|
22
15
|
- '**/Rakefile'
|
@@ -25,6 +18,8 @@ AllCops:
|
|
25
18
|
- 'spec/**/*'
|
26
19
|
- 'tmp/**/*'
|
27
20
|
- 'pkg/**/*'
|
21
|
+
- 'lib/rest_my_case/accusation_attorneys/**/*'
|
22
|
+
- 'lib/rest_my_case/validator/errors.rb'
|
28
23
|
|
29
24
|
Documentation:
|
30
25
|
Enabled: false
|
data/lib/rest_my_case.rb
CHANGED
@@ -1,21 +1,31 @@
|
|
1
1
|
require 'ostruct'
|
2
2
|
|
3
3
|
require 'rest_my_case/version'
|
4
|
+
require 'rest_my_case/helpers'
|
4
5
|
require 'rest_my_case/errors'
|
5
|
-
|
6
6
|
require 'rest_my_case/config/base'
|
7
7
|
require 'rest_my_case/config/general'
|
8
|
-
|
9
8
|
require 'rest_my_case/defense_attorney/base'
|
10
9
|
require 'rest_my_case/context/base'
|
11
10
|
require 'rest_my_case/judge/base'
|
12
|
-
|
13
|
-
require 'rest_my_case/trial/defendant'
|
14
11
|
require 'rest_my_case/trial/case'
|
15
12
|
require 'rest_my_case/trial/court'
|
16
13
|
|
17
14
|
require 'rest_my_case/base'
|
18
15
|
|
16
|
+
require 'rest_my_case/accusation_attorneys/helper_methods'
|
17
|
+
require 'rest_my_case/accusation_attorneys/base'
|
18
|
+
require 'rest_my_case/accusation_attorneys/each'
|
19
|
+
require 'rest_my_case/accusation_attorneys/custom'
|
20
|
+
# require 'rest_my_case/accusation_attorneys/format'
|
21
|
+
# require 'rest_my_case/accusation_attorneys/length'
|
22
|
+
require 'rest_my_case/accusation_attorneys/presence'
|
23
|
+
# require 'rest_my_case/accusation_attorneys/numericality'
|
24
|
+
|
25
|
+
require 'rest_my_case/validator/class_methods'
|
26
|
+
require 'rest_my_case/validator/errors'
|
27
|
+
require 'rest_my_case/validator/base'
|
28
|
+
|
19
29
|
module RestMyCase
|
20
30
|
|
21
31
|
def self.configure
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module RestMyCase
|
2
|
+
module AccusationAttorneys
|
3
|
+
|
4
|
+
class Base
|
5
|
+
|
6
|
+
attr_accessor :base
|
7
|
+
|
8
|
+
attr_reader :options
|
9
|
+
|
10
|
+
def initialize(options = {})
|
11
|
+
@options = Helpers.except(options, :class).freeze
|
12
|
+
end
|
13
|
+
|
14
|
+
# Override this method in subclasses with validation logic, adding errors
|
15
|
+
# to the records +errors+ array where necessary.
|
16
|
+
def validate(record)
|
17
|
+
fail NotImplementedError, "Subclasses must implement a validate(record) method."
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module RestMyCase
|
2
|
+
module AccusationAttorneys
|
3
|
+
|
4
|
+
class Custom < Base
|
5
|
+
|
6
|
+
attr_reader :methods
|
7
|
+
|
8
|
+
def initialize(args)
|
9
|
+
@methods = args
|
10
|
+
|
11
|
+
super Helpers.extract_options!(args)
|
12
|
+
end
|
13
|
+
|
14
|
+
def validate(record)
|
15
|
+
[*methods].map { |method| base.send(method, record) }.all?
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module RestMyCase
|
2
|
+
module AccusationAttorneys
|
3
|
+
|
4
|
+
class Each < Base
|
5
|
+
|
6
|
+
attr_reader :attributes
|
7
|
+
|
8
|
+
def initialize(options)
|
9
|
+
@attributes = Array(options.delete(:attributes))
|
10
|
+
fail ArgumentError, ":attributes cannot be blank" if @attributes.empty?
|
11
|
+
super
|
12
|
+
check_validity!
|
13
|
+
end
|
14
|
+
|
15
|
+
def validate(record)
|
16
|
+
attributes.each do |attribute|
|
17
|
+
value = record.respond_to?(attribute) ? record.send(attribute) : nil
|
18
|
+
next if (value.nil? && options[:allow_nil]) || (Helpers.blank?(value) && options[:allow_blank])
|
19
|
+
validate_each(record, attribute, value)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# Override this method in subclasses with the validation logic, adding
|
24
|
+
# errors to the records +errors+ array where necessary.
|
25
|
+
def validate_each(record, attribute, value)
|
26
|
+
fail NotImplementedError, "Subclasses must implement a validate_each(record, attribute, value) method"
|
27
|
+
end
|
28
|
+
|
29
|
+
def check_validity!; end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module RestMyCase
|
2
|
+
module AccusationAttorneys
|
3
|
+
|
4
|
+
module HelperMethods
|
5
|
+
|
6
|
+
def _merge_attributes(attr_names)
|
7
|
+
options = Helpers.symbolyze_keys(Helpers.extract_options!(attr_names))
|
8
|
+
attr_names.flatten!
|
9
|
+
options[:attributes] = attr_names
|
10
|
+
options
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module RestMyCase
|
2
|
+
module AccusationAttorneys
|
3
|
+
|
4
|
+
class Presence < Each
|
5
|
+
def validate_each(record, attr_name, value)
|
6
|
+
record.errors.add(attr_name, :blank, options) if Helpers.blank?(value)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
module HelperMethods
|
11
|
+
def validates_presence_of(*attr_names)
|
12
|
+
validates_with Presence, _merge_attributes(attr_names)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
data/lib/rest_my_case/base.rb
CHANGED
@@ -4,7 +4,10 @@ module RestMyCase
|
|
4
4
|
|
5
5
|
extend Config::Base
|
6
6
|
|
7
|
-
|
7
|
+
def self.trial_court
|
8
|
+
@trial_court ||= Trial::Court.new \
|
9
|
+
Judge::Base, DefenseAttorney::Base, RestMyCase::Base
|
10
|
+
end
|
8
11
|
|
9
12
|
def self.depends(*use_case_classes)
|
10
13
|
dependencies.push(*use_case_classes)
|
@@ -21,7 +24,7 @@ module RestMyCase
|
|
21
24
|
fail ArgumentError, 'Must respond_to method #to_hash'
|
22
25
|
end
|
23
26
|
|
24
|
-
|
27
|
+
trial_court.execute([self], attributes.to_hash).context
|
25
28
|
end
|
26
29
|
|
27
30
|
def self.context_accessor(*methods)
|
@@ -58,11 +61,11 @@ module RestMyCase
|
|
58
61
|
def final; end
|
59
62
|
|
60
63
|
def invoke(*use_case_classes)
|
61
|
-
|
64
|
+
trial_court.execute(use_case_classes, context.to_hash).context
|
62
65
|
end
|
63
66
|
|
64
67
|
def invoke!(*use_case_classes)
|
65
|
-
|
68
|
+
trial_court.execute(use_case_classes, context).tap do |trial_case|
|
66
69
|
abort if trial_case.aborted
|
67
70
|
end.context
|
68
71
|
end
|
@@ -93,10 +96,15 @@ module RestMyCase
|
|
93
96
|
|
94
97
|
protected ######################## PROTECTED ###############################
|
95
98
|
|
99
|
+
def trial_court
|
100
|
+
self.class.trial_court
|
101
|
+
end
|
102
|
+
|
96
103
|
def silent_abort?
|
97
104
|
return false if dependent_use_case.nil?
|
98
105
|
|
99
|
-
RestMyCase.get_config
|
106
|
+
RestMyCase.get_config \
|
107
|
+
:silence_dependencies_abort, dependent_use_case.class
|
100
108
|
end
|
101
109
|
|
102
110
|
end
|
@@ -10,11 +10,25 @@ module RestMyCase
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def get(attribute, use_case_class)
|
13
|
-
custom_config =
|
13
|
+
custom_config = use_case_class_config(attribute, use_case_class)
|
14
14
|
|
15
15
|
custom_config.nil? ? send(attribute) : custom_config
|
16
16
|
end
|
17
17
|
|
18
|
+
protected ######################## PROTECTED #############################
|
19
|
+
|
20
|
+
def use_case_class_config(attribute, use_case_class)
|
21
|
+
return nil unless use_case_class.respond_to? attribute
|
22
|
+
|
23
|
+
custom_config = use_case_class.send(attribute)
|
24
|
+
|
25
|
+
if custom_config.nil?
|
26
|
+
use_case_class_config(attribute, use_case_class.superclass)
|
27
|
+
else
|
28
|
+
custom_config
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
18
32
|
end
|
19
33
|
|
20
34
|
end
|
@@ -9,7 +9,7 @@ module RestMyCase
|
|
9
9
|
|
10
10
|
def build_case_for_the_defendant
|
11
11
|
@trial_case.use_cases =
|
12
|
-
@trial_case.
|
12
|
+
@trial_case.use_case_classes.map do |use_case_class|
|
13
13
|
all_dependencies(use_case_class)
|
14
14
|
end.flatten
|
15
15
|
end
|
@@ -17,17 +17,15 @@ module RestMyCase
|
|
17
17
|
protected ######################## PROTECTED #############################
|
18
18
|
|
19
19
|
def all_dependencies(use_case_class)
|
20
|
-
return []
|
20
|
+
return [] if use_case_class == @trial_case.last_ancestor
|
21
21
|
|
22
22
|
all_dependencies(use_case_class.superclass) |
|
23
|
-
|
23
|
+
dependencies_including_itself(use_case_class, @trial_case.defendant)
|
24
24
|
end
|
25
25
|
|
26
26
|
private ########################### PRIVATE ##############################
|
27
27
|
|
28
|
-
def
|
29
|
-
return [] unless use_case_class.superclass.respond_to? :dependencies
|
30
|
-
|
28
|
+
def dependencies_including_itself(use_case_class, dependent_use_case)
|
31
29
|
use_case = use_case_class.new(@trial_case.context, dependent_use_case)
|
32
30
|
|
33
31
|
dependencies(use_case).push use_case
|
@@ -35,7 +33,7 @@ module RestMyCase
|
|
35
33
|
|
36
34
|
def dependencies(use_case)
|
37
35
|
use_case.class.dependencies.map do |dependency|
|
38
|
-
|
36
|
+
dependencies_including_itself dependency, use_case
|
39
37
|
end
|
40
38
|
end
|
41
39
|
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module RestMyCase
|
2
|
+
|
3
|
+
module Helpers
|
4
|
+
|
5
|
+
module_function
|
6
|
+
|
7
|
+
def super_method(object, method_name, *args)
|
8
|
+
return nil unless object.superclass.respond_to? method_name
|
9
|
+
|
10
|
+
object.superclass.send method_name, *args
|
11
|
+
end
|
12
|
+
|
13
|
+
def blank?(object)
|
14
|
+
if object.is_a?(String)
|
15
|
+
object !~ /[^[:space:]]/
|
16
|
+
else
|
17
|
+
object.respond_to?(:empty?) ? object.empty? : !object
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def marked_for_destruction?(object)
|
22
|
+
return false unless object.respond_to?(:marked_for_destruction?)
|
23
|
+
|
24
|
+
object.marked_for_destruction?
|
25
|
+
end
|
26
|
+
|
27
|
+
def extract_options!(array)
|
28
|
+
if array.last.is_a?(Hash) && array.last.instance_of?(Hash)
|
29
|
+
array.pop
|
30
|
+
else
|
31
|
+
{}
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def symbolyze_keys(hash)
|
36
|
+
hash.keys.each_with_object({}) do |key, symbolyzed_hash|
|
37
|
+
symbolyzed_hash[key.to_sym] = hash[key]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def except(hash, *keys)
|
42
|
+
hash = hash.dup
|
43
|
+
keys.each { |key| hash.delete(key) }
|
44
|
+
hash
|
45
|
+
end
|
46
|
+
|
47
|
+
def slice(hash, *keys)
|
48
|
+
keys.each_with_object({}) do |key, sliced_hash|
|
49
|
+
sliced_hash[key] = hash[key]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def call_proc_or_method(base, proc_or_method, object = nil)
|
54
|
+
if proc_or_method.is_a?(Proc)
|
55
|
+
base.instance_exec(object, &proc_or_method)
|
56
|
+
else
|
57
|
+
base.send(proc_or_method, object)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
@@ -15,7 +15,7 @@ module RestMyCase
|
|
15
15
|
run_rollback_methods
|
16
16
|
run_final_methods
|
17
17
|
|
18
|
-
@trial_case.
|
18
|
+
@trial_case.should_abort = !@use_case_that_aborted.nil?
|
19
19
|
end
|
20
20
|
|
21
21
|
protected ######################## PROTECTED #############################
|
@@ -3,15 +3,19 @@ module RestMyCase
|
|
3
3
|
|
4
4
|
class Case
|
5
5
|
|
6
|
-
attr_accessor :use_cases, :
|
6
|
+
attr_accessor :use_cases, :should_abort
|
7
7
|
|
8
|
-
attr_reader :context, :defendant
|
8
|
+
attr_reader :context, :defendant, :last_ancestor, :use_case_classes
|
9
9
|
|
10
|
-
def initialize(use_case_classes, attributes)
|
11
|
-
@
|
12
|
-
@
|
13
|
-
@
|
14
|
-
@
|
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
|
15
|
+
end
|
16
|
+
|
17
|
+
def aborted
|
18
|
+
@should_abort || defendant.options[:should_abort]
|
15
19
|
end
|
16
20
|
|
17
21
|
protected ######################## PROTECTED #############################
|
@@ -22,6 +26,12 @@ module RestMyCase
|
|
22
26
|
Context::Base.new attributes
|
23
27
|
end
|
24
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)
|
33
|
+
end
|
34
|
+
|
25
35
|
end
|
26
36
|
|
27
37
|
end
|
@@ -1,10 +1,10 @@
|
|
1
1
|
module RestMyCase
|
2
2
|
module Trial
|
3
3
|
|
4
|
-
Court = Struct.new(:judge_class, :defense_attorney_class) do
|
4
|
+
Court = Struct.new(:judge_class, :defense_attorney_class, :last_ancestor) do
|
5
5
|
|
6
6
|
def execute(use_case_classes, attributes = {})
|
7
|
-
trial_case = Case.new(use_case_classes, attributes)
|
7
|
+
trial_case = Case.new(last_ancestor, use_case_classes, attributes)
|
8
8
|
|
9
9
|
defense_attorney_class.new(trial_case).build_case_for_the_defendant
|
10
10
|
|
@@ -0,0 +1,82 @@
|
|
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
|
@@ -0,0 +1,58 @@
|
|
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
|
@@ -0,0 +1,366 @@
|
|
1
|
+
module RestMyCase
|
2
|
+
module Validator
|
3
|
+
|
4
|
+
class Errors
|
5
|
+
include Enumerable
|
6
|
+
|
7
|
+
CALLBACKS_OPTIONS = [:if, :unless, :on, :allow_nil, :allow_blank, :strict]
|
8
|
+
|
9
|
+
attr_reader :messages
|
10
|
+
|
11
|
+
# Pass in the instance of the object that is using the errors object.
|
12
|
+
#
|
13
|
+
# class Person
|
14
|
+
# def initialize
|
15
|
+
# @errors = ActiveModel::Errors.new(self)
|
16
|
+
# end
|
17
|
+
# end
|
18
|
+
def initialize(base)
|
19
|
+
@base = base
|
20
|
+
@messages = {}
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize_dup(other) # :nodoc:
|
24
|
+
@messages = other.messages.dup
|
25
|
+
super
|
26
|
+
end
|
27
|
+
|
28
|
+
# Clear the error messages.
|
29
|
+
#
|
30
|
+
# person.errors.full_messages # => ["name can not be nil"]
|
31
|
+
# person.errors.clear
|
32
|
+
# person.errors.full_messages # => []
|
33
|
+
def clear
|
34
|
+
messages.clear
|
35
|
+
end
|
36
|
+
|
37
|
+
# Returns +true+ if the error messages include an error for the given key
|
38
|
+
# +attribute+, +false+ otherwise.
|
39
|
+
#
|
40
|
+
# person.errors.messages # => {:name=>["can not be nil"]}
|
41
|
+
# person.errors.include?(:name) # => true
|
42
|
+
# person.errors.include?(:age) # => false
|
43
|
+
def include?(attribute)
|
44
|
+
(v = messages[attribute]) && v.any?
|
45
|
+
end
|
46
|
+
# aliases include?
|
47
|
+
alias :has_key? :include?
|
48
|
+
|
49
|
+
# Get messages for +key+.
|
50
|
+
#
|
51
|
+
# person.errors.messages # => {:name=>["can not be nil"]}
|
52
|
+
# person.errors.get(:name) # => ["can not be nil"]
|
53
|
+
# person.errors.get(:age) # => nil
|
54
|
+
def get(key)
|
55
|
+
messages[key]
|
56
|
+
end
|
57
|
+
|
58
|
+
# Set messages for +key+ to +value+.
|
59
|
+
#
|
60
|
+
# person.errors.get(:name) # => ["can not be nil"]
|
61
|
+
# person.errors.set(:name, ["can't be nil"])
|
62
|
+
# person.errors.get(:name) # => ["can't be nil"]
|
63
|
+
def set(key, value)
|
64
|
+
messages[key] = value
|
65
|
+
end
|
66
|
+
|
67
|
+
# Delete messages for +key+. Returns the deleted messages.
|
68
|
+
#
|
69
|
+
# person.errors.get(:name) # => ["can not be nil"]
|
70
|
+
# person.errors.delete(:name) # => ["can not be nil"]
|
71
|
+
# person.errors.get(:name) # => nil
|
72
|
+
def delete(key)
|
73
|
+
messages.delete(key)
|
74
|
+
end
|
75
|
+
|
76
|
+
# When passed a symbol or a name of a method, returns an array of errors
|
77
|
+
# for the method.
|
78
|
+
#
|
79
|
+
# person.errors[:name] # => ["can not be nil"]
|
80
|
+
# person.errors['name'] # => ["can not be nil"]
|
81
|
+
def [](attribute)
|
82
|
+
get(attribute.to_sym) || set(attribute.to_sym, [])
|
83
|
+
end
|
84
|
+
|
85
|
+
# Adds to the supplied attribute the supplied error message.
|
86
|
+
#
|
87
|
+
# person.errors[:name] = "must be set"
|
88
|
+
# person.errors[:name] # => ['must be set']
|
89
|
+
def []=(attribute, error)
|
90
|
+
self[attribute] << error
|
91
|
+
end
|
92
|
+
|
93
|
+
# Iterates through each error key, value pair in the error messages hash.
|
94
|
+
# Yields the attribute and the error for that attribute. If the attribute
|
95
|
+
# has more than one error message, yields once for each error message.
|
96
|
+
#
|
97
|
+
# person.errors.add(:name, "can't be blank")
|
98
|
+
# person.errors.each do |attribute, error|
|
99
|
+
# # Will yield :name and "can't be blank"
|
100
|
+
# end
|
101
|
+
#
|
102
|
+
# person.errors.add(:name, "must be specified")
|
103
|
+
# person.errors.each do |attribute, error|
|
104
|
+
# # Will yield :name and "can't be blank"
|
105
|
+
# # then yield :name and "must be specified"
|
106
|
+
# end
|
107
|
+
def each
|
108
|
+
messages.each_key do |attribute|
|
109
|
+
self[attribute].each { |error| yield attribute, error }
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
# Returns the number of error messages.
|
114
|
+
#
|
115
|
+
# person.errors.add(:name, "can't be blank")
|
116
|
+
# person.errors.size # => 1
|
117
|
+
# person.errors.add(:name, "must be specified")
|
118
|
+
# person.errors.size # => 2
|
119
|
+
def size
|
120
|
+
values.flatten.size
|
121
|
+
end
|
122
|
+
|
123
|
+
# Returns all message values.
|
124
|
+
#
|
125
|
+
# person.errors.messages # => {:name=>["can not be nil", "must be specified"]}
|
126
|
+
# person.errors.values # => [["can not be nil", "must be specified"]]
|
127
|
+
def values
|
128
|
+
messages.values
|
129
|
+
end
|
130
|
+
|
131
|
+
# Returns all message keys.
|
132
|
+
#
|
133
|
+
# person.errors.messages # => {:name=>["can not be nil", "must be specified"]}
|
134
|
+
# person.errors.keys # => [:name]
|
135
|
+
def keys
|
136
|
+
messages.keys
|
137
|
+
end
|
138
|
+
|
139
|
+
# Returns an array of error messages, with the attribute name included.
|
140
|
+
#
|
141
|
+
# person.errors.add(:name, "can't be blank")
|
142
|
+
# person.errors.add(:name, "must be specified")
|
143
|
+
# person.errors.to_a # => ["name can't be blank", "name must be specified"]
|
144
|
+
def to_a
|
145
|
+
full_messages
|
146
|
+
end
|
147
|
+
|
148
|
+
# Returns the number of error messages.
|
149
|
+
#
|
150
|
+
# person.errors.add(:name, "can't be blank")
|
151
|
+
# person.errors.count # => 1
|
152
|
+
# person.errors.add(:name, "must be specified")
|
153
|
+
# person.errors.count # => 2
|
154
|
+
def count
|
155
|
+
to_a.size
|
156
|
+
end
|
157
|
+
|
158
|
+
# Returns +true+ if no errors are found, +false+ otherwise.
|
159
|
+
# If the error message is a string it can be empty.
|
160
|
+
#
|
161
|
+
# person.errors.full_messages # => ["name can not be nil"]
|
162
|
+
# person.errors.empty? # => false
|
163
|
+
def empty?
|
164
|
+
all? { |k, v| v && v.empty? && !v.is_a?(String) }
|
165
|
+
end
|
166
|
+
# aliases empty?
|
167
|
+
alias_method :blank?, :empty?
|
168
|
+
|
169
|
+
# Returns an xml formatted representation of the Errors hash.
|
170
|
+
#
|
171
|
+
# person.errors.add(:name, "can't be blank")
|
172
|
+
# person.errors.add(:name, "must be specified")
|
173
|
+
# person.errors.to_xml
|
174
|
+
# # =>
|
175
|
+
# # <?xml version=\"1.0\" encoding=\"UTF-8\"?>
|
176
|
+
# # <errors>
|
177
|
+
# # <error>name can't be blank</error>
|
178
|
+
# # <error>name must be specified</error>
|
179
|
+
# # </errors>
|
180
|
+
def to_xml(options={})
|
181
|
+
to_a.to_xml({ root: "errors", skip_types: true }.merge!(options))
|
182
|
+
end
|
183
|
+
|
184
|
+
# Returns a Hash that can be used as the JSON representation for this
|
185
|
+
# object. You can pass the <tt>:full_messages</tt> option. This determines
|
186
|
+
# if the json object should contain full messages or not (false by default).
|
187
|
+
#
|
188
|
+
# person.as_json # => {:name=>["can not be nil"]}
|
189
|
+
# person.as_json(full_messages: true) # => {:name=>["name can not be nil"]}
|
190
|
+
def as_json(options=nil)
|
191
|
+
to_hash(options && options[:full_messages])
|
192
|
+
end
|
193
|
+
|
194
|
+
# Returns a Hash of attributes with their error messages. If +full_messages+
|
195
|
+
# is +true+, it will contain full messages (see +full_message+).
|
196
|
+
#
|
197
|
+
# person.to_hash # => {:name=>["can not be nil"]}
|
198
|
+
# person.to_hash(true) # => {:name=>["name can not be nil"]}
|
199
|
+
def to_hash(full_messages = false)
|
200
|
+
if full_messages
|
201
|
+
messages = {}
|
202
|
+
self.messages.each do |attribute, array|
|
203
|
+
messages[attribute] = array.map { |message| full_message(attribute, message) }
|
204
|
+
end
|
205
|
+
messages
|
206
|
+
else
|
207
|
+
self.messages.dup
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
# Adds +message+ to the error messages on +attribute+. More than one error
|
212
|
+
# can be added to the same +attribute+. If no +message+ is supplied,
|
213
|
+
# <tt>:invalid</tt> is assumed.
|
214
|
+
#
|
215
|
+
# person.errors.add(:name)
|
216
|
+
# # => ["is invalid"]
|
217
|
+
# person.errors.add(:name, 'must be implemented')
|
218
|
+
# # => ["is invalid", "must be implemented"]
|
219
|
+
#
|
220
|
+
# person.errors.messages
|
221
|
+
# # => {:name=>["must be implemented", "is invalid"]}
|
222
|
+
#
|
223
|
+
# If +message+ is a symbol, it will be translated using the appropriate
|
224
|
+
# scope (see +generate_message+).
|
225
|
+
#
|
226
|
+
# If +message+ is a proc, it will be called, allowing for things like
|
227
|
+
# <tt>Time.now</tt> to be used within an error.
|
228
|
+
#
|
229
|
+
# person.errors.messages # => {}
|
230
|
+
def add(attribute, message = nil, options = {})
|
231
|
+
message = normalize_message(attribute, message, options)
|
232
|
+
self[attribute] << message
|
233
|
+
end
|
234
|
+
|
235
|
+
# Returns +true+ if an error on the attribute with the given message is
|
236
|
+
# present, +false+ otherwise. +message+ is treated the same as for +add+.
|
237
|
+
#
|
238
|
+
# person.errors.add :name, :blank
|
239
|
+
# person.errors.added? :name, :blank # => true
|
240
|
+
def added?(attribute, message = nil, options = {})
|
241
|
+
message = normalize_message(attribute, message, options)
|
242
|
+
self[attribute].include? message
|
243
|
+
end
|
244
|
+
|
245
|
+
# Returns all the full error messages in an array.
|
246
|
+
#
|
247
|
+
# class Person
|
248
|
+
# validates_presence_of :name, :address, :email
|
249
|
+
# validates_length_of :name, in: 5..30
|
250
|
+
# end
|
251
|
+
#
|
252
|
+
# person = Person.create(address: '123 First St.')
|
253
|
+
# person.errors.full_messages
|
254
|
+
# # => ["Name is too short (minimum is 5 characters)", "Name can't be blank", "Email can't be blank"]
|
255
|
+
def full_messages
|
256
|
+
map { |attribute, message| full_message(attribute, message) }
|
257
|
+
end
|
258
|
+
|
259
|
+
# Returns all the full error messages for a given attribute in an array.
|
260
|
+
#
|
261
|
+
# class Person
|
262
|
+
# validates_presence_of :name, :email
|
263
|
+
# validates_length_of :name, in: 5..30
|
264
|
+
# end
|
265
|
+
#
|
266
|
+
# person = Person.create()
|
267
|
+
# person.errors.full_messages_for(:name)
|
268
|
+
# # => ["Name is too short (minimum is 5 characters)", "Name can't be blank"]
|
269
|
+
def full_messages_for(attribute)
|
270
|
+
(get(attribute) || []).map { |message| full_message(attribute, message) }
|
271
|
+
end
|
272
|
+
|
273
|
+
# Returns a full message for a given attribute.
|
274
|
+
#
|
275
|
+
# person.errors.full_message(:name, 'is invalid') # => "Name is invalid"
|
276
|
+
def full_message(attribute, message)
|
277
|
+
return message if attribute == :base || !@base.class.respond_to?(:model_name)
|
278
|
+
|
279
|
+
attr_name = attribute.to_s.tr('.', '_').humanize
|
280
|
+
attr_name = @base.class.human_attribute_name(attribute, default: attr_name)
|
281
|
+
I18n.t(:"errors.format", {
|
282
|
+
default: "%{attribute} %{message}",
|
283
|
+
attribute: attr_name,
|
284
|
+
message: message
|
285
|
+
})
|
286
|
+
end
|
287
|
+
|
288
|
+
# Translates an error message in its default scope
|
289
|
+
# (<tt>activemodel.errors.messages</tt>).
|
290
|
+
#
|
291
|
+
# Error messages are first looked up in <tt>models.MODEL.attributes.ATTRIBUTE.MESSAGE</tt>,
|
292
|
+
# if it's not there, it's looked up in <tt>models.MODEL.MESSAGE</tt> and if
|
293
|
+
# that is not there also, it returns the translation of the default message
|
294
|
+
# (e.g. <tt>activemodel.errors.messages.MESSAGE</tt>). The translated model
|
295
|
+
# name, translated attribute name and the value are available for
|
296
|
+
# interpolation.
|
297
|
+
#
|
298
|
+
# When using inheritance in your models, it will check all the inherited
|
299
|
+
# models too, but only if the model itself hasn't been found. Say you have
|
300
|
+
# <tt>class Admin < User; end</tt> and you wanted the translation for
|
301
|
+
# the <tt>:blank</tt> error message for the <tt>title</tt> attribute,
|
302
|
+
# it looks for these translations:
|
303
|
+
#
|
304
|
+
# * <tt>activemodel.errors.models.admin.attributes.title.blank</tt>
|
305
|
+
# * <tt>activemodel.errors.models.admin.blank</tt>
|
306
|
+
# * <tt>activemodel.errors.models.user.attributes.title.blank</tt>
|
307
|
+
# * <tt>activemodel.errors.models.user.blank</tt>
|
308
|
+
# * any default you provided through the +options+ hash (in the <tt>activemodel.errors</tt> scope)
|
309
|
+
# * <tt>activemodel.errors.messages.blank</tt>
|
310
|
+
# * <tt>errors.attributes.title.blank</tt>
|
311
|
+
# * <tt>errors.messages.blank</tt>
|
312
|
+
def generate_message(attribute, type = :invalid, options = {})
|
313
|
+
type = options.delete(:message) if options[:message].is_a?(Symbol)
|
314
|
+
|
315
|
+
if !@base.class.respond_to?(:model_name)
|
316
|
+
return options.key?(:message) ? options[:message] : type
|
317
|
+
end
|
318
|
+
|
319
|
+
if @base.class.respond_to?(:i18n_scope)
|
320
|
+
defaults = @base.class.lookup_ancestors.map do |klass|
|
321
|
+
[ :"#{@base.class.i18n_scope}.errors.models.#{klass.model_name.i18n_key}.attributes.#{attribute}.#{type}",
|
322
|
+
:"#{@base.class.i18n_scope}.errors.models.#{klass.model_name.i18n_key}.#{type}" ]
|
323
|
+
end
|
324
|
+
else
|
325
|
+
defaults = []
|
326
|
+
end
|
327
|
+
|
328
|
+
defaults << options.delete(:message)
|
329
|
+
defaults << :"#{@base.class.i18n_scope}.errors.messages.#{type}" if @base.class.respond_to?(:i18n_scope)
|
330
|
+
defaults << :"errors.attributes.#{attribute}.#{type}"
|
331
|
+
defaults << :"errors.messages.#{type}"
|
332
|
+
|
333
|
+
defaults.compact!
|
334
|
+
defaults.flatten!
|
335
|
+
|
336
|
+
key = defaults.shift
|
337
|
+
value = (attribute != :base ? @base.send(attribute) : nil)
|
338
|
+
|
339
|
+
options = {
|
340
|
+
default: defaults,
|
341
|
+
model: @base.class.model_name.human,
|
342
|
+
attribute: @base.class.human_attribute_name(attribute),
|
343
|
+
value: value
|
344
|
+
}.merge!(options)
|
345
|
+
|
346
|
+
I18n.translate(key, options)
|
347
|
+
end
|
348
|
+
|
349
|
+
private
|
350
|
+
def normalize_message(attribute, message, options)
|
351
|
+
message ||= :invalid
|
352
|
+
|
353
|
+
case message
|
354
|
+
when Symbol
|
355
|
+
generate_message(attribute, message, Helpers.except(options, *CALLBACKS_OPTIONS))
|
356
|
+
when Proc
|
357
|
+
message.call
|
358
|
+
else
|
359
|
+
message
|
360
|
+
end
|
361
|
+
end
|
362
|
+
|
363
|
+
end
|
364
|
+
|
365
|
+
end
|
366
|
+
end
|
data/lib/rest_my_case/version.rb
CHANGED
@@ -295,7 +295,7 @@ describe RestMyCase::Base do
|
|
295
295
|
it "context prove that only the correct method have ran" do
|
296
296
|
expect(@context.setup.length).to be 7
|
297
297
|
expect(@context.perform.length).to be 7
|
298
|
-
expect(@context.rollback.length).to be
|
298
|
+
expect(@context.rollback.length).to be 0
|
299
299
|
expect(@context.final.length).to be 7
|
300
300
|
end
|
301
301
|
|
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
describe RestMyCase::DefenseAttorney::Base do
|
4
4
|
|
5
5
|
let(:use_cases) do
|
6
|
-
trial_case = RestMyCase::Trial::Case.new(use_case_classes, id: 1)
|
6
|
+
trial_case = RestMyCase::Trial::Case.new(RestMyCase::Base, use_case_classes, id: 1)
|
7
7
|
|
8
8
|
described_class.new(trial_case).build_case_for_the_defendant
|
9
9
|
|
@@ -4,12 +4,14 @@ describe RestMyCase::Trial::Court do
|
|
4
4
|
|
5
5
|
context "When using Judge::Base and DefenseAttorney::Base" do
|
6
6
|
before do
|
7
|
-
@
|
7
|
+
@use_case_class = Class.new(RestMyCase::Base)
|
8
|
+
@trial_court = described_class.new \
|
9
|
+
RestMyCase::Judge::Base, RestMyCase::DefenseAttorney::Base, RestMyCase::Base
|
8
10
|
end
|
9
11
|
|
10
12
|
context "When something that responds to #to_hash is passed down" do
|
11
13
|
|
12
|
-
let(:context) { @trial_court.execute([
|
14
|
+
let(:context) { @trial_court.execute([@use_case_class], id: 1, name: '2').context }
|
13
15
|
|
14
16
|
it "should create a context with it" do
|
15
17
|
expect(context).to be_a RestMyCase::Context::Base
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Testing hierarchy capabilities' do
|
4
|
+
|
5
|
+
it "HierarchyValidation::Son should be able to inherit Father's validations and alter them" do
|
6
|
+
# post_for_father = RubyPost.new
|
7
|
+
# father_context = HierarchyValidation::Father.perform(post: post_for_father)
|
8
|
+
|
9
|
+
# expect(father_context.ok?).to be false
|
10
|
+
# expect(post_for_father.errors.added?(:title, :blank)).to be true
|
11
|
+
# expect(post_for_father.errors.size).to be 1
|
12
|
+
|
13
|
+
post_for_son = RubyPost.new
|
14
|
+
son_context = HierarchyValidation::Son.perform(post: post_for_son)
|
15
|
+
|
16
|
+
expect(son_context.ok?).to be false
|
17
|
+
expect(post_for_son.errors.added?(:title, :blank)).to be true
|
18
|
+
expect(post_for_son.errors.added?(:email, :blank)).to be true
|
19
|
+
expect(post_for_son.errors.size).to be 2
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
@@ -0,0 +1,28 @@
|
|
1
|
+
class RubyPostWithComments
|
2
|
+
|
3
|
+
class RubyComment
|
4
|
+
|
5
|
+
attr_accessor :title, :email, :post_id
|
6
|
+
|
7
|
+
def initialize(attributes = {})
|
8
|
+
(attributes || {}).each { |name, value| send("#{name}=", value) }
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
attr_reader :comments
|
15
|
+
|
16
|
+
def initialize(comments = {})
|
17
|
+
@comments = comments.map { |comment| RubyComment.new(comment) }
|
18
|
+
@comments = [] if @comments.nil?
|
19
|
+
end
|
20
|
+
|
21
|
+
def first_two_comments
|
22
|
+
[
|
23
|
+
comments[0],
|
24
|
+
comments[1]
|
25
|
+
]
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
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.
|
4
|
+
version: 1.7.0
|
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-
|
11
|
+
date: 2015-04-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pry
|
@@ -112,25 +112,37 @@ files:
|
|
112
112
|
- Rakefile
|
113
113
|
- console
|
114
114
|
- lib/rest_my_case.rb
|
115
|
+
- lib/rest_my_case/accusation_attorneys/base.rb
|
116
|
+
- lib/rest_my_case/accusation_attorneys/custom.rb
|
117
|
+
- lib/rest_my_case/accusation_attorneys/each.rb
|
118
|
+
- lib/rest_my_case/accusation_attorneys/helper_methods.rb
|
119
|
+
- lib/rest_my_case/accusation_attorneys/presence.rb
|
115
120
|
- lib/rest_my_case/base.rb
|
116
121
|
- lib/rest_my_case/config/base.rb
|
117
122
|
- lib/rest_my_case/config/general.rb
|
118
123
|
- lib/rest_my_case/context/base.rb
|
119
124
|
- lib/rest_my_case/defense_attorney/base.rb
|
120
125
|
- lib/rest_my_case/errors.rb
|
126
|
+
- lib/rest_my_case/helpers.rb
|
121
127
|
- lib/rest_my_case/judge/base.rb
|
122
128
|
- lib/rest_my_case/trial/case.rb
|
123
129
|
- lib/rest_my_case/trial/court.rb
|
124
|
-
- lib/rest_my_case/
|
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
|
125
133
|
- lib/rest_my_case/version.rb
|
126
134
|
- rest_my_case.gemspec
|
127
135
|
- spec/rest_my_case/base_spec.rb
|
128
136
|
- spec/rest_my_case/defense_attorney/base_spec.rb
|
129
137
|
- spec/rest_my_case/trial_case/court_spec.rb
|
138
|
+
- spec/rest_my_case/validator/hierarchy_spec.rb
|
130
139
|
- spec/spec_helper.rb
|
131
140
|
- spec/support/defense_attorney.rb
|
132
141
|
- spec/support/perform.rb
|
133
142
|
- spec/support/rest_my_case_base.rb
|
143
|
+
- spec/support/validator/models/ruby_post.rb
|
144
|
+
- spec/support/validator/models/ruby_post_with_comments.rb
|
145
|
+
- spec/support/validator/usecases/hierarchy_validation.rb
|
134
146
|
homepage: https://github.com/goncalvesjoao/rest_my_case
|
135
147
|
licenses:
|
136
148
|
- MIT
|
@@ -159,7 +171,11 @@ test_files:
|
|
159
171
|
- spec/rest_my_case/base_spec.rb
|
160
172
|
- spec/rest_my_case/defense_attorney/base_spec.rb
|
161
173
|
- spec/rest_my_case/trial_case/court_spec.rb
|
174
|
+
- spec/rest_my_case/validator/hierarchy_spec.rb
|
162
175
|
- spec/spec_helper.rb
|
163
176
|
- spec/support/defense_attorney.rb
|
164
177
|
- spec/support/perform.rb
|
165
178
|
- spec/support/rest_my_case_base.rb
|
179
|
+
- spec/support/validator/models/ruby_post.rb
|
180
|
+
- spec/support/validator/models/ruby_post_with_comments.rb
|
181
|
+
- spec/support/validator/usecases/hierarchy_validation.rb
|