paper_trail 2.7.2 → 3.0.0.beta1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +13 -4
  5. data/CHANGELOG.md +15 -0
  6. data/README.md +109 -38
  7. data/Rakefile +9 -3
  8. data/gemfiles/3.0.gemfile +31 -0
  9. data/lib/generators/paper_trail/install_generator.rb +7 -4
  10. data/lib/paper_trail.rb +15 -9
  11. data/lib/paper_trail/cleaner.rb +34 -0
  12. data/lib/paper_trail/frameworks/cucumber.rb +31 -0
  13. data/lib/paper_trail/frameworks/rails.rb +79 -0
  14. data/lib/paper_trail/frameworks/rspec.rb +24 -0
  15. data/lib/paper_trail/frameworks/rspec/extensions.rb +20 -0
  16. data/lib/paper_trail/frameworks/sinatra.rb +31 -0
  17. data/lib/paper_trail/has_paper_trail.rb +22 -20
  18. data/lib/paper_trail/version.rb +188 -161
  19. data/lib/paper_trail/version_number.rb +1 -1
  20. data/paper_trail.gemspec +10 -6
  21. data/spec/models/widget_spec.rb +13 -0
  22. data/spec/paper_trail_spec.rb +47 -0
  23. data/spec/spec_helper.rb +41 -0
  24. data/test/dummy/app/controllers/widgets_controller.rb +10 -2
  25. data/test/dummy/app/models/protected_widget.rb +1 -1
  26. data/test/dummy/app/models/widget.rb +6 -1
  27. data/test/dummy/app/versions/post_version.rb +1 -1
  28. data/test/dummy/config/application.rb +5 -6
  29. data/test/dummy/config/environments/development.rb +6 -4
  30. data/test/dummy/config/environments/production.rb +6 -0
  31. data/test/dummy/config/environments/test.rb +4 -4
  32. data/test/dummy/config/initializers/paper_trail.rb +4 -2
  33. data/test/functional/controller_test.rb +2 -2
  34. data/test/functional/modular_sinatra_test.rb +44 -0
  35. data/test/functional/sinatra_test.rb +45 -0
  36. data/test/functional/thread_safety_test.rb +1 -1
  37. data/test/paper_trail_test.rb +2 -2
  38. data/test/unit/cleaner_test.rb +143 -0
  39. data/test/unit/inheritance_column_test.rb +3 -3
  40. data/test/unit/model_test.rb +74 -55
  41. data/test/unit/protected_attrs_test.rb +12 -7
  42. data/test/unit/timestamp_test.rb +2 -2
  43. data/test/unit/version_test.rb +37 -20
  44. metadata +86 -26
  45. data/lib/paper_trail/controller.rb +0 -75
@@ -1,3 +1,3 @@
1
1
  module PaperTrail
2
- VERSION = '2.7.2'
2
+ VERSION = '3.0.0.beta1'
3
3
  end
@@ -7,7 +7,7 @@ Gem::Specification.new do |s|
7
7
  s.summary = "Track changes to your models' data. Good for auditing or versioning."
8
8
  s.description = s.summary
9
9
  s.homepage = 'http://github.com/airblade/paper_trail'
10
- s.authors = ['Andy Stewart']
10
+ s.authors = ['Andy Stewart', 'Ben Atkins']
11
11
  s.email = 'boss@airbladesoftware.com'
12
12
 
13
13
  s.files = `git ls-files`.split("\n")
@@ -15,17 +15,21 @@ Gem::Specification.new do |s|
15
15
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
16
16
  s.require_paths = ['lib']
17
17
 
18
- s.add_dependency 'railties', '~> 3.0'
19
- s.add_dependency 'activerecord', '~> 3.0'
18
+ s.add_dependency 'activerecord', ['>= 3.0', '< 5.0']
20
19
 
21
20
  s.add_development_dependency 'rake'
