glasner-couchrest 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. data/LICENSE +176 -0
  2. data/README.md +93 -0
  3. data/Rakefile +66 -0
  4. data/THANKS.md +18 -0
  5. data/examples/model/example.rb +144 -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/lib/couchrest.rb +189 -0
  17. data/lib/couchrest/commands/generate.rb +71 -0
  18. data/lib/couchrest/commands/push.rb +103 -0
  19. data/lib/couchrest/core/database.rb +313 -0
  20. data/lib/couchrest/core/design.rb +89 -0
  21. data/lib/couchrest/core/document.rb +96 -0
  22. data/lib/couchrest/core/response.rb +16 -0
  23. data/lib/couchrest/core/server.rb +88 -0
  24. data/lib/couchrest/core/view.rb +4 -0
  25. data/lib/couchrest/helper/pager.rb +103 -0
  26. data/lib/couchrest/helper/streamer.rb +44 -0
  27. data/lib/couchrest/mixins.rb +4 -0
  28. data/lib/couchrest/mixins/attachments.rb +31 -0
  29. data/lib/couchrest/mixins/callbacks.rb +483 -0
  30. data/lib/couchrest/mixins/design_doc.rb +64 -0
  31. data/lib/couchrest/mixins/document_queries.rb +48 -0
  32. data/lib/couchrest/mixins/extended_attachments.rb +68 -0
  33. data/lib/couchrest/mixins/extended_document_mixins.rb +6 -0
  34. data/lib/couchrest/mixins/properties.rb +125 -0
  35. data/lib/couchrest/mixins/validation.rb +234 -0
  36. data/lib/couchrest/mixins/views.rb +168 -0
  37. data/lib/couchrest/monkeypatches.rb +119 -0
  38. data/lib/couchrest/more/casted_model.rb +28 -0
  39. data/lib/couchrest/more/extended_document.rb +217 -0
  40. data/lib/couchrest/more/property.rb +40 -0
  41. data/lib/couchrest/support/blank.rb +42 -0
  42. data/lib/couchrest/support/class.rb +191 -0
  43. data/lib/couchrest/validation/auto_validate.rb +163 -0
  44. data/lib/couchrest/validation/contextual_validators.rb +78 -0
  45. data/lib/couchrest/validation/validation_errors.rb +118 -0
  46. data/lib/couchrest/validation/validators/absent_field_validator.rb +74 -0
  47. data/lib/couchrest/validation/validators/confirmation_validator.rb +99 -0
  48. data/lib/couchrest/validation/validators/format_validator.rb +117 -0
  49. data/lib/couchrest/validation/validators/formats/email.rb +66 -0
  50. data/lib/couchrest/validation/validators/formats/url.rb +43 -0
  51. data/lib/couchrest/validation/validators/generic_validator.rb +120 -0
  52. data/lib/couchrest/validation/validators/length_validator.rb +134 -0
  53. data/lib/couchrest/validation/validators/method_validator.rb +89 -0
  54. data/lib/couchrest/validation/validators/numeric_validator.rb +104 -0
  55. data/lib/couchrest/validation/validators/required_field_validator.rb +109 -0
  56. data/spec/couchrest/core/couchrest_spec.rb +201 -0
  57. data/spec/couchrest/core/database_spec.rb +745 -0
  58. data/spec/couchrest/core/design_spec.rb +131 -0
  59. data/spec/couchrest/core/document_spec.rb +311 -0
  60. data/spec/couchrest/core/server_spec.rb +35 -0
  61. data/spec/couchrest/helpers/pager_spec.rb +122 -0
  62. data/spec/couchrest/helpers/streamer_spec.rb +23 -0
  63. data/spec/couchrest/more/casted_extended_doc_spec.rb +40 -0
  64. data/spec/couchrest/more/casted_model_spec.rb +98 -0
  65. data/spec/couchrest/more/extended_doc_attachment_spec.rb +130 -0
  66. data/spec/couchrest/more/extended_doc_spec.rb +509 -0
  67. data/spec/couchrest/more/extended_doc_view_spec.rb +207 -0
  68. data/spec/couchrest/more/property_spec.rb +130 -0
  69. data/spec/couchrest/support/class_spec.rb +59 -0
  70. data/spec/fixtures/attachments/README +3 -0
  71. data/spec/fixtures/attachments/couchdb.png +0 -0
  72. data/spec/fixtures/attachments/test.html +11 -0
  73. data/spec/fixtures/more/article.rb +34 -0
  74. data/spec/fixtures/more/card.rb +20 -0
  75. data/spec/fixtures/more/course.rb +14 -0
  76. data/spec/fixtures/more/event.rb +6 -0
  77. data/spec/fixtures/more/invoice.rb +17 -0
  78. data/spec/fixtures/more/person.rb +8 -0
  79. data/spec/fixtures/more/question.rb +6 -0
  80. data/spec/fixtures/more/service.rb +12 -0
  81. data/spec/fixtures/views/lib.js +3 -0
  82. data/spec/fixtures/views/test_view/lib.js +3 -0
  83. data/spec/fixtures/views/test_view/only-map.js +4 -0
  84. data/spec/fixtures/views/test_view/test-map.js +3 -0
  85. data/spec/fixtures/views/test_view/test-reduce.js +3 -0
  86. data/spec/spec.opts +6 -0
  87. data/spec/spec_helper.rb +26 -0
  88. data/utils/remap.rb +27 -0
  89. data/utils/subset.rb +30 -0
  90. metadata +219 -0
