Commit 4001b435cc8e42f14a80853eae274b6472b95a21

Authored by Rodrigo Souto
1 parent 8042c0ea

rails3: update acts_as_versioned to a rails3 compatible version

Showing 28 changed files with 513 additions and 1240 deletions   Show diff stats
vendor/plugins/acts_as_versioned/.document 0 → 100644
... ... @@ -0,0 +1,5 @@
  1 +README.rdoc
  2 +lib/**/*.rb
  3 +bin/*
  4 +features/**/*.feature
  5 +LICENSE
... ...
vendor/plugins/acts_as_versioned/.rvmrc 0 → 100644
... ... @@ -0,0 +1 @@
  1 +rvm --create use 1.9.2@acts_as_versioned
... ...
vendor/plugins/acts_as_versioned/CHANGELOG
... ... @@ -1,82 +0,0 @@
1   -*GIT* (version numbers are overrated)
2   -
3   -* (16 Jun 2008) Backwards Compatibility is overrated (big updates for rails 2.1)
4   -
5   - * Use ActiveRecord 2.1's dirty attribute checking instead [Asa Calow]
6   - * Remove last traces of #non_versioned_fields
7   - * Remove AR::Base.find_version and AR::Base.find_versions, rely on AR association proxies and named_scope
8   - * Remove #versions_count, rely on AR association counter caching.
9   - * Remove #versioned_attributes, basically the same as AR::Base.versioned_columns
10   -
11   -* (5 Oct 2006) Allow customization of #versions association options [Dan Peterson]
12   -
13   -*0.5.1*
14   -
15   -* (8 Aug 2006) Versioned models now belong to the unversioned model. @article_version.article.class => Article [Aslak Hellesoy]
16   -
17   -*0.5* # do versions even matter for plugins?
18   -
19   -* (21 Apr 2006) Added without_locking and without_revision methods.
20   -
21   - Foo.without_revision do
22   - @foo.update_attributes ...
23   - end
24   -
25   -*0.4*
26   -
27   -* (28 March 2006) Rename non_versioned_fields to non_versioned_columns (old one is kept for compatibility).
28   -* (28 March 2006) Made explicit documentation note that string column names are required for non_versioned_columns.
29   -
30   -*0.3.1*
31   -
32   -* (7 Jan 2006) explicitly set :foreign_key option for the versioned model's belongs_to assocation for STI [Caged]
33   -* (7 Jan 2006) added tests to prove has_many :through joins work
34   -
35   -*0.3*
36   -
37   -* (2 Jan 2006) added ability to share a mixin with versioned class
38   -* (2 Jan 2006) changed the dynamic version model to MyModel::Version
39   -
40   -*0.2.4*
41   -
42   -* (27 Nov 2005) added note about possible destructive behavior of if_changed? [Michael Schuerig]
43   -
44   -*0.2.3*
45   -
46   -* (12 Nov 2005) fixed bug with old behavior of #blank? [Michael Schuerig]
47   -* (12 Nov 2005) updated tests to use ActiveRecord Schema
48   -
49   -*0.2.2*
50   -
51   -* (3 Nov 2005) added documentation note to #acts_as_versioned [Martin Jul]
52   -
53   -*0.2.1*
54   -
55   -* (6 Oct 2005) renamed dirty? to changed? to keep it uniform. it was aliased to keep it backwards compatible.
56   -
57   -*0.2*
58   -
59   -* (6 Oct 2005) added find_versions and find_version class methods.
60   -
61   -* (6 Oct 2005) removed transaction from create_versioned_table().
62   - this way you can specify your own transaction around a group of operations.
63   -
64   -* (30 Sep 2005) fixed bug where find_versions() would order by 'version' twice. (found by Joe Clark)
65   -
66   -* (26 Sep 2005) added :sequence_name option to acts_as_versioned to set the sequence name on the versioned model
67   -
68   -*0.1.3* (18 Sep 2005)
69   -
70   -* First RubyForge release
71   -
72   -*0.1.2*
73   -
74   -* check if module is already included when acts_as_versioned is called
75   -
76   -*0.1.1*
77   -
78   -* Adding tests and rdocs
79   -
80   -*0.1*
81   -
82   -* Initial transfer from Rails ticket: http://dev.rubyonrails.com/ticket/1974
83 0 \ No newline at end of file
vendor/plugins/acts_as_versioned/Gemfile 0 → 100644
... ... @@ -0,0 +1,7 @@
  1 +source 'http://rubygems.org'
  2 +
  3 +group :development do
  4 + gem 'rails', '~> 3.1.0'
  5 + gem 'sqlite3'
  6 + gem 'echoe'
  7 +end
... ...
vendor/plugins/acts_as_versioned/Gemfile.lock 0 → 100644
... ... @@ -0,0 +1,101 @@
  1 +GEM
  2 + remote: http://rubygems.org/
  3 + specs:
  4 + actionmailer (3.1.4)
  5 + actionpack (= 3.1.4)
  6 + mail (~> 2.3.0)
  7 + actionpack (3.1.4)
  8 + activemodel (= 3.1.4)
  9 + activesupport (= 3.1.4)
  10 + builder (~> 3.0.0)
  11 + erubis (~> 2.7.0)
  12 + i18n (~> 0.6)
  13 + rack (~> 1.3.6)
  14 + rack-cache (~> 1.1)
  15 + rack-mount (~> 0.8.2)
  16 + rack-test (~> 0.6.1)
  17 + sprockets (~> 2.0.3)
  18 + activemodel (3.1.4)
  19 + activesupport (= 3.1.4)
  20 + builder (~> 3.0.0)
  21 + i18n (~> 0.6)
  22 + activerecord (3.1.4)
  23 + activemodel (= 3.1.4)
  24 + activesupport (= 3.1.4)
  25 + arel (~> 2.2.3)
  26 + tzinfo (~> 0.3.29)
  27 + activeresource (3.1.4)
  28 + activemodel (= 3.1.4)
  29 + activesupport (= 3.1.4)
  30 + activesupport (3.1.4)
  31 + multi_json (~> 1.0)
  32 + allison (2.0.3)
  33 + arel (2.2.3)
  34 + builder (3.0.0)
  35 + echoe (4.6.3)
  36 + allison (>= 2.0.3)
  37 + gemcutter (>= 0.7.0)
  38 + rake (>= 0.9.2)
  39 + rdoc (>= 3.6.1)
  40 + rubyforge (>= 2.0.4)
  41 + erubis (2.7.0)
  42 + gemcutter (0.7.1)
  43 + hike (1.2.1)
  44 + i18n (0.6.0)
  45 + json (1.6.6)
  46 + json_pure (1.7.7)
  47 + mail (2.3.3)
  48 + i18n (>= 0.4.0)
  49 + mime-types (~> 1.16)
  50 + treetop (~> 1.4.8)
  51 + mime-types (1.18)
  52 + multi_json (1.2.0)
  53 + polyglot (0.3.3)
  54 + rack (1.3.6)
  55 + rack-cache (1.2)
  56 + rack (>= 0.4)
  57 + rack-mount (0.8.3)
  58 + rack (>= 1.0.0)
  59 + rack-ssl (1.3.2)
  60 + rack
  61 + rack-test (0.6.1)
  62 + rack (>= 1.0)
  63 + rails (3.1.4)
  64 + actionmailer (= 3.1.4)
  65 + actionpack (= 3.1.4)
  66 + activerecord (= 3.1.4)
  67 + activeresource (= 3.1.4)
  68 + activesupport (= 3.1.4)
  69 + bundler (~> 1.0)
  70 + railties (= 3.1.4)
  71 + railties (3.1.4)
  72 + actionpack (= 3.1.4)
  73 + activesupport (= 3.1.4)
  74 + rack-ssl (~> 1.3.2)
  75 + rake (>= 0.8.7)
  76 + rdoc (~> 3.4)
  77 + thor (~> 0.14.6)
  78 + rake (0.9.2.2)
  79 + rdoc (3.12)
  80 + json (~> 1.4)
  81 + rubyforge (2.0.4)
  82 + json_pure (>= 1.1.7)
  83 + sprockets (2.0.3)
  84 + hike (~> 1.2)
  85 + rack (~> 1.0)
  86 + tilt (~> 1.1, != 1.3.0)
  87 + sqlite3 (1.3.5)
  88 + thor (0.14.6)
  89 + tilt (1.3.3)
  90 + treetop (1.4.10)
  91 + polyglot
  92 + polyglot (>= 0.3.1)
  93 + tzinfo (0.3.33)
  94 +
  95 +PLATFORMS
  96 + ruby
  97 +
  98 +DEPENDENCIES
  99 + echoe
  100 + rails (~> 3.1.0)
  101 + sqlite3
