couchmodel 0.1.0.beta4 → 0.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/README.rdoc CHANGED
@@ -66,20 +66,20 @@ a design document will be created (but not saved to the file). The design ducume
66
66
 
67
67
  A design document should look like this
68
68
 
69
- :id: "test_design"
70
- :language: "javascript"
71
- :views:
72
- :view_name_1:
73
- :map:
69
+ id: "test_design"
70
+ language: "javascript"
71
+ views:
72
+ view_name_1:
73
+ map:
74
74
  function(document) {
75
75
  ...
76
76
  };
77
- :reduce:
77
+ reduce:
78
78
  function(key, values, rereduce) {
79
79
  ...
80
80
  };
81
- :view_name_2:
82
- :keys: [ "key_one", "key_two" ]
81
+ view_name_2:
82
+ keys: [ "key_one", "key_two" ]
83
83
  ...
84
84
 
85
85
  It will create the methods <tt>Model.view_name_1</tt> and <tt>Model.view_name_2</tt>, which returns the result of the
data/Rakefile CHANGED
@@ -1,10 +1,44 @@
1
1
  require 'rubygems'
2
2
  gem 'rspec'
3
3
  require 'spec'
4
+ require 'rake/rdoctask'
5
+ require 'rake/gempackagetask'
4
6
  require 'spec/rake/spectask'
5
7
 
6
8
  task :default => :spec
7
9
 
10
+ specification = Gem::Specification.new do |specification|
11
+ specification.name = "couchmodel"
12
+ specification.version = "0.1.0"
13
+ specification.date = "2010-03-31"
14
+
15
+ specification.authors = [ "Philipp Bruell" ]
16
+ specification.email = "b.phifty@gmail.com"
17
+ specification.homepage = "http://github.com/phifty/couchmodel"
18
+ specification.rubyforge_project = "couchmodel"
19
+
20
+ specification.summary = "CouchModel provides an interface to easly handle CouchDB documents."
21
+ specification.description = "CouchModel provides an interface to easly handle CouchDB documents. It also comes with a ActiveModel implementation to integrate into an Rails 3 application."
22
+
23
+ specification.has_rdoc = true
24
+ specification.files = [ "README.rdoc", "LICENSE", "Rakefile" ] + Dir["lib/**/*"] + Dir["spec/**/*"]
25
+ specification.extra_rdoc_files = [ "README.rdoc" ]
26
+ specification.require_path = "lib"
27
+
28
+ specification.test_files = Dir["spec/**/*_spec.rb"]
29
+ end
30
+
31
+ Rake::GemPackageTask.new(specification) do |package|
32
+ package.gem_spec = specification
33
+ end
34
+
35
+ desc "Generate the rdoc"
36
+ Rake::RDocTask.new do |rdoc|
37
+ rdoc.rdoc_files.add [ "README.rdoc", "lib/**/*.rb" ]
38
+ rdoc.main = "README.rdoc"
39
+ rdoc.title = "CouchModel interface to handle CouchDB documents."
40
+ end
41
+
8
42
  desc "Run all specs in spec directory"
9
43
  Spec::Rake::SpecTask.new do |task|
10
44
  task.spec_files = FileList["spec/lib/**/*_spec.rb"]
@@ -0,0 +1,3 @@
1
+ ---
2
+ LongMethod:
3
+ max_statements: 9
@@ -63,9 +63,9 @@ module CouchModel
63
63
  end
64
64
 
65
65
  def load
66
- load_response Transport.request(:get, url, :expected_status_code => 200)
66
+ load_response ExtendedTransport.request(:get, url, :expected_status_code => 200)
67
67
  true
68
- rescue Transport::UnexpectedStatusCodeError => error
68
+ rescue ExtendedTransport::UnexpectedStatusCodeError => error
69
69
  upgrade_unexpected_status_error error
70
70
  end
71
71
 
@@ -77,10 +77,10 @@ module CouchModel
77
77
 
78
78
  def destroy
79
79
  return false if new?
80
- Transport.request :delete, self.url, :headers => { "If-Match" => self.rev }, :expected_status_code => 200
80
+ ExtendedTransport.request :delete, self.url, :headers => { "If-Match" => self.rev }, :expected_status_code => 200
81
81
  clear_rev
82
82
  true
83
- rescue Transport::UnexpectedStatusCodeError => error
83
+ rescue ExtendedTransport::UnexpectedStatusCodeError => error
84
84
  upgrade_unexpected_status_error error
85
85
  end
86
86
 
