couchrest 1.2.1 → 2.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,74 @@
1
+ require File.expand_path("../../spec_helper", __FILE__)
2
+
3
+ describe CouchRest::Exception do
4
+ it "returns a 'message' equal to the class name if the message is not set, because 'message' should not be nil" do
5
+ e = CouchRest::Exception.new
6
+ expect(e.message).to eq "CouchRest::Exception"
7
+ end
8
+
9
+ it "returns the 'message' that was set" do
10
+ e = CouchRest::Exception.new
11
+ message = "An explicitly set message"
12
+ e.message = message
13
+ expect(e.message).to eq message
14
+ end
15
+
16
+ it "sets the exception message to ErrorMessage" do
17
+ expect(CouchRest::NotFound.new.message).to eq 'Not Found'
18
+ end
19
+
20
+ it "contains exceptions in CouchRest" do
21
+ expect(CouchRest::Unauthorized.new).to be_a_kind_of(CouchRest::Exception)
22
+ end
23
+ end
24
+
25
+ describe CouchRest::RequestFailed do
26
+ before do
27
+ @response = double('HTTP Response', :status => 500)
28
+ end
29
+
30
+ it "stores the http response on the exception" do
31
+ response = "response"
32
+ begin
33
+ raise CouchRest::RequestFailed, response
34
+ rescue CouchRest::RequestFailed => e
35
+ expect(e.response).to eq response
36
+ end
37
+ end
38
+
39
+ it "http_code convenience method for fetching the code as an integer" do
40
+ expect(CouchRest::RequestFailed.new(@response).http_code).to eq 500
41
+ end
42
+
43
+ it "http_body convenience method for fetching the body (decoding when necessary)" do
44
+ expect(CouchRest::RequestFailed.new(@response).http_code).to eq 500
45
+ expect(CouchRest::RequestFailed.new(@response).message).to eq 'HTTP status code 500'
46
+ end
47
+
48
+ it "shows the status code in the message" do
49
+ expect(CouchRest::RequestFailed.new(@response).to_s).to match(/500/)
50
+ end
51
+ end
52
+
53
+ describe CouchRest::NotFound do
54
+ it "also has the http response attached" do
55
+ response = "response"
56
+ begin
57
+ raise CouchRest::NotFound, response
58
+ rescue CouchRest::NotFound => e
59
+ expect(e.response).to eq response
60
+ end
61
+ end
62
+
63
+ it 'stores the body on the response of the exception' do
64
+ body = "body"
65
+ stub_request(:get, "http://www.example.com").to_return(:body => body, :status => 404)
66
+ begin
67
+ CouchRest.get "http://www.example.com"
68
+ raise
69
+ rescue CouchRest::NotFound => e
70
+ expect(e.response.body).to eq body
71
+ end
72
+ end
73
+ end
74
+
@@ -22,7 +22,7 @@ describe CouchRest::Pager do
22
22
  end
23
23
 
24
24
  it "should store the db" do
25
- @pager.db.should == @db
25
+ expect(@pager.db).to eql @db
26
26
  end
27
27
 
28
28
  describe "paging all docs" do
@@ -31,22 +31,22 @@ describe CouchRest::Pager do
31
31
  @pager.all_docs(10) do |doc|
32
32
  n += 1
33
33
  end
34
- n.should == 10
34
+ expect(n).to eql 10
35
35
  end
36
36
  it "should yield each docrow group without duplicate docs" do
37
37
  docids = {}
38
38
  @pager.all_docs(10) do |docrows|
39
39
  docrows.each do |row|
40
- docids[row['id']].should be_nil
40
+ expect(docids[row['id']]).to be_nil
41
41
  docids[row['id']] = true
42
42
  end
43
43
  end
44
- docids.keys.length.should == 100
44
+ expect(docids.keys.length).to eql 100
45
45
  end
46
46
  it "should yield each docrow group" do
47
47
  @pager.all_docs(10) do |docrows|
48
48
  doc = @db.get(docrows[0]['id'])
49
- doc['number'].class.should == Fixnum
49
+ expect(doc['number'].class).to eql Fixnum
50
50
  end
51
51
  end
52
52
  end
