mongoid-versioning 0.1.0

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 (195) hide show
  1. data/.gitignore +25 -0
  2. data/CHANGELOG.md +2 -0
  3. data/Gemfile +7 -0
  4. data/README.md +73 -0
  5. data/Rakefile +7 -0
  6. data/lib/mongoid/versioning.rb +217 -0
  7. data/lib/mongoid/versioning/version.rb +5 -0
  8. data/mongoid-versioning.gemspec +18 -0
  9. data/spec/app/models/account.rb +32 -0
  10. data/spec/app/models/acolyte.rb +16 -0
  11. data/spec/app/models/actor.rb +19 -0
  12. data/spec/app/models/actor_observer.rb +15 -0
  13. data/spec/app/models/actress.rb +2 -0
  14. data/spec/app/models/address.rb +72 -0
  15. data/spec/app/models/address_component.rb +5 -0
  16. data/spec/app/models/address_number.rb +6 -0
  17. data/spec/app/models/agency.rb +5 -0
  18. data/spec/app/models/agent.rb +12 -0
  19. data/spec/app/models/album.rb +14 -0
  20. data/spec/app/models/alert.rb +5 -0
  21. data/spec/app/models/animal.rb +25 -0
  22. data/spec/app/models/answer.rb +4 -0
  23. data/spec/app/models/appointment.rb +7 -0
  24. data/spec/app/models/article.rb +13 -0
  25. data/spec/app/models/artist.rb +66 -0
  26. data/spec/app/models/artwork.rb +4 -0
  27. data/spec/app/models/augmentation.rb +11 -0
  28. data/spec/app/models/author.rb +6 -0
  29. data/spec/app/models/band.rb +25 -0
  30. data/spec/app/models/bar.rb +9 -0
  31. data/spec/app/models/basic.rb +6 -0
  32. data/spec/app/models/bed.rb +1 -0
  33. data/spec/app/models/big_palette.rb +2 -0
  34. data/spec/app/models/birthday.rb +13 -0
  35. data/spec/app/models/book.rb +12 -0
  36. data/spec/app/models/breed.rb +4 -0
  37. data/spec/app/models/browser.rb +6 -0
  38. data/spec/app/models/building.rb +7 -0
  39. data/spec/app/models/building_address.rb +7 -0
  40. data/spec/app/models/bus.rb +7 -0
  41. data/spec/app/models/business.rb +5 -0
  42. data/spec/app/models/callback_recorder.rb +25 -0
  43. data/spec/app/models/callback_test.rb +9 -0
  44. data/spec/app/models/canvas.rb +25 -0
  45. data/spec/app/models/car.rb +1 -0
  46. data/spec/app/models/cat.rb +8 -0
  47. data/spec/app/models/category.rb +8 -0
  48. data/spec/app/models/child.rb +4 -0
  49. data/spec/app/models/child_doc.rb +22 -0
  50. data/spec/app/models/church.rb +4 -0
  51. data/spec/app/models/circle.rb +3 -0
  52. data/spec/app/models/circuit.rb +4 -0
  53. data/spec/app/models/circus.rb +7 -0
  54. data/spec/app/models/code.rb +5 -0
  55. data/spec/app/models/comment.rb +16 -0
  56. data/spec/app/models/contractor.rb +7 -0
  57. data/spec/app/models/cookie.rb +6 -0
  58. data/spec/app/models/country_code.rb +8 -0
  59. data/spec/app/models/definition.rb +7 -0
  60. data/spec/app/models/description.rb +11 -0
  61. data/spec/app/models/dictionary.rb +10 -0
  62. data/spec/app/models/division.rb +10 -0
  63. data/spec/app/models/doctor.rb +12 -0
  64. data/spec/app/models/dog.rb +6 -0
  65. data/spec/app/models/dokument.rb +5 -0
  66. data/spec/app/models/driver.rb +7 -0
  67. data/spec/app/models/drug.rb +8 -0
  68. data/spec/app/models/email.rb +6 -0
  69. data/spec/app/models/employer.rb +5 -0
  70. data/spec/app/models/entry.rb +6 -0
  71. data/spec/app/models/eraser.rb +1 -0
  72. data/spec/app/models/event.rb +22 -0
  73. data/spec/app/models/exhibition.rb +4 -0
  74. data/spec/app/models/exhibitor.rb +5 -0
  75. data/spec/app/models/eye.rb +9 -0
  76. data/spec/app/models/eye_bowl.rb +9 -0
  77. data/spec/app/models/face.rb +8 -0
  78. data/spec/app/models/favorite.rb +6 -0
  79. data/spec/app/models/filesystem.rb +4 -0
  80. data/spec/app/models/firefox.rb +4 -0
  81. data/spec/app/models/fish.rb +8 -0
  82. data/spec/app/models/folder.rb +7 -0
  83. data/spec/app/models/folder_item.rb +9 -0
  84. data/spec/app/models/fruits.rb +28 -0
  85. data/spec/app/models/game.rb +21 -0
  86. data/spec/app/models/ghost.rb +7 -0
  87. data/spec/app/models/home.rb +4 -0
  88. data/spec/app/models/house.rb +8 -0
  89. data/spec/app/models/html_writer.rb +3 -0
  90. data/spec/app/models/image.rb +22 -0
  91. data/spec/app/models/implant.rb +16 -0
  92. data/spec/app/models/item.rb +12 -0
  93. data/spec/app/models/jar.rb +7 -0
  94. data/spec/app/models/label.rb +40 -0
  95. data/spec/app/models/language.rb +5 -0
  96. data/spec/app/models/lat_lng.rb +15 -0
  97. data/spec/app/models/league.rb +11 -0
  98. data/spec/app/models/learner.rb +2 -0
  99. data/spec/app/models/line_item.rb +6 -0
  100. data/spec/app/models/location.rb +8 -0
  101. data/spec/app/models/login.rb +8 -0
  102. data/spec/app/models/manufacturer.rb +7 -0
  103. data/spec/app/models/meat.rb +4 -0
  104. data/spec/app/models/membership.rb +4 -0
  105. data/spec/app/models/mixed_drink.rb +4 -0
  106. data/spec/app/models/movie.rb +12 -0
  107. data/spec/app/models/my_hash.rb +2 -0
  108. data/spec/app/models/name.rb +23 -0
  109. data/spec/app/models/node.rb +5 -0
  110. data/spec/app/models/note.rb +12 -0
  111. data/spec/app/models/ordered_post.rb +6 -0
  112. data/spec/app/models/ordered_preference.rb +6 -0
  113. data/spec/app/models/oscar.rb +15 -0
  114. data/spec/app/models/override.rb +16 -0
  115. data/spec/app/models/ownable.rb +6 -0
  116. data/spec/app/models/owner.rb +6 -0
  117. data/spec/app/models/page.rb +5 -0
  118. data/spec/app/models/page_question.rb +4 -0
  119. data/spec/app/models/palette.rb +7 -0
  120. data/spec/app/models/paranoid_phone.rb +25 -0
  121. data/spec/app/models/paranoid_post.rb +36 -0
  122. data/spec/app/models/parent.rb +5 -0
  123. data/spec/app/models/parent_doc.rb +6 -0
  124. data/spec/app/models/passport.rb +5 -0
  125. data/spec/app/models/patient.rb +9 -0
  126. data/spec/app/models/pdf_writer.rb +3 -0
  127. data/spec/app/models/pencil.rb +1 -0
  128. data/spec/app/models/person.rb +200 -0
  129. data/spec/app/models/pet.rb +23 -0
  130. data/spec/app/models/pet_owner.rb +6 -0
  131. data/spec/app/models/phone.rb +11 -0
  132. data/spec/app/models/phone_observer.rb +6 -0
  133. data/spec/app/models/pizza.rb +7 -0
  134. data/spec/app/models/player.rb +35 -0
  135. data/spec/app/models/post.rb +42 -0
  136. data/spec/app/models/powerup.rb +11 -0
  137. data/spec/app/models/preference.rb +9 -0
  138. data/spec/app/models/princess.rb +8 -0
  139. data/spec/app/models/product.rb +15 -0
  140. data/spec/app/models/profile.rb +5 -0
  141. data/spec/app/models/pronunciation.rb +5 -0
  142. data/spec/app/models/purchase.rb +4 -0
  143. data/spec/app/models/question.rb +8 -0
  144. data/spec/app/models/quiz.rb +10 -0
  145. data/spec/app/models/rating.rb +8 -0
  146. data/spec/app/models/record.rb +46 -0
  147. data/spec/app/models/registry.rb +4 -0
  148. data/spec/app/models/role.rb +5 -0
  149. data/spec/app/models/root_category.rb +4 -0
  150. data/spec/app/models/sandwich.rb +4 -0
  151. data/spec/app/models/scheduler.rb +7 -0
  152. data/spec/app/models/seo.rb +7 -0
  153. data/spec/app/models/series.rb +4 -0
  154. data/spec/app/models/server.rb +13 -0
  155. data/spec/app/models/service.rb +22 -0
  156. data/spec/app/models/shape.rb +12 -0
  157. data/spec/app/models/shelf.rb +5 -0
  158. data/spec/app/models/shipping_container.rb +5 -0
  159. data/spec/app/models/shop.rb +6 -0
  160. data/spec/app/models/short_agent.rb +4 -0
  161. data/spec/app/models/short_quiz.rb +5 -0
  162. data/spec/app/models/slave.rb +6 -0
  163. data/spec/app/models/song.rb +8 -0
  164. data/spec/app/models/square.rb +4 -0
  165. data/spec/app/models/strategy.rb +3 -0
  166. data/spec/app/models/sub_item.rb +3 -0
  167. data/spec/app/models/survey.rb +5 -0
  168. data/spec/app/models/symptom.rb +6 -0
  169. data/spec/app/models/tag.rb +8 -0
  170. data/spec/app/models/target.rb +5 -0
  171. data/spec/app/models/template.rb +5 -0
  172. data/spec/app/models/thing.rb +9 -0
  173. data/spec/app/models/title.rb +4 -0
  174. data/spec/app/models/tool.rb +8 -0
  175. data/spec/app/models/topping.rb +5 -0
  176. data/spec/app/models/track.rb +38 -0
  177. data/spec/app/models/translation.rb +5 -0
  178. data/spec/app/models/tree.rb +9 -0
  179. data/spec/app/models/truck.rb +3 -0
  180. data/spec/app/models/user.rb +20 -0
  181. data/spec/app/models/user_account.rb +10 -0
  182. data/spec/app/models/validation_callback.rb +10 -0
  183. data/spec/app/models/vehicle.rb +11 -0
  184. data/spec/app/models/version.rb +5 -0
  185. data/spec/app/models/vet_visit.rb +5 -0
  186. data/spec/app/models/video.rb +17 -0
  187. data/spec/app/models/weapon.rb +11 -0
  188. data/spec/app/models/wiki_page.rb +17 -0
  189. data/spec/app/models/word.rb +12 -0
  190. data/spec/app/models/word_origin.rb +11 -0
  191. data/spec/app/models/writer.rb +11 -0
  192. data/spec/config/mongoid.yml +40 -0
  193. data/spec/mongoid/versioning_spec.rb +540 -0
  194. data/spec/spec_helper.rb +80 -0
  195. metadata +271 -0
