samflores-couchrest 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +176 -0
- data/README.md +93 -0
- data/Rakefile +66 -0
- data/THANKS.md +18 -0
- data/examples/model/example.rb +144 -0
- data/examples/word_count/markov +38 -0
- data/examples/word_count/views/books/chunked-map.js +3 -0
- data/examples/word_count/views/books/united-map.js +1 -0
- data/examples/word_count/views/markov/chain-map.js +6 -0
- data/examples/word_count/views/markov/chain-reduce.js +7 -0
- data/examples/word_count/views/word_count/count-map.js +6 -0
- data/examples/word_count/views/word_count/count-reduce.js +3 -0
- data/examples/word_count/word_count.rb +46 -0
- data/examples/word_count/word_count_query.rb +40 -0
- data/examples/word_count/word_count_views.rb +26 -0
- data/lib/couchrest/commands/generate.rb +71 -0
- data/lib/couchrest/commands/push.rb +103 -0
- data/lib/couchrest/core/database.rb +316 -0
- data/lib/couchrest/core/design.rb +89 -0
- data/lib/couchrest/core/document.rb +96 -0
- data/lib/couchrest/core/response.rb +16 -0
- data/lib/couchrest/core/server.rb +88 -0
- data/lib/couchrest/core/view.rb +4 -0
- data/lib/couchrest/helper/pager.rb +103 -0
- data/lib/couchrest/helper/streamer.rb +44 -0
- data/lib/couchrest/mixins/attachments.rb +31 -0
- data/lib/couchrest/mixins/callbacks.rb +483 -0
- data/lib/couchrest/mixins/design_doc.rb +64 -0
- data/lib/couchrest/mixins/document_queries.rb +48 -0
- data/lib/couchrest/mixins/extended_attachments.rb +68 -0
- data/lib/couchrest/mixins/extended_document_mixins.rb +6 -0
- data/lib/couchrest/mixins/properties.rb +125 -0
- data/lib/couchrest/mixins/validation.rb +234 -0
- data/lib/couchrest/mixins/views.rb +168 -0
- data/lib/couchrest/mixins.rb +4 -0
- data/lib/couchrest/monkeypatches.rb +119 -0
- data/lib/couchrest/more/casted_model.rb +28 -0
- data/lib/couchrest/more/extended_document.rb +217 -0
- data/lib/couchrest/more/property.rb +40 -0
- data/lib/couchrest/support/blank.rb +42 -0
- data/lib/couchrest/support/class.rb +191 -0
- data/lib/couchrest/validation/auto_validate.rb +163 -0
- data/lib/couchrest/validation/contextual_validators.rb +78 -0
- data/lib/couchrest/validation/validation_errors.rb +118 -0
- data/lib/couchrest/validation/validators/absent_field_validator.rb +74 -0
- data/lib/couchrest/validation/validators/confirmation_validator.rb +99 -0
- data/lib/couchrest/validation/validators/format_validator.rb +117 -0
- data/lib/couchrest/validation/validators/formats/email.rb +66 -0
- data/lib/couchrest/validation/validators/formats/url.rb +43 -0
- data/lib/couchrest/validation/validators/generic_validator.rb +120 -0
- data/lib/couchrest/validation/validators/length_validator.rb +134 -0
- data/lib/couchrest/validation/validators/method_validator.rb +89 -0
- data/lib/couchrest/validation/validators/numeric_validator.rb +104 -0
- data/lib/couchrest/validation/validators/required_field_validator.rb +109 -0
- data/lib/couchrest.rb +189 -0
- data/spec/couchrest/core/couchrest_spec.rb +201 -0
- data/spec/couchrest/core/database_spec.rb +745 -0
- data/spec/couchrest/core/design_spec.rb +131 -0
- data/spec/couchrest/core/document_spec.rb +311 -0
- data/spec/couchrest/core/server_spec.rb +35 -0
- data/spec/couchrest/helpers/pager_spec.rb +122 -0
- data/spec/couchrest/helpers/streamer_spec.rb +23 -0
- data/spec/couchrest/more/casted_extended_doc_spec.rb +40 -0
- data/spec/couchrest/more/casted_model_spec.rb +98 -0
- data/spec/couchrest/more/extended_doc_attachment_spec.rb +130 -0
- data/spec/couchrest/more/extended_doc_spec.rb +509 -0
- data/spec/couchrest/more/extended_doc_view_spec.rb +207 -0
- data/spec/couchrest/more/property_spec.rb +130 -0
- data/spec/couchrest/support/class_spec.rb +59 -0
- data/spec/fixtures/attachments/README +3 -0
- data/spec/fixtures/attachments/couchdb.png +0 -0
- data/spec/fixtures/attachments/test.html +11 -0
- data/spec/fixtures/more/article.rb +34 -0
- data/spec/fixtures/more/card.rb +20 -0
- data/spec/fixtures/more/course.rb +14 -0
- data/spec/fixtures/more/event.rb +6 -0
- data/spec/fixtures/more/invoice.rb +17 -0
- data/spec/fixtures/more/person.rb +8 -0
- data/spec/fixtures/more/question.rb +6 -0
- data/spec/fixtures/more/service.rb +12 -0
- data/spec/fixtures/views/lib.js +3 -0
- data/spec/fixtures/views/test_view/lib.js +3 -0
- data/spec/fixtures/views/test_view/only-map.js +4 -0
- data/spec/fixtures/views/test_view/test-map.js +3 -0
- data/spec/fixtures/views/test_view/test-reduce.js +3 -0
- data/spec/spec.opts +6 -0
- data/spec/spec_helper.rb +26 -0
- data/utils/remap.rb +27 -0
- data/utils/subset.rb +30 -0
- metadata +219 -0
@@ -0,0 +1,98 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
|
2
|
+
require File.join(FIXTURE_PATH, 'more', 'card')
|
3
|
+
|
4
|
+
class WithCastedModelMixin < Hash
|
5
|
+
include CouchRest::CastedModel
|
6
|
+
property :name
|
7
|
+
end
|
8
|
+
|
9
|
+
class DummyModel < CouchRest::ExtendedDocument
|
10
|
+
use_database TEST_SERVER.default_database
|
11
|
+
raise "Default DB not set" if TEST_SERVER.default_database.nil?
|
12
|
+
property :casted_attribute, :cast_as => 'WithCastedModelMixin'
|
13
|
+
property :keywords, :cast_as => ["String"]
|
14
|
+
end
|
15
|
+
|
16
|
+
describe CouchRest::CastedModel do
|
17
|
+
|
18
|
+
describe "A non hash class including CastedModel" do
|
19
|
+
it "should fail raising and include error" do
|
20
|
+
lambda do
|
21
|
+
class NotAHashButWithCastedModelMixin
|
22
|
+
include CouchRest::CastedModel
|
23
|
+
property :name
|
24
|
+
end
|
25
|
+
|
26
|
+
end.should raise_error
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "isolated" do
|
31
|
+
before(:each) do
|
32
|
+
@obj = WithCastedModelMixin.new
|
33
|
+
end
|
34
|
+
it "should automatically include the property mixin and define getters and setters" do
|
35
|
+
@obj.name = 'Matt'
|
36
|
+
@obj.name.should == 'Matt'
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "casted as attribute" do
|
41
|
+
before(:each) do
|
42
|
+
@obj = DummyModel.new(:casted_attribute => {:name => 'whatever'})
|
43
|
+
@casted_obj = @obj.casted_attribute
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should be available from its parent" do
|
47
|
+
@casted_obj.should be_an_instance_of(WithCastedModelMixin)
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should have the getters defined" do
|
51
|
+
@casted_obj.name.should == 'whatever'
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should know who casted it" do
|
55
|
+
@casted_obj.casted_by.should == @obj
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "casted as an array of a different type" do
|
60
|
+
before(:each) do
|
61
|
+
@obj = DummyModel.new(:keywords => ['couch', 'sofa', 'relax', 'canapé'])
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should cast the array propery" do
|
65
|
+
@obj.keywords.should be_an_instance_of(Array)
|
66
|
+
@obj.keywords.first.should == 'couch'
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
describe "saved document with casted models" do
|
72
|
+
before(:each) do
|
73
|
+
reset_test_db!
|
74
|
+
@obj = DummyModel.new(:casted_attribute => {:name => 'whatever'})
|
75
|
+
@obj.save.should be_true
|
76
|
+
@obj = DummyModel.get(@obj.id)
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should be able to load with the casted models" do
|
80
|
+
casted_obj = @obj.casted_attribute
|
81
|
+
casted_obj.should_not be_nil
|
82
|
+
casted_obj.should be_an_instance_of(WithCastedModelMixin)
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should have defined getters for the casted model" do
|
86
|
+
casted_obj = @obj.casted_attribute
|
87
|
+
casted_obj.name.should == "whatever"
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should have defined setters for the casted model" do
|
91
|
+
casted_obj = @obj.casted_attribute
|
92
|
+
casted_obj.name = "test"
|
93
|
+
casted_obj.name.should == "test"
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper'
|
2
|
+
|
3
|
+
describe "ExtendedDocument attachments" do
|
4
|
+
|
5
|
+
describe "#has_attachment?" do
|
6
|
+
before(:each) do
|
7
|
+
reset_test_db!
|
8
|
+
@obj = Basic.new
|
9
|
+
@obj.save.should == true
|
10
|
+
@file = File.open(FIXTURE_PATH + '/attachments/test.html')
|
11
|
+
@attachment_name = 'my_attachment'
|
12
|
+
@obj.create_attachment(:file => @file, :name => @attachment_name)
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should return false if there is no attachment' do
|
16
|
+
@obj.has_attachment?('bogus').should be_false
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should return true if there is an attachment' do
|
20
|
+
@obj.has_attachment?(@attachment_name).should be_true
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should return true if an object with an attachment is reloaded' do
|
24
|
+
@obj.save.should be_true
|
25
|
+
reloaded_obj = Basic.get(@obj.id)
|
26
|
+
reloaded_obj.has_attachment?(@attachment_name).should be_true
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should return false if an attachment has been removed' do
|
30
|
+
@obj.delete_attachment(@attachment_name)
|
31
|
+
@obj.has_attachment?(@attachment_name).should be_false
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "creating an attachment" do
|
36
|
+
before(:each) do
|
37
|
+
@obj = Basic.new
|
38
|
+
@obj.save.should == true
|
39
|
+
@file_ext = File.open(FIXTURE_PATH + '/attachments/test.html')
|
40
|
+
@file_no_ext = File.open(FIXTURE_PATH + '/attachments/README')
|
41
|
+
@attachment_name = 'my_attachment'
|
42
|
+
@content_type = 'media/mp3'
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should create an attachment from file with an extension" do
|
46
|
+
@obj.create_attachment(:file => @file_ext, :name => @attachment_name)
|
47
|
+
@obj.save.should == true
|
48
|
+
reloaded_obj = Basic.get(@obj.id)
|
49
|
+
reloaded_obj['_attachments'][@attachment_name].should_not be_nil
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should create an attachment from file without an extension" do
|
53
|
+
@obj.create_attachment(:file => @file_no_ext, :name => @attachment_name)
|
54
|
+
@obj.save.should == true
|
55
|
+
reloaded_obj = Basic.get(@obj.id)
|
56
|
+
reloaded_obj['_attachments'][@attachment_name].should_not be_nil
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'should raise ArgumentError if :file is missing' do
|
60
|
+
lambda{ @obj.create_attachment(:name => @attachment_name) }.should raise_error
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'should raise ArgumentError if :name is missing' do
|
64
|
+
lambda{ @obj.create_attachment(:file => @file_ext) }.should raise_error
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'should set the content-type if passed' do
|
68
|
+
@obj.create_attachment(:file => @file_ext, :name => @attachment_name, :content_type => @content_type)
|
69
|
+
@obj['_attachments'][@attachment_name]['content-type'].should == @content_type
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe 'reading, updating, and deleting an attachment' do
|
74
|
+
before(:each) do
|
75
|
+
@obj = Basic.new
|
76
|
+
@file = File.open(FIXTURE_PATH + '/attachments/test.html')
|
77
|
+
@attachment_name = 'my_attachment'
|
78
|
+
@obj.create_attachment(:file => @file, :name => @attachment_name)
|
79
|
+
@obj.save.should == true
|
80
|
+
@file.rewind
|
81
|
+
@content_type = 'media/mp3'
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'should read an attachment that exists' do
|
85
|
+
@obj.read_attachment(@attachment_name).should == @file.read
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'should update an attachment that exists' do
|
89
|
+
file = File.open(FIXTURE_PATH + '/attachments/README')
|
90
|
+
@file.should_not == file
|
91
|
+
@obj.update_attachment(:file => file, :name => @attachment_name)
|
92
|
+
@obj.save
|
93
|
+
reloaded_obj = Basic.get(@obj.id)
|
94
|
+
file.rewind
|
95
|
+
reloaded_obj.read_attachment(@attachment_name).should_not == @file.read
|
96
|
+
reloaded_obj.read_attachment(@attachment_name).should == file.read
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'should se the content-type if passed' do
|
100
|
+
file = File.open(FIXTURE_PATH + '/attachments/README')
|
101
|
+
@file.should_not == file
|
102
|
+
@obj.update_attachment(:file => file, :name => @attachment_name, :content_type => @content_type)
|
103
|
+
@obj['_attachments'][@attachment_name]['content-type'].should == @content_type
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'should delete an attachment that exists' do
|
107
|
+
@obj.delete_attachment(@attachment_name)
|
108
|
+
@obj.save
|
109
|
+
lambda{Basic.get(@obj.id).read_attachment(@attachment_name)}.should raise_error
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
describe "#attachment_url" do
|
114
|
+
before(:each) do
|
115
|
+
@obj = Basic.new
|
116
|
+
@file = File.open(FIXTURE_PATH + '/attachments/test.html')
|
117
|
+
@attachment_name = 'my_attachment'
|
118
|
+
@obj.create_attachment(:file => @file, :name => @attachment_name)
|
119
|
+
@obj.save.should == true
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'should return nil if attachment does not exist' do
|
123
|
+
@obj.attachment_url('bogus').should be_nil
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'should return the attachment URL as specified by CouchDB HttpDocumentApi' do
|
127
|
+
@obj.attachment_url(@attachment_name).should == "#{Basic.database}/#{@obj.id}/#{@attachment_name}"
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|