@@ -0,0 +1,131 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe CouchRest::Design do
4
+
5
+ describe "defining a view" do
6
+ it "should add a view to the design doc" do
7
+ @des = CouchRest::Design.new
8
+ method = @des.view_by :name
9
+ method.should == "by_name"
10
+ @des["views"]["by_name"].should_not be_nil
11
+ end
12
+ end
13
+
14
+ describe "with an unsaved view" do
15
+ before(:each) do
16
+ @des = CouchRest::Design.new
17
+ method = @des.view_by :name
18
+ end
19
+ it "should accept a name" do
20
+ @des.name = "mytest"
21
+ @des.name.should == "mytest"
22
+ end
23
+ it "should not save on view definition" do
24
+ @des.rev.should be_nil
25
+ end
26
+ it "should freak out on view access" do
27
+ lambda{@des.view :by_name}.should raise_error
28
+ end
29
+ end
30
+
31
+ describe "saving" do
32
+ before(:each) do
33
+ @des = CouchRest::Design.new
34
+ method = @des.view_by :name
35
+ @des.database = reset_test_db!
36
+ end
37
+ it "should fail without a name" do
38
+ lambda{@des.save}.should raise_error(ArgumentError)
39
+ end
40
+ it "should work with a name" do
41
+ @des.name = "myview"
42
+ @des.save
43
+ end
44
+ end
45
+
46
+ describe "when it's saved" do
47
+ before(:each) do
48
+ @db = reset_test_db!
49
+ @db.bulk_save([{"name" => "x"},{"name" => "y"}])
50
+ @des = CouchRest::Design.new
51
+ @des.database = @db
52
+ method = @des.view_by :name
53
+ end
54
+ it "should by queryable when it's saved" do
55
+ @des.name = "mydesign"
56
+ @des.save
57
+ res = @des.view :by_name
58
+ res["rows"][0]["key"].should == "x"
59
+ end
60
+ end
61
+
62
+ describe "from a saved document" do
63
+ before(:each) do
64
+ @db = reset_test_db!
65
+ @db.save_doc({
66
+ "_id" => "_design/test",
67
+ "views" => {
68
+ "by_name" => {
69
+ "map" => "function(doc){if (doc.name) emit(doc.name, null)}"
70
+ }
71
+ }
72
+ })
73
+ @db.bulk_save([{"name" => "a"},{"name" => "b"}])
74
+ @des = @db.get "_design/test"
75
+ end
76
+ it "should be a Design" do
77
+ @des.should be_an_instance_of(CouchRest::Design)
78
+ end
79
+ it "should have a modifiable name" do
80
+ @des.name.should == "test"
81
+ @des.name = "supertest"
82
+ @des.id.should == "_design/supertest"
83
+ end
84
+ it "should by queryable" do
85
+ res = @des.view :by_name
86
+ res["rows"][0]["key"].should == "a"
87
+ end
88
+ end
89
+
90
+ describe "a view with default options" do
91
+ before(:all) do
92
+ @db = reset_test_db!
93
+ @des = CouchRest::Design.new
94
+ @des.name = "test"
95
+ method = @des.view_by :name, :descending => true
96
+ @des.database = @db
97
+ @des.save
98
+ @db.bulk_save([{"name" => "a"},{"name" => "z"}])
99
+ end
100
+ it "should save them" do
101
+ @d2 = @db.get(@des.id)
102
+ @d2["views"]["by_name"]["couchrest-defaults"].should == {"descending"=>true}
103
+ end
104
+ it "should use them" do
105
+ res = @des.view :by_name
106
+ res["rows"].first["key"].should == "z"
107
+ end
108
+ it "should override them" do
109
+ res = @des.view :by_name, :descending => false
110
+ res["rows"].first["key"].should == "a"
111
+ end
112
+ end
113
+
114
+ describe "a view with multiple keys" do
115
+ before(:all) do
116
+ @db = reset_test_db!
117
+ @des = CouchRest::Design.new
118
+ @des.name = "test"
119
+ method = @des.view_by :name, :age
120
+ @des.database = @db
121
+ @des.save
122
+ @db.bulk_save([{"name" => "a", "age" => 2},
123
+ {"name" => "a", "age" => 4},{"name" => "z", "age" => 9}])
124
+ end
125
+ it "should work" do
126
+ res = @des.view :by_name_and_age
127
+ res["rows"].first["key"].should == ["a",2]
128
+ end
129
+ end
130
+
131
+ end
@@ -0,0 +1,311 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ class Video < CouchRest::Document; end
4
+
5
+ describe CouchRest::Document do
6
+
7
+ before(:all) do
8
+ @couch = CouchRest.new
9
+ @db = @couch.database!(TESTDB)
10
+ end
11
+
12
+ describe "[]=" do
13
+ before(:each) do
14
+ @doc = CouchRest::Document.new
15
+ end
16
+ it "should work" do
17
+ @doc["enamel"].should == nil
18
+ @doc["enamel"] = "Strong"
19
+ @doc["enamel"].should == "Strong"
20
+ end
21
+ it "[]= should convert to string" do
22
+ @doc["enamel"].should == nil
23
+ @doc[:enamel] = "Strong"
24
+ @doc["enamel"].should == "Strong"
25
+ end
26
+ it "should read as a string" do
27
+ @doc[:enamel] = "Strong"
28
+ @doc[:enamel].should == "Strong"
29
+ end
30
+ end
31
+
32
+ describe "default database" do
33
+ before(:each) do
34
+ Video.use_database nil
35
+ end
36
+ it "should be set using use_database on the model" do
37
+ Video.new.database.should be_nil
38
+ Video.use_database @db
39
+ Video.new.database.should == @db
40
+ Video.use_database nil
41
+ end
42
+
43
+ it "should be overwritten by instance" do
44
+ db = @couch.database('test')
45
+ article = Video.new
46
+ article.database.should be_nil
47
+ article.database = db
48
+ article.database.should_not be_nil
49
+ article.database.should == db
50
+ end
51
+ end
52
+
53
+ describe "new" do
54
+ before(:each) do
55
+ @doc = CouchRest::Document.new("key" => [1,2,3], :more => "values")
56
+ end
57
+ it "should create itself from a Hash" do
58
+ @doc["key"].should == [1,2,3]
59
+ @doc["more"].should == "values"
60
+ end
61
+ it "should not have rev and id" do
62
+ @doc.rev.should be_nil
63
+ @doc.id.should be_nil
64
+ end
65
+
66
+ it "should freak out when saving without a database" do
67
+ lambda{@doc.save}.should raise_error(ArgumentError)
68
+ end
69
+
70
+ end
71
+
72
+ # move to database spec
73
+ describe "saving using a database" do
74
+ before(:all) do
75
+ @doc = CouchRest::Document.new("key" => [1,2,3], :more => "values")
76
+ @db = reset_test_db!
77
+ @resp = @db.save_doc(@doc)
78
+ end
79
+ it "should apply the database" do
80
+ @doc.database.should == @db
81
+ end
82
+ it "should get id and rev" do
83
+ @doc.id.should == @resp["id"]
84
+ @doc.rev.should == @resp["rev"]
85
+ end
86
+ end
87
+
88
+ describe "bulk saving" do
89
+ before :all do
90
+ @db = reset_test_db!
91
+ end
92
+
93
+ it "should use the document bulk save cache" do
94
+ doc = CouchRest::Document.new({"_id" => "bulkdoc", "val" => 3})
95
+ doc.database = @db
96
+ doc.save(true)
97
+ lambda { doc.database.get(doc["_id"]) }.should raise_error(RestClient::ResourceNotFound)
98
+ doc.database.bulk_save
99
+ doc.database.get(doc["_id"])["val"].should == doc["val"]
100
+ end
101
+ end
102
+
103
+ describe "getting from a database" do
104
+ before(:all) do
105
+ @db = reset_test_db!
106
+ @resp = @db.save_doc({
107
+ "key" => "value"
108
+ })
109
+ @doc = @db.get @resp['id']
110
+ end
111
+ it "should return a document" do
112
+ @doc.should be_an_instance_of(CouchRest::Document)
113
+ end
114
+ it "should have a database" do
115
+ @doc.database.should == @db
116
+ end
117
+ it "should be saveable and resavable" do
118
+ @doc["more"] = "keys"
119
+ @doc.save
120
+ @db.get(@resp['id'])["more"].should == "keys"
121
+ @doc["more"] = "these keys"
122
+ @doc.save
123
+ @db.get(@resp['id'])["more"].should == "these keys"
124
+ end
125
+ end
126
+
127
+ describe "destroying a document from a db" do
128
+ before(:all) do
129
+ @db = reset_test_db!
130
+ @resp = @db.save_doc({
131
+ "key" => "value"
132
+ })
133
+ @doc = @db.get @resp['id']
134
+ end
135
+ it "should make it disappear" do
136
+ @doc.destroy
137
+ lambda{@db.get @resp['id']}.should raise_error
138
+ end
139
+ it "should error when there's no db" do
140
+ @doc = CouchRest::Document.new("key" => [1,2,3], :more => "values")
141
+ lambda{@doc.destroy}.should raise_error(ArgumentError)
142
+ end
143
+ end
144
+
145
+
146
+ describe "destroying a document from a db using bulk save" do
147
+ before(:all) do
148
+ @db = reset_test_db!
149
+ @resp = @db.save_doc({
150
+ "key" => "value"
151
+ })
152
+ @doc = @db.get @resp['id']
153
+ end
154
+ it "should defer actual deletion" do
155
+ @doc.destroy(true)
156
+ @doc['_id'].should == nil
157
+ @doc['_rev'].should == nil
158
+ lambda{@db.get @resp['id']}.should_not raise_error
159
+ @db.bulk_save
160
+ lambda{@db.get @resp['id']}.should raise_error
161
+ end
162
+ end
163
+
164
+ describe "copying a document" do
165
+ before :each do
166
+ @db = reset_test_db!
167
+ @resp = @db.save_doc({'key' => 'value'})
168
+ @docid = 'new-location'
169
+ @doc = @db.get(@resp['id'])
170
+ end
171
+ describe "to a new location" do
172
+ it "should work" do
173
+ @doc.copy @docid
174
+ newdoc = @db.get(@docid)
175
+ newdoc['key'].should == 'value'
176
+ end
177
+ it "should fail without a database" do
178
+ lambda{CouchRest::Document.new({"not"=>"a real doc"}).copy}.should raise_error(ArgumentError)
179
+ end
180
+ end
181
+ describe "to an existing location" do
182
+ before :each do
183
+ @db.save_doc({'_id' => @docid, 'will-exist' => 'here'})
184
+ end
185
+ it "should fail without a rev" do
186
+ lambda{@doc.copy @docid}.should raise_error(RestClient::RequestFailed)
187
+ end
188
+ it "should succeed with a rev" do
189
+ @to_be_overwritten = @db.get(@docid)
190
+ @doc.copy "#{@docid}?rev=#{@to_be_overwritten['_rev']}"
191
+ newdoc = @db.get(@docid)
192
+ newdoc['key'].should == 'value'
193
+ end
194
+ it "should succeed given the doc to overwrite" do
195
+ @to_be_overwritten = @db.get(@docid)
196
+ @doc.copy @to_be_overwritten
197
+ newdoc = @db.get(@docid)
198
+ newdoc['key'].should == 'value'
199
+ end
200
+ end
201
+ end
202
+
203
+ describe "MOVE existing document" do
204
+ before :each do
205
+ @db = reset_test_db!
206
+ @resp = @db.save_doc({'key' => 'value'})
207
+ @docid = 'new-location'
208
+ @doc = @db.get(@resp['id'])
209
+ end
210
+ describe "to a new location" do
211
+ it "should work" do
212
+ @doc.move @docid
213
+ newdoc = @db.get(@docid)
214
+ newdoc['key'].should == 'value'
215
+ lambda {@db.get(@resp['id'])}.should raise_error(RestClient::ResourceNotFound)
216
+ end
217
+ it "should fail without a database" do
218
+ lambda{CouchRest::Document.new({"not"=>"a real doc"}).move}.should raise_error(ArgumentError)
219
+ lambda{CouchRest::Document.new({"_id"=>"not a real doc"}).move}.should raise_error(ArgumentError)
220
+ end
221
+ end
222
+ describe "to an existing location" do
223
+ before :each do
224
+ @db.save_doc({'_id' => @docid, 'will-exist' => 'here'})
225
+ end
226
+ it "should fail without a rev" do
227
+ lambda{@doc.move @docid}.should raise_error(RestClient::RequestFailed)
228
+ lambda{@db.get(@resp['id'])}.should_not raise_error
229
+ end
230
+ it "should succeed with a rev" do
231
+ @to_be_overwritten = @db.get(@docid)
232
+ @doc.move "#{@docid}?rev=#{@to_be_overwritten['_rev']}"
233
+ newdoc = @db.get(@docid)
234
+ newdoc['key'].should == 'value'
235
+ lambda {@db.get(@resp['id'])}.should raise_error(RestClient::ResourceNotFound)
236
+ end
237
+ it "should succeed given the doc to overwrite" do
238
+ @to_be_overwritten = @db.get(@docid)
239
+ @doc.move @to_be_overwritten
240
+ newdoc = @db.get(@docid)
241
+ newdoc['key'].should == 'value'
242
+ lambda {@db.get(@resp['id'])}.should raise_error(RestClient::ResourceNotFound)
243
+ end
244
+ end
245
+ end
246
+ end
247
+
248
+ describe "dealing with attachments" do
249
+ before do
250
+ @db = reset_test_db!
251
+ @attach = "<html><head><title>My Doc</title></head><body><p>Has words.</p></body></html>"
252
+ response = @db.save_doc({'key' => 'value'})
253
+ @doc = @db.get(response['id'])
254
+ end
255
+
256
+ def append_attachment(name='test.html', attach=@attach)
257
+ @doc['_attachments'] ||= {}
258
+ @doc['_attachments'][name] = {
259
+ 'type' => 'text/html',
260
+ 'data' => attach
261
+ }
262
+ @doc.save
263
+ @rev = @doc['_rev']
264
+ end
265
+
266
+ describe "PUTing an attachment directly to the doc" do
267
+ before do
268
+ @doc.put_attachment('test.html', @attach)
269
+ end
270
+
271
+ it "is there" do
272
+ @db.fetch_attachment(@doc, 'test.html').should == @attach
273
+ end
274
+
275
+ it "updates the revision" do
276
+ @doc['_rev'].should_not == @rev
277
+ end
278
+
279
+ it "updates attachments" do
280
+ @attach2 = "<html><head><title>My Doc</title></head><body><p>Is Different.</p></body></html>"
281
+ @doc.put_attachment('test.html', @attach2)
282
+ @db.fetch_attachment(@doc, 'test.html').should == @attach2
283
+ end
284
+ end
285
+
286
+ describe "fetching an attachment from a doc directly" do
287
+ before do
288
+ append_attachment
289
+ end
290
+
291
+ it "pulls the attachment" do
292
+ @doc.fetch_attachment('test.html').should == @attach
293
+ end
294
+ end
295
+
296
+ describe "deleting an attachment from a doc directly" do
297
+ before do
298
+ append_attachment
299
+ @doc.delete_attachment('test.html')
300
+ end
301
+
302
+ it "removes it" do
303
+ lambda { @db.fetch_attachment(@doc, 'test.html').should }.should raise_error(RestClient::ResourceNotFound)
304
+ end
305
+
306
+ it "updates the revision" do
307
+ @doc['_rev'].should_not == @rev
308
+ end
309
+ end
310
+
311
+ end
@@ -0,0 +1,35 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe CouchRest::Server do
4
+
5
+ describe "available databases" do
6
+ before(:each) do
7
+ @couch = CouchRest::Server.new
8
+ end
9
+
10
+ after(:each) do
11
+ @couch.available_databases.each do |ref, db|
12
+ db.delete!
13
+ end
14
+ end
15
+
16
+ it "should let you add more databases" do
17
+ @couch.available_databases.should be_empty
18
+ @couch.define_available_database(:default, "cr-server-test-db")
19
+ @couch.available_databases.keys.should include(:default)
20
+ end
21
+
22
+ it "should verify that a database is available" do
23
+ @couch.define_available_database(:default, "cr-server-test-db")
24
+ @couch.available_database?(:default).should be_true
25
+ @couch.available_database?("cr-server-test-db").should be_true
26
+ @couch.available_database?(:matt).should be_false
27
+ end
28
+
29
+ it "should let you set a default database" do
30
+ @couch.default_database = 'cr-server-test-default-db'
31
+ @couch.available_database?(:default).should be_true
32
+ end
33
+ end
34
+
35
+ end