yssk22-couch_resource 0.1.0
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/LICENSE +2 -0
- data/MIT_LICENSE +8 -0
- data/README.rdoc +7 -0
- data/lib/couch_resource.rb +25 -0
- data/lib/couch_resource/base.rb +705 -0
- data/lib/couch_resource/callbacks.rb +103 -0
- data/lib/couch_resource/connection.rb +194 -0
- data/lib/couch_resource/error.rb +3 -0
- data/lib/couch_resource/struct.rb +340 -0
- data/lib/couch_resource/validations.rb +520 -0
- data/lib/couch_resource/view.rb +228 -0
- data/test/test_base.rb +384 -0
- data/test/test_callbacks.rb +115 -0
- data/test/test_connection.rb +39 -0
- data/test/test_struct.rb +332 -0
- data/test/test_validations.rb +186 -0
- metadata +70 -0
@@ -0,0 +1,115 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require File.join(File.dirname(__FILE__), "../lib/couch_resource")
|
3
|
+
TEST_DB_PATH = "/couch_resource_callback_test"
|
4
|
+
|
5
|
+
class CallbackOrderTest < CouchResource::Base
|
6
|
+
self.database = "http://localhost:5984/#{TEST_DB_PATH}"
|
7
|
+
string :title
|
8
|
+
def callback_orders
|
9
|
+
@callback_orders ||= []
|
10
|
+
end
|
11
|
+
CouchResource::Callbacks::CALLBACKS.each do |callback|
|
12
|
+
module_eval "def #{callback}; callback_orders << :#{callback}; end"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class StopCallbackTest < CouchResource::Base
|
17
|
+
self.database = "http://localhost:5984/#{TEST_DB_PATH}"
|
18
|
+
string :stopper_method
|
19
|
+
def called_callbacks
|
20
|
+
@called_callbacks ||= []
|
21
|
+
end
|
22
|
+
[:before_validation, :before_validation_on_create, :before_validation_on_update,
|
23
|
+
:before_save, :before_create, :before_update, :before_destroy].each do |callback|
|
24
|
+
module_eval <<-EOS
|
25
|
+
def #{callback};
|
26
|
+
called_callbacks << :#{callback}
|
27
|
+
return false if self.stopper_method.to_s == "#{callback}"
|
28
|
+
end
|
29
|
+
EOS
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
class TestValidations < Test::Unit::TestCase
|
36
|
+
def setup
|
37
|
+
res = CallbackOrderTest.connection.put(CallbackOrderTest.database.path)
|
38
|
+
unless res[:ok]
|
39
|
+
puts "Failed to create test database. Check couchdb server running."
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def teardown
|
44
|
+
res = CallbackOrderTest.connection.delete(CallbackOrderTest.database.path)
|
45
|
+
unless res[:ok]
|
46
|
+
puts "Failed to drop test database. Delete manually before you test next time."
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_callback_order
|
51
|
+
obj = CallbackOrderTest.new
|
52
|
+
|
53
|
+
# after_initialize
|
54
|
+
assert_equal [:after_initialize], obj.callback_orders
|
55
|
+
obj.callback_orders.clear
|
56
|
+
|
57
|
+
# validate and save callbacks
|
58
|
+
obj.title = "hoge"
|
59
|
+
assert obj.save
|
60
|
+
assert_not_nil obj.callback_orders
|
61
|
+
assert_equal [:before_validation, :before_validation_on_create,
|
62
|
+
:after_validation, :after_validation_on_create,
|
63
|
+
:before_save, :before_create,
|
64
|
+
:after_create, :after_save], obj.callback_orders
|
65
|
+
obj.callback_orders.clear
|
66
|
+
assert obj.save
|
67
|
+
assert_equal [:before_validation, :before_validation_on_update,
|
68
|
+
:after_validation, :after_validation_on_update,
|
69
|
+
:before_save, :before_update,
|
70
|
+
:after_update, :after_save], obj.callback_orders
|
71
|
+
obj.callback_orders.clear
|
72
|
+
|
73
|
+
# after_find
|
74
|
+
obj2 = CallbackOrderTest.find(obj.id)
|
75
|
+
assert_equal [:after_initialize, :after_find], obj2.callback_orders
|
76
|
+
obj2.callback_orders.clear
|
77
|
+
|
78
|
+
# destroy
|
79
|
+
assert obj.destroy
|
80
|
+
assert_equal [:before_destroy, :after_destroy], obj.callback_orders
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_stop_callback
|
84
|
+
obj = StopCallbackTest.new
|
85
|
+
|
86
|
+
befores = [:before_validation, :before_validation_on_create,
|
87
|
+
:before_save, :before_create]
|
88
|
+
|
89
|
+
befores.each_with_index do |stopper, index|
|
90
|
+
obj.stopper_method = stopper
|
91
|
+
assert !obj.save, "unexpected saving not working stopper (#{stopper})"
|
92
|
+
assert_equal befores[0..index], obj.called_callbacks
|
93
|
+
obj.called_callbacks.clear
|
94
|
+
end
|
95
|
+
|
96
|
+
obj.stopper_method = nil
|
97
|
+
assert obj.save
|
98
|
+
obj.called_callbacks.clear
|
99
|
+
|
100
|
+
befores = [:before_validation, :before_validation_on_update,
|
101
|
+
:before_save, :before_update]
|
102
|
+
befores.each_with_index do |stopper, index|
|
103
|
+
obj.stopper_method = stopper
|
104
|
+
assert !obj.save, "unexpected saving not working stopper (#{stopper})"
|
105
|
+
assert_equal befores[0..index], obj.called_callbacks
|
106
|
+
obj.called_callbacks.clear
|
107
|
+
end
|
108
|
+
|
109
|
+
obj.called_callbacks.clear
|
110
|
+
obj.stopper_method = :before_destroy
|
111
|
+
assert !obj.destroy
|
112
|
+
assert_not_nil obj.rev
|
113
|
+
assert_equal [:before_destroy], obj.called_callbacks
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require File.join(File.dirname(__FILE__), "../lib/couch_resource/connection")
|
3
|
+
|
4
|
+
TEST_DB_PATH = "/couch_resource_connection_test"
|
5
|
+
|
6
|
+
class TestStruct < Test::Unit::TestCase
|
7
|
+
def setup
|
8
|
+
@connection = CouchResource::Connection.new("http://localhost:5984")
|
9
|
+
begin
|
10
|
+
res = @connection.put(TEST_DB_PATH)
|
11
|
+
rescue CouchResource::ResourceConflict, CouchResource::PreconditionFailed => e
|
12
|
+
@connection.delete(TEST_DB_PATH)
|
13
|
+
retry
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_get
|
18
|
+
res = @connection.get("/")
|
19
|
+
assert_not_nil res[:couchdb]
|
20
|
+
assert_equal "Welcome", res[:couchdb]
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_normalize_hash
|
24
|
+
res = @connection.post(TEST_DB_PATH, {
|
25
|
+
:a => {:b => { :c => [1,2,3]}}
|
26
|
+
}.to_json)
|
27
|
+
assert_not_nil res[:id]
|
28
|
+
id = res[:id]
|
29
|
+
res = @connection.get(File.join(TEST_DB_PATH, id))
|
30
|
+
assert_not_nil res[:_id]
|
31
|
+
assert_not_nil res[:a]
|
32
|
+
assert_not_nil res[:a][:b]
|
33
|
+
assert_not_nil res[:a][:b][:c]
|
34
|
+
assert_not_nil res["_id"]
|
35
|
+
assert_not_nil res["a"]
|
36
|
+
assert_not_nil res["a"]["b"]
|
37
|
+
assert_not_nil res["a"]["b"]["c"]
|
38
|
+
end
|
39
|
+
end
|
data/test/test_struct.rb
ADDED
@@ -0,0 +1,332 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
|
3
|
+
require File.join(File.dirname(__FILE__), "../lib/couch_resource/struct")
|
4
|
+
|
5
|
+
class StringTest
|
6
|
+
include CouchResource::Struct
|
7
|
+
string :member
|
8
|
+
string :nillable_member, :allow_nil => true
|
9
|
+
end
|
10
|
+
|
11
|
+
class NumberTest
|
12
|
+
include CouchResource::Struct
|
13
|
+
number :member
|
14
|
+
end
|
15
|
+
|
16
|
+
class BooleanTest
|
17
|
+
include CouchResource::Struct
|
18
|
+
boolean :member
|
19
|
+
end
|
20
|
+
|
21
|
+
class ArrayTest
|
22
|
+
include CouchResource::Struct
|
23
|
+
array :member
|
24
|
+
end
|
25
|
+
|
26
|
+
class ObjectTest
|
27
|
+
include CouchResource::Struct
|
28
|
+
object :member
|
29
|
+
end
|
30
|
+
|
31
|
+
class CollectionTest
|
32
|
+
include CouchResource::Struct
|
33
|
+
class NestedClass
|
34
|
+
include CouchResource::Struct
|
35
|
+
string :member
|
36
|
+
end
|
37
|
+
collection :member, :each => NestedClass
|
38
|
+
end
|
39
|
+
|
40
|
+
class NestedObjectTest
|
41
|
+
include CouchResource::Struct
|
42
|
+
class NestedClass
|
43
|
+
include CouchResource::Struct
|
44
|
+
object :member
|
45
|
+
end
|
46
|
+
object :nest, :is_a => NestedClass
|
47
|
+
end
|
48
|
+
|
49
|
+
class DateTimeTest
|
50
|
+
include CouchResource::Struct
|
51
|
+
datetime :member
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
class TestStruct < Test::Unit::TestCase
|
56
|
+
def test_string
|
57
|
+
obj = StringTest.new
|
58
|
+
# test attribute (with implicit type conversion)
|
59
|
+
obj.member = "hogehoge"
|
60
|
+
assert_equal "hogehoge", obj.member
|
61
|
+
obj.member = 1
|
62
|
+
assert_equal "1", obj.member
|
63
|
+
obj.member = true
|
64
|
+
assert_equal "true", obj.member
|
65
|
+
obj.member = [1,2,3]
|
66
|
+
assert_equal "123", obj.member
|
67
|
+
obj.member = { :hoge => :fuga }
|
68
|
+
assert_equal "hogefuga", obj.member
|
69
|
+
|
70
|
+
# test to_hash
|
71
|
+
obj.member = "hogehoge"
|
72
|
+
assert_equal({ "class" => "StringTest",
|
73
|
+
"member" => "hogehoge",
|
74
|
+
"nillable_member" => nil},
|
75
|
+
obj.to_hash)
|
76
|
+
|
77
|
+
# test from_hash
|
78
|
+
assert_equal obj.member, StringTest.from_hash(obj.to_hash).member
|
79
|
+
|
80
|
+
# test allow_nil
|
81
|
+
obj.nillable_member = "a"
|
82
|
+
assert_equal "a", obj.nillable_member
|
83
|
+
obj.nillable_member = nil
|
84
|
+
assert_nil obj.nillable_member
|
85
|
+
obj.nillable_member = false
|
86
|
+
assert_nil obj.nillable_member
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_number
|
91
|
+
obj = NumberTest.new
|
92
|
+
# test attribute (with implicit type conversion)
|
93
|
+
obj.member = 10
|
94
|
+
assert_equal 10, obj.member
|
95
|
+
obj.member = 10.1
|
96
|
+
assert_equal 10.1, obj.member
|
97
|
+
obj.member = "hogehoge"
|
98
|
+
assert_equal 0, obj.member
|
99
|
+
obj.member = "111"
|
100
|
+
assert_equal 111, obj.member
|
101
|
+
obj.member = true
|
102
|
+
assert_equal 0, obj.member
|
103
|
+
obj.member = [1,2,3]
|
104
|
+
assert_equal 123, obj.member # because [1,2,3] (to_s) => "123" (to_i) =>
|
105
|
+
obj.member = { :hoge => :fuga }
|
106
|
+
assert_equal 0, obj.member
|
107
|
+
|
108
|
+
|
109
|
+
# test to_hash
|
110
|
+
obj.member = 10
|
111
|
+
assert_equal({"class" => "NumberTest", "member" => 10},
|
112
|
+
obj.to_hash)
|
113
|
+
|
114
|
+
# test from_hash
|
115
|
+
assert_equal obj.member, NumberTest.from_hash(obj.to_hash).member
|
116
|
+
end
|
117
|
+
|
118
|
+
def test_boolean
|
119
|
+
obj = BooleanTest.new
|
120
|
+
# test attribute (with implicit type conversion)
|
121
|
+
obj.member = true
|
122
|
+
assert obj.member
|
123
|
+
assert obj.member?
|
124
|
+
obj.member = 10
|
125
|
+
assert_equal true, obj.member
|
126
|
+
obj.member = 10.1
|
127
|
+
assert_equal true, obj.member
|
128
|
+
obj.member = "hogehoge"
|
129
|
+
assert_equal true, obj.member
|
130
|
+
obj.member = "111"
|
131
|
+
assert_equal true, obj.member
|
132
|
+
obj.member = [1,2,3]
|
133
|
+
assert_equal true, obj.member # because [1,2,3] (to_s) => "123" (to_i) =>
|
134
|
+
obj.member = { :hoge => :fuga }
|
135
|
+
assert_equal true, obj.member
|
136
|
+
obj.member = false
|
137
|
+
assert !obj.member
|
138
|
+
assert !obj.member?
|
139
|
+
|
140
|
+
# test to_hash
|
141
|
+
obj.member = true
|
142
|
+
assert_equal({"class" => "BooleanTest", "member" => true},
|
143
|
+
obj.to_hash)
|
144
|
+
# test from_hash
|
145
|
+
assert_equal obj.member, BooleanTest.from_hash(obj.to_hash).member
|
146
|
+
|
147
|
+
obj.member = false
|
148
|
+
assert_equal({"class" => "BooleanTest", "member" => false},
|
149
|
+
obj.to_hash)
|
150
|
+
# test from_hash
|
151
|
+
assert_equal obj.member, BooleanTest.from_hash(obj.to_hash).member
|
152
|
+
|
153
|
+
|
154
|
+
|
155
|
+
end
|
156
|
+
|
157
|
+
def test_array
|
158
|
+
obj = ArrayTest.new
|
159
|
+
# test attribute (with implicit type conversion)
|
160
|
+
obj.member = []
|
161
|
+
assert_equal [], obj.member
|
162
|
+
obj.member = 10
|
163
|
+
assert_equal [10], obj.member
|
164
|
+
obj.member = 10.1
|
165
|
+
assert_equal [10.1], obj.member
|
166
|
+
obj.member = "hogehoge"
|
167
|
+
assert_equal ["hogehoge"], obj.member
|
168
|
+
obj.member = [1,2,3]
|
169
|
+
assert_equal [1,2,3], obj.member # because [1,2,3] (to_s) => "123" (to_i) =>
|
170
|
+
obj.member = { :hoge => :fuga }
|
171
|
+
assert_equal [[:hoge , :fuga]] , obj.member
|
172
|
+
|
173
|
+
# test to_hash
|
174
|
+
obj.member = []
|
175
|
+
assert_equal({"class" => "ArrayTest", "member" => []},
|
176
|
+
obj.to_hash)
|
177
|
+
assert_equal obj.member, ArrayTest.from_hash(obj.to_hash).member
|
178
|
+
|
179
|
+
# test from_hash
|
180
|
+
obj.member = "hoge"
|
181
|
+
assert_equal ["hoge"], obj.member
|
182
|
+
assert_equal({"class" => "ArrayTest", "member" => ["hoge"]},
|
183
|
+
obj.to_hash)
|
184
|
+
assert_equal obj.member, ArrayTest.from_hash(obj.to_hash).member
|
185
|
+
end
|
186
|
+
|
187
|
+
def test_collection
|
188
|
+
obj = CollectionTest.new
|
189
|
+
# test attribute (with implicit type conversion)
|
190
|
+
obj.member = []
|
191
|
+
assert_equal [], obj.member
|
192
|
+
obj.member = 10
|
193
|
+
assert_equal [], obj.member
|
194
|
+
obj.member = 10.1
|
195
|
+
assert_equal [], obj.member
|
196
|
+
obj.member = "hogehoge"
|
197
|
+
assert_equal [], obj.member
|
198
|
+
obj.member = [1,2,3]
|
199
|
+
assert_equal [], obj.member # because [1,2,3] (to_s) => "123" (to_i) =>
|
200
|
+
obj.member = { :hoge => :fuga }
|
201
|
+
assert_equal [] , obj.member
|
202
|
+
|
203
|
+
obj.member = []
|
204
|
+
obj.member << CollectionTest::NestedClass.from_hash({:member => "hoge"})
|
205
|
+
|
206
|
+
assert_equal "hoge", obj.member.first.member
|
207
|
+
|
208
|
+
#obj.member = []
|
209
|
+
#obj.member << {:member => "hoge"}
|
210
|
+
|
211
|
+
# test to_hash
|
212
|
+
obj.member = []
|
213
|
+
assert_equal({"class" => "CollectionTest", "member" => []},
|
214
|
+
obj.to_hash)
|
215
|
+
assert_equal obj.member, CollectionTest.from_hash(obj.to_hash).member
|
216
|
+
|
217
|
+
# test from_hash
|
218
|
+
obj.member = "hoge"
|
219
|
+
assert_equal [], obj.member
|
220
|
+
assert_equal({"class" => "CollectionTest", "member" => []},
|
221
|
+
obj.to_hash)
|
222
|
+
assert_equal obj.member, CollectionTest.from_hash(obj.to_hash).member
|
223
|
+
end
|
224
|
+
|
225
|
+
def test_object
|
226
|
+
obj = ObjectTest.new
|
227
|
+
# test attribute (with implicit type conversion)
|
228
|
+
obj.member = []
|
229
|
+
assert_nil obj.member
|
230
|
+
obj.member = 10
|
231
|
+
assert_nil obj.member
|
232
|
+
obj.member = 10.1
|
233
|
+
assert_nil obj.member
|
234
|
+
obj.member = "hogehoge"
|
235
|
+
assert_nil obj.member
|
236
|
+
obj.member = [1,2,3]
|
237
|
+
assert_nil obj.member
|
238
|
+
obj.member = { "hoge" => :fuga }
|
239
|
+
assert_equal({ "hoge" => :fuga }, obj.member)
|
240
|
+
|
241
|
+
# test to_hash & from_hash
|
242
|
+
obj.member = nil
|
243
|
+
assert_nil obj.member
|
244
|
+
assert_equal({ "class" => "ObjectTest",
|
245
|
+
"member" => nil
|
246
|
+
}, obj.to_hash)
|
247
|
+
assert_equal obj.member, ObjectTest.from_hash(obj.to_hash).member
|
248
|
+
obj.member = {
|
249
|
+
:hoge => :fuga,
|
250
|
+
:foo => :bar
|
251
|
+
}
|
252
|
+
assert_equal :fuga, obj.member[:hoge]
|
253
|
+
assert_equal :bar, obj.member[:foo]
|
254
|
+
assert_equal({ "class" => "ObjectTest",
|
255
|
+
"member" => {
|
256
|
+
"hoge" => :fuga,
|
257
|
+
"foo" => :bar
|
258
|
+
}},
|
259
|
+
obj.to_hash)
|
260
|
+
assert_equal obj.member, ObjectTest.from_hash(obj.to_hash).member
|
261
|
+
end
|
262
|
+
|
263
|
+
def test_nested_object
|
264
|
+
obj = NestedObjectTest.new
|
265
|
+
assert_nil obj.nest
|
266
|
+
assert_equal({ "class" => "NestedObjectTest",
|
267
|
+
"nest" => nil
|
268
|
+
}, obj.to_hash)
|
269
|
+
obj.nest = NestedObjectTest::NestedClass.new
|
270
|
+
assert_not_nil obj.nest
|
271
|
+
assert_equal({ "class" => "NestedObjectTest",
|
272
|
+
"nest" => {
|
273
|
+
"class" => "NestedObjectTest::NestedClass",
|
274
|
+
"member" => nil
|
275
|
+
}
|
276
|
+
}, obj.to_hash)
|
277
|
+
assert_equal obj.nest.member, NestedObjectTest.from_hash(obj.to_hash).nest.member
|
278
|
+
|
279
|
+
obj.nest.member = {
|
280
|
+
:hoge => :fuga,
|
281
|
+
:foo => :bar
|
282
|
+
}
|
283
|
+
assert_equal :fuga, obj.nest.member[:hoge]
|
284
|
+
assert_equal :bar, obj.nest.member[:foo]
|
285
|
+
assert_equal({"class" => "NestedObjectTest",
|
286
|
+
"nest" => {
|
287
|
+
"class" => "NestedObjectTest::NestedClass",
|
288
|
+
"member" => {
|
289
|
+
"hoge" => :fuga,
|
290
|
+
"foo" => :bar
|
291
|
+
}
|
292
|
+
}
|
293
|
+
},
|
294
|
+
obj.to_hash)
|
295
|
+
assert_equal obj.nest.member[:hoge], NestedObjectTest.from_hash(obj.to_hash).nest.member[:hoge]
|
296
|
+
assert_equal obj.nest.member[:foo], NestedObjectTest.from_hash(obj.to_hash).nest.member[:foo]
|
297
|
+
|
298
|
+
end
|
299
|
+
|
300
|
+
def test_datetime
|
301
|
+
obj = DateTimeTest.new
|
302
|
+
obj.member = Time.now
|
303
|
+
assert_not_nil obj.member
|
304
|
+
obj.member = Date.today
|
305
|
+
assert_not_nil obj.member
|
306
|
+
obj.member = DateTime.now
|
307
|
+
assert_not_nil obj.member
|
308
|
+
# test attribute (with implicit type conversion)
|
309
|
+
obj.member = DateTime.now.to_s
|
310
|
+
assert_not_nil obj.member
|
311
|
+
obj.member = "hogehoge"
|
312
|
+
assert_nil obj.member
|
313
|
+
obj.member = 1
|
314
|
+
assert_nil obj.member
|
315
|
+
obj.member = true
|
316
|
+
assert_nil obj.member
|
317
|
+
obj.member = [1,2,3,4,5,6]
|
318
|
+
assert_nil obj.member
|
319
|
+
obj.member = { :hoge => :fuga }
|
320
|
+
assert_nil obj.member
|
321
|
+
|
322
|
+
# test to_hash
|
323
|
+
d = DateTime.now
|
324
|
+
obj.member = d
|
325
|
+
assert_equal({ "class" => "DateTimeTest",
|
326
|
+
"member" => d},
|
327
|
+
obj.to_hash)
|
328
|
+
|
329
|
+
# test from_hash
|
330
|
+
assert_equal obj.member, DateTimeTest.from_hash(obj.to_hash).member
|
331
|
+
end
|
332
|
+
end
|