... ...
vendor/plugins/acts_as_versioned/Manifest 0 → 100644
... ... @@ -0,0 +1,11 @@
  1 +Gemfile
  2 +Gemfile.lock
  3 +MIT-LICENSE
  4 +Manifest
  5 +README.md
  6 +RUNNING_UNIT_TESTS
  7 +Rakefile
  8 +acts_as_versioned.gemspec
  9 +acts_as_versioned_plugin.sqlite3.db
  10 +init.rb
  11 +lib/acts_as_versioned.rb
... ...
vendor/plugins/acts_as_versioned/README
... ... @@ -1,28 +0,0 @@
1   -= acts_as_versioned
2   -
3   -This library adds simple versioning to an ActiveRecord module. ActiveRecord is required.
4   -
5   -== Resources
6   -
7   -Install
8   -
9   -* gem install acts_as_versioned
10   -
11   -Rubyforge project
12   -
13   -* http://rubyforge.org/projects/ar-versioned
14   -
15   -RDocs
16   -
17   -* http://ar-versioned.rubyforge.org
18   -
19   -Subversion
20   -
21   -* http://techno-weenie.net/svn/projects/acts_as_versioned
22   -
23   -Collaboa
24   -
25   -* http://collaboa.techno-weenie.net/repository/browse/acts_as_versioned
26   -
27   -Special thanks to Dreamer on ##rubyonrails for help in early testing. His ServerSideWiki (http://serversidewiki.com)
28   -was the first project to use acts_as_versioned <em>in the wild</em>.
29 0 \ No newline at end of file
vendor/plugins/acts_as_versioned/README.md 0 → 100644
... ... @@ -0,0 +1,120 @@
  1 +## About ##
  2 +=====
  3 +
  4 +acts_as_versioned is a gem for Rails 3.1 & 3.2 to enable easy versioning of models. As a versioned model is updated revisions are kept in a seperate table, providing a record of what changed.
  5 +
  6 +## Getting Started ##
  7 +=====
  8 +
  9 +In your Gemfile simply include:
  10 +
  11 + gem 'acts_as_versioned', :git => 'https://github.com/jwhitehorn/acts_as_versioned.git'
  12 +
  13 +The next time you run `bundle install` you'll be all set to start using acts_as_versioned.
  14 +
  15 +## Usage ##
  16 +=====
  17 +
  18 +#### Versioning a Model ####
  19 +By default acts_as_versioned is unobtrusive. You will need to explicitly state which models to version. To do so, add the line `acts_as_versioned` to your model, like so:
  20 +
  21 + class MyModel < ActiveRecord::Base
  22 + acts_as_versioned
  23 + #...
  24 + end
  25 +
  26 +Next we need to create a migration to setup our versioning tables:
  27 +
  28 + bundle exec rails generate migration AddVersioningToMyModel
  29 +
  30 +Once that is completed, edit the generated migration. acts_as_versioned patches your model to add a `create_versioned_table` and `drop_versioned_table` method. A migration for `MyModel` (assuming MyModel already existed) might look like:
  31 +
  32 + class AddVersioningToMyModel < ActiveRecord::Migration
  33 + def self.up
  34 + MyModel.create_versioned_table
  35 + end
  36 +
  37 + def self.down
  38 + MyModel.drop_versioned_table
  39 + end
  40 + end
  41 +
  42 +Execute your migration:
  43 +
  44 + bundle exec rake db:migrate
  45 +
  46 +And you're finished! Without any addition work, `MyModel` is being versioned.
  47 +
  48 +#### Excluding attributes from versioning ####
  49 +
  50 +Sometime you want to exclude an attribute of a model from being versioned. That can be accomplished with the `:except` paramter to `acts_as_versioned`:
  51 +
  52 + class MyMode < ActiveRecord::Base
  53 + acts_as_versioned :except => :some_attr_i_dont_want_versioned
  54 +
  55 + end
  56 +
  57 +
  58 +#### Revisions ####
  59 +
  60 +Recording a history of changes to a model is only useful if you can do something with that data. With acts_as_versioned there are several ways you can interact with a model's revisions.
  61 +
  62 +##### Version Number #####
  63 +To determine what the current version number for a model is:
  64 +
  65 + model.version
  66 +
  67 +The `version` attribute is available for both the actual model, and also any revisions of a model. Thusly, the following is valid:
  68 +
  69 + model.versions.last.version
  70 +
  71 +##### Revisions List #####
  72 +As alluded to above, you can get an array of revisions of a model via the `versions` attribute:
  73 +
  74 + model.versions
  75 +
  76 +The returned objects are of a type `MyModel::Version` where `MyModel` is the model you are working with. These objects have identical fields to `MyModel`. So, if `MyModel` had a `name` attribute, you could also say:
  77 +
  78 + model.versions.last.name
  79 +
  80 +##### Reverting to a Revision #####
  81 +To revert a model to an older revision, simply call `revert_to` with the version number you desire to rever to:
  82 +
  83 + model.revert_to(version_number)
  84 +
  85 +##### Saving Without Revisions #####
  86 +Occasionally you might need to save a model without necessary creating revisions. To do so, use the `save_without_revision` method:
  87 +
  88 + model.save_without_revision
  89 +
  90 +
  91 +#### Migrations ####
  92 +Adding a field to your model does not automatically add it to the versioning table. So, when you add new fields, be sure to add them to both:
  93 +
  94 + class AddNewFieldToMyModel < ActiveRecord::Migration
  95 + def change
  96 + add_column :my_models, :new_field_, :string
  97 + add_column :my_model_versions, :new_field_, :string
  98 + end
  99 + end
  100 +
  101 +#### Version Class ####
  102 +As has been stated, the versioned data is stored seperately from the main class. This also implies that `model.versions` returns an area of object of a class _other_ than `MyModel` (where `model` is an instance of `MyModel`, keeping with our working example). The instances returned are actually of type `MyModel::Version`. With this, comes the fact that any methods, associations, etc. defined on `MyModel` are not present on `MyModel::Version`.
  103 +
  104 +While this sounds obvious, it can some times be unexpected. Especially when acts_as_versioned make it so easy to grab historical records from a live record. A common scenario where this can come up is associations.
  105 +
  106 +Say `MyModel` belongs to `TheMan`. Also, assume that you want to find out where (in the past) a particular instance of `MyModel` was updated in regards to it's association to `TheMan`. You could write that as:
  107 +
  108 + model.versions.keep_if { |m| m.the_man != current_man }.last
  109 +
  110 +However, this will not work. This is because `MyModel::Version` does _not_ belong to `TheMan`. You could compare ids here, or you could patch `MyModel::Version` to belong to `TheMan` like:
  111 +
  112 + class MyModel
  113 + acts_as_versioned
  114 + belongs_to :the_men
  115 + #some stuff
  116 +
  117 + class Version
  118 + belongs_to :the_men
  119 + end
  120 + end
