rufus-jig 0.1.23 → 1.0.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/.rspec +1 -0
- data/CHANGELOG.txt +8 -0
- data/README.rdoc +41 -11
- data/Rakefile +37 -12
- data/TODO.txt +6 -3
- data/lib/rufus/jig/adapters/em.rb +21 -24
- data/lib/rufus/jig/adapters/net.rb +3 -4
- data/lib/rufus/jig/adapters/net_persistent.rb +26 -7
- data/lib/rufus/jig/adapters/patron.rb +25 -10
- data/lib/rufus/jig/couch.rb +199 -36
- data/lib/rufus/jig/http.rb +183 -90
- data/lib/rufus/jig/path.rb +4 -4
- data/lib/rufus/jig/version.rb +1 -1
- data/rufus-jig.gemspec +55 -34
- data/spec/couch/attachements_spec.rb +113 -0
- data/spec/couch/basic_auth_spec.rb +75 -0
- data/spec/couch/conditional_spec.rb +178 -0
- data/spec/couch/continuous.rb +97 -0
- data/spec/couch/couch_spec.rb +64 -0
- data/spec/couch/db_spec.rb +366 -0
- data/{test → spec/couch}/tweet.png +0 -0
- data/spec/couch/views_spec.rb +326 -0
- data/spec/couch_url.txt +2 -0
- data/spec/jig/basic_auth_spec.rb +51 -0
- data/spec/jig/conditional_spec.rb +76 -0
- data/spec/jig/delete_spec.rb +32 -0
- data/spec/jig/get_spec.rb +116 -0
- data/spec/jig/misc_spec.rb +120 -0
- data/spec/jig/new_spec.rb +95 -0
- data/spec/jig/parse_uri_spec.rb +139 -0
- data/spec/jig/post_spec.rb +79 -0
- data/spec/jig/prefix_spec.rb +51 -0
- data/spec/jig/put_spec.rb +68 -0
- data/spec/jig/timeout_spec.rb +94 -0
- data/{test → spec}/server.rb +14 -4
- data/spec/spec_helper.rb +61 -0
- data/spec/support/couch_helper.rb +14 -0
- data/spec/support/server_helper.rb +32 -0
- metadata +98 -43
- data/lib/rufus/jig/adapters/net_response.rb +0 -42
- data/test/base.rb +0 -53
- data/test/bm/bm0.rb +0 -49
- data/test/bm/bm1.rb +0 -43
- data/test/conc/put_vs_delete.rb +0 -28
- data/test/couch_base.rb +0 -52
- data/test/couch_url.txt +0 -1
- data/test/ct_0_couch.rb +0 -64
- data/test/ct_1_couchdb.rb +0 -204
- data/test/ct_2_couchdb_options.rb +0 -50
- data/test/ct_3_couchdb_views.rb +0 -106
- data/test/ct_4_attachments.rb +0 -126
- data/test/ct_5_couchdb_continuous.rb +0 -92
- data/test/cut_0_auth_couch.rb +0 -62
- data/test/test.rb +0 -28
- data/test/to.sh +0 -25
- data/test/tt_0_get_timeout.rb +0 -92
- data/test/ut_0_http_get.rb +0 -191
- data/test/ut_1_http_post.rb +0 -81
- data/test/ut_2_http_delete.rb +0 -42
- data/test/ut_3_http_put.rb +0 -105
- data/test/ut_4_http_prefix.rb +0 -50
- data/test/ut_5_http_misc.rb +0 -65
- data/test/ut_6_args.rb +0 -98
- data/test/ut_7_parse_uri.rb +0 -79
- data/test/ut_8_auth.rb +0 -37
@@ -0,0 +1,97 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
#
|
4
|
+
# specifying rufus-jig
|
5
|
+
#
|
6
|
+
# Tue Nov 30 10:16:03 JST 2010
|
7
|
+
#
|
8
|
+
|
9
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper.rb')
|
10
|
+
|
11
|
+
|
12
|
+
describe Rufus::Jig::Couch do
|
13
|
+
|
14
|
+
context 'and feed=continuous' do
|
15
|
+
|
16
|
+
before(:each) do
|
17
|
+
|
18
|
+
h = Rufus::Jig::Http.new(couch_url)
|
19
|
+
|
20
|
+
begin
|
21
|
+
h.delete('/rufus_jig_test')
|
22
|
+
rescue Exception => e
|
23
|
+
#p e
|
24
|
+
end
|
25
|
+
h.put('/rufus_jig_test', '')
|
26
|
+
h.close
|
27
|
+
|
28
|
+
@c = Rufus::Jig::Couch.new(couch_url, 'rufus_jig_test')
|
29
|
+
end
|
30
|
+
|
31
|
+
after(:each) do
|
32
|
+
|
33
|
+
@c.close
|
34
|
+
end
|
35
|
+
|
36
|
+
describe '#on_change' do
|
37
|
+
|
38
|
+
it 'intercepts changes' do
|
39
|
+
|
40
|
+
stack = []
|
41
|
+
|
42
|
+
t = Thread.new do
|
43
|
+
@c.on_change { |doc_id, deleted| stack << doc_id }
|
44
|
+
end
|
45
|
+
|
46
|
+
@c.put('_id' => 'angel0', 'name' => 'samael')
|
47
|
+
@c.put('_id' => 'angel1', 'name' => 'raphael')
|
48
|
+
|
49
|
+
sleep 0.500
|
50
|
+
t.kill
|
51
|
+
|
52
|
+
stack.size.should == 2
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'intercepts changes and docs' do
|
56
|
+
|
57
|
+
stack = []
|
58
|
+
|
59
|
+
Thread.abort_on_exception = true
|
60
|
+
|
61
|
+
t = Thread.new do
|
62
|
+
@c.on_change { |doc_id, deleted, doc| stack << doc }
|
63
|
+
end
|
64
|
+
|
65
|
+
@c.put('_id' => 'angel2', 'name' => 'samael')
|
66
|
+
@c.put('_id' => 'angel3', 'name' => 'ゆきひろ')
|
67
|
+
|
68
|
+
sleep 0.500
|
69
|
+
t.kill
|
70
|
+
|
71
|
+
stack[1]['name'].should == 'ゆきひろ'
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'intercepts changes and among them, doc deletions' do
|
75
|
+
|
76
|
+
stack = []
|
77
|
+
|
78
|
+
Thread.abort_on_exception = true
|
79
|
+
|
80
|
+
t = Thread.new do
|
81
|
+
@c.on_change { |doc_id, deleted, doc| stack << [ doc_id, deleted ] }
|
82
|
+
end
|
83
|
+
|
84
|
+
@c.put('_id' => 'angel4', 'name' => 'samael')
|
85
|
+
sleep 0.077
|
86
|
+
@c.delete(@c.get('angel4'))
|
87
|
+
|
88
|
+
sleep 0.500
|
89
|
+
t.kill
|
90
|
+
|
91
|
+
([["angel4", false], ["angel4", true]] == stack ||
|
92
|
+
[["angel4", true]] == stack).should == true
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
@@ -0,0 +1,64 @@
|
|
1
|
+
|
2
|
+
#
|
3
|
+
# specifying rufus-jig
|
4
|
+
#
|
5
|
+
# Mon Nov 29 22:14:22 JST 2010
|
6
|
+
#
|
7
|
+
|
8
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper.rb')
|
9
|
+
|
10
|
+
|
11
|
+
describe Rufus::Jig::Couch do
|
12
|
+
|
13
|
+
context 'without a particular db' do
|
14
|
+
|
15
|
+
before(:each) do
|
16
|
+
|
17
|
+
h = Rufus::Jig::Http.new(couch_url)
|
18
|
+
begin
|
19
|
+
h.delete('/rufus_jig_test')
|
20
|
+
rescue Exception => e
|
21
|
+
#p e
|
22
|
+
ensure
|
23
|
+
h.close rescue nil
|
24
|
+
end
|
25
|
+
|
26
|
+
@c = Rufus::Jig::Couch.new(couch_url)
|
27
|
+
end
|
28
|
+
|
29
|
+
after(:each) do
|
30
|
+
|
31
|
+
@c.close
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '#get' do
|
35
|
+
|
36
|
+
it 'returns a Hash instance' do
|
37
|
+
|
38
|
+
@c.get('.').keys.sort.should == %w[ couchdb version ]
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe '#put' do
|
43
|
+
|
44
|
+
it 'can put a db' do
|
45
|
+
|
46
|
+
@c.put('rufus_jig_test')
|
47
|
+
|
48
|
+
Rufus::Jig::Http.new(couch_url).get('/rufus_jig_test').should_not == nil
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe '#delete' do
|
53
|
+
|
54
|
+
it 'can delete a db' do
|
55
|
+
|
56
|
+
@c.put('rufus_jig_test')
|
57
|
+
@c.delete('rufus_jig_test')
|
58
|
+
|
59
|
+
Rufus::Jig::Http.new(couch_url).get('/rufus_jig_test').should == nil
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
@@ -0,0 +1,366 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
#
|
4
|
+
# specifying rufus-jig
|
5
|
+
#
|
6
|
+
# Mon Nov 29 22:45:31 JST 2010
|
7
|
+
#
|
8
|
+
|
9
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper.rb')
|
10
|
+
|
11
|
+
|
12
|
+
describe Rufus::Jig::Couch do
|
13
|
+
|
14
|
+
context 'with a db' do
|
15
|
+
|
16
|
+
before(:each) do
|
17
|
+
|
18
|
+
h = Rufus::Jig::Http.new(couch_url)
|
19
|
+
|
20
|
+
begin
|
21
|
+
h.delete('/rufus_jig_test')
|
22
|
+
rescue Exception => e
|
23
|
+
#p e
|
24
|
+
end
|
25
|
+
|
26
|
+
h.put('/rufus_jig_test', '')
|
27
|
+
h.put('/rufus_jig_test/coffee1', '{"_id":"coffee1","type":"ristretto"}')
|
28
|
+
|
29
|
+
h.close
|
30
|
+
|
31
|
+
@c = Rufus::Jig::Couch.new(couch_url, 'rufus_jig_test')
|
32
|
+
@doc = @c.get('coffee1', :cache => false)
|
33
|
+
end
|
34
|
+
|
35
|
+
after(:each) do
|
36
|
+
|
37
|
+
@c.close
|
38
|
+
end
|
39
|
+
|
40
|
+
describe '#path' do
|
41
|
+
|
42
|
+
it "returns the path for this couch db" do
|
43
|
+
|
44
|
+
@c.path.should == 'rufus_jig_test'
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe '#name' do
|
49
|
+
|
50
|
+
it "returns the name of this couch db" do
|
51
|
+
|
52
|
+
@c.name.should == 'rufus_jig_test'
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe '#get' do
|
57
|
+
|
58
|
+
it "returns nil when the doc doesn't exist" do
|
59
|
+
|
60
|
+
@c.get('coffee-1').should == nil
|
61
|
+
end
|
62
|
+
|
63
|
+
it "returns the doc when it exists" do
|
64
|
+
|
65
|
+
@c.get('coffee1')['type'].should == 'ristretto'
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'can get docs with UTF-8 ids' do
|
69
|
+
|
70
|
+
@c.put('_id' => 'コーヒー', 'type' => 'espresso')
|
71
|
+
|
72
|
+
@c.get('コーヒー')['type'].should == 'espresso'
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'caches documents' do
|
76
|
+
|
77
|
+
@c.get('coffee1')
|
78
|
+
@c.http.cache.size.should == 1
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'goes 200 then 304' do
|
82
|
+
|
83
|
+
@c.get('coffee1')
|
84
|
+
@c.http.last_response.status.should == 200
|
85
|
+
|
86
|
+
@c.get('coffee1')
|
87
|
+
@c.http.last_response.status.should == 304
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe '#delete(doc)' do
|
92
|
+
|
93
|
+
it 'deletes a document' do
|
94
|
+
|
95
|
+
@c.delete(@doc)
|
96
|
+
|
97
|
+
@c.get('coffee1').should == nil
|
98
|
+
end
|
99
|
+
|
100
|
+
it "returns nil when it's successful" do
|
101
|
+
|
102
|
+
@c.delete(@doc).should == nil
|
103
|
+
end
|
104
|
+
|
105
|
+
it "returns the current doc when the delete's rev is wrong" do
|
106
|
+
|
107
|
+
@doc['_rev'] = "777-12er"
|
108
|
+
|
109
|
+
@c.delete(@doc)['type'].should == 'ristretto'
|
110
|
+
end
|
111
|
+
|
112
|
+
it "returns true when the doc is already gone" do
|
113
|
+
|
114
|
+
@c.delete(@doc)
|
115
|
+
|
116
|
+
@c.delete(@doc).should == true
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe '#delete(id, rev)' do
|
121
|
+
|
122
|
+
it 'deletes a document' do
|
123
|
+
|
124
|
+
@c.delete(@doc['_id'], @doc['_rev'])
|
125
|
+
|
126
|
+
@c.get('coffee1').should == nil
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'returns nil when successful' do
|
130
|
+
|
131
|
+
@c.delete(@doc['_id'], @doc['_rev']).should == nil
|
132
|
+
end
|
133
|
+
|
134
|
+
it 'returns the current doc if the rev is outdated' do
|
135
|
+
|
136
|
+
@c.delete(@doc['_id'], '999-2')['type'].should == 'ristretto'
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'returns true if the doc is already gone' do
|
140
|
+
|
141
|
+
@c.delete(@doc)
|
142
|
+
|
143
|
+
@c.delete(@doc['_id'], @doc['_rev']).should == true
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
describe '#put' do
|
148
|
+
|
149
|
+
it 'returns nil when the put was successful' do
|
150
|
+
|
151
|
+
@c.put({ '_id' => 'coffee0', 'type' => 'espresso' }).should == nil
|
152
|
+
end
|
153
|
+
|
154
|
+
it 'returns the current doc if the put has the wrong _rev' do
|
155
|
+
|
156
|
+
@c.put({ '_id' => 'coffee1', 'type' => 'espresso' })['type'].should ==
|
157
|
+
'ristretto'
|
158
|
+
end
|
159
|
+
|
160
|
+
it 'returns true when putting a doc that is gone' do
|
161
|
+
|
162
|
+
@c.delete(@doc)
|
163
|
+
|
164
|
+
@c.put(@doc).should == true
|
165
|
+
end
|
166
|
+
|
167
|
+
it 'updates the _rev of the doc when :update_rev => true' do
|
168
|
+
|
169
|
+
rev = @doc['_rev']
|
170
|
+
@c.put(@doc, :update_rev => true)
|
171
|
+
|
172
|
+
@doc['_rev'].should_not == rev
|
173
|
+
end
|
174
|
+
|
175
|
+
it 'returns true when putting a doc in a missing db' do
|
176
|
+
|
177
|
+
@c.delete('.')
|
178
|
+
|
179
|
+
@c.put({ '_id' => 'coffee0', 'type' => 'espresso' }).should == true
|
180
|
+
end
|
181
|
+
|
182
|
+
it 'can put UTF-8 stuff' do
|
183
|
+
|
184
|
+
@c.put('_id' => 'コーヒー', 'type' => 'espresso').should == nil
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
describe '#all' do
|
189
|
+
|
190
|
+
before(:each) do
|
191
|
+
|
192
|
+
@c.put({
|
193
|
+
'_id' => '_design/my_test',
|
194
|
+
'views' => {
|
195
|
+
'my_view' => {
|
196
|
+
'map' => "function(doc) { emit(doc['type'], null); }"
|
197
|
+
}
|
198
|
+
}
|
199
|
+
})
|
200
|
+
|
201
|
+
3.times { |i| @c.put({ '_id' => "tea#{i}" }) }
|
202
|
+
end
|
203
|
+
|
204
|
+
it 'gets many docs at once' do
|
205
|
+
|
206
|
+
docs = @c.all
|
207
|
+
|
208
|
+
docs.collect { |doc| doc['_id'] }.should == %w[
|
209
|
+
_design/my_test coffee1 tea0 tea1 tea2
|
210
|
+
]
|
211
|
+
end
|
212
|
+
|
213
|
+
it 'accepts parameters like :limit' do
|
214
|
+
|
215
|
+
docs = @c.all(:skip => 2, :limit => 1)
|
216
|
+
|
217
|
+
docs.collect { |doc| doc.delete('_rev'); doc }.should == [
|
218
|
+
{ '_id' => 'tea0' }
|
219
|
+
]
|
220
|
+
end
|
221
|
+
|
222
|
+
it 'accepts the :keys parameters' do
|
223
|
+
|
224
|
+
docs = @c.all(:keys => %w[ tea1 tea2 ])
|
225
|
+
|
226
|
+
docs.collect { |doc| doc.delete('_rev'); doc }.should == [
|
227
|
+
{ '_id' => 'tea1' }, { '_id' => 'tea2' }
|
228
|
+
]
|
229
|
+
end
|
230
|
+
|
231
|
+
it 'returns immediately [] if :keys => []' do
|
232
|
+
|
233
|
+
lroi = @c.http.last_response.object_id
|
234
|
+
docs = @c.all(:keys => [])
|
235
|
+
|
236
|
+
docs.should == []
|
237
|
+
@c.http.last_response.object_id.should == lroi
|
238
|
+
end
|
239
|
+
|
240
|
+
it 'accepts :include_docs => false' do
|
241
|
+
|
242
|
+
docs = @c.all(:include_docs => false)
|
243
|
+
|
244
|
+
docs.size.should == 5
|
245
|
+
|
246
|
+
docs.inject([]) { |a, doc| a.concat(doc.keys) }.uniq.sort.should ==
|
247
|
+
%w[ _id _rev ]
|
248
|
+
end
|
249
|
+
|
250
|
+
it "doesn't list design docs when :include_design_docs => false" do
|
251
|
+
|
252
|
+
@c.all(
|
253
|
+
:include_design_docs => false
|
254
|
+
).collect { |d|
|
255
|
+
d['_id']
|
256
|
+
}.should == %w[
|
257
|
+
coffee1 tea0 tea1 tea2
|
258
|
+
]
|
259
|
+
end
|
260
|
+
|
261
|
+
it 'is OK with nil parameters' do
|
262
|
+
|
263
|
+
docs = @c.all(:skip => 3, :limit => nil)
|
264
|
+
|
265
|
+
docs.collect { |doc| doc['_id'] }.should == %w[ tea1 tea2 ]
|
266
|
+
end
|
267
|
+
|
268
|
+
it 'leaves the opts hash untouched' do
|
269
|
+
|
270
|
+
opts = { :skip => 3, :limit => nil }
|
271
|
+
|
272
|
+
@c.all(opts)
|
273
|
+
|
274
|
+
opts.should == { :skip => 3, :limit => nil }
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
describe '#ids' do
|
279
|
+
|
280
|
+
before(:each) do
|
281
|
+
@c.put({
|
282
|
+
'_id' => '_design/my_test',
|
283
|
+
'views' => {
|
284
|
+
'my_view' => {
|
285
|
+
'map' => "function(doc) { emit(doc['type'], null); }"
|
286
|
+
}
|
287
|
+
}
|
288
|
+
})
|
289
|
+
end
|
290
|
+
|
291
|
+
it 'list all ids' do
|
292
|
+
|
293
|
+
@c.ids.should == %w[ _design/my_test coffee1 ]
|
294
|
+
end
|
295
|
+
|
296
|
+
it 'list all ids but :include_design_docs => false' do
|
297
|
+
|
298
|
+
@c.ids(:include_design_docs => false).should == %w[ coffee1 ]
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
describe '#bulk_put' do
|
303
|
+
|
304
|
+
it 'creates many docs at once' do
|
305
|
+
|
306
|
+
@c.bulk_put([
|
307
|
+
{ '_id' => 'h0', 'msg' => 'ok' },
|
308
|
+
{ '_id' => 'h1', 'msg' => 'not ok' }
|
309
|
+
])
|
310
|
+
|
311
|
+
@c.ids.should == %w[ coffee1 h0 h1 ]
|
312
|
+
end
|
313
|
+
|
314
|
+
it "returns a list [ { '_id' => x, '_rev' => y } ]" do
|
315
|
+
|
316
|
+
res = @c.bulk_put([
|
317
|
+
{ '_id' => 'h2', 'msg' => 'ok' },
|
318
|
+
{ '_id' => 'h3', 'msg' => 'not ok' }
|
319
|
+
])
|
320
|
+
|
321
|
+
res.collect { |row| row['_id'] }.should ==
|
322
|
+
%w[ h2 h3 ]
|
323
|
+
res.collect { |row| row.keys }.flatten.uniq.sort.should ==
|
324
|
+
%w[ _id _rev ]
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
328
|
+
describe '#bulk_delete' do
|
329
|
+
|
330
|
+
before(:each) do
|
331
|
+
3.times { |i| @c.put({ '_id' => "macha#{i}" }) }
|
332
|
+
end
|
333
|
+
|
334
|
+
it 'deletes in bulk' do
|
335
|
+
|
336
|
+
docs = @c.all(:keys => %w[ coffee1 macha1 ])
|
337
|
+
|
338
|
+
@c.bulk_delete(docs)
|
339
|
+
|
340
|
+
@c.ids.should == %w[ macha0 macha2 ]
|
341
|
+
end
|
342
|
+
|
343
|
+
it 'is OK with nil docs' do
|
344
|
+
|
345
|
+
docs = @c.all(:keys => %w[ nada macha1 ])
|
346
|
+
|
347
|
+
@c.bulk_delete(docs)
|
348
|
+
|
349
|
+
@c.ids.should == %w[ coffee1 macha0 macha2 ]
|
350
|
+
end
|
351
|
+
|
352
|
+
it 'returns the list of deleted docs' do
|
353
|
+
|
354
|
+
docs = @c.all(:keys => %w[ nada macha1 ])
|
355
|
+
|
356
|
+
res = @c.bulk_delete(docs)
|
357
|
+
|
358
|
+
res.collect { |doc| doc['_id'] }.should == %w[ macha1 ]
|
359
|
+
|
360
|
+
res.first['_rev'].should match(/^2-/)
|
361
|
+
# does it deserve its own spec ?
|
362
|
+
end
|
363
|
+
end
|
364
|
+
end
|
365
|
+
end
|
366
|
+
|