22
- s.add_development_dependency 'shoulda', '~> 3.3'
23
- s.add_development_dependency 'shoulda-matchers', '~> 1.5'
21
+ s.add_development_dependency 'shoulda', '~> 3.5'
22
+ # s.add_development_dependency 'shoulda-matchers', '~> 1.5'
24
23
  s.add_development_dependency 'ffaker', '>= 1.15'
24
+ s.add_development_dependency 'railties', ['>= 3.0', '< 5.0']
25
+ s.add_development_dependency 'sinatra', '~> 1.0'
26
+ s.add_development_dependency 'rack-test', '>= 0.6'
27
+ s.add_development_dependency 'rspec-rails', '~> 2.14'
28
+
25
29
  # JRuby support for the test ENV
26
30
  unless defined?(JRUBY_VERSION)
27
31
  s.add_development_dependency 'sqlite3', '~> 1.2'
28
32
  else
29
- s.add_development_dependency 'activerecord-jdbcsqlite3-adapter', '~> 1.2.9'
33
+ s.add_development_dependency 'activerecord-jdbcsqlite3-adapter', ['>= 1.3.0.rc1', '< 1.4']
30
34
  end
31
35
  end
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ describe Widget do
4
+ it { should be_versioned }
5
+
6
+ context 'be_versioned matcher', :versioning => true do
7
+ it 'should respond to be_versioned' do
8
+ widget = Widget.create :name => 'Bob', :an_integer => 1
9
+ widget.should be_versioned
10
+ widget.versions.size.should == 1
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+
3
+ describe "PaperTrail RSpec Helper" do
4
+ describe :enabled do
5
+ context 'default' do
6
+ it 'should have versioning off by default' do
7
+ ::PaperTrail.should_not be_enabled
8
+ end
9
+ it 'should turn versioning on in a with_versioning block' do
10
+ ::PaperTrail.should_not be_enabled
11
+ with_versioning do
12
+ ::PaperTrail.should be_enabled
13
+ end
14
+ ::PaperTrail.should_not be_enabled
15
+ end
16
+ end
17
+
18
+ context 'versioning: true', :versioning => true do
19
+ it 'should have versioning on by default' do
20
+ ::PaperTrail.should be_enabled
21
+ end
22
+ it 'should keep versioning on after a with_versioning block' do
23
+ ::PaperTrail.should be_enabled
24
+ with_versioning do
25
+ ::PaperTrail.should be_enabled
26
+ end
27
+ ::PaperTrail.should be_enabled
28
+ end
29
+ end
30
+ end
31
+
32
+ describe :whodunnit do
33
+ before(:all) { ::PaperTrail.whodunnit = 'foobar' }
34
+
35
+ it "should get set to `nil` by default" do
36
+ ::PaperTrail.whodunnit.should be_nil
37
+ end
38
+ end
39
+
40
+ describe :controller_info do
41
+ before(:all) { ::PaperTrail.controller_info = {:foo => 'bar'} }
42
+
43
+ it "should get set to an empty hash before each test" do
44
+ ::PaperTrail.controller_info.should == {}
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,41 @@
1
+ ENV["RAILS_ENV"] ||= 'test'
2
+ require File.expand_path('../../test/dummy/config/environment', __FILE__)
3
+
4
+ require 'rspec/rails'
5
+ require 'rspec/autorun'
6
+
7
+ # Requires supporting ruby files with custom matchers and macros, etc,
8
+ # in spec/support/ and its subdirectories.
9
+ Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }
10
+
11
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
12
+ RSpec.configure do |config|
13
+ config.treat_symbols_as_metadata_keys_with_true_values = true
14
+
15
+ # ## Mock Framework
16
+ #
17
+ # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
18
+ #
19
+ # config.mock_with :mocha
20
+ # config.mock_with :flexmock
21
+ # config.mock_with :rr
22
+
23
+ # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
24
+ # config.fixture_path = "#{::Rails.root}/spec/fixtures"
25
+
26
+ # If you're not using ActiveRecord, or you'd prefer not to run each of your
27
+ # examples within a transaction, remove the following line or assign false
28
+ # instead of true.
29
+ config.use_transactional_fixtures = true
30
+
31
+ # If true, the base class of anonymous controllers will be inferred
32
+ # automatically. This will be the default behavior in future versions of
33
+ # rspec-rails.
34
+ config.infer_base_class_for_anonymous_controllers = false
35
+
36
+ # Run specs in random order to surface order dependencies. If you find an
37
+ # order dependency and want to debug it, you can fix the order by providing
38
+ # the seed, which is printed after each run.
39
+ # --seed 1234
40
+ config.order = 'random'
41
+ end
@@ -5,13 +5,21 @@ class WidgetsController < ApplicationController
5
5
  end