@@ -105,19 +105,19 @@ module CouchModel
105
105
  end
106
106
 
107
107
  def create
108
- response = Transport.request :post, self.database.url, :body => self.attributes, :expected_status_code => 201
108
+ response = ExtendedTransport.request :post, self.database.url, :body => self.attributes, :expected_status_code => 201
109
109
  self.id = response["id"]
110
110
  self.rev = response["rev"]
111
111
  true
112
- rescue Transport::UnexpectedStatusCodeError
112
+ rescue ExtendedTransport::UnexpectedStatusCodeError
113
113
  false
114
114
  end
115
115
 
116
116
  def update
117
- response = Transport.request :put, self.url, :body => self.attributes, :expected_status_code => 201
117
+ response = ExtendedTransport.request :put, self.url, :body => self.attributes, :expected_status_code => 201
118
118
  self.rev = response["rev"]
119
119
  true
120
- rescue Transport::UnexpectedStatusCodeError
120
+ rescue ExtendedTransport::UnexpectedStatusCodeError
121
121
  false
122
122
  end
123
123
 
@@ -64,7 +64,7 @@ module CouchModel
64
64
  end
65
65
 
66
66
  def fetch_response
67
- @response = Transport.request(
67
+ @response = ExtendedTransport.request(
68
68
  :get, url,
69
69
  :parameters => request_parameters,
70
70
  :expected_status_code => 200
@@ -72,7 +72,7 @@ module CouchModel
72
72
  end
73
73
 
74
74
  def fetch_meta_response
75
- @response = Transport.request(
75
+ @response = ExtendedTransport.request(
76
76
  :get, url,
77
77
  :parameters => request_parameters.merge(:limit => 0),
78
78
  :expected_status_code => 200
@@ -25,7 +25,7 @@ module CouchModel
25
25
  end
26
26
 
27
27
  def create!
28
- Transport.request :put, url, :expected_status_code => 201
28
+ ExtendedTransport.request :put, url, :expected_status_code => 201
29
29
  end
30
30
 
31
31
  def create_if_missing!
@@ -33,7 +33,7 @@ module CouchModel
33
33
  end
34
34
 
35
35
  def delete!
36
- Transport.request :delete, url, :expected_status_code => 200
36
+ ExtendedTransport.request :delete, url, :expected_status_code => 200
37
37
  end
38
38
 
39
39
  def delete_if_exists!
@@ -41,7 +41,7 @@ module CouchModel
41
41
  end
42
42
 
43
43
  def informations
44
- Transport.request :get, url, :expected_status_code => 200
44
+ ExtendedTransport.request :get, url, :expected_status_code => 200
45
45
  end
46
46
 
47
47
  def exists?
@@ -33,7 +33,9 @@ module CouchModel
33
33
  end
34
34
 
35
35
  def load_file
36
- self.id, self.language, self.views = YAML::load_file(self.filename).values_at(:id, :language, :views)
36
+ hash = YAML::load_file self.filename
37
+ symbolize_hash_keys hash
38
+ self.id, self.language, self.views = hash.values_at(:id, :language, :views)
37
39
  true
38
40
  rescue Errno::ENOENT
39
41
  false
@@ -65,7 +67,7 @@ module CouchModel
65
67
  end
66
68
 
67
69
  def exists?
68
- Transport.request :get, self.url, :expected_status_code => 200
70
+ ExtendedTransport.request :get, self.url, :expected_status_code => 200
69
71
  true
70
72
  rescue Transport::UnexpectedStatusCodeError
71
73
  false
@@ -73,9 +75,9 @@ module CouchModel
73
75
 
74
76
  def push
75
77
  url = self.url
76
- evaluate Transport.request(:get, url)
78
+ evaluate ExtendedTransport.request(:get, url)
77
79
 
78
- Transport.request :put, url, :body => self.to_hash, :expected_status_code => 201
80
+ ExtendedTransport.request :put, url, :body => self.to_hash, :expected_status_code => 201
79
81
  true
80
82
  end
81
83
 
@@ -87,6 +89,14 @@ module CouchModel
87
89
 
88
90
  attr_writer :rev
89
91
 
92
+ def symbolize_hash_keys(hash)
93
+ hash.keys.each do |key|
94
+ value = hash.delete key
95
+ symbolize_hash_keys value if value.is_a?(Hash)
96
+ hash[(key.to_sym rescue key) || key] = value
97
+ end
98
+ end
99
+
90
100
  def evaluate(response)
91
101
  self.rev = response["_rev"] if response.has_key?("_rev")
92
102
  end
@@ -19,19 +19,19 @@ module CouchModel
19
19
  end
20
20
 
21
21
  def informations
22
- Transport.request :get, url + "/", :expected_status_code => 200
22
+ ExtendedTransport.request :get, url + "/", :expected_status_code => 200
23
23
  end
24
24
 
25
25
  def statistics
26
- Transport.request :get, url + "/_stats", :expected_status_code => 200
26
+ ExtendedTransport.request :get, url + "/_stats", :expected_status_code => 200
27
27
  end
28
28
 
29
29
  def database_names
30
- Transport.request :get, url + "/_all_dbs", :expected_status_code => 200
30
+ ExtendedTransport.request :get, url + "/_all_dbs", :expected_status_code => 200
31
31
  end
32
32
 
33
33
  def uuids(count = 1)
34
- response = Transport.request :get, url + "/_uuids", :expected_status_code => 200, :parameters => { :count => count }
34
+ response = ExtendedTransport.request :get, url + "/_uuids", :expected_status_code => 200, :parameters => { :count => count }
35
35
  response["uuids"]
36
36
  end
37
37
 
@@ -1,89 +1,178 @@
1
1
  require 'uri'
2
+ require 'cgi'
2
3
  require 'net/http'
3
4
  require 'json'
4
5
 
5
6
  module CouchModel
6
7
 
7
- module Transport
8
+ # Common transport layer for http transfers.
9
+ class Transport
10
+
11
+ attr_reader :http_method
12
+ attr_reader :url
13
+ attr_reader :options
14
+ attr_reader :headers
15
+ attr_reader :parameters
16
+ attr_reader :body
17
+ attr_reader :response
18
+
19
+ def initialize(http_method, url, options = { })
20
+ @http_method = http_method
21
+ @uri = URI.parse url
22
+ @headers = options[:headers] || { }
23
+ @parameters = options[:parameters] || { }
24
+ @body = options[:body]
25
+ end
8
26
 
9
- # The UnexpectedStatusCodeError is raised if the :expected_status_code option is given to
10
- # the :request method and the responded status code is different from the expected one.
11
- class UnexpectedStatusCodeError < StandardError
27
+ def perform
28
+ initialize_request_class
29
+ initialize_request_path
30
+ initialize_request
31
+ initialize_request_body
32
+ perform_request
33
+ end
12
34
 
13
- attr_reader :status_code
35
+ private
36
+
37
+ def initialize_request_class
38
+ request_class_name = @http_method.to_s.capitalize
39
+ raise NotImplementedError, "the request method #{http_method} is not implemented" unless Net::HTTP.const_defined?(request_class_name)
40
+ @request_class = Net::HTTP.const_get request_class_name
41
+ end
14
42
 
15
- def initialize(status_code)
16
- @status_code = status_code
43
+ def initialize_request_path
44
+ serialize_parameters
45
+ @request_path = @uri.path + @serialized_parameters
46
+ end
47
+
48
+ def serialize_parameters
49
+ quote_parameters
50
+ @serialized_parameters = if @parameters.nil? || @parameters.empty?
51
+ ""
52
+ else
53
+ "?" + @quoted_parameters.collect do |key, value|
54
+ value.is_a?(Array) ?
55
+ value.map{ |element| "#{key}=#{element}" }.join("&") :
56
+ "#{key}=#{value}"
57
+ end.join("&")
17
58
  end
59
+ end
18
60
 
19
- def to_s
20
- "#{super} received status code #{self.status_code}"
61
+ def quote_parameters
62
+ @quoted_parameters = { }
63
+ @parameters.each do |key, value|
64
+ encoded_key = CGI.escape(key.to_s)
65
+ @quoted_parameters[encoded_key] = value.is_a?(Array) ? value.map{ |element| CGI.escape element } : CGI.escape(value)
21
66
  end
67
+ end
22
68
 
69
+ def initialize_request
70
+ @request = @request_class.new @request_path, @headers
23
71
  end
24
72
 
25
- def self.request(http_method, url, options = { })
26
- expected_status_code = options[:expected_status_code]
73
+ def initialize_request_body
74
+ return unless [ :post, :put ].include?(@http_method.to_sym)
75
+ @request.body = @body ? @body : @serialized_parameters.sub(/^\?/, "")
76
+ end
27
77
 
28
- uri = URI.parse url
29
- response = perform request_object(http_method, uri, options), uri
78
+ def perform_request
79
+ @response = Net::HTTP.start(@uri.host, @uri.port) do |connection|
80
+ connection.request @request
81
+ end
82
+ end
30
83
 
31
- check_status_code response, expected_status_code if expected_status_code
32
- parse response
84
+ def self.request(http_method, url, options = { })
85
+ transport = new http_method, url, options
86
+ transport.perform
87
+ transport.response
33
88
  end
34
89
 
35
- def self.request_object(http_method, uri, options)
36
- raise NotImplementedError, "the request method #{http_method} is not implemented" unless
37
- self.respond_to?(:"#{http_method}_request_object")
90
+ end
91
+
92
+ # Extended transport layer for http transfers. Basic authorization and JSON transfers are supported.
93
+ class ExtendedTransport < Transport
94
+
95
+ # The UnexpectedStatusCodeError is raised if the :expected_status_code option is given to
96
+ # the :request method and the responded status code is different from the expected one.
97
+ class UnexpectedStatusCodeError < StandardError
98
+
99
+ attr_reader :status_code
100
+ attr_reader :message
101
+
102
+ def initialize(status_code, message = nil)
103
+ @status_code, @message = status_code, message
104
+ end
105
+
106
+ def to_s
107
+ "#{super} received status code #{self.status_code}" + (@message ? " [#{@message}]" : "")
108
+ end
38
109
 
39
- request_object = send :"#{http_method}_request_object", uri.path, (options[:parameters] || { }), (options[:headers] || { })
40
- request_object.body = options[:body].to_json if options.has_key?(:body)
41
- request_object
42
110
  end
43
111
 
44
- def self.get_request_object(path, parameters, headers)
45
- Net::HTTP::Get.new path + serialize_parameters(parameters),
46
- headers
112
+ attr_reader :expected_status_code
113
+ attr_reader :auth_type
114
+ attr_reader :username
115
+ attr_reader :password
116
+
117
+ def initialize(http_method, url, options = { })
118
+ super http_method, url, options
119
+ @expected_status_code = options[:expected_status_code]
120
+ @auth_type = options[:auth_type]
121
+ @username = options[:username]
122
+ @password = options[:password]
47
123
  end
48
124
 
49
- def self.post_request_object(path, parameters, headers)
50
- Net::HTTP::Post.new path + serialize_parameters(parameters),
51
- { "Content-Type" => "application/json" }.merge(headers)
125
+ def perform
126
+ initialize_headers
127
+ super
128
+ check_status_code
129
+ parse_response
52
130
  end
53
131
 
54
- def self.put_request_object(path, parameters, headers)
55
- Net::HTTP::Put.new path + serialize_parameters(parameters),
56
- { "Content-Type" => "application/json" }.merge(headers)
132
+ private
133
+
134
+ def initialize_headers
135
+ @headers["Accept"] = "application/json"
57
136
  end
58
137
 
59
- def self.delete_request_object(path, parameters, headers)
60
- Net::HTTP::Delete.new path + serialize_parameters(parameters),
61
- headers
138
+ def initialize_request
139
+ super
140
+ if @auth_type == :basic
141
+ @request.basic_auth @username, @password
142
+ elsif @auth_type
143
+ raise NotImplementedError, "the given auth_type [#{@auth_type}] is not implemented"
144
+ end
62
145
  end
63
146
 
64
- def self.serialize_parameters(parameters)
65
- return "" if parameters.empty?
66
- "?" + parameters.collect do |key, value|
67
- value = value.respond_to?(:to_json) ? value.to_json : value.to_s
68
- "#{key}=#{URI.escape(value)}"
69
- end.reverse.join("&")
147
+ def quote_parameters
148
+ @parameters.each do |key, value|
149
+ @parameters[key] = value.to_json if value.respond_to?(:to_json)
150
+ end
151
+ super
70
152
  end
71
153
 
72
- def self.perform(request, uri)
73
- Net::HTTP.start(uri.host, uri.port) do |connection|
74
- connection.request request
154
+ def initialize_request_body
155
+ super
156
+ if @body
157
+ @request.body = @body.to_json
158
+ @request["Content-Type"] = "application/json"
75
159
  end
76
160
  end
77
161
 
78
- def self.check_status_code(response, expected_status_code)
79
- response_code = response.code
80
- raise UnexpectedStatusCodeError, response_code.to_i if expected_status_code.to_s != response_code
162
+ def check_status_code
163
+ return unless @expected_status_code
164
+ response_code = @response.code
165
+ response_body = @response.body
166
+ raise UnexpectedStatusCodeError.new(response_code.to_i, response_body) if @expected_status_code.to_s != response_code
81
167
  end
82
168
 
83
- def self.parse(response)
84
- JSON.parse response.body
169
+ def parse_response
170
+ body = @response.body
171
+ @response = body.nil? ? nil : JSON.parse(body)
172
+ rescue JSON::ParserError
173
+ @response = body.to_s
85
174
  end
86
175
 
87
176
  end
88
177
 
89
- end
178
+ end
@@ -1,29 +1,38 @@
1
1
  require 'yaml'
2
2
 
3
- module CouchModel
3
+ module FakeTransport
4
4
 
5
- module Transport
5
+ def self.enable!
6
+ @enabled = true
7
+ end
8
+
9
+ def self.disable!
10
+ @enabled = false
11
+ end
6
12
 
7
- def self.fake!
8
- @@fake ||= YAML::load_file File.join(File.dirname(__FILE__), "fake_transport.yml")
9
- self.stub!(:request).and_return do |http_method, url, options|
10
- options ||= { }
11
- parameters = options[:parameters]
12
- headers = options[:headers]
13
- expected_status_code = options[:expected_status_code]
13
+ def self.transport_class
14
+ CouchModel::ExtendedTransport
15
+ end
16
+
17
+ def self.fake!
18
+ return unless @enabled
19
+ @@fake ||= YAML::load_file File.join(File.dirname(__FILE__), "fake_transport.yml")
20
+ transport_class.stub!(:request).and_return do |http_method, url, options|
21
+ options ||= { }
22
+ parameters = options[:parameters]
23
+ headers = options[:headers]
24
+ expected_status_code = options[:expected_status_code]
14
25
 
15
- request = @@fake.detect do |hash|
16
- hash[:http_method].to_s == http_method.to_s &&
17
- hash[:url].to_s == url.to_s &&
18
- hash[:parameters] == parameters &&
19
- hash[:headers] == headers
20
- end
21
- raise StandardError, "no fake request found for [#{http_method} #{url} #{parameters.inspect} #{headers.inspect}]" unless request
22
- raise UnexpectedStatusCodeError, request[:response][:code].to_i if expected_status_code && expected_status_code.to_s != request[:response][:code]
23
- request[:response][:body].dup
26
+ request = @@fake.detect do |hash|
27
+ hash[:http_method].to_s == http_method.to_s &&
28
+ hash[:url].to_s == url.to_s &&
29
+ hash[:parameters] == parameters &&
30
+ hash[:headers] == headers
24
31
  end
32
+ raise StandardError, "no fake request found for [#{http_method} #{url} #{parameters.inspect} #{headers.inspect}]" unless request
33
+ raise transport_class::UnexpectedStatusCodeError.new(request[:response][:code].to_i, request[:response][:body]) if expected_status_code && expected_status_code.to_s != request[:response][:code]
34
+ request[:response][:body].dup
25
35
  end
26
-
27
36
  end
28
37
 
29
38
  end
@@ -121,7 +121,12 @@ describe "integration" do
121
121
  describe "all" do
122
122
 
123
123
  it "should include the saved user" do
124
- User.all.should include(@user_one)
124
+ begin
125
+ User.all.should include(@user_one)
126
+ rescue Object => error
127
+ puts error.backtrace
128
+ raise error
129
+ end
125
130
  User.all.should include(@user_two)
126
131
  end
127
132
 
@@ -1,5 +1,5 @@
1
- :id: "membership"
2
- :language: "javascript"
3
- :views:
4
- :by_user_id_and_created_at:
5
- :keys: [ "user_id", "created_at" ]
1
+ id: "membership"
2
+ language: "javascript"
3
+ views:
4
+ by_user_id_and_created_at:
5
+ keys: [ "user_id", "created_at" ]
@@ -1,14 +1,14 @@
1
- :id: "user"
2
- :language: "javascript"
3
- :views:
4
- :user_count:
5
- :map:
1
+ id: "user"
2
+ language: "javascript"
3
+ views:
4
+ user_count:
5
+ map:
6
6
  function(document) {
7
7
  if (document['model_class'] == 'User') {
8
8
  emit('user_count', 1);
9
9
  }
10
10
  }
11
- :reduce:
11
+ reduce:
12
12
  function(keys, values, rereduce) {
13
13
  return sum(values);
14
14
  }
@@ -93,7 +93,7 @@ describe BaseTestModel do
93
93
  end
94
94
 
95
95
  it "should return false on wrong status code" do
96
- CouchModel::Transport.stub!(:request).and_raise(CouchModel::Transport::UnexpectedStatusCodeError.new(404))
96
+ CouchModel::ExtendedTransport.stub!(:request).and_raise(CouchModel::ExtendedTransport::UnexpectedStatusCodeError.new(404))
97
97
  do_save.should be_false
98
98
  end
99
99
 
@@ -110,7 +110,7 @@ describe BaseTestModel do
110
110
  end
111
111
 
112
112
  it "should return false on wrong status code" do
113
- CouchModel::Transport.stub!(:request).and_raise(CouchModel::Transport::UnexpectedStatusCodeError.new(404))
113
+ CouchModel::ExtendedTransport.stub!(:request).and_raise(CouchModel::ExtendedTransport::UnexpectedStatusCodeError.new(404))
114
114
  do_save.should be_false
115
115
  end
116
116
 
@@ -143,7 +143,7 @@ describe BaseTestModel do
143
143
  end
144
144
 
145
145
  it "should raise NotFoundError on wrong status code" do
146
- CouchModel::Transport.stub!(:request).and_raise(CouchModel::Transport::UnexpectedStatusCodeError.new(404))
146
+ CouchModel::ExtendedTransport.stub!(:request).and_raise(CouchModel::ExtendedTransport::UnexpectedStatusCodeError.new(404))
147
147
  lambda do
148
148
  do_destroy
149
149
  end.should raise_error(CouchModel::Base::NotFoundError)
@@ -175,7 +175,7 @@ describe BaseTestModel do
175
175
  end
176
176
 
177
177
  it "should return nil on error" do
178
- CouchModel::Transport.stub!(:request).and_raise(CouchModel::Transport::UnexpectedStatusCodeError.new(500))
178
+ CouchModel::ExtendedTransport.stub!(:request).and_raise(CouchModel::ExtendedTransport::UnexpectedStatusCodeError.new(500))
179
179
  model = BaseTestModel.create :id => "test_model_1"
180
180
  model.should be_nil
181
181
  end
@@ -41,7 +41,7 @@ describe CouchModel::Collection do
41
41
  describe "without a previously performed fetch" do
42
42
 
43
43
  it "should perform a meta fetch (with a limit of zero)" do
44
- CouchModel::Transport.should_receive(:request).with(anything, anything,
44
+ CouchModel::ExtendedTransport.should_receive(:request).with(anything, anything,
45
45
  hash_including(:parameters => { :include_docs => true, :limit => 0 }))
46
46
  @collection.total_count
47
47
  end
@@ -59,7 +59,7 @@ describe CouchModel::Collection do
59
59
  end
60
60
 
61
61
  it "should not perform another fetch" do
62
- CouchModel::Transport.should_not_receive(:request)
62
+ CouchModel::ExtendedTransport.should_not_receive(:request)
63
63
  @collection.total_count
64
64
  end
65
65
 
@@ -49,11 +49,11 @@ describe CouchModel::Database do
49
49
 
50
50
  before :each do
51
51
  @response = { :code => "201" }
52
- CouchModel::Transport.stub!(:request).and_return(@response)
52
+ CouchModel::ExtendedTransport.stub!(:request).and_return(@response)
53
53
  end
54
54
 
55
55
  it "should create the database" do
56
- CouchModel::Transport.should_receive(:request).with(:put, /test$/, anything).and_return(@response)
56
+ CouchModel::ExtendedTransport.should_receive(:request).with(:put, /test$/, anything).and_return(@response)
57
57
  @database.create!
58
58
  end
59
59
 
@@ -83,11 +83,11 @@ describe CouchModel::Database do
83
83
 
84
84
  before :each do
85
85
  @response = { :code => "200" }
86
- CouchModel::Transport.stub!(:request).and_return(@response)
86
+ CouchModel::ExtendedTransport.stub!(:request).and_return(@response)
87
87
  end
88
88
 
89
89
  it "should delete the database" do
90
- CouchModel::Transport.should_receive(:request).with(:delete, /test$/, anything).and_return(@response)
90
+ CouchModel::ExtendedTransport.should_receive(:request).with(:delete, /test$/, anything).and_return(@response)
91
91
  @database.delete!
92
92
  end
93
93
 
@@ -1,5 +1,5 @@
1
- :id: "test_design"
2
- :language: "javascript"
3
- :views:
4
- "by_related_id_and_name":
5
- :keys: [ "related_id", "name" ]
1
+ id: "test_design"
2
+ language: "javascript"
3
+ views:
4
+ by_related_id_and_name:
5
+ keys: [ "related_id", "name" ]
@@ -1,10 +1,10 @@
1
- :id: "test_design"
2
- :language: "javascript"
3
- :views:
4
- "test_view":
5
- :map:
1
+ id: "test_design"
2
+ language: "javascript"
3
+ views:
4
+ test_view:
5
+ map:
6
6
  function(document) {
7
7
  };
8
- :reduce:
8
+ reduce:
9
9
  function(key, values, rereduce) {
10
10
  };
@@ -1,10 +1,10 @@
1
- :id: "test_design"
2
- :language: "javascript"
3
- :views:
4
- "test_view":
5
- :map:
1
+ id: "test_design"
2
+ language: "javascript"
3
+ views:
4
+ test_view:
5
+ map:
6
6
  function(document) {
7
7
  };
8
- :reduce:
8
+ reduce:
9
9
  function(key, values, rereduce) {
10
10
  };
@@ -3,19 +3,19 @@ require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "li
3
3
 
4
4
  describe CouchModel::Transport do
5
5
 
6
- describe "request" do
6
+ use_real_transport!
7
7
 
8
- use_real_transport!
8
+ describe "request" do
9
9
 
10
10
  before :each do
11
11
  @http_method = :get
12
12
  @url = "http://localhost:5984/"
13
13
  @options = { }
14
14
 
15
- @request = Net::HTTP::Get.new "/"
15
+ @request = Net::HTTP::Get.new "/", { }
16
16
  @response = Object.new
17
17
  @response.stub!(:code).and_return("200")
18
- @response.stub!(:body).and_return("{\"couchdb\":\"Welcome\",\"version\":\"0.10.0\"}")
18
+ @response.stub!(:body).and_return("test")
19
19
  Net::HTTP.stub!(:start).and_return(@response)
20
20
  end
21
21
 
@@ -33,29 +33,82 @@ describe CouchModel::Transport do
33
33
  do_request
34
34
  end
35
35
 
36
- it "should raise UnexpectedStatusCodeError if an unexpected status id returned" do
37
- lambda do
38
- do_request :expected_status_code => 201
39
- end.should raise_error(CouchModel::Transport::UnexpectedStatusCodeError)
36
+ it "should return the response" do
37
+ do_request.body.should == "test"
38
+ end
39
+
40
+ context "with parameters" do
41
+
42
+ before :each do
43
+ @options.merge! :parameters => { :foo => "bar", :test => [ "value1", "value2" ] }
44
+ end
45
+
46
+ it "should initialize the correct request object" do
47
+ Net::HTTP::Get.should_receive(:new).with(
48
+ "/?foo=bar&test=value1&test=value2", { }
49
+ ).and_return(@request)
50
+ do_request
51
+ end
52
+
40
53
  end
41
54
 
42
55
  end
43
56
 
44
- describe "serialize_parameters" do
57
+ end
58
+
59
+ describe CouchModel::ExtendedTransport do
60
+
61
+ use_real_transport!
62
+
63
+ describe "request" do
45
64
 
46
65
  before :each do
47
- @parameters = { :test => [ :test, 1, 2, 3 ], :another_test => :test }
66
+ @http_method = :get
67
+ @url = "http://localhost:5984/"
68
+ @options = {
69
+ :auth_type => :basic,
70
+ :username => "test",
71
+ :password => "test",
72
+ :expected_status_code => 200
73
+ }
74
+
75
+ @request = Net::HTTP::Get.new "/", { }
76
+ @response = Object.new
77
+ @response.stub!(:code).and_return("200")
78
+ @response.stub!(:body).and_return("{\"test\":\"test\"}")
79
+ Net::HTTP.stub!(:start).and_return(@response)
48
80
  end
49
81
 
50
- it "should return an empty string on empty parameter hash" do
51
- CouchModel::Transport.send(:serialize_parameters, { }).should == ""
82
+ def do_request(options = { })
83
+ CouchModel::ExtendedTransport.request @http_method, @url, @options.merge(options)
84
+ end
85
+
86
+ it "should initialize the correct request object" do
87
+ Net::HTTP::Get.should_receive(:new).with("/", { "Accept" => "application/json" }).and_return(@request)
88
+ do_request
52
89
  end
53
-
54
- it "should serialize the given parameters" do
55
- CouchModel::Transport.send(:serialize_parameters, @parameters).should ==
56
- "?another_test=%22test%22&test=[%22test%22,1,2,3]"
90
+
91
+ it "should perform the request" do
92
+ Net::HTTP.should_receive(:start).and_return(@response)
93
+ do_request
94
+ end
95
+
96
+ it "should return the parsed response" do
97
+ do_request.should == { "test" => "test" }
98
+ end
99
+
100
+ it "should raise NotImplementedError if the given auth_type is wrong" do
101
+ lambda do
102
+ do_request :auth_type => :invalid
103
+ end.should raise_error(NotImplementedError)
104
+ end
105
+
106
+ it "should raise UnexpectedStatusCodeError if responded status code is wrong" do
107
+ lambda do
108
+ do_request :expected_status_code => 201
109
+ end.should raise_error(CouchModel::ExtendedTransport::UnexpectedStatusCodeError)
57
110
  end
58
111
 
59
112
  end
60
113
 
61
- end
114
+ end
data/spec/spec_helper.rb CHANGED
@@ -2,13 +2,12 @@ require 'rubygems'
2
2
  gem 'rspec', '1.3.0'
3
3
  require 'spec'
4
4
 
5
- require File.expand_path(File.join(File.dirname(__FILE__), "..", "lib", "couch_model", "configuration"))
6
5
  require File.join(File.dirname(__FILE__), "fake_transport_helper")
7
6
 
8
- CouchModel::Configuration.fake_transport = true
7
+ FakeTransport.enable!
9
8
  Spec::Runner.configure do |configuration|
10
9
  configuration.before :each do
11
- CouchModel::Transport.fake! if CouchModel::Configuration.fake_transport
10
+ FakeTransport.fake!
12
11
  end
13
12
  end
14
13
 
@@ -16,11 +15,11 @@ def use_real_transport!
16
15
  class_eval do
17
16
 
18
17
  before :all do
19
- CouchModel::Configuration.fake_transport = false
18
+ FakeTransport.disable!
20
19
  end
21
20
 
22
21
  after :all do
23
- CouchModel::Configuration.fake_transport = true
22
+ FakeTransport.enable!
24
23
  end
25
24
 
26
25
  end
metadata CHANGED
@@ -1,21 +1,20 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: couchmodel
3
3
  version: !ruby/object:Gem::Version
4
- prerelease: true
4
+ prerelease: false
5
5
  segments:
6
6
  - 0
7
7
  - 1
8
8
  - 0
9
- - beta4
10
- version: 0.1.0.beta4
9
+ version: 0.1.0
11
10
  platform: ruby
12
11
  authors:
13
- - "Philipp Br\xC3\xBCll"
12
+ - Philipp Bruell
14
13
  autorequire:
15
14
  bindir: bin
16
15
  cert_chain: []
17
16
 
18
- date: 2010-03-25 00:00:00 +01:00
17
+ date: 2010-03-31 00:00:00 +02:00
19
18
  default_executable:
20
19
  dependencies: []
21
20
 
@@ -48,6 +47,7 @@ files:
48
47
  - lib/couch_model.rb
49
48
  - lib/core_extension/string.rb
50
49
  - lib/core_extension/array.rb
50
+ - lib/code_smells.reek
51
51
  - spec/spec_helper.rb
52
52
  - spec/lib/couch_model/view_spec.rb
53
53
  - spec/lib/couch_model/server_spec.rb
@@ -79,10 +79,8 @@ homepage: http://github.com/phifty/couchmodel
79
79
  licenses: []
80
80
 
81
81
  post_install_message:
82
- rdoc_options:
83
- - --line-numbers
84
- - --main
85
- - README.rdoc
82
+ rdoc_options: []
83
+
86
84
  require_paths:
87
85
  - lib
88
86
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -90,22 +88,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
90
88
  - - ">="
91
89
  - !ruby/object:Gem::Version
92
90
  segments:
93
- - 1
94
- - 9
95
- - 1
96
- version: 1.9.1
91
+ - 0
92
+ version: "0"
97
93
  required_rubygems_version: !ruby/object:Gem::Requirement
98
94
  requirements:
99
- - - ">"
95
+ - - ">="
100
96
  - !ruby/object:Gem::Version
101
97
  segments:
102
- - 1
103
- - 3
104
- - 1
105
- version: 1.3.1
98
+ - 0
99
+ version: "0"
106
100
  requirements: []
107
101
 
108
- rubyforge_project:
102
+ rubyforge_project: couchmodel
109
103
  rubygems_version: 1.3.6
110
104
  signing_key:
111
105
  specification_version: 3