novelys_mongo_mapper 0.6.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. data/.gitignore +10 -0
  2. data/LICENSE +20 -0
  3. data/README.rdoc +38 -0
  4. data/Rakefile +54 -0
  5. data/VERSION +1 -0
  6. data/bin/mmconsole +60 -0
  7. data/lib/mongo_mapper.rb +124 -0
  8. data/lib/mongo_mapper/descendant_appends.rb +44 -0
  9. data/lib/mongo_mapper/document.rb +423 -0
  10. data/lib/mongo_mapper/dynamic_finder.rb +74 -0
  11. data/lib/mongo_mapper/embedded_document.rb +67 -0
  12. data/lib/mongo_mapper/finder_options.rb +127 -0
  13. data/lib/mongo_mapper/plugins.rb +14 -0
  14. data/lib/mongo_mapper/plugins/associations.rb +104 -0
  15. data/lib/mongo_mapper/plugins/associations/base.rb +121 -0
  16. data/lib/mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +30 -0
  17. data/lib/mongo_mapper/plugins/associations/belongs_to_proxy.rb +25 -0
  18. data/lib/mongo_mapper/plugins/associations/collection.rb +21 -0
  19. data/lib/mongo_mapper/plugins/associations/embedded_collection.rb +50 -0
  20. data/lib/mongo_mapper/plugins/associations/in_array_proxy.rb +139 -0
  21. data/lib/mongo_mapper/plugins/associations/many_documents_as_proxy.rb +28 -0
  22. data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +117 -0
  23. data/lib/mongo_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +31 -0
  24. data/lib/mongo_mapper/plugins/associations/many_embedded_proxy.rb +23 -0
  25. data/lib/mongo_mapper/plugins/associations/many_polymorphic_proxy.rb +13 -0
  26. data/lib/mongo_mapper/plugins/associations/one_proxy.rb +68 -0
  27. data/lib/mongo_mapper/plugins/associations/proxy.rb +118 -0
  28. data/lib/mongo_mapper/plugins/callbacks.rb +76 -0
  29. data/lib/mongo_mapper/plugins/clone.rb +13 -0
  30. data/lib/mongo_mapper/plugins/descendants.rb +16 -0
  31. data/lib/mongo_mapper/plugins/dirty.rb +119 -0
  32. data/lib/mongo_mapper/plugins/equality.rb +23 -0
  33. data/lib/mongo_mapper/plugins/identity_map.rb +122 -0
  34. data/lib/mongo_mapper/plugins/inspect.rb +14 -0
  35. data/lib/mongo_mapper/plugins/keys.rb +300 -0
  36. data/lib/mongo_mapper/plugins/logger.rb +17 -0
  37. data/lib/mongo_mapper/plugins/pagination.rb +85 -0
  38. data/lib/mongo_mapper/plugins/protected.rb +41 -0
  39. data/lib/mongo_mapper/plugins/rails.rb +45 -0
  40. data/lib/mongo_mapper/plugins/serialization.rb +105 -0
  41. data/lib/mongo_mapper/plugins/validations.rb +62 -0
  42. data/lib/mongo_mapper/support.rb +214 -0
  43. data/mongo_mapper.gemspec +179 -0
  44. data/performance/read_write.rb +52 -0
  45. data/specs.watchr +51 -0
  46. data/test/NOTE_ON_TESTING +1 -0
  47. data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +63 -0
  48. data/test/functional/associations/test_belongs_to_proxy.rb +101 -0
  49. data/test/functional/associations/test_in_array_proxy.rb +309 -0
  50. data/test/functional/associations/test_many_documents_as_proxy.rb +229 -0
  51. data/test/functional/associations/test_many_documents_proxy.rb +431 -0
  52. data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +176 -0
  53. data/test/functional/associations/test_many_embedded_proxy.rb +256 -0
  54. data/test/functional/associations/test_many_polymorphic_proxy.rb +302 -0
  55. data/test/functional/associations/test_one_proxy.rb +161 -0
  56. data/test/functional/test_associations.rb +44 -0
  57. data/test/functional/test_binary.rb +27 -0
  58. data/test/functional/test_callbacks.rb +81 -0
  59. data/test/functional/test_dirty.rb +163 -0
  60. data/test/functional/test_document.rb +1245 -0
  61. data/test/functional/test_embedded_document.rb +125 -0
  62. data/test/functional/test_identity_map.rb +508 -0
  63. data/test/functional/test_logger.rb +20 -0
  64. data/test/functional/test_modifiers.rb +252 -0
  65. data/test/functional/test_pagination.rb +93 -0
  66. data/test/functional/test_protected.rb +139 -0
  67. data/test/functional/test_string_id_compatibility.rb +67 -0
  68. data/test/functional/test_validations.rb +329 -0
  69. data/test/models.rb +232 -0
  70. data/test/support/custom_matchers.rb +55 -0
  71. data/test/support/timing.rb +16 -0
  72. data/test/test_helper.rb +55 -0
  73. data/test/unit/associations/test_base.rb +207 -0
  74. data/test/unit/associations/test_proxy.rb +105 -0
  75. data/test/unit/serializers/test_json_serializer.rb +189 -0
  76. data/test/unit/test_descendant_appends.rb +71 -0
  77. data/test/unit/test_document.rb +231 -0
  78. data/test/unit/test_dynamic_finder.rb +125 -0
  79. data/test/unit/test_embedded_document.rb +663 -0
  80. data/test/unit/test_finder_options.rb +329 -0
  81. data/test/unit/test_keys.rb +169 -0
  82. data/test/unit/test_mongo_mapper.rb +65 -0
  83. data/test/unit/test_pagination.rb +127 -0
  84. data/test/unit/test_plugins.rb +50 -0
  85. data/test/unit/test_rails.rb +123 -0
  86. data/test/unit/test_rails_compatibility.rb +52 -0
  87. data/test/unit/test_serialization.rb +51 -0
  88. data/test/unit/test_support.rb +354 -0
  89. data/test/unit/test_time_zones.rb +39 -0
  90. data/test/unit/test_validations.rb +544 -0
  91. metadata +248 -0