@@ -0,0 +1,11 @@
1
+ class Vehicle
2
+ include Mongoid::Document
3
+ belongs_to :shipping_container
4
+ belongs_to :driver
5
+
6
+ accepts_nested_attributes_for :driver
7
+ accepts_nested_attributes_for :shipping_container
8
+ end
9
+
10
+ require "app/models/car"
11
+ require "app/models/truck"
@@ -0,0 +1,5 @@
1
+ class Version
2
+ include Mongoid::Document
3
+ field :number, type: Integer
4
+ embedded_in :memorable, polymorphic: true
5
+ end
@@ -0,0 +1,5 @@
1
+ class VetVisit
2
+ include Mongoid::Document
3
+ field :date, type: Date
4
+ embedded_in :pet
5
+ end
@@ -0,0 +1,17 @@
1
+ class Video
2
+ include Mongoid::Document
3
+ field :title, type: String
4
+ field :year, type: Integer
5
+ field :release_dates, type: Set
6
+ field :genres, type: Array
7
+
8
+ embedded_in :person
9
+ belongs_to :post
10
+ belongs_to :game
11
+
12
+ default_scope asc(:title)
13
+
14
+ attr_accessible :title, as: [ :default, :admin ]
15
+ attr_accessible :year, as: [ :default ]
16
+ attr_accessible :person_attributes, as: [ :default ]
17
+ end
@@ -0,0 +1,11 @@
1
+ class Weapon
2
+ include Mongoid::Document
3
+
4
+ field :name
5
+
6
+ belongs_to :player, inverse_of: :weapons
7
+
8
+ after_build do
9
+ self.name = "Holy Hand Grenade (#{player.frags})"
10
+ end
11
+ end
@@ -0,0 +1,17 @@
1
+ class WikiPage
2
+ include Mongoid::Document
3
+ include Mongoid::Timestamps
4
+ include Mongoid::Versioning
5
+
6
+ field :title, type: String
7
+ field :transient_property, type: String, versioned: false
8
+ field :author, type: String
9
+ field :description, type: String, localize: true
10
+ max_versions 5
11
+
12
+ attr_protected :author
13
+
14
+ has_many :comments, dependent: :destroy, validate: false
15
+ has_many :child_pages, class_name: "WikiPage", dependent: :delete, inverse_of: :parent_pages
16
+ belongs_to :parent_pages, class_name: "WikiPage", inverse_of: :child_pages
17
+ end
@@ -0,0 +1,12 @@
1
+ class Word
2
+ include Mongoid::Document
3
+ field :name, type: String
4
+
5
+ belongs_to :dictionary
6
+
7
+ embeds_many :definitions, validate: false
8
+ embeds_many :word_origins, validate: false
9
+ embeds_one :pronunciation, validate: false
10
+
11
+ accepts_nested_attributes_for :definitions, allow_destroy: true
12
+ end
@@ -0,0 +1,11 @@
1
+ class WordOrigin
2
+ include Mongoid::Document
3
+
4
+ field :_id, type: Integer, default: ->{ origin_id }
5
+
6
+ field :origin_id, type: Integer
7
+ field :country, type: String
8
+ field :city, type: String
9
+
10
+ embedded_in :word
11
+ end
@@ -0,0 +1,11 @@
1
+ class Writer
2
+ include Mongoid::Document
3
+ field :speed, type: Integer, default: 0
4
+
5
+ embedded_in :canvas
6
+
7
+ def write; end
8
+ end
9
+
10
+ require "app/models/pdf_writer"
11
+ require "app/models/html_writer"
@@ -0,0 +1,40 @@
1
+ test:
2
+ sessions:
3
+ default:
4
+ database: mongoid_test
5
+ hosts:
6
+ - <%=ENV["MONGOID_SPEC_HOST"]%>:<%=ENV["MONGOID_SPEC_PORT"]%>
7
+ options:
8
+ consistency: :strong
9
+ mongohq_single:
10
+ database: <%=ENV["MONGOHQ_SINGLE_NAME"]%>
11
+ username: <%=ENV["MONGOHQ_SINGLE_USER"]%>
12
+ password: <%=ENV["MONGOHQ_SINGLE_PASS"]%>
13
+ hosts:
14
+ - <%=ENV["MONGOHQ_SINGLE_URL"]%>
15
+ options:
16
+ safe: true
17
+ consistency: :strong
18
+ mongohq_repl:
19
+ database: <%=ENV["MONGOHQ_REPL_NAME"]%>
20
+ username: <%=ENV["MONGOHQ_REPL_USER"]%>
21
+ password: <%=ENV["MONGOHQ_REPL_PASS"]%>
22
+ hosts:
23
+ - <%=ENV["MONGOHQ_REPL_1_URL"]%>
24
+ - <%=ENV["MONGOHQ_REPL_2_URL"]%>
25
+ options:
26
+ consistency: :strong
27
+ safe: true
28
+ mongohq_repl_uri:
29
+ uri: <%= ENV["MONGOHQ_REPL_URI"]%>
30
+ options:
31
+ allow_dynamic_fields: true
32
+ identity_map_enabled: false
33
+ include_root_in_json: false
34
+ include_type_for_serialization: false
35
+ preload_models: false
36
+ scope_overwrite_exception: false
37
+ raise_not_found_error: true
38
+ skip_version_check: true
39
+ use_activesupport_time_zone: true
40
+ use_utc: false
@@ -0,0 +1,540 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Versioning do
4
+
5
+ describe ".max_versions" do
6
+
7
+ context "when provided an integer" do
8
+
9
+ before do
10
+ WikiPage.max_versions(10)
11
+ end
12
+
13
+ after do
14
+ WikiPage.max_versions(5)
15
+ end
16
+
17
+ it "sets the class version max" do
18
+ WikiPage.version_max.should eq(10)
19
+ end
20
+ end
21
+
22
+ context "when provided a string" do
23
+
24
+ before do
25
+ WikiPage.max_versions("10")
26
+ end
27
+
28
+ after do
29
+ WikiPage.max_versions(5)
30
+ end
31
+
32
+ it "sets the class version max" do
33
+ WikiPage.version_max.should eq(10)
34
+ end
35
+ end
36
+ end
37
+
38
+ describe "#version" do
39
+
40
+ context "when there is no default scope" do
41
+
42
+ context "when the document is new" do
43
+
44
+ it "returns 1" do
45
+ WikiPage.new.version.should eq(1)
46
+ end
47
+ end
48
+
49
+ context "when the document is persisted once" do
50
+
51
+ let(:page) do
52
+ WikiPage.create(title: "1")
53
+ end
54
+
55
+ it "returns 1" do
56
+ page.version.should eq(1)
57
+ end
58
+ end
59
+
60
+ context "when the document is persisted more than once" do
61
+
62
+ let(:page) do
63
+ WikiPage.create(title: "1")
64
+ end
65
+
66
+ before do
67
+ 3.times { |n| page.update_attribute(:title, "#{n}") }
68
+ end
69
+
70
+ it "returns the number of versions" do
71
+ page.version.should eq(4)
72
+ end
73
+ end
74
+
75
+ context "when maximum versions is defined" do
76
+
77
+ let(:page) do
78
+ WikiPage.create(title: "1")
79
+ end
80
+
81
+ context "when saving over the max versions limit" do
82
+
83
+ before do
84
+ 10.times { |n| page.update_attribute(:title, "#{n}") }
85
+ end
86
+
87
+ it "returns the number of versions" do
88
+ page.version.should eq(11)
89
+ end
90
+ end
91
+ end
92
+
93
+ context "when performing versionless saves" do
94
+
95
+ let(:page) do
96
+ WikiPage.create(title: "1")
97
+ end
98
+
99
+ before do
100
+ 10.times do |n|
101
+ page.versionless { |doc| doc.update_attribute(:title, "#{n}") }
102
+ end
103
+ end
104
+
105
+ it "does not increment the version number" do
106
+ page.version.should eq(1)
107
+ end
108
+ end
109
+ end
110
+
111
+ context "when there is a default scope" do
112
+
113
+ before :all do
114
+ class WikiPage
115
+ default_scope where(author: "Jim")
116
+ end
117
+ end
118
+
119
+ after :all do
120
+ WikiPage.default_scoping = nil
121
+ end
122
+
123
+ context "when the document is new" do
124
+
125
+ it "returns 1" do
126
+ WikiPage.new.version.should eq(1)
127
+ end
128
+ end
129
+
130
+ context "when the document is persisted once" do
131
+
132
+ let(:page) do
133
+ WikiPage.create(title: "1")
134
+ end
135
+
136
+ it "returns 1" do
137
+ page.version.should eq(1)
138
+ end
139
+ end
140
+
141
+ context "when the document is persisted more than once" do
142
+
143
+ let(:page) do
144
+ WikiPage.create(title: "1")
145
+ end
146
+
147
+ before do
148
+ 3.times { |n| page.update_attribute(:title, "#{n}") }
149
+ end
150
+
151
+ it "returns the number of versions" do
152
+ page.version.should eq(4)
153
+ end
154
+ end
155
+
156
+ context "when maximum versions is defined" do
157
+
158
+ let(:page) do
159
+ WikiPage.create(title: "1")
160
+ end
161
+
162
+ context "when saving over the max versions limit" do
163
+
164
+ before do
165
+ 10.times { |n| page.update_attribute(:title, "#{n}") }
166
+ end
167
+
168
+ it "returns the number of versions" do
169
+ page.version.should eq(11)
170
+ end
171
+ end
172
+ end
173
+
174
+ context "when performing versionless saves" do
175
+
176
+ let(:page) do
177
+ WikiPage.create(title: "1")
178
+ end
179
+
180
+ before do
181
+ 10.times do |n|
182
+ page.versionless { |doc| doc.update_attribute(:title, "#{n}") }
183
+ end
184
+ end
185
+
186
+ it "does not increment the version number" do
187
+ page.version.should eq(1)
188
+ end
189
+ end
190
+ end
191
+
192
+ context "when not using the default database" do
193
+
194
+ let(:title) { "my new wiki" }
195
+
196
+ let!(:page) do
197
+ WikiPage.with(database: "mongoid_test_alt").create!(description: "1",title: title)
198
+ end
199
+
200
+ context "when the document is persisted once" do
201
+
202
+ it "returns 1" do
203
+ page.version.should eq(1)
204
+ end
205
+
206
+ it "does not persist to default database" do
207
+ expect {
208
+ WikiPage.find_by(title: title)
209
+ }.to raise_error(Mongoid::Errors::DocumentNotFound)
210
+ end
211
+
212
+ it "persists to specified database" do
213
+ WikiPage.with(database: "mongoid_test_alt").find_by(title: title).should_not be_nil
214
+ end
215
+ end
216
+
217
+ context "when the document is persisted more than once" do
218
+
219
+ before do
220
+ 3.times { |n| page.with(database: "mongoid_test_alt").update_attribute(:description, "#{n}") }
221
+ end
222
+
223
+ it "returns the number of versions" do
224
+ page.version.should eq(4)
225
+ end
226
+
227
+ it "persists to specified database" do
228
+ WikiPage.with(database: "mongoid_test_alt").find_by(:title => title).should_not be_nil
229
+ end
230
+
231
+ it "persists the versions to specified database" do
232
+ WikiPage.with(database: "mongoid_test_alt").find_by(:title => title).version.should eq(4)
233
+ end
234
+ end
235
+ end
236
+ end
237
+
238
+ describe "#versionless" do
239
+
240
+ let(:page) do
241
+ WikiPage.new(created_at: Time.now.utc)
242
+ end
243
+
244
+ context "when executing the block" do
245
+
246
+ it "sets versionless to true" do
247
+ page.versionless do |doc|
248
+ doc.should be_versionless
249
+ end
250
+ end
251
+ end
252
+
253
+ context "when the block finishes" do
254
+
255
+ it "sets versionless to false" do
256
+ page.versionless
257
+ page.should_not be_versionless
258
+ end
259
+ end
260
+ end
261
+
262
+ describe "#versions" do
263
+
264
+ let(:page) do
265
+ WikiPage.create(title: "1", description: "test") do |wiki|
266
+ wiki.author = "woodchuck"
267
+ end
268
+ end
269
+
270
+ context "when saving the document " do
271
+
272
+ context "when the document has changed" do
273
+
274
+ before do
275
+ page.update_attribute(:title, "2")
276
+ end
277
+
278
+ let(:version) do
279
+ page.versions.first
280
+ end
281
+
282
+ it "creates a new version" do
283
+ version.title.should eq("1")
284
+ end
285
+
286
+ it "properly versions the localized fields" do
287
+ version.description.should eq("test")
288
+ end
289
+
290
+ it "only creates 1 new version" do
291
+ page.versions.count.should eq(1)
292
+ end
293
+
294
+ it "does not version the _id" do
295
+ version._id.should be_nil
296
+ end
297
+
298
+ it "does version the updated_at timestamp" do
299
+ version.updated_at.should_not be_nil
300
+ end
301
+
302
+ context "when only updated_at was changed" do
303
+
304
+ before do
305
+ page.update_attributes(updated_at: Time.now)
306
+ end
307
+
308
+ it "does not generate another version" do
309
+ page.versions.count.should eq(1)
310
+ end
311
+ end
312
+
313
+ it "does not embed versions within versions" do
314
+ version.versions.should be_empty
315
+ end
316
+
317
+ it "versions protected fields" do
318
+ version.author.should eq("woodchuck")
319
+ end
320
+
321
+ context "when saving multiple times" do
322
+
323
+ before do
324
+ page.update_attribute(:title, "3")
325
+ end
326
+
327
+ it "does not embed versions within versions" do
328
+ version.versions.should be_empty
329
+ end
330
+
331
+ it "does not embed versions multiple levels deep" do
332
+ page.versions.last.versions.should be_empty
333
+ end
334
+ end
335
+ end
336
+
337
+ context "when the document has not changed" do
338
+
339
+ before do
340
+ page.save
341
+ end
342
+
343
+ let(:version) do
344
+ page.versions.first
345
+ end
346
+
347
+ it "does not create a new version" do
348
+ version.should be_nil
349
+ end
350
+ end
351
+
352
+ context "when saving over the number of maximum versions" do
353
+
354
+ context "when the document is paranoid" do
355
+
356
+ let!(:post) do
357
+ ParanoidPost.create(title: "test")
358
+ end
359
+
360
+ before do
361
+ 3.times do |n|
362
+ post.update_attribute(:title, "#{n}")
363
+ end
364
+ end
365
+
366
+ it "only versions the maximum amount" do
367
+ post.versions.target.size.should eq(2)
368
+ end
369
+
370
+ it "persists the changes" do
371
+ post.reload.versions.target.size.should eq(2)
372
+ end
373
+ end
374
+
375
+ context "when saving in succession" do
376
+
377
+ before do
378
+ 10.times do |n|
379
+ page.update_attribute(:title, "#{n}")
380
+ end
381
+ end
382
+
383
+ let(:versions) do
384
+ page.versions
385
+ end
386
+
387
+ it "only versions the maximum amount" do
388
+ versions.count.should eq(5)
389
+ end
390
+
391
+ it "shifts the versions in order" do
392
+ versions.last.title.should eq("8")
393
+ end
394
+
395
+ it "persists the version shifts" do
396
+ page.reload.versions.last.title.should eq("8")
397
+ end
398
+ end
399
+
400
+ context "when saving in batches" do
401
+
402
+ before do
403
+ 2.times do
404
+ 5.times do |n|
405
+ WikiPage.find(page.id).update_attributes(title: "#{n}")
406
+ end
407
+ end
408
+ end
409
+
410
+ let(:from_db) do
411
+ WikiPage.find(page.id)
412
+ end
413
+
414
+ let(:versions) do
415
+ from_db.versions
416
+ end
417
+
418
+ it "only versions the maximum amount" do
419
+ versions.count.should eq(5)
420
+ end
421
+ end
422
+ end
423
+
424
+ context "when persisting versionless" do
425
+
426
+ before do
427
+ page.versionless { |doc| doc.update_attribute(:title, "2") }
428
+ end
429
+
430
+ it "does not version the document" do
431
+ page.versions.count.should eq(0)
432
+ end
433
+ end
434
+
435
+ context "when deleting versions" do
436
+
437
+ let(:comment) do
438
+ Comment.new(title: "Don't delete me!")
439
+ end
440
+
441
+ let!(:orphaned) do
442
+ Comment.create(title: "Annie")
443
+ end
444
+
445
+ before do
446
+ page.comments << comment
447
+ page.update_attribute(:title, "5")
448
+ end
449
+
450
+ context "when the version had a dependent relation" do
451
+
452
+ before do
453
+ page.versions.delete_all
454
+ end
455
+
456
+ let(:from_db) do
457
+ Comment.find(comment.id)
458
+ end
459
+
460
+ it "does not perform dependent cascading" do
461
+ from_db.should eq(comment)
462
+ end
463
+
464
+ it "does not delete related orphans" do
465
+ Comment.find(orphaned.id).should eq(orphaned)
466
+ end
467
+
468
+ it "deletes the version" do
469
+ page.versions.should be_empty
470
+ end
471
+
472
+ it "persists the deletion" do
473
+ page.reload.versions.should be_empty
474
+ end
475
+
476
+ it "retains the root relation" do
477
+ page.reload.comments.should eq([ comment ])
478
+ end
479
+ end
480
+ end
481
+ end
482
+ end
483
+
484
+ context "when appending a self referencing document with versions" do
485
+
486
+ let(:page) do
487
+ WikiPage.create(title: "1")
488
+ end
489
+
490
+ let(:child) do
491
+ WikiPage.new
492
+ end
493
+
494
+ before do
495
+ page.child_pages << child
496
+ end
497
+
498
+ it "allows the document to be added" do
499
+ page.child_pages.should eq([ child ])
500
+ end
501
+
502
+ it "persists the changes" do
503
+ page.reload.child_pages.should eq([ child ])
504
+ end
505
+ end
506
+
507
+ context "when the identity map is enabled" do
508
+
509
+ before do
510
+ Mongoid.identity_map_enabled = true
511
+ end
512
+
513
+ after do
514
+ Mongoid.identity_map_enabled = false
515
+ end
516
+
517
+ context "when updating a loaded attribute" do
518
+
519
+ let!(:page) do
520
+ WikiPage.create(title: "first")
521
+ end
522
+
523
+ let!(:loaded) do
524
+ WikiPage.find(page.id)
525
+ end
526
+
527
+ before do
528
+ loaded.update_attribute(:title, "revised")
529
+ end
530
+
531
+ let(:reloaded) do
532
+ WikiPage.find(page.id)
533
+ end
534
+
535
+ it "returns the revised im memory document" do
536
+ reloaded.title.should eq("revised")
537
+ end
538
+ end
539
+ end
540
+ end