sr-couchy 0.0.2

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 (41) hide show
  1. data/README.textile +77 -0
  2. data/Rakefile +46 -0
  3. data/bin/couchy +80 -0
  4. data/couchy.gemspec +58 -0
  5. data/lib/couchy.rb +21 -0
  6. data/lib/couchy/database.rb +129 -0
  7. data/lib/couchy/server.rb +89 -0
  8. data/spec/couchy_spec.rb +71 -0
  9. data/spec/database_spec.rb +417 -0
  10. data/spec/fixtures/attachments/test.html +11 -0
  11. data/spec/fixtures/views/lib.js +3 -0
  12. data/spec/fixtures/views/test_view/lib.js +3 -0
  13. data/spec/fixtures/views/test_view/only-map.js +4 -0
  14. data/spec/fixtures/views/test_view/test-map.js +3 -0
  15. data/spec/fixtures/views/test_view/test-reduce.js +3 -0
  16. data/spec/spec.opts +6 -0
  17. data/spec/spec_helper.rb +5 -0
  18. data/test/couchy_test.rb +13 -0
  19. data/test/database_test.rb +193 -0
  20. data/test/server_test.rb +211 -0
  21. data/test/test_helper.rb +10 -0
  22. data/vendor/addressable/.gitignore +7 -0
  23. data/vendor/addressable/CHANGELOG +51 -0
  24. data/vendor/addressable/LICENSE +20 -0
  25. data/vendor/addressable/README +24 -0
  26. data/vendor/addressable/Rakefile +51 -0
  27. data/vendor/addressable/lib/addressable/idna.rb +4867 -0
  28. data/vendor/addressable/lib/addressable/uri.rb +2212 -0
  29. data/vendor/addressable/lib/addressable/version.rb +35 -0
  30. data/vendor/addressable/spec/addressable/idna_spec.rb +196 -0
  31. data/vendor/addressable/spec/addressable/uri_spec.rb +3827 -0
  32. data/vendor/addressable/spec/data/rfc3986.txt +3419 -0
  33. data/vendor/addressable/tasks/clobber.rake +2 -0
  34. data/vendor/addressable/tasks/gem.rake +62 -0
  35. data/vendor/addressable/tasks/git.rake +40 -0
  36. data/vendor/addressable/tasks/metrics.rake +22 -0
  37. data/vendor/addressable/tasks/rdoc.rake +29 -0
  38. data/vendor/addressable/tasks/rubyforge.rake +89 -0
  39. data/vendor/addressable/tasks/spec.rake +107 -0
  40. data/vendor/addressable/website/index.html +107 -0
  41. metadata +113 -0
