acts_as_versioned 0.2.3 → 0.6.0

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