gluttonberg_acts_as_versioned 2.0.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.
@@ -0,0 +1,49 @@
1
+ require "rubygems"
2
+ require "bundler"
3
+ Bundler.setup(:default, :development)
4
+
5
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
6
+ require 'test/unit'
7
+ require 'active_support'
8
+ require 'active_record'
9
+ require 'active_record/fixtures'
10
+ require 'active_record/test_case'
11
+
12
+ begin
13
+ require 'ruby-debug'
14
+ Debugger.start
15
+ rescue LoadError
16
+ end
17
+
18
+ require 'acts_as_versioned'
19
+
20
+ config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
21
+ ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/debug.log")
22
+ ActiveRecord::Base.configurations = {'test' => config[ENV['DB'] || 'sqlite3']}
23
+ ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations['test'])
24
+
25
+ load(File.dirname(__FILE__) + "/schema.rb")
26
+
27
+ # set up custom sequence on widget_versions for DBs that support sequences
28
+ if ENV['DB'] == 'postgresql'
29
+ ActiveRecord::Base.connection.execute "DROP SEQUENCE widgets_seq;" rescue nil
30
+ ActiveRecord::Base.connection.remove_column :widget_versions, :id
31
+ ActiveRecord::Base.connection.execute "CREATE SEQUENCE widgets_seq START 101;"
32
+ ActiveRecord::Base.connection.execute "ALTER TABLE widget_versions ADD COLUMN id INTEGER PRIMARY KEY DEFAULT nextval('widgets_seq');"
33
+ end
34
+
35
+ class ActiveSupport::TestCase #:nodoc:
36
+ include ActiveRecord::TestFixtures
37
+
38
+ self.fixture_path = File.dirname(__FILE__) + "/fixtures/"
39
+
40
+ # Turn off transactional fixtures if you're working with MyISAM tables in MySQL
41
+ self.use_transactional_fixtures = true
42
+
43
+ # Instantiated fixtures are slow, but give you @david where you otherwise would need people(:david)
44
+ self.use_instantiated_fixtures = false
45
+
46
+ # Add more helper methods to be used by all tests here...
47
+ end
48
+
49
+ $:.unshift(ActiveSupport::TestCase.fixture_path)
@@ -0,0 +1,12 @@
1
+ postgresql:
2
+ adapter: postgresql
3
+ username: postgres
4
+ password:
5
+ database: acts_as_versioned_plugin_test
6
+ min_messages: ERROR
7
+ mysql:
8
+ adapter: mysql
9
+ host: localhost
10
+ username: root
11
+ password:
12
+ database: acts_as_versioned_plugin_test
@@ -0,0 +1,6 @@
1
+ caged:
2
+ id: 1
3
+ name: caged
4
+ mly:
5
+ id: 2
6
+ name: mly
@@ -0,0 +1,3 @@
1
+ class Landmark < ActiveRecord::Base
2
+ acts_as_versioned :if_changed => [ :name, :longitude, :latitude ]
3
+ end
@@ -0,0 +1,7 @@
1
+ washington:
2
+ id: 1
3
+ landmark_id: 1
4
+ version: 1
5
+ name: Washington, D.C.
6
+ latitude: 38.895
7
+ longitude: -77.036667
@@ -0,0 +1,7 @@
1
+ washington:
2
+ id: 1
3
+ name: Washington, D.C.
4
+ latitude: 38.895
5
+ longitude: -77.036667
6
+ doesnt_trigger_version: This is not important
7
+ version: 1
@@ -0,0 +1,10 @@
1
+ welcome:
2
+ id: 1
3
+ title: Welcome to the weblog
4
+ lock_version: 24
5
+ type: LockedPage
6
+ thinking:
7
+ id: 2
8
+ title: So I was thinking
9
+ lock_version: 24
10
+ type: SpecialLockedPage
@@ -0,0 +1,27 @@
1
+ welcome_1:
2
+ id: 1
3
+ page_id: 1
4
+ title: Welcome to the weblg
5
+ lock_version: 23
6
+ version_type: LockedPage
7
+
8
+ welcome_2:
9
+ id: 2
10
+ page_id: 1
11
+ title: Welcome to the weblog
12
+ lock_version: 24
13
+ version_type: LockedPage
14
+
15
+ thinking_1:
16
+ id: 3
17
+ page_id: 2
18
+ title: So I was thinking!!!
19
+ lock_version: 23
20
+ version_type: SpecialLockedPage
21
+
22
+ thinking_2:
23
+ id: 4
24
+ page_id: 2
25
+ title: So I was thinking
26
+ lock_version: 24
27
+ version_type: SpecialLockedPage
@@ -0,0 +1,15 @@
1
+ class AddVersionedTables < ActiveRecord::Migration
2
+ def self.up
3
+ create_table("things") do |t|
4
+ t.column :title, :text
5
+ t.column :price, :decimal, :precision => 7, :scale => 2
6
+ t.column :type, :string
7
+ end
8
+ Thing.create_versioned_table
9
+ end
10
+
11
+ def self.down
12
+ Thing.drop_versioned_table
13
+ drop_table "things" rescue nil
14
+ end
15
+ end
@@ -0,0 +1,43 @@
1
+ class Page < ActiveRecord::Base
2
+ belongs_to :author
3
+ has_many :authors, :through => :versions, :order => 'name'
4
+ belongs_to :revisor, :class_name => 'Author'
5
+ has_many :revisors, :class_name => 'Author', :through => :versions, :order => 'name'
6
+ acts_as_versioned :non_versioned_columns => [:state], :if => :feeling_good? do
7
+ def self.included(base)
8
+ base.cattr_accessor :feeling_good
9
+ base.feeling_good = true
10
+ base.belongs_to :author
11
+ base.belongs_to :revisor, :class_name => 'Author'
12
+ end
13
+
14
+ def feeling_good?
15
+ @@feeling_good == true
16
+ end
17
+ end
18
+ end
19
+
20
+ module LockedPageExtension
21
+ def hello_world
22
+ 'hello_world'
23
+ end
24
+ end
25
+
26
+ class LockedPage < ActiveRecord::Base
27
+ acts_as_versioned \
28
+ :inheritance_column => :version_type,
29
+ :foreign_key => :page_id,
30
+ :table_name => :locked_pages_revisions,
31
+ :class_name => 'LockedPageRevision',
32
+ :version_column => :lock_version,
33
+ :limit => 2,
34
+ :if_changed => :title,
35
+ :extend => LockedPageExtension
36
+ end
37
+
38
+ class SpecialLockedPage < LockedPage
39
+ end
40
+
41
+ class Author < ActiveRecord::Base
42
+ has_many :pages
43
+ end
@@ -0,0 +1,17 @@
1
+ welcome_2:
2
+ id: 1
3
+ page_id: 1
4
+ title: Welcome to the weblog
5
+ body: Such a lovely day
6
+ version: 24
7
+ author_id: 1
8
+ revisor_id: 1
9
+ welcome_1:
10
+ id: 2
11
+ page_id: 1
12
+ title: Welcome to the weblg
13
+ body: Such a lovely day
14
+ version: 23
15
+ author_id: 2
16
+ revisor_id: 2
17
+ version_status: draft
@@ -0,0 +1,9 @@
1
+ welcome:
2
+ id: 1
3
+ title: Welcome to the weblog
4
+ body: Such a lovely day
5
+ state: published
6
+ version: 24
7
+ author_id: 1
8
+ revisor_id: 1
9
+ created_on: "2008-01-01 00:00:00"
@@ -0,0 +1,6 @@
1
+ class Widget < ActiveRecord::Base
2
+ acts_as_versioned :sequence_name => 'widgets_seq', :association_options => {
3
+ :dependent => :nullify, :order => 'version desc'
4
+ }
5
+ non_versioned_columns << 'foo'
6
+ end
@@ -0,0 +1,50 @@
1
+ require File.join(File.dirname(__FILE__), 'abstract_unit')
2
+
3
+ if ActiveRecord::Base.connection.supports_migrations?
4
+ class Thing < ActiveRecord::Base
5
+ attr_accessor :version
6
+ acts_as_versioned
7
+ end
8
+
9
+ class MigrationTest < ActiveSupport::TestCase
10
+ self.use_transactional_fixtures = false
11
+ def teardown
12
+ if ActiveRecord::Base.connection.respond_to?(:initialize_schema_information)
13
+ ActiveRecord::Base.connection.initialize_schema_information
14
+ ActiveRecord::Base.connection.update "UPDATE schema_info SET version = 0"
15
+ else
16
+ ActiveRecord::Base.connection.initialize_schema_migrations_table
17
+ ActiveRecord::Base.connection.assume_migrated_upto_version(0)
18
+ end
19
+
20
+ Thing.connection.drop_table "things" rescue nil
21
+ Thing.connection.drop_table "thing_versions" rescue nil
22
+ Thing.reset_column_information
23
+ end
24
+
25
+ def test_versioned_migration
26
+ assert_raises(ActiveRecord::StatementInvalid) { Thing.create :title => 'blah blah' }
27
+ # take 'er up
28
+ ActiveRecord::Migrator.up(File.dirname(__FILE__) + '/fixtures/migrations/')
29
+ t = Thing.create :title => 'blah blah', :price => 123.45, :type => 'Thing'
30
+ assert_equal 1, t.versions.size
31
+
32
+ # check that the price column has remembered its value correctly
33
+ assert_equal t.price, t.versions.first.price
34
+ assert_equal t.title, t.versions.first.title
35
+ assert_equal t[:type], t.versions.first[:type]
36
+
37
+ # make sure that the precision of the price column has been preserved
38
+ assert_equal 7, Thing::Version.columns.find{|c| c.name == "price"}.precision
39
+ assert_equal 2, Thing::Version.columns.find{|c| c.name == "price"}.scale
40
+
41
+ # make sure freerange version additional fields are also created
42
+ assert_equal :integer, Thing::Version.columns.find{|c| c.name == "version_user_id"}.type
43
+ assert_equal :string, Thing::Version.columns.find{|c| c.name == "version_status"}.type
44
+
45
+ # now lets take 'er back down
46
+ ActiveRecord::Migrator.down(File.dirname(__FILE__) + '/fixtures/migrations/')
47
+ assert_raises(ActiveRecord::StatementInvalid) { Thing.create :title => 'blah blah' }
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,85 @@
1
+ ActiveRecord::Schema.define(:version => 0) do
2
+ create_table :pages, :force => true do |t|
3
+ t.column :version, :integer
4
+ t.column :title, :string, :limit => 255
5
+ t.column :body, :text
6
+ t.column :state, :string #Freerange extension for publishable
7
+ t.column :created_on, :datetime
8
+ t.column :updated_on, :datetime
9
+ t.column :author_id, :integer
10
+ t.column :revisor_id, :integer
11
+ end
12
+
13
+ create_table :page_versions, :force => true do |t|
14
+ t.column :page_id, :integer
15
+ t.column :version, :integer
16
+ t.column :title, :string, :limit => 255
17
+ t.column :body, :text
18
+ t.column :created_on, :datetime
19
+ t.column :updated_on, :datetime
20
+ t.column :author_id, :integer
21
+ t.column :revisor_id, :integer
22
+ t.column :version_status, :string
23
+ t.column :version_user_id, :integer
24
+ end
25
+
26
+ add_index :page_versions, [:page_id, :version], :unique => true
27
+
28
+ create_table :authors, :force => true do |t|
29
+ t.column :page_id, :integer
30
+ t.column :name, :string
31
+ end
32
+
33
+ create_table :locked_pages, :force => true do |t|
34
+ t.column :lock_version, :integer
35
+ t.column :title, :string, :limit => 255
36
+ t.column :body, :text
37
+ t.column :type, :string, :limit => 255
38
+ end
39
+
40
+ create_table :locked_pages_revisions, :force => true do |t|
41
+ t.column :page_id, :integer
42
+ t.column :lock_version, :integer
43
+ t.column :title, :string, :limit => 255
44
+ t.column :body, :text
45
+ t.column :version_type, :string, :limit => 255
46
+ t.column :updated_at, :datetime
47
+ end
48
+
49
+ add_index :locked_pages_revisions, [:page_id, :lock_version], :unique => true
50
+
51
+ create_table :widgets, :force => true do |t|
52
+ t.column :name, :string, :limit => 50
53
+ t.column :foo, :string
54
+ t.column :version, :integer
55
+ t.column :updated_at, :datetime
56
+ end
57
+
58
+ create_table :widget_versions, :force => true do |t|
59
+ t.column :widget_id, :integer
60
+ t.column :name, :string, :limit => 50
61
+ t.column :version, :integer
62
+ t.column :updated_at, :datetime
63
+ end
64
+
65
+ add_index :widget_versions, [:widget_id, :version], :unique => true
66
+
67
+ create_table :landmarks, :force => true do |t|
68
+ t.column :name, :string
69
+ t.column :latitude, :float
70
+ t.column :longitude, :float
71
+ t.column :doesnt_trigger_version,:string
72
+ t.column :version, :integer
73
+ end
74
+
75
+ create_table :landmark_versions, :force => true do |t|
76
+ t.column :landmark_id, :integer
77
+ t.column :name, :string
78
+ t.column :latitude, :float
79
+ t.column :longitude, :float
80
+ t.column :doesnt_trigger_version,:string
81
+ t.column :version, :integer
82
+ end
83
+
84
+ add_index :landmark_versions, [:landmark_id, :version], :unique => true
85
+ end
@@ -0,0 +1,377 @@
1
+ require File.join(File.dirname(__FILE__), 'abstract_unit')
2
+ require File.join(File.dirname(__FILE__), 'fixtures/page')
3
+ require File.join(File.dirname(__FILE__), 'fixtures/widget')
4
+
5
+ class VersionedTest < ActiveSupport::TestCase
6
+ fixtures :pages, :page_versions, :locked_pages, :locked_pages_revisions, :authors, :landmarks, :landmark_versions
7
+ set_fixture_class :page_versions => Page::Version
8
+
9
+ def test_saves_versioned_copy
10
+ p = Page.create! :title => 'first title', :body => 'first body'
11
+ assert !p.new_record?
12
+ assert_equal 1, p.versions.size
13
+ assert_equal 1, p.version
14
+ assert_instance_of Page.versioned_class, p.versions.first
15
+ end
16
+
17
+ def test_saves_without_revision
18
+ p = pages(:welcome)
19
+ old_versions = p.versions.count
20
+
21
+ p.save_without_revision
22
+
23
+ p.without_revision do
24
+ p.update_attributes :title => 'changed'
25
+ end
26
+
27
+ assert_equal old_versions, p.versions.count
28
+ end
29
+
30
+ def test_rollback_with_version_number
31
+ p = pages(:welcome)
32
+ assert_equal 24, p.version
33
+ assert_equal 'Welcome to the weblog', p.title
34
+
35
+ assert p.revert_to!(23), "Couldn't revert to 23"
36
+ assert_equal 23, p.version
37
+ assert_equal 'Welcome to the weblg', p.title
38
+
39
+ #Freerange extension
40
+ #test loaded_version
41
+ assert_equal p.loaded_version.version , p.version
42
+ #test status
43
+ assert_equal p.loaded_version.version_status , 'draft'
44
+ end
45
+
46
+ def test_versioned_class_name
47
+ assert_equal 'Version', Page.versioned_class_name
48
+ assert_equal 'LockedPageRevision', LockedPage.versioned_class_name
49
+ end
50
+
51
+ def test_versioned_class
52
+ assert_equal Page::Version, Page.versioned_class
53
+ assert_equal LockedPage::LockedPageRevision, LockedPage.versioned_class
54
+ end
55
+
56
+ def test_special_methods
57
+ assert_nothing_raised { pages(:welcome).feeling_good? }
58
+ assert_nothing_raised { pages(:welcome).versions.first.feeling_good? }
59
+ assert_nothing_raised { locked_pages(:welcome).hello_world }
60
+ assert_nothing_raised { locked_pages(:welcome).versions.first.hello_world }
61
+ end
62
+
63
+ def test_rollback_with_version_class
64
+ p = pages(:welcome)
65
+ assert_equal 24, p.version
66
+ assert_equal 'Welcome to the weblog', p.title
67
+
68
+ assert p.revert_to!(p.versions.find_by_version(23)), "Couldn't revert to 23"
69
+ assert_equal 23, p.version
70
+ assert_equal 'Welcome to the weblg', p.title
71
+ end
72
+
73
+ def test_rollback_fails_with_invalid_revision
74
+ p = locked_pages(:welcome)
75
+ assert !p.revert_to!(locked_pages(:thinking))
76
+ end
77
+
78
+ def test_saves_versioned_copy_with_options
79
+ p = LockedPage.create! :title => 'first title'
80
+ assert !p.new_record?
81
+ assert_equal 1, p.versions.size
82
+ assert_instance_of LockedPage.versioned_class, p.versions.first
83
+ end
84
+
85
+ def test_rollback_with_version_number_with_options
86
+ p = locked_pages(:welcome)
87
+ assert_equal 'Welcome to the weblog', p.title
88
+ assert_equal 'LockedPage', p.versions.first.version_type
89
+
90
+ assert p.revert_to!(p.versions.first.lock_version), "Couldn't revert to 23"
91
+ assert_equal 'Welcome to the weblg', p.title
92
+ assert_equal 'LockedPage', p.versions.first.version_type
93
+ end
94
+
95
+ def test_rollback_with_version_class_with_options
96
+ p = locked_pages(:welcome)
97
+ assert_equal 'Welcome to the weblog', p.title
98
+ assert_equal 'LockedPage', p.versions.first.version_type
99
+
100
+ assert p.revert_to!(p.versions.first), "Couldn't revert to 1"
101
+ assert_equal 'Welcome to the weblg', p.title
102
+ assert_equal 'LockedPage', p.versions.first.version_type
103
+ end
104
+
105
+ def test_saves_versioned_copy_with_sti
106
+ p = SpecialLockedPage.create! :title => 'first title'
107
+ assert !p.new_record?
108
+ assert_equal 1, p.versions.size
109
+ assert_instance_of LockedPage.versioned_class, p.versions.first
110
+ assert_equal 'SpecialLockedPage', p.versions.first.version_type
111
+ end
112
+
113
+ def test_rollback_with_version_number_with_sti
114
+ p = locked_pages(:thinking)
115
+ assert_equal 'So I was thinking', p.title
116
+
117
+ assert p.revert_to!(p.versions.first.lock_version), "Couldn't revert to 1"
118
+ assert_equal 'So I was thinking!!!', p.title
119
+ assert_equal 'SpecialLockedPage', p.versions.first.version_type
120
+ end
121
+
122
+ def test_lock_version_works_with_versioning
123
+ p = locked_pages(:thinking)
124
+ p2 = LockedPage.find(p.id)
125
+
126
+ p.title = 'fresh title'
127
+ p.save
128
+ assert_equal 2, p.versions.size # limit!
129
+
130
+ assert_raises(ActiveRecord::StaleObjectError) do
131
+ p2.title = 'stale title'
132
+ p2.save
133
+ end
134
+ end
135
+
136
+ def test_version_if_condition
137
+ p = Page.create! :title => "title"
138
+ assert_equal 1, p.version
139
+
140
+ Page.feeling_good = false
141
+ p.save
142
+ assert_equal 1, p.version
143
+ Page.feeling_good = true
144
+ end
145
+
146
+ def test_version_if_condition2
147
+ # set new if condition
148
+ Page.class_eval do
149
+ def new_feeling_good() title[0..0] == 'a'; end
150
+ alias_method :old_feeling_good, :feeling_good?
151
+ alias_method :feeling_good?, :new_feeling_good
152
+ end
153
+
154
+ p = Page.create! :title => "title", :state => "published"
155
+ assert_equal 1, p.version # version does not increment
156
+ assert_equal 1, p.versions.count
157
+ assert_equal "published", p.versions.first.version_status
158
+
159
+ p.update_attributes(:title => 'new title')
160
+ assert_equal 1, p.version # version does not increment
161
+ assert_equal 1, p.versions.count
162
+
163
+ p.update_attributes(:title => 'a title')
164
+ assert_equal 2, p.version
165
+ assert_equal 2, p.versions.count
166
+
167
+ # reset original if condition
168
+ Page.class_eval { alias_method :feeling_good?, :old_feeling_good }
169
+ end
170
+
171
+ def test_version_if_condition_with_block
172
+ # set new if condition
173
+ old_condition = Page.version_condition
174
+ Page.version_condition = Proc.new { |page| page.title[0..0] == 'b' }
175
+
176
+ p = Page.create! :title => "title"
177
+ assert_equal 1, p.version # version does not increment
178
+ assert_equal 1, p.versions.count
179
+
180
+ p.update_attributes(:title => 'a title')
181
+ assert_equal 1, p.version # version does not increment
182
+ assert_equal 1, p.versions.count
183
+
184
+ p.update_attributes(:title => 'b title')
185
+ assert_equal 2, p.version
186
+ assert_equal 2, p.versions.count
187
+
188
+ # reset original if condition
189
+ Page.version_condition = old_condition
190
+ end
191
+
192
+ def test_version_no_limit
193
+ p = Page.create! :title => "title", :body => 'first body'
194
+ p.save
195
+ p.save
196
+ 5.times do |i|
197
+ p.title = "title#{i}"
198
+ p.save
199
+ assert_equal "title#{i}", p.title
200
+ assert_equal (i+2), p.version
201
+ end
202
+ end
203
+
204
+ def test_version_max_limit
205
+ p = LockedPage.create! :title => "title"
206
+ p.update_attributes(:title => "title1")
207
+ p.update_attributes(:title => "title2")
208
+ 5.times do |i|
209
+ p.title = "title#{i}"
210
+ p.save
211
+ assert_equal "title#{i}", p.title
212
+ assert_equal (i+4), p.lock_version
213
+ assert p.versions(true).size <= 2, "locked version can only store 2 versions"
214
+ end
215
+ end
216
+
217
+ def test_track_altered_attributes_default_value
218
+ assert !Page.track_altered_attributes
219
+ assert LockedPage.track_altered_attributes
220
+ assert SpecialLockedPage.track_altered_attributes
221
+ end
222
+
223
+ def test_track_altered_attributes
224
+ p = LockedPage.create! :title => "title"
225
+ assert_equal 1, p.lock_version
226
+ assert_equal 1, p.versions(true).size
227
+
228
+ p.body = 'whoa'
229
+ assert !p.save_version?
230
+ p.save
231
+ assert_equal 2, p.lock_version # still increments version because of optimistic locking
232
+ assert_equal 1, p.versions(true).size
233
+
234
+ p.title = 'updated title'
235
+ assert p.save_version?
236
+ p.save
237
+ assert_equal 3, p.lock_version
238
+ assert_equal 1, p.versions(true).size # version 1 deleted
239
+
240
+ p.title = 'updated title!'
241
+ assert p.save_version?
242
+ p.save
243
+ assert_equal 4, p.lock_version
244
+ assert_equal 2, p.versions(true).size # version 1 deleted
245
+ end
246
+
247
+ def test_find_versions
248
+ assert_equal 1, locked_pages(:welcome).versions.find(:all, :conditions => ['title LIKE ?', '%weblog%']).size
249
+ end
250
+
251
+ def test_find_version
252
+ assert_equal page_versions(:welcome_1), pages(:welcome).versions.find_by_version(23)
253
+ end
254
+
255
+ def test_with_sequence
256
+ assert_equal 'widgets_seq', Widget.versioned_class.sequence_name
257
+ 3.times { Widget.create! :name => 'new widget' }
258
+ assert_equal 3, Widget.count
259
+ assert_equal 3, Widget.versioned_class.count
260
+ end
261
+
262
+ def test_has_many_through
263
+ assert_equal [authors(:caged), authors(:mly)], pages(:welcome).authors
264
+ end
265
+
266
+ def test_has_many_through_with_custom_association
267
+ assert_equal [authors(:caged), authors(:mly)], pages(:welcome).revisors
268
+ end
269
+
270
+ def test_referential_integrity
271
+ pages(:welcome).destroy
272
+ assert_equal 0, Page.count
273
+ assert_equal 0, Page::Version.count
274
+ end
275
+
276
+ def test_association_options
277
+ association = Page.reflect_on_association(:versions)
278
+ options = association.options
279
+ assert_equal :delete_all, options[:dependent]
280
+
281
+ association = Widget.reflect_on_association(:versions)
282
+ options = association.options
283
+ assert_equal :nullify, options[:dependent]
284
+ assert_equal 'version desc', options[:order]
285
+ assert_equal 'widget_id', options[:foreign_key]
286
+
287
+ widget = Widget.create! :name => 'new widget'
288
+ assert_equal 1, Widget.count
289
+ assert_equal 1, Widget.versioned_class.count
290
+ widget.destroy
291
+ assert_equal 0, Widget.count
292
+ assert_equal 1, Widget.versioned_class.count
293
+ end
294
+
295
+ def test_versioned_records_should_belong_to_parent
296
+ page = pages(:welcome)
297
+ page_version = page.versions.last
298
+ assert_equal page, page_version.page
299
+ end
300
+
301
+ def test_unaltered_attributes
302
+ landmarks(:washington).attributes = landmarks(:washington).attributes.except("id")
303
+ assert !landmarks(:washington).changed?
304
+ end
305
+
306
+ def test_unchanged_string_attributes
307
+ landmarks(:washington).attributes = landmarks(:washington).attributes.except("id").inject({}) { |params, (key, value)| params.update(key => value.to_s) }
308
+ assert !landmarks(:washington).changed?
309
+ end
310
+
311
+ def test_should_find_earliest_version
312
+ assert_equal page_versions(:welcome_1), pages(:welcome).versions.earliest
313
+ end
314
+
315
+ def test_should_find_latest_version
316
+ assert_equal page_versions(:welcome_2), pages(:welcome).versions.latest
317
+ end
318
+
319
+ def test_should_find_previous_version
320
+ assert_equal page_versions(:welcome_1), page_versions(:welcome_2).previous
321
+ assert_equal page_versions(:welcome_1), pages(:welcome).versions.before(page_versions(:welcome_2))
322
+ end
323
+
324
+ def test_should_find_next_version
325
+ assert_equal page_versions(:welcome_2), page_versions(:welcome_1).next
326
+ assert_equal page_versions(:welcome_2), pages(:welcome).versions.after(page_versions(:welcome_1))
327
+ end
328
+
329
+ def test_should_find_version_count
330
+ assert_equal 2, pages(:welcome).versions.size
331
+ end
332
+
333
+ def test_if_changed_creates_version_if_a_listed_column_is_changed
334
+ landmarks(:washington).name = "Washington"
335
+ assert landmarks(:washington).changed?
336
+ assert landmarks(:washington).altered?
337
+ end
338
+
339
+ def test_if_changed_creates_version_if_all_listed_columns_are_changed
340
+ landmarks(:washington).name = "Washington"
341
+ landmarks(:washington).latitude = 1.0
342
+ landmarks(:washington).longitude = 1.0
343
+ assert landmarks(:washington).changed?
344
+ assert landmarks(:washington).altered?
345
+ end
346
+
347
+ def test_if_changed_does_not_create_new_version_if_unlisted_column_is_changed
348
+ landmarks(:washington).doesnt_trigger_version = "This should not trigger version"
349
+ assert landmarks(:washington).changed?
350
+ assert !landmarks(:washington).altered?
351
+ end
352
+
353
+ def test_without_locking_temporarily_disables_optimistic_locking
354
+ enabled1 = false
355
+ block_called = false
356
+
357
+ ActiveRecord::Base.lock_optimistically = true
358
+ LockedPage.without_locking do
359
+ enabled1 = ActiveRecord::Base.lock_optimistically
360
+ block_called = true
361
+ end
362
+ enabled2 = ActiveRecord::Base.lock_optimistically
363
+
364
+ assert block_called
365
+ assert !enabled1
366
+ assert enabled2
367
+ end
368
+
369
+ def test_without_locking_reverts_optimistic_locking_settings_if_block_raises_exception
370
+ assert_raises(RuntimeError) do
371
+ LockedPage.without_locking do
372
+ raise RuntimeError, "oh noes"
373
+ end
374
+ end
375
+ assert ActiveRecord::Base.lock_optimistically
376
+ end
377
+ end