paper_trail 3.0.1 → 3.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1054af34e2822ac77b034943d283274d8a9daa62
4
- data.tar.gz: 219b4b1fd749df6babf4517ff056ae223ba6bb6e
3
+ metadata.gz: a4b0bcf1de1e90e178545aca16201e7f3bf5de2a
4
+ data.tar.gz: 01b443dae88b5d51479bbca1e788b723f2c37c89
5
5
  SHA512:
6
- metadata.gz: 0397014880df4049900f6191b41d31c70b4bee0373943dfd1fd8cc876ed4ed220273a5e973c8d8bae471be9ebc875d12b23ede208bf246ebe2247a230fc99f03
7
- data.tar.gz: 9697bea9302726a452c319909a77face2e281392ca29a187f1bd7d5c3f35ce92b1ba94e3c9698aca50b5c88623d0bcb0b7f66fc692a2fe723a7ef171efece060
6
+ metadata.gz: f4ca7aa698867e094708d43673e77a29a681674ab3ddceefda21df783167d7f5876e0ea067945978e58615b25fdd7229f27a1630100d881c9da99feb01ee873a
7
+ data.tar.gz: f01d87966c55fe86b9894d015cf906ef833fe70e67187a920aa20676694ab5a1c64a79182917fbdb6b5a0cd8ea66d457f3d2370862f6ce764af0573530bbb112
data/.gitignore CHANGED
@@ -1,6 +1,7 @@
1
1
  NOTES
2
2
  test/debug.log
3
3
  test/paper_trail_plugin.sqlite3.db
