This repository has been archived by the owner on Apr 17, 2018. It is now read-only.
/
violation_set.rb
115 lines (96 loc) · 3.2 KB
/
violation_set.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
require 'data_mapper/validation/support/ordered_hash'
require 'data_mapper/validation/violation'
module DataMapper
module Validation
class ViolationSet
include Enumerable
# @api private
attr_reader :resource
# @api private
attr_reader :violations
# TODO: why was this private?
private :violations
# TODO: replace OrderedHash with OrderedSet and remove vendor'd OrderedHash
def initialize(resource)
@resource = resource
@violations = OrderedHash.new { |h,k| h[k] = [] }
end
# Clear existing validation violations.
#
# @api public
def clear
violations.clear
end
# Add a validation error. Use the attribute_name :general if the violations
# does not apply to a specific field of the Resource.
#
# @param [Symbol, Violation] attribute_name_or_violation
# The name of the field that caused the violation, or
# the Violation which describes the validation violation
# @param [NilClass, String, #call, Hash] message
# The message to add.
#
# @see Violation#initialize
#
# @api public
def add(attribute_name_or_violation, message = nil)
violation =
if attribute_name_or_violation.kind_of?(Violation)
attribute_name_or_violation
else
Violation.new(resource, message, nil, attribute_name_or_violation)
end
violations[violation.attribute_name] << violation
end
# Collect all violations into a single list.
#
# @api public
def full_messages
violations.inject([]) do |list, (attribute_name, violations)|
messages = violations
messages = violations.full_messages if violations.respond_to?(:full_messages)
list += messages
end
end
# Return validation violations for a particular attribute_name.
#
# @param [Symbol] attribute_name
# The name of the field you want an violation for.
#
# @return [Array(Violation, String), NilClass]
# Array of Violations, if there are violations on +attribute_name+
# nil if there are no violations on +attribute_name+
#
# @api public
#
# TODO: use a data structure that ensures uniqueness
def on(attribute_name)
attribute_violations = violations[attribute_name]
attribute_violations.empty? ? nil : attribute_violations.uniq
end
# @api public
def each
violations.each_value do |v|
yield(v) unless DataMapper::Ext.blank?(v)
end
end
# @api public
def empty?
violations.all? { |attribute_name, violations| violations.empty? }
end
# @api public
#
# FIXME: calling #to_sym on uncontrolled input is an
# invitation for a memory leak
def [](attribute_name)
violations[attribute_name.to_sym]
end
def method_missing(meth, *args, &block)
violations.send(meth, *args, &block)
end
def respond_to?(method)
super || violations.respond_to?(method)
end
end # class ViolationSet
end # module Validation
end # module DataMapper