decisiv-acts_as_versioned 0.6.1
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/CHANGELOG +102 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +24 -0
- data/RUNNING_UNIT_TESTS +21 -0
- data/Rakefile +24 -0
- data/lib/acts_as_versioned.rb +492 -0
- data/test/fixtures/authors.yml +6 -0
- data/test/fixtures/landmark_versions.yml +7 -0
- data/test/fixtures/landmarks.yml +7 -0
- data/test/fixtures/locked_pages.yml +10 -0
- data/test/fixtures/locked_pages_revisions.yml +27 -0
- data/test/fixtures/page_versions.yml +16 -0
- data/test/fixtures/pages.yml +8 -0
- data/test/fixtures/widgets.yml +2 -0
- data/test/helper.rb +27 -0
- data/test/lib/boot.rb +68 -0
- data/test/lib/database.yml +26 -0
- data/test/lib/schema.rb +91 -0
- data/test/migration_test.rb +43 -0
- data/test/migrations/1_add_versioned_tables.rb +19 -0
- data/test/models/author.rb +3 -0
- data/test/models/landmark.rb +3 -0
- data/test/models/page.rb +38 -0
- data/test/models/thing.rb +7 -0
- data/test/models/widget.rb +6 -0
- data/test/versioned_test.rb +336 -0
- metadata +80 -0
@@ -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,16 @@
|
|
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
|
data/test/helper.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require File.join(File.dirname(__FILE__),'lib/boot') unless defined?(ActiveRecord)
|
3
|
+
require 'acts_as_versioned'
|
4
|
+
|
5
|
+
class AAVTestCase < ActiveRecord::TestCase
|
6
|
+
|
7
|
+
self.use_transactional_fixtures = true
|
8
|
+
self.use_instantiated_fixtures = false
|
9
|
+
|
10
|
+
fixtures :all
|
11
|
+
set_fixture_class :page_versions => Page::Version
|
12
|
+
|
13
|
+
protected
|
14
|
+
|
15
|
+
def assert_sql(*patterns_to_match)
|
16
|
+
$queries_executed = []
|
17
|
+
yield
|
18
|
+
ensure
|
19
|
+
failed_patterns = []
|
20
|
+
patterns_to_match.each do |pattern|
|
21
|
+
failed_patterns << pattern unless $queries_executed.any?{ |sql| pattern === sql }
|
22
|
+
end
|
23
|
+
assert failed_patterns.empty?, "Query pattern(s) #{failed_patterns.map(&:inspect).join(', ')} not found in:\n#{$queries_executed.inspect}"
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
data/test/lib/boot.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
|
2
|
+
# Requiring ActiveRecord via RubyGems.
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
|
6
|
+
PROJECT_ROOT = File.expand_path(File.join(File.dirname(__FILE__),'..','..'))
|
7
|
+
AR_VERSION = ENV['AR_VERSION'] || '2.2.2'
|
8
|
+
|
9
|
+
['.','lib','test','test/models'].each do |test_lib|
|
10
|
+
load_path = File.expand_path(File.join(PROJECT_ROOT,test_lib))
|
11
|
+
$LOAD_PATH.unshift(load_path) unless $LOAD_PATH.include?(load_path)
|
12
|
+
end
|
13
|
+
|
14
|
+
puts "Using ActiveRecord #{AR_VERSION} from gems"
|
15
|
+
gem 'activerecord', AR_VERSION
|
16
|
+
require 'active_record'
|
17
|
+
|
18
|
+
|
19
|
+
# Setting up ActiveRecord TestCase and fixtures. We make sure our setup runs before setup_fixtures.
|
20
|
+
|
21
|
+
FIXTURES_ROOT = PROJECT_ROOT + "/test/fixtures"
|
22
|
+
MIGRATIONS_ROOT = PROJECT_ROOT + "/test/migrations"
|
23
|
+
|
24
|
+
require 'active_record/fixtures'
|
25
|
+
require 'active_record/test_case'
|
26
|
+
|
27
|
+
|
28
|
+
# Establishing the ActiveRecord connection and DB specific tasks.
|
29
|
+
|
30
|
+
ardb = ENV['DB'] || 'sqlite3'
|
31
|
+
arconfig = YAML::load(IO.read("#{PROJECT_ROOT}/test/lib/database.yml"))
|
32
|
+
|
33
|
+
case ardb
|
34
|
+
when 'sqlserver'
|
35
|
+
gem 'rails-sqlserver-2000-2005-adapter'
|
36
|
+
require 'active_record/connection_adapters/sqlserver_adapter'
|
37
|
+
end
|
38
|
+
|
39
|
+
ActiveRecord::Base.logger = Logger.new("#{PROJECT_ROOT}/test/debug.log")
|
40
|
+
ActiveRecord::Base.configurations = {'test' => arconfig[ardb]}
|
41
|
+
ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations['test'])
|
42
|
+
puts "With database: #{ardb}"
|
43
|
+
|
44
|
+
ActiveRecord::Base.connection.class.class_eval do
|
45
|
+
IGNORED_SQL = [/^PRAGMA/, /^SELECT currval/, /^SELECT CAST/, /^SELECT @@IDENTITY/, /^SELECT @@ROWCOUNT/]
|
46
|
+
def execute_with_query_record(sql, name = nil, &block)
|
47
|
+
$queries_executed ||= []
|
48
|
+
$queries_executed << sql unless IGNORED_SQL.any? { |r| sql =~ r }
|
49
|
+
execute_without_query_record(sql, name, &block)
|
50
|
+
end
|
51
|
+
alias_method_chain :execute, :query_record
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
# Creating the DB schema and DB specific tasks.
|
56
|
+
|
57
|
+
ActiveRecord::Migration.verbose = false
|
58
|
+
|
59
|
+
load(File.dirname(__FILE__)+"/schema.rb")
|
60
|
+
|
61
|
+
case ardb
|
62
|
+
when 'postgresql'
|
63
|
+
ActiveRecord::Base.connection.execute "DROP SEQUENCE widgets_seq;" rescue nil
|
64
|
+
ActiveRecord::Base.connection.remove_column :widget_versions, :id
|
65
|
+
ActiveRecord::Base.connection.execute "CREATE SEQUENCE widgets_seq START 101;"
|
66
|
+
ActiveRecord::Base.connection.execute "ALTER TABLE widget_versions ADD COLUMN id INTEGER PRIMARY KEY DEFAULT nextval('widgets_seq');"
|
67
|
+
end
|
68
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
|
2
|
+
sqlite3:
|
3
|
+
adapter: sqlite3
|
4
|
+
database: ":memory:"
|
5
|
+
|
6
|
+
postgresql:
|
7
|
+
adapter: postgresql
|
8
|
+
username: postgres
|
9
|
+
password: postgres
|
10
|
+
database: acts_as_versioned_plugin_test
|
11
|
+
min_messages: ERROR
|
12
|
+
|
13
|
+
mysql:
|
14
|
+
adapter: mysql
|
15
|
+
host: localhost
|
16
|
+
username: rails
|
17
|
+
password:
|
18
|
+
database: acts_as_versioned_plugin_test
|
19
|
+
|
20
|
+
sqlserver:
|
21
|
+
adapter: sqlserver
|
22
|
+
mode: ODBC
|
23
|
+
username: rails
|
24
|
+
password:
|
25
|
+
dsn: acts_as_versioned_plugin_test
|
26
|
+
|
data/test/lib/schema.rb
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
ActiveRecord::Base.class_eval do
|
2
|
+
|
3
|
+
connection.create_table :pages, :force => true do |t|
|
4
|
+
t.column :version, :integer
|
5
|
+
t.column :title, :string, :limit => 255
|
6
|
+
t.column :body, :text
|
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
|
+
connection.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
|
+
end
|
23
|
+
|
24
|
+
connection.add_index :page_versions, [:page_id, :version], :unique => true
|
25
|
+
|
26
|
+
connection.create_table :authors, :force => true do |t|
|
27
|
+
t.column :page_id, :integer
|
28
|
+
t.column :name, :string
|
29
|
+
end
|
30
|
+
|
31
|
+
connection.create_table :locked_pages, :force => true do |t|
|
32
|
+
t.column :lock_version, :integer
|
33
|
+
t.column :title, :string, :limit => 255
|
34
|
+
t.column :body, :text
|
35
|
+
t.column :type, :string, :limit => 255
|
36
|
+
end
|
37
|
+
|
38
|
+
connection.create_table :locked_pages_revisions, :force => true do |t|
|
39
|
+
t.column :page_id, :integer
|
40
|
+
t.column :lock_version, :integer
|
41
|
+
t.column :title, :string, :limit => 255
|
42
|
+
t.column :body, :text
|
43
|
+
t.column :version_type, :string, :limit => 255
|
44
|
+
t.column :updated_at, :datetime
|
45
|
+
end
|
46
|
+
|
47
|
+
connection.add_index :locked_pages_revisions, [:page_id, :lock_version], :unique => true
|
48
|
+
|
49
|
+
connection.create_table :widgets, :force => true do |t|
|
50
|
+
t.column :name, :string, :limit => 50
|
51
|
+
t.column :foo, :string
|
52
|
+
t.column :version, :integer
|
53
|
+
t.column :updated_at, :datetime
|
54
|
+
end
|
55
|
+
|
56
|
+
connection.create_table :widget_versions, :force => true do |t|
|
57
|
+
t.column :widget_id, :integer
|
58
|
+
t.column :name, :string, :limit => 50
|
59
|
+
t.column :version, :integer
|
60
|
+
t.column :updated_at, :datetime
|
61
|
+
end
|
62
|
+
|
63
|
+
connection.add_index :widget_versions, [:widget_id, :version], :unique => true
|
64
|
+
|
65
|
+
connection.create_table :landmarks, :force => true do |t|
|
66
|
+
t.column :name, :string
|
67
|
+
t.column :latitude, :float
|
68
|
+
t.column :longitude, :float
|
69
|
+
t.column :doesnt_trigger_version, :string
|
70
|
+
t.column :version, :integer
|
71
|
+
end
|
72
|
+
|
73
|
+
connection.create_table :landmark_versions, :force => true do |t|
|
74
|
+
t.column :landmark_id, :integer
|
75
|
+
t.column :name, :string
|
76
|
+
t.column :latitude, :float
|
77
|
+
t.column :longitude, :float
|
78
|
+
t.column :doesnt_trigger_version, :string
|
79
|
+
t.column :version, :integer
|
80
|
+
end
|
81
|
+
|
82
|
+
connection.add_index :landmark_versions, [:landmark_id, :version], :unique => true
|
83
|
+
|
84
|
+
connection.create_table :things, :force => true do |t|
|
85
|
+
t.column :title, :text
|
86
|
+
t.column :price, :decimal, :precision => 7, :scale => 2
|
87
|
+
t.column :type, :string
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'models/thing'
|
3
|
+
|
4
|
+
class MigrationTest < AAVTestCase
|
5
|
+
|
6
|
+
self.use_transactional_fixtures = false
|
7
|
+
|
8
|
+
setup :migrate_up, :create_thing
|
9
|
+
teardown :migrate_down
|
10
|
+
|
11
|
+
|
12
|
+
test "that the price column has remembered its value correctly" do
|
13
|
+
assert_equal @thing.price, @thing.versions.first.price
|
14
|
+
assert_equal @thing.title, @thing.versions.first.title
|
15
|
+
assert_equal @thing[:type], @thing.versions.first[:type]
|
16
|
+
end
|
17
|
+
|
18
|
+
test "to make sure that the precision of the price column has been preserved" do
|
19
|
+
assert_equal 7, Thing::Version.columns.find{|c| c.name == "price"}.precision
|
20
|
+
assert_equal 2, Thing::Version.columns.find{|c| c.name == "price"}.scale
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
protected
|
25
|
+
|
26
|
+
def migrate_up
|
27
|
+
ActiveRecord::Migrator.up(MIGRATIONS_ROOT)
|
28
|
+
Thing.reset_column_information
|
29
|
+
end
|
30
|
+
|
31
|
+
def create_thing
|
32
|
+
@thing = Thing.create :title => 'blah blah', :price => 123.45, :type => 'Thing'
|
33
|
+
end
|
34
|
+
|
35
|
+
def migrate_down
|
36
|
+
ActiveRecord::Migrator.down(MIGRATIONS_ROOT)
|
37
|
+
ActiveRecord::Base.connection.initialize_schema_migrations_table
|
38
|
+
ActiveRecord::Base.connection.assume_migrated_upto_version(0)
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
end
|
43
|
+
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class AddVersionedTables < ActiveRecord::Migration
|
2
|
+
|
3
|
+
def self.up
|
4
|
+
drop_table :things rescue nil
|
5
|
+
drop_table :thing_versions rescue nil
|
6
|
+
create_table :things do |t|
|
7
|
+
t.column :title, :text
|
8
|
+
t.column :price, :decimal, :precision => 7, :scale => 2
|
9
|
+
t.column :type, :string
|
10
|
+
end
|
11
|
+
Thing.create_versioned_table
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.down
|
15
|
+
drop_table :things rescue nil
|
16
|
+
drop_table :thing_versions rescue nil
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
data/test/models/page.rb
ADDED
@@ -0,0 +1,38 @@
|
|
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 :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
|
+
def feeling_good?
|
14
|
+
@@feeling_good == true
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
module LockedPageExtension
|
20
|
+
def hello_world
|
21
|
+
'hello_world'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class LockedPage < ActiveRecord::Base
|
26
|
+
acts_as_versioned \
|
27
|
+
:inheritance_column => :version_type,
|
28
|
+
:foreign_key => :page_id,
|
29
|
+
:table_name => :locked_pages_revisions,
|
30
|
+
:class_name => 'LockedPageRevision',
|
31
|
+
:version_column => :lock_version,
|
32
|
+
:limit => 2,
|
33
|
+
:if_changed => :title,
|
34
|
+
:extend => LockedPageExtension
|
35
|
+
end
|
36
|
+
|
37
|
+
class SpecialLockedPage < LockedPage
|
38
|
+
end
|