6
6
 
7
7
  def create
8
- @widget = Widget.create params[:widget]
8
+ if PaperTrail.active_record_protected_attributes?
9
+ @widget = Widget.create params[:widget]
10
+ else
11
+ @widget = Widget.create params[:widget].permit!
12
+ end
9
13
  head :ok
10
14
  end
11
15
 
12
16
  def update
13
17
  @widget = Widget.find params[:id]
14
- @widget.update_attributes params[:widget]
18
+ if PaperTrail.active_record_protected_attributes?
19
+ @widget.update_attributes params[:widget]
20
+ else
21
+ @widget.update_attributes params[:widget].permit!
22
+ end
15
23
  head :ok
16
24
  end
17
25
 
@@ -1,3 +1,3 @@
1
1
  class ProtectedWidget < Widget
2
- attr_accessible :name, :a_text
2
+ attr_accessible :name, :a_text if ::PaperTrail.active_record_protected_attributes?
3
3
  end
@@ -1,5 +1,10 @@
1
1
  class Widget < ActiveRecord::Base
2
2
  has_paper_trail
3
3
  has_one :wotsit
4
- has_many :fluxors, :order => :name
4
+
5
+ if ActiveRecord::VERSION::STRING.to_f >= 4.0 # `has_many` syntax for specifying order uses a lambda in Rails 4
6
+ has_many :fluxors, lambda { order(:name) }
7
+ else
8
+ has_many :fluxors, :order => :name
9
+ end
5
10
  end
@@ -1,3 +1,3 @@
1
- class PostVersion < Version
1
+ class PostVersion < PaperTrail::Version
2
2
  self.table_name = 'post_versions'
3
3
  end
@@ -1,9 +1,8 @@
1
1
  require File.expand_path('../boot', __FILE__)
2
2
 
3
- require "active_model/railtie"
3
+ # Pick the frameworks you want:
4
4
  require "active_record/railtie"
5
5
  require "action_controller/railtie"
6
- require "action_view/railtie"
7
6
 
8
7
  Bundler.require(:default, Rails.env) if defined?(Bundler)
9
8
  require 'paper_trail'
@@ -50,15 +49,15 @@ module Dummy
50
49
  # This will create an empty whitelist of attributes available for mass-assignment for all models
51
50
  # in your app. As such, your models will need to explicitly whitelist or blacklist accessible
52
51
  # parameters by using an attr_accessible or attr_protected declaration.
53
- #
54
- # This is uncommented in new rails apps by default but for our testing purposes its more convenient
55
- # to leave it commented out.
56
- # config.active_record.whitelist_attributes = true
52
+ config.active_record.whitelist_attributes = false if ::PaperTrail.active_record_protected_attributes?
57
53
 
58
54
  # Enable the asset pipeline
59
55
  config.assets.enabled = false
60
56
 
61
57
  # Version of your assets, change this if you want to expire all your assets
62
58
  # config.assets.version = '1.0'
59
+
60
+ # Rails 4 key for generating secret key
61
+ config.secret_key_base = 'A fox regularly kicked the screaming pile of biscuits.'
63
62
  end
64
63
  end
@@ -6,8 +6,8 @@ Dummy::Application.configure do
6
6
  # since you don't have to restart the web server when you make code changes.
