couchmodel 0.1.0.beta2
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/LICENSE +20 -0
- data/README.rdoc +156 -0
- data/Rakefile +20 -0
- data/lib/core_extension/array.rb +14 -0
- data/lib/core_extension/string.rb +12 -0
- data/lib/couch_model/active_model.rb +86 -0
- data/lib/couch_model/base/accessor.rb +39 -0
- data/lib/couch_model/base/association.rb +63 -0
- data/lib/couch_model/base/finder.rb +28 -0
- data/lib/couch_model/base/setup.rb +88 -0
- data/lib/couch_model/base.rb +117 -0
- data/lib/couch_model/collection.rb +84 -0
- data/lib/couch_model/configuration.rb +68 -0
- data/lib/couch_model/database.rb +64 -0
- data/lib/couch_model/design.rb +92 -0
- data/lib/couch_model/server.rb +44 -0
- data/lib/couch_model/transport.rb +68 -0
- data/lib/couch_model/view.rb +52 -0
- data/lib/couch_model.rb +15 -0
- data/spec/fake_transport.yml +202 -0
- data/spec/fake_transport_helper.rb +27 -0
- data/spec/integration/basic_spec.rb +125 -0
- data/spec/integration/design/membership.design +5 -0
- data/spec/integration/design/user.design +2 -0
- data/spec/lib/core_extension/array_spec.rb +24 -0
- data/spec/lib/core_extension/string_spec.rb +22 -0
- data/spec/lib/couch_model/active_model_spec.rb +228 -0
- data/spec/lib/couch_model/base_spec.rb +169 -0
- data/spec/lib/couch_model/collection_spec.rb +100 -0
- data/spec/lib/couch_model/configuration_spec.rb +117 -0
- data/spec/lib/couch_model/core/accessor_spec.rb +59 -0
- data/spec/lib/couch_model/core/association_spec.rb +114 -0
- data/spec/lib/couch_model/core/finder_spec.rb +24 -0
- data/spec/lib/couch_model/core/setup_spec.rb +88 -0
- data/spec/lib/couch_model/database_spec.rb +165 -0
- data/spec/lib/couch_model/design/association_test_model_one.design +5 -0
- data/spec/lib/couch_model/design/base_test_model.design +10 -0
- data/spec/lib/couch_model/design/setup_test_model.design +10 -0
- data/spec/lib/couch_model/design_spec.rb +144 -0
- data/spec/lib/couch_model/server_spec.rb +64 -0
- data/spec/lib/couch_model/transport_spec.rb +44 -0
- data/spec/lib/couch_model/view_spec.rb +166 -0
- data/spec/lib/couch_model_spec.rb +3 -0
- data/spec/spec_helper.rb +27 -0
- metadata +128 -0
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module CouchModel
|
4
|
+
|
5
|
+
module Transport
|
6
|
+
|
7
|
+
def self.fake!
|
8
|
+
@@fake ||= YAML::load_file File.join(File.dirname(__FILE__), "fake_transport.yml")
|
9
|
+
self.stub!(:request).and_return do |http_method, url, options|
|
10
|
+
options ||= { }
|
11
|
+
parameters = options[:parameters]
|
12
|
+
expected_status_code = options[:expected_status_code]
|
13
|
+
|
14
|
+
request = @@fake.detect do |hash|
|
15
|
+
hash[:http_method].to_s == http_method.to_s &&
|
16
|
+
hash[:url].to_s == url.to_s &&
|
17
|
+
hash[:parameters] == parameters
|
18
|
+
end
|
19
|
+
raise StandardError, "no fake request found for [#{http_method} #{url} #{parameters.inspect}]" unless request
|
20
|
+
raise UnexpectedStatusCodeError, request[:response][:code].to_i if expected_status_code && expected_status_code.to_s != request[:response][:code]
|
21
|
+
request[:response][:json].dup
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "..", "spec_helper"))
|
2
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "lib", "couch_model"))
|
3
|
+
|
4
|
+
CouchModel::Configuration.design_directory = File.join File.dirname(__FILE__), "design"
|
5
|
+
|
6
|
+
class User < CouchModel::Base
|
7
|
+
|
8
|
+
setup_database :url => "http://localhost:5984/test", :setup_on_initialization => true, :delete_if_exists => true
|
9
|
+
|
10
|
+
key_accessor :username
|
11
|
+
key_accessor :email
|
12
|
+
|
13
|
+
has_many :memberships,
|
14
|
+
:class_name => "Membership",
|
15
|
+
:view_name => :by_user_id_and_created_at,
|
16
|
+
:query => lambda { |created_at| { :startkey => [ self.id, (created_at || nil) ], :endkey => [ self.id, (created_at || { }) ] } }
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
class Membership < CouchModel::Base
|
21
|
+
|
22
|
+
setup_database :url => "http://localhost:5984/test", :setup_on_initialization => true, :delete_if_exists => true
|
23
|
+
|
24
|
+
key_accessor :created_at
|
25
|
+
|
26
|
+
belongs_to :user, :class_name => "User"
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "integration" do
|
31
|
+
|
32
|
+
use_real_transport!
|
33
|
+
|
34
|
+
context "on new models" do
|
35
|
+
|
36
|
+
before :each do
|
37
|
+
@user = User.new :username => "user", :email => "email"
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "setup" do
|
41
|
+
|
42
|
+
it "should have been created the database" do
|
43
|
+
User.database.exists?.should be_true
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should have been created the design" do
|
47
|
+
User.design.exists?.should be_true
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should setup unique databases" do
|
51
|
+
User.database.should === Membership.database
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should setup designs for each model" do
|
55
|
+
User.design.should_not == Membership.design
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "save" do
|
61
|
+
|
62
|
+
it "should create the model" do
|
63
|
+
@user.save
|
64
|
+
@user.should_not be_new
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
context "on saved models" do
|
72
|
+
|
73
|
+
before :each do
|
74
|
+
@user_one = User.new :username => "user one", :email => "email one"
|
75
|
+
@user_one.save
|
76
|
+
@user_two = User.new :username => "user two", :email => "email two"
|
77
|
+
@user_two.save
|
78
|
+
@membership_one = Membership.new :created_at => "yesterday"
|
79
|
+
@membership_one.user = @user_one
|
80
|
+
@membership_one.save
|
81
|
+
@membership_two = Membership.new :created_at => "yesterday"
|
82
|
+
@membership_two.user = @user_two
|
83
|
+
@membership_two.save
|
84
|
+
end
|
85
|
+
|
86
|
+
describe "all" do
|
87
|
+
|
88
|
+
it "should include the saved user" do
|
89
|
+
User.all.should include(@user_one)
|
90
|
+
User.all.should include(@user_two)
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
describe "belongs_to" do
|
96
|
+
|
97
|
+
it "should return the related model" do
|
98
|
+
@membership_one.user.should == @user_one
|
99
|
+
@membership_two.user.should == @user_two
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
describe "has_many" do
|
105
|
+
|
106
|
+
it "should include the related model" do
|
107
|
+
@user_one.memberships.should include(@membership_one)
|
108
|
+
@user_two.memberships.should include(@membership_two)
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should not include the not-related model" do
|
112
|
+
@user_one.memberships.should_not include(@membership_two)
|
113
|
+
@user_two.memberships.should_not include(@membership_one)
|
114
|
+
end
|
115
|
+
|
116
|
+
it "should use the selector" do
|
117
|
+
@user_one.memberships("yesterday").should include(@membership_one)
|
118
|
+
@user_one.memberships("today").should_not include(@membership_one)
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "spec_helper"))
|
2
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "lib", "core_extension", "array"))
|
3
|
+
|
4
|
+
describe Array do
|
5
|
+
|
6
|
+
describe "wrap" do
|
7
|
+
|
8
|
+
it "should wrap an object into an array" do
|
9
|
+
Array.wrap("test").should == [ "test" ]
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should keep an array as it is" do
|
13
|
+
Array.wrap([ "test" ]).should == [ "test" ]
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should use to_ary to convert the object" do
|
17
|
+
object = Object.new
|
18
|
+
object.stub!(:to_ary).and_return([ "test" ])
|
19
|
+
Array.wrap(object).should == [ "test" ]
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "spec_helper"))
|
2
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "lib", "core_extension", "string"))
|
3
|
+
|
4
|
+
describe String do
|
5
|
+
|
6
|
+
describe "underscore" do
|
7
|
+
|
8
|
+
it "should convert camelcase to underscore" do
|
9
|
+
"TestModel".underscore.should == "test_model"
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "camelize" do
|
15
|
+
|
16
|
+
it "should convert underscore to camelcase" do
|
17
|
+
"test_model".camelize.should == "TestModel"
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,228 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "spec_helper"))
|
2
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "lib", "couch_model", "active_model"))
|
3
|
+
|
4
|
+
class ActiveTestModel < CouchModel::Base
|
5
|
+
|
6
|
+
setup_database :url => "http://localhost:5984/test"
|
7
|
+
|
8
|
+
key_accessor :name
|
9
|
+
key_accessor :email
|
10
|
+
|
11
|
+
validates_presence_of :name
|
12
|
+
|
13
|
+
before_initialize :initialize_callback
|
14
|
+
before_save :save_callback
|
15
|
+
before_create :create_callback
|
16
|
+
before_update :update_callback
|
17
|
+
before_destroy :destroy_callback
|
18
|
+
|
19
|
+
attr_reader :initialized
|
20
|
+
|
21
|
+
def initialize_callback
|
22
|
+
@initialized = true
|
23
|
+
end
|
24
|
+
|
25
|
+
def save_callback; end
|
26
|
+
def create_callback; end
|
27
|
+
def update_callback; end
|
28
|
+
def destroy_callback; end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
describe ActiveTestModel do
|
33
|
+
include ActiveModel::Lint::Tests
|
34
|
+
|
35
|
+
before :each do
|
36
|
+
@model = ActiveTestModel.new :id => "test_model_1"
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "initialize" do
|
40
|
+
|
41
|
+
it "should call the initialize callback" do
|
42
|
+
@model.initialized.should be_true
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "new_record?" do
|
48
|
+
|
49
|
+
it "should fullfill the lint test" do
|
50
|
+
test_new_record?
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "destroyed?" do
|
56
|
+
|
57
|
+
it "should fullfill the lint test" do
|
58
|
+
test_destroyed?
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should return true if model is new" do
|
62
|
+
@model.stub!(:new?).and_return(true)
|
63
|
+
@model.should be_destroyed
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
describe "naming" do
|
69
|
+
|
70
|
+
it "should fullfill the lint test" do
|
71
|
+
test_model_naming
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
describe "valid?" do
|
77
|
+
|
78
|
+
it "should be true with a given name" do
|
79
|
+
@model.name = "test"
|
80
|
+
@model.should be_valid
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should be false without a given name" do
|
84
|
+
@model.name = ""
|
85
|
+
@model.should_not be_valid
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
describe "changed?" do
|
91
|
+
|
92
|
+
it "should be true if a attribute has changed" do
|
93
|
+
@model.name = "test"
|
94
|
+
@model.should be_changed
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
describe "name_changed?" do
|
100
|
+
|
101
|
+
it "should be true if the attribute has changed" do
|
102
|
+
@model.name = "test"
|
103
|
+
@model.should be_name_changed
|
104
|
+
end
|
105
|
+
|
106
|
+
it "should be false if another attribute has changed" do
|
107
|
+
@model.email = "test"
|
108
|
+
@model.should_not be_name_changed
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
describe "reset_name!" do
|
114
|
+
|
115
|
+
before :each do
|
116
|
+
@model.name = "test"
|
117
|
+
end
|
118
|
+
|
119
|
+
it "should reset the attributes" do
|
120
|
+
@model.reset_name!
|
121
|
+
@model.name.should be_nil
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
125
|
+
|
126
|
+
describe "save" do
|
127
|
+
|
128
|
+
before :each do
|
129
|
+
@model.name = "test"
|
130
|
+
end
|
131
|
+
|
132
|
+
it "should commit the changes" do
|
133
|
+
@model.save
|
134
|
+
@model.should_not be_changed
|
135
|
+
end
|
136
|
+
|
137
|
+
it "should call the save callback" do
|
138
|
+
@model.should_receive(:save_callback)
|
139
|
+
@model.save
|
140
|
+
end
|
141
|
+
|
142
|
+
describe "on a new model" do
|
143
|
+
|
144
|
+
before :each do
|
145
|
+
@model.stub!(:new?).and_return(true)
|
146
|
+
end
|
147
|
+
|
148
|
+
it "should call the create callback" do
|
149
|
+
@model.should_receive(:create_callback)
|
150
|
+
@model.save
|
151
|
+
end
|
152
|
+
|
153
|
+
end
|
154
|
+
|
155
|
+
describe "on an existing model" do
|
156
|
+
|
157
|
+
before :each do
|
158
|
+
@model.stub!(:new?).and_return(false)
|
159
|
+
end
|
160
|
+
|
161
|
+
it "should call the update callback" do
|
162
|
+
@model.should_receive(:update_callback)
|
163
|
+
@model.save
|
164
|
+
end
|
165
|
+
|
166
|
+
end
|
167
|
+
|
168
|
+
end
|
169
|
+
|
170
|
+
describe "destroy" do
|
171
|
+
|
172
|
+
def do_destroy
|
173
|
+
@model.destroy
|
174
|
+
end
|
175
|
+
|
176
|
+
it "should call the destroy callback" do
|
177
|
+
@model.should_receive(:destroy_callback)
|
178
|
+
do_destroy
|
179
|
+
end
|
180
|
+
|
181
|
+
end
|
182
|
+
|
183
|
+
describe "to_json" do
|
184
|
+
|
185
|
+
before :each do
|
186
|
+
@model.name = "test"
|
187
|
+
@model.email = "test"
|
188
|
+
end
|
189
|
+
|
190
|
+
it "should return all attributes as json" do
|
191
|
+
@model.to_json.should == "{\"_id\":\"test_model_1\",\"email\":\"test\",\"model_class\":\"ActiveTestModel\",\"name\":\"test\"}"
|
192
|
+
end
|
193
|
+
|
194
|
+
end
|
195
|
+
|
196
|
+
describe "to_xml" do
|
197
|
+
|
198
|
+
before :each do
|
199
|
+
@model.name = "test"
|
200
|
+
@model.email = "test"
|
201
|
+
end
|
202
|
+
|
203
|
+
it "should return all attributes as xml" do
|
204
|
+
@model.to_xml.should == "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<active-test-model>\n <-id>test_model_1</-id>\n <email>test</email>\n <model-class>ActiveTestModel</model-class>\n <name>test</name>\n</active-test-model>\n"
|
205
|
+
end
|
206
|
+
|
207
|
+
end
|
208
|
+
|
209
|
+
describe "human_attribute_name" do
|
210
|
+
|
211
|
+
it "should return a human readable attribute name" do
|
212
|
+
ActiveTestModel.human_attribute_name("name").should == "Name"
|
213
|
+
end
|
214
|
+
|
215
|
+
end
|
216
|
+
|
217
|
+
private
|
218
|
+
|
219
|
+
def assert(condition, message = nil)
|
220
|
+
puts message unless condition
|
221
|
+
condition.should be_true
|
222
|
+
end
|
223
|
+
|
224
|
+
def assert_kind_of(klass, value)
|
225
|
+
value.should be_kind_of(klass)
|
226
|
+
end
|
227
|
+
|
228
|
+
end
|
@@ -0,0 +1,169 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "spec_helper"))
|
2
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "lib", "couch_model", "base"))
|
3
|
+
|
4
|
+
CouchModel::Configuration.design_directory = File.join File.dirname(__FILE__), "design"
|
5
|
+
|
6
|
+
class BaseTestModel < CouchModel::Base
|
7
|
+
|
8
|
+
setup_database :url => "http://localhost:5984/test"
|
9
|
+
|
10
|
+
key_accessor :name
|
11
|
+
|
12
|
+
end
|
13
|
+
|
14
|
+
describe BaseTestModel do
|
15
|
+
|
16
|
+
before :each do
|
17
|
+
@model = BaseTestModel.new :id => "test_model_1"
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "attributes=" do
|
21
|
+
|
22
|
+
it "should convert an :id or 'id' key to '_id'" do
|
23
|
+
@model.attributes = { :id => "test" }
|
24
|
+
@model.attributes.should == { "_id" => "test", CouchModel::Configuration::CLASS_KEY => "BaseTestModel" }
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "==" do
|
30
|
+
|
31
|
+
before :each do
|
32
|
+
@other = BaseTestModel.new
|
33
|
+
@other.id = "test_model_1"
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should be true if the id's of the models are equal" do
|
37
|
+
@model.should == @other
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should be false if the id's of the models are not equal" do
|
41
|
+
@other.id = "invalid"
|
42
|
+
@model.should_not == @other
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "new?" do
|
48
|
+
|
49
|
+
it "should be true on new model" do
|
50
|
+
BaseTestModel.new.should be_new
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should be false on existing model" do
|
54
|
+
BaseTestModel.find("test_model_1").should_not be_new
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "load" do
|
60
|
+
|
61
|
+
before :each do
|
62
|
+
@model = BaseTestModel.new :id => "test_model_1"
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should load the model" do
|
66
|
+
@model.load
|
67
|
+
@model.attributes["name"].should == "phil"
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should raise an NotFoundError if the model id is not existing" do
|
71
|
+
@model.id = "invalid"
|
72
|
+
lambda do
|
73
|
+
@model.load
|
74
|
+
end.should raise_error(CouchModel::Base::NotFoundError)
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
describe "save" do
|
80
|
+
|
81
|
+
def do_save
|
82
|
+
@model.save
|
83
|
+
end
|
84
|
+
|
85
|
+
describe "a new model" do
|
86
|
+
|
87
|
+
before :each do
|
88
|
+
@model = BaseTestModel.new
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should return true if the model has been saved" do
|
92
|
+
do_save.should be_true
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should return false on wrong status code" do
|
96
|
+
CouchModel::Transport.stub!(:request).and_raise(CouchModel::Transport::UnexpectedStatusCodeError.new(404))
|
97
|
+
do_save.should be_false
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
describe "an existing model" do
|
103
|
+
|
104
|
+
before :each do
|
105
|
+
@model = BaseTestModel.find "test_model_1"
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should return true if the model has been updated" do
|
109
|
+
do_save.should be_true
|
110
|
+
end
|
111
|
+
|
112
|
+
it "should return false on wrong status code" do
|
113
|
+
CouchModel::Transport.stub!(:request).and_raise(CouchModel::Transport::UnexpectedStatusCodeError.new(404))
|
114
|
+
do_save.should be_false
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
120
|
+
|
121
|
+
describe "destroy" do
|
122
|
+
|
123
|
+
def do_destroy
|
124
|
+
@model.destroy
|
125
|
+
end
|
126
|
+
|
127
|
+
describe "on a new model" do
|
128
|
+
|
129
|
+
it "should return false" do
|
130
|
+
do_destroy.should be_false
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
134
|
+
|
135
|
+
describe "on an existing model" do
|
136
|
+
|
137
|
+
before :each do
|
138
|
+
@model.load
|
139
|
+
end
|
140
|
+
|
141
|
+
it "should return true if the model has been destroyed" do
|
142
|
+
do_destroy.should be_true
|
143
|
+
end
|
144
|
+
|
145
|
+
it "should raise NotFoundError on wrong status code" do
|
146
|
+
CouchModel::Transport.stub!(:request).and_raise(CouchModel::Transport::UnexpectedStatusCodeError.new(404))
|
147
|
+
lambda do
|
148
|
+
do_destroy
|
149
|
+
end.should raise_error(CouchModel::Base::NotFoundError)
|
150
|
+
end
|
151
|
+
|
152
|
+
it "should be new afterwards" do
|
153
|
+
do_destroy
|
154
|
+
@model.should be_new
|
155
|
+
end
|
156
|
+
|
157
|
+
end
|
158
|
+
|
159
|
+
end
|
160
|
+
|
161
|
+
describe "all" do
|
162
|
+
|
163
|
+
it "should return a collection for the class view" do
|
164
|
+
BaseTestModel.all.should be_instance_of(CouchModel::Collection)
|
165
|
+
end
|
166
|
+
|
167
|
+
end
|
168
|
+
|
169
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "spec_helper"))
|
2
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "lib", "couch_model", "base"))
|
3
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "lib", "couch_model", "collection"))
|
4
|
+
|
5
|
+
CouchModel::Configuration.design_directory = File.join File.dirname(__FILE__), "design"
|
6
|
+
|
7
|
+
class CollectionTestModel < CouchModel::Base
|
8
|
+
|
9
|
+
setup_database :url => "http://localhost:5984/test"
|
10
|
+
|
11
|
+
key_accessor :name
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
describe CouchModel::Collection do
|
16
|
+
|
17
|
+
before :each do
|
18
|
+
@database = CouchModel::Database.new :name => "test"
|
19
|
+
@collection = @database.documents :limit => 1
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "initialize" do
|
23
|
+
|
24
|
+
before :each do
|
25
|
+
@collection = CouchModel::Collection.new @database.url + "/_all_docs", :option => "test"
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should set the url" do
|
29
|
+
@collection.url.should == @database.url + "/_all_docs"
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should set the options" do
|
33
|
+
@collection.options.should == { :option => "test" }
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "total_count" do
|
39
|
+
|
40
|
+
describe "without a previously performed fetch" do
|
41
|
+
|
42
|
+
it "should perform a meta fetch (with a limit of zero)" do
|
43
|
+
CouchModel::Transport.should_receive(:request).with(anything, anything,
|
44
|
+
hash_including(:parameters => { "include_docs" => "true", "limit" => "0" }))
|
45
|
+
@collection.total_count
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should return the total count" do
|
49
|
+
@collection.total_count.should == 1
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "with a previously performed fetch" do
|
55
|
+
|
56
|
+
before :each do
|
57
|
+
@collection.first # perform the fetch
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should not perform another fetch" do
|
61
|
+
CouchModel::Transport.should_not_receive(:request)
|
62
|
+
@collection.total_count
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should return the total count" do
|
66
|
+
@collection.total_count.should == 1
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
describe "fetch" do
|
74
|
+
|
75
|
+
def do_fetch
|
76
|
+
@collection.send :fetch
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should return true" do
|
80
|
+
do_fetch.should be_true
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should fetch the model" do
|
84
|
+
do_fetch
|
85
|
+
@collection.first.should be_instance_of(CollectionTestModel)
|
86
|
+
@collection.first.name.should == "phil"
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
describe "request_parameters" do
|
92
|
+
|
93
|
+
it "should convert options to request parameters" do
|
94
|
+
parameters = @collection.send :request_parameters
|
95
|
+
parameters.should == { "include_docs" => "true", "limit" => "1" }
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|