@@ -64,12 +64,12 @@ describe CouchRest::Pager do
64
64
  end
65
65
 
66
66
  it "should have docs" do
67
- @docs.length.should == 100
68
- @db.documents['rows'].length.should == 101
67
+ expect(@docs.length).to eql 100
68
+ expect(@db.documents['rows'].length).to eql 101
69
69
  end
70
70
 
71
71
  it "should have a view" do
72
- @db.view('magic/number', :limit => 10)['rows'][0]['key'].should == 0
72
+ expect(@db.view('magic/number', :limit => 10)['rows'][0]['key']).to eql 0
73
73
  end
74
74
 
75
75
  it "should yield once per key" do
@@ -77,8 +77,8 @@ describe CouchRest::Pager do
77
77
  @pager.key_reduce('magic/number', 20) do |k,vs|
78
78
  results[k] = vs.length
79
79
  end
80
- results[0].should == 10
81
- results[3].should == 10
80
+ expect(results[0]).to eql 10
81
+ expect(results[3]).to eql 10
82
82
  end
83
83
 
84
84
  it "with a small step size should yield once per key" do
@@ -86,30 +86,30 @@ describe CouchRest::Pager do
86
86
  @pager.key_reduce('magic/number', 7) do |k,vs|
87
87
  results[k] = vs.length
88
88
  end
89
- results[0].should == 10
90
- results[3].should == 10
91
- results[9].should == 10
89
+ expect(results[0]).to eql 10
90
+ expect(results[3]).to eql 10
91
+ expect(results[9]).to eql 10
92
92
  end
93
93
  it "with a large step size should yield once per key" do
94
94
  results = {}
95
95
  @pager.key_reduce('magic/number', 1000) do |k,vs|
96
96
  results[k] = vs.length
97
97
  end
98
- results[0].should == 10
99
- results[3].should == 10
100
- results[9].should == 10
98
+ expect(results[0]).to eql 10
99
+ expect(results[3]).to eql 10
100
+ expect(results[9]).to eql 10
101
101
  end
102
102
  it "with a begin and end should only yield in the range (and leave out the lastkey)" do
103
103
  results = {}
104
104
  @pager.key_reduce('magic/number', 1000, 4, 7) do |k,vs|
105
105
  results[k] = vs.length
106
106
  end
107
- results[0].should be_nil
108
- results[4].should == 10
109
- results[6].should == 10
110
- results[7].should be_nil
111
- results[8].should be_nil
112
- results[9].should be_nil
107
+ expect(results[0]).to be_nil
108
+ expect(results[4]).to eql 10
109
+ expect(results[6]).to eql 10
110
+ expect(results[7]).to be_nil
111
+ expect(results[8]).to be_nil
112
+ expect(results[9]).to be_nil
113
113
  end
114
114
  end
115
115
  end
