couchmodel 0.1.0.beta3 → 0.1.0.beta4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. data/README.rdoc +22 -7
  2. data/lib/core_extension/array.rb +18 -2
  3. data/lib/core_extension/string.rb +12 -2
  4. data/lib/couch_model/active_model.rb +31 -8
  5. data/lib/couch_model/base/accessor.rb +8 -5
  6. data/lib/couch_model/base/association.rb +36 -15
  7. data/lib/couch_model/base/finder.rb +1 -0
  8. data/lib/couch_model/base/setup.rb +6 -1
  9. data/lib/couch_model/base.rb +55 -17
  10. data/lib/couch_model/collection.rb +41 -21
  11. data/lib/couch_model/configuration.rb +42 -46
  12. data/lib/couch_model/database.rb +2 -2
  13. data/lib/couch_model/design.rb +18 -14
  14. data/lib/couch_model/row.rb +34 -0
  15. data/lib/couch_model/server.rb +2 -2
  16. data/lib/couch_model/transport.rb +55 -34
  17. data/lib/couch_model/view.rb +9 -5
  18. data/spec/fake_transport.yml +84 -29
  19. data/spec/fake_transport_helper.rb +5 -3
  20. data/spec/integration/basic_spec.rb +26 -12
  21. data/spec/integration/design/membership.design +1 -1
  22. data/spec/integration/design/user.design +12 -0
  23. data/spec/lib/core_extension/array_spec.rb +24 -0
  24. data/spec/lib/couch_model/active_model_spec.rb +51 -0
  25. data/spec/lib/couch_model/base_spec.rb +30 -1
  26. data/spec/lib/couch_model/collection_spec.rb +31 -7
  27. data/spec/lib/couch_model/configuration_spec.rb +2 -2
  28. data/spec/lib/couch_model/core/accessor_spec.rb +11 -3
  29. data/spec/lib/couch_model/core/association_spec.rb +26 -0
  30. data/spec/lib/couch_model/core/setup_spec.rb +8 -0
  31. data/spec/lib/couch_model/design_spec.rb +1 -5
  32. data/spec/lib/couch_model/row_spec.rb +71 -0
  33. data/spec/lib/couch_model/transport_spec.rb +18 -1
  34. data/spec/lib/couch_model/view_spec.rb +2 -2
  35. data/spec/spec_helper.rb +1 -1
  36. metadata +6 -3
@@ -15,7 +15,7 @@ class User < CouchModel::Base
15
15
  setup_database DATABASE
16
16
 
17
17
  key_accessor :username
18
- key_accessor :email
18
+ key_accessor :email, :default => "no email"
19
19
 
20
20
  has_many :memberships,
21
21
  :class_name => "Membership",
@@ -41,7 +41,7 @@ describe "integration" do
41
41
  context "on new models" do
42
42
 
43
43
  before :each do
44
- @user = User.new :username => "user", :email => "email"
44
+ @user = User.new :username => "user"
45
45
  end
46
46
 
47
47
  describe "setup" do
@@ -82,16 +82,10 @@ describe "integration" do
82
82
  context "on saved models" do
83
83
 
84
84
  before :each do
85
- @user_one = User.new :username => "user one", :email => "email one"
86
- @user_one.save
87
- @user_two = User.new :username => "user two", :email => "email two"
88
- @user_two.save
89
- @membership_one = Membership.new :created_at => "yesterday"
90
- @membership_one.user = @user_one
91
- @membership_one.save
92
- @membership_two = Membership.new :created_at => "yesterday"
93
- @membership_two.user = @user_two
94
- @membership_two.save
85
+ @user_one = User.create :username => "user one"
86
+ @user_two = User.create :username => "user two"
87
+ @membership_one = Membership.create :created_at => "yesterday", :user => @user_one
88
+ @membership_two = Membership.create :created_at => "yesterday", :user => @user_two
95
89
  end