@@ -0,0 +1,11 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Test</title>
5
+ </head>
6
+ <body>
7
+ <p>
8
+ Test
9
+ </p>
10
+ </body>
11
+ </html>
@@ -0,0 +1,3 @@
1
+ function globalLib() {
2
+ return "fixture";
3
+ };
@@ -0,0 +1,3 @@
1
+ function justThisView() {
2
+ return "fixture";
3
+ };
@@ -0,0 +1,4 @@
1
+ function(doc) {
2
+ //include-lib
3
+ emit(null, null);
4
+ };
@@ -0,0 +1,3 @@
1
+ function(doc) {
2
+ emit(null, null);
3
+ };
@@ -0,0 +1,3 @@
1
+ function(ks,vs,co) {
2
+ return vs.length;
3
+ };
@@ -0,0 +1,6 @@
1
+ --colour
2
+ --format
3
+ progress
4
+ --loadby
5
+ mtime
6
+ --reverse
@@ -0,0 +1,5 @@
1
+ require 'rubygems'
2
+ require 'spec'
3
+
4
+ CouchHost = "http://localhost:5984/"
5
+ TestDatabase = 'couchy-test'
@@ -0,0 +1,13 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ describe 'Couchy#new' do
4
+ it 'creates a new Server with the given server URI' do
5
+ Couchy::Server.expects(:new).with('uri')
6
+ Couchy.new('uri')
7
+ end
8
+
9
+ specify 'uri default to http://localhost:5984/' do
10
+ server = Couchy.new
11
+ server.uri.to_s.should.equal 'http://localhost:5984/'
12
+ end
13
+ end
@@ -0,0 +1,193 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ describe 'Database' do
4
+ before(:each) do
5
+ @server = stub('server', :get => '', :post => '', :put => '', :delete => '')
6
+ @database = Couchy::Database.new(@server, TestDatabase)
7
+ end
8
+
9
+ it 'has an accessor on its name' do
10
+ @database.name.should.equal TestDatabase
11
+ end
12
+
13
+ it 'has an accessor on the server instance' do
14
+ @database.server.should.equal @server
15
+ end
16
+
17
+ specify '#base64 removes new lines to workaround <https://issues.apache.org/jira/browse/COUCHDB-19>' do
18
+ @database.send(:base64, 'foo').should.equal 'Zm9v'
19
+ end
20
+
21
+ describe 'Encoding attachments of a document' do
22
+ setup do
23
+ Couchy::Database.class_eval { public :encode_attachments_of }
24
+ @server.stubs(:base64).returns('')
25
+ @database = Couchy::Database.new(@server, TestDatabase)
26
+ @attachments = { 'foo' => { 'type' => 'text/plain', 'data' => 'some text' },
27
+ 'bar' => { 'type' => 'text/plain', 'data' => 'same here' }}
28
+ @doc = {:foo => 'bar', '_attachments' => @attachments}
29
+ end
30
+
31
+ it 'returns the doc as is if there is no attachment' do
32
+ @database.encode_attachments_of(:foo => 'bar').should.equal(:foo => 'bar')
33
+ end
34
+
35
+ it 'encodes the data of each attachment in base64' do
36
+ @database.expects(:base64).with('some text').returns('')
37
+ @database.expects(:base64).with('same here').returns('')
38
+ @database.encode_attachments_of(@doc)
39
+ end
40
+
41
+ it 'returns the document with the attachments encoded' do
42
+ doc = @database.encode_attachments_of(@doc)
43
+ doc['_attachments']['foo']['data'].should.equal 'c29tZSB0ZXh0'
44
+ doc['_attachments']['bar']['data'].should.equal 'c2FtZSBoZXJl'
45
+ end
46
+ end
47
+
48
+ describe 'Deleting itselfs' do
49
+ it 'DELETE $database_name' do
50
+ @server.expects(:delete).with(TestDatabase)
51
+ @database.delete!
52
+ end
53
+ end
54
+
55
+ describe 'Getting a list of documents' do
56
+ it 'GET $database_name/_all_docs' do
57
+ @server.expects(:get).with(TestDatabase + '/_all_docs', {})
58
+ @database.documents
59
+ end
60
+
61
+ it 'uses given parameters' do
62
+ @server.expects(:get).with(TestDatabase + '/_all_docs', :startkey => 'somedoc', :count => 3)
63
+ @database.documents(:startkey => 'somedoc', :count => 3)
64
+ end
65
+ end
66
+
67
+ describe 'Getting a document' do
68
+ it 'GET $database_name/$document_id' do
69
+ @server.expects(:get).with("#{TestDatabase}/foobar")
70
+ @database.get('foobar')
71
+ end
72
+
73
+ it 'escapes the given document id' do
74
+ CGI.expects(:escape).with('foobar')
75
+ @database.get('foobar')
76
+ end
77
+ end
78
+
79
+ describe 'Saving a document' do
80
+ it 'encodes attachments of the given document' do
81
+ doc = {:foo => 'bar'}
82
+ @database.expects(:encode_attachments_of).with(doc).returns({})
83
+ @database.save(doc)
84
+ end
85
+
86
+ it 'POST the document to $database_name when no document id is specified' do
87
+ doc = {:foo => 'bar'}
88
+ @server.expects(:post).with(TestDatabase, doc)
89
+ @database.save(doc)
90
+ end
91
+
92
+ describe 'When a document id was specified' do
93
+ it 'PUT the document to $database_name/$document_id' do
94
+ doc = {'_id' => 'mydocid', 'foo' => 'bar'}
95
+ @server.expects(:put).with("#{TestDatabase}/#{doc['_id']}", doc)
96
+ @database.save(doc)
97
+ end
98
+
99
+ it 'escapes the given document id' do
100
+ CGI.expects(:escape).with('mydocid')
101
+ @database.save('_id' => 'mydocid')
102
+ end
103
+ end
104
+ end
105
+
106
+ describe 'Bulk saving a bunch of documents' do
107
+ it 'POST the documents to $database_name/_bulk_docs' do
108
+ @server.expects(:post).with("#{TestDatabase}/_bulk_docs", :docs => ['doc1', 'doc2'])
109
+ @database.bulk_save(['doc1', 'doc2'])
110
+ end
111
+ end
112
+
113
+ describe 'Fetching an attachment' do
114
+ it 'GET $database_name/$document_id/$attachment_id' do
115
+ @server.expects(:get).with("#{TestDatabase}/my-doc/foo", anything)
116
+ @database.fetch_attachment('my-doc', 'foo')
117
+ end
118
+
119
+ it 'escapes the document id and the attachement id' do
120
+ CGI.expects(:escape).with('my-doc')
121
+ CGI.expects(:escape).with('foo')
122
+ @database.fetch_attachment('my-doc', 'foo')
123
+ end
124
+ end
125
+
126
+ describe 'Deleting a document' do
127
+ describe 'When given the document id and the revision' do
128
+ it 'DELETE $database_name/$document_id?rev=$revision' do
129
+ @server.expects(:delete).with("#{TestDatabase}/mydocid", :rev => 2800624930)
130
+ @database.delete('mydocid', 2800624930)
131
+ end
132
+
133
+ it 'escapes the document id' do
134
+ CGI.expects(:escape).with('mydocid')
135
+ @database.delete('mydocid', 2800624930)
136
+ end
137
+ end
138
+
139
+ describe 'When given an Hash representing a document' do
140
+ it 'raises ArgumentError if the doc doesnt have an _id' do
141
+ lambda { @database.delete('foo' => 'bar') }.should.raise(ArgumentError)
142
+ end
143
+
144
+ it 'raises ArgumentError if the doc doesnt have a _rev' do
145
+ lambda { @database.delete('_id' => 'foo') }.should.raise(ArgumentError)
146
+ end
147
+
148
+ it 'DELETE $database_name/$document_id?rev=$revision' do
149
+ @server.expects(:delete).with("#{TestDatabase}/mydocid", :rev => 2800624930)
150
+ @database.delete('_id' => 'mydocid', '_rev' => 2800624930)
151
+ end
152
+
153
+ it 'escapes the document id' do
154
+ CGI.expects(:escape).with('mydocid')
155
+ @database.delete('_id' => 'mydocid', '_rev' => 286633)
156
+ end
157
+ end
158
+
159
+ it 'raises ArgumentError if the given argument is neither a document id nor a document' do
160
+ lambda { @database.delete(:fooo) }.should.raise(ArgumentError)
161
+ end
162
+ end
163
+
164
+ describe 'Creating a temporary view' do
165
+ it 'POST $database_name/_temp_view with the given fonction' do
166
+ @server.expects(:post).with(TestDatabase + '/_temp_view', 'js function', anything)
167
+ @database.temp_view('js function')
168
+ end
169
+
170
+ it "sets the request's Content-Type to application/json" do
171
+ @server.expects(:post).with(anything, anything,
172
+ has_entries(:headers => {'Content-Type' => 'application/json'}))
173
+ @database.temp_view('foo')
174
+ end
175
+
176
+ it 'uses the given parameters' do
177
+ @server.expects(:post).with(anything, 'foo', has_entries(:startkey => 'foo'))
178
+ @database.temp_view('foo', :startkey => 'foo')
179
+ end
180
+ end
181
+
182
+ describe 'Getting a view' do
183
+ it 'GET $database_name/_view/$view_name' do
184
+ @server.expects(:get).with("#{TestDatabase}/_view/my-view", {})
185
+ @database.view('my-view')
186
+ end
187
+
188
+ it 'uses the given parameters' do
189
+ @server.expects(:get).with(anything, :count => 100)
190
+ @database.view('my-view', :count => 100)
191
+ end
192
+ end
193
+ end
@@ -0,0 +1,211 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ describe 'Server' do
4
+ setup do
5
+ @server = Couchy::Server.new('http://localhost:5984/')
6
+ end
7
+
8
+ it 'has an accessor on its uri' do
9
+ server = Couchy::Server.new('foo')
10
+ server.uri.to_s.should.equal 'foo'
11
+ end
12
+
13
+ describe 'Various utility methods' do
14
+ setup do
15
+ Couchy::Server.class_eval { public :uri_for, :json, :stringify_keys_and_jsonify_values }
16
+ @server = Couchy::Server.new('http://foo.org/')
17
+ end
18
+
19
+ specify '#json parse the given json string with the given options' do
20
+ JSON.expects(:parse).with('foo', :bar => :spam)
21
+ @server.send(:json, 'foo', :bar => :spam)
22
+ end
23
+
24
+ describe '#uri_for' do
25
+ setup do
26
+ @uri = stub('server uri joined with given path', :query_values= => '')
27
+ @server.uri.stubs(:join).returns(@uri)
28
+ end
29
+
30
+ it 'joins the given path with the URI of the server' do
31
+ @server.uri.expects(:join).with('bar/spam')
32
+ @server.uri_for('bar/spam')
33
+ end
34
+
35
+ it 'stringifys keys and jsonifys values of the given parameters' do
36
+ @server.expects(:stringify_keys_and_jsonify_values).with(:is => 'awesome').returns({})
37
+ @server.uri_for('group/home', {:is => 'awesome'})
38
+ end
39
+
40
+ it 'sets the query to the given parameters' do
41
+ params = {:foo => 'bar'}
42
+ @uri.expects(:query_values=).with('stringified keys')
43
+ @server.stubs(:stringify_keys_and_jsonify_values).with(params).returns('stringified keys')
44
+ @server.uri_for('dj/premier', params)
45
+ end
46
+
47
+ it 'do not set the query if no parameters' do
48
+ @uri.expects(:query_values=).never
49
+ @server.uri_for('primo')
50
+ end
51
+
52
+ it 'returns the resulting URI as a string' do
53
+ @uri.expects(:to_s).returns('resulting uri as a string')
54
+ @server.uri_for('supa/star').should.equal 'resulting uri as a string'
55
+ end
56
+ end
57
+
58
+ describe '#stringify_keys_and_jsonify_values' do
59
+ it 'stringifys keys' do
60
+ @server.stringify_keys_and_jsonify_values(:foo => 'bar').should.equal('foo' => 'bar')
61
+ end
62
+
63
+ it 'jsonifys value if key is "key"' do
64
+ @server.stringify_keys_and_jsonify_values(:key => {'foo' => 'bar'}).should.
65
+ equal('key' => '{"foo":"bar"}')
66
+ end
67
+
68
+ it 'jsonifys value if key is "startkey"' do
69
+ @server.stringify_keys_and_jsonify_values(:startkey => {'foo' => 'bar'}).should.
70
+ equal('startkey' => '{"foo":"bar"}')
71
+ end
72
+
73
+ it 'jsonifys value if key is "endkey"' do
74
+ @server.stringify_keys_and_jsonify_values(:endkey => {'foo' => 'bar'}).should.
75
+ equal('endkey' => '{"foo":"bar"}')
76
+ end
77
+ end
78
+ end
79
+
80
+ describe 'HTTP requests utility methods' do
81
+ describe 'GET' do
82
+ it "appends the given path to the server's URI" do
83
+ @server.stubs(:json)
84
+ RestClient.expects(:get).with('http://localhost:5984/foo/bar')
85
+ @server.get('foo/bar')
86
+ end
87
+
88
+ it 'appends the given parameters as the query string' do
89
+ @server.stubs(:json)
90
+ RestClient.expects(:get).with('http://localhost:5984/foo?bar=spam')
91
+ @server.get('foo', :bar => 'spam')
92
+ end
93
+
94
+ it 'parses the server response as json with :max_nesting set to false' do
95
+ RestClient.stubs(:get).returns('some json')
96
+ @server.expects(:json).with('some json', :max_nesting => false).returns([])
97
+ @server.get('give_me_some_json')
98
+ end
99
+
100
+ it 'do not parse the result as json if :no_json is specified' do
101
+ RestClient.stubs(:get)
102
+ @server.expects(:json).never
103
+ @server.get('foo', :no_json => true)
104
+ end
105
+ end
106
+
107
+ describe 'POST' do
108
+ setup do
109
+ @server.stubs(:json)
110
+ end
111
+
112
+ it "appends the given path to server's URI" do
113
+ RestClient.expects(:post).with('http://localhost:5984/a/b', nil, anything)
114
+ @server.post('a/b')
115
+ end
116
+
117
+ it 'appends the given parameters as the query string' do
118
+ RestClient.expects(:post).with('http://localhost:5984/foo?bar=spam', nil, anything)
119
+ @server.post('foo', nil, :bar => 'spam')
120
+ end
121
+
122
+ it 'jsonify the given body and post it' do
123
+ body = {:foo => 'bar'}
124
+ body.expects(:to_json).returns('some json')
125
+ RestClient.expects(:post).with(anything, 'some json', anything)
126
+ @server.post('foo', body)
127
+ end
128
+
129
+ it 'passes given headers to RestClient' do
130
+ RestClient.expects(:post).with(anything, anything, {'Content-Type' => 'application/json'})
131
+ @server.post('foo', nil, :headers => {'Content-Type' => 'application/json'})
132
+ end
133
+ end
134
+
135
+ describe 'PUT' do
136
+ setup do
137
+ @server.stubs(:json)
138
+ end
139
+
140
+ it "appends the given path to the server's URI" do
141
+ RestClient.expects(:put).with('http://localhost:5984/a/b', anything)
142
+ @server.put('a/b')
143
+ end
144
+
145
+ it 'jsonify and PUT the given body' do
146
+ body = {:foo => 'bar'}
147
+ body.expects(:to_json).returns('some json')
148
+ RestClient.expects(:put).with(anything, 'some json')
149
+ @server.put('foo', body)
150
+ end
151
+ end
152
+
153
+ describe 'DELETE' do
154
+ it "appends the given path to the server's URI" do
155
+ @server.stubs(:json).returns('')
156
+ RestClient.expects(:delete).with('http://localhost:5984/a/b')
157
+ @server.delete('a/b')
158
+ end
159
+
160
+ it 'appends the given parameters as the query string' do
161
+ @server.stubs(:json)
162
+ RestClient.expects(:delete).with('http://localhost:5984/foo/bar?a=b')
163
+ @server.delete('foo/bar', :a => :b)
164
+ end
165
+ end
166
+ end
167
+
168
+ describe 'Getting a list of all the databases' do
169
+ it 'GET _all_dbs' do
170
+ @server.expects(:get).with('_all_dbs')
171
+ @server.databases
172
+ end
173
+ end
174
+
175
+ describe 'Getting a database' do
176
+ it 'creates a new Database object with the given name and itselfs' do
177
+ Couchy::Database.expects(:new).with(@server, 'mydb')
178
+ @server.database('mydb')
179
+ end
180
+
181
+ it 'returns a Database object' do
182
+ @server.database('mydb').should.be.an.instance_of Couchy::Database
183
+ end
184
+ end
185
+
186
+ describe 'Getting info on the server' do
187
+ it 'GET the server URI' do
188
+ @server.expects(:get).with('/')
189
+ @server.info
190
+ end
191
+ end
192
+
193
+ describe 'Restarting the server' do
194
+ it 'POST _restart' do
195
+ @server.expects(:post).with('_restart')
196
+ @server.restart!
197
+ end
198
+ end
199
+
200
+ describe 'Creating a new database' do
201
+ it 'PUT to database_name' do
202
+ @server.expects(:put).with('mydb')
203
+ @server.create_db('mydb')
204
+ end
205
+
206
+ it 'returns a Database object' do
207
+ @server.stubs(:put)
208
+ @server.create_db('mydb').should.be.an.instance_of Couchy::Database
209
+ end
210
+ end
211
+ end