namelessjon-couchrest 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. data/LICENSE +176 -0
  2. data/README.md +46 -0
  3. data/Rakefile +69 -0
  4. data/THANKS.md +21 -0
  5. data/couchrest.gemspec +111 -0
  6. data/examples/word_count/markov +38 -0
  7. data/examples/word_count/views/books/chunked-map.js +3 -0
  8. data/examples/word_count/views/books/united-map.js +1 -0
  9. data/examples/word_count/views/markov/chain-map.js +6 -0
  10. data/examples/word_count/views/markov/chain-reduce.js +7 -0
  11. data/examples/word_count/views/word_count/count-map.js +6 -0
  12. data/examples/word_count/views/word_count/count-reduce.js +3 -0
  13. data/examples/word_count/word_count.rb +46 -0
  14. data/examples/word_count/word_count_query.rb +40 -0
  15. data/examples/word_count/word_count_views.rb +26 -0
  16. data/history.txt +145 -0
  17. data/lib/couchrest/commands/generate.rb +71 -0
  18. data/lib/couchrest/commands/push.rb +103 -0
  19. data/lib/couchrest/database.rb +373 -0
  20. data/lib/couchrest/design.rb +80 -0
  21. data/lib/couchrest/document.rb +89 -0
  22. data/lib/couchrest/helper/attachments.rb +29 -0
  23. data/lib/couchrest/helper/pager.rb +103 -0
  24. data/lib/couchrest/helper/streamer.rb +51 -0
  25. data/lib/couchrest/helper/upgrade.rb +52 -0
  26. data/lib/couchrest/json_response.rb +14 -0
  27. data/lib/couchrest/middlewares/logger.rb +263 -0
  28. data/lib/couchrest/monkeypatches.rb +42 -0
  29. data/lib/couchrest/response.rb +35 -0
  30. data/lib/couchrest/rest_api.rb +62 -0
  31. data/lib/couchrest/server.rb +90 -0
  32. data/lib/couchrest/support/inheritable_attributes.rb +107 -0
  33. data/lib/couchrest.rb +127 -0
  34. data/spec/couchrest/couchrest_spec.rb +202 -0
  35. data/spec/couchrest/database_spec.rb +870 -0
  36. data/spec/couchrest/design_spec.rb +158 -0
  37. data/spec/couchrest/document_spec.rb +279 -0
  38. data/spec/couchrest/helpers/pager_spec.rb +123 -0
  39. data/spec/couchrest/helpers/streamer_spec.rb +52 -0
  40. data/spec/couchrest/server_spec.rb +35 -0
  41. data/spec/fixtures/attachments/README +3 -0
  42. data/spec/fixtures/attachments/couchdb.png +0 -0
  43. data/spec/fixtures/attachments/test.html +11 -0
  44. data/spec/fixtures/views/lib.js +3 -0
  45. data/spec/fixtures/views/test_view/lib.js +3 -0
  46. data/spec/fixtures/views/test_view/only-map.js +4 -0
  47. data/spec/fixtures/views/test_view/test-map.js +3 -0
  48. data/spec/fixtures/views/test_view/test-reduce.js +3 -0
  49. data/spec/spec.opts +5 -0
  50. data/spec/spec_helper.rb +44 -0
  51. data/utils/remap.rb +27 -0
  52. data/utils/subset.rb +30 -0
  53. metadata +179 -0