96
90
 
97
91
  describe "save" do
@@ -133,6 +127,14 @@ describe "integration" do
133
127
 
134
128
  end
135
129
 
130
+ describe "count" do
131
+
132
+ it "should return the number of users" do
133
+ User.count.should >= 2
134
+ end
135
+
136
+ end
137
+
136
138
  describe "belongs_to" do
137
139
 
138
140
  it "should return the related model" do
@@ -161,6 +163,18 @@ describe "integration" do
161
163
 
162
164
  end
163
165
 
166
+ describe "user_count" do
167
+
168
+ before :each do
169
+ @rows = User.user_count :returns => :rows
170
+ end
171
+
172
+ it "should return the user count" do
173
+ @rows.first.value.should >= 2
174
+ end
175
+
176
+ end
177
+
164
178
  end
165
179
 
166
180
  end
@@ -1,5 +1,5 @@
1
1
  :id: "membership"
2
2
  :language: "javascript"
3
3
  :views:
4
- "by_user_id_and_created_at":
4
+ :by_user_id_and_created_at:
5
5
  :keys: [ "user_id", "created_at" ]
@@ -1,2 +1,14 @@
1
1
  :id: "user"
2
2
  :language: "javascript"
3
+ :views:
4
+ :user_count:
5
+ :map:
6
+ function(document) {
7
+ if (document['model_class'] == 'User') {
8
+ emit('user_count', 1);
9
+ }
10
+ }
11
+ :reduce:
12
+ function(keys, values, rereduce) {
13
+ return sum(values);
14
+ }
@@ -3,6 +3,30 @@ require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "li
3
3
 
4
4
  describe Array do
5
5
 
6
+ describe "resize" do
7
+
8
+ it "should extend an array to the given length with the given elements" do
9
+ [ 1, 2, 3 ].resize(6, 4).should == [ 1, 2, 3, 4, 4, 4 ]
10
+ end
11
+
12
+ it "should shrink the array to the given length" do
13
+ [ 1, 2, 3 ].resize(1).should == [ 1 ]
14
+ end
15
+
16
+ it "should return the original array if the given length fits" do
17
+ [ 1, 2, 3 ].resize(3).should == [ 1, 2, 3 ]
18
+ end
19
+
20
+ it "should not change the original array" do
21
+ array = [ 1, 2, 3 ]
22
+ lambda do
23
+ array.resize 6
24
+ array.resize 1
25
+ end.should_not change(array, :size)
26
+ end
27
+
28
+ end
29
+
6
30
  describe "wrap" do
7
31
 
8
32
  it "should wrap an object into an array" do
@@ -123,6 +123,14 @@ describe ActiveTestModel do
123
123
 
124
124
  end
125
125
 
126
+ describe "to_param" do
127
+
128
+ it "should return the model's id" do
129
+ @model.to_param.should == @model.id
130
+ end
131
+
132
+ end
133
+
126
134
  describe "save" do
127
135
 
128
136
  before :each do
@@ -172,6 +180,49 @@ describe ActiveTestModel do
172
180
 
173
181
  end
174
182
 
183
+ describe "save!" do
184
+
185
+ before :each do
186
+ @model.name = "test"
187
+ end
188
+
189
+ it "should commit the changes" do
190
+ @model.save!
191
+ @model.should_not be_changed
192
+ end
193
+
194
+ it "should raise InvalidModelError on failing validations" do
195
+ @model.name = ""
196
+ lambda do
197
+ @model.save!
198
+ end.should raise_error(CouchModel::Base::InvalidModelError)
199
+ end
200
+
201
+ it "should raise StandardError on all other errors" do
202
+ @model.stub!(:save).and_return(false)
203
+ lambda do
204
+ @model.save!
205
+ end.should raise_error(StandardError)
206
+ end
207
+
208
+ end
209
+
210
+ describe "create!" do
211
+
212
+ it "should create a model" do
213
+ model = ActiveTestModel.create! :id => "test_model_1", :name => "test"
214
+ model.should be_instance_of(ActiveTestModel)
215
+ model.should_not be_new
216
+ end
217
+
218
+ it "should raise InvalidModelError on failing validations" do
219
+ lambda do
220
+ ActiveTestModel.create! :id => "test_model_1", :name => ""
221
+ end.should raise_error(CouchModel::Base::InvalidModelError)
222
+ end
223
+
224
+ end
225
+
175
226
  describe "destroy" do
