ohm-contrib 0.1.2 → 1.0.rc0
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.
- data/lib/ohm/{contrib/callbacks.rb → callbacks.rb} +20 -65
- data/lib/ohm/contrib.rb +9 -17
- data/lib/ohm/datatypes.rb +38 -0
- data/lib/ohm/{contrib/locking.rb → locking.rb} +1 -2
- data/lib/ohm/plugin.rb +54 -0
- data/lib/ohm/{contrib/scope.rb → scope.rb} +7 -6
- data/lib/ohm/{contrib/slug.rb → slug.rb} +11 -6
- data/lib/ohm/{contrib/soft_delete.rb → softdelete.rb} +23 -19
- data/lib/ohm/timestamping.rb +41 -0
- data/ohm-contrib.gemspec +30 -0
- data/rakefile +6 -0
- data/test/{instance_callbacks_test.rb → instance_callbacks.rb} +2 -6
- data/test/{macro_callbacks_test.rb → macro_callbacks.rb} +1 -9
- data/test/plugin.rb +212 -0
- data/test/{scope_test.rb → scope.rb} +2 -3
- data/test/slug.rb +24 -0
- data/test/{soft_delete_test.rb → soft_delete.rb} +13 -3
- data/test/{timestamping_test.rb → timestamping.rb} +5 -6
- metadata +33 -70
- data/Rakefile +0 -8
- data/lib/ohm/contrib/active_model_extension.rb +0 -87
- data/lib/ohm/contrib/boundaries.rb +0 -41
- data/lib/ohm/contrib/date_validations.rb +0 -23
- data/lib/ohm/contrib/extra_validations.rb +0 -48
- data/lib/ohm/contrib/fulltext_searching.rb +0 -80
- data/lib/ohm/contrib/length_validations.rb +0 -32
- data/lib/ohm/contrib/number_validations.rb +0 -14
- data/lib/ohm/contrib/timestamping.rb +0 -38
- data/lib/ohm/contrib/typecast.rb +0 -350
- data/lib/ohm/contrib/web_validations.rb +0 -52
- data/test/activemodel_test.rb +0 -27
- data/test/boundaries_test.rb +0 -45
- data/test/callbacks_lint.rb +0 -141
- data/test/date_validations_test.rb +0 -29
- data/test/fixtures/ascii8bit.txt +0 -1
- data/test/fulltext_searching_test.rb +0 -63
- data/test/length_validations_test.rb +0 -31
- data/test/membership_validation_test.rb +0 -31
- data/test/number_validations_test.rb +0 -37
- data/test/slug_test.rb +0 -30
- data/test/typecast_array_test.rb +0 -146
- data/test/typecast_boolean_test.rb +0 -43
- data/test/typecast_date_test.rb +0 -82
- data/test/typecast_decimal_test.rb +0 -82
- data/test/typecast_existing_attribute_test.rb +0 -22
- data/test/typecast_float_test.rb +0 -57
- data/test/typecast_hash_test.rb +0 -120
- data/test/typecast_integer_test.rb +0 -71
- data/test/typecast_string_test.rb +0 -43
- data/test/typecast_time_test.rb +0 -72
- data/test/typecast_timezone_test.rb +0 -37
- data/test/web_validations_test.rb +0 -79
@@ -1,80 +0,0 @@
|
|
1
|
-
begin
|
2
|
-
require "text"
|
3
|
-
rescue LoadError
|
4
|
-
raise LoadError,
|
5
|
-
"Type `[sudo] gem install text` to use Ohm::FulltextSearching."
|
6
|
-
end
|
7
|
-
|
8
|
-
module Ohm
|
9
|
-
module FulltextSearching
|
10
|
-
def self.included(model)
|
11
|
-
model.extend ClassMethods
|
12
|
-
end
|
13
|
-
|
14
|
-
module ClassMethods
|
15
|
-
def search(hash)
|
16
|
-
find(hash_to_metaphones(hash))
|
17
|
-
end
|
18
|
-
|
19
|
-
def hash_to_metaphones(hash)
|
20
|
-
ret = Hash.new { |h, k| h[k] = [] }
|
21
|
-
|
22
|
-
hash.each do |att, string|
|
23
|
-
metaphones(string).each { |m| ret[:"fulltext_#{att}"] << m }
|
24
|
-
end
|
25
|
-
|
26
|
-
return ret
|
27
|
-
end
|
28
|
-
|
29
|
-
def double_metaphone(str)
|
30
|
-
return [] if STOPWORDS.include?(str.to_s.downcase)
|
31
|
-
|
32
|
-
Text::Metaphone.double_metaphone(str).compact
|
33
|
-
end
|
34
|
-
|
35
|
-
def metaphones(str)
|
36
|
-
str.to_s.strip.split(/\s+/).map { |s| double_metaphone(s) }.flatten
|
37
|
-
end
|
38
|
-
|
39
|
-
def fulltext(att)
|
40
|
-
field = :"fulltext_#{att}"
|
41
|
-
|
42
|
-
define_method(field) { self.class.metaphones(send(att)) }
|
43
|
-
index(field)
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
STOPWORDS = %w{a about above according across actually adj after
|
48
|
-
afterwards again against all almost alone along already also although
|
49
|
-
always among amongst an and another any anyhow anyone anything anywhere
|
50
|
-
are aren't around as at b be became because become becomes becoming
|
51
|
-
been before beforehand begin behind being below beside besides between
|
52
|
-
beyond both but by c can can't cannot caption co co. could couldn't d
|
53
|
-
did didn't do does doesn't don't down during e each eg eight eighty
|
54
|
-
either else elsewhere end ending enough etc even ever every everyone
|
55
|
-
everything everywhere except f few first for found from further g h
|
56
|
-
had has hasn't have haven't he he'd he'll he's hence her here here's
|
57
|
-
hereafter hereby herein hereupon hers herself him himself his how
|
58
|
-
however hundred i i'd i'll i'm i've ie if in inc. indeed instead into is
|
59
|
-
isn't it it's its itself j k l last later latter latterly least less let
|
60
|
-
let's like likely ltd m made make makes many maybe me meantime meanwhile
|
61
|
-
might miss more moreover most mostly mr mrs much must my myself n namely
|
62
|
-
neither never nevertheless next nine ninety no nobody none nonetheless
|
63
|
-
noone nor not nothing now nowhere o of off often on once one one's only
|
64
|
-
onto or other others otherwise our ours ourselves out over overall own
|
65
|
-
p per perhaps q r rather recent recently s same seem seemed seeming
|
66
|
-
seems seven several she she'd she'll she's should shouldn't since so
|
67
|
-
some somehow someone something sometime sometimes somewhere still such
|
68
|
-
t taking than that that'll that's that've the their them themselves then
|
69
|
-
thence there there'd there'll there're there's there've thereafter thereby
|
70
|
-
therefore therein thereupon these they they'd they'll they're they've
|
71
|
-
thirty this those though three through throughout thru thus to together
|
72
|
-
too toward towards u under unless unlike unlikely until up upon us used
|
73
|
-
using v very via w was wasn't we we'd we'll we're we've well were weren't
|
74
|
-
what what'll what's what've whatever when whence whenever where where's
|
75
|
-
whereafter whereas whereby wherein whereupon wherever whether which while
|
76
|
-
whither who who'd who'll who's whoever whole whom whomever whose why will
|
77
|
-
with within without won't would wouldn't x y yes yet you you'd you'll
|
78
|
-
you're you've your yours yourself yourselves z}
|
79
|
-
end
|
80
|
-
end
|
@@ -1,32 +0,0 @@
|
|
1
|
-
module Ohm
|
2
|
-
module LengthValidations
|
3
|
-
|
4
|
-
def assert_min_length(att, length, error = [att, :too_short])
|
5
|
-
if assert_present(att, error)
|
6
|
-
m = send(att).to_s
|
7
|
-
assert is_long_enough?(m, length), error
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
def assert_max_length(att, length, error = [att, :too_long])
|
12
|
-
if assert_present(att, error)
|
13
|
-
m = send(att).to_s
|
14
|
-
assert is_too_long?(m, length), error
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
private
|
19
|
-
def is_too_long?(string, length)
|
20
|
-
string.size <= length
|
21
|
-
rescue ArgumentError
|
22
|
-
return false
|
23
|
-
end
|
24
|
-
|
25
|
-
def is_long_enough?(string, length)
|
26
|
-
string.size >= length
|
27
|
-
rescue ArgumentError
|
28
|
-
return false
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
@@ -1,14 +0,0 @@
|
|
1
|
-
module Ohm
|
2
|
-
# This module will include all numeric validation needs.
|
3
|
-
# As of VERSION 0.0.27, Ohm::NumberValidations#assert_decimal
|
4
|
-
# is the only method provided.
|
5
|
-
module NumberValidations
|
6
|
-
DECIMAL_REGEX = /^(\d+)?(\.\d+)?$/
|
7
|
-
|
8
|
-
protected
|
9
|
-
def assert_decimal(att, error = [att, :not_decimal])
|
10
|
-
assert_format att, DECIMAL_REGEX, error
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
@@ -1,38 +0,0 @@
|
|
1
|
-
module Ohm
|
2
|
-
# Provides created_at / updated_at timestamps.
|
3
|
-
#
|
4
|
-
# @example
|
5
|
-
#
|
6
|
-
# class Post < Ohm::Model
|
7
|
-
# include Ohm::Timestamping
|
8
|
-
# end
|
9
|
-
#
|
10
|
-
# post = Post.create
|
11
|
-
# post.created_at.to_s == Time.now.utc.to_s
|
12
|
-
# # => true
|
13
|
-
#
|
14
|
-
# post = Post[post.id]
|
15
|
-
# post.save
|
16
|
-
# post.updated_at.to_s == Time.now.utc.to_s
|
17
|
-
# # => true
|
18
|
-
module Timestamping
|
19
|
-
def self.included(base)
|
20
|
-
base.attribute :created_at
|
21
|
-
base.attribute :updated_at
|
22
|
-
end
|
23
|
-
|
24
|
-
def create
|
25
|
-
self.created_at ||= Time.now.utc.to_s
|
26
|
-
|
27
|
-
super
|
28
|
-
end
|
29
|
-
|
30
|
-
protected
|
31
|
-
def write
|
32
|
-
self.updated_at = Time.now.utc.to_s
|
33
|
-
|
34
|
-
super
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
data/lib/ohm/contrib/typecast.rb
DELETED
@@ -1,350 +0,0 @@
|
|
1
|
-
require 'bigdecimal'
|
2
|
-
require 'time'
|
3
|
-
require 'date'
|
4
|
-
require 'forwardable'
|
5
|
-
require "json"
|
6
|
-
|
7
|
-
module Ohm
|
8
|
-
# Provides all the primitive types. The following are included:
|
9
|
-
#
|
10
|
-
# * String
|
11
|
-
# * Decimal
|
12
|
-
# * Integer
|
13
|
-
# * Float
|
14
|
-
# * Date
|
15
|
-
# * Time
|
16
|
-
# * Hash
|
17
|
-
# * Array
|
18
|
-
# * Boolean
|
19
|
-
module Types
|
20
|
-
def self.defined?(type)
|
21
|
-
@_constants ||= constants.map { |c| c.to_sym }
|
22
|
-
@_constants.include?(type.to_sym)
|
23
|
-
end
|
24
|
-
|
25
|
-
def self.[](type)
|
26
|
-
const_get(type.to_s.split('::').last)
|
27
|
-
end
|
28
|
-
|
29
|
-
class Base < BasicObject
|
30
|
-
class Exception < ::Exception; end
|
31
|
-
|
32
|
-
extend ::Forwardable
|
33
|
-
|
34
|
-
@@delegation_blacklist = [
|
35
|
-
:==, :to_s, :initialize, :inspect, :object_id, :__send__, :__id__,
|
36
|
-
:respond_to?
|
37
|
-
]
|
38
|
-
|
39
|
-
def self.[](value)
|
40
|
-
return empty if value.to_s.empty?
|
41
|
-
|
42
|
-
new(value)
|
43
|
-
end
|
44
|
-
|
45
|
-
def self.empty
|
46
|
-
defined?(self::RAW) ? self::RAW.new : nil
|
47
|
-
end
|
48
|
-
|
49
|
-
def self.delegate_to(klass, except = @@delegation_blacklist)
|
50
|
-
methods = klass.public_instance_methods.map { |e| e.to_sym } - except
|
51
|
-
def_delegators :object, *methods
|
52
|
-
end
|
53
|
-
|
54
|
-
def inspect
|
55
|
-
@raw.inspect
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
class Primitive < Base
|
60
|
-
def initialize(value)
|
61
|
-
@raw = value
|
62
|
-
end
|
63
|
-
|
64
|
-
def to_s
|
65
|
-
@raw.to_s
|
66
|
-
end
|
67
|
-
|
68
|
-
def ==(other)
|
69
|
-
to_s == other.to_s
|
70
|
-
end
|
71
|
-
|
72
|
-
def respond_to?(method)
|
73
|
-
object.respond_to?(method)
|
74
|
-
rescue ::ArgumentError
|
75
|
-
@raw.respond_to?(method)
|
76
|
-
end
|
77
|
-
|
78
|
-
def object
|
79
|
-
@raw
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
class String < Primitive
|
84
|
-
delegate_to ::String
|
85
|
-
|
86
|
-
def type
|
87
|
-
::String
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
class Decimal < Primitive
|
92
|
-
delegate_to ::BigDecimal
|
93
|
-
|
94
|
-
def object
|
95
|
-
::Kernel::BigDecimal(@raw)
|
96
|
-
end
|
97
|
-
|
98
|
-
def type
|
99
|
-
::BigDecimal
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
class Integer < Primitive
|
104
|
-
delegate_to ::Fixnum
|
105
|
-
|
106
|
-
def object
|
107
|
-
::Kernel::Integer(@raw)
|
108
|
-
end
|
109
|
-
|
110
|
-
def type
|
111
|
-
::Fixnum
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
class Float < Primitive
|
116
|
-
delegate_to ::Float
|
117
|
-
|
118
|
-
def object
|
119
|
-
::Kernel::Float(@raw)
|
120
|
-
end
|
121
|
-
|
122
|
-
def type
|
123
|
-
::Float
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
class Time < Primitive
|
128
|
-
delegate_to ::Time
|
129
|
-
|
130
|
-
def object
|
131
|
-
::Time.parse(@raw).utc
|
132
|
-
end
|
133
|
-
|
134
|
-
def type
|
135
|
-
::Time
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
class Date < Primitive
|
140
|
-
delegate_to ::Date
|
141
|
-
|
142
|
-
def object
|
143
|
-
::Date.parse(@raw)
|
144
|
-
end
|
145
|
-
|
146
|
-
def type
|
147
|
-
::Date
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
class Boolean
|
152
|
-
def self.[](value)
|
153
|
-
case value
|
154
|
-
when 'false', false, '0', 0 then false
|
155
|
-
when 'true', true, '1', 1 then true
|
156
|
-
end
|
157
|
-
end
|
158
|
-
end
|
159
|
-
|
160
|
-
class Serialized < Base
|
161
|
-
attr :object
|
162
|
-
|
163
|
-
def initialize(raw)
|
164
|
-
@object = case raw
|
165
|
-
when self.class::RAW
|
166
|
-
raw
|
167
|
-
when ::String
|
168
|
-
begin
|
169
|
-
::JSON.parse(raw)
|
170
|
-
rescue ::JSON::ParserError
|
171
|
-
raw
|
172
|
-
end
|
173
|
-
when self.class
|
174
|
-
raw.object
|
175
|
-
else
|
176
|
-
::Kernel.raise ::TypeError,
|
177
|
-
"%s does not accept %s" % [self.class, raw.inspect]
|
178
|
-
end
|
179
|
-
end
|
180
|
-
|
181
|
-
def ==(other)
|
182
|
-
object == other
|
183
|
-
end
|
184
|
-
|
185
|
-
def to_s
|
186
|
-
object.to_json
|
187
|
-
end
|
188
|
-
alias :inspect :to_s
|
189
|
-
|
190
|
-
def respond_to?(method)
|
191
|
-
object.respond_to?(method)
|
192
|
-
end
|
193
|
-
|
194
|
-
def type
|
195
|
-
self.class::RAW
|
196
|
-
end
|
197
|
-
end
|
198
|
-
|
199
|
-
class Hash < Serialized
|
200
|
-
RAW = ::Hash
|
201
|
-
|
202
|
-
delegate_to ::Hash
|
203
|
-
|
204
|
-
# @private since basic object doesn't include a #class we need
|
205
|
-
# to define this manually
|
206
|
-
def class
|
207
|
-
::Ohm::Types::Hash
|
208
|
-
end
|
209
|
-
end
|
210
|
-
|
211
|
-
class Array < Serialized
|
212
|
-
RAW = ::Array
|
213
|
-
|
214
|
-
delegate_to ::Array
|
215
|
-
|
216
|
-
# @private since basic object doesn't include a #class we need
|
217
|
-
# to define this manually
|
218
|
-
def class
|
219
|
-
::Ohm::Types::Array
|
220
|
-
end
|
221
|
-
end
|
222
|
-
end
|
223
|
-
|
224
|
-
# Provides unobtrusive, non-explosive typecasting. Instead of exploding on
|
225
|
-
# set of an invalid value, this module takes the approach of just taking in
|
226
|
-
# parameters and letting you do validation yourself. The only thing this
|
227
|
-
# module does for you is the boilerplate casting you might need to do.
|
228
|
-
#
|
229
|
-
# @example
|
230
|
-
#
|
231
|
-
# # without typecasting
|
232
|
-
# class Item < Ohm::Model
|
233
|
-
# attribute :price
|
234
|
-
# attribute :posted
|
235
|
-
# end
|
236
|
-
#
|
237
|
-
# item = Item.create(:price => 299, :posted => Time.now.utc)
|
238
|
-
# item = Item[item.id]
|
239
|
-
#
|
240
|
-
# # now when you try and grab `item.price`, its a string.
|
241
|
-
# "299" == item.price
|
242
|
-
# # => true
|
243
|
-
#
|
244
|
-
# # you can opt to manually cast everytime, or do it in the model, i.e.
|
245
|
-
#
|
246
|
-
# class Item
|
247
|
-
# def price
|
248
|
-
# BigDecimal(read_local(:price))
|
249
|
-
# end
|
250
|
-
# end
|
251
|
-
#
|
252
|
-
# The Typecasted way
|
253
|
-
# ------------------
|
254
|
-
#
|
255
|
-
# class Item < Ohm::Model
|
256
|
-
# include Ohm::Typecast
|
257
|
-
#
|
258
|
-
# attribute :price, Decimal
|
259
|
-
# attribute :posted, Time
|
260
|
-
# end
|
261
|
-
#
|
262
|
-
# item = Item.create(:price => "299", :posted => Time.now.utc)
|
263
|
-
# item = Item[item.id]
|
264
|
-
# item.price.class == BigDecimal
|
265
|
-
# # => true
|
266
|
-
#
|
267
|
-
# item.price.to_s == "299"
|
268
|
-
# # => true
|
269
|
-
#
|
270
|
-
# item.price * 2 == 598
|
271
|
-
# # => true
|
272
|
-
#
|
273
|
-
# item.posted.strftime('%m/%d/%Y')
|
274
|
-
# # => works!!!
|
275
|
-
module Typecast
|
276
|
-
def self.included(base)
|
277
|
-
base.extend ClassMethods
|
278
|
-
end
|
279
|
-
|
280
|
-
module ClassMethods
|
281
|
-
# Defines a typecasted attribute.
|
282
|
-
#
|
283
|
-
# @example
|
284
|
-
#
|
285
|
-
# class User < Ohm::Model
|
286
|
-
# include Ohm::Typecast
|
287
|
-
#
|
288
|
-
# attribute :birthday, Date
|
289
|
-
# attribute :last_login, Time
|
290
|
-
# attribute :age, Integer
|
291
|
-
# attribute :spending, Decimal
|
292
|
-
# attribute :score, Float
|
293
|
-
# end
|
294
|
-
#
|
295
|
-
# user = User.new(:birthday => "2000-01-01")
|
296
|
-
# user.birthday.month == 1
|
297
|
-
# # => true
|
298
|
-
#
|
299
|
-
# user.birthday.year == 2000
|
300
|
-
# # => true
|
301
|
-
#
|
302
|
-
# user.birthday.day == 1
|
303
|
-
# # => true
|
304
|
-
#
|
305
|
-
# user = User.new(:age => 20)
|
306
|
-
# user.age - 1 == 19
|
307
|
-
# => true
|
308
|
-
#
|
309
|
-
# @param [Symbol] name the name of the attribute to define.
|
310
|
-
# @param [Class] type (defaults to Ohm::Types::String) a class defined in
|
311
|
-
# Ohm::Types. You may define custom types in Ohm::Types if
|
312
|
-
# you need to.
|
313
|
-
# @return [Array] the array of attributes already defined.
|
314
|
-
# @return [nil] if the attribute is already defined.
|
315
|
-
def attribute(name, type = Ohm::Types::String, klass = Ohm::Types[type])
|
316
|
-
# Primitive types maintain a reference to the original object
|
317
|
-
# stored in @_attributes[att]. Hence mutation works for the
|
318
|
-
# Primitive case. For cases like Hash, Array where the value
|
319
|
-
# is `JSON.parse`d, we need to set the actual Ohm::Types::Hash
|
320
|
-
# (or similar) to @_attributes[att] for mutation to work.
|
321
|
-
if klass.superclass == Ohm::Types::Primitive
|
322
|
-
define_method(name) { klass[read_local(name)] }
|
323
|
-
else
|
324
|
-
define_method(name) { write_local(name, klass[read_local(name)]) }
|
325
|
-
end
|
326
|
-
|
327
|
-
define_method(:"#{name}=") do |value|
|
328
|
-
write_local(name, klass[value].to_s)
|
329
|
-
end
|
330
|
-
|
331
|
-
attributes << name unless attributes.include?(name)
|
332
|
-
types[name] = type
|
333
|
-
end
|
334
|
-
alias :typecast :attribute
|
335
|
-
|
336
|
-
def types
|
337
|
-
@types ||= {}
|
338
|
-
end
|
339
|
-
|
340
|
-
private
|
341
|
-
def const_missing(name)
|
342
|
-
if Ohm::Types.defined?(name)
|
343
|
-
Ohm::Types[name]
|
344
|
-
else
|
345
|
-
super
|
346
|
-
end
|
347
|
-
end
|
348
|
-
end
|
349
|
-
end
|
350
|
-
end
|
@@ -1,52 +0,0 @@
|
|
1
|
-
module Ohm
|
2
|
-
# All credit goes to gnrfan of github
|
3
|
-
# Basically an extraction from http://github.com/gnrfan/ohm_extra_validations
|
4
|
-
#
|
5
|
-
# * 2010-05-29 Updated Email Regex, Extracted out regexs to constants
|
6
|
-
#
|
7
|
-
# This module provides the following:
|
8
|
-
# * assert_slug
|
9
|
-
# * assert_email
|
10
|
-
# * assert_url
|
11
|
-
# * assert_ipv4
|
12
|
-
module WebValidations
|
13
|
-
# @see http://fightingforalostcause.net/misc/2006/compare-email-regex.php
|
14
|
-
EMAIL_REGEX = /^([\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+\.)*[\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+@((((([a-z0-9]{1}[a-z0-9\-]{0,62}[a-z0-9]{1})|[a-z])\.)+[a-z]{2,6})|(\d{1,3}\.){3}\d{1,3}(\:\d{1,5})?)$/i
|
15
|
-
|
16
|
-
SLUG_REGEX = /^[-\w]+$/
|
17
|
-
|
18
|
-
URL_REGEX = /^(http|https):\/\/([a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}|(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}|localhost)(:[0-9]{1,5})?(\/.*)?$/ix
|
19
|
-
|
20
|
-
IPV4_REGEX = /^(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}$/
|
21
|
-
|
22
|
-
protected
|
23
|
-
def assert_slug(att, error = [att, :not_slug])
|
24
|
-
if assert_present(att, error) and assert_unique(att)
|
25
|
-
assert_format(att, SLUG_REGEX, error)
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def assert_email(att, error = [att, :not_email])
|
30
|
-
if assert_present(att, error)
|
31
|
-
assert_format(att, EMAIL_REGEX, error)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
def assert_url(att, error = [att, :not_url])
|
36
|
-
if assert_present(att, error)
|
37
|
-
assert_format(att, URL_REGEX, error)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
def assert_ipv4(att, error = [att, :not_ipv4])
|
42
|
-
if assert_present(att, error)
|
43
|
-
assert_format(att, IPV4_REGEX, error)
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
def assert_ipaddr(att, error = [att, :not_ipaddr])
|
48
|
-
assert_ipv4(att, error)
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
data/test/activemodel_test.rb
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
|
-
require File.expand_path("./helper", File.dirname(__FILE__))
|
4
|
-
|
5
|
-
require "test/unit"
|
6
|
-
require "active_model"
|
7
|
-
|
8
|
-
class ActiveModelTest < Test::Unit::TestCase
|
9
|
-
include ActiveModel::Lint::Tests
|
10
|
-
|
11
|
-
class Post < Ohm::Model
|
12
|
-
include Ohm::ActiveModelExtension
|
13
|
-
|
14
|
-
attribute :body
|
15
|
-
list :related, Post
|
16
|
-
|
17
|
-
def validate
|
18
|
-
assert_present :body
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def setup
|
23
|
-
@model = Post.new
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
|
data/test/boundaries_test.rb
DELETED
@@ -1,45 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
|
-
require File.expand_path("./helper", File.dirname(__FILE__))
|
4
|
-
|
5
|
-
class Person < Ohm::Model
|
6
|
-
include Ohm::Boundaries
|
7
|
-
|
8
|
-
attribute :name
|
9
|
-
index :name
|
10
|
-
end
|
11
|
-
|
12
|
-
test "first / last are nil when no records" do
|
13
|
-
assert nil == Person.first
|
14
|
-
assert nil == Person.last
|
15
|
-
end
|
16
|
-
|
17
|
-
test "first / last returns the only record when just 1 record" do
|
18
|
-
matz = Person.create(:name => "matz")
|
19
|
-
|
20
|
-
assert matz == Person.first
|
21
|
-
assert matz == Person.last
|
22
|
-
end
|
23
|
-
|
24
|
-
test "has chronological order by default" do
|
25
|
-
matz = Person.create(:name => "matz")
|
26
|
-
linus = Person.create(:name => "linus")
|
27
|
-
|
28
|
-
assert matz == Person.first
|
29
|
-
assert linus == Person.last
|
30
|
-
end
|
31
|
-
|
32
|
-
test "respects filters passed in" do
|
33
|
-
matz = Person.create(:name => "matz")
|
34
|
-
linus = Person.create(:name => "linus")
|
35
|
-
|
36
|
-
assert matz == Person.first(:name => "matz")
|
37
|
-
assert matz == Person.last(:name => "matz")
|
38
|
-
|
39
|
-
assert linus == Person.first(:name => "linus")
|
40
|
-
assert linus == Person.last(:name => "linus")
|
41
|
-
|
42
|
-
assert nil == Person.first(:name => "quentin")
|
43
|
-
assert nil == Person.last(:name => "quentin")
|
44
|
-
end
|
45
|
-
|