couchmodel 0.1.0.beta2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|