176
227
 
177
228
  def do_destroy
@@ -163,7 +163,36 @@ describe BaseTestModel do
163
163
  it "should return a collection for the class view" do
164
164
  BaseTestModel.all.should be_instance_of(CouchModel::Collection)
165
165
  end
166
-
166
+
167
+ end
168
+
169
+ describe "create" do
170
+
171
+ it "should return a new created model" do
172
+ model = BaseTestModel.create :id => "test_model_1"
173
+ model.should be_instance_of(BaseTestModel)
174
+ model.should_not be_new
175
+ end
176
+
177
+ it "should return nil on error" do
178
+ CouchModel::Transport.stub!(:request).and_raise(CouchModel::Transport::UnexpectedStatusCodeError.new(500))
179
+ model = BaseTestModel.create :id => "test_model_1"
180
+ model.should be_nil
181
+ end
182
+
183
+ end
184
+
185
+ describe "destroy_all" do
186
+
187
+ before :each do
188
+ BaseTestModel.stub!(:all).and_return([ @model ])
189
+ end
190
+
191
+ it "should destroy all documents of the class" do
192
+ @model.should_receive(:destroy)
193
+ BaseTestModel.destroy_all
194
+ end
195
+
167
196
  end
168
197
 
169
198
  end
@@ -1,6 +1,7 @@
1
1
  require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "spec_helper"))
2
2
  require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "lib", "couch_model", "base"))
3
3
  require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "lib", "couch_model", "collection"))
4
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "lib", "couch_model", "row"))
4
5
 
5
6
  CouchModel::Configuration.design_directory = File.join File.dirname(__FILE__), "design"
6
7
 
@@ -30,7 +31,7 @@ describe CouchModel::Collection do
30
31
  end
31
32
 
32
33
  it "should set the options" do
33
- @collection.options.should == { :option => "test" }
34
+ @collection.options.should == { :option => "test", :returns => :models }
34
35
  end
35
36
 
36
37
  end
@@ -41,7 +42,7 @@ describe CouchModel::Collection do
41
42
 
42
43
  it "should perform a meta fetch (with a limit of zero)" do
43
44
  CouchModel::Transport.should_receive(:request).with(anything, anything,
44
- hash_including(:parameters => { "include_docs" => "true", "limit" => "0" }))
45
+ hash_including(:parameters => { :include_docs => true, :limit => 0 }))
45
46
  @collection.total_count
46
47
  end
47
48
 
@@ -80,10 +81,33 @@ describe CouchModel::Collection do
80
81
  do_fetch.should be_true
81
82
  end
82
83
 
83
- it "should fetch the model" do
84
- do_fetch
85
- @collection.first.should be_instance_of(CollectionTestModel)
86
- @collection.first.name.should == "phil"
84
+ context "returning models" do
85
+
86
+ before :each do
87
+ @collection.options[:returns] = :models
88
+ end
89
+
90
+ it "should fetch the model" do
91
+ do_fetch
92
+ @collection.first.should be_instance_of(CollectionTestModel)
93
+ @collection.first.name.should == "phil"
94
+ end
95
+
96
+ end
97
+
98
+ context "returning rows" do
99
+
100
+ before :each do
101
+ @collection.options[:returns] = :rows
102
+ end
103
+
104
+ it "should fetch the row" do
105
+ do_fetch
106
+ @collection.first.should be_instance_of(CouchModel::Row)
107
+ @collection.first.model.should be_instance_of(CollectionTestModel)
108
+ @collection.first.model.name.should == "phil"
109
+ end
110
+
87
111
  end
