couchrest 1.1.0.pre3 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|