7
7
  config.cache_classes = false
8
8
 
9
- # Log error messages when you accidentally call methods on nil.
10
- config.whiny_nils = true
9
+ # Do not eager load code on boot.
10
+ config.eager_load = false
11
11
 
12
12
  # Show full error reports and disable caching
13
13
  config.consider_all_requests_local = true
@@ -23,7 +23,7 @@ Dummy::Application.configure do
23
23
  config.action_dispatch.best_standards_support = :builtin
24
24
 
25
25
  # Raise exception on mass assignment protection for Active Record models
26
- config.active_record.mass_assignment_sanitizer = :strict
26
+ config.active_record.mass_assignment_sanitizer = :strict if ::PaperTrail.active_record_protected_attributes?
27
27
 
28
28
  # Log the query plan for queries taking more than this (works
29
29
  # with SQLite, MySQL, and PostgreSQL)
@@ -32,7 +32,9 @@ Dummy::Application.configure do
32
32
  # Do not compress assets
33
33
  config.assets.compress = false
34
34
 
35
- # Expands the lines which load the assets
35
+ # Debug mode disables concatenation and preprocessing of assets.
36
+ # This option may cause significant delays in view rendering with a large
37
+ # number of complex assets.
36
38
  config.assets.debug = true
37
39
  end
38
40
 
@@ -4,6 +4,12 @@ Dummy::Application.configure do
4
4
  # Code is not reloaded between requests
5
5
  config.cache_classes = true
6
6
 
7
+ # Eager load code on boot. This eager loads most of Rails and
8
+ # your application in memory, allowing both thread web servers
9
+ # and those relying on copy on write to perform better.
10
+ # Rake tasks automatically ignore this option for performance.
11
+ config.eager_load = true
12
+
7
13
  # Full error reports are disabled and caching is turned on
8
14
  config.consider_all_requests_local = false
9
15
  config.action_controller.perform_caching = true
@@ -7,13 +7,13 @@ Dummy::Application.configure do
7
7
  # and recreated between test runs. Don't rely on the data there!
8
8
  config.cache_classes = true
9
9
 
10
+ # Eager loads all registered namespaces
11
+ config.eager_load = true
12
+
10
13
  # Configure static asset server for tests with Cache-Control for performance
11
14
  config.serve_static_assets = true
12
15
  config.static_cache_control = "public, max-age=3600"
13
16
 
14
- # Log error messages when you accidentally call methods on nil
15
- config.whiny_nils = true
16
-
17
17
  # Show full error reports and disable caching
18
18
  config.consider_all_requests_local = true
19
19
  config.action_controller.perform_caching = false
@@ -30,7 +30,7 @@ Dummy::Application.configure do
30
30
  # config.action_mailer.delivery_method = :test
31
31
 
32
32
  # Raise exception on mass assignment protection for Active Record models
33
- config.active_record.mass_assignment_sanitizer = :strict
33
+ config.active_record.mass_assignment_sanitizer = :strict if ::PaperTrail.active_record_protected_attributes?
34
34
 
35
35
  # Print deprecation notices to the stderr
36
36
  config.active_support.deprecation = :stderr
@@ -1,3 +1,5 @@
1
- class Version < ActiveRecord::Base
2
- attr_accessible :created_at, :updated_at, :answer, :action, :question, :article_id, :ip, :user_agent, :title
1
+ module PaperTrail
2
+ class Version < ActiveRecord::Base
3
+ attr_accessible :created_at, :updated_at, :answer, :action, :question, :article_id, :ip, :user_agent, :title if ::PaperTrail.active_record_protected_attributes?
4
+ end
3
5
  end
@@ -34,7 +34,7 @@ class ControllerTest < ActionController::TestCase
34
34
  assert_equal 0, w.versions.length
35
35
  delete :destroy, :id => w.id
36
36
  widget = assigns(:widget)
