openlogic-couchrest_model 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.
- data/.gitignore +11 -0
- data/.rspec +4 -0
- data/Gemfile +4 -0
- data/LICENSE +176 -0
- data/README.md +137 -0
- data/Rakefile +38 -0
- data/THANKS.md +21 -0
- data/VERSION +1 -0
- data/benchmarks/dirty.rb +118 -0
- data/couchrest_model.gemspec +36 -0
- data/history.md +309 -0
- data/init.rb +1 -0
- data/lib/couchrest/model.rb +10 -0
- data/lib/couchrest/model/associations.rb +231 -0
- data/lib/couchrest/model/base.rb +129 -0
- data/lib/couchrest/model/callbacks.rb +28 -0
- data/lib/couchrest/model/casted_array.rb +83 -0
- data/lib/couchrest/model/casted_by.rb +33 -0
- data/lib/couchrest/model/casted_hash.rb +84 -0
- data/lib/couchrest/model/class_proxy.rb +135 -0
- data/lib/couchrest/model/collection.rb +273 -0
- data/lib/couchrest/model/configuration.rb +67 -0
- data/lib/couchrest/model/connection.rb +70 -0
- data/lib/couchrest/model/core_extensions/hash.rb +9 -0
- data/lib/couchrest/model/core_extensions/time_parsing.rb +66 -0
- data/lib/couchrest/model/design_doc.rb +128 -0
- data/lib/couchrest/model/designs.rb +91 -0
- data/lib/couchrest/model/designs/view.rb +513 -0
- data/lib/couchrest/model/dirty.rb +39 -0
- data/lib/couchrest/model/document_queries.rb +99 -0
- data/lib/couchrest/model/embeddable.rb +78 -0
- data/lib/couchrest/model/errors.rb +25 -0
- data/lib/couchrest/model/extended_attachments.rb +83 -0
- data/lib/couchrest/model/persistence.rb +178 -0
- data/lib/couchrest/model/properties.rb +228 -0
- data/lib/couchrest/model/property.rb +114 -0
- data/lib/couchrest/model/property_protection.rb +71 -0
- data/lib/couchrest/model/proxyable.rb +183 -0
- data/lib/couchrest/model/support/couchrest_database.rb +13 -0
- data/lib/couchrest/model/support/couchrest_design.rb +33 -0
- data/lib/couchrest/model/typecast.rb +154 -0
- data/lib/couchrest/model/validations.rb +80 -0
- data/lib/couchrest/model/validations/casted_model.rb +16 -0
- data/lib/couchrest/model/validations/locale/en.yml +5 -0
- data/lib/couchrest/model/validations/uniqueness.rb +69 -0
- data/lib/couchrest/model/views.rb +151 -0
- data/lib/couchrest/railtie.rb +24 -0
- data/lib/couchrest_model.rb +66 -0
- data/lib/rails/generators/couchrest_model.rb +16 -0
- data/lib/rails/generators/couchrest_model/config/config_generator.rb +18 -0
- data/lib/rails/generators/couchrest_model/config/templates/couchdb.yml +21 -0
- data/lib/rails/generators/couchrest_model/model/model_generator.rb +27 -0
- data/lib/rails/generators/couchrest_model/model/templates/model.rb +2 -0
- data/spec/.gitignore +1 -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/config/couchdb.yml +10 -0
- data/spec/fixtures/models/article.rb +36 -0
- data/spec/fixtures/models/base.rb +164 -0
- data/spec/fixtures/models/card.rb +19 -0
- data/spec/fixtures/models/cat.rb +23 -0
- data/spec/fixtures/models/client.rb +6 -0
- data/spec/fixtures/models/course.rb +27 -0
- data/spec/fixtures/models/event.rb +8 -0
- data/spec/fixtures/models/invoice.rb +14 -0
- data/spec/fixtures/models/key_chain.rb +5 -0
- data/spec/fixtures/models/membership.rb +4 -0
- data/spec/fixtures/models/person.rb +11 -0
- data/spec/fixtures/models/project.rb +6 -0
- data/spec/fixtures/models/question.rb +7 -0
- data/spec/fixtures/models/sale_entry.rb +9 -0
- data/spec/fixtures/models/sale_invoice.rb +14 -0
- data/spec/fixtures/models/service.rb +10 -0
- data/spec/fixtures/models/user.rb +22 -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/functional/validations_spec.rb +8 -0
- data/spec/spec_helper.rb +60 -0
- data/spec/unit/active_model_lint_spec.rb +30 -0
- data/spec/unit/assocations_spec.rb +242 -0
- data/spec/unit/attachment_spec.rb +176 -0
- data/spec/unit/base_spec.rb +537 -0
- data/spec/unit/casted_spec.rb +72 -0
- data/spec/unit/class_proxy_spec.rb +167 -0
- data/spec/unit/collection_spec.rb +86 -0
- data/spec/unit/configuration_spec.rb +77 -0
- data/spec/unit/connection_spec.rb +148 -0
- data/spec/unit/core_extensions/time_parsing.rb +77 -0
- data/spec/unit/design_doc_spec.rb +241 -0
- data/spec/unit/designs/view_spec.rb +831 -0
- data/spec/unit/designs_spec.rb +134 -0
- data/spec/unit/dirty_spec.rb +436 -0
- data/spec/unit/embeddable_spec.rb +498 -0
- data/spec/unit/inherited_spec.rb +33 -0
- data/spec/unit/persistence_spec.rb +481 -0
- data/spec/unit/property_protection_spec.rb +192 -0
- data/spec/unit/property_spec.rb +481 -0
- data/spec/unit/proxyable_spec.rb +376 -0
- data/spec/unit/subclass_spec.rb +85 -0
- data/spec/unit/typecast_spec.rb +521 -0
- data/spec/unit/validations_spec.rb +140 -0
- data/spec/unit/view_spec.rb +367 -0
- metadata +301 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
class Driver < CouchRest::Model::Base
|
|
4
|
+
use_database TEST_SERVER.default_database
|
|
5
|
+
# You have to add a casted_by accessor if you want to reach a casted extended doc parent
|
|
6
|
+
attr_accessor :casted_by
|
|
7
|
+
|
|
8
|
+
property :name
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
class Car < CouchRest::Model::Base
|
|
12
|
+
use_database TEST_SERVER.default_database
|
|
13
|
+
|
|
14
|
+
property :name
|
|
15
|
+
property :driver, Driver
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
describe "casting an extended document" do
|
|
19
|
+
|
|
20
|
+
before(:each) do
|
|
21
|
+
@driver = Driver.new(:name => 'Matt')
|
|
22
|
+
@car = Car.new(:name => 'Renault 306', :driver => @driver)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it "should retain all properties of the casted attribute" do
|
|
26
|
+
@car.driver.should == @driver
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "should let the casted document know who casted it" do
|
|
30
|
+
@car.driver.casted_by.should == @car
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
describe "assigning a value to casted attribute after initializing an object" do
|
|
35
|
+
|
|
36
|
+
before(:each) do
|
|
37
|
+
@car = Car.new(:name => 'Renault 306')
|
|
38
|
+
@driver = Driver.new(:name => 'Matt')
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "should not create an empty casted object" do
|
|
42
|
+
@car.driver.should be_nil
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it "should let you assign the value" do
|
|
46
|
+
@car.driver = @driver
|
|
47
|
+
@car.driver.name.should == 'Matt'
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it "should cast attribute" do
|
|
51
|
+
@car.driver = JSON.parse(@driver.to_json)
|
|
52
|
+
@car.driver.should be_instance_of(Driver)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
describe "casting a model from parsed JSON" do
|
|
58
|
+
|
|
59
|
+
before(:each) do
|
|
60
|
+
@driver = Driver.new(:name => 'Matt')
|
|
61
|
+
@car = Car.new(:name => 'Renault 306', :driver => @driver)
|
|
62
|
+
@new_car = Car.new(JSON.parse(@car.to_json))
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it "should cast casted attribute" do
|
|
66
|
+
@new_car.driver.should be_instance_of(Driver)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
it "should retain all properties of the casted attribute" do
|
|
70
|
+
@new_car.driver.should == @driver
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
class UnattachedDoc < CouchRest::Model::Base
|
|
4
|
+
# Note: no use_database here
|
|
5
|
+
property :title
|
|
6
|
+
property :questions
|
|
7
|
+
property :professor
|
|
8
|
+
view_by :title
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
describe "Proxy Class" do
|
|
13
|
+
|
|
14
|
+
before(:all) do
|
|
15
|
+
reset_test_db!
|
|
16
|
+
# setup the class default doc to save the design doc
|
|
17
|
+
UnattachedDoc.use_database nil # just to be sure it is really unattached
|
|
18
|
+
@us = UnattachedDoc.on(DB)
|
|
19
|
+
%w{aaa bbb ddd eee}.each do |title|
|
|
20
|
+
u = @us.new(:title => title)
|
|
21
|
+
u.save
|
|
22
|
+
@first_id ||= u.id
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it "should query all" do
|
|
27
|
+
rs = @us.all
|
|
28
|
+
rs.length.should == 4
|
|
29
|
+
end
|
|
30
|
+
it "should count" do
|
|
31
|
+
@us.count.should == 4
|
|
32
|
+
end
|
|
33
|
+
it "should make the design doc upon first query" do
|
|
34
|
+
@us.by_title
|
|
35
|
+
doc = @us.design_doc
|
|
36
|
+
doc['views']['all']['map'].should include('UnattachedDoc')
|
|
37
|
+
end
|
|
38
|
+
it "should merge query params" do
|
|
39
|
+
rs = @us.by_title :startkey=>"bbb", :endkey=>"eee"
|
|
40
|
+
rs.length.should == 3
|
|
41
|
+
end
|
|
42
|
+
it "should query via view" do
|
|
43
|
+
view = @us.view :by_title
|
|
44
|
+
designed = @us.by_title
|
|
45
|
+
view.should == designed
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it "should query via first_from_view" do
|
|
49
|
+
UnattachedDoc.should_receive(:first_from_view).with('by_title', 'bbb', {:database => DB})
|
|
50
|
+
@us.first_from_view('by_title', 'bbb')
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
it "should query via first_from_view with complex options" do
|
|
54
|
+
UnattachedDoc.should_receive(:first_from_view).with('by_title', {:key => 'bbb', :database => DB})
|
|
55
|
+
@us.first_from_view('by_title', :key => 'bbb')
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it "should query via first_from_view with complex extra options" do
|
|
59
|
+
UnattachedDoc.should_receive(:first_from_view).with('by_title', 'bbb', {:limit => 1, :database => DB})
|
|
60
|
+
@us.first_from_view('by_title', 'bbb', :limit => 1)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it "should allow dynamic view matching for single elements" do
|
|
64
|
+
@us.should_receive(:first_from_view).with('by_title', 'bbb')
|
|
65
|
+
@us.find_by_title('bbb')
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it "should yield" do
|
|
69
|
+
things = []
|
|
70
|
+
@us.view(:by_title) do |thing|
|
|
71
|
+
things << thing
|
|
72
|
+
end
|
|
73
|
+
things[0]["doc"]["title"].should =='aaa'
|
|
74
|
+
end
|
|
75
|
+
it "should yield with by_key method" do
|
|
76
|
+
things = []
|
|
77
|
+
@us.by_title do |thing|
|
|
78
|
+
things << thing
|
|
79
|
+
end
|
|
80
|
+
things[0]["doc"]["title"].should =='aaa'
|
|
81
|
+
end
|
|
82
|
+
it "should get from specific database" do
|
|
83
|
+
u = @us.get(@first_id)
|
|
84
|
+
u.title.should == "aaa"
|
|
85
|
+
end
|
|
86
|
+
it "should get first" do
|
|
87
|
+
u = @us.first
|
|
88
|
+
u.should == @us.all.first
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
it "should get last" do
|
|
92
|
+
u = @us.last
|
|
93
|
+
u.should == @us.all.last
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
it "should set database on first retreived document" do
|
|
97
|
+
u = @us.first
|
|
98
|
+
u.database.should === DB
|
|
99
|
+
end
|
|
100
|
+
it "should set database on all retreived documents" do
|
|
101
|
+
@us.all.each do |u|
|
|
102
|
+
u.database.should === DB
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
it "should set database on each retreived document" do
|
|
106
|
+
rs = @us.by_title :startkey=>"bbb", :endkey=>"eee"
|
|
107
|
+
rs.length.should == 3
|
|
108
|
+
rs.each do |u|
|
|
109
|
+
u.database.should === DB
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
it "should set database on document retreived by id" do
|
|
113
|
+
u = @us.get(@first_id)
|
|
114
|
+
u.database.should === DB
|
|
115
|
+
end
|
|
116
|
+
it "should not attempt to set database on raw results using :all" do
|
|
117
|
+
@us.all(:raw => true).each do |u|
|
|
118
|
+
u.respond_to?(:database).should be_false
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
it "should not attempt to set database on raw results using view" do
|
|
122
|
+
@us.by_title(:raw => true).each do |u|
|
|
123
|
+
u.respond_to?(:database).should be_false
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
describe "#get!" do
|
|
128
|
+
it "raises exception when passed a nil" do
|
|
129
|
+
expect { @us.get!(nil)}.to raise_error(CouchRest::Model::DocumentNotFound)
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
it "raises exception when passed an empty string " do
|
|
133
|
+
expect { @us.get!("")}.to raise_error(CouchRest::Model::DocumentNotFound)
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
it "raises exception when document with provided id does not exist" do
|
|
137
|
+
expect { @us.get!("thisisnotreallyadocumentid")}.to raise_error(CouchRest::Model::DocumentNotFound)
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
describe "#find!" do
|
|
142
|
+
it "raises exception when passed a nil" do
|
|
143
|
+
expect { @us.find!(nil)}.to raise_error(CouchRest::Model::DocumentNotFound)
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
it "raises exception when passed an empty string " do
|
|
147
|
+
expect { @us.find!("")}.to raise_error(CouchRest::Model::DocumentNotFound)
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
it "raises exception when document with provided id does not exist" do
|
|
151
|
+
expect { @us.find!("thisisnotreallyadocumentid")}.to raise_error(CouchRest::Model::DocumentNotFound)
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
# Sam Lown 2010-04-07
|
|
156
|
+
# Removed as unclear why this should happen as before my changes
|
|
157
|
+
# this happend by accident, not explicitly.
|
|
158
|
+
# If requested, this feature should be added as a specific method.
|
|
159
|
+
#
|
|
160
|
+
#it "should clean up design docs left around on specific database" do
|
|
161
|
+
# @us.by_title
|
|
162
|
+
# original_id = @us.model_design_doc['_rev']
|
|
163
|
+
# Unattached.view_by :professor
|
|
164
|
+
# @us.by_professor
|
|
165
|
+
# @us.model_design_doc['_rev'].should_not == original_id
|
|
166
|
+
#end
|
|
167
|
+
end
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe "Collections" do
|
|
4
|
+
|
|
5
|
+
before(:all) do
|
|
6
|
+
reset_test_db!
|
|
7
|
+
titles = ["very uniq one", "really interesting", "some fun",
|
|
8
|
+
"really awesome", "crazy bob", "this rocks", "super rad"]
|
|
9
|
+
titles.each_with_index do |title,i|
|
|
10
|
+
a = Article.new(:title => title, :date => Date.today)
|
|
11
|
+
a.save
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
titles = ["yesterday very uniq one", "yesterday really interesting", "yesterday some fun",
|
|
15
|
+
"yesterday really awesome", "yesterday crazy bob", "yesterday this rocks"]
|
|
16
|
+
titles.each_with_index do |title,i|
|
|
17
|
+
a = Article.new(:title => title, :date => Date.today - 1)
|
|
18
|
+
a.save
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
it "should return a proxy that looks like an array of 7 Article objects" do
|
|
22
|
+
articles = Article.collection_proxy_for('Article', 'by_date', :descending => true,
|
|
23
|
+
:key => Date.today, :include_docs => true)
|
|
24
|
+
articles.class.should == Array
|
|
25
|
+
articles.size.should == 7
|
|
26
|
+
end
|
|
27
|
+
it "should provide a class method for paginate" do
|
|
28
|
+
articles = Article.paginate(:design_doc => 'Article', :view_name => 'by_date',
|
|
29
|
+
:per_page => 3, :descending => true, :key => Date.today)
|
|
30
|
+
articles.size.should == 3
|
|
31
|
+
|
|
32
|
+
articles = Article.paginate(:design_doc => 'Article', :view_name => 'by_date',
|
|
33
|
+
:per_page => 3, :page => 2, :descending => true, :key => Date.today)
|
|
34
|
+
articles.size.should == 3
|
|
35
|
+
|
|
36
|
+
articles = Article.paginate(:design_doc => 'Article', :view_name => 'by_date',
|
|
37
|
+
:per_page => 3, :page => 3, :descending => true, :key => Date.today)
|
|
38
|
+
articles.size.should == 1
|
|
39
|
+
end
|
|
40
|
+
it "should provide a class method for paginated_each" do
|
|
41
|
+
options = { :design_doc => 'Article', :view_name => 'by_date',
|
|
42
|
+
:per_page => 3, :page => 1, :descending => true, :key => Date.today }
|
|
43
|
+
Article.paginated_each(options) do |a|
|
|
44
|
+
a.should_not be_nil
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
it "should provide a class method to get a collection for a view" do
|
|
48
|
+
articles = Article.find_all_article_details(:key => Date.today)
|
|
49
|
+
articles.class.should == Array
|
|
50
|
+
articles.size.should == 7
|
|
51
|
+
end
|
|
52
|
+
it "should get a subset of articles using paginate" do
|
|
53
|
+
articles = Article.collection_proxy_for('Article', 'by_date', :key => Date.today, :include_docs => true)
|
|
54
|
+
articles.paginate(:page => 1, :per_page => 3).size.should == 3
|
|
55
|
+
articles.paginate(:page => 2, :per_page => 3).size.should == 3
|
|
56
|
+
articles.paginate(:page => 3, :per_page => 3).size.should == 1
|
|
57
|
+
end
|
|
58
|
+
it "should get all articles, a few at a time, using paginated each" do
|
|
59
|
+
articles = Article.collection_proxy_for('Article', 'by_date', :key => Date.today, :include_docs => true)
|
|
60
|
+
articles.paginated_each(:per_page => 3) do |a|
|
|
61
|
+
a.should_not be_nil
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it "should raise an exception if design_doc is not provided" do
|
|
66
|
+
lambda{Article.collection_proxy_for(nil, 'by_date')}.should raise_error
|
|
67
|
+
lambda{Article.paginate(:view_name => 'by_date')}.should raise_error
|
|
68
|
+
end
|
|
69
|
+
it "should raise an exception if view_name is not provided" do
|
|
70
|
+
lambda{Article.collection_proxy_for('Article', nil)}.should raise_error
|
|
71
|
+
lambda{Article.paginate(:design_doc => 'Article')}.should raise_error
|
|
72
|
+
end
|
|
73
|
+
it "should be able to span multiple keys" do
|
|
74
|
+
articles = Article.collection_proxy_for('Article', 'by_date', :startkey => Date.today - 1, :endkey => Date.today, :include_docs => true)
|
|
75
|
+
articles.paginate(:page => 1, :per_page => 3).size.should == 3
|
|
76
|
+
articles.paginate(:page => 3, :per_page => 3).size.should == 3
|
|
77
|
+
articles.paginate(:page => 5, :per_page => 3).size.should == 1
|
|
78
|
+
end
|
|
79
|
+
it "should pass database parameter to pager" do
|
|
80
|
+
proxy = mock(:proxy)
|
|
81
|
+
proxy.stub!(:paginate)
|
|
82
|
+
::CouchRest::Model::Collection::CollectionProxy.should_receive(:new).with('database', anything(), anything(), anything(), anything()).and_return(proxy)
|
|
83
|
+
Article.paginate(:design_doc => 'Article', :view_name => 'by_date', :database => 'database')
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
end
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require "spec_helper"
|
|
3
|
+
|
|
4
|
+
describe CouchRest::Model::Configuration do
|
|
5
|
+
|
|
6
|
+
before do
|
|
7
|
+
@class = Class.new(CouchRest::Model::Base)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
describe '.configure' do
|
|
11
|
+
it "should set a configuration parameter" do
|
|
12
|
+
@class.add_config :foo_bar
|
|
13
|
+
@class.configure do |config|
|
|
14
|
+
config.foo_bar = 'monkey'
|
|
15
|
+
end
|
|
16
|
+
@class.foo_bar.should == 'monkey'
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
describe '.add_config' do
|
|
21
|
+
|
|
22
|
+
it "should add a class level accessor" do
|
|
23
|
+
@class.add_config :foo_bar
|
|
24
|
+
@class.foo_bar = 'foo'
|
|
25
|
+
@class.foo_bar.should == 'foo'
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
['foo', :foo, 45, ['foo', :bar]].each do |val|
|
|
29
|
+
it "should be inheritable for a #{val.class}" do
|
|
30
|
+
@class.add_config :foo_bar
|
|
31
|
+
@child_class = Class.new(@class)
|
|
32
|
+
|
|
33
|
+
@class.foo_bar = val
|
|
34
|
+
@class.foo_bar.should == val
|
|
35
|
+
@child_class.foo_bar.should == val
|
|
36
|
+
|
|
37
|
+
@child_class.foo_bar = "bar"
|
|
38
|
+
@child_class.foo_bar.should == "bar"
|
|
39
|
+
|
|
40
|
+
@class.foo_bar.should == val
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
it "should add an instance level accessor" do
|
|
46
|
+
@class.add_config :foo_bar
|
|
47
|
+
@class.foo_bar = 'foo'
|
|
48
|
+
@class.new.foo_bar.should == 'foo'
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it "should add a convenient in-class setter" do
|
|
52
|
+
@class.add_config :foo_bar
|
|
53
|
+
@class.foo_bar "monkey"
|
|
54
|
+
@class.foo_bar.should == "monkey"
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
describe "General examples" do
|
|
59
|
+
|
|
60
|
+
before(:all) do
|
|
61
|
+
@default_model_key = 'model-type'
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
it "should be possible to override on class using configure method" do
|
|
66
|
+
default_model_key = Cat.model_type_key
|
|
67
|
+
Cat.instance_eval do
|
|
68
|
+
model_type_key 'cat-type'
|
|
69
|
+
end
|
|
70
|
+
CouchRest::Model::Base.model_type_key.should eql(default_model_key)
|
|
71
|
+
Cat.model_type_key.should eql('cat-type')
|
|
72
|
+
cat = Cat.new
|
|
73
|
+
cat.model_type_key.should eql('cat-type')
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
end
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require 'spec_helper'
|
|
3
|
+
|
|
4
|
+
describe CouchRest::Model::Connection do
|
|
5
|
+
|
|
6
|
+
before do
|
|
7
|
+
@class = Class.new(CouchRest::Model::Base)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
describe "instance methods" do
|
|
11
|
+
before :each do
|
|
12
|
+
@obj = @class.new
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
describe "#database" do
|
|
16
|
+
it "should respond to" do
|
|
17
|
+
@obj.should respond_to(:database)
|
|
18
|
+
end
|
|
19
|
+
it "should provided class's database" do
|
|
20
|
+
@obj.class.should_receive :database
|
|
21
|
+
@obj.database
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
describe "#server" do
|
|
26
|
+
it "should respond to method" do
|
|
27
|
+
@obj.should respond_to(:server)
|
|
28
|
+
end
|
|
29
|
+
it "should return class's server" do
|
|
30
|
+
@obj.class.should_receive :server
|
|
31
|
+
@obj.server
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
describe "default configuration" do
|
|
37
|
+
|
|
38
|
+
it "should provide environment" do
|
|
39
|
+
@class.environment.should eql(:development)
|
|
40
|
+
end
|
|
41
|
+
it "should provide connection config file" do
|
|
42
|
+
@class.connection_config_file.should eql(File.join(Dir.pwd, 'config', 'couchdb.yml'))
|
|
43
|
+
end
|
|
44
|
+
it "should provided simple connection details" do
|
|
45
|
+
@class.connection[:prefix].should eql('couchrest')
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
describe "class methods" do
|
|
51
|
+
|
|
52
|
+
describe ".use_database" do
|
|
53
|
+
it "should respond to" do
|
|
54
|
+
@class.should respond_to(:use_database)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
describe ".database" do
|
|
59
|
+
it "should respond to" do
|
|
60
|
+
@class.should respond_to(:database)
|
|
61
|
+
end
|
|
62
|
+
it "should provide a database object" do
|
|
63
|
+
@class.database.should be_a(CouchRest::Database)
|
|
64
|
+
end
|
|
65
|
+
it "should provide a database with default name" do
|
|
66
|
+
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
describe ".server" do
|
|
72
|
+
it "should respond to" do
|
|
73
|
+
@class.should respond_to(:server)
|
|
74
|
+
end
|
|
75
|
+
it "should provide a server object" do
|
|
76
|
+
@class.server.should be_a(CouchRest::Server)
|
|
77
|
+
end
|
|
78
|
+
it "should provide a server with default config" do
|
|
79
|
+
@class.server.uri.should eql("http://localhost:5984")
|
|
80
|
+
end
|
|
81
|
+
it "should allow the configuration to be overwritten" do
|
|
82
|
+
@class.connection = {
|
|
83
|
+
:protocol => "https",
|
|
84
|
+
:host => "127.0.0.1",
|
|
85
|
+
:port => '5985',
|
|
86
|
+
:prefix => 'sample',
|
|
87
|
+
:suffix => 'test',
|
|
88
|
+
:username => 'foo',
|
|
89
|
+
:password => 'bar'
|
|
90
|
+
}
|
|
91
|
+
@class.server.uri.should eql("https://foo:bar@127.0.0.1:5985")
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
describe ".prepare_database" do
|
|
97
|
+
|
|
98
|
+
it "should respond to" do
|
|
99
|
+
@class.should respond_to(:prepare_database)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
it "should join the database name correctly" do
|
|
103
|
+
@class.connection[:suffix] = 'db'
|
|
104
|
+
db = @class.prepare_database('test')
|
|
105
|
+
db.name.should eql('couchrest_test_db')
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
it "should ignore nil values in database name" do
|
|
109
|
+
@class.connection[:suffix] = nil
|
|
110
|
+
db = @class.prepare_database('test')
|
|
111
|
+
db.name.should eql('couchrest_test')
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
describe "protected methods" do
|
|
116
|
+
|
|
117
|
+
describe ".connection_configuration" do
|
|
118
|
+
it "should provide main config by default" do
|
|
119
|
+
@class.send(:connection_configuration).should eql(@class.connection)
|
|
120
|
+
end
|
|
121
|
+
it "should load file if available" do
|
|
122
|
+
@class.connection_config_file = File.join(FIXTURE_PATH, 'config', 'couchdb.yml')
|
|
123
|
+
hash = @class.send(:connection_configuration)
|
|
124
|
+
hash[:protocol].should eql('https')
|
|
125
|
+
hash[:host].should eql('sample.cloudant.com')
|
|
126
|
+
hash[:join].should eql('_')
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
describe ".load_connection_config_file" do
|
|
131
|
+
it "should provide an empty hash if config not found" do
|
|
132
|
+
@class.send(:load_connection_config_file).should eql({})
|
|
133
|
+
end
|
|
134
|
+
it "should load file if available" do
|
|
135
|
+
@class.connection_config_file = File.join(FIXTURE_PATH, 'config', 'couchdb.yml')
|
|
136
|
+
hash = @class.send(:load_connection_config_file)
|
|
137
|
+
hash[:development].should_not be_nil
|
|
138
|
+
@class.server.uri.should eql("https://test:user@sample.cloudant.com:443")
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
end
|