88
112
 
89
113
  end
@@ -92,7 +116,7 @@ describe CouchModel::Collection do
92
116
 
93
117
  it "should convert options to request parameters" do
94
118
  parameters = @collection.send :request_parameters
95
- parameters.should == { "include_docs" => "true", "limit" => "1" }
119
+ parameters.should == { :include_docs => true, :limit => 1 }
96
120
  end
97
121
 
98
122
  end
@@ -41,7 +41,7 @@ describe CouchModel::Configuration do
41
41
  describe "setup_databases" do
42
42
 
43
43
  before :each do
44
- CouchModel::Configuration.class_variable_set :@@databases, [ ]
44
+ CouchModel::Configuration.instance_variable_set :@databases, [ ]
45
45
  @database = CouchModel::Database.new :name => "test"
46
46
  CouchModel::Configuration.register_database @database
47
47
 
@@ -83,7 +83,7 @@ describe CouchModel::Configuration do
83
83
  describe "setup_designs" do
84
84
 
85
85
  before :each do
86
- CouchModel::Configuration.class_variable_set :@@designs, [ ]
86
+ CouchModel::Configuration.instance_variable_set :@designs, [ ]
87
87
 
88
88
  @database = CouchModel::Database.new :name => "test"
89
89
  @design = CouchModel::Design.new @database, :id => "test_design"
@@ -16,7 +16,7 @@ describe AccessorTestModel do
16
16
  describe "key_reader" do
17
17
 
18
18
  before :each do
19
- AccessorTestModel.key_reader :test
19
+ AccessorTestModel.key_reader :test, :default => "test default"
20
20
  @model = AccessorTestModel.new
21
21
  end
22
22
 
@@ -24,12 +24,16 @@ describe AccessorTestModel do
24
24
  @model.should respond_to(:test)
25
25
  end
26
26
 
27
+ it "should set a default value" do
28
+ @model.test.should == "test default"
29
+ end
30
+
27
31
  end
28
32
 
29
33
  describe "key_writer" do
30
34
 
31
35
  before :each do
32
- AccessorTestModel.key_writer :test
36
+ AccessorTestModel.key_writer :test, :default => "test default"
33
37
  @model = AccessorTestModel.new
34
38
  end
35
39
 
@@ -37,12 +41,16 @@ describe AccessorTestModel do
37
41
  @model.should respond_to(:test=)
38
42
  end
39
43
 
44
+ it "should set a default value" do
45
+ @model.test.should == "test default"
46
+ end
47
+
40
48
  end
41
49
 
42
50
  describe "key_accessor" do
43
51
 
44
52
  before :each do
45
- AccessorTestModel.key_accessor :test
53
+ AccessorTestModel.key_accessor(:test, :default => "test default")
46
54
  @model = AccessorTestModel.new
47
55
  end
48
56
 
@@ -24,6 +24,10 @@ class AssociationTestModelTwo < CouchModel::Base
24
24
  :view_name => :by_related_id_and_name,
25
25
  :query => lambda { |name| { :startkey => [ self.id, (name || nil) ], :endkey => [ self.id, (name || { }) ] } }
26
26
 
27
+ has_many :also_related,
28
+ :class_name => "AssociationTestModelOne",
29
+ :view_name => :by_related_id_and_name
30
+
27
31
  end
28
32
 
29
33
  describe AssociationTestModelOne do
@@ -109,6 +113,28 @@ describe AssociationTestModelTwo do
109
113
  @model.related(@other.name).should include(@other)
110
114
  end
111
115
 