37
- assert_equal 0, Version.with_item_keys('Widget', w.id).size
37
+ assert_equal 0, PaperTrail::Version.with_item_keys('Widget', w.id).size
38
38
  end
39
39
 
40
40
  test 'create' do
@@ -62,7 +62,7 @@ class ControllerTest < ActionController::TestCase
62
62
  assert_equal 1, w.versions.length
63
63
  delete :destroy, :id => w.id
64
64
  widget = assigns(:widget)
65
- versions_for_widget = Version.with_item_keys('Widget', w.id)
65
+ versions_for_widget = PaperTrail::Version.with_item_keys('Widget', w.id)
66
66
  assert_equal 2, versions_for_widget.length
67
67
  assert_equal 153, versions_for_widget.last.whodunnit.to_i
68
68
  assert_equal '127.0.0.1', versions_for_widget.last.ip
@@ -0,0 +1,44 @@
1
+ require 'test_helper'
2
+ require 'sinatra/base'
3
+
4
+ # --- Tests for modular `Sinatra::Base` style ----
5
+ class BaseApp < Sinatra::Base
6
+ ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => File.expand_path('../../dummy/db/test.sqlite3', __FILE__))
7
+ register Sinatra::PaperTrail
8
+
9
+ get '/test' do
10
+ Widget.create!(:name => 'foo')
11
+ 'Hello'
12
+ end
13
+
14
+ def current_user
15
+ 'foobar'
16
+ end
17
+ end
18
+
19
+ class ModularSinatraTest < ActionDispatch::IntegrationTest
20
+ include Rack::Test::Methods
21
+
22
+ def app
23
+ @app ||= BaseApp
24
+ end
25
+
26
+ test 'baseline' do
27
+ assert_nil Widget.first
28
+ assert_nil Widget.create.versions.first.whodunnit
29
+ end
30
+
31
+ context "`PaperTrail::Sinatra` in a `Sinatra::Base` application" do
32
+
33
+ should "sets the `user_for_paper_trail` from the `current_user` method" do
34
+ get '/test'
35
+ assert_equal 'Hello', last_response.body
36
+ widget = Widget.first
37
+ assert_not_nil widget
38
+ assert_equal 'foo', widget.name
39
+ assert_equal 1, widget.versions.size
40
+ assert_equal 'foobar', widget.versions.first.whodunnit
41
+ end
42
+
43
+ end
44
+ end
@@ -0,0 +1,45 @@
1
+ require 'test_helper'
2
+ # require 'sinatra/main'
3
+
4
+ # --- Tests for non-modular `Sinatra::Application` style ----
5
+ class Sinatra::Application
6
+ ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => File.expand_path('../../dummy/db/test.sqlite3', __FILE__))
7
+ register Sinatra::PaperTrail # we shouldn't actually need this line if I'm not mistaken but the tests seem to fail without it ATM
8
+
9
+ get '/test' do
10
+ Widget.create!(:name => 'bar')
11
+ 'Hai'
12
+ end
13
+
14
+ def current_user
15
+ 'raboof'
16
+ end
17
+
18
+ end
19
+
20
+ class SinatraTest < ActionDispatch::IntegrationTest
21
+ include Rack::Test::Methods
22
+
23
+ def app
24
+ @app ||= Sinatra::Application
25
+ end
26
+
27
+ test 'baseline' do
28
+ assert_nil Widget.first
29
+ assert_nil Widget.create.versions.first.whodunnit
30
+ end
31
+
32
+ context "`PaperTrail::Sinatra` in a `Sinatra::Application` application" do
33
+
34
+ should "sets the `user_for_paper_trail` from the `current_user` method" do
35
+ get '/test'
36
+ assert_equal 'Hai', last_response.body
37
+ widget = Widget.first
38
+ assert_not_nil widget
39
+ assert_equal 'bar', widget.name
40
+ assert_equal 1, widget.versions.size
41
+ assert_equal 'raboof', widget.versions.first.whodunnit
42
+ end
43
+
44
+ end
45
+ end
@@ -1,7 +1,7 @@
1
1
  require 'test_helper'
