ohm-contrib 0.0.20 → 0.0.21
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +93 -1
- data/VERSION +1 -1
- data/lib/ohm/contrib.rb +1 -1
- data/lib/ohm/contrib/callbacks.rb +1 -1
- data/lib/ohm/contrib/typecast.rb +29 -25
- data/lib/ohm/contrib/web_validations.rb +3 -3
- data/ohm-contrib.gemspec +2 -2
- data/test/test_ohm_contrib_callbacks.rb +4 -4
- data/test/test_ohm_typecast.rb +91 -22
- data/test/test_ohm_web_validations.rb +1 -1
- metadata +3 -3
data/README.markdown
CHANGED
@@ -68,6 +68,76 @@ Example usage
|
|
68
68
|
|
69
69
|
Typecasting explained
|
70
70
|
---------------------
|
71
|
+
|
72
|
+
I studied various typecasting behaviors implemented by a few ORMs in Ruby.
|
73
|
+
|
74
|
+
### ActiveRecord
|
75
|
+
|
76
|
+
class Post < ActiveRecord::Base
|
77
|
+
# say we have an integer column in the DB named votes
|
78
|
+
end
|
79
|
+
Post.new(:votes => "FooBar").votes == 0
|
80
|
+
# => true
|
81
|
+
|
82
|
+
### DataMapper
|
83
|
+
class Post
|
84
|
+
include DataMapper::Resource
|
85
|
+
|
86
|
+
property :id, Serial
|
87
|
+
property :votes, Integer
|
88
|
+
end
|
89
|
+
|
90
|
+
post = Post.new(:votes => "FooBar")
|
91
|
+
post.votes == "FooBar"
|
92
|
+
# => true
|
93
|
+
|
94
|
+
post.save
|
95
|
+
post.reload
|
96
|
+
|
97
|
+
# Get ready!!!!
|
98
|
+
post.votes == 0
|
99
|
+
# => true
|
100
|
+
|
101
|
+
### Ohm::Typecast approach.
|
102
|
+
|
103
|
+
#### Mindset:
|
104
|
+
|
105
|
+
1. Explosion everytime is too cumbersome.
|
106
|
+
2. Mutation of data is less than ideal (Also similar to MySQL silently allowing you
|
107
|
+
to store more than 255 chars in a VARCHAR and then truncating that data. Yes I know
|
108
|
+
you can configure it to be noisy but the defaults kill).
|
109
|
+
3. We just want to operate on it like it should!
|
110
|
+
|
111
|
+
#### Short Demo:
|
112
|
+
class Post < Ohm::Model
|
113
|
+
include Ohm::Typecast
|
114
|
+
attribute :votes
|
115
|
+
end
|
116
|
+
|
117
|
+
post = Post.new(:votes => "FooBar")
|
118
|
+
post.votes == "FooBar"
|
119
|
+
# => true
|
120
|
+
|
121
|
+
post.save
|
122
|
+
post = Post[post.id]
|
123
|
+
post.votes == "FooBar"
|
124
|
+
# => true
|
125
|
+
|
126
|
+
# Here comes the cool part...
|
127
|
+
post.votes * 1
|
128
|
+
# => ArgumentError: invalid value for Integer: "FooBar"
|
129
|
+
|
130
|
+
post.votes = 50
|
131
|
+
post.votes * 2 == 100
|
132
|
+
# => true
|
133
|
+
|
134
|
+
post.votes.class == Ohm::Types::Integer
|
135
|
+
# => true
|
136
|
+
post.votes.inspect == "50"
|
137
|
+
# => true
|
138
|
+
|
139
|
+
#### More examples just to show the normal case.
|
140
|
+
|
71
141
|
require 'ohm'
|
72
142
|
require 'ohm/contrib'
|
73
143
|
|
@@ -77,9 +147,14 @@ Typecasting explained
|
|
77
147
|
attribute :price, Decimal
|
78
148
|
attribute :available_at, Time
|
79
149
|
attribute :stock, Integer
|
150
|
+
attribute :address, Hash
|
151
|
+
attribute :tags, Array
|
80
152
|
end
|
81
153
|
|
82
|
-
post = Post.create(:price => "10.20", :stock => "100"
|
154
|
+
post = Post.create(:price => "10.20", :stock => "100",
|
155
|
+
:address => { "city" => "Boston", "country" => "US" },
|
156
|
+
:tags => ["redis", "ohm", "typecast"])
|
157
|
+
|
83
158
|
post.price.to_s == "10.20"
|
84
159
|
# => true
|
85
160
|
|
@@ -89,6 +164,23 @@ Typecasting explained
|
|
89
164
|
post.stock / 10 == 10
|
90
165
|
# => true
|
91
166
|
|
167
|
+
post.address["city"] == "Boston"
|
168
|
+
post.tags.map { |tag| tag.upcase }
|
169
|
+
|
170
|
+
# of course mutation works for both cases
|
171
|
+
post.price += 5
|
172
|
+
post.stock -= 1
|
173
|
+
post.tags << "contrib"
|
174
|
+
post.address["state"] = "MA"
|
175
|
+
post.save
|
176
|
+
post = Post[post.id]
|
177
|
+
|
178
|
+
post.address["state"] == "MA"
|
179
|
+
# => true
|
180
|
+
post.tags.include?("contrib")
|
181
|
+
# => true
|
182
|
+
|
183
|
+
|
92
184
|
Credits
|
93
185
|
-------
|
94
186
|
Thanks to github user gnrfan for the web validations.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.21
|
data/lib/ohm/contrib.rb
CHANGED
data/lib/ohm/contrib/typecast.rb
CHANGED
@@ -24,7 +24,7 @@ module Ohm
|
|
24
24
|
def self.[](type)
|
25
25
|
const_get(type.to_s.split('::').last)
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
class Base < BasicObject
|
29
29
|
class Exception < ::Exception; end
|
30
30
|
|
@@ -36,23 +36,23 @@ module Ohm
|
|
36
36
|
|
37
37
|
def self.[](value)
|
38
38
|
return self::EMPTY if value.to_s.empty?
|
39
|
-
|
39
|
+
|
40
40
|
new(value)
|
41
41
|
end
|
42
42
|
|
43
43
|
def self.delegate_to(klass, except = @@delegation_blacklist)
|
44
44
|
methods = klass.public_instance_methods.map(&:to_sym) - except
|
45
|
-
def_delegators :object, *methods
|
45
|
+
def_delegators :object, *methods
|
46
46
|
end
|
47
47
|
|
48
48
|
def inspect
|
49
|
-
|
49
|
+
@raw.inspect
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
53
53
|
class Primitive < Base
|
54
54
|
EMPTY = nil
|
55
|
-
|
55
|
+
|
56
56
|
def initialize(value)
|
57
57
|
@raw = value
|
58
58
|
end
|
@@ -64,7 +64,7 @@ module Ohm
|
|
64
64
|
def ==(other)
|
65
65
|
to_s == other.to_s
|
66
66
|
end
|
67
|
-
|
67
|
+
|
68
68
|
protected
|
69
69
|
def object
|
70
70
|
@raw
|
@@ -78,10 +78,6 @@ module Ohm
|
|
78
78
|
class Decimal < Primitive
|
79
79
|
delegate_to ::BigDecimal
|
80
80
|
|
81
|
-
def inspect
|
82
|
-
object.to_s('F')
|
83
|
-
end
|
84
|
-
|
85
81
|
protected
|
86
82
|
def object
|
87
83
|
::Kernel::BigDecimal(@raw)
|
@@ -123,28 +119,36 @@ module Ohm
|
|
123
119
|
::Date.parse(@raw)
|
124
120
|
end
|
125
121
|
end
|
126
|
-
|
122
|
+
|
127
123
|
class Serialized < Base
|
128
124
|
attr :object
|
129
125
|
|
130
126
|
def initialize(raw)
|
131
127
|
@object = case raw
|
132
|
-
when self.class::RAW
|
133
|
-
|
134
|
-
when
|
128
|
+
when self.class::RAW
|
129
|
+
raw
|
130
|
+
when ::String
|
131
|
+
begin
|
132
|
+
::JSON.parse(raw)
|
133
|
+
rescue ::JSON::ParserError
|
134
|
+
raw
|
135
|
+
end
|
136
|
+
when self.class
|
137
|
+
raw.object
|
135
138
|
else
|
136
|
-
::Kernel.raise ::TypeError,
|
139
|
+
::Kernel.raise ::TypeError,
|
137
140
|
"%s does not accept %s" % [self.class, raw.inspect]
|
138
141
|
end
|
139
142
|
end
|
140
143
|
|
141
144
|
def ==(other)
|
142
|
-
object == other
|
145
|
+
object == other
|
143
146
|
end
|
144
|
-
|
147
|
+
|
145
148
|
def to_s
|
146
149
|
object.to_json
|
147
150
|
end
|
151
|
+
alias :inspect :to_s
|
148
152
|
end
|
149
153
|
|
150
154
|
class Hash < Serialized
|
@@ -163,9 +167,9 @@ module Ohm
|
|
163
167
|
class Array < Serialized
|
164
168
|
EMPTY = []
|
165
169
|
RAW = ::Array
|
166
|
-
|
170
|
+
|
167
171
|
delegate_to ::Array
|
168
|
-
|
172
|
+
|
169
173
|
# @private since basic object doesn't include a #class we need
|
170
174
|
# to define this manually
|
171
175
|
def class
|
@@ -234,7 +238,7 @@ module Ohm
|
|
234
238
|
# Defines a typecasted attribute.
|
235
239
|
#
|
236
240
|
# @example
|
237
|
-
#
|
241
|
+
#
|
238
242
|
# class User < Ohm::Model
|
239
243
|
# include Ohm::Typecast
|
240
244
|
#
|
@@ -258,9 +262,9 @@ module Ohm
|
|
258
262
|
# user = User.new(:age => 20)
|
259
263
|
# user.age - 1 == 19
|
260
264
|
# => true
|
261
|
-
#
|
265
|
+
#
|
262
266
|
# @param [Symbol] name the name of the attribute to define.
|
263
|
-
# @param [Class] type (defaults to Ohm::Types::String) a class defined in
|
267
|
+
# @param [Class] type (defaults to Ohm::Types::String) a class defined in
|
264
268
|
# Ohm::Types. You may define custom types in Ohm::Types if
|
265
269
|
# you need to.
|
266
270
|
# @return [Array] the array of attributes already defined.
|
@@ -269,8 +273,8 @@ module Ohm
|
|
269
273
|
define_method(name) do
|
270
274
|
# Primitive types maintain a reference to the original object
|
271
275
|
# 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
|
276
|
+
# Primitive case. For cases like Hash, Array where the value
|
277
|
+
# is `JSON.parse`d, we need to set the actual Ohm::Types::Hash
|
274
278
|
# (or similar) to @_attributes[att] for mutation to work.
|
275
279
|
if klass.superclass == Ohm::Types::Primitive
|
276
280
|
klass[read_local(name)]
|
@@ -296,4 +300,4 @@ module Ohm
|
|
296
300
|
end
|
297
301
|
end
|
298
302
|
end
|
299
|
-
end
|
303
|
+
end
|
@@ -12,9 +12,9 @@ module Ohm
|
|
12
12
|
module WebValidations
|
13
13
|
# @see http://fightingforalostcause.net/misc/2006/compare-email-regex.php
|
14
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
|
-
|
15
|
+
|
16
16
|
SLUG_REGEX = /^[-\w]+$/
|
17
|
-
|
17
|
+
|
18
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
19
|
|
20
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}$/
|
@@ -48,4 +48,4 @@ module Ohm
|
|
48
48
|
assert_ipv4(att, error)
|
49
49
|
end
|
50
50
|
end
|
51
|
-
end
|
51
|
+
end
|
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.21"
|
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-30}
|
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 = [
|
@@ -14,7 +14,7 @@ class OhmContribCallbacksTest < Test::Unit::TestCase
|
|
14
14
|
|
15
15
|
before :save, :do_before_save
|
16
16
|
after :save, :do_after_save
|
17
|
-
|
17
|
+
|
18
18
|
before :delete, :do_before_delete
|
19
19
|
after :delete, :do_after_delete
|
20
20
|
|
@@ -151,8 +151,8 @@ class OhmContribCallbacksTest < Test::Unit::TestCase
|
|
151
151
|
@post = Post[@post.id]
|
152
152
|
@post.delete
|
153
153
|
end
|
154
|
-
|
155
|
-
|
154
|
+
|
155
|
+
|
156
156
|
should "call delete related callbacks once" do
|
157
157
|
assert_equal 1, @post.count(:do_before_delete)
|
158
158
|
assert_equal 1, @post.count(:do_after_delete)
|
@@ -167,4 +167,4 @@ class OhmContribCallbacksTest < Test::Unit::TestCase
|
|
167
167
|
assert ! @post.did?(:do_after_save)
|
168
168
|
end
|
169
169
|
end
|
170
|
-
end
|
170
|
+
end
|
data/test/test_ohm_typecast.rb
CHANGED
@@ -92,14 +92,23 @@ class TestOhmTypecast < Test::Unit::TestCase
|
|
92
92
|
assert_kind_of String, post.price.to_s
|
93
93
|
end
|
94
94
|
|
95
|
-
test "equality matching" do
|
95
|
+
test "equality and comparable matching" do
|
96
96
|
post = Post.create(:price => "399.50")
|
97
97
|
assert (post.price == "399.50")
|
98
|
+
assert (post.price < 399.51)
|
99
|
+
assert (post.price > 399.49)
|
100
|
+
assert (post.price <= 399.50)
|
101
|
+
assert (post.price <= 399.51)
|
102
|
+
assert (post.price >= 399.50)
|
103
|
+
assert (post.price >= 399.49)
|
98
104
|
end
|
99
105
|
|
100
106
|
test "inspecting a Decimal" do
|
101
107
|
post = Post.new(:price => 399.50)
|
102
|
-
assert_equal '399.5', post.price.inspect
|
108
|
+
assert_equal '"399.5"', post.price.inspect
|
109
|
+
|
110
|
+
post.price = 'FooBar'
|
111
|
+
assert_equal '"FooBar"', post.price.inspect
|
103
112
|
end
|
104
113
|
end
|
105
114
|
|
@@ -145,7 +154,10 @@ class TestOhmTypecast < Test::Unit::TestCase
|
|
145
154
|
|
146
155
|
test "inspecting" do
|
147
156
|
post = Post.new(:price => "50000")
|
148
|
-
assert_equal '50000', post.price.inspect
|
157
|
+
assert_equal '"50000"', post.price.inspect
|
158
|
+
|
159
|
+
post.price = 'FooBar'
|
160
|
+
assert_equal '"FooBar"', post.price.inspect
|
149
161
|
end
|
150
162
|
end
|
151
163
|
|
@@ -191,7 +203,10 @@ class TestOhmTypecast < Test::Unit::TestCase
|
|
191
203
|
|
192
204
|
test "inspecting" do
|
193
205
|
post = Post.new(:price => "12345.67890")
|
194
|
-
assert_equal '12345.
|
206
|
+
assert_equal '"12345.67890"', post.price.inspect
|
207
|
+
|
208
|
+
post.price = 'FooBar'
|
209
|
+
assert_equal '"FooBar"', post.price.inspect
|
195
210
|
end
|
196
211
|
end
|
197
212
|
|
@@ -250,6 +265,14 @@ class TestOhmTypecast < Test::Unit::TestCase
|
|
250
265
|
post.created_at.slice
|
251
266
|
end
|
252
267
|
end
|
268
|
+
|
269
|
+
test "inspecting" do
|
270
|
+
post = Post.create(:created_at => Time.utc(2010, 05, 05))
|
271
|
+
assert_equal '"2010-05-05 00:00:00 UTC"', post.created_at.inspect
|
272
|
+
|
273
|
+
post.created_at = 'FooBar'
|
274
|
+
assert_equal '"FooBar"', post.created_at.inspect
|
275
|
+
end
|
253
276
|
end
|
254
277
|
|
255
278
|
context "when using a date" do
|
@@ -317,6 +340,14 @@ class TestOhmTypecast < Test::Unit::TestCase
|
|
317
340
|
test "still able to access Date" do
|
318
341
|
assert_equal Date.today, Post.new.today
|
319
342
|
end
|
343
|
+
|
344
|
+
test "inspecting" do
|
345
|
+
post = Post.create(:created_on => Date.new(2010, 5, 5))
|
346
|
+
assert_equal '"2010-05-05"', post.created_on.inspect
|
347
|
+
|
348
|
+
post.created_on = 'FooBar'
|
349
|
+
assert_equal '"FooBar"', post.created_on.inspect
|
350
|
+
end
|
320
351
|
end
|
321
352
|
|
322
353
|
context "when using a Hash" do
|
@@ -333,13 +364,13 @@ class TestOhmTypecast < Test::Unit::TestCase
|
|
333
364
|
Hash
|
334
365
|
end
|
335
366
|
end
|
336
|
-
|
367
|
+
|
337
368
|
test "importing" do
|
338
369
|
assert_equal Hash.new, Ohm::Types::Hash[nil]
|
339
370
|
assert_equal Hash.new, Ohm::Types::Hash[""]
|
340
371
|
assert_equal Hash.new, Ohm::Types::Hash[{}]
|
341
372
|
|
342
|
-
assert_equal Hash[:a => "b", :c => "d"],
|
373
|
+
assert_equal Hash[:a => "b", :c => "d"],
|
343
374
|
Ohm::Types::Hash[{ :a => "b", :c => "d" }]
|
344
375
|
end
|
345
376
|
|
@@ -360,7 +391,7 @@ class TestOhmTypecast < Test::Unit::TestCase
|
|
360
391
|
test "handles nil case correctly" do
|
361
392
|
post = Post.create(:address => nil)
|
362
393
|
assert_equal({}, post.address)
|
363
|
-
|
394
|
+
|
364
395
|
post = Post[post.id]
|
365
396
|
assert_equal({}, post.address)
|
366
397
|
end
|
@@ -368,7 +399,7 @@ class TestOhmTypecast < Test::Unit::TestCase
|
|
368
399
|
test "handles empty string case correctly" do
|
369
400
|
post = Post.create(:address => "")
|
370
401
|
assert_equal({}, post.address)
|
371
|
-
|
402
|
+
|
372
403
|
post = Post[post.id]
|
373
404
|
assert_equal({}, post.address)
|
374
405
|
end
|
@@ -377,7 +408,7 @@ class TestOhmTypecast < Test::Unit::TestCase
|
|
377
408
|
address = { "address1" => "#123", "city" => "Singapore", "country" => "SG"}
|
378
409
|
post = Post.create(:address => address)
|
379
410
|
assert_equal address, post.address
|
380
|
-
|
411
|
+
|
381
412
|
post = Post[post.id]
|
382
413
|
assert_equal address, post.address
|
383
414
|
end
|
@@ -385,7 +416,7 @@ class TestOhmTypecast < Test::Unit::TestCase
|
|
385
416
|
test "allows for hash operations" do
|
386
417
|
address = { "address1" => "#123", "city" => "Singapore", "country" => "SG"}
|
387
418
|
post = Post.create(:address => address)
|
388
|
-
|
419
|
+
|
389
420
|
assert_equal ["address1", "city", "country"], post.address.keys
|
390
421
|
assert_equal ["#123", "Singapore", "SG"], post.address.values
|
391
422
|
|
@@ -397,7 +428,7 @@ class TestOhmTypecast < Test::Unit::TestCase
|
|
397
428
|
test "handles mutation" do
|
398
429
|
address = { "address1" => "#123", "city" => "Singapore", "country" => "SG"}
|
399
430
|
post = Post.create(:address => address)
|
400
|
-
|
431
|
+
|
401
432
|
post.address["address1"] = "#456"
|
402
433
|
post.save
|
403
434
|
|
@@ -408,7 +439,7 @@ class TestOhmTypecast < Test::Unit::TestCase
|
|
408
439
|
assert_equal ["address1", "city", "country"], post.address.keys
|
409
440
|
assert_equal ["#456", "Singapore", "SG"], post.address.values
|
410
441
|
end
|
411
|
-
|
442
|
+
|
412
443
|
Address = Class.new(Struct.new(:city, :country))
|
413
444
|
|
414
445
|
test "raises when trying to assign a non-hash" do
|
@@ -420,6 +451,18 @@ class TestOhmTypecast < Test::Unit::TestCase
|
|
420
451
|
Post.new(:address => Address.new)
|
421
452
|
end
|
422
453
|
end
|
454
|
+
|
455
|
+
test "inspecting" do
|
456
|
+
post = Post.create(:address => { "address1" => "#456",
|
457
|
+
"city" => "Singapore",
|
458
|
+
"country" => "SG" })
|
459
|
+
|
460
|
+
assert_equal %q{{"address1":"#456","city":"Singapore","country":"SG"}},
|
461
|
+
post.address.inspect
|
462
|
+
|
463
|
+
post.address = 'FooBar'
|
464
|
+
assert_equal %{"\\\"FooBar\\\""}, post.address.inspect
|
465
|
+
end
|
423
466
|
end
|
424
467
|
|
425
468
|
context "when using an Array" do
|
@@ -436,7 +479,7 @@ class TestOhmTypecast < Test::Unit::TestCase
|
|
436
479
|
Array
|
437
480
|
end
|
438
481
|
end
|
439
|
-
|
482
|
+
|
440
483
|
test "importing" do
|
441
484
|
assert_equal [], Ohm::Types::Array[nil]
|
442
485
|
assert_equal [], Ohm::Types::Array[""]
|
@@ -463,7 +506,7 @@ class TestOhmTypecast < Test::Unit::TestCase
|
|
463
506
|
test "handles nil case correctly" do
|
464
507
|
post = Post.create(:addresses => nil)
|
465
508
|
assert_equal([], post.addresses)
|
466
|
-
|
509
|
+
|
467
510
|
post = Post[post.id]
|
468
511
|
assert_equal([], post.addresses)
|
469
512
|
end
|
@@ -471,7 +514,7 @@ class TestOhmTypecast < Test::Unit::TestCase
|
|
471
514
|
test "handles empty string case correctly" do
|
472
515
|
post = Post.create(:addresses => "")
|
473
516
|
assert_equal([], post.addresses)
|
474
|
-
|
517
|
+
|
475
518
|
post = Post[post.id]
|
476
519
|
assert_equal([], post.addresses)
|
477
520
|
end
|
@@ -482,11 +525,11 @@ class TestOhmTypecast < Test::Unit::TestCase
|
|
482
525
|
|
483
526
|
post = Post.create(:addresses => addresses)
|
484
527
|
assert_equal addresses, post.addresses
|
485
|
-
|
528
|
+
|
486
529
|
post = Post[post.id]
|
487
530
|
assert_equal addresses, post.addresses
|
488
531
|
end
|
489
|
-
|
532
|
+
|
490
533
|
class Address < Struct.new(:city, :country)
|
491
534
|
def to_json
|
492
535
|
[city, country].to_json
|
@@ -496,10 +539,10 @@ class TestOhmTypecast < Test::Unit::TestCase
|
|
496
539
|
test "handles an arbitrary class as an element of the array" do
|
497
540
|
addresses = [Address.new("Singapore", "SG"),
|
498
541
|
Address.new("Philippines", "PH")]
|
499
|
-
|
542
|
+
|
500
543
|
post = Post.create(:addresses => addresses)
|
501
544
|
assert_equal [['Singapore', 'SG'], ['Philippines', 'PH']], post.addresses
|
502
|
-
|
545
|
+
|
503
546
|
post = Post[post.id]
|
504
547
|
assert_equal [['Singapore', 'SG'], ['Philippines', 'PH']], post.addresses
|
505
548
|
end
|
@@ -520,9 +563,23 @@ class TestOhmTypecast < Test::Unit::TestCase
|
|
520
563
|
post.addresses.push({"city" => "Hong Kong", "country" => "ZN"})
|
521
564
|
end
|
522
565
|
|
566
|
+
test "looping! and other enumerablems" do
|
567
|
+
array = [1, 2, 3]
|
568
|
+
post = Post.create(:addresses => array)
|
569
|
+
|
570
|
+
total = 0
|
571
|
+
post.addresses.each { |e| total += e }
|
572
|
+
assert_equal 6, total
|
573
|
+
|
574
|
+
post = Post[post.id]
|
575
|
+
total = 0
|
576
|
+
post.addresses.each { |e| total += e }
|
577
|
+
assert_equal 6, total
|
578
|
+
end
|
579
|
+
|
523
580
|
test "handles mutation" do
|
524
581
|
post = Post.create(:addresses => [1, 2, 3])
|
525
|
-
|
582
|
+
|
526
583
|
post.addresses.push(4, 5, 6)
|
527
584
|
post.save
|
528
585
|
|
@@ -533,7 +590,7 @@ class TestOhmTypecast < Test::Unit::TestCase
|
|
533
590
|
assert_equal 6, post.addresses.size
|
534
591
|
assert_equal [1, 2, 3, 4, 5, 6], post.addresses
|
535
592
|
end
|
536
|
-
|
593
|
+
|
537
594
|
|
538
595
|
test "raises when trying to assign a non-array" do
|
539
596
|
assert_raise TypeError do
|
@@ -544,5 +601,17 @@ class TestOhmTypecast < Test::Unit::TestCase
|
|
544
601
|
Post.new(:addresses => Address.new)
|
545
602
|
end
|
546
603
|
end
|
604
|
+
|
605
|
+
test "inspecting" do
|
606
|
+
post = Post.create(:addresses => [{ "address1" => "#456",
|
607
|
+
"city" => "Singapore",
|
608
|
+
"country" => "SG" }])
|
609
|
+
|
610
|
+
assert_equal %q{[{"address1":"#456","city":"Singapore","country":"SG"}]},
|
611
|
+
post.addresses.inspect
|
612
|
+
|
613
|
+
post.addresses = 'FooBar'
|
614
|
+
assert_equal %{"\\\"FooBar\\\""}, post.addresses.inspect
|
615
|
+
end
|
547
616
|
end
|
548
|
-
end
|
617
|
+
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
|
+
- 21
|
9
|
+
version: 0.0.21
|
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-30 00:00:00 +08:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|