4
+ test/dummy/config/database.yml
4
5
  test/dummy/db/*.sqlite3
5
6
  test/dummy/log/*
6
7
  test/dummy/tmp/*
data/.travis.yml CHANGED
@@ -5,8 +5,18 @@ rvm:
5
5
  - 1.8.7
6
6
  - jruby-19mode
7
7
  - jruby-18mode
8
+ env:
9
+ - DB=mysql
10
+ - DB=postgres
11
+ - DB=sqlite
8
12
 
9
- before_install: gem update --system 2.2.1
13
+ before_script:
14
+ - sh -c "if [ \"$DB\" = 'mysql' ]; then mysql -e 'create database paper_trail_test;'; fi"
15
+ - sh -c "if [ \"$DB\" = 'mysql' ]; then mysql -e 'create database paper_trail_bar; '; fi"
16
+ - sh -c "if [ \"$DB\" = 'mysql' ]; then mysql -e 'create database paper_trail_foo; '; fi"
17
+ - sh -c "if [ \"$DB\" = 'postgres' ]; then psql -c 'create database paper_trail_test;' -U postgres; fi"
18
+ - sh -c "if [ \"$DB\" = 'postgres' ]; then psql -c 'create database paper_trail_bar;' -U postgres; fi"
19
+ - sh -c "if [ \"$DB\" = 'postgres' ]; then psql -c 'create database paper_trail_foo;' -U postgres; fi"
10
20
 
11
21
  gemfile:
12
22
  - Gemfile
@@ -19,3 +29,4 @@ matrix:
19
29
  gemfile: Gemfile
20
30
  - rvm: 1.8.7
21
31
  gemfile: Gemfile
32
+
data/CHANGELOG.md CHANGED
@@ -1,3 +1,22 @@
1
+ ## 3.0.2
2
+
3
+ - [#357](https://github.com/airblade/paper_trail/issues/357) - If a `Version` instance is reified and then persisted at that state,
4
+ it's timestamp attributes for update should still get `touch`ed.
5
+ - [#351](https://github.com/airblade/paper_trail/pull/351) / [#352](https://github.com/airblade/paper_trail/pull/352) -
6
+ `PaperTrail::Rails::Controller` should hook into all controller types, and should not get loaded unless `ActionController` is.
7
+ - [#346](https://github.com/airblade/paper_trail/pull/346) - `user_for_paper_trail` method should accommodate different types
8
+ for return values from `current_user` method.
9
+ - [#344](https://github.com/airblade/paper_trail/pull/344) - Gem is now tested against `MySQL` and `PostgreSQL` in addition to `SQLite`.
10
+ - [#317](https://github.com/airblade/paper_trail/issues/317) / [#314](https://github.com/airblade/paper_trail/issues/314) -
11
+ `versions` should default to ordering via the primary key if it is an integer to avoid timestamp comparison issues.
12
+ - `PaperTrail::Cleaner.clean_versions!` should group versions by `PaperTrail.timestamp_field` when deciding which ones to
13
+ keep / destroy, instead of always grouping by the `created_at` field.
14
+ - If a `Version` instance is reified and then persisted at that state, it's source version
15
+ (`model_instance#version_association_name`, usually `model_instance#version`) will get cleared since persisting it causes it to
16
+ become the live instance.
17
+ - If `destroy` actions are tracked for a versioned model, invoking `destroy` on the model will cause the corresponding version that
18
+ gets generated to be assigned as the source version (`model_instance#version_association_name`, usually `model_instance#version`).
19
+
1
20
  ## 3.0.1
2
21
 
3
22
  - [#340](https://github.com/airblade/paper_trail/issues/340) - Prevent potential error encountered when using the `InstallGenerator`
@@ -32,7 +51,7 @@
32
51
  - [#281](https://github.com/airblade/paper_trail/issues/281) - `Rails::Controller` helper will return `false` for the
33
52
  `paper_trail_enabled_for_controller` method if `PaperTrail.enabled? == false`.
34
53
  - [#280](https://github.com/airblade/paper_trail/pull/280) - Don't track virtual timestamp attributes.
35
- - [#278](https://github.com/airblade/paper_trail/issues/278)/[#272](https://github.com/airblade/paper_trail/issues/272) -
54
+ - [#278](https://github.com/airblade/paper_trail/issues/278) / [#272](https://github.com/airblade/paper_trail/issues/272) -
36
55
  Make RSpec and Cucumber helpers usable with [Spork](https://github.com/sporkrb/spork) and [Zeus](https://github.com/burke/zeus).
37
56
  - [#273](https://github.com/airblade/paper_trail/pull/273) - Make the `only` and `ignore` options accept `Hash` arguments;
38
57
  allows for conditional tracking.
data/README.md CHANGED
@@ -42,7 +42,7 @@ The Rails 2.3 code is on the [`rails2`](https://github.com/airblade/paper_trail/
42
42
 
43
43
  1. Add `PaperTrail` to your `Gemfile`.
44
44
 
45
- `gem 'paper_trail', '~> 3.0.1'`
45
+ `gem 'paper_trail', '~> 3.0.2'`
46
46
 
47
47
  2. Generate a migration which will add a `versions` table to your database.
48
48
 
@@ -64,7 +64,7 @@ your applications `ActiveRecord` connection in a manner similar to the way `Rail
64
64
 
65
65
  1. Add `PaperTrail` to your `Gemfile`.
66
66
 
67
- `gem 'paper_trail', '~> 3.0.1'`
67
+ `gem 'paper_trail', '~> 3.0.2'`
68
68
 
69
69
  2. Generate a migration to add a `versions` table to your database.
70
70
 
@@ -889,7 +889,7 @@ A valid serializer is a `module` (or `class`) that defines a `load` and `dump` m
889
889
 
890
890
  ## Limiting the number of versions created per object instance
891
891
 
892
- If you are weary of your `versions` table growing to an unwieldy size, or just don't care to track more than a certain number of versions per object,
892
+ If you are wary of your `versions` table growing to an unwieldy size, or just don't care to track more than a certain number of versions per object,
893
893
  there is a configuration option that can be set to cap the number of versions saved per object. Note that this value must be numeric, and it only applies to
894
894
  versions other than `create` events (which will always be preserved if they are stored).
895
895
 
@@ -1018,11 +1018,23 @@ require 'rspec/rails'
1018
1018
  require 'paper_trail/frameworks/rspec'
1019
1019
  ```
1020
1020
 
1021
+ ## Testing PaperTrail
1022
+
1023
+ Paper Trail has facilities to test aganist Postgres, Mysql and SQLite. To switch between DB engines you will need to export the DB Variable for the engine you wish to test aganist.
1024
+
1025
+ Though be aware we do not have the abilty to create the db's (except sqlite) for you. You can look at .travis.yml before_script for an example of how to create the db's needed.
1026
+
1027
+ ```
1028
+ export DB=postgres
1029
+ export DB=mysql
1030
+ export DB=sqlite # this is default
1031
+ ```
1032
+
1021
1033
  ## Articles
1022
1034
 
1023
- [Using PaperTrail to track stack traces](http://rubyrailsexpert.com/?p=36), T James Corcoran's blog, 1st October 2013.
1024
- [RailsCast #255 - Undo with PaperTrail](http://railscasts.com/episodes/255-undo-with-paper-trail), 28th February 2011.
1025
- [Keep a Paper Trail with PaperTrail](http://www.linux-mag.com/id/7528), Linux Magazine, 16th September 2009.
1035
+ * [Using PaperTrail to track stack traces](http://rubyrailsexpert.com/?p=36), T James Corcoran's blog, 1st October 2013.
1036
+ * [RailsCast #255 - Undo with PaperTrail](http://railscasts.com/episodes/255-undo-with-paper-trail), 28th February 2011.
1037
+ * [Keep a Paper Trail with PaperTrail](http://www.linux-mag.com/id/7528), Linux Magazine, 16th September 2009.
1026
1038
 
1027
1039
 
1028
1040
  ## Problems
@@ -1034,6 +1046,7 @@ Please use GitHub's [issue tracker](http://github.com/airblade/paper_trail/issue
1034
1046
 
1035
1047
  Many thanks to:
1036
1048
 
1049
+ * [Russell Osborne](https://github.com/rposborne)
1037
1050
  * [Zachery Hostens](http://github.com/zacheryph)
1038
1051
  * [Jeremy Weiskotten](http://github.com/jeremyw)
1039
1052
  * [Phan Le](http://github.com/revo)
@@ -1082,6 +1095,7 @@ Many thanks to:
1082
1095
  * [Sean Marcia](https://github.com/SeanMarcia)
1083
1096
  * [Chulki Lee](https://github.com/chulkilee)
1084
1097
  * [Lucas Souza](https://github.com/lucasas)
1098
+ * [Russell Osborne](https://github.com/rposborne)
1085
1099
 
1086
1100
 
1087
1101
  ## Inspirations
data/Rakefile CHANGED
@@ -1,6 +1,18 @@
1
1
  require 'bundler'
2
2
  Bundler::GemHelper.install_tasks
3
3
 
4
+ desc 'Set a relevant database.yml for testing'
5
+ task :prepare do
6
+ ENV["DB"] ||= "sqlite"
7
+ if RUBY_VERSION.to_f >= 1.9
8
+ FileUtils.cp "test/dummy/config/database.#{ENV["DB"]}.yml", "test/dummy/config/database.yml"
9
+ else
10
+ require 'ftools'
11
+ File.cp "test/dummy/config/database.#{ENV["DB"]}.yml", "test/dummy/config/database.yml"
12
+ end
13
+ end
14
+
15
+
4
16
  require 'rake/testtask'
5
17
  desc 'Run tests on PaperTrail with Test::Unit.'
6
18
  Rake::TestTask.new(:test) do |t|
@@ -15,4 +27,4 @@ desc 'Run PaperTrail specs for the RSpec helper.'
15
27
  RSpec::Core::RakeTask.new(:spec)
16
28
 
17
29
  desc 'Default: run all available test suites'
18
- task :default => [:test, :spec]
30
+ task :default => [:prepare, :test, :spec]
data/gemfiles/3.0.gemfile CHANGED
@@ -3,7 +3,7 @@ source 'https://rubygems.org'
3
3
  gem 'activerecord', '~> 3.0'
4
4
 
5
5
  group :development, :test do
6
- gem 'rake'
6
+ gem 'rake', '~> 10.1.1'
7
7
  gem 'shoulda', '~> 3.5'
8
8
  gem 'ffaker', '>= 1.15'
9
9
 
@@ -14,19 +14,29 @@ group :development, :test do
14
14
  gem 'sinatra', '~> 1.0'
15
15
  gem 'rack-test', '>= 0.6'
16
16
 
17
- # Use sqlite3 gem for regular Ruby
18
- gem 'sqlite3', '~> 1.2', :platform => :ruby
19
-
20
17
  # RSpec testing
21
18
  gem 'rspec-rails', '~> 2.14'
22
19
  gem 'generator_spec'
23
20
 
21
+ # To do proper transactional testing with ActiveSupport::TestCase on MySQL
22
+ gem 'database_cleaner', '~> 1.2'
23
+
24
+ platforms :ruby do
25
+ gem 'sqlite3', '~> 1.2'
26
+ gem 'mysql2', '~> 0.3'
27
+ gem 'pg', '~> 0.17'
28
+ end
29
+
24
30
  platforms :jruby, :ruby_18 do
25
31
  # shoulda-matchers > 2.0 is not compatible with Ruby18.
26
32
  # Since we can't specify difference between JRuby 18/19, we need to use shoulda-matchers 1.5 for all JRuby testing.
27
33
  gem 'shoulda-matchers', '~> 1.5'
28
34
  end
29
35
 
30
- # Use jRuby's sqlite3 adapter for jRuby
31
- gem 'activerecord-jdbcsqlite3-adapter', '~> 1.2.9', :platform => :jruby
36
+ platforms :jruby do
37
+ # Use jRuby's sqlite3 adapter for jRuby
38
+ gem 'activerecord-jdbcsqlite3-adapter', '~> 1.3'
39
+ gem 'activerecord-jdbcpostgresql-adapter', '~> 1.3'
40
+ gem 'activerecord-jdbcmysql-adapter', '~> 1.3'
41
+ end
32
42
  end
data/lib/paper_trail.rb CHANGED
@@ -120,17 +120,18 @@ end
120
120
 
121
121
  require 'paper_trail/version'
122
122
 
123
+ ActiveSupport.on_load(:active_record) do
124
+ include PaperTrail::Model
125
+ end
126
+
123
127
  # Require frameworks
124
- require 'paper_trail/frameworks/rails'
125
128
  require 'paper_trail/frameworks/sinatra'
126
129
  require 'paper_trail/frameworks/rspec' if defined? RSpec
127
130
  require 'paper_trail/frameworks/cucumber' if defined? World
128
131
 
129
- ActiveSupport.on_load(:active_record) do
130
- include PaperTrail::Model
131
- end
132
-
133
132
  if defined?(ActionController)
133
+ require 'paper_trail/frameworks/rails'
134
+
134
135
  ActiveSupport.on_load(:action_controller) do
135
136
  include PaperTrail::Rails::Controller
136
137
  end
@@ -12,8 +12,9 @@ module PaperTrail
12
12
  def clean_versions!(options = {})
13
13
  options = {:keeping => 1, :date => :all}.merge(options)
14
14
  gather_versions(options[:item_id], options[:date]).each do |item_id, versions|
15
- versions.group_by { |v| v.created_at.to_date }.each do |date, versions| # now group the versions by date and iterate through those
16
- versions.pop(options[:keeping]) # remove the number of versions we wish to keep from the collection of versions prior to destruction
15
+ versions.group_by { |v| v.send(PaperTrail.timestamp_field).to_date }.each do |date, versions|
16
+ # remove the number of versions we wish to keep from the collection of versions prior to destruction
17
+ versions.pop(options[:keeping])
17
18
  versions.map(&:destroy)
18
19
  end
19
20
  end
@@ -3,10 +3,8 @@ module PaperTrail
3
3
  module Controller
4
4
 
5
5
  def self.included(base)
6
- if defined?(ActionController) && (base == ActionController::Base || base == ActionController::API)
7
- base.before_filter :set_paper_trail_enabled_for_controller
8
- base.before_filter :set_paper_trail_whodunnit, :set_paper_trail_controller_info
9
- end
6
+ base.before_filter :set_paper_trail_enabled_for_controller
7
+ base.before_filter :set_paper_trail_whodunnit, :set_paper_trail_controller_info
10
8
  end
11
9
 
12
10
  protected
@@ -17,7 +15,10 @@ module PaperTrail
17
15
  # Override this method in your controller to call a different
18
16
  # method, e.g. `current_person`, or anything you like.
19
17
  def user_for_paper_trail
20
- current_user.try(:id) if defined?(current_user)
18
+ return unless defined?(current_user)
19
+ ActiveSupport::VERSION::MAJOR >= 4 ? current_user.try!(:id) : current_user.try(:id)
20
+ rescue NoMethodError
21
+ current_user
21
22
  end
22
23
 
23
24
  # Returns any information about the controller or request that you
@@ -1,3 +1,5 @@
1
+ require 'active_support/core_ext/object' # provides the `try` method
2
+
1
3
  module PaperTrail
2
4
  module Sinatra
3
5
 
@@ -15,7 +17,10 @@ module PaperTrail
15
17
  # Override this method in your controller to call a different
16
18
  # method, e.g. `current_person`, or anything you like.
17
19
  def user_for_paper_trail
18
- current_user.try(:id) if defined?(current_user)
20
+ return unless defined?(current_user)
21
+ ActiveSupport::VERSION::MAJOR >= 4 ? current_user.try!(:id) : current_user.try(:id)
22
+ rescue NoMethodError
23
+ current_user
19
24
  end
20
25
 
21
26
  private
@@ -61,18 +61,22 @@ module PaperTrail
61
61
 
62
62
  if ::ActiveRecord::VERSION::MAJOR >= 4 # `has_many` syntax for specifying order uses a lambda in Rails 4
63
63
  has_many self.versions_association_name,
64
- lambda { order("#{PaperTrail.timestamp_field} ASC") },
64
+ lambda { |model| order(model.version_class_name.constantize.timestamp_sort_order) },
65
65
  :class_name => self.version_class_name, :as => :item
66
66
  else
67
67
  has_many self.versions_association_name,
68
68
  :class_name => self.version_class_name,
69
69
  :as => :item,
70
- :order => "#{PaperTrail.timestamp_field} ASC"
70
+ :order => self.paper_trail_version_class.timestamp_sort_order
71
71
  end
72
72
 
73
73
  options_on = Array(options[:on]) # so that a single symbol can be passed in without wrapping it in an `Array`
74
74
  after_create :record_create, :if => :save_version? if options_on.empty? || options_on.include?(:create)
75
- before_update :record_update, :if => :save_version? if options_on.empty? || options_on.include?(:update)
75
+ if options_on.empty? || options_on.include?(:update)
76
+ before_save :reset_timestamp_attrs_for_update_if_needed!, :on => :update
77
+ before_update :record_update, :if => :save_version?
78
+ after_update :clear_version_instance!
79
+ end
76
80
  after_destroy :record_destroy, :if => :save_version? if options_on.empty? || options_on.include?(:destroy)
77
81
  end
78
82
 
@@ -91,7 +95,7 @@ module PaperTrail
91
95
  PaperTrail.enabled_for_model(self, true)
92
96
  end
93
97
 
94
- def paper_trail_on
98
+ def paper_trail_on
95
99
  warn "DEPRECATED: use `paper_trail_on!` instead of `paper_trail_on`. Support for `paper_trail_on` will be removed in PaperTrail 3.1"
96
100
  self.paper_trail_on!
97
101
  end
@@ -165,7 +169,7 @@ module PaperTrail
165
169
  # Returns true if this instance is the current, live one;
166
170
  # returns false if this instance came from a previous version.
167
171
  def live?
168
- @is_live ||= source_version.nil?
172
+ source_version.nil?
169
173
  end
170
174
 
171
175
  # Returns who put the object into its current state.
@@ -177,7 +181,7 @@ module PaperTrail
177
181
  def version_at(timestamp, reify_options={})
178
182
  # Because a version stores how its object looked *before* the change,
179
183
  # we need to look for the first version created *after* the timestamp.
180
- v = send(self.class.versions_association_name).subsequent(timestamp).first
184
+ v = send(self.class.versions_association_name).subsequent(timestamp, true).first
181
185
  v ? v.reify(reify_options) : self
182
186
  end
183
187
 
@@ -271,6 +275,7 @@ module PaperTrail
271
275
  :object => self.class.paper_trail_version_class.object_col_is_json? ? object_attrs : PaperTrail.serializer.dump(object_attrs),
272
276
  :whodunnit => PaperTrail.whodunnit
273
277
  }
278
+
274
279
  if self.class.paper_trail_version_class.column_names.include?('object_changes')
275
280
  data[:object_changes] = self.class.paper_trail_version_class.object_changes_col_is_json? ? changes_for_paper_trail :
276
281
  PaperTrail.serializer.dump(changes_for_paper_trail)
@@ -285,6 +290,16 @@ module PaperTrail
285
290
  end.tap { |changes| self.class.serialize_attribute_changes(changes) }
286
291
  end
287
292
 
293
+ # Invoked via `after_update` callback for when a previous version is reified and then saved
294
+ def clear_version_instance!
295
+ send("#{self.class.version_association_name}=", nil)
296
+ end
297
+
298
+ def reset_timestamp_attrs_for_update_if_needed!
299
+ return if self.live? # invoked via callback when a user attempts to persist a reified `Version`
300
+ timestamp_attributes_for_update_in_model.each { |column| send("reset_#{column}!") }
301
+ end
302
+
288
303
  def record_destroy
289
304
  if paper_trail_switched_on? and not new_record?
290
305
  object_attrs = object_attrs_for_paper_trail(item_before_change)
@@ -295,7 +310,7 @@ module PaperTrail
295
310
  :object => self.class.paper_trail_version_class.object_col_is_json? ? object_attrs : PaperTrail.serializer.dump(object_attrs),
296
311
  :whodunnit => PaperTrail.whodunnit
297
312
  }
298
- self.class.paper_trail_version_class.create merge_metadata(data)
313
+ send("#{self.class.version_association_name}=", self.class.paper_trail_version_class.create(merge_metadata(data)))
299
314
  send(self.class.versions_association_name).send :load_target
300
315
  end
301
316
  end
@@ -33,22 +33,45 @@ module PaperTrail
33
33
  where 'event <> ?', 'create'
34
34
  end
35
35
 
36
- # These methods accept a timestamp or a version and returns other versions that come before or after
37
- def subsequent(obj)
36
+ # Expects `obj` to be an instance of `PaperTrail::Version` by default, but can accept a timestamp if
37
+ # `timestamp_arg` receives `true`
38
+ def subsequent(obj, timestamp_arg = false)
39
+ if timestamp_arg != true && self.primary_key_is_int?
40
+ return where("#{table_name}.#{self.primary_key} > ?", obj).order("#{table_name}.#{self.primary_key} ASC")
41
+ end
42
+
38
43
  obj = obj.send(PaperTrail.timestamp_field) if obj.is_a?(self)
39
- where("#{table_name}.#{PaperTrail.timestamp_field} > ?", obj).
40
- order("#{table_name}.#{PaperTrail.timestamp_field} ASC")
44
+ where("#{table_name}.#{PaperTrail.timestamp_field} > ?", obj).order(self.timestamp_sort_order)
41
45
  end
42
46
 
43
- def preceding(obj)
47
+ def preceding(obj, timestamp_arg = false)
48
+ if timestamp_arg != true && self.primary_key_is_int?
49
+ return where("#{table_name}.#{self.primary_key} < ?", obj).order("#{table_name}.#{self.primary_key} DESC")
50
+ end
51
+
44
52
  obj = obj.send(PaperTrail.timestamp_field) if obj.is_a?(self)
45
- where("#{table_name}.#{PaperTrail.timestamp_field} < ?", obj).
46
- order("#{table_name}.#{PaperTrail.timestamp_field} DESC")
53
+ where("#{table_name}.#{PaperTrail.timestamp_field} < ?", obj).order(self.timestamp_sort_order('DESC'))
47
54
  end
48
55
 
56
+
49
57
  def between(start_time, end_time)
50
58
  where("#{table_name}.#{PaperTrail.timestamp_field} > ? AND #{table_name}.#{PaperTrail.timestamp_field} < ?",
51
- start_time, end_time).order("#{table_name}.#{PaperTrail.timestamp_field} ASC")
59
+ start_time, end_time).order(self.timestamp_sort_order)
60
+ end
61
+
62
+ # defaults to using the primary key as the secondary sort order if possible
63
+ def timestamp_sort_order(order = 'ASC')
64
+ if self.primary_key_is_int?
65
+ "#{table_name}.#{PaperTrail.timestamp_field} #{order}, #{table_name}.#{self.primary_key} #{order}"
66
+ else
67
+ "#{table_name}.#{PaperTrail.timestamp_field} #{order}"
68
+ end
69
+ end
70
+
71
+ def primary_key_is_int?
72
+ @primary_key_is_int ||= columns_hash[primary_key].type == :integer
73
+ rescue
74
+ true
52
75
  end
53
76
 
54
77
  # Returns whether the `object` column is using the `json` type supported by PostgreSQL
@@ -1,3 +1,3 @@
1
1
  module PaperTrail
2
- VERSION = '3.0.1'
2
+ VERSION = '3.0.2'
3
3
  end
data/paper_trail.gemspec CHANGED
@@ -22,7 +22,7 @@ Gem::Specification.new do |s|
22
22
  s.add_dependency 'activerecord', ['>= 3.0', '< 5.0']
23
23
  s.add_dependency 'activesupport', ['>= 3.0', '< 5.0']
24
24
 
25
- s.add_development_dependency 'rake'
25
+ s.add_development_dependency 'rake', '~> 10.1.1'
26
26
  s.add_development_dependency 'shoulda', '~> 3.5'
27
27
  # s.add_development_dependency 'shoulda-matchers', '~> 1.5' # needed for ActiveRecord < 4
28
28
  s.add_development_dependency 'ffaker', '>= 1.15'
@@ -31,11 +31,16 @@ Gem::Specification.new do |s|
31
31
  s.add_development_dependency 'rack-test', '>= 0.6'
32
32
  s.add_development_dependency 'rspec-rails', '~> 2.14'
33
33
  s.add_development_dependency 'generator_spec'
34
+ s.add_development_dependency 'database_cleaner', '~> 1.2'
34
35
 
35
36
  # JRuby support for the test ENV
36
37
  unless defined?(JRUBY_VERSION)
37
38
  s.add_development_dependency 'sqlite3', '~> 1.2'
39
+ s.add_development_dependency 'mysql2', '~> 0.3'
40
+ s.add_development_dependency 'pg', '~> 0.17'
38
41
  else
39
42
  s.add_development_dependency 'activerecord-jdbcsqlite3-adapter', '~> 1.3'
43
+ s.add_development_dependency 'activerecord-jdbcpostgresql-adapter', '~> 1.3'
44
+ s.add_development_dependency 'activerecord-jdbcmysql-adapter', '~> 1.3'
40
45
  end
41
46
  end
@@ -5,7 +5,7 @@ describe Widget do
5
5
  it { should be_versioned }
6
6
  end
7
7
 
8
- let(:widget) { Widget.create :name => 'Bob', :an_integer => 1 }
8
+ let(:widget) { Widget.create! :name => 'Bob', :an_integer => 1 }
9
9
 
10
10
  describe "`versioning` option" do
11
11
  context :enabled, :versioning => true do
@@ -21,6 +21,46 @@ describe Widget do
21
21
  end
22
22
  end
23
23
 
24
+ describe "Callbacks", :versioning => true do
25
+ describe :before_save do
26
+ context ':on => :update' do
27
+ before { widget.update_attributes!(:name => 'Foobar') }
28
+
29
+ subject { widget.versions.last.reify }
30
+
31
+ it "should reset the value for the timestamp attrs for update so that value gets updated properly" do
32
+ expect { subject.save! }.to change(subject, :updated_at)
33
+ end
34
+ end
35
+ end
36
+
37
+ describe :after_update do
38
+ before { widget.update_attributes!(:name => 'Foobar') }
39
+
40
+ subject { widget.versions.last.reify }
41
+
42
+ it { subject.should_not be_live }
43
+
44
+ it "should clear the `versions_association_name` virtual attribute" do
45
+ subject.save!
46
+ subject.should be_live
47
+ end
48
+ end
49
+
50
+ describe :after_destroy do
51
+ it "should create a version for that event" do
52
+ expect { widget.destroy }.to change(widget.versions, :count).by(1)
53
+ end
54
+
55
+ it "should assign the version into the `versions_association_name`" do
56
+ widget.version.should be_nil
57
+ widget.destroy
58
+ widget.version.should_not be_nil
59
+ widget.version.should == widget.versions.last
60
+ end
61
+ end
62
+ end
63
+
24
64
  describe "Methods" do
25
65
  describe "Instance", :versioning => true do
26
66
  describe :whodunnit do
@@ -16,4 +16,19 @@ describe "Articles" do
16
16
  PaperTrail.should be_enabled_for_controller
17
17
  end
18
18
  end
19
+
20
+ with_versioning do
21
+ let(:article) { Article.last }
22
+
23
+ context "`current_user` method returns a `String`" do
24
+ if RUBY_VERSION.to_f >= 1.9
25
+ it "should set that value as the `whodunnit`" do
26
+ expect { post articles_path(valid_params) }.to change(PaperTrail::Version, :count).by(1)
27
+ article.title.should == 'Doh'
28
+ PaperTrail.whodunnit.should == 'foobar'
29
+ article.versions.last.whodunnit.should == 'foobar'
30
+ end
31
+ end
32
+ end
33
+ end
19
34
  end
data/spec/spec_helper.rb CHANGED
@@ -1,4 +1,9 @@
1
1
  ENV["RAILS_ENV"] ||= 'test'
2
+ ENV["DB"] ||= 'sqlite'
3
+
4
+ unless File.exists?(File.expand_path('../../test/dummy/config/database.yml', __FILE__))
5
+ warn "WARNING: No database.yml detected for the dummy app, please run `rake prepare` first"
6
+ end
2
7
 
3
8
  require File.expand_path('../../test/dummy/config/environment', __FILE__)
4
9
  require 'rspec/rails'
@@ -2,15 +2,21 @@
2
2
  # then defines those namespaces, then establishes the sqlite3 connection for the namespaces
3
3
  # to simulate an application with multiple database connections.
4
4
 
5
+ #Load database yaml to use
6
+ configs = YAML.load_file("#{Rails.root}/config/database.yml")
7
+
8
+ #If we are testing with sqlite make it quick
5
9
  db_directory = "#{Rails.root}/db"
6
10
  # setup alternate databases
7
- if RUBY_VERSION.to_f >= 1.9
8
- FileUtils.cp "#{db_directory}/test.sqlite3", "#{db_directory}/test-foo.sqlite3"
9
- FileUtils.cp "#{db_directory}/test.sqlite3", "#{db_directory}/test-bar.sqlite3"
10
- else
11
- require 'ftools'
12
- File.cp "#{db_directory}/test.sqlite3", "#{db_directory}/test-foo.sqlite3"
13
- File.cp "#{db_directory}/test.sqlite3", "#{db_directory}/test-bar.sqlite3"
11
+ if ENV["DB"] == "sqlite"
12
+ if RUBY_VERSION.to_f >= 1.9
13
+ FileUtils.cp "#{db_directory}/test.sqlite3", "#{db_directory}/test-foo.sqlite3"
14
+ FileUtils.cp "#{db_directory}/test.sqlite3", "#{db_directory}/test-bar.sqlite3"
15
+ else
16
+ require 'ftools'
17
+ File.cp "#{db_directory}/test.sqlite3", "#{db_directory}/test-foo.sqlite3"
18
+ File.cp "#{db_directory}/test.sqlite3", "#{db_directory}/test-bar.sqlite3"
19
+ end
14
20
  end
15
21
 
16
22
  module Foo
@@ -26,7 +32,11 @@ module Foo
26
32
  has_paper_trail :class_name => 'Foo::Version'
27
33
  end
28
34
  end
29
- Foo::Base.establish_connection(:adapter => 'sqlite3', :database => "#{db_directory}/test-foo.sqlite3")
35
+
36
+ Foo::Base.configurations = configs
37
+ Foo::Base.establish_connection(:foo)
38
+ ActiveRecord::Base.establish_connection(:foo)
39
+ ActiveRecord::Migrator.migrate File.expand_path("#{db_directory}/migrate/", __FILE__)
30
40
 
31
41
  module Bar
32
42
  class Base < ActiveRecord::Base
@@ -41,4 +51,9 @@ module Bar
41
51
  has_paper_trail :class_name => 'Bar::Version'
42
52
  end
43
53
  end
44
- Bar::Base.establish_connection(:adapter => 'sqlite3', :database => "#{db_directory}/test-bar.sqlite3")
54
+
55
+ Bar::Base.configurations = configs
56
+ Bar::Base.establish_connection(:bar)
57
+ ActiveRecord::Base.establish_connection(:bar)
58
+
59
+ ActiveRecord::Migrator.migrate File.expand_path("#{db_directory}/migrate/", __FILE__)
@@ -7,4 +7,8 @@ class ArticlesController < ApplicationController
7
7
  end
8
8
  head :ok
9
9
  end
10
+
11
+ def current_user
12
+ 'foobar'
13
+ end
10
14
  end
@@ -0,0 +1,19 @@
1
+ test: &test
2
+ adapter: mysql2
3
+ encoding: utf8
4
+ database: paper_trail_test
5
+ pool: 5
6
+ username: root
7
+ password:
8
+ host: localhost
9
+
10
+ # Warning: The database defined as "test" will be erased and
11
+ # re-generated from your development database when you run "rake".
12
+ # Do not set this db to the same as development or production.
13
+ foo:
14
+ <<: *test
15
+ database: paper_trail_foo
16
+
17
+ bar:
18
+ <<: *test
19
+ database: paper_trail_bar
@@ -0,0 +1,15 @@
1
+ test: &test
2
+ adapter: postgresql
3
+ database: paper_trail_test
4
+ username: postgres
5
+ password:
6
+ host: localhost
7
+ port: 5432
8
+
9
+ foo:
10
+ <<: *test
11
+ database: paper_trail_foo
12
+
13
+ bar:
14
+ <<: *test
15
+ database: paper_trail_bar
@@ -0,0 +1,15 @@
1
+ # SQLite version 3.x
2
+ # gem install sqlite3-ruby (not necessary on OS X Leopard)
3
+ test: &test
4
+ adapter: sqlite3
5
+ pool: 5
6
+ timeout: 5000
7
+ database: db/test.sqlite3
8
+
9
+ foo:
10
+ <<: *test
11
+ database: db/test-foo.sqlite3
12
+
13
+ bar:
14
+ <<: *test
15
+ database: db/test-bar.sqlite3
@@ -5,7 +5,7 @@ class SetUpTestTables < ActiveRecord::Migration
5
5
  t.text :a_text
6
6
  t.integer :an_integer
7
7
  t.float :a_float
8
- t.decimal :a_decimal
8
+ t.decimal :a_decimal, :precision => 6, :scale => 4
9
9
  t.datetime :a_datetime
10
10
  t.time :a_time
11
11
  t.date :a_date
@@ -62,11 +62,10 @@ 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 = PaperTrail::Version.with_item_keys('Widget', w.id)
66
- assert_equal 2, versions_for_widget.length
67
- assert_equal 153, versions_for_widget.last.whodunnit.to_i
68
- assert_equal '127.0.0.1', versions_for_widget.last.ip
69
- assert_equal 'Rails Testing', versions_for_widget.last.user_agent
65
+ assert_equal 2, widget.versions.length
66
+ assert_equal '127.0.0.1', widget.versions.last.ip
67
+ assert_equal 'Rails Testing', widget.versions.last.user_agent
68
+ assert_equal 153, widget.versions.last.whodunnit.to_i
70
69
  end
71
70
 
72
71
  test "controller metadata methods should get evaluated if paper trail is enabled for controller" do
@@ -3,7 +3,9 @@ require 'sinatra/base'
3
3
 
4
4
  # --- Tests for modular `Sinatra::Base` style ----
5
5
  class BaseApp < Sinatra::Base
6
- ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => File.expand_path('../../dummy/db/test.sqlite3', __FILE__))
6
+ configs = YAML.load_file(File.expand_path('../../dummy/config/database.yml', __FILE__))
7
+ ActiveRecord::Base.configurations = configs
8
+ ActiveRecord::Base.establish_connection(:test)
7
9
  register PaperTrail::Sinatra
8
10
 
9
11
  get '/test' do
@@ -27,7 +29,6 @@ class ModularSinatraTest < ActionDispatch::IntegrationTest
27
29
  end
28
30
 
29
31
  test 'baseline' do
30
- assert_nil Widget.first
31
32
  assert_nil Widget.create.versions.first.whodunnit
32
33
  end
33
34
 
@@ -36,7 +37,7 @@ class ModularSinatraTest < ActionDispatch::IntegrationTest
36
37
  should "sets the `user_for_paper_trail` from the `current_user` method" do
37
38
  get '/test'
38
39
  assert_equal 'Hello', last_response.body
39
- widget = Widget.first
40
+ widget = Widget.last
40
41
  assert_not_nil widget
41
42
  assert_equal 'foo', widget.name
42
43
  assert_equal 1, widget.versions.size
@@ -3,7 +3,9 @@ require 'test_helper'
3
3
 
4
4
  # --- Tests for non-modular `Sinatra::Application` style ----
5
5
  class Sinatra::Application
6
- ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => File.expand_path('../../dummy/db/test.sqlite3', __FILE__))
6
+ configs = YAML.load_file(File.expand_path('../../dummy/config/database.yml', __FILE__))
7
+ ActiveRecord::Base.configurations = configs
8
+ ActiveRecord::Base.establish_connection(:test)
7
9
  register PaperTrail::Sinatra # we shouldn't actually need this line if I'm not mistaken but the tests seem to fail without it ATM
8
10
 
9
11
  get '/test' do
@@ -28,7 +30,6 @@ class SinatraTest < ActionDispatch::IntegrationTest
28
30
  end
29
31
 
30
32
  test 'baseline' do
31
- assert_nil Widget.first
32
33
  assert_nil Widget.create.versions.first.whodunnit
33
34
  end
34
35
 
@@ -37,7 +38,7 @@ class SinatraTest < ActionDispatch::IntegrationTest
37
38
  should "sets the `user_for_paper_trail` from the `current_user` method" do
38
39
  get '/test'
39
40
  assert_equal 'Hai', last_response.body
40
- widget = Widget.first
41
+ widget = Widget.last
41
42
  assert_not_nil widget
42
43
  assert_equal 'bar', widget.name
43
44
  assert_equal 1, widget.versions.size
data/test/test_helper.rb CHANGED
@@ -1,10 +1,19 @@
1
- # Configure Rails Envinronment
2
1
  ENV["RAILS_ENV"] = "test"
2
+ ENV["DB"] ||= "sqlite"
3
+
4
+ unless File.exists?(File.expand_path('../../test/dummy/config/database.yml', __FILE__))
5
+ warn "WARNING: No database.yml detected for the dummy app, please run `rake prepare` first"
6
+ end
7
+
8
+ def using_mysql?
9
+ @using_mysql ||= ActiveRecord::Base.connection_config[:adapter].to_sym == :mysql2
10
+ end
3
11
 
4
12
  require File.expand_path("../dummy/config/environment.rb", __FILE__)
5
13
  require "rails/test_help"
6
14
  require 'shoulda'
7
15
  require 'ffaker'
16
+ require 'database_cleaner' if using_mysql?
8
17
 
9
18
  Rails.backtrace_cleaner.remove_silencers!
10
19
 
@@ -14,9 +23,18 @@ ActiveRecord::Migrator.migrate File.expand_path("../dummy/db/migrate/", __FILE__
14
23
  # Load support files
15
24
  Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
16
25
 
26
+ # DatabaseCleaner is apparently necessary for doing proper transactions within MySQL (ugh)
27
+ DatabaseCleaner.strategy = :truncation if using_mysql?
28
+
17
29
  # global setup block resetting Thread.current
18
30
  class ActiveSupport::TestCase
31
+ if using_mysql?
32
+ self.use_transactional_fixtures = false
33
+ setup { DatabaseCleaner.start }
34
+ end
35
+
19
36
  teardown do
37
+ DatabaseCleaner.clean if using_mysql?
20
38
  Thread.current[:paper_trail] = nil
21
39
  end
22
40
  end
@@ -32,4 +50,20 @@ def change_schema
32
50
  add_column :versions, :custom_created_at, :datetime
33
51
  end
34
52
  ActiveRecord::Migration.verbose = true
53
+ reset_version_class_column_info!
54
+ end
55
+
56
+ def restore_schema
57
+ ActiveRecord::Migration.verbose = false
58
+ ActiveRecord::Schema.define do
59
+ add_column :widgets, :sacrificial_column, :string
60
+ remove_column :versions, :custom_created_at
61
+ end
62
+ ActiveRecord::Migration.verbose = true
63
+ reset_version_class_column_info!
64
+ end
65
+
66
+ def reset_version_class_column_info!
67
+ PaperTrail::Version.connection.schema_cache.clear!
68
+ PaperTrail::Version.reset_column_information
35
69
  end
@@ -2,19 +2,21 @@ require 'test_helper'
2
2
 
3
3
  class PaperTrailCleanerTest < ActiveSupport::TestCase
4
4
 
5
- setup do
5
+ def populate_db!
6
6
  @animals = [@animal = Animal.new, @dog = Dog.new, @cat = Cat.new]
7
7
  @animals.each do |animal|
8
8
  3.times { animal.update_attribute(:name, Faker::Name.name) }
9
9
  end
10
10
  end
11
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
12
  context '`clean_versions!` method' do
13
+ setup { self.populate_db! }
14
+
15
+ should 'Baseline' do
16
+ assert_equal 9, PaperTrail::Version.count
17
+ @animals.each { |animal| assert_equal 3, animal.versions.size }
18
+ end
19
+
18
20
  should 'be extended by `PaperTrail` module' do
19
21
  assert_respond_to PaperTrail, :clean_versions!
20
22
  end
@@ -140,4 +142,41 @@ class PaperTrailCleanerTest < ActiveSupport::TestCase
140
142
  end
141
143
 
142
144
  end # clean_versions! method
145
+
146
+ context "Custom timestamp field" do
147
+ setup do
148
+ change_schema
149
+ self.populate_db!
150
+ # now mess with the timestamps
151
+ @animals.each do |animal|
152
+ animal.versions.reverse.each_with_index do |version, index|
153
+ version.update_attribute(:custom_created_at, Time.now.utc + index.days)
154
+ end
155
+ end
156
+ PaperTrail.timestamp_field = :custom_created_at
157
+ @animals.map { |a| a.versions(true) } # reload the `versions` association for each animal
158
+ end
159
+
160
+ teardown do
161
+ PaperTrail.timestamp_field = :created_at
162
+ restore_schema
163
+ end
164
+
165
+ should 'Baseline' do
166
+ assert_equal 9, PaperTrail::Version.count
167
+ @animals.each do |animal|
168
+ assert_equal 3, animal.versions.size
169
+ animal.versions.each_cons(2) do |a,b|
170
+ a.created_at.to_date == b.created_at.to_date
171
+ a.custom_created_at.to_date != b.custom_created_at.to_date
172
+ end
173
+ end
174
+ end
175
+
176
+ should 'group by `PaperTrail.timestamp_field` when seperating the versions by date to clean' do
177
+ assert_equal 9, PaperTrail::Version.count
178
+ PaperTrail.clean_versions!
179
+ assert_equal 9, PaperTrail::Version.count
180
+ end
181
+ end
143
182
  end
@@ -23,19 +23,19 @@ class InheritanceColumnTest < ActiveSupport::TestCase
23
23
  should 'work with custom STI inheritance column' do
24
24
  assert_equal 12, PaperTrail::Version.count
25
25
  assert_equal 4, @animal.versions.count
26
- assert @animal.versions.first.reify.nil?
26
+ assert_nil @animal.versions.first.reify
27
27
  @animal.versions[1..-1].each { |v| assert_equal 'Animal', v.reify.class.name }
28
28
 
29
29
  # For some reason `@dog.versions` doesn't include the final `destroy` version.
30
30
  # Neither do `@dog.versions.scoped` nor `@dog.versions(true)` nor `@dog.versions.reload`.
31
31
  dog_versions = PaperTrail::Version.where(:item_id => @dog.id)
32
32
  assert_equal 4, dog_versions.count
33
- assert dog_versions.first.reify.nil?
33
+ assert_nil dog_versions.first.reify
34
34
  dog_versions[1..-1].each { |v| assert_equal 'Dog', v.reify.class.name }
35
35
 
36
36
  cat_versions = PaperTrail::Version.where(:item_id => @cat.id)
37
37
  assert_equal 4, cat_versions.count
38
- assert cat_versions.first.reify.nil?
38
+ assert_nil cat_versions.first.reify
39
39
  cat_versions[1..-1].each { |v| assert_equal 'Cat', v.reify.class.name }
40
40
  end
41
41
  end
@@ -213,13 +213,18 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
213
213
  end
214
214
 
215
215
  should 'have changes' do
216
+
217
+ #TODO Postgres does not appear to pass back ActiveSupport::TimeWithZone,
218
+ # so chosing the lowest common denominator to test.
219
+
216
220
  changes = {
217
221
  'name' => [nil, 'Henry'],
218
- 'created_at' => [nil, @widget.created_at],
219
- 'updated_at' => [nil, @widget.updated_at],
220
- 'id' => [nil, 1]
222
+ 'created_at' => [nil, @widget.created_at.to_time.utc],
223
+ 'updated_at' => [nil, @widget.updated_at.to_time.utc],
224
+ 'id' => [nil, @widget.id]
221
225
  }
222
226
 
227
+ assert_equal "Time", @widget.versions.last.changeset['updated_at'][1].class.to_s
223
228
  assert_equal changes, @widget.versions.last.changeset
224
229
  end
225
230
 
@@ -437,6 +442,10 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
437
442
  @last = @widget.versions.last
438
443
  end
439
444
 
445
+ teardown do
446
+ restore_schema
447
+ end
448
+
440
449
  should 'reify previous version' do
441
450
  assert_kind_of Widget, @last.reify
442
451
  end
@@ -933,7 +942,7 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
933
942
  should 'store version on join clear' do
934
943
  @book.authors << @dostoyevsky
935
944
  count = PaperTrail::Version.count
936
- @book.authorships(true).clear
945
+ @book.authorships(true).destroy_all
937
946
  assert_equal 1, PaperTrail::Version.count - count
938
947
  assert_equal @book, PaperTrail::Version.last.reify.book
939
948
  assert_equal @dostoyevsky, PaperTrail::Version.last.reify.person
@@ -65,7 +65,7 @@ class SerializerTest < ActiveSupport::TestCase
65
65
  end
66
66
 
67
67
  should 'store object_changes' do
68
- initial_changeset = {"name" => [nil, "Some text."], "id" => [nil, 1]}
68
+ initial_changeset = {"name" => [nil, "Some text."], "id" => [nil, @fluxor.id]}
69
69
  second_changeset = {"name"=>["Some text.", "Some more text."]}
70
70
  assert_equal initial_changeset, @fluxor.versions[0].changeset
71
71
  assert_equal second_changeset, @fluxor.versions[1].changeset
@@ -107,7 +107,7 @@ class SerializerTest < ActiveSupport::TestCase
107
107
  end
108
108
 
109
109
  should 'store object_changes' do
110
- initial_changeset = {"id" => [nil, 1]}
110
+ initial_changeset = {"id" => [nil, @fluxor.id]}
111
111
  second_changeset = {"name"=>[nil, "Some more text."]}
112
112
  assert_equal initial_changeset, @fluxor.versions[0].changeset
113
113
  assert_equal second_changeset, @fluxor.versions[1].changeset
@@ -5,8 +5,6 @@ class TimestampTest < ActiveSupport::TestCase
5
5
  setup do
6
6
  PaperTrail.timestamp_field = :custom_created_at
7
7
  change_schema
8
- PaperTrail::Version.connection.schema_cache.clear!
9
- PaperTrail::Version.reset_column_information
10
8
 
11
9
  Fluxor.instance_eval <<-END
12
10
  has_paper_trail
@@ -19,6 +17,7 @@ class TimestampTest < ActiveSupport::TestCase
19
17
 
20
18
  teardown do
21
19
  PaperTrail.timestamp_field = :created_at
20
+ restore_schema
22
21
  end
23
22
 
24
23
  test 'versions works with custom timestamp field' do
@@ -7,6 +7,12 @@ class PaperTrail::VersionTest < ActiveSupport::TestCase
7
7
  assert PaperTrail::Version.creates.present?
8
8
  end
9
9
 
10
+ teardown do
11
+ restore_schema
12
+ Animal.connection.schema_cache.clear!
13
+ Animal.reset_column_information
14
+ end
15
+
10
16
  context "PaperTrail::Version.creates" do
11
17
  should "return only create events" do
12
18
  PaperTrail::Version.creates.each do |version|
@@ -59,10 +65,10 @@ class PaperTrail::VersionTest < ActiveSupport::TestCase
59
65
  setup { 2.times { @animal.update_attributes(:name => Faker::Lorem.word) } }
60
66
 
61
67
  context "receiving a TimeStamp" do
62
- should "return all versions that were created before the Timestamp; descendingly by order of the `PaperTrail.timestamp_field`" do
63
- value = PaperTrail::Version.subsequent(1.hour.ago)
68
+ should "return all versions that were created before the Timestamp" do
69
+ value = PaperTrail::Version.subsequent(1.hour.ago, true)
64
70
  assert_equal value, @animal.versions.to_a
65
- assert_not_nil value.to_sql.match(/ORDER BY versions.created_at ASC\z/)
71
+ assert_not_nil value.to_sql.match(/ORDER BY versions.created_at ASC/)
66
72
  end
67
73
  end
68
74
 
@@ -70,10 +76,6 @@ class PaperTrail::VersionTest < ActiveSupport::TestCase
70
76
  should "grab the Timestamp from the version and use that as the value" do
71
77
  value = PaperTrail::Version.subsequent(@animal.versions.first)
72
78
  assert_equal value, @animal.versions.to_a.tap { |assoc| assoc.shift }
73
- # This asssertion can't pass in Ruby18 because the `strftime` method doesn't accept the %6 (milliseconds) command
74
- if RUBY_VERSION.to_f >= 1.9 and not defined?(JRUBY_VERSION)
75
- assert_not_nil value.to_sql.match(/WHERE \(versions.created_at > '#{@animal.versions.first.send(PaperTrail.timestamp_field).strftime("%F %T.%6N")}'\)/)
76
- end
77
79
  end
78
80
  end
79
81
  end
@@ -82,10 +84,10 @@ class PaperTrail::VersionTest < ActiveSupport::TestCase
82
84
  setup { 2.times { @animal.update_attributes(:name => Faker::Lorem.word) } }
83
85
 
84
86
  context "receiving a TimeStamp" do
85
- should "return all versions that were created before the Timestamp; descendingly by order of the `PaperTrail.timestamp_field`" do
86
- value = PaperTrail::Version.preceding(Time.now)
87
+ should "return all versions that were created before the Timestamp" do
88
+ value = PaperTrail::Version.preceding(5.seconds.from_now, true)
87
89
  assert_equal value, @animal.versions.reverse
88
- assert_not_nil value.to_sql.match(/ORDER BY versions.created_at DESC\z/)
90
+ assert_not_nil value.to_sql.match(/ORDER BY versions.created_at DESC/)
89
91
  end
90
92
  end
91
93
 
@@ -93,10 +95,6 @@ class PaperTrail::VersionTest < ActiveSupport::TestCase
93
95
  should "grab the Timestamp from the version and use that as the value" do
94
96
  value = PaperTrail::Version.preceding(@animal.versions.last)
95
97
  assert_equal value, @animal.versions.to_a.tap { |assoc| assoc.pop }.reverse
96
- # This asssertion can't pass in Ruby18 because the `strftime` method doesn't accept the %6 (milliseconds) command
97
- if RUBY_VERSION.to_f >= 1.9 and not defined?(JRUBY_VERSION)
98
- assert_not_nil value.to_sql.match(/WHERE \(versions.created_at < '#{@animal.versions.last.send(PaperTrail.timestamp_field).strftime("%F %T.%6N")}'\)/)
99
- end
100
98
  end
101
99
  end
102
100
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: paper_trail
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.1
4
+ version: 3.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Stewart
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-03-14 00:00:00.000000000 Z
12
+ date: 2014-05-12 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
@@ -55,16 +55,16 @@ dependencies:
55
55
  name: rake
56
56
  requirement: !ruby/object:Gem::Requirement
57
57
  requirements:
58
- - - '>='
58
+ - - ~>
59
59
  - !ruby/object:Gem::Version
60
- version: '0'
60
+ version: 10.1.1
61
61
  type: :development
62
62
  prerelease: false
63
63
  version_requirements: !ruby/object:Gem::Requirement
64
64
  requirements:
65
- - - '>='
65
+ - - ~>
66
66
  - !ruby/object:Gem::Version
67
- version: '0'
67
+ version: 10.1.1
68
68
  - !ruby/object:Gem::Dependency
69
69
  name: shoulda
70
70
  requirement: !ruby/object:Gem::Requirement
@@ -169,6 +169,20 @@ dependencies:
169
169
  - - '>='
170
170
  - !ruby/object:Gem::Version
171
171
  version: '0'
172
+ - !ruby/object:Gem::Dependency
173
+ name: database_cleaner
174
+ requirement: !ruby/object:Gem::Requirement
175
+ requirements:
176
+ - - ~>
177
+ - !ruby/object:Gem::Version
178
+ version: '1.2'
179
+ type: :development
180
+ prerelease: false
181
+ version_requirements: !ruby/object:Gem::Requirement
182
+ requirements:
183
+ - - ~>
184
+ - !ruby/object:Gem::Version
185
+ version: '1.2'
172
186
  - !ruby/object:Gem::Dependency
173
187
  name: sqlite3
174
188
  requirement: !ruby/object:Gem::Requirement
@@ -183,6 +197,34 @@ dependencies:
183
197
  - - ~>
184
198
  - !ruby/object:Gem::Version
185
199
  version: '1.2'
200
+ - !ruby/object:Gem::Dependency
201
+ name: mysql2
202
+ requirement: !ruby/object:Gem::Requirement
203
+ requirements:
204
+ - - ~>
205
+ - !ruby/object:Gem::Version
206
+ version: '0.3'
207
+ type: :development
208
+ prerelease: false
209
+ version_requirements: !ruby/object:Gem::Requirement
210
+ requirements:
211
+ - - ~>
212
+ - !ruby/object:Gem::Version
213
+ version: '0.3'
214
+ - !ruby/object:Gem::Dependency
215
+ name: pg
216
+ requirement: !ruby/object:Gem::Requirement
217
+ requirements:
218
+ - - ~>
219
+ - !ruby/object:Gem::Version
220
+ version: '0.17'
221
+ type: :development
222
+ prerelease: false
223
+ version_requirements: !ruby/object:Gem::Requirement
224
+ requirements:
225
+ - - ~>
226
+ - !ruby/object:Gem::Version
227
+ version: '0.17'
186
228
  description: Track changes to your models' data. Good for auditing or versioning.
187
229
  email: batkinz@gmail.com
188
230
  executables: []
@@ -257,7 +299,9 @@ files:
257
299
  - test/dummy/config.ru
258
300
  - test/dummy/config/application.rb
259
301
  - test/dummy/config/boot.rb
260
- - test/dummy/config/database.yml
302
+ - test/dummy/config/database.mysql.yml
303
+ - test/dummy/config/database.postgres.yml
304
+ - test/dummy/config/database.sqlite.yml
261
305
  - test/dummy/config/environment.rb
262
306
  - test/dummy/config/environments/development.rb
263
307
  - test/dummy/config/environments/production.rb
@@ -367,7 +411,9 @@ test_files:
367
411
  - test/dummy/config.ru
368
412
  - test/dummy/config/application.rb
369
413
  - test/dummy/config/boot.rb
370
- - test/dummy/config/database.yml
414
+ - test/dummy/config/database.mysql.yml
415
+ - test/dummy/config/database.postgres.yml
416
+ - test/dummy/config/database.sqlite.yml
371
417
  - test/dummy/config/environment.rb
372
418
  - test/dummy/config/environments/development.rb
373
419
  - test/dummy/config/environments/production.rb
@@ -1,22 +0,0 @@
1
- # SQLite version 3.x
2
- # gem install sqlite3-ruby (not necessary on OS X Leopard)
3
- development:
4
- adapter: sqlite3
5
- database: db/development.sqlite3
6
- pool: 5
7
- timeout: 5000
8
-
9
- # Warning: The database defined as "test" will be erased and
10
- # re-generated from your development database when you run "rake".
11
- # Do not set this db to the same as development or production.
12
- test:
13
- adapter: sqlite3
14
- database: db/test.sqlite3
15
- pool: 5
16
- timeout: 5000
17
-
18
- production:
19
- adapter: sqlite3
20
- database: db/production.sqlite3
21
- pool: 5
22
- timeout: 5000