0 121 \ No newline at end of file
... ...
vendor/plugins/acts_as_versioned/Rakefile
1   -require 'rubygems'
2   -
3   -require 'rake/rdoctask'
4   -require 'rake/packagetask'
5   -require 'rake/gempackagetask'
6   -require 'rake/testtask'
7   -require 'rake/contrib/rubyforgepublisher'
8   -
9   -PKG_NAME = 'acts_as_versioned'
10   -PKG_VERSION = '0.3.1'
11   -PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
12   -PROD_HOST = "technoweenie@bidwell.textdrive.com"
13   -RUBY_FORGE_PROJECT = 'ar-versioned'
14   -RUBY_FORGE_USER = 'technoweenie'
15   -
16   -desc 'Default: run unit tests.'
17   -task :default => :test
18   -
19   -desc 'Test the calculations plugin.'
20   -Rake::TestTask.new(:test) do |t|
21   - t.libs << 'lib'
22   - t.pattern = 'test/**/*_test.rb'
23   - t.verbose = true
24   -end
25   -
26   -desc 'Generate documentation for the calculations plugin.'
27   -Rake::RDocTask.new(:rdoc) do |rdoc|
28   - rdoc.rdoc_dir = 'rdoc'
29   - rdoc.title = "#{PKG_NAME} -- Simple versioning with active record models"
30   - rdoc.options << '--line-numbers --inline-source'
31   - rdoc.rdoc_files.include('README', 'CHANGELOG', 'RUNNING_UNIT_TESTS')
32   - rdoc.rdoc_files.include('lib/**/*.rb')
33   -end
34   -
35   -spec = Gem::Specification.new do |s|
36   - s.name = PKG_NAME
37   - s.version = PKG_VERSION
38   - s.platform = Gem::Platform::RUBY
39   - s.summary = "Simple versioning with active record models"
40   - s.files = FileList["{lib,test}/**/*"].to_a + %w(README MIT-LICENSE CHANGELOG RUNNING_UNIT_TESTS)
41   - s.files.delete "acts_as_versioned_plugin.sqlite.db"
42   - s.files.delete "acts_as_versioned_plugin.sqlite3.db"
43   - s.files.delete "test/debug.log"
44   - s.require_path = 'lib'
45   - s.autorequire = 'acts_as_versioned'
46   - s.has_rdoc = true
47   - s.test_files = Dir['test/**/*_test.rb']
48   - s.add_dependency 'activerecord', '>= 1.10.1'
49   - s.add_dependency 'activesupport', '>= 1.1.1'
50   - s.author = "Rick Olson"
51   - s.email = "technoweenie@gmail.com"
52   - s.homepage = "http://techno-weenie.net"
53   -end
54   -
55   -Rake::GemPackageTask.new(spec) do |pkg|
56   - pkg.need_tar = true
57   -end
58   -
59   -desc "Publish the API documentation"
60   -task :pdoc => [:rdoc] do
61   - Rake::RubyForgePublisher.new(RUBY_FORGE_PROJECT, RUBY_FORGE_USER).upload
62   -end
63   -
64   -desc 'Publish the gem and API docs'
65   -task :publish => [:pdoc, :rubyforge_upload]
66   -
67   -desc "Publish the release files to RubyForge."
68   -task :rubyforge_upload => :package do
69   - files = %w(gem tgz).map { |ext| "pkg/#{PKG_FILE_NAME}.#{ext}" }
70   -
71   - if RUBY_FORGE_PROJECT then
72   - require 'net/http'
73   - require 'open-uri'
74   -
75   - project_uri = "http://rubyforge.org/projects/#{RUBY_FORGE_PROJECT}/"
76   - project_data = open(project_uri) { |data| data.read }
77   - group_id = project_data[/[?&]group_id=(\d+)/, 1]
78   - raise "Couldn't get group id" unless group_id
79   -
80   - # This echos password to shell which is a bit sucky
81   - if ENV["RUBY_FORGE_PASSWORD"]
82   - password = ENV["RUBY_FORGE_PASSWORD"]
83   - else
84   - print "#{RUBY_FORGE_USER}@rubyforge.org's password: "
85   - password = STDIN.gets.chomp
86   - end
87   -
88   - login_response = Net::HTTP.start("rubyforge.org", 80) do |http|
89   - data = [
90   - "login=1",
91   - "form_loginname=#{RUBY_FORGE_USER}",
92   - "form_pw=#{password}"
93   - ].join("&")
94   - http.post("/account/login.php", data)
95   - end
96   -
97   - cookie = login_response["set-cookie"]
98   - raise "Login failed" unless cookie
99   - headers = { "Cookie" => cookie }
100   -
101   - release_uri = "http://rubyforge.org/frs/admin/?group_id=#{group_id}"
102   - release_data = open(release_uri, headers) { |data| data.read }
103   - package_id = release_data[/[?&]package_id=(\d+)/, 1]
104   - raise "Couldn't get package id" unless package_id
105   -
106   - first_file = true
107   - release_id = ""
108   -
109   - files.each do |filename|
110   - basename = File.basename(filename)
111   - file_ext = File.extname(filename)
112   - file_data = File.open(filename, "rb") { |file| file.read }
113   -
114   - puts "Releasing #{basename}..."
115   -
116   - release_response = Net::HTTP.start("rubyforge.org", 80) do |http|
117   - release_date = Time.now.strftime("%Y-%m-%d %H:%M")
118   - type_map = {
119   - ".zip" => "3000",
120   - ".tgz" => "3110",
121   - ".gz" => "3110",
122   - ".gem" => "1400"
123   - }; type_map.default = "9999"
124   - type = type_map[file_ext]
125   - boundary = "rubyqMY6QN9bp6e4kS21H4y0zxcvoor"
126   -
127   - query_hash = if first_file then
128   - {
129   - "group_id" => group_id,
130   - "package_id" => package_id,
131   - "release_name" => PKG_FILE_NAME,
132   - "release_date" => release_date,
133   - "type_id" => type,
134   - "processor_id" => "8000", # Any
135   - "release_notes" => "",
136   - "release_changes" => "",
137   - "preformatted" => "1",
138   - "submit" => "1"
139   - }
140   - else
141   - {
142   - "group_id" => group_id,
143   - "release_id" => release_id,
144   - "package_id" => package_id,
145   - "step2" => "1",
146   - "type_id" => type,
147   - "processor_id" => "8000", # Any
148   - "submit" => "Add This File"
149   - }
150   - end
151   -
152   - query = "?" + query_hash.map do |(name, value)|
153   - [name, URI.encode(value)].join("=")
154   - end.join("&")
155   -
156   - data = [
157   - "--" + boundary,
158   - "Content-Disposition: form-data; name=\"userfile\"; filename=\"#{basename}\"",
159   - "Content-Type: application/octet-stream",
160   - "Content-Transfer-Encoding: binary",
161   - "", file_data, ""
162   - ].join("\x0D\x0A")
163   -
164   - release_headers = headers.merge(
165   - "Content-Type" => "multipart/form-data; boundary=#{boundary}"
166   - )
167   -
168   - target = first_file ? "/frs/admin/qrs.php" : "/frs/admin/editrelease.php"
169   - http.post(target + query, data, release_headers)
170   - end
171   -
172   - if first_file then
173   - release_id = release_response.body[/release_id=(\d+)/, 1]
174   - raise("Couldn't get release id") unless release_id
175   - end
176   -
177   - first_file = false
178   - end
179   - end
180   -end
181 1 \ No newline at end of file
  2 +require 'rubygems'
  3 +require 'rake'
  4 +require 'echoe'
  5 +
  6 +Echoe.new('acts_as_versioned', '3.2.1') do |p|
  7 + p.description = "Active Record model versioning"
  8 + p.url = "http://github.com/jwhitehorn/acts_as_versioned"
  9 + p.author = "Jason Whitehorn"
  10 + p.email = "jason.whitehorn@gmail.com"
  11 + p.dependencies = ['activerecord']
  12 +end
  13 +
  14 +Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
182 15 \ No newline at end of file
... ...
vendor/plugins/acts_as_versioned/VERSION.yml
... ... @@ -1,4 +0,0 @@
1   ----
2   -:patch: 2
3   -:major: 0
4   -:minor: 5
vendor/plugins/acts_as_versioned/acts_as_versioned.gemspec
1 1 # -*- encoding: utf-8 -*-
2 2  
3 3 Gem::Specification.new do |s|
4   - s.name = %q{acts_as_versioned}
5   - s.version = "0.5.2"
  4 + s.name = "acts_as_versioned"
  5 + s.version = "3.2.1"
