ohm-contrib 0.0.20 → 0.0.21
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/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
|