2
2
 
3
3
  class ThreadSafetyTest < ActionController::TestCase
4
- should "be thread safe" do
4
+ test "be thread safe" do
5
5
  blocked = true
6
6
 
7
7
  slow_thread = Thread.new do
@@ -2,7 +2,7 @@ require 'test_helper'
2
2
 
3
3
  class PaperTrailTest < ActiveSupport::TestCase
4
4
  test 'Sanity test' do
5
- assert_kind_of Module, PaperTrail
5
+ assert_kind_of Module, PaperTrail::Version
6
6
  end
7
7
 
8
8
  test 'create with plain model class' do
@@ -21,7 +21,7 @@ class PaperTrailTest < ActiveSupport::TestCase
21
21
  widget = Widget.create
22
22
  assert_equal 1, widget.versions.length
23
23
  widget.destroy
24
- versions_for_widget = Version.with_item_keys('Widget', widget.id)
24
+ versions_for_widget = PaperTrail::Version.with_item_keys('Widget', widget.id)
25
25
  assert_equal 2, versions_for_widget.length
26
26
  end
27
27
  end
@@ -0,0 +1,143 @@
1
+ require 'test_helper'
2
+
3
+ class PaperTrailCleanerTest < ActiveSupport::TestCase
4
+
5
+ setup do
6
+ @animals = [@animal = Animal.new, @dog = Dog.new, @cat = Cat.new]
7
+ @animals.each do |animal|
8
+ 3.times { animal.update_attribute(:name, Faker::Name.name) }
9
+ end
10
+ end
11
+
12
+ test 'Baseline' do
13
+ assert_equal 9, PaperTrail::Version.count
14
+ @animals.each { |animal| assert_equal 3, animal.versions.size }
15
+ end
16
+
17
+ context '`clean_versions!` method' do
18
+ should 'be extended by `PaperTrail` module' do
19
+ assert_respond_to PaperTrail, :clean_versions!
20
+ end
21
+
22
+ context 'No options provided' do
23
+ should 'removes extra versions for each item' do
24
+ PaperTrail.clean_versions!
25
+ assert_equal 3, PaperTrail::Version.count
26
+ @animals.each { |animal| assert_equal 1, animal.versions.size }
27
+ end
28
+
29
+ should 'removes the earliest version(s)' do
30
+ most_recent_version_names = @animals.map { |animal| animal.versions.last.reify.name }
31
+ PaperTrail.clean_versions!
32
+ assert_equal most_recent_version_names, @animals.map { |animal| animal.versions.last.reify.name }
33
+ end
34
+ end
35
+
36
+ context '`:keeping` option' do
37
+ should 'modifies the number of versions ommitted from destruction' do
38
+ PaperTrail.clean_versions!(:keeping => 2)
39
+ assert_equal 6, PaperTrail::Version.all.count
40
+ @animals.each { |animal| assert_equal 2, animal.versions.size }
41
+ end
42
+ end
43
+
44
+ context '`:date` option' do
45
+ setup do
46
+ @animal.versions.each { |ver| ver.update_attribute(:created_at, ver.created_at - 1.day) }
47
+ @date = @animal.versions.first.created_at.to_date
48
+ @animal.update_attribute(:name, Faker::Name.name)
49
+ end
50
+
51
+ should 'restrict the versions destroyed to those that were created on the date provided' do
52
+ assert_equal 10, PaperTrail::Version.count
53
+ assert_equal 4, @animal.versions.size
54
+ assert_equal 3, @animal.versions_between(@date, @date + 1.day).size
55
+ PaperTrail.clean_versions!(:date => @date)
56
+ assert_equal 8, PaperTrail::Version.count
57
+ assert_equal 2, @animal.versions(true).size
58
+ assert_equal @date, @animal.versions.first.created_at.to_date
59
+ assert_not_same @date, @animal.versions.last.created_at.to_date
60
+ end
61
+ end
62
+
63
+ context '`:item_id` option' do
64
+ context 'single ID received' do
65
+ should 'restrict the versions destroyed to the versions for the Item with that ID' do
66
+ PaperTrail.clean_versions!(:item_id => @animal.id)
67
+ assert_equal 1, @animal.versions.size
68
+ assert_equal 7, PaperTrail::Version.count
69
+ end
70
+ end
71
+
72
+ context "collection of ID's received" do
73
+ should "restrict the versions destroyed to the versions for the Item with those ID's" do
74
+ PaperTrail.clean_versions!(:item_id => [@animal.id, @dog.id])
75
+ assert_equal 1, @animal.versions.size
76
+ assert_equal 1, @dog.versions.size
77
+ assert_equal 5, PaperTrail::Version.count
78
+ end
79
+ end
80
+ end
81
+
82
+ context 'options combinations' do # additional tests to cover combinations of options
83
+ context '`:date`' do
84
+ setup do
85
+ [@animal, @dog].each do |animal|
86
+ animal.versions.each { |ver| ver.update_attribute(:created_at, ver.created_at - 1.day) }
87
+ animal.update_attribute(:name, Faker::Name.name)
88
+ end
89
+ @date = @animal.versions.first.created_at.to_date
90
+ end
91
+
92
+ should 'Baseline' do
93
+ assert_equal 11, PaperTrail::Version.count
94
+ [@animal, @dog].each do |animal|
95
+ assert_equal 4, animal.versions.size
96
+ assert_equal 3, animal.versions.between(@date, @date+1.day).size
97
+ end
98
+ end
99
+
100
+ context 'and `:keeping`' do
101
+ should 'restrict cleaning properly' do
102
+ PaperTrail.clean_versions!(:date => @date, :keeping => 2)
103
+ [@animal, @dog].each do |animal|
104
+ animal.versions.reload # reload the association to pick up the destructions made by the `Cleaner`
105
+ assert_equal 3, animal.versions.size
106
+ assert_equal 2, animal.versions.between(@date, @date+1.day).size
107
+ end
108
+ assert_equal 9, PaperTrail::Version.count # ensure that the versions for the `@cat` instance wasn't touched
109
+ end
110
+ end
111
+
112
+ context 'and `:item_id`' do
113
+ should 'restrict cleaning properly' do
114
+ PaperTrail.clean_versions!(:date => @date, :item_id => @dog.id)
115
+ @dog.versions.reload # reload the association to pick up the destructions made by the `Cleaner`
116
+ assert_equal 2, @dog.versions.size
117
+ assert_equal 1, @dog.versions.between(@date, @date+1.day).size
118
+ assert_equal 9, PaperTrail::Version.count # ensure the versions for other animals besides `@animal` weren't touched
119
+ end
120
+ end
121
+
122
+ context ', `:item_id`, and `:keeping`' do
123
+ should 'restrict cleaning properly' do
124
+ PaperTrail.clean_versions!(:date => @date, :item_id => @dog.id, :keeping => 2)
125
+ @dog.versions.reload # reload the association to pick up the destructions made by the `Cleaner`
126
+ assert_equal 3, @dog.versions.size
127
+ assert_equal 2, @dog.versions.between(@date, @date+1.day).size
128
+ assert_equal 10, PaperTrail::Version.count # ensure the versions for other animals besides `@animal` weren't touched
129
+ end
130
+ end
131
+ end
132
+
133
+ context '`:keeping` and `:item_id`' do
134
+ should 'restrict cleaning properly' do
135
+ PaperTrail.clean_versions!(:keeping => 2, :item_id => @animal.id)
136
+ assert_equal 2, @animal.versions.size
137
+ assert_equal 8, PaperTrail::Version.count # ensure the versions for other animals besides `@animal` weren't touched
138
+ end
139
+ end
140
+ end
141
+
142
+ end # clean_versions! method
143
+ end