@@ -0,0 +1,42 @@
1
+ require 'timeout'
2
+
3
+ # This file must be loaded after the JSON gem and any other library that beats up the Time class.
4
+ class Time
5
+ # This date format sorts lexicographically
6
+ # and is compatible with Javascript's <tt>new Date(time_string)</tt> constructor.
7
+ # Note this this format stores all dates in UTC so that collation
8
+ # order is preserved. (There's no longer a need to set <tt>ENV['TZ'] = 'UTC'</tt>
9
+ # in your application.)
10
+
11
+ def to_json(options = nil)
12
+ u = self.getutc
13
+ %("#{u.strftime("%Y/%m/%d %H:%M:%S +0000")}")
14
+ end
15
+
16
+ end
17
+
18
+ # Monkey patch for faster net/http io
19
+ if RUBY_VERSION.to_f < 1.9
20
+ class Net::BufferedIO #:nodoc:
21
+ alias :old_rbuf_fill :rbuf_fill
22
+ def rbuf_fill
23
+ if @io.respond_to?(:read_nonblock)
24
+ begin
25
+ @rbuf << @io.read_nonblock(65536)
26
+ rescue Errno::EWOULDBLOCK
27
+ if IO.select([@io], nil, nil, @read_timeout)
28
+ retry
29
+ else
30
+ raise Timeout::Error, "IO timeout"
31
+ end
32
+ end
33
+ else
34
+ timeout(@read_timeout) do
35
+ @rbuf << @io.sysread(65536)
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+
42
+
@@ -0,0 +1,35 @@
1
+ module CouchRest
2
+ class Response < Hash
3
+ attr_reader :headers, :raw
4
+ def initialize(pkeys = {})
5
+ pkeys ||= {}
6
+ pkeys.each do |k,v|
7
+ self[k.to_s] = v
8
+ end
9
+ @headers = pkeys.respond_to?(:headers) ? pkeys.headers : {}
10
+ @raw = pkeys.respond_to?(:raw) ? pkeys.raw : nil
11
+ @original = {}
12
+ end
13
+
14
+ def []=(key, value)
15
+ k = key.to_s
16
+ @original[k] ||= self[k] if defined?(@original)
17
+ super(k, value)
18
+ end
19
+
20
+ def original
21
+ self.merge(@original)
22
+ end
23
+
24
+ def delete(key)
25
+ k = key.to_s
26
+ r = self.delete(k)
27
+ @original[k] ||= r
28
+ r
29
+ end
30
+
31
+ def [](key)
32
+ super(key.to_s)
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,62 @@
1
+ require 'couchrest/json_response'
2
+ module CouchRest
3
+ module RestAPI
4
+
5
+ def default_headers
6
+ {
7
+ :content_type => :json,
8
+ :accept => :json
9
+ }
10
+ end
11
+
12
+ def put(uri, doc = nil)
13
+ payload = doc.to_json if doc
14
+ begin
15
+ JsonResponse.create(RestClient.put(uri, payload, default_headers))
16
+ rescue Exception => e
17
+ if $DEBUG
18
+ raise "Error while sending a PUT request #{uri}\npayload: #{payload.inspect}\n#{e}"
19
+ else
20
+ raise e
21
+ end
22
+ end
23
+ end
24
+
25
+ def get(uri)
26
+ begin
27
+ JsonResponse.create(RestClient.get(uri, default_headers))
28
+ rescue => e
29
+ if $DEBUG
30
+ raise "Error while sending a GET request #{uri}\n: #{e}"
31
+ else
32
+ raise e
33
+ end
34
+ end
35
+ end
36
+
37
+ def post(uri, doc = nil)
38
+ payload = doc.to_json if doc
39
+ begin
40
+ JsonResponse.create(RestClient.post(uri, payload, default_headers))
41
+ rescue Exception => e
42
+ if $DEBUG
43
+ raise "Error while sending a POST request #{uri}\npayload: #{payload.inspect}\n#{e}"
44
+ else
45
+ raise e
46
+ end
47
+ end
48
+ end
49
+
50
+ def delete(uri)
51
+ JsonResponse.create(RestClient.delete(uri, default_headers))
52
+ end
53
+
54
+ def copy(uri, destination)
55
+ JsonResponse.create(RestClient::Request.execute( :method => :copy,
56
+ :url => uri,
57
+ :headers => default_headers.merge('Destination' => destination)
58
+ ))
59
+ end
60
+
61
+ end
62
+ end
@@ -0,0 +1,90 @@
1
+ module CouchRest
2
+ class Server
3
+ attr_accessor :uri, :uuid_batch_count, :available_databases
4
+ def initialize(server = 'http://127.0.0.1:5984', uuid_batch_count = 1000)
5
+ @uri = server
6
+ @uuid_batch_count = uuid_batch_count
7
+ end
8
+
9
+ # Lists all "available" databases.
10
+ # An available database, is a database that was specified
11
+ # as avaiable by your code.
12
+ # It allows to define common databases to use and reuse in your code
13
+ def available_databases
14
+ @available_databases ||= {}
15
+ end
16
+
17
+ # Adds a new available database and create it unless it already exists
18
+ #
19
+ # Example:
20
+ #
21
+ # @couch = CouchRest::Server.new
22
+ # @couch.define_available_database(:default, "tech-blog")
23
+ #
24
+ def define_available_database(reference, db_name, create_unless_exists = true)
25
+ available_databases[reference.to_sym] = create_unless_exists ? database!(db_name) : database(db_name)
26
+ end
27
+
28
+ # Checks that a database is set as available
29
+ #
30
+ # Example:
31
+ #
32
+ # @couch.available_database?(:default)
33
+ #
34
+ def available_database?(ref_or_name)
35
+ ref_or_name.is_a?(Symbol) ? available_databases.keys.include?(ref_or_name) : available_databases.values.map{|db| db.name}.include?(ref_or_name)
36
+ end
37
+
38
+ def default_database=(name, create_unless_exists = true)
39
+ define_available_database(:default, name, create_unless_exists = true)
40
+ end
41
+
42
+ def default_database
43
+ available_databases[:default]
44
+ end
45
+
46
+ # Lists all databases on the server
47
+ def databases
48
+ CouchRest.get "#{@uri}/_all_dbs"
49
+ end
50
+
51
+ # Returns a CouchRest::Database for the given name
52
+ def database(name)
53
+ CouchRest::Database.new(self, name)
54
+ end
55
+
56
+ # Creates the database if it doesn't exist
57
+ def database!(name)
58
+ create_db(name) rescue nil
59
+ database(name)
60
+ end
61
+
62
+ # GET the welcome message
63
+ def info
64
+ CouchRest.get "#{@uri}/"
65
+ end
66
+
67
+ # Create a database
68
+ def create_db(name)
69
+ CouchRest.put "#{@uri}/#{name}"
70
+ database(name)
71
+ end
72
+
73
+ # Restart the CouchDB instance
74
+ def restart!
75
+ CouchRest.post "#{@uri}/_restart"
76
+ rescue RestClient::ServerBrokeConnection
77
+ # Shouldn't really happen, but does in CouchDB 1.0.0
78
+ end
79
+
80
+ # Retrive an unused UUID from CouchDB. Server instances manage caching a list of unused UUIDs.
81
+ def next_uuid(count = @uuid_batch_count)
82
+ @uuids ||= []
83
+ if @uuids.empty?
84
+ @uuids = CouchRest.get("#{@uri}/_uuids?count=#{count}")["uuids"]
85
+ end
86
+ @uuids.pop
87
+ end
88
+
89
+ end
90
+ end
@@ -0,0 +1,107 @@
1
+ # Copyright (c) 2006-2009 David Heinemeier Hansson
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # "Software"), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge, publish,
7
+ # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # permit persons to whom the Software is furnished to do so, subject to
9
+ # the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+ #
22
+ # Extracted From
23
+ # http://github.com/rails/rails/commit/971e2438d98326c994ec6d3ef8e37b7e868ed6e2
24
+
25
+ module CouchRest
26
+ module InheritableAttributes
27
+
28
+ # Defines class-level inheritable attribute reader. Attributes are available to subclasses,
29
+ # each subclass has a copy of parent's attribute.
30
+ #
31
+ # @param *syms<Array[#to_s]> Array of attributes to define inheritable reader for.
32
+ # @return <Array[#to_s]> Array of attributes converted into inheritable_readers.
33
+ #
34
+ # @api public
35
+ #
36
+ # @todo Do we want to block instance_reader via :instance_reader => false
37
+ # @todo It would be preferable that we do something with a Hash passed in
38
+ # (error out or do the same as other methods above) instead of silently
39
+ # moving on). In particular, this makes the return value of this function
40
+ # less useful.
41
+ def couchrest_inheritable_reader(*ivars)
42
+ instance_reader = ivars.pop[:reader] if ivars.last.is_a?(Hash)
43
+
44
+ ivars.each do |ivar|
45
+ self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
46
+ def self.#{ivar}
47
+ return @#{ivar} if self.object_id == #{self.object_id} || defined?(@#{ivar})
48
+ ivar = superclass.#{ivar}
49
+ return nil if ivar.nil? && !#{self}.instance_variable_defined?("@#{ivar}")
50
+ @#{ivar} = ivar && !ivar.is_a?(Module) && !ivar.is_a?(Numeric) && !ivar.is_a?(TrueClass) && !ivar.is_a?(FalseClass) ? ivar.dup : ivar
51
+ end
52
+ RUBY
53
+ unless instance_reader == false
54
+ self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
55
+ def #{ivar}
56
+ self.class.#{ivar}
57
+ end
58
+ RUBY
59
+ end
60
+ end
61
+ end
62
+
63
+ # Defines class-level inheritable attribute writer. Attributes are available to subclasses,
64
+ # each subclass has a copy of parent's attribute.
65
+ #
66
+ # @param *syms<Array[*#to_s, Hash{:instance_writer => Boolean}]> Array of attributes to
67
+ # define inheritable writer for.
68
+ # @option syms :instance_writer<Boolean> if true, instance-level inheritable attribute writer is defined.
69
+ # @return <Array[#to_s]> An Array of the attributes that were made into inheritable writers.
70
+ #
71
+ # @api public
72
+ #
73
+ # @todo We need a style for class_eval <<-HEREDOC. I'd like to make it
74
+ # class_eval(<<-RUBY, __FILE__, __LINE__), but we should codify it somewhere.
75
+ def couchrest_inheritable_writer(*ivars)
76
+ instance_writer = ivars.pop[:writer] if ivars.last.is_a?(Hash)
77
+ ivars.each do |ivar|
78
+ self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
79
+ def self.#{ivar}=(obj)
80
+ @#{ivar} = obj
81
+ end
82
+ RUBY
83
+ unless instance_writer == false
84
+ self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
85
+ def #{ivar}=(obj) self.class.#{ivar} = obj end
86
+ RUBY
87
+ end
88
+
89
+ self.send("#{ivar}=", yield) if block_given?
90
+ end
91
+ end
92
+
93
+ # Defines class-level inheritable attribute accessor. Attributes are available to subclasses,
94
+ # each subclass has a copy of parent's attribute.
95
+ #
96
+ # @param *syms<Array[*#to_s, Hash{:instance_writer => Boolean}]> Array of attributes to
97
+ # define inheritable accessor for.
98
+ # @option syms :instance_writer<Boolean> if true, instance-level inheritable attribute writer is defined.
99
+ # @return <Array[#to_s]> An Array of attributes turned into inheritable accessors.
100
+ #
101
+ # @api public
102
+ def couchrest_inheritable_accessor(*syms, &block)
103
+ couchrest_inheritable_reader(*syms)
104
+ couchrest_inheritable_writer(*syms, &block)
105
+ end
106
+ end
107
+ end
data/lib/couchrest.rb ADDED
@@ -0,0 +1,127 @@
1
+ # Copyright 2008 J. Chris Anderson
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'yajl/json_gem'
16
+ require 'rest_client'
17
+
18
+ # Not sure why this is required, so removed until a reason is found!
19
+ $:.unshift File.dirname(__FILE__) unless
20
+ $:.include?(File.dirname(__FILE__)) ||
21
+ $:.include?(File.expand_path(File.dirname(__FILE__)))
22
+
23
+ require 'couchrest/monkeypatches'
24
+ require 'couchrest/rest_api'
25
+ require 'couchrest/support/inheritable_attributes'
26
+
27
+ # = CouchDB, close to the metal
28
+ module CouchRest
29
+ VERSION = '1.0.0'
30
+
31
+ # we always want these
32
+ require 'couchrest/server'
33
+ require 'couchrest/database'
34
+
35
+ # we extend CouchRest with the RestAPI module which gives us acess to
36
+ # the get, post, put, delete and copy
37
+ CouchRest.extend(RestAPI)
38
+
39
+ # The CouchRest module methods handle the basic JSON serialization
40
+ # and deserialization, as well as query parameters. The module also includes
41
+ # some helpers for tasks like instantiating a new Database or Server instance.
42
+ class << self
43
+
44
+ # todo, make this parse the url and instantiate a Server or Database instance
45
+ # depending on the specificity.
46
+ def new(*opts)
47
+ Server.new(*opts)
48
+ end
49
+
50
+ def parse url
51
+ case url
52
+ when /^(https?:\/\/)(.*)\/(.*)\/(.*)/
53
+ scheme = $1
54
+ host = $2
55
+ db = $3
56
+ docid = $4
57
+ when /^(https?:\/\/)(.*)\/(.*)/
58
+ scheme = $1
59
+ host = $2
60
+ db = $3
61
+ when /^(https?:\/\/)(.*)/
62
+ scheme = $1
63
+ host = $2
64
+ when /(.*)\/(.*)\/(.*)/
65
+ host = $1
66
+ db = $2
67
+ docid = $3
68
+ when /(.*)\/(.*)/
69
+ host = $1
70
+ db = $2
71
+ else
72
+ db = url
73
+ end
74
+
75
+ db = nil if db && db.empty?
76
+
77
+ {
78
+ :host => (scheme || "http://") + (host || "127.0.0.1:5984"),
79
+ :database => db,
80
+ :doc => docid
81
+ }
82
+ end
83
+
84
+ # set proxy to use
85
+ def proxy url
86
+ RestClient.proxy = url
87
+ end
88
+
89
+ # ensure that a database exists
90
+ # creates it if it isn't already there
91
+ # returns it after it's been created
92
+ def database! url
93
+ parsed = parse url
94
+ cr = CouchRest.new(parsed[:host])
95
+ cr.database!(parsed[:database])
96
+ end
97
+
98
+ def database url
99
+ parsed = parse url
100
+ cr = CouchRest.new(parsed[:host])
101
+ cr.database(parsed[:database])
102
+ end
103
+
104
+ def paramify_url url, params = {}
105
+ if params && !params.empty?
106
+ query = params.collect do |k,v|
107
+ v = v.to_json if %w{key startkey endkey}.include?(k.to_s)
108
+ "#{k}=#{CGI.escape(v.to_s)}"
109
+ end.join("&")
110
+ url = "#{url}?#{query}"
111
+ end
112
+ url
113
+ end
114
+ end # class << self
115
+ end
116
+ # For the sake of backwards compatability, generate a dummy ExtendedDocument class
117
+ # which should be replaced by real library: couchrest_extended_document.
118
+ #
119
+ # Added 2010-05-10 by Sam Lown. Please remove at some point in the future.
120
+ #
121
+ class CouchRest::ExtendedDocument < CouchRest::Document
122
+
123
+ def self.inherited(subclass)
124
+ raise "ExtendedDocument is no longer included in CouchRest base driver, see couchrest_extended_document gem"
125
+ end
126
+
127
+ end
@@ -0,0 +1,202 @@
1
+ require File.expand_path("../../spec_helper", __FILE__)
2
+
3
+ describe CouchRest do
4
+
5
+ before(:each) do
6
+ @cr = CouchRest.new(COUCHHOST)
7
+ begin
8
+ @db = @cr.database(TESTDB)
9
+ @db.delete! rescue nil
10
+ end
11
+ end
12
+
13
+ after(:each) do
14
+ begin
15
+ @db.delete! rescue nil
16
+ end
17
+ end
18
+
19
+ describe "getting info" do
20
+ it "should list databases" do
21
+ @cr.databases.should be_an_instance_of(Array)
22
+ end
23
+ it "should get info" do
24
+ @cr.info["couchdb"].should == "Welcome"
25
+ @cr.info.class.should == Hash
26
+ end
27
+ end
28
+
29
+ it "should restart" do
30
+ @cr.restart!
31
+ begin
32
+ @cr.info
33
+ rescue
34
+ # Give the couchdb time to restart
35
+ sleep 0.2
36
+ retry
37
+ end
38
+ end
39
+
40
+ it "should provide one-time access to uuids" do
41
+ @cr.next_uuid.should_not be_nil
42
+ end
43
+
44
+ describe "initializing a database" do
45
+ it "should return a db" do
46
+ db = @cr.database(TESTDB)
47
+ db.should be_an_instance_of(CouchRest::Database)
48
+ db.host.should == @cr.uri
49
+ end
50
+ end
51
+
52
+ describe "parsing urls" do
53
+ it "should parse just a dbname" do
54
+ db = CouchRest.parse "my-db"
55
+ db[:database].should == "my-db"
56
+ db[:host].should == "http://127.0.0.1:5984"
57
+ end
58
+ it "should parse a host and db" do
59
+ db = CouchRest.parse "127.0.0.1/my-db"
60
+ db[:database].should == "my-db"
61
+ db[:host].should == "http://127.0.0.1"
62
+ end
63
+ it "should parse a host and db with http" do
64
+ db = CouchRest.parse "http://127.0.0.1/my-db"
65
+ db[:database].should == "my-db"
66
+ db[:host].should == "http://127.0.0.1"
67
+ end
68
+ it "should parse a host and db with https" do
69
+ db = CouchRest.parse "https://127.0.0.1/my-db"
70
+ db[:database].should == "my-db"
71
+ db[:host].should == "https://127.0.0.1"
72
+ end
73
+ it "should parse a host with a port and db" do
74
+ db = CouchRest.parse "127.0.0.1:5555/my-db"
75
+ db[:database].should == "my-db"
76
+ db[:host].should == "http://127.0.0.1:5555"
77
+ end
78
+ it "should parse a host with a port and db with http" do
79
+ db = CouchRest.parse "http://127.0.0.1:5555/my-db"
80
+ db[:database].should == "my-db"
81
+ db[:host].should == "http://127.0.0.1:5555"
82
+ end
83
+ it "should parse a host with a port and db with https" do
84
+ db = CouchRest.parse "https://127.0.0.1:5555/my-db"
85
+ db[:database].should == "my-db"
86
+ db[:host].should == "https://127.0.0.1:5555"
87
+ end
88
+ it "should parse just a host" do
89
+ db = CouchRest.parse "http://127.0.0.1:5555/"
90
+ db[:database].should be_nil
91
+ db[:host].should == "http://127.0.0.1:5555"
92
+ end
93
+ it "should parse just a host with https" do
94
+ db = CouchRest.parse "https://127.0.0.1:5555/"
95
+ db[:database].should be_nil
96
+ db[:host].should == "https://127.0.0.1:5555"
97
+ end
98
+ it "should parse just a host no slash" do
99
+ db = CouchRest.parse "http://127.0.0.1:5555"
100
+ db[:host].should == "http://127.0.0.1:5555"
101
+ db[:database].should be_nil
102
+ end
103
+ it "should parse just a host no slash and https" do
104
+ db = CouchRest.parse "https://127.0.0.1:5555"
105
+ db[:host].should == "https://127.0.0.1:5555"
106
+ db[:database].should be_nil
107
+ end
108
+ it "should get docid" do
109
+ db = CouchRest.parse "127.0.0.1:5555/my-db/my-doc"
110
+ db[:database].should == "my-db"
111
+ db[:host].should == "http://127.0.0.1:5555"
112
+ db[:doc].should == "my-doc"
113
+ end
114
+ it "should get docid with http" do
115
+ db = CouchRest.parse "http://127.0.0.1:5555/my-db/my-doc"
116
+ db[:database].should == "my-db"
117
+ db[:host].should == "http://127.0.0.1:5555"
118
+ db[:doc].should == "my-doc"
119
+ end
120
+ it "should get docid with https" do
121
+ db = CouchRest.parse "https://127.0.0.1:5555/my-db/my-doc"
122
+ db[:database].should == "my-db"
123
+ db[:host].should == "https://127.0.0.1:5555"
124
+ db[:doc].should == "my-doc"
125
+ end
126
+ end
127
+
128
+ describe "easy initializing a database adapter" do
129
+ it "should be possible without an explicit CouchRest instantiation" do
130
+ db = CouchRest.database "http://127.0.0.1:5984/couchrest-test"
131
+ db.should be_an_instance_of(CouchRest::Database)
132
+ db.host.should == "http://127.0.0.1:5984"
133
+ end
134
+ # TODO add https support (need test environment...)
135
+ # it "should work with https" # do
136
+ # db = CouchRest.database "https://127.0.0.1:5984/couchrest-test"
137
+ # db.host.should == "https://127.0.0.1:5984"
138
+ # end
139
+ it "should not create the database automatically" do
140
+ db = CouchRest.database "http://127.0.0.1:5984/couchrest-test"
141
+ lambda{db.info}.should raise_error(RestClient::ResourceNotFound)
142
+ end
143
+ end
144
+
145
+ describe "ensuring the db exists" do
146
+ it "should be super easy" do
147
+ db = CouchRest.database! "#{COUCHHOST}/couchrest-test-2"
148
+ db.name.should == 'couchrest-test-2'
149
+ db.info["db_name"].should == 'couchrest-test-2'
150
+ end
151
+ end
152
+
153
+ describe "successfully creating a database" do
154
+ it "should start without a database" do
155
+ @cr.databases.should_not include(TESTDB)
156
+ end
157
+ it "should return the created database" do
158
+ db = @cr.create_db(TESTDB)
159
+ db.should be_an_instance_of(CouchRest::Database)
160
+ end
161
+ it "should create the database" do
162
+ db = @cr.create_db(TESTDB)
163
+ @cr.databases.should include(TESTDB)
164
+ end
165
+ end
166
+
167
+ describe "failing to create a database because the name is taken" do
168
+ before(:each) do
169
+ db = @cr.create_db(TESTDB)
170
+ end
171
+ it "should start with the test database" do
172
+ @cr.databases.should include(TESTDB)
173
+ end
174
+ it "should PUT the database and raise an error" do
175
+ lambda{
176
+ @cr.create_db(TESTDB)
177
+ }.should raise_error(RestClient::Request::RequestFailed)
178
+ end
179
+ end
180
+
181
+ describe "using a proxy for RestClient connections" do
182
+ it "should set proxy url for RestClient" do
183
+ CouchRest.proxy 'http://localhost:8888/'
184
+ proxy_uri = URI.parse(RestClient.proxy)
185
+ proxy_uri.host.should eql( 'localhost' )
186
+ proxy_uri.port.should eql( 8888 )
187
+ CouchRest.proxy nil
188
+ end
189
+ end
190
+
191
+ describe "Including old ExtendedDocument library" do
192
+
193
+ it "should raise an exception" do
194
+ lambda do
195
+ class TestDoc < CouchRest::ExtendedDocument
196
+ attr_reader :fail
197
+ end
198
+ end.should raise_error(RuntimeError)
199
+ end
200
+
201
+ end
202
+ end