servi 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/servi/validations.rb +206 -0
  3. metadata +2 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6811acf7e53f4885c8132c0d83eded742bf588a7
4
- data.tar.gz: 9821e8dca4ce04e82cc3c491c5cdc7a2802416b0
3
+ metadata.gz: d709873b6eb803abba6738c857dc91ab3f5db58b
4
+ data.tar.gz: 65fc977b2f68056312576f5354e4990d16862c18
5
5
  SHA512:
6
- metadata.gz: 8ec854851433cf72b0d9036f93fbbef5b88616f25baefdfa4e709ae28a43bc1ef88a5e5587e047634d0e253bf8277bd0308597ceb34d82967290c25031bbf035
7
- data.tar.gz: 35432e25d98b66cf15dcfa21a24d1332083723a85660fc76774e680a48f662590580b08345ba25ef9cc148065f2d97a73358efcffe4c018e30359d4607154ca0
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.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