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
File without changes
|
@@ -0,0 +1,326 @@
|
|
1
|
+
|
2
|
+
#
|
3
|
+
# specifying rufus-jig
|
4
|
+
#
|
5
|
+
# Tue Nov 30 08:40:05 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 'with views' do
|
14
|
+
|
15
|
+
before(:each) do
|
16
|
+
|
17
|
+
h = Rufus::Jig::Http.new(couch_url)
|
18
|
+
|
19
|
+
begin
|
20
|
+
h.delete('/rufus_jig_test')
|
21
|
+
rescue Exception => e
|
22
|
+
#p e
|
23
|
+
end
|
24
|
+
|
25
|
+
h.put('/rufus_jig_test', '')
|
26
|
+
|
27
|
+
h.put('/rufus_jig_test/c0', '{"_id":"c0","type":"espresso"}')
|
28
|
+
h.put('/rufus_jig_test/c1', '{"_id":"c1","type":"ristretto"}')
|
29
|
+
h.put('/rufus_jig_test/c2', '{"_id":"c2","type":"macchiato"}')
|
30
|
+
h.put('/rufus_jig_test/c3', '{"_id":"c3","type":"capuccino"}')
|
31
|
+
h.put('/rufus_jig_test/c4', '{"_id":"c4","type":"macchiato"}')
|
32
|
+
h.put('/rufus_jig_test/c5', '{"_id":"c5","type":"veloce espresso"}')
|
33
|
+
|
34
|
+
h.put(
|
35
|
+
'/rufus_jig_test/_design/my_test',
|
36
|
+
{
|
37
|
+
'_id' => '_design/my_test',
|
38
|
+
'views' => {
|
39
|
+
'my_view' => {
|
40
|
+
'map' => "function(doc) { emit(doc['type'], null); }"
|
41
|
+
},
|
42
|
+
'my_reduced_view' => {
|
43
|
+
'map' => "function(doc) { emit(doc['type'], 1); }",
|
44
|
+
'reduce' => "_count"
|
45
|
+
},
|
46
|
+
'my_double_view' => {
|
47
|
+
'map' => "function(doc) { emit(doc['type'], null); emit(doc['type'], null); }"
|
48
|
+
}
|
49
|
+
}
|
50
|
+
},
|
51
|
+
:content_type => :json)
|
52
|
+
|
53
|
+
h.close
|
54
|
+
|
55
|
+
@c = Rufus::Jig::Couch.new(couch_url, 'rufus_jig_test')
|
56
|
+
end
|
57
|
+
|
58
|
+
after(:each) do
|
59
|
+
|
60
|
+
@c.close
|
61
|
+
end
|
62
|
+
|
63
|
+
describe '#get from view' do
|
64
|
+
|
65
|
+
it 'returns the result set' do
|
66
|
+
|
67
|
+
@c.get('_design/my_test/_view/my_view').should == {
|
68
|
+
"total_rows"=>6,
|
69
|
+
"offset"=>0,
|
70
|
+
"rows"=> [
|
71
|
+
{"id"=>"c3", "key"=>"capuccino", "value"=>nil},
|
72
|
+
{"id"=>"c0", "key"=>"espresso", "value"=>nil},
|
73
|
+
{"id"=>"c2", "key"=>"macchiato", "value"=>nil},
|
74
|
+
{"id"=>"c4", "key"=>"macchiato", "value"=>nil},
|
75
|
+
{"id"=>"c1", "key"=>"ristretto", "value"=>nil},
|
76
|
+
{"id"=>"c5", "key"=>"veloce espresso", "value"=>nil}
|
77
|
+
]
|
78
|
+
}
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe '#post keys to view' do
|
83
|
+
|
84
|
+
it 'returns the desired docs' do
|
85
|
+
|
86
|
+
@c.post(
|
87
|
+
'_design/my_test/_view/my_view',
|
88
|
+
{ 'keys' => [ 'espresso', 'macchiato' ] }
|
89
|
+
).should == {
|
90
|
+
"total_rows"=>6,
|
91
|
+
"offset"=>1,
|
92
|
+
"rows"=> [
|
93
|
+
{"id"=>"c0", "key"=>"espresso", "value"=>nil},
|
94
|
+
{"id"=>"c2", "key"=>"macchiato", "value"=>nil},
|
95
|
+
{"id"=>"c4", "key"=>"macchiato", "value"=>nil}
|
96
|
+
]
|
97
|
+
}
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'returns no row when the key points to nothing' do
|
101
|
+
|
102
|
+
@c.post(
|
103
|
+
'_design/my_test/_view/my_view',
|
104
|
+
{ 'keys' => [ 'espresso', 'macha' ] }
|
105
|
+
).should == {
|
106
|
+
"total_rows"=>6,
|
107
|
+
"offset"=>1,
|
108
|
+
"rows"=> [
|
109
|
+
{"id"=>"c0", "key"=>"espresso", "value"=>nil}
|
110
|
+
]
|
111
|
+
}
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
describe '#nuke_design_documents' do
|
116
|
+
|
117
|
+
it 'removes design documents from the db' do
|
118
|
+
|
119
|
+
@c.nuke_design_documents
|
120
|
+
|
121
|
+
@c.get('_design/my_test').should == nil
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
describe '#query' do
|
126
|
+
|
127
|
+
it 'queries with the full path (_design/<id>/_view/<view>' do
|
128
|
+
|
129
|
+
@c.query('_design/my_test/_view/my_view').should == [
|
130
|
+
{"id"=>"c3", "key"=>"capuccino", "value"=>nil},
|
131
|
+
{"id"=>"c0", "key"=>"espresso", "value"=>nil},
|
132
|
+
{"id"=>"c2", "key"=>"macchiato", "value"=>nil},
|
133
|
+
{"id"=>"c4", "key"=>"macchiato", "value"=>nil},
|
134
|
+
{"id"=>"c1", "key"=>"ristretto", "value"=>nil},
|
135
|
+
{"id"=>"c5", "key"=>"veloce espresso", "value"=>nil}
|
136
|
+
]
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'queries with the short path (<id>:<view>)' do
|
140
|
+
|
141
|
+
@c.query('my_test:my_view').should == [
|
142
|
+
{"id"=>"c3", "key"=>"capuccino", "value"=>nil},
|
143
|
+
{"id"=>"c0", "key"=>"espresso", "value"=>nil},
|
144
|
+
{"id"=>"c2", "key"=>"macchiato", "value"=>nil},
|
145
|
+
{"id"=>"c4", "key"=>"macchiato", "value"=>nil},
|
146
|
+
{"id"=>"c1", "key"=>"ristretto", "value"=>nil},
|
147
|
+
{"id"=>"c5", "key"=>"veloce espresso", "value"=>nil}
|
148
|
+
]
|
149
|
+
end
|
150
|
+
|
151
|
+
it "returns nil when the view doesn't exist" do
|
152
|
+
|
153
|
+
@c.query('nemo:nada').should == nil
|
154
|
+
end
|
155
|
+
|
156
|
+
it "returns nil when the view doesn't exist (and passing :keys)" do
|
157
|
+
|
158
|
+
@c.query('nemo:nada', :keys => %[ x y ]).should == nil
|
159
|
+
end
|
160
|
+
|
161
|
+
it 'returns the complete response on :raw => true' do
|
162
|
+
|
163
|
+
@c.query('my_test:my_view', :raw => true).should == {
|
164
|
+
"total_rows"=>6,
|
165
|
+
"offset"=>0,
|
166
|
+
"rows"=>
|
167
|
+
[{"id"=>"c3", "key"=>"capuccino", "value"=>nil},
|
168
|
+
{"id"=>"c0", "key"=>"espresso", "value"=>nil},
|
169
|
+
{"id"=>"c2", "key"=>"macchiato", "value"=>nil},
|
170
|
+
{"id"=>"c4", "key"=>"macchiato", "value"=>nil},
|
171
|
+
{"id"=>"c1", "key"=>"ristretto", "value"=>nil},
|
172
|
+
{"id"=>"c5", "key"=>"veloce espresso", "value"=>nil}]
|
173
|
+
}
|
174
|
+
end
|
175
|
+
|
176
|
+
it 'accepts parameters' do
|
177
|
+
|
178
|
+
@c.query('my_test:my_view', :limit => 2).should == [
|
179
|
+
{"id"=>"c3", "key"=>"capuccino", "value"=>nil},
|
180
|
+
{"id"=>"c0", "key"=>"espresso", "value"=>nil}
|
181
|
+
]
|
182
|
+
end
|
183
|
+
|
184
|
+
it 'is OK with nil parameters' do
|
185
|
+
|
186
|
+
@c.query('my_test:my_view', :skip => nil, :limit => 2).should == [
|
187
|
+
{"id"=>"c3", "key"=>"capuccino", "value"=>nil},
|
188
|
+
{"id"=>"c0", "key"=>"espresso", "value"=>nil}
|
189
|
+
]
|
190
|
+
end
|
191
|
+
|
192
|
+
it 'is OK with reduced views' do
|
193
|
+
|
194
|
+
@c.query('my_test:my_reduced_view', :group => true).should == [
|
195
|
+
{"key"=>"capuccino", "value"=>1},
|
196
|
+
{"key"=>"espresso", "value"=>1},
|
197
|
+
{"key"=>"macchiato", "value"=>2},
|
198
|
+
{"key"=>"ristretto", "value"=>1},
|
199
|
+
{"key"=>"veloce espresso", "value"=>1}
|
200
|
+
]
|
201
|
+
end
|
202
|
+
|
203
|
+
it 'is OK with reduced views and :key' do
|
204
|
+
|
205
|
+
@c.query(
|
206
|
+
'my_test:my_reduced_view', :key => 'macchiato', :group => true
|
207
|
+
).should == [
|
208
|
+
{ 'key' => 'macchiato', 'value' => 2 }
|
209
|
+
]
|
210
|
+
end
|
211
|
+
|
212
|
+
it 'is OK with complex keys (array for example' do
|
213
|
+
|
214
|
+
lambda {
|
215
|
+
@c.query(
|
216
|
+
'my_test:my_reduced_view', :key => [ "a", 2 ], :group => true)
|
217
|
+
}.should_not raise_error
|
218
|
+
end
|
219
|
+
|
220
|
+
it 'uses POST when there is a :keys parameter' do
|
221
|
+
|
222
|
+
@c.query(
|
223
|
+
'my_test:my_view', :keys => %w[ capuccino ristretto ]
|
224
|
+
).should == [
|
225
|
+
{"id"=>"c3", "key"=>"capuccino", "value"=>nil},
|
226
|
+
{"id"=>"c1", "key"=>"ristretto", "value"=>nil}
|
227
|
+
]
|
228
|
+
end
|
229
|
+
|
230
|
+
it 'caches in case of GET' do
|
231
|
+
|
232
|
+
@c.query('my_test:my_view')
|
233
|
+
s0 = @c.http.last_response.status
|
234
|
+
@c.query('my_test:my_view')
|
235
|
+
s1 = @c.http.last_response.status
|
236
|
+
|
237
|
+
s0.should == 200
|
238
|
+
s1.should == 304
|
239
|
+
@c.http.cache.size.should == 1
|
240
|
+
end
|
241
|
+
|
242
|
+
it 'caches in case of POST' do
|
243
|
+
|
244
|
+
@c.query('my_test:my_view', :keys => %w[ capuccino ristretto ])
|
245
|
+
s0 = @c.http.last_response.status
|
246
|
+
@c.query('my_test:my_view', :keys => %w[ capuccino ristretto ])
|
247
|
+
s1 = @c.http.last_response.status
|
248
|
+
|
249
|
+
s0.should == 200
|
250
|
+
s1.should == 304
|
251
|
+
@c.http.cache.size.should == 1
|
252
|
+
end
|
253
|
+
|
254
|
+
it 'does not cache if :cache => false (GET)' do
|
255
|
+
|
256
|
+
@c.query('my_test:my_view', :cache => false)
|
257
|
+
|
258
|
+
@c.http.cache.size.should == 0
|
259
|
+
end
|
260
|
+
|
261
|
+
it 'does not cache if :cache => false (POST)' do
|
262
|
+
|
263
|
+
@c.query(
|
264
|
+
'my_test:my_view',
|
265
|
+
:keys => %w[ capuccino ristretto ], :cache => false)
|
266
|
+
|
267
|
+
@c.http.cache.size.should == 0
|
268
|
+
end
|
269
|
+
|
270
|
+
it 'escapes :key(s) in the URI' do
|
271
|
+
|
272
|
+
@c.query('my_test:my_view', :key => 'veloce espresso').should == [
|
273
|
+
{ 'id' => 'c5', 'key' => 'veloce espresso', 'value' => nil }
|
274
|
+
]
|
275
|
+
end
|
276
|
+
|
277
|
+
it 'leaves the opts hash untouched' do
|
278
|
+
|
279
|
+
opts = { :skip => 3, :limit => nil }
|
280
|
+
|
281
|
+
@c.query('my_test:my_view', opts)
|
282
|
+
|
283
|
+
opts.should == { :skip => 3, :limit => nil }
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
describe '#query_for_docs' do
|
288
|
+
|
289
|
+
it 'returns documents' do
|
290
|
+
|
291
|
+
docs = @c.query_for_docs('my_test:my_view')
|
292
|
+
|
293
|
+
docs.collect { |doc| doc['type'] }.should == %w[
|
294
|
+
capuccino espresso macchiato macchiato ristretto
|
295
|
+
] + [ 'veloce espresso' ]
|
296
|
+
end
|
297
|
+
|
298
|
+
it 'accepts :keys' do
|
299
|
+
|
300
|
+
docs = @c.query_for_docs('my_test:my_view', :keys => %w[ macchiato ])
|
301
|
+
|
302
|
+
docs.collect { |doc| doc['_id'] }.should == %w[ c2 c4 ]
|
303
|
+
end
|
304
|
+
|
305
|
+
it "doesn't return twice the same doc" do
|
306
|
+
|
307
|
+
@c.query_for_docs('my_test:my_double_view').size.should == 6
|
308
|
+
end
|
309
|
+
|
310
|
+
it "returns nil when the view doesn't exist" do
|
311
|
+
|
312
|
+
@c.query_for_docs('nemo:nada').should == nil
|
313
|
+
end
|
314
|
+
|
315
|
+
it 'leaves the opts hash untouched' do
|
316
|
+
|
317
|
+
opts = { :skip => 3, :limit => nil }
|
318
|
+
|
319
|
+
@c.query_for_docs('nemo:nada', opts)
|
320
|
+
|
321
|
+
opts.should == { :skip => 3, :limit => nil }
|
322
|
+
end
|
323
|
+
end
|
324
|
+
end
|
325
|
+
end
|
326
|
+
|
data/spec/couch_url.txt
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
|
2
|
+
#
|
3
|
+
# specifiying rufus-jig
|
4
|
+
#
|
5
|
+
# Wed Dec 1 15:07:42 JST 2010
|
6
|
+
#
|
7
|
+
|
8
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper.rb')
|
9
|
+
|
10
|
+
|
11
|
+
describe Rufus::Jig::Http do
|
12
|
+
|
13
|
+
context 'HTTP basic authorization' do
|
14
|
+
|
15
|
+
context 'without authorization' do
|
16
|
+
|
17
|
+
before(:each) do
|
18
|
+
purge_server
|
19
|
+
@h = Rufus::Jig::Http.new('127.0.0.1', 4567)
|
20
|
+
end
|
21
|
+
after(:each) do
|
22
|
+
@h.close
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'gets denied' do
|
26
|
+
|
27
|
+
lambda {
|
28
|
+
@h.get('/protected')
|
29
|
+
}.should raise_error(Rufus::Jig::HttpError)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'with authorization' do
|
34
|
+
|
35
|
+
before(:each) do
|
36
|
+
purge_server
|
37
|
+
@h = Rufus::Jig::Http.new(
|
38
|
+
'127.0.0.1', 4567, :basic_auth => %w[ admin nimda ])
|
39
|
+
end
|
40
|
+
after(:each) do
|
41
|
+
@h.close
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'gets through' do
|
45
|
+
|
46
|
+
@h.get('/protected').should == { 'info' => 'secretive' }
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
@@ -0,0 +1,76 @@
|
|
1
|
+
|
2
|
+
#
|
3
|
+
# specifiying rufus-jig
|
4
|
+
#
|
5
|
+
# Tue Nov 30 13:03:00 JST 2010
|
6
|
+
#
|
7
|
+
|
8
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper.rb')
|
9
|
+
|
10
|
+
|
11
|
+
describe Rufus::Jig::Http do
|
12
|
+
|
13
|
+
before(:each) do
|
14
|
+
purge_server
|
15
|
+
@h = Rufus::Jig::Http.new('127.0.0.1', 4567)
|
16
|
+
end
|
17
|
+
after(:each) do
|
18
|
+
@h.close
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'with conditional requests' do
|
22
|
+
|
23
|
+
describe '#get' do
|
24
|
+
|
25
|
+
it "caches the response" do
|
26
|
+
|
27
|
+
@h.get('/document_with_etag')
|
28
|
+
|
29
|
+
@h.cache.should == {
|
30
|
+
'/document_with_etag' => [ '"123456123456"', { 'car' => 'Peugeot' } ]
|
31
|
+
}
|
32
|
+
end
|
33
|
+
|
34
|
+
it "goes 200 then 304" do
|
35
|
+
|
36
|
+
@h.get('/document_with_etag', :raw => true).status.should == 200
|
37
|
+
@h.get('/document_with_etag', :raw => true).status.should == 304
|
38
|
+
end
|
39
|
+
|
40
|
+
it "doesn't cache when :cache => false" do
|
41
|
+
|
42
|
+
@h.get('/document_with_etag', :cache => false)
|
43
|
+
|
44
|
+
@h.cache.should == {}
|
45
|
+
end
|
46
|
+
|
47
|
+
it "returns duplicates" do
|
48
|
+
|
49
|
+
doc0 = @h.get('/document_with_etag', :raw => true)
|
50
|
+
doc1 = @h.get('/document_with_etag', :raw => true)
|
51
|
+
|
52
|
+
doc0.object_id.should_not == doc1.object_id
|
53
|
+
end
|
54
|
+
|
55
|
+
it "goes 200 when the ETag is obsolete" do
|
56
|
+
|
57
|
+
@h.get('/document_with_etag')
|
58
|
+
@h.get('/document_with_etag', :etag => '"nada"')
|
59
|
+
|
60
|
+
@h.last_response.status.should == 200
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe '#cache' do
|
65
|
+
|
66
|
+
it 'should be clearable' do
|
67
|
+
|
68
|
+
@h.get('/document_with_etag')
|
69
|
+
@h.cache.clear
|
70
|
+
|
71
|
+
@h.cache.size.should == 0
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|