couchmodel 0.1.0.beta3 → 0.1.0.beta4

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.
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