rest_my_case 1.6.0 → 1.7.0
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 +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
|