servi 1.0.0 → 1.0.1
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/lib/servi/validations.rb +206 -0
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d709873b6eb803abba6738c857dc91ab3f5db58b
|
4
|
+
data.tar.gz: 65fc977b2f68056312576f5354e4990d16862c18
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bc3671d343c2fc906ad0e72f43348eca4298b6f128ff6dcf588b00f060fe170ec1ccbcee6fc1042cb9501edc5efb84b8d3c590e7d5c175d1481706c5288ef517
|
7
|
+
data.tar.gz: 1018746b84bfa01ecba75849adbbaf71c3709394d5c6ac764758e32fa8dcbd0dc499f0578893d9e2826b58cd06a4e2e732094ca93cd2ae4d6da9fce73d46775c
|
@@ -0,0 +1,206 @@
|
|
1
|
+
class Servi
|
2
|
+
|
3
|
+
# Provides a base implementation for extensible validation routines.
|
4
|
+
# {Scrivener::Validations} currently only provides the following assertions:
|
5
|
+
#
|
6
|
+
# * assert
|
7
|
+
# * assert_present
|
8
|
+
# * assert_format
|
9
|
+
# * assert_numeric
|
10
|
+
# * assert_url
|
11
|
+
# * assert_email
|
12
|
+
# * assert_member
|
13
|
+
# * assert_length
|
14
|
+
# * assert_decimal
|
15
|
+
# * assert_equal
|
16
|
+
#
|
17
|
+
# The core tenets that Scrivener::Validations advocates can be summed up in a
|
18
|
+
# few bullet points:
|
19
|
+
#
|
20
|
+
# 1. Validations are much simpler and better done using composition rather
|
21
|
+
# than macros.
|
22
|
+
# 2. Error messages should be kept separate and possibly in the view or
|
23
|
+
# presenter layer.
|
24
|
+
# 3. It should be easy to write your own validation routine.
|
25
|
+
#
|
26
|
+
# Other validations are simply added on a per-model or per-project basis.
|
27
|
+
#
|
28
|
+
# @example
|
29
|
+
#
|
30
|
+
# class Quote
|
31
|
+
# attr_accessor :title
|
32
|
+
# attr_accessor :price
|
33
|
+
# attr_accessor :date
|
34
|
+
#
|
35
|
+
# def validate
|
36
|
+
# assert_present :title
|
37
|
+
# assert_numeric :price
|
38
|
+
# assert_format :date, /\A[\d]{4}-[\d]{1,2}-[\d]{1,2}\z
|
39
|
+
# end
|
40
|
+
# end
|
41
|
+
#
|
42
|
+
# s = Quote.new
|
43
|
+
# s.valid?
|
44
|
+
# # => false
|
45
|
+
#
|
46
|
+
# s.errors
|
47
|
+
# # => { :title => [:not_present],
|
48
|
+
# :price => [:not_numeric],
|
49
|
+
# :date => [:format] }
|
50
|
+
#
|
51
|
+
module Validations
|
52
|
+
|
53
|
+
# Check if the current model state is valid. Each call to {#valid?} will
|
54
|
+
# reset the {#errors} array.
|
55
|
+
#
|
56
|
+
# All validations should be declared in a `validate` method.
|
57
|
+
#
|
58
|
+
# @example
|
59
|
+
#
|
60
|
+
# class Login
|
61
|
+
# attr_accessor :username
|
62
|
+
# attr_accessor :password
|
63
|
+
#
|
64
|
+
# def validate
|
65
|
+
# assert_present :user
|
66
|
+
# assert_present :password
|
67
|
+
# end
|
68
|
+
# end
|
69
|
+
#
|
70
|
+
def valid?
|
71
|
+
errors.clear
|
72
|
+
validate
|
73
|
+
errors.empty?
|
74
|
+
end
|
75
|
+
|
76
|
+
# Base validate implementation. Override this method in subclasses.
|
77
|
+
def validate
|
78
|
+
end
|
79
|
+
|
80
|
+
# Hash of errors for each attribute in this model.
|
81
|
+
def errors
|
82
|
+
@errors ||= Hash.new { |hash, key| hash[key] = [] }
|
83
|
+
end
|
84
|
+
|
85
|
+
protected
|
86
|
+
|
87
|
+
# Allows you to do a validation check against a regular expression.
|
88
|
+
# It's important to note that this internally calls {#assert_present},
|
89
|
+
# therefore you need not structure your regular expression to check
|
90
|
+
# for a non-empty value.
|
91
|
+
#
|
92
|
+
# @param [Symbol] att The attribute you want to verify the format of.
|
93
|
+
# @param [Regexp] format The regular expression with which to compare
|
94
|
+
# the value of att with.
|
95
|
+
# @param [Array<Symbol, Symbol>] error The error that should be returned
|
96
|
+
# when the validation fails.
|
97
|
+
def assert_format(att, format, error = [att, :format])
|
98
|
+
if assert_present(att, error)
|
99
|
+
assert(get(att).to_s.match(format), error)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# The most basic and highly useful assertion. Simply checks if the
|
104
|
+
# value of the attribute is empty.
|
105
|
+
#
|
106
|
+
# @param [Symbol] att The attribute you wish to verify the presence of.
|
107
|
+
# @param [Array<Symbol, Symbol>] error The error that should be returned
|
108
|
+
# when the validation fails.
|
109
|
+
def assert_present(att, error = [att, :not_present])
|
110
|
+
assert(!get(att).to_s.empty?, error)
|
111
|
+
end
|
112
|
+
|
113
|
+
# Checks if all the characters of an attribute is a digit.
|
114
|
+
#
|
115
|
+
# @param [Symbol] att The attribute you wish to verify the numeric format.
|
116
|
+
# @param [Array<Symbol, Symbol>] error The error that should be returned
|
117
|
+
# when the validation fails.
|
118
|
+
def assert_numeric(att, error = [att, :not_numeric])
|
119
|
+
if assert_present(att, error)
|
120
|
+
assert_format(att, /\A\-?\d+\z/, error)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
URL = /\A(http|https):\/\/([a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,12}|(2
|
125
|
+
5[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}
|
126
|
+
|localhost)(:[0-9]{1,5})?(\/.*)?\z/ix
|
127
|
+
|
128
|
+
def assert_url(att, error = [att, :not_url])
|
129
|
+
if assert_present(att, error)
|
130
|
+
assert_format(att, URL, error)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
EMAIL = /\A([\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+\.)*
|
135
|
+
[\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+@
|
136
|
+
((((([a-z0-9]{1}[a-z0-9\-]{0,62}[a-z0-9]{1})|[a-z])\.)+
|
137
|
+
[a-z]{2,12})|(\d{1,3}\.){3}\d{1,3}(\:\d{1,5})?)\z/ix
|
138
|
+
|
139
|
+
def assert_email(att, error = [att, :not_email])
|
140
|
+
if assert_present(att, error)
|
141
|
+
assert_format(att, EMAIL, error)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def assert_member(att, set, err = [att, :not_valid])
|
146
|
+
assert(set.include?(get(att)), err)
|
147
|
+
end
|
148
|
+
|
149
|
+
def assert_length(att, range, error = [att, :not_in_range])
|
150
|
+
if assert_present(att, error)
|
151
|
+
val = get(att).to_s
|
152
|
+
assert range.include?(val.length), error
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
DECIMAL = /\A\-?(\d+)?(\.\d+)?\z/
|
157
|
+
|
158
|
+
def assert_decimal(att, error = [att, :not_decimal])
|
159
|
+
assert_format att, DECIMAL, error
|
160
|
+
end
|
161
|
+
|
162
|
+
# Check that the attribute has the expected value. It uses === for
|
163
|
+
# comparison, so type checks are possible too. Note that in order
|
164
|
+
# to make the case equality work, the check inverts the order of
|
165
|
+
# the arguments: `assert_equal :foo, Bar` is translated to the
|
166
|
+
# expression `Bar === get(:foo)`.
|
167
|
+
#
|
168
|
+
# @example
|
169
|
+
#
|
170
|
+
# def validate
|
171
|
+
# assert_equal :status, "pending"
|
172
|
+
# assert_equal :quantity, Fixnum
|
173
|
+
# end
|
174
|
+
#
|
175
|
+
# @param [Symbol] att The attribute you wish to verify for equality.
|
176
|
+
# @param [Object] value The value you want to test against.
|
177
|
+
# @param [Array<Symbol, Symbol>] error The error that should be returned
|
178
|
+
# when the validation fails.
|
179
|
+
def assert_equal(att, value, error = [att, :not_equal])
|
180
|
+
assert value === get(att), error
|
181
|
+
end
|
182
|
+
|
183
|
+
# The grand daddy of all assertions. If you want to build custom
|
184
|
+
# assertions, or even quick and dirty ones, you can simply use this method.
|
185
|
+
#
|
186
|
+
# @example
|
187
|
+
#
|
188
|
+
# class CreatePost
|
189
|
+
# attr_accessor :slug
|
190
|
+
# attr_accessor :votes
|
191
|
+
#
|
192
|
+
# def validate
|
193
|
+
# assert_slug :slug
|
194
|
+
# assert votes.to_i > 0, [:votes, :not_valid]
|
195
|
+
# end
|
196
|
+
#
|
197
|
+
# protected
|
198
|
+
# def assert_slug(att, error = [att, :not_slug])
|
199
|
+
# assert get(att).to_s =~ /\A[a-z\-0-9]+\z/, error
|
200
|
+
# end
|
201
|
+
# end
|
202
|
+
def assert(value, error)
|
203
|
+
value or errors[error.first].push(error.last) && false
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: servi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kevin Hanna
|
@@ -19,6 +19,7 @@ extensions: []
|
|
19
19
|
extra_rdoc_files: []
|
20
20
|
files:
|
21
21
|
- lib/servi.rb
|
22
|
+
- lib/servi/validations.rb
|
22
23
|
homepage: http://github.com/kevinjhanna/servi
|
23
24
|
licenses:
|
24
25
|
- MIT
|