6 6  
7   - s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8   - s.authors = ["technoweenie"]
9   - s.date = %q{2009-01-20}
10   - s.description = %q{TODO}
11   - s.email = %q{technoweenie@bidwell.textdrive.com}
12   - s.files = ["VERSION.yml", "lib/acts_as_versioned.rb", "test/abstract_unit.rb", "test/database.yml", "test/fixtures", "test/fixtures/authors.yml", "test/fixtures/landmark.rb", "test/fixtures/landmark_versions.yml", "test/fixtures/landmarks.yml", "test/fixtures/locked_pages.yml", "test/fixtures/locked_pages_revisions.yml", "test/fixtures/migrations", "test/fixtures/migrations/1_add_versioned_tables.rb", "test/fixtures/page.rb", "test/fixtures/page_versions.yml", "test/fixtures/pages.yml", "test/fixtures/widget.rb", "test/migration_test.rb", "test/schema.rb", "test/versioned_test.rb"]
13   - s.has_rdoc = true
14   - s.homepage = %q{http://github.com/technoweenie/acts_as_versioned}
15   - s.rdoc_options = ["--inline-source", "--charset=UTF-8"]
  7 + s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
  8 + s.authors = ["Jason Whitehorn"]
  9 + s.date = "2013-05-03"
  10 + s.description = "Active Record model versioning"
  11 + s.email = "jason.whitehorn@gmail.com"
  12 + s.extra_rdoc_files = ["README.md", "lib/acts_as_versioned.rb"]
  13 + s.files = ["Gemfile", "Gemfile.lock", "MIT-LICENSE", "Manifest", "README.md", "RUNNING_UNIT_TESTS", "Rakefile", "acts_as_versioned.gemspec", "acts_as_versioned_plugin.sqlite3.db", "init.rb", "lib/acts_as_versioned.rb"]
  14 + s.homepage = "http://github.com/jwhitehorn/acts_as_versioned"
  15 + s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Acts_as_versioned", "--main", "README.md"]
16 16 s.require_paths = ["lib"]
17   - s.rubygems_version = %q{1.3.1}
18   - s.summary = %q{TODO}
  17 + s.rubyforge_project = "acts_as_versioned"
  18 + s.rubygems_version = "1.8.25"
  19 + s.summary = "Active Record model versioning"
19 20  
20 21 if s.respond_to? :specification_version then
21   - current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
22   - s.specification_version = 2
  22 + s.specification_version = 3
23 23  
24   - if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
  24 + if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
  25 + s.add_runtime_dependency(%q<activerecord>, [">= 0"])
25 26 else
  27 + s.add_dependency(%q<activerecord>, [">= 0"])
26 28 end
27 29 else
  30 + s.add_dependency(%q<activerecord>, [">= 0"])
28 31 end
29 32 end
... ...
vendor/plugins/acts_as_versioned/lib/acts_as_versioned.rb
... ... @@ -18,6 +18,7 @@
18 18 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 19 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 20 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  21 +require 'active_support/concern'
21 22  
22 23 module ActiveRecord #:nodoc:
23 24 module Acts #:nodoc:
... ... @@ -66,203 +67,206 @@ module ActiveRecord #:nodoc:
66 67 #
67 68 # See ActiveRecord::Acts::Versioned::ClassMethods#acts_as_versioned for configuration options
68 69 module Versioned
  70 + VERSION = "0.6.0"
69 71 CALLBACKS = [:set_new_version, :save_version, :save_version?]
70   - def self.included(base) # :nodoc:
71   - base.extend ClassMethods
72   - end
73 72  
74   - module ClassMethods
75   - # == Configuration options
76   - #
77   - # * <tt>class_name</tt> - versioned model class name (default: PageVersion in the above example)
78   - # * <tt>table_name</tt> - versioned model table name (default: page_versions in the above example)
79   - # * <tt>foreign_key</tt> - foreign key used to relate the versioned model to the original model (default: page_id in the above example)
80   - # * <tt>inheritance_column</tt> - name of the column to save the model's inheritance_column value for STI. (default: versioned_type)
81   - # * <tt>version_column</tt> - name of the column in the model that keeps the version number (default: version)
82   - # * <tt>sequence_name</tt> - name of the custom sequence to be used by the versioned model.
83   - # * <tt>limit</tt> - number of revisions to keep, defaults to unlimited
84   - # * <tt>if</tt> - symbol of method to check before saving a new version. If this method returns false, a new version is not saved.
85   - # For finer control, pass either a Proc or modify Model#version_condition_met?
86   - #
87   - # acts_as_versioned :if => Proc.new { |auction| !auction.expired? }
88   - #
89   - # or...
90   - #
91   - # class Auction
92   - # def version_condition_met? # totally bypasses the <tt>:if</tt> option
93   - # !expired?
94   - # end
95   - # end
96   - #
97   - # * <tt>if_changed</tt> - Simple way of specifying attributes that are required to be changed before saving a model. This takes
98   - # either a symbol or array of symbols.
99   - #
100   - # * <tt>extend</tt> - Lets you specify a module to be mixed in both the original and versioned models. You can also just pass a block
101   - # to create an anonymous mixin:
102   - #
103   - # class Auction
104   - # acts_as_versioned do
105   - # def started?
106   - # !started_at.nil?
107   - # end
108   - # end
109   - # end
110   - #
111   - # or...
112   - #
113   - # module AuctionExtension
114   - # def started?
115   - # !started_at.nil?
116   - # end
117   - # end
118   - # class Auction
119   - # acts_as_versioned :extend => AuctionExtension
120   - # end
121   - #
122   - # Example code:
123   - #
124   - # @auction = Auction.find(1)
125   - # @auction.started?
126   - # @auction.versions.first.started?
127   - #
128   - # == Database Schema
129   - #
130   - # The model that you're versioning needs to have a 'version' attribute. The model is versioned
131   - # into a table called #{model}_versions where the model name is singlular. The _versions table should
132   - # contain all the fields you want versioned, the same version column, and a #{model}_id foreign key field.
133   - #
134   - # A lock_version field is also accepted if your model uses Optimistic Locking. If your table uses Single Table inheritance,
135   - # then that field is reflected in the versioned model as 'versioned_type' by default.
136   - #
137   - # Acts_as_versioned comes prepared with the ActiveRecord::Acts::Versioned::ActMethods::ClassMethods#create_versioned_table
138   - # method, perfect for a migration. It will also create the version column if the main model does not already have it.
139   - #
140   - # class AddVersions < ActiveRecord::Migration
141   - # def self.up
142   - # # create_versioned_table takes the same options hash
143   - # # that create_table does
144   - # Post.create_versioned_table
145   - # end
146   - #
147   - # def self.down
148   - # Post.drop_versioned_table
149   - # end
150   - # end
151   - #
152   - # == Changing What Fields Are Versioned
153   - #
154   - # By default, acts_as_versioned will version all but these fields:
155   - #
156   - # [self.primary_key, inheritance_column, 'version', 'lock_version', versioned_inheritance_column]
157   - #
158   - # You can add or change those by modifying #non_versioned_columns. Note that this takes strings and not symbols.
159   - #
160   - # class Post < ActiveRecord::Base
161   - # acts_as_versioned
162   - # self.non_versioned_columns << 'comments_count'
163   - # end
164   - #
165   - def acts_as_versioned(options = {}, &extension)
166   - # don't allow multiple calls
167   - return if self.included_modules.include?(ActiveRecord::Acts::Versioned::ActMethods)
168   -
169   - send :include, ActiveRecord::Acts::Versioned::ActMethods
170   -
171   - cattr_accessor :versioned_class_name, :versioned_foreign_key, :versioned_table_name, :versioned_inheritance_column,
172   - :version_column, :max_version_limit, :track_altered_attributes, :version_condition, :version_sequence_name, :non_versioned_columns,
173   - :version_association_options, :version_if_changed
174   -
175   - self.versioned_class_name = options[:class_name] || "Version"
176   - self.versioned_foreign_key = options[:foreign_key] || self.to_s.foreign_key
177   - self.versioned_table_name = options[:table_name] || "#{table_name_prefix}#{base_class.name.demodulize.underscore}_versions#{table_name_suffix}"
178   - self.versioned_inheritance_column = options[:inheritance_column] || "versioned_#{inheritance_column}"
179   - self.version_column = options[:version_column] || 'version'
180   - self.version_sequence_name = options[:sequence_name]
181   - self.max_version_limit = options[:limit].to_i
182   - self.version_condition = options[:if] || true
183   - self.non_versioned_columns = [self.primary_key, inheritance_column, self.version_column, 'lock_version', versioned_inheritance_column] + options[:non_versioned_columns].to_a.map(&:to_s)
184   - self.version_association_options = {
185   - :class_name => "#{self.to_s}::#{versioned_class_name}",
186   - :foreign_key => versioned_foreign_key,
187   - :dependent => :delete_all
188   - }.merge(options[:association_options] || {})
189   -
190   - if block_given?
191   - extension_module_name = "#{versioned_class_name}Extension"
192   - silence_warnings do
193   - self.const_set(extension_module_name, Module.new(&extension))
194   - end
195   -
196   - options[:extend] = self.const_get(extension_module_name)
  73 + # == Configuration options
  74 + #
  75 + # * <tt>class_name</tt> - versioned model class name (default: PageVersion in the above example)
  76 + # * <tt>table_name</tt> - versioned model table name (default: page_versions in the above example)
  77 + # * <tt>foreign_key</tt> - foreign key used to relate the versioned model to the original model (default: page_id in the above example)
  78 + # * <tt>inheritance_column</tt> - name of the column to save the model's inheritance_column value for STI. (default: versioned_type)
  79 + # * <tt>version_column</tt> - name of the column in the model that keeps the version number (default: version)
  80 + # * <tt>sequence_name</tt> - name of the custom sequence to be used by the versioned model.
  81 + # * <tt>limit</tt> - number of revisions to keep, defaults to unlimited
  82 + # * <tt>if</tt> - symbol of method to check before saving a new version. If this method returns false, a new version is not saved.
  83 + # For finer control, pass either a Proc or modify Model#version_condition_met?
  84 + #
  85 + # acts_as_versioned :if => Proc.new { |auction| !auction.expired? }
  86 + #
  87 + # or...
  88 + #
  89 + # class Auction
  90 + # def version_condition_met? # totally bypasses the <tt>:if</tt> option
  91 + # !expired?
  92 + # end
  93 + # end
  94 + #
  95 + # * <tt>if_changed</tt> - Simple way of specifying attributes that are required to be changed before saving a model. This takes
  96 + # either a symbol or array of symbols.
  97 + #
  98 + # * <tt>extend</tt> - Lets you specify a module to be mixed in both the original and versioned models. You can also just pass a block
  99 + # to create an anonymous mixin:
  100 + #
  101 + # class Auction
  102 + # acts_as_versioned do
  103 + # def started?
  104 + # !started_at.nil?
  105 + # end
  106 + # end
  107 + # end
  108 + #
  109 + # or...
  110 + #
  111 + # module AuctionExtension
  112 + # def started?
  113 + # !started_at.nil?
  114 + # end
  115 + # end
  116 + # class Auction
  117 + # acts_as_versioned :extend => AuctionExtension
  118 + # end
  119 + #
  120 + # Example code:
  121 + #
  122 + # @auction = Auction.find(1)
  123 + # @auction.started?
  124 + # @auction.versions.first.started?
  125 + #
  126 + # == Database Schema
  127 + #
  128 + # The model that you're versioning needs to have a 'version' attribute. The model is versioned
  129 + # into a table called #{model}_versions where the model name is singlular. The _versions table should
  130 + # contain all the fields you want versioned, the same version column, and a #{model}_id foreign key field.
  131 + #
  132 + # A lock_version field is also accepted if your model uses Optimistic Locking. If your table uses Single Table inheritance,
  133 + # then that field is reflected in the versioned model as 'versioned_type' by default.
  134 + #
  135 + # Acts_as_versioned comes prepared with the ActiveRecord::Acts::Versioned::ActMethods::ClassMethods#create_versioned_table
  136 + # method, perfect for a migration. It will also create the version column if the main model does not already have it.
  137 + #
  138 + # class AddVersions < ActiveRecord::Migration
  139 + # def self.up
  140 + # # create_versioned_table takes the same options hash
  141 + # # that create_table does
  142 + # Post.create_versioned_table
  143 + # end
  144 + #
  145 + # def self.down
  146 + # Post.drop_versioned_table
  147 + # end
  148 + # end
  149 + #
  150 + # == Changing What Fields Are Versioned
  151 + #
  152 + # By default, acts_as_versioned will version all but these fields:
  153 + #
  154 + # [self.primary_key, inheritance_column, 'version', 'lock_version', versioned_inheritance_column]
  155 + #
  156 + # You can add or change those by modifying #non_versioned_columns. Note that this takes strings and not symbols.
  157 + #
  158 + # class Post < ActiveRecord::Base
  159 + # acts_as_versioned
  160 + # self.non_versioned_columns << 'comments_count'
  161 + # end
  162 + #
  163 + def acts_as_versioned(options = {}, &extension)
  164 + # don't allow multiple calls
  165 + return if self.included_modules.include?(ActiveRecord::Acts::Versioned::Behaviors)
  166 +
  167 + cattr_accessor :versioned_class_name, :versioned_foreign_key, :versioned_table_name, :versioned_inheritance_column,
  168 + :version_column, :max_version_limit, :track_altered_attributes, :version_condition, :version_sequence_name, :non_versioned_columns,
  169 + :version_association_options, :version_if_changed, :version_except_columns
  170 +
  171 + self.versioned_class_name = options[:class_name] || "Version"
  172 + self.versioned_foreign_key = options[:foreign_key] || self.to_s.foreign_key
  173 + self.versioned_table_name = options[:table_name] || "#{table_name_prefix}#{base_class.name.demodulize.underscore}_versions#{table_name_suffix}"
  174 + self.versioned_inheritance_column = options[:inheritance_column] || "versioned_#{inheritance_column}"
  175 + self.version_column = options[:version_column] || 'version'
  176 + self.version_sequence_name = options[:sequence_name]
  177 + self.max_version_limit = options[:limit].to_i
  178 + self.version_condition = options[:if] || true
  179 + self.version_except_columns = [options[:except]].flatten.map(&:to_s) #these columns are kept in _versioned, but changing them does not excplitly cause a version change
  180 + self.non_versioned_columns = [self.primary_key, inheritance_column, self.version_column, 'lock_version', versioned_inheritance_column] #these columns are excluded from _versions, and changing them does not cause a version change
  181 + self.version_association_options = {
  182 + :class_name => "#{self.to_s}::#{versioned_class_name}",
  183 + :foreign_key => versioned_foreign_key,
  184 + :dependent => :delete_all
  185 + }.merge(options[:association_options] || {})
  186 +
  187 + if block_given?
  188 + extension_module_name = "#{versioned_class_name}Extension"
  189 + silence_warnings do
  190 + self.const_set(extension_module_name, Module.new(&extension))
197 191 end
198 192  
199   - class_eval <<-CLASS_METHODS
200   - has_many :versions, version_association_options do
201   - # finds earliest version of this record
202   - def earliest
203   - @earliest ||= find(:first, :order => '#{version_column}')
204   - end
  193 + options[:extend] = self.const_get(extension_module_name)
  194 + end
205 195  
206   - # find latest version of this record
207   - def latest
208   - @latest ||= find(:first, :order => '#{version_column} desc')
209   - end
210   - end
211   - before_save :set_new_version
212   - after_save :save_version
213   - after_save :clear_old_versions
214   -
215   - unless options[:if_changed].nil?
216   - self.track_altered_attributes = true
217   - options[:if_changed] = [options[:if_changed]] unless options[:if_changed].is_a?(Array)
218   - self.version_if_changed = options[:if_changed].map(&:to_s)
219   - end
  196 + unless options[:if_changed].nil?
  197 + self.track_altered_attributes = true
  198 + options[:if_changed] = [options[:if_changed]] unless options[:if_changed].is_a?(Array)
  199 + self.version_if_changed = options[:if_changed].map(&:to_s)
  200 + end
220 201  
221   - include options[:extend] if options[:extend].is_a?(Module)
222   - CLASS_METHODS
  202 + include options[:extend] if options[:extend].is_a?(Module)
223 203  
224   - # create the dynamic versioned model
225   - const_set(versioned_class_name, Class.new(ActiveRecord::Base)).class_eval do
226   - def self.reloadable? ; false ; end
227   - # find first version before the given version
228   - def self.before(version)
229   - find :first, :order => 'version desc',
230   - :conditions => ["#{original_class.versioned_foreign_key} = ? and version < ?", version.send(original_class.versioned_foreign_key), version.version]
231   - end
  204 + include ActiveRecord::Acts::Versioned::Behaviors
232 205  
233   - # find first version after the given version.
234   - def self.after(version)
235   - find :first, :order => 'version',
236   - :conditions => ["#{original_class.versioned_foreign_key} = ? and version > ?", version.send(original_class.versioned_foreign_key), version.version]
237   - end
  206 + #
  207 + # Create the dynamic versioned model
  208 + #
  209 + const_set(versioned_class_name, Class.new(ActiveRecord::Base)).class_eval do
  210 + def self.reloadable?;
  211 + false;
  212 + end
238 213  
239   - def previous
240   - self.class.before(self)
241   - end
  214 + # find first version before the given version
  215 + def self.before(version)
  216 + where(["#{original_class.versioned_foreign_key} = ? and version < ?", version.send(original_class.versioned_foreign_key), version.version]).
  217 + order('version DESC').
  218 + first
  219 + end
242 220  
243   - def next
244   - self.class.after(self)
245   - end
  221 + # find first version after the given version.
  222 + def self.after(version)
  223 + where(["#{original_class.versioned_foreign_key} = ? and version > ?", version.send(original_class.versioned_foreign_key), version.version]).
  224 + order('version ASC').
  225 + first
  226 + end
246 227  
247   - def versions_count
248   - page.version
249   - end
  228 + # finds earliest version of this record
  229 + def self.earliest
  230 + order("#{original_class.version_column}").first
  231 + end
  232 +
  233 + # find latest version of this record
  234 + def self.latest
  235 + order("#{original_class.version_column} desc").first
  236 + end
  237 +
  238 + def previous
  239 + self.class.before(self)
  240 + end
  241 +
  242 + def next
  243 + self.class.after(self)
250 244 end
251 245  
252   - versioned_class.cattr_accessor :original_class
253   - versioned_class.original_class = self
254   - versioned_class.set_table_name versioned_table_name
255   - versioned_class.belongs_to self.to_s.demodulize.underscore.to_sym,
256   - :class_name => "::#{self.to_s}",
257   - :foreign_key => versioned_foreign_key
258   - versioned_class.send :include, options[:extend] if options[:extend].is_a?(Module)
259   - versioned_class.set_sequence_name version_sequence_name if version_sequence_name
  246 + def versions_count
  247 + page.version
  248 + end
260 249 end
  250 +
  251 + versioned_class.cattr_accessor :original_class
  252 + versioned_class.original_class = self
  253 + versioned_class.table_name = versioned_table_name
  254 + versioned_class.belongs_to self.to_s.demodulize.underscore.to_sym,
  255 + :class_name => "::#{self.to_s}",
  256 + :foreign_key => versioned_foreign_key
  257 + versioned_class.send :include, options[:extend] if options[:extend].is_a?(Module)
  258 + versioned_class.set_sequence_name version_sequence_name if version_sequence_name
261 259 end
262 260  
263   - module ActMethods
264   - def self.included(base) # :nodoc:
265   - base.extend ClassMethods
  261 + module Behaviors
  262 + extend ActiveSupport::Concern
  263 +
  264 + included do
  265 + has_many :versions, self.version_association_options
  266 +
  267 + before_save :set_new_version
  268 + after_save :save_version
  269 + after_save :clear_old_versions
266 270 end
267 271  
268 272 # Saves a version of the model in the versioned table. This is called in the after_save callback by default
... ... @@ -292,7 +296,7 @@ module ActiveRecord #:nodoc:
292 296 if version.is_a?(self.class.versioned_class)
293 297 return false unless version.send(self.class.versioned_foreign_key) == id and !version.new_record?
294 298 else
295   - return false unless version = versions.send("find_by_#{self.class.version_column}", version)
  299 + return false unless version = versions.where(self.class.version_column => version).first
296 300 end
297 301 self.clone_versioned_model(version, self)
298 302 send("#{self.class.version_column}=", version.send(self.class.version_column))
... ... @@ -320,23 +324,33 @@ module ActiveRecord #:nodoc:
320 324 end
321 325 end
322 326 end
323   -
  327 +
324 328 def altered?
325   - track_altered_attributes ? (version_if_changed - changed).length < version_if_changed.length : changed?
  329 + changed.map { |c| self.class.versioned_columns.map(&:name).include?(c) & !self.class.version_except_columns.include?(c) }.any?
326 330 end
327 331  
328 332 # Clones a model. Used when saving a new version or reverting a model's version.
329 333 def clone_versioned_model(orig_model, new_model)
330 334 self.class.versioned_columns.each do |col|
331   - new_model.send("#{col.name}=", orig_model.send(col.name)) if orig_model.has_attribute?(col.name)
  335 + next unless orig_model.has_attribute?(col.name)
  336 + define_method(new_model, col.name.to_sym)
  337 + new_model.send("#{col.name.to_sym}=", orig_model.send(col.name))
332 338 end
333 339  
334 340 if orig_model.is_a?(self.class.versioned_class)
335 341 new_model[new_model.class.inheritance_column] = orig_model[self.class.versioned_inheritance_column]
336 342 elsif new_model.is_a?(self.class.versioned_class)
337   - new_model[self.class.versioned_inheritance_column] = orig_model[orig_model.class.inheritance_column]
  343 + sym = self.class.versioned_inheritance_column.to_sym
  344 + define_method new_model, sym
  345 + new_model.send("#{sym}=", orig_model[orig_model.class.inheritance_column]) if orig_model[orig_model.class.inheritance_column]
338 346 end
339 347 end
  348 +
  349 + def define_method(object, method)
  350 + return if object.methods.include? method
  351 + metaclass = class << object; self; end
  352 + metaclass.send :attr_accessor, method
  353 + end
340 354  
341 355 # Checks whether a new version shall be saved or not. Calls <tt>version_condition_met?</tt> and <tt>changed?</tt>.
342 356 def save_version?
... ... @@ -347,12 +361,12 @@ module ActiveRecord #:nodoc:
347 361 # custom version condition checking.
348 362 def version_condition_met?
349 363 case
350   - when version_condition.is_a?(Symbol)
351   - send(version_condition)
352   - when version_condition.respond_to?(:call) && (version_condition.arity == 1 || version_condition.arity == -1)
353   - version_condition.call(self)
354   - else
355   - version_condition
  364 + when version_condition.is_a?(Symbol)
  365 + send(version_condition)
  366 + when version_condition.respond_to?(:call) && (version_condition.arity == 1 || version_condition.arity == -1)
  367 + version_condition.call(self)
  368 + else
  369 + version_condition
356 370 end
357 371 end
358 372  
... ... @@ -376,19 +390,23 @@ module ActiveRecord #:nodoc:
376 390 self.class.without_locking(&block)
377 391 end
378 392  
379   - def empty_callback() end #:nodoc:
  393 + def empty_callback()
  394 + end
  395 +
  396 + #:nodoc:
380 397  
381 398 protected
382   - # sets the new version before saving, unless you're using optimistic locking. In that case, let it take care of the version.
383   - def set_new_version
384   - @saving_version = new_record? || save_version?
385   - self.send("#{self.class.version_column}=", next_version) if new_record? || (!locking_enabled? && save_version?)
386   - end
  399 + # sets the new version before saving, unless you're using optimistic locking. In that case, let it take care of the version.
  400 + def set_new_version
  401 + @saving_version = new_record? || save_version?
  402 + self.send("#{self.class.version_column}=", next_version) if new_record? || (!locking_enabled? && save_version?)
  403 + end
  404 +
  405 + # Gets the next available version for the current record, or 1 for a new record
  406 + def next_version
  407 + (new_record? ? 0 : versions.calculate(:maximum, version_column).to_i) + 1
  408 + end
387 409  
388   - # Gets the next available version for the current record, or 1 for a new record
389   - def next_version
390   - (new_record? ? 0 : versions.calculate(:max, version_column).to_i) + 1
391   - end
392 410  
393 411 module ClassMethods
394 412 # Returns an array of columns that are versioned. See non_versioned_columns
... ... @@ -410,28 +428,28 @@ module ActiveRecord #:nodoc:
410 428 end
411 429  
412 430 return if connection.table_exists?(versioned_table_name)
413   -
  431 +
414 432 self.connection.create_table(versioned_table_name, create_table_options) do |t|
415 433 t.column versioned_foreign_key, :integer
416 434 t.column version_column, :integer
417 435 end
418 436  
419   - self.versioned_columns.each do |col|
420   - self.connection.add_column versioned_table_name, col.name, col.type,
421   - :limit => col.limit,
422   - :default => col.default,
423   - :scale => col.scale,
424   - :precision => col.precision
  437 + self.versioned_columns.each do |col|
  438 + self.connection.add_column versioned_table_name, col.name, col.type,
  439 + :limit => col.limit,
  440 + :default => col.default,
  441 + :scale => col.scale,
  442 + :precision => col.precision
425 443 end
426 444  
427 445 if type_col = self.columns_hash[inheritance_column]
428   - self.connection.add_column versioned_table_name, versioned_inheritance_column, type_col.type,
429   - :limit => type_col.limit,
430   - :default => type_col.default,
431   - :scale => type_col.scale,
432   - :precision => type_col.precision
  446 + self.connection.add_column versioned_table_name, versioned_inheritance_column, type_col.type,
  447 + :limit => type_col.limit,
  448 + :default => type_col.default,
  449 + :scale => type_col.scale,
  450 + :precision => type_col.precision
433 451 end
434   -
  452 +
435 453 self.connection.add_index versioned_table_name, versioned_foreign_key
436 454 end
437 455  
... ... @@ -447,7 +465,7 @@ module ActiveRecord #:nodoc:
447 465 # end
448 466 #
449 467 def without_revision(&block)
450   - class_eval do
  468 + class_eval do
451 469 CALLBACKS.each do |attr_name|
452 470 alias_method "orig_#{attr_name}".to_sym, attr_name
453 471 alias_method attr_name, :empty_callback
... ... @@ -455,7 +473,7 @@ module ActiveRecord #:nodoc:
455 473 end
456 474 block.call
457 475 ensure
458   - class_eval do
  476 + class_eval do
459 477 CALLBACKS.each do |attr_name|
460 478 alias_method attr_name, "orig_#{attr_name}".to_sym
461 479 end
... ... @@ -483,4 +501,4 @@ module ActiveRecord #:nodoc:
483 501 end
484 502 end
485 503  
486   -ActiveRecord::Base.send :include, ActiveRecord::Acts::Versioned
  504 +ActiveRecord::Base.extend ActiveRecord::Acts::Versioned
... ...
vendor/plugins/acts_as_versioned/test/abstract_unit.rb
... ... @@ -1,48 +0,0 @@
1   -$:.unshift(File.dirname(__FILE__) + '/../../../rails/activesupport/lib')
2   -$:.unshift(File.dirname(__FILE__) + '/../../../rails/activerecord/lib')
3   -$:.unshift(File.dirname(__FILE__) + '/../lib')
4   -require 'test/unit'
5   -begin
6   - require 'active_support'
7   - require 'active_record'
8   - require 'active_record/fixtures'
9   -rescue LoadError
10   - require 'rubygems'
11   - retry
12   -end
13   -
14   -begin
15   - require 'ruby-debug'
16   - Debugger.start
17   -rescue LoadError
18   -end
19   -
20   -require 'acts_as_versioned'
21   -
22   -config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
23   -ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/debug.log")
24   -ActiveRecord::Base.configurations = {'test' => config[ENV['DB'] || 'sqlite3']}
25   -ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations['test'])
26   -
27   -load(File.dirname(__FILE__) + "/schema.rb")
28   -
29   -# set up custom sequence on widget_versions for DBs that support sequences
30   -if ENV['DB'] == 'postgresql'
31   - ActiveRecord::Base.connection.execute "DROP SEQUENCE widgets_seq;" rescue nil
32   - ActiveRecord::Base.connection.remove_column :widget_versions, :id
33   - ActiveRecord::Base.connection.execute "CREATE SEQUENCE widgets_seq START 101;"
34   - ActiveRecord::Base.connection.execute "ALTER TABLE widget_versions ADD COLUMN id INTEGER PRIMARY KEY DEFAULT nextval('widgets_seq');"
35   -end
36   -
37   -Test::Unit::TestCase.fixture_path = File.dirname(__FILE__) + "/fixtures/"
38   -$:.unshift(Test::Unit::TestCase.fixture_path)
39   -
40   -class Test::Unit::TestCase #:nodoc:
41   - # Turn off transactional fixtures if you're working with MyISAM tables in MySQL
42   - self.use_transactional_fixtures = true
43   -
44   - # Instantiated fixtures are slow, but give you @david where you otherwise would need people(:david)
45   - self.use_instantiated_fixtures = false
46   -
47   - # Add more helper methods to be used by all tests here...
48   -end
49 0 \ No newline at end of file
vendor/plugins/acts_as_versioned/test/database.yml
... ... @@ -1,18 +0,0 @@
1   -sqlite:
2   - :adapter: sqlite
3   - :dbfile: acts_as_versioned_plugin.sqlite.db
4   -sqlite3:
5   - :adapter: sqlite3
6   - :dbfile: acts_as_versioned_plugin.sqlite3.db
7   -postgresql:
8   - :adapter: postgresql
9   - :username: postgres
10   - :password: postgres
11   - :database: acts_as_versioned_plugin_test
12   - :min_messages: ERROR
13   -mysql:
14   - :adapter: mysql
15   - :host: localhost
16   - :username: rails
17   - :password:
18   - :database: acts_as_versioned_plugin_test
19 0 \ No newline at end of file
vendor/plugins/acts_as_versioned/test/fixtures/authors.yml
... ... @@ -1,6 +0,0 @@
1   -caged:
2   - id: 1
3   - name: caged
4   -mly:
5   - id: 2
6   - name: mly
7 0 \ No newline at end of file
vendor/plugins/acts_as_versioned/test/fixtures/landmark.rb
... ... @@ -1,3 +0,0 @@
1   -class Landmark < ActiveRecord::Base
2   - acts_as_versioned :if_changed => [ :name, :longitude, :latitude ]
3   -end
vendor/plugins/acts_as_versioned/test/fixtures/landmark_versions.yml
... ... @@ -1,7 +0,0 @@
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
vendor/plugins/acts_as_versioned/test/fixtures/landmarks.yml
... ... @@ -1,7 +0,0 @@
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
vendor/plugins/acts_as_versioned/test/fixtures/locked_pages.yml
... ... @@ -1,10 +0,0 @@
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
vendor/plugins/acts_as_versioned/test/fixtures/locked_pages_revisions.yml
... ... @@ -1,27 +0,0 @@
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
vendor/plugins/acts_as_versioned/test/fixtures/migrations/1_add_versioned_tables.rb
... ... @@ -1,15 +0,0 @@
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
16 0 \ No newline at end of file
vendor/plugins/acts_as_versioned/test/fixtures/page.rb
... ... @@ -1,43 +0,0 @@
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   -
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
44 0 \ No newline at end of file
vendor/plugins/acts_as_versioned/test/fixtures/page_versions.yml
... ... @@ -1,16 +0,0 @@
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
vendor/plugins/acts_as_versioned/test/fixtures/pages.yml
... ... @@ -1,8 +0,0 @@
1   -welcome:
2   - id: 1
3   - title: Welcome to the weblog
4   - body: Such a lovely day
5   - version: 24
6   - author_id: 1
7   - revisor_id: 1
8   - created_on: "2008-01-01 00:00:00"
9 0 \ No newline at end of file
vendor/plugins/acts_as_versioned/test/fixtures/widget.rb
... ... @@ -1,6 +0,0 @@
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
7 0 \ No newline at end of file
vendor/plugins/acts_as_versioned/test/migration_test.rb
... ... @@ -1,46 +0,0 @@
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 < Test::Unit::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   - # now lets take 'er back down
42   - ActiveRecord::Migrator.down(File.dirname(__FILE__) + '/fixtures/migrations/')
43   - assert_raises(ActiveRecord::StatementInvalid) { Thing.create :title => 'blah blah' }
44   - end
45   - end
46   -end
vendor/plugins/acts_as_versioned/test/schema.rb
... ... @@ -1,82 +0,0 @@
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 :created_on, :datetime
7   - t.column :updated_on, :datetime
8   - t.column :author_id, :integer
9   - t.column :revisor_id, :integer
10   - end
11   -
12   - create_table :page_versions, :force => true do |t|
13   - t.column :page_id, :integer
14   - t.column :version, :integer
15   - t.column :title, :string, :limit => 255
16   - t.column :body, :text
17   - t.column :created_on, :datetime
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
28   - end
29   -
30   - create_table :locked_pages, :force => true do |t|
31   - t.column :lock_version, :integer
32   - t.column :title, :string, :limit => 255
33   - t.column :body, :text
34   - t.column :type, :string, :limit => 255
35   - end
36   -
37   - create_table :locked_pages_revisions, :force => true do |t|
38   - t.column :page_id, :integer
39   - t.column :lock_version, :integer
40   - t.column :title, :string, :limit => 255
41   - t.column :body, :text
42   - t.column :version_type, :string, :limit => 255
43   - t.column :updated_at, :datetime
44   - end
45   -
46   - add_index :locked_pages_revisions, [:page_id, :lock_version], :unique => true
47   -
48   - create_table :widgets, :force => true do |t|
49   - t.column :name, :string, :limit => 50
50   - t.column :foo, :string
51   - t.column :version, :integer
52   - t.column :updated_at, :datetime
53   - end
54   -
55   - create_table :widget_versions, :force => true do |t|
56   - t.column :widget_id, :integer
57   - t.column :name, :string, :limit => 50
58   - t.column :version, :integer
59   - t.column :updated_at, :datetime
60   - 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
vendor/plugins/acts_as_versioned/test/versioned_test.rb
... ... @@ -1,370 +0,0 @@
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 < Test::Unit::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   - end
39   -
40   - def test_versioned_class_name
41   - assert_equal 'Version', Page.versioned_class_name
42   - assert_equal 'LockedPageRevision', LockedPage.versioned_class_name
43   - end
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   -
57   - def test_rollback_with_version_class
58   - p = pages(:welcome)
59   - assert_equal 24, p.version
60   - assert_equal 'Welcome to the weblog', p.title
61   -
62   - assert p.revert_to!(p.versions.find_by_version(23)), "Couldn't revert to 23"
63   - assert_equal 23, p.version
64   - assert_equal 'Welcome to the weblg', p.title
65   - end
66   -
67   - def test_rollback_fails_with_invalid_revision
68   - p = locked_pages(:welcome)
69   - assert !p.revert_to!(locked_pages(:thinking))
70   - end
71   -
72   - def test_saves_versioned_copy_with_options
73   - p = LockedPage.create! :title => 'first title'
74   - assert !p.new_record?
75   - assert_equal 1, p.versions.size
76   - assert_instance_of LockedPage.versioned_class, p.versions.first
77   - end
78   -
79   - def test_rollback_with_version_number_with_options
80   - p = locked_pages(:welcome)
81   - assert_equal 'Welcome to the weblog', p.title
82   - assert_equal 'LockedPage', p.versions.first.version_type
83   -
84   - assert p.revert_to!(p.versions.first.lock_version), "Couldn't revert to 23"
85   - assert_equal 'Welcome to the weblg', p.title
86   - assert_equal 'LockedPage', p.versions.first.version_type
87   - end
88   -
89   - def test_rollback_with_version_class_with_options
90   - p = locked_pages(:welcome)
91   - assert_equal 'Welcome to the weblog', p.title
92   - assert_equal 'LockedPage', p.versions.first.version_type
93   -
94   - assert p.revert_to!(p.versions.first), "Couldn't revert to 1"
95   - assert_equal 'Welcome to the weblg', p.title
96   - assert_equal 'LockedPage', p.versions.first.version_type
97   - end
98   -
99   - def test_saves_versioned_copy_with_sti
100   - p = SpecialLockedPage.create! :title => 'first title'
101   - assert !p.new_record?
102   - assert_equal 1, p.versions.size
103   - assert_instance_of LockedPage.versioned_class, p.versions.first
104   - assert_equal 'SpecialLockedPage', p.versions.first.version_type
105   - end
106   -
107   - def test_rollback_with_version_number_with_sti
108   - p = locked_pages(:thinking)
109   - assert_equal 'So I was thinking', p.title
110   -
111   - assert p.revert_to!(p.versions.first.lock_version), "Couldn't revert to 1"
112   - assert_equal 'So I was thinking!!!', p.title
113   - assert_equal 'SpecialLockedPage', p.versions.first.version_type
114   - end
115   -
116   - def test_lock_version_works_with_versioning
117   - p = locked_pages(:thinking)
118   - p2 = LockedPage.find(p.id)
119   -
120   - p.title = 'fresh title'
121   - p.save
122   - assert_equal 2, p.versions.size # limit!
123   -
124   - assert_raises(ActiveRecord::StaleObjectError) do
125   - p2.title = 'stale title'
126   - p2.save
127   - end
128   - end
129   -
130   - def test_version_if_condition
131   - p = Page.create! :title => "title"
132   - assert_equal 1, p.version
133   -
134   - Page.feeling_good = false
135   - p.save
136   - assert_equal 1, p.version
137   - Page.feeling_good = true
138   - end
139   -
140   - def test_version_if_condition2
141   - # set new if condition
142   - Page.class_eval do
143   - def new_feeling_good() title[0..0] == 'a'; end
144   - alias_method :old_feeling_good, :feeling_good?
145   - alias_method :feeling_good?, :new_feeling_good
146   - end
147   -
148   - p = Page.create! :title => "title"
149   - assert_equal 1, p.version # version does not increment
150   - assert_equal 1, p.versions.count
151   -
152   - p.update_attributes(:title => 'new title')
153   - assert_equal 1, p.version # version does not increment
154   - assert_equal 1, p.versions.count
155   -
156   - p.update_attributes(:title => 'a title')
157   - assert_equal 2, p.version
158   - assert_equal 2, p.versions.count
159   -
160   - # reset original if condition
161   - Page.class_eval { alias_method :feeling_good?, :old_feeling_good }
162   - end
163   -
164   - def test_version_if_condition_with_block
165   - # set new if condition
166   - old_condition = Page.version_condition
167   - Page.version_condition = Proc.new { |page| page.title[0..0] == 'b' }
168   -
169   - p = Page.create! :title => "title"
170   - assert_equal 1, p.version # version does not increment
171   - assert_equal 1, p.versions.count
172   -
173   - p.update_attributes(:title => 'a title')
174   - assert_equal 1, p.version # version does not increment
175   - assert_equal 1, p.versions.count
176   -
177   - p.update_attributes(:title => 'b title')
178   - assert_equal 2, p.version
179   - assert_equal 2, p.versions.count
180   -
181   - # reset original if condition
182   - Page.version_condition = old_condition
183   - end
184   -
185   - def test_version_no_limit
186   - p = Page.create! :title => "title", :body => 'first body'
187   - p.save
188   - p.save
189   - 5.times do |i|
190   - p.title = "title#{i}"
191   - p.save
192   - assert_equal "title#{i}", p.title
193   - assert_equal (i+2), p.version
194   - end
195   - end
196   -
197   - def test_version_max_limit
198   - p = LockedPage.create! :title => "title"
199   - p.update_attributes(:title => "title1")
200   - p.update_attributes(:title => "title2")
201   - 5.times do |i|
202   - p.title = "title#{i}"
203   - p.save
204   - assert_equal "title#{i}", p.title
205   - assert_equal (i+4), p.lock_version
206   - assert p.versions(true).size <= 2, "locked version can only store 2 versions"
207   - end
208   - end
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
214   - end
215   -
216   - def test_track_altered_attributes
217   - p = LockedPage.create! :title => "title"
218   - assert_equal 1, p.lock_version
219   - assert_equal 1, p.versions(true).size
220   -
221   - p.body = 'whoa'
222   - assert !p.save_version?
223   - p.save
224   - assert_equal 2, p.lock_version # still increments version because of optimistic locking
225   - assert_equal 1, p.versions(true).size
226   -
227   - p.title = 'updated title'
228   - assert p.save_version?
229   - p.save
230   - assert_equal 3, p.lock_version
231   - assert_equal 1, p.versions(true).size # version 1 deleted
232   -
233   - p.title = 'updated title!'
234   - assert p.save_version?
235   - p.save
236   - assert_equal 4, p.lock_version
237   - assert_equal 2, p.versions(true).size # version 1 deleted
238   - end
239   -
240   - def test_find_versions
241   - assert_equal 1, locked_pages(:welcome).versions.find(:all, :conditions => ['title LIKE ?', '%weblog%']).size
242   - end
243   -
244   - def test_find_version
245   - assert_equal page_versions(:welcome_1), pages(:welcome).versions.find_by_version(23)
246   - end
247   -
248   - def test_with_sequence
249   - assert_equal 'widgets_seq', Widget.versioned_class.sequence_name
250   - 3.times { Widget.create! :name => 'new widget' }
251   - assert_equal 3, Widget.count
252   - assert_equal 3, Widget.versioned_class.count
253   - 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
371 0 \ No newline at end of file