ohm-contrib 0.0.19 → 0.0.20
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/VERSION +1 -1
- data/lib/ohm/contrib/typecast.rb +104 -13
- data/lib/ohm/contrib/web_validations.rb +22 -6
- data/lib/ohm/contrib.rb +1 -1
- data/ohm-contrib.gemspec +2 -2
- data/test/test_ohm_typecast.rb +229 -2
- data/test/test_ohm_web_validations.rb +7 -6
- metadata +3 -3
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.0.
|
|
1
|
+
0.0.20
|
data/lib/ohm/contrib/typecast.rb
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
require 'bigdecimal'
|
|
2
2
|
require 'time'
|
|
3
3
|
require 'date'
|
|
4
|
+
require 'json'
|
|
5
|
+
require 'forwardable'
|
|
4
6
|
|
|
5
7
|
module Ohm
|
|
6
8
|
# Provides all the primitive types. The following are included:
|
|
@@ -11,6 +13,8 @@ module Ohm
|
|
|
11
13
|
# * Float
|
|
12
14
|
# * Date
|
|
13
15
|
# * Time
|
|
16
|
+
# * Hash
|
|
17
|
+
# * Array
|
|
14
18
|
module Types
|
|
15
19
|
def self.defined?(type)
|
|
16
20
|
@constants ||= constants.map(&:to_s)
|
|
@@ -20,8 +24,35 @@ module Ohm
|
|
|
20
24
|
def self.[](type)
|
|
21
25
|
const_get(type.to_s.split('::').last)
|
|
22
26
|
end
|
|
27
|
+
|
|
28
|
+
class Base < BasicObject
|
|
29
|
+
class Exception < ::Exception; end
|
|
23
30
|
|
|
24
|
-
|
|
31
|
+
extend ::Forwardable
|
|
32
|
+
|
|
33
|
+
@@delegation_blacklist = [
|
|
34
|
+
:==, :to_s, :initialize, :inspect, :object_id, :__send__, :__id__
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
def self.[](value)
|
|
38
|
+
return self::EMPTY if value.to_s.empty?
|
|
39
|
+
|
|
40
|
+
new(value)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def self.delegate_to(klass, except = @@delegation_blacklist)
|
|
44
|
+
methods = klass.public_instance_methods.map(&:to_sym) - except
|
|
45
|
+
def_delegators :object, *methods
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def inspect
|
|
49
|
+
object.inspect
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
class Primitive < Base
|
|
54
|
+
EMPTY = nil
|
|
55
|
+
|
|
25
56
|
def initialize(value)
|
|
26
57
|
@raw = value
|
|
27
58
|
end
|
|
@@ -30,28 +61,23 @@ module Ohm
|
|
|
30
61
|
@raw.to_s
|
|
31
62
|
end
|
|
32
63
|
|
|
33
|
-
def inspect
|
|
34
|
-
object
|
|
35
|
-
end
|
|
36
|
-
|
|
37
64
|
def ==(other)
|
|
38
65
|
to_s == other.to_s
|
|
39
66
|
end
|
|
40
|
-
|
|
67
|
+
|
|
41
68
|
protected
|
|
42
69
|
def object
|
|
43
70
|
@raw
|
|
44
71
|
end
|
|
45
|
-
|
|
46
|
-
def method_missing(meth, *args, &blk)
|
|
47
|
-
object.send(meth, *args, &blk)
|
|
48
|
-
end
|
|
49
72
|
end
|
|
50
73
|
|
|
51
74
|
class String < Primitive
|
|
75
|
+
delegate_to ::String
|
|
52
76
|
end
|
|
53
77
|
|
|
54
78
|
class Decimal < Primitive
|
|
79
|
+
delegate_to ::BigDecimal
|
|
80
|
+
|
|
55
81
|
def inspect
|
|
56
82
|
object.to_s('F')
|
|
57
83
|
end
|
|
@@ -63,6 +89,8 @@ module Ohm
|
|
|
63
89
|
end
|
|
64
90
|
|
|
65
91
|
class Integer < Primitive
|
|
92
|
+
delegate_to ::Fixnum
|
|
93
|
+
|
|
66
94
|
protected
|
|
67
95
|
def object
|
|
68
96
|
::Kernel::Integer(@raw)
|
|
@@ -70,6 +98,8 @@ module Ohm
|
|
|
70
98
|
end
|
|
71
99
|
|
|
72
100
|
class Float < Primitive
|
|
101
|
+
delegate_to ::Float
|
|
102
|
+
|
|
73
103
|
protected
|
|
74
104
|
def object
|
|
75
105
|
::Kernel::Float(@raw)
|
|
@@ -77,6 +107,8 @@ module Ohm
|
|
|
77
107
|
end
|
|
78
108
|
|
|
79
109
|
class Time < Primitive
|
|
110
|
+
delegate_to ::Time
|
|
111
|
+
|
|
80
112
|
protected
|
|
81
113
|
def object
|
|
82
114
|
::Time.parse(@raw)
|
|
@@ -84,11 +116,62 @@ module Ohm
|
|
|
84
116
|
end
|
|
85
117
|
|
|
86
118
|
class Date < Primitive
|
|
119
|
+
delegate_to ::Date
|
|
120
|
+
|
|
87
121
|
protected
|
|
88
122
|
def object
|
|
89
123
|
::Date.parse(@raw)
|
|
90
124
|
end
|
|
91
125
|
end
|
|
126
|
+
|
|
127
|
+
class Serialized < Base
|
|
128
|
+
attr :object
|
|
129
|
+
|
|
130
|
+
def initialize(raw)
|
|
131
|
+
@object = case raw
|
|
132
|
+
when self.class::RAW then raw
|
|
133
|
+
when ::String then ::JSON.parse(raw)
|
|
134
|
+
when self.class then raw.object
|
|
135
|
+
else
|
|
136
|
+
::Kernel.raise ::TypeError,
|
|
137
|
+
"%s does not accept %s" % [self.class, raw.inspect]
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def ==(other)
|
|
142
|
+
object == other
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def to_s
|
|
146
|
+
object.to_json
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
class Hash < Serialized
|
|
151
|
+
EMPTY = {}
|
|
152
|
+
RAW = ::Hash
|
|
153
|
+
|
|
154
|
+
delegate_to ::Hash
|
|
155
|
+
|
|
156
|
+
# @private since basic object doesn't include a #class we need
|
|
157
|
+
# to define this manually
|
|
158
|
+
def class
|
|
159
|
+
::Ohm::Types::Hash
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
class Array < Serialized
|
|
164
|
+
EMPTY = []
|
|
165
|
+
RAW = ::Array
|
|
166
|
+
|
|
167
|
+
delegate_to ::Array
|
|
168
|
+
|
|
169
|
+
# @private since basic object doesn't include a #class we need
|
|
170
|
+
# to define this manually
|
|
171
|
+
def class
|
|
172
|
+
::Ohm::Types::Array
|
|
173
|
+
end
|
|
174
|
+
end
|
|
92
175
|
end
|
|
93
176
|
|
|
94
177
|
# Provides unobtrusive, non-explosive typecasting.Instead of exploding on set
|
|
@@ -184,12 +267,20 @@ module Ohm
|
|
|
184
267
|
# @return [nil] if the attribute is already defined.
|
|
185
268
|
def attribute(name, type = Ohm::Types::String, klass = Ohm::Types[type])
|
|
186
269
|
define_method(name) do
|
|
187
|
-
|
|
188
|
-
|
|
270
|
+
# Primitive types maintain a reference to the original object
|
|
271
|
+
# stored in @_attributes[att]. Hence mutation works for the
|
|
272
|
+
# Primitive case. For cases like Hash, Array where the value
|
|
273
|
+
# is `JSON.parse`d, we need to set the actual Ohm::Types::Hash
|
|
274
|
+
# (or similar) to @_attributes[att] for mutation to work.
|
|
275
|
+
if klass.superclass == Ohm::Types::Primitive
|
|
276
|
+
klass[read_local(name)]
|
|
277
|
+
else
|
|
278
|
+
write_local(name, klass[read_local(name)])
|
|
279
|
+
end
|
|
189
280
|
end
|
|
190
281
|
|
|
191
282
|
define_method(:"#{name}=") do |value|
|
|
192
|
-
write_local(name, value
|
|
283
|
+
write_local(name, klass[value].to_s)
|
|
193
284
|
end
|
|
194
285
|
|
|
195
286
|
attributes << name unless attributes.include?(name)
|
|
@@ -1,35 +1,51 @@
|
|
|
1
1
|
module Ohm
|
|
2
2
|
# All credit goes to gnrfan of github
|
|
3
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
|
|
4
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}$/
|
|
5
21
|
|
|
6
22
|
protected
|
|
7
23
|
def assert_slug(att, error = [att, :not_slug])
|
|
8
24
|
if assert_present(att, error) and assert_unique(att)
|
|
9
|
-
|
|
25
|
+
assert_format(att, SLUG_REGEX, error)
|
|
10
26
|
end
|
|
11
27
|
end
|
|
12
28
|
|
|
13
29
|
def assert_email(att, error = [att, :not_email])
|
|
14
30
|
if assert_present(att, error)
|
|
15
|
-
assert_format(att,
|
|
31
|
+
assert_format(att, EMAIL_REGEX, error)
|
|
16
32
|
end
|
|
17
33
|
end
|
|
18
34
|
|
|
19
35
|
def assert_url(att, error = [att, :not_url])
|
|
20
36
|
if assert_present(att, error)
|
|
21
|
-
assert_format(att,
|
|
37
|
+
assert_format(att, URL_REGEX, error)
|
|
22
38
|
end
|
|
23
39
|
end
|
|
24
40
|
|
|
25
41
|
def assert_ipv4(att, error = [att, :not_ipv4])
|
|
26
42
|
if assert_present(att, error)
|
|
27
|
-
assert_format(att,
|
|
43
|
+
assert_format(att, IPV4_REGEX, error)
|
|
28
44
|
end
|
|
29
45
|
end
|
|
30
46
|
|
|
31
47
|
def assert_ipaddr(att, error = [att, :not_ipaddr])
|
|
32
|
-
|
|
48
|
+
assert_ipv4(att, error)
|
|
33
49
|
end
|
|
34
50
|
end
|
|
35
|
-
end
|
|
51
|
+
end
|
data/lib/ohm/contrib.rb
CHANGED
data/ohm-contrib.gemspec
CHANGED
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
|
|
6
6
|
Gem::Specification.new do |s|
|
|
7
7
|
s.name = %q{ohm-contrib}
|
|
8
|
-
s.version = "0.0.
|
|
8
|
+
s.version = "0.0.20"
|
|
9
9
|
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
|
11
11
|
s.authors = ["Cyril David"]
|
|
12
|
-
s.date = %q{2010-05-
|
|
12
|
+
s.date = %q{2010-05-29}
|
|
13
13
|
s.description = %q{Highly decoupled drop-in functionality for Ohm models}
|
|
14
14
|
s.email = %q{cyx.ucron@gmail.com}
|
|
15
15
|
s.extra_rdoc_files = [
|
data/test/test_ohm_typecast.rb
CHANGED
|
@@ -145,7 +145,7 @@ class TestOhmTypecast < Test::Unit::TestCase
|
|
|
145
145
|
|
|
146
146
|
test "inspecting" do
|
|
147
147
|
post = Post.new(:price => "50000")
|
|
148
|
-
assert_equal 50000, post.price.inspect
|
|
148
|
+
assert_equal '50000', post.price.inspect
|
|
149
149
|
end
|
|
150
150
|
end
|
|
151
151
|
|
|
@@ -191,7 +191,7 @@ class TestOhmTypecast < Test::Unit::TestCase
|
|
|
191
191
|
|
|
192
192
|
test "inspecting" do
|
|
193
193
|
post = Post.new(:price => "12345.67890")
|
|
194
|
-
assert_equal 12345.
|
|
194
|
+
assert_equal '12345.6789', post.price.inspect
|
|
195
195
|
end
|
|
196
196
|
end
|
|
197
197
|
|
|
@@ -318,4 +318,231 @@ class TestOhmTypecast < Test::Unit::TestCase
|
|
|
318
318
|
assert_equal Date.today, Post.new.today
|
|
319
319
|
end
|
|
320
320
|
end
|
|
321
|
+
|
|
322
|
+
context "when using a Hash" do
|
|
323
|
+
class Post < Ohm::Model
|
|
324
|
+
include Ohm::Typecast
|
|
325
|
+
|
|
326
|
+
attribute :address, Hash
|
|
327
|
+
|
|
328
|
+
def hash
|
|
329
|
+
Hash.new
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
def top_level_hash
|
|
333
|
+
Hash
|
|
334
|
+
end
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
test "importing" do
|
|
338
|
+
assert_equal Hash.new, Ohm::Types::Hash[nil]
|
|
339
|
+
assert_equal Hash.new, Ohm::Types::Hash[""]
|
|
340
|
+
assert_equal Hash.new, Ohm::Types::Hash[{}]
|
|
341
|
+
|
|
342
|
+
assert_equal Hash[:a => "b", :c => "d"],
|
|
343
|
+
Ohm::Types::Hash[{ :a => "b", :c => "d" }]
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
test "exporting / dumping" do
|
|
347
|
+
assert_equal "{}", Ohm::Types::Hash[nil].to_s
|
|
348
|
+
assert_equal "{}", Ohm::Types::Hash[""].to_s
|
|
349
|
+
assert_equal "{}", Ohm::Types::Hash[{}].to_s
|
|
350
|
+
|
|
351
|
+
assert_equal %q{{"a":"b","c":"d"}},
|
|
352
|
+
Ohm::Types::Hash[{ :a => "b", :c => "d" }].to_s
|
|
353
|
+
end
|
|
354
|
+
|
|
355
|
+
test "still able to get top level methods" do
|
|
356
|
+
assert_equal({}, Post.new.hash)
|
|
357
|
+
assert_equal Hash, Post.new.top_level_hash
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
test "handles nil case correctly" do
|
|
361
|
+
post = Post.create(:address => nil)
|
|
362
|
+
assert_equal({}, post.address)
|
|
363
|
+
|
|
364
|
+
post = Post[post.id]
|
|
365
|
+
assert_equal({}, post.address)
|
|
366
|
+
end
|
|
367
|
+
|
|
368
|
+
test "handles empty string case correctly" do
|
|
369
|
+
post = Post.create(:address => "")
|
|
370
|
+
assert_equal({}, post.address)
|
|
371
|
+
|
|
372
|
+
post = Post[post.id]
|
|
373
|
+
assert_equal({}, post.address)
|
|
374
|
+
end
|
|
375
|
+
|
|
376
|
+
test "handles populated hashes" do
|
|
377
|
+
address = { "address1" => "#123", "city" => "Singapore", "country" => "SG"}
|
|
378
|
+
post = Post.create(:address => address)
|
|
379
|
+
assert_equal address, post.address
|
|
380
|
+
|
|
381
|
+
post = Post[post.id]
|
|
382
|
+
assert_equal address, post.address
|
|
383
|
+
end
|
|
384
|
+
|
|
385
|
+
test "allows for hash operations" do
|
|
386
|
+
address = { "address1" => "#123", "city" => "Singapore", "country" => "SG"}
|
|
387
|
+
post = Post.create(:address => address)
|
|
388
|
+
|
|
389
|
+
assert_equal ["address1", "city", "country"], post.address.keys
|
|
390
|
+
assert_equal ["#123", "Singapore", "SG"], post.address.values
|
|
391
|
+
|
|
392
|
+
post = Post[post.id]
|
|
393
|
+
assert_equal ["address1", "city", "country"], post.address.keys
|
|
394
|
+
assert_equal ["#123", "Singapore", "SG"], post.address.values
|
|
395
|
+
end
|
|
396
|
+
|
|
397
|
+
test "handles mutation" do
|
|
398
|
+
address = { "address1" => "#123", "city" => "Singapore", "country" => "SG"}
|
|
399
|
+
post = Post.create(:address => address)
|
|
400
|
+
|
|
401
|
+
post.address["address1"] = "#456"
|
|
402
|
+
post.save
|
|
403
|
+
|
|
404
|
+
assert_equal ["address1", "city", "country"], post.address.keys
|
|
405
|
+
assert_equal ["#456", "Singapore", "SG"], post.address.values
|
|
406
|
+
|
|
407
|
+
post = Post[post.id]
|
|
408
|
+
assert_equal ["address1", "city", "country"], post.address.keys
|
|
409
|
+
assert_equal ["#456", "Singapore", "SG"], post.address.values
|
|
410
|
+
end
|
|
411
|
+
|
|
412
|
+
Address = Class.new(Struct.new(:city, :country))
|
|
413
|
+
|
|
414
|
+
test "raises when trying to assign a non-hash" do
|
|
415
|
+
assert_raise TypeError do
|
|
416
|
+
Post.new(:address => [])
|
|
417
|
+
end
|
|
418
|
+
|
|
419
|
+
assert_raise TypeError do
|
|
420
|
+
Post.new(:address => Address.new)
|
|
421
|
+
end
|
|
422
|
+
end
|
|
423
|
+
end
|
|
424
|
+
|
|
425
|
+
context "when using an Array" do
|
|
426
|
+
class Post < Ohm::Model
|
|
427
|
+
include Ohm::Typecast
|
|
428
|
+
|
|
429
|
+
attribute :addresses, Array
|
|
430
|
+
|
|
431
|
+
def array
|
|
432
|
+
Array.new
|
|
433
|
+
end
|
|
434
|
+
|
|
435
|
+
def top_level_array
|
|
436
|
+
Array
|
|
437
|
+
end
|
|
438
|
+
end
|
|
439
|
+
|
|
440
|
+
test "importing" do
|
|
441
|
+
assert_equal [], Ohm::Types::Array[nil]
|
|
442
|
+
assert_equal [], Ohm::Types::Array[""]
|
|
443
|
+
assert_equal [], Ohm::Types::Array[[]]
|
|
444
|
+
|
|
445
|
+
assert_equal ['a', 'b', 'c', 'd'],
|
|
446
|
+
Ohm::Types::Array[['a', 'b', 'c', 'd']]
|
|
447
|
+
end
|
|
448
|
+
|
|
449
|
+
test "exporting / dumping" do
|
|
450
|
+
assert_equal "[]", Ohm::Types::Array[nil].to_s
|
|
451
|
+
assert_equal "[]", Ohm::Types::Array[""].to_s
|
|
452
|
+
assert_equal "[]", Ohm::Types::Array[[]].to_s
|
|
453
|
+
|
|
454
|
+
assert_equal %q{["a","b","c","d"]},
|
|
455
|
+
Ohm::Types::Array[['a', 'b', 'c', 'd']].to_s
|
|
456
|
+
end
|
|
457
|
+
|
|
458
|
+
test "still able to get top level methods" do
|
|
459
|
+
assert_equal([], Post.new.array)
|
|
460
|
+
assert_equal Array, Post.new.top_level_array
|
|
461
|
+
end
|
|
462
|
+
|
|
463
|
+
test "handles nil case correctly" do
|
|
464
|
+
post = Post.create(:addresses => nil)
|
|
465
|
+
assert_equal([], post.addresses)
|
|
466
|
+
|
|
467
|
+
post = Post[post.id]
|
|
468
|
+
assert_equal([], post.addresses)
|
|
469
|
+
end
|
|
470
|
+
|
|
471
|
+
test "handles empty string case correctly" do
|
|
472
|
+
post = Post.create(:addresses => "")
|
|
473
|
+
assert_equal([], post.addresses)
|
|
474
|
+
|
|
475
|
+
post = Post[post.id]
|
|
476
|
+
assert_equal([], post.addresses)
|
|
477
|
+
end
|
|
478
|
+
|
|
479
|
+
test "handles populated arrays" do
|
|
480
|
+
addresses = [{"city" => "Singapore", "country" => "SG"},
|
|
481
|
+
{"city" => "Manila", "country" => "PH"}]
|
|
482
|
+
|
|
483
|
+
post = Post.create(:addresses => addresses)
|
|
484
|
+
assert_equal addresses, post.addresses
|
|
485
|
+
|
|
486
|
+
post = Post[post.id]
|
|
487
|
+
assert_equal addresses, post.addresses
|
|
488
|
+
end
|
|
489
|
+
|
|
490
|
+
class Address < Struct.new(:city, :country)
|
|
491
|
+
def to_json
|
|
492
|
+
[city, country].to_json
|
|
493
|
+
end
|
|
494
|
+
end
|
|
495
|
+
|
|
496
|
+
test "handles an arbitrary class as an element of the array" do
|
|
497
|
+
addresses = [Address.new("Singapore", "SG"),
|
|
498
|
+
Address.new("Philippines", "PH")]
|
|
499
|
+
|
|
500
|
+
post = Post.create(:addresses => addresses)
|
|
501
|
+
assert_equal [['Singapore', 'SG'], ['Philippines', 'PH']], post.addresses
|
|
502
|
+
|
|
503
|
+
post = Post[post.id]
|
|
504
|
+
assert_equal [['Singapore', 'SG'], ['Philippines', 'PH']], post.addresses
|
|
505
|
+
end
|
|
506
|
+
|
|
507
|
+
test "allows for array operations" do
|
|
508
|
+
addresses = [{"city" => "Singapore", "country" => "SG"},
|
|
509
|
+
{"city" => "Manila", "country" => "PH"}]
|
|
510
|
+
|
|
511
|
+
|
|
512
|
+
post = Post.create(:addresses => addresses)
|
|
513
|
+
assert_equal 2, post.addresses.size
|
|
514
|
+
assert_equal addresses + [{"city" => "Hong Kong", "country" => "ZN"}],
|
|
515
|
+
post.addresses.push({"city" => "Hong Kong", "country" => "ZN"})
|
|
516
|
+
|
|
517
|
+
post = Post[post.id]
|
|
518
|
+
assert_equal 2, post.addresses.size
|
|
519
|
+
assert_equal addresses + [{"city" => "Hong Kong", "country" => "ZN"}],
|
|
520
|
+
post.addresses.push({"city" => "Hong Kong", "country" => "ZN"})
|
|
521
|
+
end
|
|
522
|
+
|
|
523
|
+
test "handles mutation" do
|
|
524
|
+
post = Post.create(:addresses => [1, 2, 3])
|
|
525
|
+
|
|
526
|
+
post.addresses.push(4, 5, 6)
|
|
527
|
+
post.save
|
|
528
|
+
|
|
529
|
+
assert_equal 6, post.addresses.size
|
|
530
|
+
assert_equal [1, 2, 3, 4, 5, 6], post.addresses
|
|
531
|
+
|
|
532
|
+
post = Post[post.id]
|
|
533
|
+
assert_equal 6, post.addresses.size
|
|
534
|
+
assert_equal [1, 2, 3, 4, 5, 6], post.addresses
|
|
535
|
+
end
|
|
536
|
+
|
|
537
|
+
|
|
538
|
+
test "raises when trying to assign a non-array" do
|
|
539
|
+
assert_raise TypeError do
|
|
540
|
+
Post.new(:addresses => {})
|
|
541
|
+
end
|
|
542
|
+
|
|
543
|
+
assert_raise TypeError do
|
|
544
|
+
Post.new(:addresses => Address.new)
|
|
545
|
+
end
|
|
546
|
+
end
|
|
547
|
+
end
|
|
321
548
|
end
|
|
@@ -29,6 +29,7 @@ class TestOhmWebValidations < Test::Unit::TestCase
|
|
|
29
29
|
|
|
30
30
|
context "The slug should be valid" do
|
|
31
31
|
def setup
|
|
32
|
+
Ohm.flush
|
|
32
33
|
@blog_post_01 = BlogPost.new
|
|
33
34
|
@blog_post_02 = BlogPost.new
|
|
34
35
|
end
|
|
@@ -41,11 +42,11 @@ class TestOhmWebValidations < Test::Unit::TestCase
|
|
|
41
42
|
assert_equal [[:slug, :not_slug]], @blog_post_01.errors
|
|
42
43
|
end
|
|
43
44
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
45
|
+
should "succeed if the slug is valid" do
|
|
46
|
+
@blog_post_02.slug = "this-is-a-valid-slug"
|
|
47
|
+
@blog_post_02.create
|
|
48
|
+
assert_not_nil @blog_post_02.id
|
|
49
|
+
end
|
|
49
50
|
|
|
50
51
|
should "fail if the slug is not unique" do
|
|
51
52
|
|
|
@@ -110,4 +111,4 @@ class TestOhmWebValidations < Test::Unit::TestCase
|
|
|
110
111
|
end
|
|
111
112
|
|
|
112
113
|
end
|
|
113
|
-
end
|
|
114
|
+
end
|
metadata
CHANGED
|
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
|
5
5
|
segments:
|
|
6
6
|
- 0
|
|
7
7
|
- 0
|
|
8
|
-
-
|
|
9
|
-
version: 0.0.
|
|
8
|
+
- 20
|
|
9
|
+
version: 0.0.20
|
|
10
10
|
platform: ruby
|
|
11
11
|
authors:
|
|
12
12
|
- Cyril David
|
|
@@ -14,7 +14,7 @@ autorequire:
|
|
|
14
14
|
bindir: bin
|
|
15
15
|
cert_chain: []
|
|
16
16
|
|
|
17
|
-
date: 2010-05-
|
|
17
|
+
date: 2010-05-29 00:00:00 +08:00
|
|
18
18
|
default_executable:
|
|
19
19
|
dependencies:
|
|
20
20
|
- !ruby/object:Gem::Dependency
|