116
+ it "should receive an extra query hash" do
117
+ @model.related(@other.name, :returns => :rows).first.should be_instance_of(CouchModel::Row)
118
+ end
119
+
120
+ end
121
+
122
+ describe "also_related" do
123
+
124
+ before :each do
125
+ @other = AssociationTestModelOne.find "test_model_1"
126
+ @query = { :startkey => [ @model.id, @other.name ], :endkey => [ @model.id, @other.name ] }
127
+ end
128
+
129
+ it "should return a collection" do
130
+ @model.also_related(@query).should be_instance_of(CouchModel::Collection)
131
+ end
132
+
133
+ it "should include the test model one" do
134
+ @model.also_related(@query).should include(@other)
135
+ @model.also_related(@query).should include(@other)
136
+ end
137
+
112
138
  end
113
139
 
114
140
  end
@@ -93,4 +93,12 @@ describe SetupTestModel do
93
93
 
94
94
  end
95
95
 
96
+ describe "count" do
97
+
98
+ it "should return the count of all documents of this class" do
99
+ SetupTestModel.count.should == 14
100
+ end
101
+
102
+ end
103
+
96
104
  end
@@ -44,10 +44,6 @@ describe CouchModel::Design do
44
44
 
45
45
  context "file does exists" do
46
46
 
47
- before :each do
48
- File.stub!(:exists?).and_return(true)
49
- end
50
-
51
47
  it "should set the attributes" do
52
48
  do_load
53
49
  @design.id.should == "test_design"
@@ -64,7 +60,7 @@ describe CouchModel::Design do
64
60
  context "file doesn't exists" do
65
61
 
66
62
  before :each do
67
- File.stub!(:exists?).and_return(false)
63
+ @design.stub!(:filename).and_return("invalid")
68
64
  end
69
65
 
70
66
  it "should return false" do
@@ -0,0 +1,71 @@
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", "row"))
4
+
5
+ class RowTestModel < CouchModel::Base
6
+
7
+ key_accessor :name
8
+
9
+ end
10
+
11
+ describe CouchModel::Row do
12
+
13
+ before :each do
14
+ @hash = {
15
+ "id" => "test id",
16
+ "key" => "test key",
17
+ "value" => "test value",
18
+ "doc" => {
19
+ "_id" => "test doc id",
20
+ CouchModel::Configuration::CLASS_KEY => "RowTestModel",
21
+ "name" => "test doc name"
22
+ }
23
+ }
24
+ @row = CouchModel::Row.new @hash
25
+ end
26
+
27
+ describe "initialize" do
28
+
29
+ it "should assign the id" do
30
+ @row.id.should == "test id"
31
+ end
32
+
33
+ it "should assign the key" do
34
+ @row.key.should == "test key"
35
+ end
36
+
37
+ it "should assign the id" do
38
+ @row.value.should == "test value"
39
+ end
40
+
41
+ it "should assign the document" do
42
+ @row.document.should == {
43
+ "_id" => "test doc id",
44
+ CouchModel::Configuration::CLASS_KEY => "RowTestModel",
45
+ "name" => "test doc name"
46
+ }
47
+ end
48
+
49
+ end
50
+
51
+ describe "model" do
52
+
53
+ it "should return a casted model" do
54
+ @row.model.should be_instance_of(RowTestModel)
55
+ end
56
+
57
+ it "should set the model's values" do
58
+ @row.model.id.should == "test doc id"
59
+ @row.model.name.should == "test doc name"
60
+ end
61
+
62
+ it "should raise a StandardError if model_class isn't defined" do
63
+ @row.document[CouchModel::Configuration::CLASS_KEY] = "invalid"
64
+ lambda do
65
+ @row.model
66
+ end.should raise_error(StandardError)
67
+ end
68
+
69
+ end
70
+
71
+ end
@@ -24,7 +24,7 @@ describe CouchModel::Transport do
24
24
  end
25
25
 
26
26
  it "should initialize the correct request object" do