@@ -0,0 +1,154 @@
1
+ require File.expand_path("../../../spec_helper", __FILE__)
2
+
3
+ describe CouchRest::StreamRowParser do
4
+
5
+ describe :initialize do
6
+
7
+ let :obj do
8
+ CouchRest::StreamRowParser.new
9
+ end
10
+
11
+ it "should provide object" do
12
+ expect(obj).to_not be_nil
13
+ end
14
+
15
+ end
16
+
17
+ describe "#parse with rows" do
18
+
19
+ let :obj do
20
+ CouchRest::StreamRowParser.new
21
+ end
22
+
23
+ it "should parse a basic complete segment" do
24
+ data = <<-EOF
25
+ {
26
+ "total_rows": 3, "offset": 0, "rows": [
27
+ {"id": "doc1", "key": "doc1", "value": {"rev": "4324BB"}},
28
+ {"id": "doc2", "key": "doc2", "value": {"rev":"2441HF"}},
29
+ {"id": "doc3", "key": "doc3", "value": {"rev":"74EC24"}}
30
+ ]
31
+ }
32
+ EOF
33
+ rows = []
34
+ obj.parse(data) do |row|
35
+ rows << row
36
+ end
37
+
38
+ expect(rows.length).to eql(3)
39
+ row = nil
40
+ expect do
41
+ row = MultiJson.load(rows[0])
42
+ end.to_not raise_error
43
+ expect(row['id']).to eql('doc1')
44
+
45
+ head = nil
46
+ expect do
47
+ head = MultiJson.load(obj.header)
48
+ end.to_not raise_error
49
+ expect(head).to include('total_rows')
50
+ expect(head['total_rows']).to eql(3)
51
+ end
52
+
53
+ it "should deal with basic data in segments" do
54
+ data = []
55
+ data << '{ "total_rows": 3, "offset": 0, "ro'
56
+ data << 'ws": [ {"id": "doc1", "key": "doc1", "value": {"rev": '
57
+ data << '"4324BB"}}, {"id": "doc2", "key": "doc2", "value": '
58
+ data << '{"rev":"2441HF"}}, {"id": "doc3", "key": "doc3", "value": {"rev":"74EC24"}}'
59
+ data << '] }'
60
+
61
+ rows = []
62
+ data.each do |d|
63
+ obj.parse(d) do |row|
64
+ rows << row
65
+ end
66
+ end
67
+
68
+ expect(rows.length).to eql(3)
69
+ row = nil
70
+ expect do
71
+ row = MultiJson.load(rows[1])
72
+ end.to_not raise_error
73
+ expect(row['id']).to eql('doc2')
74
+
75
+ head = nil
76
+ expect do
77
+ head = MultiJson.load(obj.header)
78
+ end.to_not raise_error
79
+ expect(head).to include('total_rows')
80
+ expect(head['total_rows']).to eql(3)
81
+ end
82
+
83
+
84
+ it "should handle strings with '}'" do
85
+ data = <<-EOF
86
+ {
87
+ "total_rows": 3, "offset": 0, "rows": [
88
+ {"id": "doc1", "key": "doc1", "value": {"rev":"43}24BB"}},
89
+ {"id": "doc2", "key": "doc2", "value": {"rev":"2{441HF"}},
90
+ {"id": "doc3", "key": "doc3", "value": {"rev":"74EC24"}}
91
+ ]
92
+ }
93
+ EOF
94
+ rows = []
95
+ obj.parse(data) do |row|
96
+ rows << row
97
+ end
98
+ expect(rows.length).to eql(3)
99
+ expect(rows.first).to match(/43}24BB/)
100
+ end
101
+
102
+ it "should handle escaped chars" do
103
+ data = <<-EOF
104
+ {
105
+ "total_rows": 3, "offset": 0, "rows": [
106
+ {"id": "doc1", "key": "doc1", "value": {"rev":"43\\"4BB"}},
107
+ {"id": "doc2", "key": "doc2", "value": {"rev":"2441HF"}},
108
+ {"id": "doc3", "key": "doc3", "value": {"rev":"74EC24"}}
109
+ ]
110
+ }
111
+ EOF
112
+ rows = []
113
+ obj.parse(data) do |row|
114
+ rows << row
115
+ end
116
+ expect(rows.length).to eql(3)
117
+ row = MultiJson.load(rows.first)
118
+ expect(row['value']['rev']).to match(/43"4BB/)
119
+ end
120
+
121
+ end
122
+
123
+
124
+ describe "#parse with feed" do
125
+
126
+ let :obj do
127
+ CouchRest::StreamRowParser.new(:feed)
128
+ end
129
+
130
+ it "should parse a basic complete segment" do
131
+ data = <<-EOF
132
+ {"id": "doc1", "key": "doc1", "value": {"rev": "4324BB"}}
133
+ {"id": "doc2", "key": "doc2", "value": {"rev":"2441HF"}}
134
+ {"id": "doc3", "key": "doc3", "value": {"rev":"74EC24"}}
135
+ EOF
136
+ rows = []
137
+ obj.parse(data) do |row|
138
+ rows << row
139
+ end
140
+
141
+ expect(rows.length).to eql(3)
142
+ row = nil
143
+ expect do
144
+ row = MultiJson.load(rows[0])
145
+ end.to_not raise_error
146
+ expect(row['id']).to eql('doc1')
147
+
148
+ obj.header.should be_empty
149
+ end
150
+
151
+
152
+ end
153
+
154
+ end
@@ -6,236 +6,72 @@ describe CouchRest::RestAPI do
6
6
 
7
7
  subject { CouchRest }
8
8
 
9
- let(:request) { RestClient::Request }
10
- let(:simple_response) { "{\"ok\":true}" }
11
- let(:parser) { MultiJson }
12
- let(:parser_opts) { {:max_nesting => false} }
13
-
14
- it "should exist" do
15
- should respond_to :get
16
- should respond_to :put
17
- should respond_to :post
18
- should respond_to :copy
19
- should respond_to :delete
20
- should respond_to :head
21
- end
22
-
23
- it "should provide default headers" do
24
- should respond_to :default_headers
25
- CouchRest.default_headers.should be_a(Hash)
9
+ let :mock_conn do
10
+ CouchRest::Connection.new(URI "http://mock")
26
11
  end
27
12
 
28
-
29
- describe :get do
30
- it "should send basic request" do
31
- req = {:url => 'foo', :method => :get, :headers => CouchRest.default_headers}
32
- request.should_receive(:execute).with(req).and_return(simple_response)
33
- parser.should_receive(:decode).with(simple_response, parser_opts)
34
- CouchRest.get('foo')
35
- end
36
-
37
- it "should never modify options" do
38
- options = {:timeout => 1000}
39
- options.freeze
40
- request.should_receive(:execute).and_return(simple_response)
41
- parser.should_receive(:decode)
42
- expect { CouchRest.get('foo', options) }.to_not raise_error
43
- end
44
-
45
-
46
- it "should accept 'content_type' header" do
47
- req = {:url => 'foo', :method => :get, :headers => CouchRest.default_headers.merge(:content_type => :foo)}
48
- request.should_receive(:execute).with(req).and_return(simple_response)
49
- parser.should_receive(:decode).with(simple_response, parser_opts)
50
- CouchRest.get('foo', :content_type => :foo)
51
- end
52
-
53
- it "should accept 'accept' header" do
54
- req = {:url => 'foo', :method => :get, :headers => CouchRest.default_headers.merge(:accept => :foo)}
55
- request.should_receive(:execute).with(req).and_return(simple_response)
56
- parser.should_receive(:decode).with(simple_response, parser_opts)
57
- CouchRest.get('foo', :accept => :foo)
58
- end
59
-
60
- it "should forward RestClient options" do
61
- req = {:url => 'foo', :method => :get, :timeout => 1000, :headers => CouchRest.default_headers}
62
- request.should_receive(:execute).with(req).and_return(simple_response)
63
- parser.should_receive(:decode).with(simple_response, parser_opts)
64
- CouchRest.get('foo', :timeout => 1000)
65
- end
66
-
67
- it "should forward parser options" do
68
- req = {:url => 'foo', :method => :get, :headers => CouchRest.default_headers}
69
- request.should_receive(:execute).with(req).and_return(simple_response)
70
- parser.should_receive(:decode).with(simple_response, parser_opts.merge(:random => 'foo'))
71
- CouchRest.get('foo', :random => 'foo')
72
- end
73
-
74
- it "should accept raw option" do
75
- req = {:url => 'foo', :method => :get, :headers => CouchRest.default_headers}
76
- request.should_receive(:execute).with(req).and_return(simple_response)
77
- parser.should_not_receive(:decode)
78
- CouchRest.get('foo', :raw => true).should eql(simple_response)
79
- end
80
-
81
- it "should allow override of method (not that you'd want to!)" do
82
- req = {:url => 'foo', :method => :fubar, :headers => CouchRest.default_headers}
83
- request.should_receive(:execute).with(req).and_return(simple_response)
84
- parser.should_receive(:decode).with(simple_response, parser_opts)
85
- CouchRest.get('foo', :method => :fubar)
86
- end
87
-
88
- it "should allow override of url (not that you'd want to!)" do
89
- req = {:url => 'foobardom', :method => :get, :headers => CouchRest.default_headers}
90
- request.should_receive(:execute).with(req).and_return(simple_response)
91
- parser.should_receive(:decode).with(simple_response, parser_opts)
92
- CouchRest.get('foo', :url => 'foobardom')
93
- end
94
-
95
-
96
- it "should forward an exception if raised" do
97
- request.should_receive(:execute).and_raise(RestClient::Exception)
98
- expect { CouchRest.get('foo') }.to raise_error(RestClient::Exception)
99
- end
100
-
101
- context 'when decode_json_objects is true' do
102
- class TestObject
103
- def self.json_create(args)
104
- new
105
- end
106
- end
107
-
108
- before(:each) do
109
- CouchRest.decode_json_objects = true
110
- end
111
-
112
- after(:each) do
113
- CouchRest.decode_json_objects = false
114
- end
115
-
116
- it 'should return the response as a Ruby object' do
117
- CouchRest.put "#{COUCHHOST}/#{TESTDB}/test", JSON.create_id => TestObject.to_s
118
-
119
- CouchRest.get("#{COUCHHOST}/#{TESTDB}/test").class.should eql(TestObject)
120
- end
121
- end
13
+ it "should exist" do
14
+ expect(subject).to respond_to :get
15
+ expect(subject).to respond_to :put
16
+ expect(subject).to respond_to :post
17
+ expect(subject).to respond_to :copy
18
+ expect(subject).to respond_to :delete
19
+ expect(subject).to respond_to :head
122
20
  end
123
21
 
124
- describe :post do
125
- it "should send basic request" do
126
- req = {:url => 'foo', :method => :post, :headers => CouchRest.default_headers, :payload => 'data'}
127
- request.should_receive(:execute).with(req).and_return(simple_response)
128
- parser.should_receive(:encode).with('data').and_return('data')
129
- parser.should_receive(:decode).with(simple_response, parser_opts)
130
- CouchRest.post('foo', 'data')
131
- end
132
-
133
- it "should send basic request" do
134
- req = {:url => 'foo', :method => :post, :headers => CouchRest.default_headers, :payload => 'data'}
135
- request.should_receive(:execute).with(req).and_return(simple_response)
136
- parser.should_receive(:encode).with('data').and_return('data')
137
- parser.should_receive(:decode).with(simple_response, parser_opts)
138
- CouchRest.post('foo', 'data')
139
- end
22
+ describe "basic forwarding" do
140
23
 
141
- it "should send raw request" do
142
- req = {:url => 'foo', :method => :post, :headers => CouchRest.default_headers, :payload => 'data'}
143
- request.should_receive(:execute).with(req).and_return(simple_response)
144
- parser.should_not_receive(:encode)
145
- parser.should_receive(:decode).with(simple_response, parser_opts)
146
- CouchRest.post('foo', 'data', :raw => true)
24
+ let :uri do
25
+ URI("http://mock/db/doc")
147
26
  end
148
27
 
149
- it "should not encode nil request" do
150
- req = {:url => 'foo', :method => :post, :headers => CouchRest.default_headers}
151
- request.should_receive(:execute).with(req).and_return(simple_response)
152
- parser.should_not_receive(:encode)
153
- parser.should_receive(:decode).with(simple_response, parser_opts)
154
- CouchRest.post('foo', nil)
155
- end
28
+ it "should start and use connection" do
29
+ expect(CouchRest::Connection).to receive(:new)
30
+ .with(uri, {})
31
+ .and_return(mock_conn)
32
+
33
+ stub_request(:get, uri.to_s)
34
+ .to_return(:body => {'_id' => 'test', 'name' => 'none'}.to_json)
156
35
 
157
- it "should send raw request automatically if file provided" do
158
- f = File.open(FIXTURE_PATH + '/attachments/couchdb.png')
159
- req = {:url => 'foo', :method => :post, :headers => CouchRest.default_headers, :payload => f}
160
- request.should_receive(:execute).with(req).and_return(simple_response)
161
- parser.should_not_receive(:encode)
162
- parser.should_receive(:decode).with(simple_response, parser_opts)
163
- CouchRest.post('foo', f)
164
- f.close
36
+ res = CouchRest.get(uri.to_s)
37
+ expect(res['name']).to eql('none')
165
38
  end
166
39
 
167
- it "should send raw request automatically if Tempfile provided" do
168
- f = Tempfile.new('couchrest')
169
- req = {:url => 'foo', :method => :post, :headers => CouchRest.default_headers, :payload => f}
170
- request.should_receive(:execute).with(req).and_return(simple_response)
171
- parser.should_not_receive(:encode)
172
- parser.should_receive(:decode).with(simple_response, parser_opts)
173
- CouchRest.post('foo', f)
174
- f.close
175
- end
40
+ it "should start connection with options" do
41
+ expect(CouchRest::Connection).to receive(:new)
42
+ .with(uri, hash_including(:test => 'foo'))
43
+ .and_return(mock_conn)
44
+
45
+ stub_request(:get, uri.to_s)
46
+ .to_return(:body => {'_id' => 'test', 'name' => 'none'}.to_json)
176
47
 
177
- it "should use as_couch_json method if available" do
178
- h = {'foo' => 'bar'}
179
- doc = CouchRest::Document.new(h)
180
- doc.should_receive(:as_couch_json).and_return(h)
181
- request.should_receive(:execute).and_return(simple_response)
182
- parser.should_receive(:encode).with(h)
183
- parser.should_receive(:decode).with(simple_response, parser_opts)
184
- CouchRest.post('foo', doc)
48
+ res = CouchRest.get(uri.to_s, :test => 'foo')
49
+ expect(res['name']).to eql('none')
185
50
  end
186
- end
187
51
 
52
+ it "should handle query parameters and send them to connection" do
188
53
 
189
- describe :put do
190
- # Only test basic as practically same as post
191
- it "should send basic request" do
192
- req = {:url => 'foo', :method => :put, :headers => CouchRest.default_headers, :payload => 'data'}
193
- request.should_receive(:execute).with(req).and_return(simple_response)
194
- parser.should_receive(:encode).with('data').and_return('data')
195
- parser.should_receive(:decode).with(simple_response, parser_opts)
196
- CouchRest.put('foo', 'data')
54
+ uri = URI("http://mock/db/doc?q=a")
55
+ expect(CouchRest::Connection).to receive(:new)
56
+ .with(uri, {})
57
+ .and_return(mock_conn)
58
+ stub_request(:get, uri.to_s)
59
+ .to_return(:body => {'_id' => 'test', 'name' => 'none'}.to_json)
60
+ res = CouchRest.get(uri.to_s)
61
+ expect(res['name']).to eql('none')
197
62
  end
198
63
 
199
64
  end
200
65
 
201
66
  describe :delete do
202
- it "should send basic request" do
203
- req = {:url => 'foo', :method => :delete, :headers => CouchRest.default_headers}
204
- request.should_receive(:execute).with(req).and_return(simple_response)
205
- parser.should_receive(:decode).with(simple_response, parser_opts)
206
- CouchRest.delete('foo')
207
- end
208
- end
209
-
210
- describe :copy do
211
- it "should send basic request" do
212
- headers = CouchRest.default_headers.merge(
213
- 'Destination' => 'fooobar'
214
- )
215
- req = {:url => 'foo', :method => :copy, :headers => headers}
216
- request.should_receive(:execute).with(req).and_return(simple_response)
217
- parser.should_receive(:decode).with(simple_response, parser_opts)
218
- CouchRest.copy('foo', 'fooobar')
67
+
68
+ it "should delete a document" do
69
+ res = CouchRest.post(DB.uri.to_s, {'name' => "TestDoc"})
70
+ res = CouchRest.delete("#{DB.uri.to_s}/#{res['id']}?rev=#{res['rev']}")
71
+ expect(res['ok']).to be_true
219
72
  end
220
73
 
221
- it "should never modify header options" do
222
- options = {:headers => {:content_type => :foo}}
223
- options.freeze
224
- request.should_receive(:execute).and_return(simple_response)
225
- parser.should_receive(:decode)
226
- expect { CouchRest.copy('foo', 'foobar', options) }.to_not raise_error
227
- end
228
-
229
- end
230
-
231
- describe :head do
232
- it "should send basic request" do
233
- req = {:url => 'foo', :method => :head, :headers => CouchRest.default_headers}
234
- request.should_receive(:execute).with(req).and_return(simple_response)
235
- CouchRest.head('foo')
236
- end
237
74
  end
238
75
 
239
76
  end
240
-
241
77
  end