mongo_mapper-unstable 2009.10.16 → 2009.10.31
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/.gitignore +3 -1
- data/README.rdoc +3 -0
- data/Rakefile +31 -65
- data/VERSION +1 -1
- data/lib/mongo_mapper/associations/base.rb +31 -4
- data/lib/mongo_mapper/associations/many_documents_as_proxy.rb +0 -2
- data/lib/mongo_mapper/associations/many_documents_proxy.rb +21 -15
- data/lib/mongo_mapper/associations/many_embedded_polymorphic_proxy.rb +2 -2
- data/lib/mongo_mapper/associations/many_embedded_proxy.rb +21 -36
- data/lib/mongo_mapper/associations/many_polymorphic_proxy.rb +1 -1
- data/lib/mongo_mapper/associations/proxy.rb +1 -0
- data/lib/mongo_mapper/associations.rb +114 -17
- data/lib/mongo_mapper/callbacks.rb +18 -0
- data/lib/mongo_mapper/document.rb +230 -95
- data/lib/mongo_mapper/dynamic_finder.rb +1 -1
- data/lib/mongo_mapper/embedded_document.rb +7 -3
- data/lib/mongo_mapper/finder_options.rb +88 -56
- data/lib/mongo_mapper/pagination.rb +2 -0
- data/lib/mongo_mapper/serialization.rb +2 -3
- data/lib/mongo_mapper/serializers/json_serializer.rb +1 -1
- data/lib/mongo_mapper/support.rb +9 -0
- data/lib/mongo_mapper/validations.rb +14 -42
- data/lib/mongo_mapper.rb +15 -13
- data/mongo_mapper.gemspec +13 -13
- data/specs.watchr +2 -2
- data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +5 -5
- data/test/functional/associations/test_belongs_to_proxy.rb +28 -30
- data/test/functional/associations/test_many_documents_as_proxy.rb +4 -4
- data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +27 -3
- data/test/functional/associations/test_many_embedded_proxy.rb +58 -38
- data/test/functional/associations/test_many_polymorphic_proxy.rb +49 -7
- data/test/functional/associations/test_many_proxy.rb +65 -15
- data/test/functional/test_associations.rb +3 -3
- data/test/functional/test_binary.rb +1 -1
- data/test/functional/test_callbacks.rb +1 -1
- data/test/functional/test_dirty.rb +3 -3
- data/test/functional/test_document.rb +178 -57
- data/test/functional/test_embedded_document.rb +1 -1
- data/test/functional/test_pagination.rb +18 -18
- data/test/functional/test_rails_compatibility.rb +1 -1
- data/test/functional/test_validations.rb +80 -27
- data/test/models.rb +93 -17
- data/test/support/{test_timing.rb → timing.rb} +1 -1
- data/test/test_helper.rb +8 -11
- data/test/unit/test_association_base.rb +23 -1
- data/test/unit/test_document.rb +29 -12
- data/test/unit/test_embedded_document.rb +13 -4
- data/test/unit/test_finder_options.rb +74 -58
- data/test/unit/test_mongomapper.rb +2 -2
- data/test/unit/test_pagination.rb +4 -0
- metadata +7 -7
@@ -3,8 +3,8 @@ require 'models'
|
|
3
3
|
|
4
4
|
class ManyEmbeddedProxyTest < Test::Unit::TestCase
|
5
5
|
def setup
|
6
|
-
Project.collection.
|
7
|
-
RealPerson.collection.
|
6
|
+
Project.collection.remove
|
7
|
+
RealPerson.collection.remove
|
8
8
|
end
|
9
9
|
|
10
10
|
should "default reader to empty array" do
|
@@ -17,13 +17,6 @@ class ManyEmbeddedProxyTest < Test::Unit::TestCase
|
|
17
17
|
project.addresses.push Address.new
|
18
18
|
project.addresses.size.should == 2
|
19
19
|
end
|
20
|
-
|
21
|
-
should "allow finding :all embedded documents" do
|
22
|
-
project = Project.new
|
23
|
-
project.addresses << Address.new
|
24
|
-
project.addresses << Address.new
|
25
|
-
project.save
|
26
|
-
end
|
27
20
|
|
28
21
|
should "be embedded in document on save" do
|
29
22
|
sb = Address.new(:city => 'South Bend', :state => 'IN')
|
@@ -45,7 +38,7 @@ class ManyEmbeddedProxyTest < Test::Unit::TestCase
|
|
45
38
|
set_collection_name 'test'
|
46
39
|
key :person, Person
|
47
40
|
end
|
48
|
-
@document.collection.
|
41
|
+
@document.collection.remove
|
49
42
|
|
50
43
|
meg = Person.new(:name => "Meg")
|
51
44
|
meg.child = Person.new(:name => "Steve")
|
@@ -92,7 +85,7 @@ class ManyEmbeddedProxyTest < Test::Unit::TestCase
|
|
92
85
|
set_collection_name 'test'
|
93
86
|
many :people
|
94
87
|
end
|
95
|
-
@document.collection.
|
88
|
+
@document.collection.remove
|
96
89
|
end
|
97
90
|
|
98
91
|
should "persist all embedded documents" do
|
@@ -130,45 +123,72 @@ class ManyEmbeddedProxyTest < Test::Unit::TestCase
|
|
130
123
|
doc.people.first.pets.first._root_document.should == doc
|
131
124
|
end
|
132
125
|
|
133
|
-
should "create properly-named reference to parent document when building off association proxy" do
|
134
|
-
person = RealPerson.new
|
135
|
-
pet = person.pets.build
|
136
|
-
person.should == pet.real_person
|
137
|
-
end
|
138
|
-
|
139
|
-
|
140
126
|
should "create a reference to the root document for all embedded documents" do
|
141
|
-
meg = Person.new(:name => "Meg")
|
142
127
|
sparky = Pet.new(:name => "Sparky", :species => "Dog")
|
143
|
-
|
128
|
+
meg = Person.new(:name => "Meg", :pets => [sparky])
|
144
129
|
doc = @document.new
|
145
|
-
|
146
|
-
meg.pets << sparky
|
147
|
-
|
148
130
|
doc.people << meg
|
149
131
|
doc.save
|
150
132
|
|
151
|
-
|
152
|
-
|
153
|
-
|
133
|
+
doc = doc.reload
|
134
|
+
doc.people.first._root_document.should == doc
|
135
|
+
doc.people.first.pets.first._root_document.should == doc
|
154
136
|
end
|
155
137
|
end
|
156
138
|
|
157
|
-
should "allow
|
158
|
-
meg = Person.new(:name => "Meg")
|
139
|
+
should "allow finding by id" do
|
159
140
|
sparky = Pet.new(:name => "Sparky", :species => "Dog")
|
160
|
-
|
161
|
-
meg.pets
|
162
|
-
|
163
|
-
meg.pets.find(:all).should include(sparky)
|
141
|
+
meg = Person.new(:name => "Meg", :pets => [sparky])
|
142
|
+
meg.pets.find(sparky.id).should == sparky
|
164
143
|
end
|
165
144
|
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
145
|
+
context "extending the association" do
|
146
|
+
setup do
|
147
|
+
@address_class = Class.new do
|
148
|
+
include MongoMapper::EmbeddedDocument
|
149
|
+
key :address, String
|
150
|
+
key :city, String
|
151
|
+
key :state, String
|
152
|
+
key :zip, Integer
|
153
|
+
end
|
154
|
+
|
155
|
+
@project_class = Class.new do
|
156
|
+
include MongoMapper::Document
|
157
|
+
key :name, String
|
158
|
+
end
|
159
|
+
|
160
|
+
@project_class.collection.remove
|
161
|
+
end
|
171
162
|
|
172
|
-
|
163
|
+
should "work using a block passed to many" do
|
164
|
+
@project_class.many :addresses, :class => @address_class do
|
165
|
+
def find_all_by_state(state)
|
166
|
+
find_all { |a| a.state == state }
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
addr1 = @address_class.new(:address => "Gate-3 Lankershim Blvd.", :city => "Universal City", :state => "CA", :zip => "91608")
|
171
|
+
addr2 = @address_class.new(:address => "3000 W. Alameda Ave.", :city => "Burbank", :state => "CA", :zip => "91523")
|
172
|
+
addr3 = @address_class.new(:address => "111 Some Ln", :city => "Nashville", :state => "TN", :zip => "37211")
|
173
|
+
project = @project_class.create(:name => "Some Project", :addresses => [addr1, addr2, addr3])
|
174
|
+
|
175
|
+
project.addresses.find_all_by_state("CA").should == [addr1, addr2]
|
176
|
+
end
|
177
|
+
|
178
|
+
should "work using many's :extend option" do
|
179
|
+
module FindByCity
|
180
|
+
def find_by_city(city)
|
181
|
+
find_all { |a| a.city == city }
|
182
|
+
end
|
183
|
+
end
|
184
|
+
@project_class.many :addresses, :class => @address_class, :extend => FindByCity
|
185
|
+
|
186
|
+
addr1 = @address_class.new(:address => "Gate-3 Lankershim Blvd.", :city => "Universal City", :state => "CA", :zip => "91608")
|
187
|
+
addr2 = @address_class.new(:address => "3000 W. Alameda Ave.", :city => "Burbank", :state => "CA", :zip => "91523")
|
188
|
+
addr3 = @address_class.new(:address => "111 Some Ln", :city => "Nashville", :state => "TN", :zip => "37211")
|
189
|
+
project = @project_class.create(:name => "Some Project", :addresses => [addr1, addr2, addr3])
|
190
|
+
|
191
|
+
project.addresses.find_by_city('Burbank').should == [addr2]
|
192
|
+
end
|
173
193
|
end
|
174
194
|
end
|
@@ -3,7 +3,8 @@ require 'models'
|
|
3
3
|
|
4
4
|
class ManyPolymorphicProxyTest < Test::Unit::TestCase
|
5
5
|
def setup
|
6
|
-
Room.collection.
|
6
|
+
Room.collection.remove
|
7
|
+
Message.collection.remove
|
7
8
|
end
|
8
9
|
|
9
10
|
should "default reader to empty array" do
|
@@ -181,7 +182,7 @@ class ManyPolymorphicProxyTest < Test::Unit::TestCase
|
|
181
182
|
end
|
182
183
|
|
183
184
|
should "work with conditions" do
|
184
|
-
messages = @lounge.messages.find(:all, :
|
185
|
+
messages = @lounge.messages.find(:all, :body => 'Loungin!', :order => "position")
|
185
186
|
messages.should == [@lm1]
|
186
187
|
end
|
187
188
|
|
@@ -197,7 +198,7 @@ class ManyPolymorphicProxyTest < Test::Unit::TestCase
|
|
197
198
|
end
|
198
199
|
|
199
200
|
should "work with conditions" do
|
200
|
-
messages = @lounge.messages.all(:
|
201
|
+
messages = @lounge.messages.all(:body => 'Loungin!', :order => "position")
|
201
202
|
messages.should == [@lm1]
|
202
203
|
end
|
203
204
|
|
@@ -213,7 +214,7 @@ class ManyPolymorphicProxyTest < Test::Unit::TestCase
|
|
213
214
|
end
|
214
215
|
|
215
216
|
should "work with conditions" do
|
216
|
-
message = @lounge.messages.find(:first, :
|
217
|
+
message = @lounge.messages.find(:first, :body => 'I love loungin!', :order => "position asc")
|
217
218
|
message.should == @lm2
|
218
219
|
end
|
219
220
|
end
|
@@ -224,7 +225,7 @@ class ManyPolymorphicProxyTest < Test::Unit::TestCase
|
|
224
225
|
end
|
225
226
|
|
226
227
|
should "work with conditions" do
|
227
|
-
message = @lounge.messages.first(:
|
228
|
+
message = @lounge.messages.first(:body => 'I love loungin!', :order => "position asc")
|
228
229
|
message.should == @lm2
|
229
230
|
end
|
230
231
|
end
|
@@ -235,7 +236,7 @@ class ManyPolymorphicProxyTest < Test::Unit::TestCase
|
|
235
236
|
end
|
236
237
|
|
237
238
|
should "work with conditions" do
|
238
|
-
message = @lounge.messages.find(:last, :
|
239
|
+
message = @lounge.messages.find(:last, :body => 'Loungin!', :order => "position asc")
|
239
240
|
message.should == @lm1
|
240
241
|
end
|
241
242
|
end
|
@@ -246,7 +247,7 @@ class ManyPolymorphicProxyTest < Test::Unit::TestCase
|
|
246
247
|
end
|
247
248
|
|
248
249
|
should "work with conditions" do
|
249
|
-
message = @lounge.messages.last(:
|
250
|
+
message = @lounge.messages.last(:body => 'Loungin!', :order => "position asc")
|
250
251
|
message.should == @lm1
|
251
252
|
end
|
252
253
|
end
|
@@ -263,6 +264,20 @@ class ManyPolymorphicProxyTest < Test::Unit::TestCase
|
|
263
264
|
end
|
264
265
|
end
|
265
266
|
|
267
|
+
context "with query options/criteria" do
|
268
|
+
should "work with order on association" do
|
269
|
+
@lounge.messages.should == [@lm1, @lm2]
|
270
|
+
end
|
271
|
+
|
272
|
+
should "allow overriding the order provided to the association" do
|
273
|
+
@lounge.messages.all(:order => 'position desc').should == [@lm2, @lm1]
|
274
|
+
end
|
275
|
+
|
276
|
+
should "allow using conditions on association" do
|
277
|
+
@hall.latest_messages.should == [@hm3, @hm2]
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
266
281
|
context "with multiple ids" do
|
267
282
|
should "work for ids in association" do
|
268
283
|
messages = @lounge.messages.find(@lm1.id, @lm2.id)
|
@@ -294,4 +309,31 @@ class ManyPolymorphicProxyTest < Test::Unit::TestCase
|
|
294
309
|
end
|
295
310
|
end
|
296
311
|
end
|
312
|
+
|
313
|
+
context "extending the association" do
|
314
|
+
should "work using a block passed to many" do
|
315
|
+
room = Room.new(:name => "Amazing Room")
|
316
|
+
messages = room.messages = [
|
317
|
+
Enter.new(:body => 'John entered room', :position => 3),
|
318
|
+
Chat.new(:body => 'Heyyyoooo!', :position => 4),
|
319
|
+
Exit.new(:body => 'John exited room', :position => 5),
|
320
|
+
Enter.new(:body => 'Steve entered room', :position => 6),
|
321
|
+
Chat.new(:body => 'Anyone there?', :position => 7),
|
322
|
+
Exit.new(:body => 'Steve exited room', :position => 8)
|
323
|
+
]
|
324
|
+
room.save
|
325
|
+
room.messages.older.should == messages[3..5]
|
326
|
+
end
|
327
|
+
|
328
|
+
should "work using many's :extend option" do
|
329
|
+
room = Room.new(:name => "Amazing Room")
|
330
|
+
accounts = room.accounts = [
|
331
|
+
Bot.new(:last_logged_in => 3.weeks.ago),
|
332
|
+
User.new(:last_logged_in => nil),
|
333
|
+
Bot.new(:last_logged_in => 1.week.ago)
|
334
|
+
]
|
335
|
+
room.save
|
336
|
+
room.accounts.inactive.should == [accounts[1]]
|
337
|
+
end
|
338
|
+
end
|
297
339
|
end
|
@@ -3,8 +3,8 @@ require 'models'
|
|
3
3
|
|
4
4
|
class ManyProxyTest < Test::Unit::TestCase
|
5
5
|
def setup
|
6
|
-
Project.collection.
|
7
|
-
Status.collection.
|
6
|
+
Project.collection.remove
|
7
|
+
Status.collection.remove
|
8
8
|
end
|
9
9
|
|
10
10
|
should "default reader to empty array" do
|
@@ -14,9 +14,9 @@ class ManyProxyTest < Test::Unit::TestCase
|
|
14
14
|
|
15
15
|
should "allow adding to association like it was an array" do
|
16
16
|
project = Project.new
|
17
|
-
project.statuses << Status.new
|
18
|
-
project.statuses.push Status.new
|
19
|
-
project.statuses.concat Status.new
|
17
|
+
project.statuses << Status.new(:name => 'Foo1!')
|
18
|
+
project.statuses.push Status.new(:name => 'Foo2!')
|
19
|
+
project.statuses.concat Status.new(:name => 'Foo3!')
|
20
20
|
project.statuses.size.should == 3
|
21
21
|
end
|
22
22
|
|
@@ -59,14 +59,14 @@ class ManyProxyTest < Test::Unit::TestCase
|
|
59
59
|
context "create" do
|
60
60
|
should "assign foreign key" do
|
61
61
|
project = Project.create
|
62
|
-
status = project.statuses.create
|
62
|
+
status = project.statuses.create(:name => 'Foo!')
|
63
63
|
status.project_id.should == project.id
|
64
64
|
end
|
65
65
|
|
66
66
|
should "save record" do
|
67
67
|
project = Project.create
|
68
68
|
lambda {
|
69
|
-
project.statuses.create
|
69
|
+
project.statuses.create(:name => 'Foo!')
|
70
70
|
}.should change { Status.count }
|
71
71
|
end
|
72
72
|
|
@@ -77,13 +77,42 @@ class ManyProxyTest < Test::Unit::TestCase
|
|
77
77
|
end
|
78
78
|
end
|
79
79
|
|
80
|
+
context "create!" do
|
81
|
+
should "assign foreign key" do
|
82
|
+
project = Project.create
|
83
|
+
status = project.statuses.create!(:name => 'Foo!')
|
84
|
+
status.project_id.should == project.id
|
85
|
+
end
|
86
|
+
|
87
|
+
should "save record" do
|
88
|
+
project = Project.create
|
89
|
+
lambda {
|
90
|
+
project.statuses.create!(:name => 'Foo!')
|
91
|
+
}.should change { Status.count }
|
92
|
+
end
|
93
|
+
|
94
|
+
should "allow passing attributes" do
|
95
|
+
project = Project.create
|
96
|
+
status = project.statuses.create!(:name => 'Foo!')
|
97
|
+
status.name.should == 'Foo!'
|
98
|
+
end
|
99
|
+
|
100
|
+
should "raise exception if not valid" do
|
101
|
+
project = Project.create
|
102
|
+
lambda {
|
103
|
+
project.statuses.create!(:name => nil)
|
104
|
+
}.should raise_error(MongoMapper::DocumentNotValid)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
|
80
109
|
context "count" do
|
81
110
|
should "work scoped to association" do
|
82
111
|
project = Project.create
|
83
|
-
3.times { project.statuses.create }
|
112
|
+
3.times { project.statuses.create(:name => 'Foo!') }
|
84
113
|
|
85
114
|
other_project = Project.create
|
86
|
-
2.times { other_project.statuses.create }
|
115
|
+
2.times { other_project.statuses.create(:name => 'Foo!') }
|
87
116
|
|
88
117
|
project.statuses.count.should == 3
|
89
118
|
other_project.statuses.count.should == 2
|
@@ -215,7 +244,7 @@ class ManyProxyTest < Test::Unit::TestCase
|
|
215
244
|
end
|
216
245
|
|
217
246
|
should "work with conditions" do
|
218
|
-
statuses = @project1.statuses.find(:all, :
|
247
|
+
statuses = @project1.statuses.find(:all, :name => 'Complete')
|
219
248
|
statuses.should == [@complete]
|
220
249
|
end
|
221
250
|
|
@@ -231,7 +260,7 @@ class ManyProxyTest < Test::Unit::TestCase
|
|
231
260
|
end
|
232
261
|
|
233
262
|
should "work with conditions" do
|
234
|
-
statuses = @project1.statuses.all(:
|
263
|
+
statuses = @project1.statuses.all(:name => 'Complete')
|
235
264
|
statuses.should == [@complete]
|
236
265
|
end
|
237
266
|
|
@@ -247,7 +276,7 @@ class ManyProxyTest < Test::Unit::TestCase
|
|
247
276
|
end
|
248
277
|
|
249
278
|
should "work with conditions" do
|
250
|
-
status = @project1.statuses.find(:first, :
|
279
|
+
status = @project1.statuses.find(:first, :name => 'Complete')
|
251
280
|
status.should == @complete
|
252
281
|
end
|
253
282
|
end
|
@@ -258,7 +287,7 @@ class ManyProxyTest < Test::Unit::TestCase
|
|
258
287
|
end
|
259
288
|
|
260
289
|
should "work with conditions" do
|
261
|
-
status = @project1.statuses.first(:
|
290
|
+
status = @project1.statuses.first(:name => 'Complete')
|
262
291
|
status.should == @complete
|
263
292
|
end
|
264
293
|
end
|
@@ -269,7 +298,7 @@ class ManyProxyTest < Test::Unit::TestCase
|
|
269
298
|
end
|
270
299
|
|
271
300
|
should "work with conditions" do
|
272
|
-
status = @project1.statuses.find(:last, :order => 'position', :
|
301
|
+
status = @project1.statuses.find(:last, :order => 'position', :name => 'New')
|
273
302
|
status.should == @brand_new
|
274
303
|
end
|
275
304
|
end
|
@@ -280,7 +309,7 @@ class ManyProxyTest < Test::Unit::TestCase
|
|
280
309
|
end
|
281
310
|
|
282
311
|
should "work with conditions" do
|
283
|
-
status = @project1.statuses.last(:order => 'position', :
|
312
|
+
status = @project1.statuses.last(:order => 'position', :name => 'New')
|
284
313
|
status.should == @brand_new
|
285
314
|
end
|
286
315
|
end
|
@@ -328,4 +357,25 @@ class ManyProxyTest < Test::Unit::TestCase
|
|
328
357
|
end
|
329
358
|
end
|
330
359
|
end
|
360
|
+
|
361
|
+
context "extending the association" do
|
362
|
+
should "work using a block passed to many" do
|
363
|
+
project = Project.new(:name => "Some Project")
|
364
|
+
status1 = Status.new(:name => "New")
|
365
|
+
status2 = Status.new(:name => "Assigned")
|
366
|
+
status3 = Status.new(:name => "Closed")
|
367
|
+
project.statuses = [status1, status2, status3]
|
368
|
+
project.save
|
369
|
+
project.statuses.open.should == [status1, status2]
|
370
|
+
end
|
371
|
+
|
372
|
+
should "work using many's :extend option" do
|
373
|
+
project = Project.new(:name => "Some Project")
|
374
|
+
collaborator1 = Collaborator.new(:name => "zing")
|
375
|
+
collaborator2 = Collaborator.new(:name => "zang")
|
376
|
+
project.collaborators = [collaborator1, collaborator2]
|
377
|
+
project.save
|
378
|
+
project.collaborators.top.should == collaborator1
|
379
|
+
end
|
380
|
+
end
|
331
381
|
end
|
@@ -8,7 +8,7 @@ class AssociationsTest < Test::Unit::TestCase
|
|
8
8
|
|
9
9
|
many :posts, :class_name => 'AssociationsTest::AwesomePost', :foreign_key => :creator_id
|
10
10
|
end
|
11
|
-
AwesomeUser.collection.
|
11
|
+
AwesomeUser.collection.remove
|
12
12
|
|
13
13
|
class AwesomeTag
|
14
14
|
include MongoMapper::EmbeddedDocument
|
@@ -28,8 +28,8 @@ class AssociationsTest < Test::Unit::TestCase
|
|
28
28
|
many :tags, :class_name => 'AssociationsTest::AwesomeTag', :foreign_key => :post_id
|
29
29
|
end
|
30
30
|
|
31
|
-
AwesomeUser.collection.
|
32
|
-
AwesomePost.collection.
|
31
|
+
AwesomeUser.collection.remove
|
32
|
+
AwesomePost.collection.remove
|
33
33
|
|
34
34
|
user = AwesomeUser.create
|
35
35
|
tag1 = AwesomeTag.new(:name => 'awesome')
|
@@ -8,10 +8,10 @@ class DirtyTest < Test::Unit::TestCase
|
|
8
8
|
set_collection_name 'test'
|
9
9
|
key :phrase, String
|
10
10
|
end
|
11
|
-
@document.collection.
|
11
|
+
@document.collection.remove
|
12
12
|
|
13
|
-
Status.collection.
|
14
|
-
Project.collection.
|
13
|
+
Status.collection.remove
|
14
|
+
Project.collection.remove
|
15
15
|
end
|
16
16
|
|
17
17
|
context "marking changes" do
|