27
- Net::HTTP::Get.should_receive(:new).with("/").and_return(@request)
27
+ Net::HTTP::Get.should_receive(:new).with("/", { }).and_return(@request)
28
28
  do_request
29
29
  end
30
30
 
@@ -41,4 +41,21 @@ describe CouchModel::Transport do
41
41
 
42
42
  end
43
43
 
44
+ describe "serialize_parameters" do
45
+
46
+ before :each do
47
+ @parameters = { :test => [ :test, 1, 2, 3 ], :another_test => :test }
48
+ end
49
+
50
+ it "should return an empty string on empty parameter hash" do
51
+ CouchModel::Transport.send(:serialize_parameters, { }).should == ""
52
+ end
53
+
54
+ it "should serialize the given parameters" do
55
+ CouchModel::Transport.send(:serialize_parameters, @parameters).should ==
56
+ "?another_test=%22test%22&test=[%22test%22,1,2,3]"
57
+ end
58
+
59
+ end
60
+
44
61
  end
@@ -57,7 +57,7 @@ describe CouchModel::View do
57
57
 
58
58
  end
59
59
 
60
- context "using explizit functions" do
60
+ context "using explicit functions" do
61
61
 
62
62
  before :each do
63
63
  @options.merge! :map => "map function",
@@ -89,7 +89,7 @@ describe CouchModel::View do
89
89
  end
90
90
 
91
91
  it "should pass the options to the collection" do
92
- @view.collection(:test => "test").options.should == { :test => "test" }
92
+ @view.collection(:test => "test").options.should == { :test => "test", :returns => :models }
93
93
  end
94
94
 
95
95
  end
data/spec/spec_helper.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  require 'rubygems'
2
- gem 'rspec'
2
+ gem 'rspec', '1.3.0'
3
3
  require 'spec'
4
4
 
5
5
  require File.expand_path(File.join(File.dirname(__FILE__), "..", "lib", "couch_model", "configuration"))
metadata CHANGED
@@ -6,8 +6,8 @@ version: !ruby/object:Gem::Version
6
6
  - 0
7
7
  - 1
8
8
  - 0
9
- - beta3
10
- version: 0.1.0.beta3
9
+ - beta4
10
+ version: 0.1.0.beta4
11
11
  platform: ruby
12
12
  authors:
13
13
  - "Philipp Br\xC3\xBCll"
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-03-10 00:00:00 +01:00
18
+ date: 2010-03-25 00:00:00 +01:00
19
19
  default_executable:
20
20
  dependencies: []
21
21
 
@@ -37,6 +37,7 @@ files:
37
37
  - lib/couch_model/base/finder.rb
38
38
  - lib/couch_model/base/association.rb
39
39
  - lib/couch_model/active_model.rb
40
+ - lib/couch_model/row.rb
40
41
  - lib/couch_model/view.rb
41
42
  - lib/couch_model/collection.rb
42
43
  - lib/couch_model/server.rb
@@ -63,6 +64,7 @@ files:
63
64
  - spec/lib/couch_model/design/setup_test_model.design
64
65
  - spec/lib/couch_model/configuration_spec.rb
65
66
  - spec/lib/couch_model/database_spec.rb
67
+ - spec/lib/couch_model/row_spec.rb
66
68
  - spec/lib/couch_model/base_spec.rb
67
69
  - spec/lib/couch_model_spec.rb
68
70
  - spec/lib/core_extension/string_spec.rb
@@ -121,6 +123,7 @@ test_files:
121
123
  - spec/lib/couch_model/collection_spec.rb
122
124
  - spec/lib/couch_model/configuration_spec.rb
123
125
  - spec/lib/couch_model/database_spec.rb
126
+ - spec/lib/couch_model/row_spec.rb
124
127
  - spec/lib/couch_model/base_spec.rb
125
128
  - spec/lib/couch_model_spec.rb
126
129
  - spec/lib/core_extension/string_spec.rb