@@ -0,0 +1,256 @@
1
+ require 'test_helper'
2
+ require 'models'
3
+
4
+ class ManyEmbeddedProxyTest < Test::Unit::TestCase
5
+ def setup
6
+ @comment_class = EDoc do
7
+ key :name, String
8
+ key :body, String
9
+ end
10
+ @post_class = Doc do
11
+ key :title, String
12
+ end
13
+ @post_class.many :comments, :class => @comment_class
14
+
15
+ @pet_class = EDoc do
16
+ key :name, String
17
+ end
18
+ @pet_class.embedded_in :person
19
+ @person_class = EDoc do
20
+ key :name, String
21
+ end
22
+ @person_class.key :child, @person_class
23
+ @person_class.many :pets, :class => @pet_class
24
+
25
+ @owner_class = Doc do
26
+ key :name, String
27
+ end
28
+ @owner_class.many :pets, :class => @pet_class
29
+ end
30
+
31
+ should "default reader to empty array" do
32
+ @post_class.new.comments.should == []
33
+ end
34
+
35
+ should "allow adding to association like it was an array" do
36
+ post = @post_class.new
37
+ post.comments << @comment_class.new
38
+ post.comments.push @comment_class.new
39
+ post.comments.size.should == 2
40
+ end
41
+
42
+ should "be embedded in document on save" do
43
+ frank = @comment_class.new(:name => 'Frank', :body => 'Hi!')
44
+ bill = @comment_class.new(:name => 'Bill', :body => 'Hi!')
45
+ post = @post_class.new
46
+ post.comments << frank
47
+ post.comments << bill
48
+ post.save
49
+
50
+ post.reload
51
+ post.comments.size.should == 2
52
+ post.comments[0].should == frank
53
+ post.comments[0].new?.should == false
54
+ post.comments[1].should == bill
55
+ post.comments[1].new?.should == false
56
+ end
57
+
58
+ should "allow embedding arbitrarily deep" do
59
+ @klass = Doc()
60
+ @klass.key :person, @person_class
61
+
62
+ meg = @person_class.new(:name => 'Meg')
63
+ meg.child = @person_class.new(:name => 'Steve')
64
+ meg.child.child = @person_class.new(:name => 'Linda')
65
+
66
+ doc = @klass.new(:person => meg)
67
+ doc.save
68
+ doc.reload
69
+
70
+ doc.person.name.should == 'Meg'
71
+ doc.person.child.name.should == 'Steve'
72
+ doc.person.child.child.name.should == 'Linda'
73
+ end
74
+
75
+ should "allow assignment of many embedded documents using a hash" do
76
+ person_attributes = {
77
+ 'name' => 'Mr. Pet Lover',
78
+ 'pets' => [
79
+ {'name' => 'Jimmy', 'species' => 'Cocker Spainel'},
80
+ {'name' => 'Sasha', 'species' => 'Siberian Husky'},
81
+ ]
82
+ }
83
+
84
+ owner = @owner_class.new(person_attributes)
85
+ owner.name.should == 'Mr. Pet Lover'
86
+ owner.pets[0].name.should == 'Jimmy'
87
+ owner.pets[0].species.should == 'Cocker Spainel'
88
+ owner.pets[1].name.should == 'Sasha'
89
+ owner.pets[1].species.should == 'Siberian Husky'
90
+
91
+ owner.save.should be_true
92
+ owner.reload
93
+
94
+ owner.name.should == 'Mr. Pet Lover'
95
+ owner.pets[0].name.should == 'Jimmy'
96
+ owner.pets[0].species.should == 'Cocker Spainel'
97
+ owner.pets[1].name.should == 'Sasha'
98
+ owner.pets[1].species.should == 'Siberian Husky'
99
+ end
100
+
101
+ context "embedding many embedded documents" do
102
+ setup do
103
+ @klass = Doc()
104
+ @klass.many :people, :class => @person_class
105
+ end
106
+
107
+ should "persist all embedded documents" do
108
+ meg = @person_class.new(:name => 'Meg', :pets => [
109
+ @pet_class.new(:name => 'Sparky', :species => 'Dog'),
110
+ @pet_class.new(:name => 'Koda', :species => 'Dog')
111
+ ])
112
+
113
+ doc = @klass.new
114
+ doc.people << meg
115
+ doc.save
116
+ doc.reload
117
+
118
+ doc.people.first.name.should == 'Meg'
119
+ doc.people.first.pets.should_not == []
120
+ doc.people.first.pets.first.name.should == 'Sparky'
121
+ doc.people.first.pets.first.species.should == 'Dog'
122
+ doc.people.first.pets[1].name.should == 'Koda'
123
+ doc.people.first.pets[1].species.should == 'Dog'
124
+ end
125
+
126
+ should "create a reference to the root document for all embedded documents before save" do
127
+ doc = @klass.new
128
+ meg = @person_class.new(:name => 'Meg')
129
+ pet = @pet_class.new(:name => 'Sparky', :species => 'Dog')
130
+
131
+ doc.people << meg
132
+ meg.pets << pet
133
+
134
+ doc.people.first._root_document.should == doc
135
+ doc.people.first.pets.first._root_document.should == doc
136
+ end
137
+ should "create a reference to the owning document for all embedded documents before save" do
138
+ doc = @klass.new
139
+ meg = @person_class.new(:name => 'Meg')
140
+ pet = @pet_class.new(:name => 'Sparky', :species => 'Dog')
141
+
142
+ doc.people << meg
143
+ meg.pets << pet
144
+
145
+ doc.people.first._parent_document.should == doc
146
+ doc.people.first.pets.first._parent_document.should == doc.people.first
147
+ end
148
+
149
+ should "create a reference to the root document for all embedded documents" do
150
+ sparky = @pet_class.new(:name => 'Sparky', :species => 'Dog')
151
+ meg = @person_class.new(:name => 'Meg', :pets => [sparky])
152
+ doc = @klass.new
153
+ doc.people << meg
154
+ doc.save
155
+
156
+ doc.reload
157
+ doc.people.first._root_document.should == doc
158
+ doc.people.first.pets.first._root_document.should == doc
159
+ end
160
+ should "create a reference to the owning document for all embedded documents" do
161
+ doc = @klass.new
162
+ meg = @person_class.new(:name => 'Meg')
163
+ pet = @pet_class.new(:name => 'Sparky', :species => 'Dog')
164
+
165
+ doc.people << meg
166
+ meg.pets << pet
167
+ doc.save
168
+
169
+ doc.reload
170
+ doc.people.first._parent_document.should == doc
171
+ doc.people.first.pets.first._parent_document.should == doc.people.first
172
+ end
173
+
174
+ should "create embedded_in relationship for embedded docs" do
175
+ doc = @klass.new
176
+ meg = @person_class.new(:name => 'Meg')
177
+ pet = @pet_class.new(:name => 'Sparky', :species => 'Dog')
178
+
179
+ doc.people << meg
180
+ meg.pets << pet
181
+ doc.save
182
+
183
+ doc.reload
184
+ doc.people.first.pets.first.person.should == doc.people.first
185
+ end
186
+ end
187
+
188
+ should "allow finding by id" do
189
+ sparky = @pet_class.new(:name => 'Sparky', :species => 'Dog')
190
+ meg = @owner_class.create(:name => 'Meg', :pets => [sparky])
191
+
192
+ meg.pets.find(sparky._id).should == sparky # oid
193
+ meg.pets.find(sparky.id.to_s).should == sparky # string
194
+ end
195
+
196
+ context "count" do
197
+ should "default to 0" do
198
+ @owner_class.new.pets.count.should == 0
199
+ end
200
+
201
+ should "return correct count if any are embedded" do
202
+ owner = @owner_class.new(:name => 'Meg')
203
+ owner.pets = [@pet_class.new, @pet_class.new]
204
+ owner.pets.count.should == 2
205
+ owner.save
206
+ owner.reload
207
+ owner.pets.count.should == 2
208
+ end
209
+ end
210
+
211
+ context "extending the association" do
212
+ setup do
213
+ @address_class = EDoc do
214
+ key :address, String
215
+ key :city, String
216
+ key :state, String
217
+ key :zip, Integer
218
+ end
219
+
220
+ @project_class = Doc do
221
+ key :name, String
222
+ end
223
+ end
224
+
225
+ should "work using a block passed to many" do
226
+ @project_class.many :addresses, :class => @address_class do
227
+ def find_all_by_state(state)
228
+ find_all { |a| a.state == state }
229
+ end
230
+ end
231
+
232
+ addr1 = @address_class.new(:address => "Gate-3 Lankershim Blvd.", :city => "Universal City", :state => "CA", :zip => "91608")
233
+ addr2 = @address_class.new(:address => "3000 W. Alameda Ave.", :city => "Burbank", :state => "CA", :zip => "91523")
234
+ addr3 = @address_class.new(:address => "111 Some Ln", :city => "Nashville", :state => "TN", :zip => "37211")
235
+ project = @project_class.create(:name => "Some Project", :addresses => [addr1, addr2, addr3])
236
+
237
+ project.addresses.find_all_by_state("CA").should == [addr1, addr2]
238
+ end
239
+
240
+ should "work using many's :extend option" do
241
+ module FindByCity
242
+ def find_by_city(city)
243
+ find_all { |a| a.city == city }
244
+ end
245
+ end
246
+ @project_class.many :addresses, :class => @address_class, :extend => FindByCity
247
+
248
+ addr1 = @address_class.new(:address => "Gate-3 Lankershim Blvd.", :city => "Universal City", :state => "CA", :zip => "91608")
249
+ addr2 = @address_class.new(:address => "3000 W. Alameda Ave.", :city => "Burbank", :state => "CA", :zip => "91523")
250
+ addr3 = @address_class.new(:address => "111 Some Ln", :city => "Nashville", :state => "TN", :zip => "37211")
251
+ project = @project_class.create(:name => "Some Project", :addresses => [addr1, addr2, addr3])
252
+
253
+ project.addresses.find_by_city('Burbank').should == [addr2]
254
+ end
255
+ end
256
+ end
@@ -0,0 +1,302 @@
1
+ require 'test_helper'
2
+ require 'models'
3
+
4
+ class ManyPolymorphicProxyTest < Test::Unit::TestCase
5
+ def setup
6
+ Room.collection.remove
7
+ Message.collection.remove
8
+ end
9
+
10
+ should "default reader to empty array" do
11
+ Room.new.messages.should == []
12
+ end
13
+
14
+ should "add type key to polymorphic class base" do
15
+ Message.keys.keys.should include('_type')
16
+ end
17
+
18
+ should "allow adding to assiciation like it was an array" do
19
+ room = Room.new
20
+ room.messages << Enter.new
21
+ room.messages.push Exit.new
22
+ room.messages.concat Exit.new
23
+ room.messages.size.should == 3
24
+ end
25
+
26
+ should "be able to replace the association" do
27
+ room = Room.create(:name => 'Lounge')
28
+
29
+ lambda {
30
+ room.messages = [
31
+ Enter.new(:body => 'John entered room', :position => 1),
32
+ Chat.new(:body => 'Heyyyoooo!', :position => 2),
33
+ Exit.new(:body => 'John exited room', :position => 3)
34
+ ]
35
+ }.should change { Message.count }.by(3)
36
+
37
+ room = room.reload
38
+ messages = room.messages.all :order => "position"
39
+ messages.size.should == 3
40
+ messages[0].body.should == 'John entered room'
41
+ messages[1].body.should == 'Heyyyoooo!'
42
+ messages[2].body.should == 'John exited room'
43
+ end
44
+
45
+ should "correctly store type when using <<, push and concat" do
46
+ room = Room.new
47
+ room.messages << Enter.new(:body => 'John entered the room', :position => 1)
48
+ room.messages.push Exit.new(:body => 'John entered the room', :position => 2)
49
+ room.messages.concat Chat.new(:body => 'Holla!' , :position => 3)
50
+
51
+ room = room.reload
52
+ messages = room.messages.all :order => "position"
53
+ messages[0]._type.should == 'Enter'
54
+ messages[1]._type.should == 'Exit'
55
+ messages[2]._type.should == 'Chat'
56
+ end
57
+
58
+ context "build" do
59
+ should "assign foreign key" do
60
+ room = Room.create
61
+ message = room.messages.build
62
+ message.room_id.should == room._id
63
+ end
64
+
65
+ should "assign _type" do
66
+ room = Room.create
67
+ message = room.messages.build
68
+ message._type.should == 'Message'
69
+ end
70
+
71
+ should "allow assigning attributes" do
72
+ room = Room.create
73
+ message = room.messages.build(:body => 'Foo!')
74
+ message.body.should == 'Foo!'
75
+ end
76
+ end
77
+
78
+ context "create" do
79
+ should "assign foreign key" do
80
+ room = Room.create
81
+ message = room.messages.create
82
+ message.room_id.should == room._id
83
+ end
84
+
85
+ should "assign _type" do
86
+ room = Room.create
87
+ message = room.messages.create
88
+ message._type.should == 'Message'
89
+ end
90
+
91
+ should "save record" do
92
+ room = Room.create
93
+ lambda {
94
+ room.messages.create
95
+ }.should change { Message.count }
96
+ end
97
+
98
+ should "allow passing attributes" do
99
+ room = Room.create
100
+ message = room.messages.create(:body => 'Foo!')
101
+ message.body.should == 'Foo!'
102
+ end
103
+ end
104
+
105
+ context "count" do
106
+ should "work scoped to association" do
107
+ room = Room.create
108
+ 3.times { room.messages.create }
109
+
110
+ other_room = Room.create
111
+ 2.times { other_room.messages.create }
112
+
113
+ room.messages.count.should == 3
114
+ other_room.messages.count.should == 2
115
+ end
116
+
117
+ should "work with conditions" do
118
+ room = Room.create
119
+ room.messages.create(:body => 'Foo')
120
+ room.messages.create(:body => 'Other 1')
121
+ room.messages.create(:body => 'Other 2')
122
+
123
+ room.messages.count(:body => 'Foo').should == 1
124
+ end
125
+ end
126
+
127
+ context "Finding scoped to association" do
128
+ setup do
129
+ @lounge = Room.create(:name => 'Lounge')
130
+ @lm1 = Message.create(:body => 'Loungin!', :position => 1)
131
+ @lm2 = Message.create(:body => 'I love loungin!', :position => 2)
132
+ @lounge.messages = [@lm1, @lm2]
133
+ @lounge.save
134
+
135
+ @hall = Room.create(:name => 'Hall')
136
+ @hm1 = Message.create(:body => 'Do not fall in the hall', :position => 1)
137
+ @hm3 = Message.create(:body => 'Loungin!', :position => 3)
138
+ @hm2 = Message.create(:body => 'Hall the king!', :position => 2)
139
+ @hall.messages = [@hm1, @hm2, @hm3]
140
+ @hall.save
141
+ end
142
+
143
+ context "dynamic finders" do
144
+ should "work with single key" do
145
+ @lounge.messages.find_by_position(1).should == @lm1
146
+ @hall.messages.find_by_position(2).should == @hm2
147
+ end
148
+
149
+ should "work with multiple keys" do
150
+ @lounge.messages.find_by_body_and_position('Loungin!', 1).should == @lm1
151
+ @lounge.messages.find_by_body_and_position('Loungin!', 2).should be_nil
152
+ end
153
+
154
+ should "raise error when using !" do
155
+ lambda {
156
+ @lounge.messages.find_by_position!(222)
157
+ }.should raise_error(MongoMapper::DocumentNotFound)
158
+ end
159
+
160
+ context "find_or_create_by" do
161
+ should "not create document if found" do
162
+ lambda {
163
+ message = @lounge.messages.find_or_create_by_body('Loungin!')
164
+ message.room.should == @lounge
165
+ message.should == @lm1
166
+ }.should_not change { Message.count }
167
+ end
168
+
169
+ should "create document if not found" do
170
+ lambda {
171
+ message = @lounge.messages.find_or_create_by_body('Yo dawg!')
172
+ message.room.should == @lounge
173
+ message._type.should == 'Message'
174
+ }.should change { Message.count }.by(1)
175
+ end
176
+ end
177
+ end
178
+
179
+ context "with #all" do
180
+ should "work" do
181
+ @lounge.messages.all(:order => "position").should == [@lm1, @lm2]
182
+ end
183
+
184
+ should "work with conditions" do
185
+ messages = @lounge.messages.all(:body => 'Loungin!', :order => "position")
186
+ messages.should == [@lm1]
187
+ end
188
+
189
+ should "work with order" do
190
+ messages = @lounge.messages.all(:order => 'position desc')
191
+ messages.should == [@lm2, @lm1]
192
+ end
193
+ end
194
+
195
+ context "with #first" do
196
+ should "work" do
197
+ @lounge.messages.first(:order => "position asc").should == @lm1
198
+ end
199
+
200
+ should "work with conditions" do
201
+ message = @lounge.messages.first(:body => 'I love loungin!', :order => "position asc")
202
+ message.should == @lm2
203
+ end
204
+ end
205
+
206
+ context "with #last" do
207
+ should "work" do
208
+ @lounge.messages.last(:order => "position asc").should == @lm2
209
+ end
210
+
211
+ should "work with conditions" do
212
+ message = @lounge.messages.last(:body => 'Loungin!', :order => "position asc")
213
+ message.should == @lm1
214
+ end
215
+ end
216
+
217
+ context "with one id" do
218
+ should "work for id in association" do
219
+ @lounge.messages.find(@lm2._id).should == @lm2
220
+ end
221
+
222
+ should "not work for id not in association" do
223
+ lambda {
224
+ @lounge.messages.find!(@hm2._id)
225
+ }.should raise_error(MongoMapper::DocumentNotFound)
226
+ end
227
+ end
228
+
229
+ context "with query options/criteria" do
230
+ should "work with order on association" do
231
+ @lounge.messages.should == [@lm1, @lm2]
232
+ end
233
+
234
+ should "allow overriding the order provided to the association" do
235
+ @lounge.messages.all(:order => 'position').should == [@lm1, @lm2]
236
+ end
237
+
238
+ should "allow using conditions on association" do
239
+ @hall.latest_messages.should == [@hm3, @hm2]
240
+ end
241
+ end
242
+
243
+ context "with multiple ids" do
244
+ should "work for ids in association" do
245
+ messages = @lounge.messages.find(@lm1._id, @lm2._id)
246
+ messages.should == [@lm1, @lm2]
247
+ end
248
+
249
+ should "not work for ids not in association" do
250
+ assert_raises(MongoMapper::DocumentNotFound) do
251
+ @lounge.messages.find!(@lm1._id, @lm2._id, @hm2._id)
252
+ end
253
+ end
254
+ end
255
+
256
+ context "with #paginate" do
257
+ setup do
258
+ @messages = @hall.messages.paginate(:per_page => 2, :page => 1, :order => 'position asc')
259
+ end
260
+
261
+ should "return total pages" do
262
+ @messages.total_pages.should == 2
263
+ end
264
+
265
+ should "return total entries" do
266
+ @messages.total_entries.should == 3
267
+ end
268
+
269
+ should "return the subject" do
270
+ @messages.should == [@hm1, @hm2]
271
+ end
272
+ end
273
+ end
274
+
275
+ context "extending the association" do
276
+ should "work using a block passed to many" do
277
+ room = Room.new(:name => "Amazing Room")
278
+ messages = room.messages = [
279
+ Enter.new(:body => 'John entered room', :position => 3),
280
+ Chat.new(:body => 'Heyyyoooo!', :position => 4),
281
+ Exit.new(:body => 'John exited room', :position => 5),
282
+ Enter.new(:body => 'Steve entered room', :position => 6),
283
+ Chat.new(:body => 'Anyone there?', :position => 7),
284
+ Exit.new(:body => 'Steve exited room', :position => 8)
285
+ ]
286
+ room.save
287
+ room.messages.older.should == messages[3..5]
288
+ end
289
+
290
+ should "work using many's :extend option" do
291
+
292
+ room = Room.new(:name => "Amazing Room")
293
+ accounts = room.accounts = [
294
+ Bot.new(:last_logged_in => 3.weeks.ago),
295
+ AccountUser.new(:last_logged_in => nil),
296
+ Bot.new(:last_logged_in => 1.week.ago)
297
+ ]
298
+ room.save
299
+ room.accounts.inactive.should == [accounts[1]]
300
+ end
301
+ end
302
+ end