couchrest 1.1.0.pre3 → 1.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/history.txt +6 -0
- data/lib/couchrest.rb +8 -7
- data/lib/couchrest/attributes.rb +75 -0
- data/lib/couchrest/database.rb +7 -1
- data/lib/couchrest/document.rb +1 -53
- data/lib/couchrest/rest_api.rb +116 -38
- data/lib/couchrest/version.rb +1 -1
- data/spec/couchrest/couchrest_spec.rb +1 -1
- data/spec/couchrest/database_spec.rb +6 -7
- data/spec/couchrest/document_spec.rb +12 -1
- data/spec/couchrest/rest_api_spec.rb +204 -0
- metadata +4 -2
data/history.txt
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
== 1.1.0 - 2011-06-25
|
2
|
+
|
3
|
+
* Minor changes
|
4
|
+
* Refactored basic CouchRest API (get, post, etc.) to pass-through RestClient and MultiJSON options, including headers.
|
5
|
+
* CouchRest::Attributes module created to make attribute related methods independent.
|
6
|
+
|
1
7
|
== 1.1.0.pre3 - 2011-06-06
|
2
8
|
|
3
9
|
* Major changes
|
data/lib/couchrest.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
# Copyright 2008 J. Chris Anderson
|
2
|
-
#
|
2
|
+
#
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
4
|
# you may not use this file except in compliance with the License.
|
5
5
|
# You may obtain a copy of the License at
|
6
|
-
#
|
6
|
+
#
|
7
7
|
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
-
#
|
8
|
+
#
|
9
9
|
# Unless required by applicable law or agreed to in writing, software
|
10
10
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
@@ -29,6 +29,7 @@ require 'forwardable'
|
|
29
29
|
|
30
30
|
# = CouchDB, close to the metal
|
31
31
|
module CouchRest
|
32
|
+
autoload :Attributes, 'couchrest/attributes'
|
32
33
|
autoload :Server, 'couchrest/server'
|
33
34
|
autoload :Database, 'couchrest/database'
|
34
35
|
autoload :Document, 'couchrest/document'
|
@@ -80,7 +81,7 @@ module CouchRest
|
|
80
81
|
end
|
81
82
|
|
82
83
|
db = nil if db && db.empty?
|
83
|
-
|
84
|
+
|
84
85
|
{
|
85
86
|
:host => (scheme || "http://") + (host || "127.0.0.1:5984"),
|
86
87
|
:database => db,
|
@@ -92,7 +93,7 @@ module CouchRest
|
|
92
93
|
def proxy url
|
93
94
|
RestClient.proxy = url
|
94
95
|
end
|
95
|
-
|
96
|
+
|
96
97
|
# ensure that a database exists
|
97
98
|
# creates it if it isn't already there
|
98
99
|
# returns it after it's been created
|
@@ -101,13 +102,13 @@ module CouchRest
|
|
101
102
|
cr = CouchRest.new(parsed[:host])
|
102
103
|
cr.database!(parsed[:database])
|
103
104
|
end
|
104
|
-
|
105
|
+
|
105
106
|
def database url
|
106
107
|
parsed = parse url
|
107
108
|
cr = CouchRest.new(parsed[:host])
|
108
109
|
cr.database(parsed[:database])
|
109
110
|
end
|
110
|
-
|
111
|
+
|
111
112
|
def paramify_url url, params = {}
|
112
113
|
if params && !params.empty?
|
113
114
|
query = params.collect do |k,v|
|
@@ -0,0 +1,75 @@
|
|
1
|
+
#
|
2
|
+
# CouchRest::Attributes
|
3
|
+
#
|
4
|
+
# When included, provide the owner with an attributes hash and
|
5
|
+
# accessors that forward calls to it.
|
6
|
+
#
|
7
|
+
# Provides the basic functionality of Hash without actually being
|
8
|
+
# a Hash using Ruby's standard Forwardable module.
|
9
|
+
#
|
10
|
+
module CouchRest
|
11
|
+
|
12
|
+
module Attributes
|
13
|
+
extend Forwardable
|
14
|
+
|
15
|
+
# Initialize a new CouchRest Document and prepare
|
16
|
+
# a hidden attributes hash.
|
17
|
+
#
|
18
|
+
# When inherting a Document, it is essential that the
|
19
|
+
# super method is called before you own changes to ensure
|
20
|
+
# that the attributes hash has been initialized before
|
21
|
+
# you attempt to use it.
|
22
|
+
def initialize(attrs = nil)
|
23
|
+
@_attributes = {}
|
24
|
+
attrs.each{|k,v| self[k] = v} unless attrs.nil?
|
25
|
+
end
|
26
|
+
|
27
|
+
# Hash equivilent methods to access the attributes
|
28
|
+
def_delegators :@_attributes, :to_a, :==, :eql?, :keys, :values, :each,
|
29
|
+
:reject, :reject!, :empty?, :clear, :merge, :merge!,
|
30
|
+
:encode_json, :as_json, :to_json, :frozen?
|
31
|
+
|
32
|
+
def []=(key, value)
|
33
|
+
@_attributes[key.to_s] = value
|
34
|
+
end
|
35
|
+
def [](key)
|
36
|
+
@_attributes[key.to_s]
|
37
|
+
end
|
38
|
+
def has_key?(key)
|
39
|
+
@_attributes.has_key?(key.to_s)
|
40
|
+
end
|
41
|
+
def delete(key)
|
42
|
+
@_attributes.delete(key.to_s)
|
43
|
+
end
|
44
|
+
def dup
|
45
|
+
new = super
|
46
|
+
@_attributes = @_attributes.dup
|
47
|
+
new
|
48
|
+
end
|
49
|
+
def clone
|
50
|
+
new = super
|
51
|
+
@_attributes = @_attributes.dup
|
52
|
+
new
|
53
|
+
end
|
54
|
+
def to_hash
|
55
|
+
@_attributes
|
56
|
+
end
|
57
|
+
|
58
|
+
# Freeze the object's attributes instead of the actual document.
|
59
|
+
# This prevents further modifications to stored data, but does allow access
|
60
|
+
# to local variables useful for callbacks or cached data.
|
61
|
+
def freeze
|
62
|
+
@_attributes.freeze; self
|
63
|
+
end
|
64
|
+
|
65
|
+
# Provide details of the current keys in the reponse. Based on ActiveRecord::Base.
|
66
|
+
def inspect
|
67
|
+
attributes_as_nice_string = self.keys.collect { |key|
|
68
|
+
"#{key}: #{self[key].inspect}"
|
69
|
+
}.compact.join(", ")
|
70
|
+
"#<#{self.class} #{attributes_as_nice_string}>"
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
data/lib/couchrest/database.rb
CHANGED
@@ -245,7 +245,7 @@ module CouchRest
|
|
245
245
|
def view(name, params = {}, payload = {}, &block)
|
246
246
|
payload['keys'] = params.delete(:keys) if params[:keys]
|
247
247
|
# Try recognising the name, otherwise assume already prepared
|
248
|
-
view_path = name
|
248
|
+
view_path = name_to_view_path(name)
|
249
249
|
url = CouchRest.paramify_url "#{@root}/#{view_path}", params
|
250
250
|
if block_given?
|
251
251
|
if !payload.empty?
|
@@ -386,5 +386,11 @@ module CouchRest
|
|
386
386
|
def base64(data)
|
387
387
|
Base64.encode64(data).gsub(/\s/,'')
|
388
388
|
end
|
389
|
+
|
390
|
+
# Convert a simplified view name into a complete view path. If
|
391
|
+
# the name already starts with a "_" no alterations will be made.
|
392
|
+
def name_to_view_path(name)
|
393
|
+
name =~ /^([^_].+?)\/(.*)$/ ? "_design/#{$1}/_view/#{$2}" : name
|
394
|
+
end
|
389
395
|
end
|
390
396
|
end
|
data/lib/couchrest/document.rb
CHANGED
@@ -17,57 +17,13 @@
|
|
17
17
|
|
18
18
|
module CouchRest
|
19
19
|
class Document
|
20
|
-
|
20
|
+
include CouchRest::Attributes
|
21
21
|
include CouchRest::Attachments
|
22
22
|
extend CouchRest::InheritableAttributes
|
23
23
|
|
24
24
|
couchrest_inheritable_accessor :database
|
25
25
|
attr_accessor :database
|
26
26
|
|
27
|
-
# Initialize a new CouchRest Document and prepare
|
28
|
-
# a hidden attributes hash.
|
29
|
-
#
|
30
|
-
# When inherting a Document, it is essential that the
|
31
|
-
# super method is called before you own changes to ensure
|
32
|
-
# that the attributes hash has been initialized before
|
33
|
-
# you attempt to use it.
|
34
|
-
def initialize(attrs = nil)
|
35
|
-
@_attributes = {}
|
36
|
-
attrs.each{|k,v| self[k] = v} unless attrs.nil?
|
37
|
-
end
|
38
|
-
|
39
|
-
# Hash equivilent methods to access the attributes
|
40
|
-
|
41
|
-
def_delegators :@_attributes, :to_a, :==, :eql?, :keys, :values, :each,
|
42
|
-
:reject, :reject!, :empty?, :clear, :merge, :merge!,
|
43
|
-
:encode_json, :as_json, :to_json
|
44
|
-
|
45
|
-
def []=(key, value)
|
46
|
-
@_attributes[key.to_s] = value
|
47
|
-
end
|
48
|
-
def [](key)
|
49
|
-
@_attributes[key.to_s]
|
50
|
-
end
|
51
|
-
def has_key?(key)
|
52
|
-
@_attributes.has_key?(key.to_s)
|
53
|
-
end
|
54
|
-
def delete(key)
|
55
|
-
@_attributes.delete(key.to_s)
|
56
|
-
end
|
57
|
-
def dup
|
58
|
-
new = super
|
59
|
-
@_attributes = @_attributes.dup
|
60
|
-
new
|
61
|
-
end
|
62
|
-
def clone
|
63
|
-
new = super
|
64
|
-
@_attributes = @_attributes.dup
|
65
|
-
new
|
66
|
-
end
|
67
|
-
def to_hash
|
68
|
-
@_attributes
|
69
|
-
end
|
70
|
-
|
71
27
|
def id
|
72
28
|
self['_id']
|
73
29
|
end
|
@@ -135,14 +91,6 @@ module CouchRest
|
|
135
91
|
@database || self.class.database
|
136
92
|
end
|
137
93
|
|
138
|
-
# Provide details of the current keys in the reponse. Based on ActiveRecord::Base.
|
139
|
-
def inspect
|
140
|
-
attributes_as_nice_string = self.keys.collect { |key|
|
141
|
-
"#{key}: #{self[key].inspect}"
|
142
|
-
}.compact.join(", ")
|
143
|
-
"#<#{self.class} #{attributes_as_nice_string}>"
|
144
|
-
end
|
145
|
-
|
146
94
|
class << self
|
147
95
|
# override the CouchRest::Model-wide default_database
|
148
96
|
# This is not a thread safe operation, do not change the model
|
data/lib/couchrest/rest_api.rb
CHANGED
@@ -1,7 +1,75 @@
|
|
1
1
|
module CouchRest
|
2
2
|
|
3
|
+
# CouchRest RestAPI
|
4
|
+
#
|
5
|
+
# The basic low-level interface for all REST requests to the database. Everything must pass
|
6
|
+
# through here before it is sent to the server.
|
7
|
+
#
|
8
|
+
# Five types of REST requests are supported: get, put, post, delete, and copy.
|
9
|
+
#
|
10
|
+
# Requests that do not have a payload, get, delete and copy, accept the URI and options parameters,
|
11
|
+
# where as put and post both expect a document as the second parameter.
|
12
|
+
#
|
13
|
+
# The API will try to intelegently split the options between the JSON parser and RestClient API.
|
14
|
+
#
|
15
|
+
# The following options will be recognised as header options and automatically added
|
16
|
+
# to the header hash:
|
17
|
+
#
|
18
|
+
# * :content_type, type of content to be sent, especially useful when sending files as this will set the file type. The default is :json.
|
19
|
+
# * :accept, the content type to accept in the response. This should pretty much always be :json.
|
20
|
+
#
|
21
|
+
# The following request options are supported:
|
22
|
+
#
|
23
|
+
# * :method override the requested method (should not be used!).
|
24
|
+
# * :url override the URL used in the request.
|
25
|
+
# * :payload override the document or data sent in the message body (only PUT or POST).
|
26
|
+
# * :headers any additional headers (overrides :content_type and :accept)
|
27
|
+
# * :timeout and :open_timeout the time in miliseconds to wait for the request, see RestClient API for more details.
|
28
|
+
# * :verify_ssl, :ssl_client_cert, :ssl_client_key, and :ssl_ca_file, SSL handling methods.
|
29
|
+
#
|
30
|
+
#
|
31
|
+
# Any other remaining options will be sent to the MultiJSON backend except for the :raw option.
|
32
|
+
#
|
33
|
+
# When :raw is true in PUT and POST requests, no attempt will be made to convert the document payload to JSON. This is
|
34
|
+
# not normally necessary as IO and Tempfile objects will not be parsed anyway. The result of the request will
|
35
|
+
# *always* be parsed.
|
36
|
+
#
|
37
|
+
# For all other requests, mainly GET, the :raw option will make no attempt to parse the result. This
|
38
|
+
# is useful for receiving files from the database.
|
39
|
+
#
|
40
|
+
|
3
41
|
module RestAPI
|
4
42
|
|
43
|
+
# Send a GET request.
|
44
|
+
def get(uri, options = {})
|
45
|
+
execute(uri, :get, options)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Send a PUT request.
|
49
|
+
def put(uri, doc = nil, options = {})
|
50
|
+
execute(uri, :put, options, doc)
|
51
|
+
end
|
52
|
+
|
53
|
+
# Send a POST request.
|
54
|
+
def post(uri, doc = nil, options = {})
|
55
|
+
execute(uri, :post, options, doc)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Send a DELETE request.
|
59
|
+
def delete(uri, options = {})
|
60
|
+
execute(uri, :delete, options)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Send a COPY request to the URI provided.
|
64
|
+
def copy(uri, destination, options = {})
|
65
|
+
opts = options.nil? ? {} : options.dup
|
66
|
+
# also copy headers!
|
67
|
+
opts[:headers] = options[:headers].nil? ? {} : options[:headers].dup
|
68
|
+
opts[:headers]['Destination'] = destination
|
69
|
+
execute(uri, :copy, opts)
|
70
|
+
end
|
71
|
+
|
72
|
+
# The default RestClient headers used in each request.
|
5
73
|
def default_headers
|
6
74
|
{
|
7
75
|
:content_type => :json,
|
@@ -9,61 +77,60 @@ module CouchRest
|
|
9
77
|
}
|
10
78
|
end
|
11
79
|
|
12
|
-
|
13
|
-
begin
|
14
|
-
parse_response(RestClient.get(uri, default_headers), options.dup)
|
15
|
-
rescue => e
|
16
|
-
if $DEBUG
|
17
|
-
raise "Error while sending a GET request #{uri}\n: #{e}"
|
18
|
-
else
|
19
|
-
raise e
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
80
|
+
private
|
23
81
|
|
24
|
-
|
25
|
-
|
26
|
-
|
82
|
+
# Perform the RestClient request by removing the parse specific options, ensuring the
|
83
|
+
# payload is prepared, and sending the request ready to parse the response.
|
84
|
+
def execute(url, method, options = {}, payload = nil)
|
85
|
+
request, parser = prepare_and_split_options(url, method, options)
|
86
|
+
# Prepare the payload if it is provided
|
87
|
+
request[:payload] = payload_from_doc(payload, parser) if payload
|
27
88
|
begin
|
28
|
-
parse_response(RestClient.
|
89
|
+
parse_response(RestClient::Request.execute(request), parser)
|
29
90
|
rescue Exception => e
|
30
91
|
if $DEBUG
|
31
|
-
raise "Error while sending a
|
92
|
+
raise "Error while sending a #{method.to_s.upcase} request #{uri}\noptions: #{opts.inspect}\n#{e}"
|
32
93
|
else
|
33
94
|
raise e
|
34
95
|
end
|
35
96
|
end
|
36
97
|
end
|
37
98
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
99
|
+
# Prepare a two hashes, one for the request to the REST backend and a second
|
100
|
+
# for the JSON parser.
|
101
|
+
#
|
102
|
+
# Returns and array of request options and parser options.
|
103
|
+
#
|
104
|
+
def prepare_and_split_options(url, method, options)
|
105
|
+
request = {
|
106
|
+
:url => url,
|
107
|
+
:method => method,
|
108
|
+
:headers => default_headers.merge(options[:headers] || {})
|
109
|
+
}
|
110
|
+
parser = {
|
111
|
+
:raw => false
|
112
|
+
}
|
113
|
+
# Split the options
|
114
|
+
(options || {}).each do |k,v|
|
115
|
+
k = k.to_sym
|
116
|
+
next if k == :headers # already dealt with
|
117
|
+
if restclient_option_keys.include?(k)
|
118
|
+
request[k] = v
|
119
|
+
elsif header_option_keys.include?(k)
|
120
|
+
request[:headers][k] = v
|
46
121
|
else
|
47
|
-
|
122
|
+
parser[k] = v
|
48
123
|
end
|
49
124
|
end
|
125
|
+
[request, parser]
|
50
126
|
end
|
51
127
|
|
52
|
-
def delete(uri, options = {})
|
53
|
-
parse_response(RestClient.delete(uri, default_headers), options.dup)
|
54
|
-
end
|
55
|
-
|
56
|
-
def copy(uri, destination, options = {})
|
57
|
-
parse_response(RestClient::Request.execute( :method => :copy,
|
58
|
-
:url => uri,
|
59
|
-
:headers => default_headers.merge('Destination' => destination)
|
60
|
-
).to_s, options)
|
61
|
-
end
|
62
|
-
|
63
|
-
protected
|
64
|
-
|
65
128
|
# Check if the provided doc is nil or special IO device or temp file. If not,
|
66
129
|
# encode it into a string.
|
130
|
+
#
|
131
|
+
# The options supported are:
|
132
|
+
# * :raw TrueClass, if true the payload will not be altered.
|
133
|
+
#
|
67
134
|
def payload_from_doc(doc, opts = {})
|
68
135
|
(opts.delete(:raw) || doc.nil? || doc.is_a?(IO) || doc.is_a?(Tempfile)) ? doc : MultiJson.encode(doc)
|
69
136
|
end
|
@@ -73,5 +140,16 @@ module CouchRest
|
|
73
140
|
opts.delete(:raw) ? result : MultiJson.decode(result, opts.update(:max_nesting => false))
|
74
141
|
end
|
75
142
|
|
143
|
+
# An array of all the options that should be passed through to restclient.
|
144
|
+
# Anything not in this list will be passed to the JSON parser.
|
145
|
+
def restclient_option_keys
|
146
|
+
[:method, :url, :payload, :headers, :timeout, :open_timeout,
|
147
|
+
:verify_ssl, :ssl_client_cert, :ssl_client_key, :ssl_ca_file]
|
148
|
+
end
|
149
|
+
|
150
|
+
def header_option_keys
|
151
|
+
[ :content_type, :accept ]
|
152
|
+
end
|
153
|
+
|
76
154
|
end
|
77
155
|
end
|
data/lib/couchrest/version.rb
CHANGED
@@ -303,7 +303,7 @@ describe CouchRest::Database do
|
|
303
303
|
@db.fetch_attachment(@db.get('mydocwithattachment'), 'test.html').should == @attach
|
304
304
|
end
|
305
305
|
end
|
306
|
-
|
306
|
+
|
307
307
|
describe "PUT attachment from file" do
|
308
308
|
before(:each) do
|
309
309
|
filename = FIXTURE_PATH + '/attachments/couchdb.png'
|
@@ -316,12 +316,11 @@ describe CouchRest::Database do
|
|
316
316
|
r = @db.put_attachment({'_id' => 'attach-this'}, 'couchdb.png', image = @file.read, {:content_type => 'image/png'})
|
317
317
|
r['ok'].should == true
|
318
318
|
doc = @db.get("attach-this")
|
319
|
-
attachment = @db.fetch_attachment(doc,"couchdb.png")
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
end
|
319
|
+
attachment = @db.fetch_attachment(doc, "couchdb.png")
|
320
|
+
(attachment == image).should be_true
|
321
|
+
#if attachment.respond_to?(:net_http_res)
|
322
|
+
# attachment.net_http_res.body.should == image
|
323
|
+
#end
|
325
324
|
end
|
326
325
|
end
|
327
326
|
|
@@ -33,7 +33,7 @@ describe CouchRest::Document do
|
|
33
33
|
it "should respond to forwarded hash methods" do
|
34
34
|
@doc = CouchRest::Document.new(:foo => 'bar')
|
35
35
|
[:to_a, :==, :eql?, :keys, :values, :each, :reject, :reject!, :empty?,
|
36
|
-
:clear, :merge, :merge!, :encode_json, :as_json, :to_json].each do |call|
|
36
|
+
:clear, :merge, :merge!, :encode_json, :as_json, :to_json, :frozen?].each do |call|
|
37
37
|
@doc.should respond_to(call)
|
38
38
|
end
|
39
39
|
end
|
@@ -94,6 +94,17 @@ describe CouchRest::Document do
|
|
94
94
|
end
|
95
95
|
end
|
96
96
|
|
97
|
+
describe "#freeze" do
|
98
|
+
it "should freeze the attributes, but not actual model" do
|
99
|
+
klass = Class.new(CouchRest::Document)
|
100
|
+
klass.class_eval { attr_accessor :test_attr }
|
101
|
+
@doc = klass.new('foo' => 'bar')
|
102
|
+
@doc.freeze
|
103
|
+
lambda { @doc['foo'] = 'bar2' }.should raise_error(/frozen/)
|
104
|
+
lambda { @doc.test_attr = "bar3" }.should_not raise_error
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
97
108
|
|
98
109
|
describe "#inspect" do
|
99
110
|
it "should provide a string of keys and values of the Response" do
|
@@ -0,0 +1,204 @@
|
|
1
|
+
require File.expand_path("../../spec_helper", __FILE__)
|
2
|
+
|
3
|
+
describe CouchRest::RestAPI do
|
4
|
+
|
5
|
+
describe "class methods" do
|
6
|
+
|
7
|
+
subject { CouchRest }
|
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
|
+
end
|
21
|
+
|
22
|
+
it "should provide default headers" do
|
23
|
+
should respond_to :default_headers
|
24
|
+
CouchRest.default_headers.should be_a(Hash)
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
describe :get do
|
29
|
+
it "should send basic request" do
|
30
|
+
req = {:url => 'foo', :method => :get, :headers => CouchRest.default_headers}
|
31
|
+
request.should_receive(:execute).with(req).and_return(simple_response)
|
32
|
+
parser.should_receive(:decode).with(simple_response, parser_opts)
|
33
|
+
CouchRest.get('foo')
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should never modify options" do
|
37
|
+
options = {:timeout => 1000}
|
38
|
+
options.freeze
|
39
|
+
request.should_receive(:execute).and_return(simple_response)
|
40
|
+
parser.should_receive(:decode)
|
41
|
+
expect { CouchRest.get('foo', options) }.to_not raise_error
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
it "should accept 'content_type' header" do
|
46
|
+
req = {:url => 'foo', :method => :get, :headers => CouchRest.default_headers.merge(:content_type => :foo)}
|
47
|
+
request.should_receive(:execute).with(req).and_return(simple_response)
|
48
|
+
parser.should_receive(:decode).with(simple_response, parser_opts)
|
49
|
+
CouchRest.get('foo', :content_type => :foo)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should accept 'accept' header" do
|
53
|
+
req = {:url => 'foo', :method => :get, :headers => CouchRest.default_headers.merge(:accept => :foo)}
|
54
|
+
request.should_receive(:execute).with(req).and_return(simple_response)
|
55
|
+
parser.should_receive(:decode).with(simple_response, parser_opts)
|
56
|
+
CouchRest.get('foo', :accept => :foo)
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should forward RestClient options" do
|
60
|
+
req = {:url => 'foo', :method => :get, :timeout => 1000, :headers => CouchRest.default_headers}
|
61
|
+
request.should_receive(:execute).with(req).and_return(simple_response)
|
62
|
+
parser.should_receive(:decode).with(simple_response, parser_opts)
|
63
|
+
CouchRest.get('foo', :timeout => 1000)
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should forward parser options" do
|
67
|
+
req = {:url => 'foo', :method => :get, :headers => CouchRest.default_headers}
|
68
|
+
request.should_receive(:execute).with(req).and_return(simple_response)
|
69
|
+
parser.should_receive(:decode).with(simple_response, parser_opts.merge(:random => 'foo'))
|
70
|
+
CouchRest.get('foo', :random => 'foo')
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should accept raw option" do
|
74
|
+
req = {:url => 'foo', :method => :get, :headers => CouchRest.default_headers}
|
75
|
+
request.should_receive(:execute).with(req).and_return(simple_response)
|
76
|
+
parser.should_not_receive(:decode)
|
77
|
+
CouchRest.get('foo', :raw => true).should eql(simple_response)
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should allow override of method (not that you'd want to!)" do
|
81
|
+
req = {:url => 'foo', :method => :fubar, :headers => CouchRest.default_headers}
|
82
|
+
request.should_receive(:execute).with(req).and_return(simple_response)
|
83
|
+
parser.should_receive(:decode).with(simple_response, parser_opts)
|
84
|
+
CouchRest.get('foo', :method => :fubar)
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should allow override of url (not that you'd want to!)" do
|
88
|
+
req = {:url => 'foobardom', :method => :get, :headers => CouchRest.default_headers}
|
89
|
+
request.should_receive(:execute).with(req).and_return(simple_response)
|
90
|
+
parser.should_receive(:decode).with(simple_response, parser_opts)
|
91
|
+
CouchRest.get('foo', :url => 'foobardom')
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
it "should forward an exception if raised" do
|
96
|
+
request.should_receive(:execute).and_raise(RestClient::Exception)
|
97
|
+
expect { CouchRest.get('foo') }.to raise_error(RestClient::Exception)
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
describe :post do
|
103
|
+
it "should send basic request" do
|
104
|
+
req = {:url => 'foo', :method => :post, :headers => CouchRest.default_headers, :payload => 'data'}
|
105
|
+
request.should_receive(:execute).with(req).and_return(simple_response)
|
106
|
+
parser.should_receive(:encode).with('data').and_return('data')
|
107
|
+
parser.should_receive(:decode).with(simple_response, parser_opts)
|
108
|
+
CouchRest.post('foo', 'data')
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should send basic request" do
|
112
|
+
req = {:url => 'foo', :method => :post, :headers => CouchRest.default_headers, :payload => 'data'}
|
113
|
+
request.should_receive(:execute).with(req).and_return(simple_response)
|
114
|
+
parser.should_receive(:encode).with('data').and_return('data')
|
115
|
+
parser.should_receive(:decode).with(simple_response, parser_opts)
|
116
|
+
CouchRest.post('foo', 'data')
|
117
|
+
end
|
118
|
+
|
119
|
+
it "should send raw request" do
|
120
|
+
req = {:url => 'foo', :method => :post, :headers => CouchRest.default_headers, :payload => 'data'}
|
121
|
+
request.should_receive(:execute).with(req).and_return(simple_response)
|
122
|
+
parser.should_not_receive(:encode)
|
123
|
+
parser.should_receive(:decode).with(simple_response, parser_opts)
|
124
|
+
CouchRest.post('foo', 'data', :raw => true)
|
125
|
+
end
|
126
|
+
|
127
|
+
it "should not encode nil request" do
|
128
|
+
req = {:url => 'foo', :method => :post, :headers => CouchRest.default_headers}
|
129
|
+
request.should_receive(:execute).with(req).and_return(simple_response)
|
130
|
+
parser.should_not_receive(:encode)
|
131
|
+
parser.should_receive(:decode).with(simple_response, parser_opts)
|
132
|
+
CouchRest.post('foo', nil)
|
133
|
+
end
|
134
|
+
|
135
|
+
it "should send raw request automatically if file provided" do
|
136
|
+
f = File.open(FIXTURE_PATH + '/attachments/couchdb.png')
|
137
|
+
req = {:url => 'foo', :method => :post, :headers => CouchRest.default_headers, :payload => f}
|
138
|
+
request.should_receive(:execute).with(req).and_return(simple_response)
|
139
|
+
parser.should_not_receive(:encode)
|
140
|
+
parser.should_receive(:decode).with(simple_response, parser_opts)
|
141
|
+
CouchRest.post('foo', f)
|
142
|
+
f.close
|
143
|
+
end
|
144
|
+
|
145
|
+
it "should send raw request automatically if Tempfile provided" do
|
146
|
+
f = Tempfile.new('couchrest')
|
147
|
+
req = {:url => 'foo', :method => :post, :headers => CouchRest.default_headers, :payload => f}
|
148
|
+
request.should_receive(:execute).with(req).and_return(simple_response)
|
149
|
+
parser.should_not_receive(:encode)
|
150
|
+
parser.should_receive(:decode).with(simple_response, parser_opts)
|
151
|
+
CouchRest.post('foo', f)
|
152
|
+
f.close
|
153
|
+
end
|
154
|
+
|
155
|
+
|
156
|
+
end
|
157
|
+
|
158
|
+
|
159
|
+
describe :put do
|
160
|
+
# Only test basic as practically same as post
|
161
|
+
it "should send basic request" do
|
162
|
+
req = {:url => 'foo', :method => :put, :headers => CouchRest.default_headers, :payload => 'data'}
|
163
|
+
request.should_receive(:execute).with(req).and_return(simple_response)
|
164
|
+
parser.should_receive(:encode).with('data').and_return('data')
|
165
|
+
parser.should_receive(:decode).with(simple_response, parser_opts)
|
166
|
+
CouchRest.put('foo', 'data')
|
167
|
+
end
|
168
|
+
|
169
|
+
end
|
170
|
+
|
171
|
+
describe :delete do
|
172
|
+
it "should send basic request" do
|
173
|
+
req = {:url => 'foo', :method => :delete, :headers => CouchRest.default_headers}
|
174
|
+
request.should_receive(:execute).with(req).and_return(simple_response)
|
175
|
+
parser.should_receive(:decode).with(simple_response, parser_opts)
|
176
|
+
CouchRest.delete('foo')
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
describe :copy do
|
181
|
+
it "should send basic request" do
|
182
|
+
headers = CouchRest.default_headers.merge(
|
183
|
+
'Destination' => 'fooobar'
|
184
|
+
)
|
185
|
+
req = {:url => 'foo', :method => :copy, :headers => headers}
|
186
|
+
request.should_receive(:execute).with(req).and_return(simple_response)
|
187
|
+
parser.should_receive(:decode).with(simple_response, parser_opts)
|
188
|
+
CouchRest.copy('foo', 'fooobar')
|
189
|
+
end
|
190
|
+
|
191
|
+
it "should never modify header options" do
|
192
|
+
options = {:headers => {:content_type => :foo}}
|
193
|
+
options.freeze
|
194
|
+
request.should_receive(:execute).and_return(simple_response)
|
195
|
+
parser.should_receive(:decode)
|
196
|
+
expect { CouchRest.copy('foo', 'foobar', options) }.to_not raise_error
|
197
|
+
end
|
198
|
+
|
199
|
+
end
|
200
|
+
|
201
|
+
|
202
|
+
end
|
203
|
+
|
204
|
+
end
|
metadata
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: couchrest
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
prerelease:
|
5
|
-
version: 1.1.0
|
4
|
+
prerelease:
|
5
|
+
version: 1.1.0
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- J. Chris Anderson
|
@@ -103,6 +103,7 @@ files:
|
|
103
103
|
- history.txt
|
104
104
|
- init.rb
|
105
105
|
- lib/couchrest.rb
|
106
|
+
- lib/couchrest/attributes.rb
|
106
107
|
- lib/couchrest/commands/generate.rb
|
107
108
|
- lib/couchrest/commands/push.rb
|
108
109
|
- lib/couchrest/database.rb
|
@@ -125,6 +126,7 @@ files:
|
|
125
126
|
- spec/couchrest/document_spec.rb
|
126
127
|
- spec/couchrest/helpers/pager_spec.rb
|
127
128
|
- spec/couchrest/helpers/streamer_spec.rb
|
129
|
+
- spec/couchrest/rest_api_spec.rb
|
128
130
|
- spec/couchrest/server_spec.rb
|
129
131
|
- spec/fixtures/attachments/README
|
130
132
|
- spec/fixtures/attachments/couchdb.png
|