vestal_versions 1.0.2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +19 -20
 - data/.travis.yml +22 -0
 - data/CHANGELOG.md +7 -0
 - data/Gemfile +10 -0
 - data/README.rdoc +63 -36
 - data/Rakefile +4 -43
 - data/gemfiles/activerecord_3_0.gemfile +10 -0
 - data/gemfiles/activerecord_3_1.gemfile +10 -0
 - data/gemfiles/activerecord_3_2.gemfile +10 -0
 - data/gemfiles/activerecord_4_0.gemfile +10 -0
 - data/lib/generators/vestal_versions.rb +11 -0
 - data/lib/generators/vestal_versions/migration/migration_generator.rb +17 -0
 - data/{generators/vestal_versions → lib/generators/vestal_versions/migration}/templates/initializer.rb +0 -0
 - data/{generators/vestal_versions → lib/generators/vestal_versions/migration}/templates/migration.rb +4 -3
 - data/lib/vestal_versions.rb +39 -12
 - data/lib/vestal_versions/changes.rb +43 -47
 - data/lib/vestal_versions/conditions.rb +31 -43
 - data/lib/vestal_versions/control.rb +162 -138
 - data/lib/vestal_versions/creation.rb +67 -59
 - data/lib/vestal_versions/deletion.rb +37 -0
 - data/lib/vestal_versions/options.rb +6 -10
 - data/lib/vestal_versions/reload.rb +7 -14
 - data/lib/vestal_versions/reset.rb +15 -19
 - data/lib/vestal_versions/reversion.rb +64 -52
 - data/lib/vestal_versions/users.rb +36 -39
 - data/lib/vestal_versions/version.rb +57 -2
 - data/lib/vestal_versions/version_tagging.rb +51 -0
 - data/lib/vestal_versions/versioned.rb +14 -17
 - data/lib/vestal_versions/versions.rb +22 -7
 - data/spec/spec_helper.rb +28 -0
 - data/spec/support/models.rb +19 -0
 - data/spec/support/schema.rb +25 -0
 - data/spec/vestal_versions/changes_spec.rb +134 -0
 - data/spec/vestal_versions/conditions_spec.rb +103 -0
 - data/spec/vestal_versions/control_spec.rb +120 -0
 - data/spec/vestal_versions/creation_spec.rb +90 -0
 - data/spec/vestal_versions/deletion_spec.rb +86 -0
 - data/spec/vestal_versions/options_spec.rb +45 -0
 - data/spec/vestal_versions/reload_spec.rb +18 -0
 - data/spec/vestal_versions/reset_spec.rb +111 -0
 - data/spec/vestal_versions/reversion_spec.rb +103 -0
 - data/spec/vestal_versions/users_spec.rb +21 -0
 - data/spec/vestal_versions/version_spec.rb +61 -0
 - data/spec/vestal_versions/version_tagging_spec.rb +39 -0
 - data/spec/vestal_versions/versioned_spec.rb +16 -0
 - data/spec/vestal_versions/versions_spec.rb +176 -0
 - data/vestal_versions.gemspec +18 -100
 - metadata +153 -102
 - data/VERSION +0 -1
 - data/generators/vestal_versions/vestal_versions_generator.rb +0 -10
 - data/init.rb +0 -1
 - data/lib/vestal_versions/configuration.rb +0 -40
 - data/lib/vestal_versions/tagging.rb +0 -50
 - data/test/changes_test.rb +0 -169
 - data/test/conditions_test.rb +0 -137
 - data/test/configuration_test.rb +0 -39
 - data/test/control_test.rb +0 -152
 - data/test/creation_test.rb +0 -110
 - data/test/options_test.rb +0 -52
 - data/test/reload_test.rb +0 -19
 - data/test/reset_test.rb +0 -112
 - data/test/reversion_test.rb +0 -68
 - data/test/schema.rb +0 -43
 - data/test/tagging_test.rb +0 -39
 - data/test/test_helper.rb +0 -11
 - data/test/users_test.rb +0 -25
 - data/test/version_test.rb +0 -43
 - data/test/versioned_test.rb +0 -18
 - data/test/versions_test.rb +0 -172
 
| 
         @@ -1,17 +1,28 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'active_record'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'active_support/configurable'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
       1 
4 
     | 
    
         
             
            module VestalVersions
         
     | 
| 
       2 
5 
     | 
    
         
             
              # The ActiveRecord model representing versions.
         
     | 
| 
       3 
6 
     | 
    
         
             
              class Version < ActiveRecord::Base
         
     | 
| 
       4 
7 
     | 
    
         
             
                include Comparable
         
     | 
| 
      
 8 
     | 
    
         
            +
                include ActiveSupport::Configurable
         
     | 
| 
       5 
9 
     | 
    
         | 
| 
       6 
10 
     | 
    
         
             
                # Associate polymorphically with the parent record.
         
     | 
| 
       7 
11 
     | 
    
         
             
                belongs_to :versioned, :polymorphic => true
         
     | 
| 
       8 
12 
     | 
    
         | 
| 
      
 13 
     | 
    
         
            +
                if ActiveRecord::VERSION::MAJOR == 3
         
     | 
| 
      
 14 
     | 
    
         
            +
                  attr_accessible :modifications, :number, :user, :tag, :reverted_from
         
     | 
| 
      
 15 
     | 
    
         
            +
                end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
       9 
17 
     | 
    
         
             
                # ActiveRecord::Base#changes is an existing method, so before serializing the +changes+ column,
         
     | 
| 
       10 
     | 
    
         
            -
                # the existing +changes+ method is undefined. The overridden +changes+ method pertained to 
     | 
| 
      
 18 
     | 
    
         
            +
                # the existing +changes+ method is undefined. The overridden +changes+ method pertained to
         
     | 
| 
       11 
19 
     | 
    
         
             
                # dirty attributes, but will not affect the partial updates functionality as that's based on
         
     | 
| 
       12 
20 
     | 
    
         
             
                # an underlying +changed_attributes+ method, not +changes+ itself.
         
     | 
| 
       13 
21 
     | 
    
         
             
                undef_method :changes
         
     | 
| 
       14 
     | 
    
         
            -
                 
     | 
| 
      
 22 
     | 
    
         
            +
                def changes
         
     | 
| 
      
 23 
     | 
    
         
            +
                  self[:modifications]
         
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
                serialize :modifications, Hash
         
     | 
| 
       15 
26 
     | 
    
         | 
| 
       16 
27 
     | 
    
         
             
                # In conjunction with the included Comparable module, allows comparison of version records
         
     | 
| 
       17 
28 
     | 
    
         
             
                # based on their corresponding version numbers, creation timestamps and IDs.
         
     | 
| 
         @@ -25,5 +36,49 @@ module VestalVersions 
     | 
|
| 
       25 
36 
     | 
    
         
             
                def initial?
         
     | 
| 
       26 
37 
     | 
    
         
             
                  number == 1
         
     | 
| 
       27 
38 
     | 
    
         
             
                end
         
     | 
| 
      
 39 
     | 
    
         
            +
                
         
     | 
| 
      
 40 
     | 
    
         
            +
                # Returns the original version number that this version was.
         
     | 
| 
      
 41 
     | 
    
         
            +
                def original_number
         
     | 
| 
      
 42 
     | 
    
         
            +
                  if reverted_from.nil?
         
     | 
| 
      
 43 
     | 
    
         
            +
                    number
         
     | 
| 
      
 44 
     | 
    
         
            +
                  else
         
     | 
| 
      
 45 
     | 
    
         
            +
                    version = versioned.versions.at(reverted_from)
         
     | 
| 
      
 46 
     | 
    
         
            +
                    version.nil? ? 1 : version.original_number
         
     | 
| 
      
 47 
     | 
    
         
            +
                  end
         
     | 
| 
      
 48 
     | 
    
         
            +
                end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                def restore!
         
     | 
| 
      
 51 
     | 
    
         
            +
                  model = restore
         
     | 
| 
      
 52 
     | 
    
         
            +
                  
         
     | 
| 
      
 53 
     | 
    
         
            +
                  if model
         
     | 
| 
      
 54 
     | 
    
         
            +
                    model.save!
         
     | 
| 
      
 55 
     | 
    
         
            +
                    destroy
         
     | 
| 
      
 56 
     | 
    
         
            +
                  end
         
     | 
| 
      
 57 
     | 
    
         
            +
                  
         
     | 
| 
      
 58 
     | 
    
         
            +
                  model
         
     | 
| 
      
 59 
     | 
    
         
            +
                end
         
     | 
| 
      
 60 
     | 
    
         
            +
                
         
     | 
| 
      
 61 
     | 
    
         
            +
                def restore
         
     | 
| 
      
 62 
     | 
    
         
            +
                  if tag == 'deleted'
         
     | 
| 
      
 63 
     | 
    
         
            +
                    attrs = modifications
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                    class_name = attrs['type'].blank? ? versioned_type : attrs['type']
         
     | 
| 
      
 66 
     | 
    
         
            +
                    klass = class_name.constantize
         
     | 
| 
      
 67 
     | 
    
         
            +
                    model = klass.new
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                    attrs.each do |k, v|
         
     | 
| 
      
 70 
     | 
    
         
            +
                      begin
         
     | 
| 
      
 71 
     | 
    
         
            +
                        model.send "#{k}=", v
         
     | 
| 
      
 72 
     | 
    
         
            +
                      rescue NoMethodError
         
     | 
| 
      
 73 
     | 
    
         
            +
                        logger.warn "Attribute #{k} does not exist on #{class_name} (Version id: #{id})." rescue nil
         
     | 
| 
      
 74 
     | 
    
         
            +
                      end
         
     | 
| 
      
 75 
     | 
    
         
            +
                    end
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
                    model
         
     | 
| 
      
 78 
     | 
    
         
            +
                  else
         
     | 
| 
      
 79 
     | 
    
         
            +
                    latest_version = self.class.where(:versioned_id => versioned_id, :versioned_type => versioned_type, :tag => 'deleted').first
         
     | 
| 
      
 80 
     | 
    
         
            +
                    latest_version.nil? ? nil : latest_version.restore
         
     | 
| 
      
 81 
     | 
    
         
            +
                  end
         
     | 
| 
      
 82 
     | 
    
         
            +
                end
         
     | 
| 
       28 
83 
     | 
    
         
             
              end
         
     | 
| 
       29 
84 
     | 
    
         
             
            end
         
     | 
| 
         @@ -0,0 +1,51 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module VestalVersions
         
     | 
| 
      
 2 
     | 
    
         
            +
              # Allows specific versions to be tagged with a custom string. Useful for assigning a more
         
     | 
| 
      
 3 
     | 
    
         
            +
              # meaningful value to a version for the purpose of reversion.
         
     | 
| 
      
 4 
     | 
    
         
            +
              module VersionTagging
         
     | 
| 
      
 5 
     | 
    
         
            +
                extend ActiveSupport::Concern
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                # Adds an instance method which allows version tagging through the parent object.
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                # Accepts a single string argument which is attached to the version record associated with
         
     | 
| 
      
 10 
     | 
    
         
            +
                # the current version number of the parent object.
         
     | 
| 
      
 11 
     | 
    
         
            +
                #
         
     | 
| 
      
 12 
     | 
    
         
            +
                # Returns the given tag if successful, nil if not. Tags must be unique within the scope of
         
     | 
| 
      
 13 
     | 
    
         
            +
                # the parent object. Tag creation will fail if non-unique.
         
     | 
| 
      
 14 
     | 
    
         
            +
                #
         
     | 
| 
      
 15 
     | 
    
         
            +
                # Version records corresponding to version number 1 are not typically created, but one will
         
     | 
| 
      
 16 
     | 
    
         
            +
                # be built to house the given tag if the parent object's current version number is 1.
         
     | 
| 
      
 17 
     | 
    
         
            +
                def tag_version(tag)
         
     | 
| 
      
 18 
     | 
    
         
            +
                  v = versions.at(version) || versions.build(:number => 1)
         
     | 
| 
      
 19 
     | 
    
         
            +
                  t = v.tag!(tag)
         
     | 
| 
      
 20 
     | 
    
         
            +
                  versions.reload
         
     | 
| 
      
 21 
     | 
    
         
            +
                  t
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
              # Instance methods included into VestalVersions::Version to enable version tagging.
         
     | 
| 
      
 26 
     | 
    
         
            +
              module VersionMethods
         
     | 
| 
      
 27 
     | 
    
         
            +
                extend ActiveSupport::Concern
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                included do
         
     | 
| 
      
 30 
     | 
    
         
            +
                  validates_uniqueness_of :tag, :scope => [:versioned_id, :versioned_type], :if => :validate_tags?
         
     | 
| 
      
 31 
     | 
    
         
            +
                end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                # Attaches the given string to the version tag column. If the uniqueness validation fails,
         
     | 
| 
      
 34 
     | 
    
         
            +
                # nil is returned. Otherwise, the given string is returned.
         
     | 
| 
      
 35 
     | 
    
         
            +
                def tag!(tag)
         
     | 
| 
      
 36 
     | 
    
         
            +
                  write_attribute(:tag, tag)
         
     | 
| 
      
 37 
     | 
    
         
            +
                  save ? tag : nil
         
     | 
| 
      
 38 
     | 
    
         
            +
                end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                # Simply returns a boolean signifying whether the version instance has a tag value attached.
         
     | 
| 
      
 41 
     | 
    
         
            +
                def tagged?
         
     | 
| 
      
 42 
     | 
    
         
            +
                  !tag.nil?
         
     | 
| 
      
 43 
     | 
    
         
            +
                end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                def validate_tags?
         
     | 
| 
      
 46 
     | 
    
         
            +
                  tagged? && tag != 'deleted'
         
     | 
| 
      
 47 
     | 
    
         
            +
                end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                Version.class_eval{ include VersionMethods }
         
     | 
| 
      
 50 
     | 
    
         
            +
              end
         
     | 
| 
      
 51 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -1,30 +1,27 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            module VestalVersions
         
     | 
| 
       2 
2 
     | 
    
         
             
              # Simply adds a flag to determine whether a model class if versioned.
         
     | 
| 
       3 
3 
     | 
    
         
             
              module Versioned
         
     | 
| 
       4 
     | 
    
         
            -
                 
     | 
| 
       5 
     | 
    
         
            -
                  base.class_eval do
         
     | 
| 
       6 
     | 
    
         
            -
                    class << self
         
     | 
| 
       7 
     | 
    
         
            -
                      alias_method_chain :versioned, :flag
         
     | 
| 
       8 
     | 
    
         
            -
                    end
         
     | 
| 
       9 
     | 
    
         
            -
                  end
         
     | 
| 
       10 
     | 
    
         
            -
                end
         
     | 
| 
      
 4 
     | 
    
         
            +
                extend ActiveSupport::Concern
         
     | 
| 
       11 
5 
     | 
    
         | 
| 
       12 
6 
     | 
    
         
             
                # Overrides the +versioned+ method to first define the +versioned?+ class method before
         
     | 
| 
       13 
7 
     | 
    
         
             
                # deferring to the original +versioned+.
         
     | 
| 
       14 
     | 
    
         
            -
                 
     | 
| 
       15 
     | 
    
         
            -
                   
     | 
| 
      
 8 
     | 
    
         
            +
                module ClassMethods
         
     | 
| 
      
 9 
     | 
    
         
            +
                  def versioned(*args)
         
     | 
| 
      
 10 
     | 
    
         
            +
                    super(*args)
         
     | 
| 
       16 
11 
     | 
    
         | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
      
 12 
     | 
    
         
            +
                    class << self
         
     | 
| 
      
 13 
     | 
    
         
            +
                      def versioned?
         
     | 
| 
      
 14 
     | 
    
         
            +
                        true
         
     | 
| 
      
 15 
     | 
    
         
            +
                      end
         
     | 
| 
       20 
16 
     | 
    
         
             
                    end
         
     | 
| 
       21 
17 
     | 
    
         
             
                  end
         
     | 
| 
       22 
     | 
    
         
            -
                end
         
     | 
| 
       23 
18 
     | 
    
         | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
      
 19 
     | 
    
         
            +
                  # For all ActiveRecord::Base models that do not call the +versioned+ method, the +versioned?+
         
     | 
| 
      
 20 
     | 
    
         
            +
                  # method will return false.
         
     | 
| 
      
 21 
     | 
    
         
            +
                  def versioned?
         
     | 
| 
      
 22 
     | 
    
         
            +
                    false
         
     | 
| 
      
 23 
     | 
    
         
            +
                  end
         
     | 
| 
       28 
24 
     | 
    
         
             
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
       29 
26 
     | 
    
         
             
              end
         
     | 
| 
       30 
27 
     | 
    
         
             
            end
         
     | 
| 
         @@ -1,3 +1,21 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # See: https://github.com/rails/rails/issues/11026
         
     | 
| 
      
 2 
     | 
    
         
            +
            if ActiveRecord::VERSION::MAJOR == 3 && ActiveRecord::VERSION::MINOR == 0 && RUBY_VERSION >= "2.0.0"
         
     | 
| 
      
 3 
     | 
    
         
            +
              module ActiveRecord
         
     | 
| 
      
 4 
     | 
    
         
            +
                module Associations
         
     | 
| 
      
 5 
     | 
    
         
            +
                  class AssociationProxy
         
     | 
| 
      
 6 
     | 
    
         
            +
                    def send(method, *args)
         
     | 
| 
      
 7 
     | 
    
         
            +
                      if proxy_respond_to?(method, true)
         
     | 
| 
      
 8 
     | 
    
         
            +
                        super
         
     | 
| 
      
 9 
     | 
    
         
            +
                      else
         
     | 
| 
      
 10 
     | 
    
         
            +
                        load_target
         
     | 
| 
      
 11 
     | 
    
         
            +
                        @target.send(method, *args)
         
     | 
| 
      
 12 
     | 
    
         
            +
                      end
         
     | 
| 
      
 13 
     | 
    
         
            +
                    end
         
     | 
| 
      
 14 
     | 
    
         
            +
                  end
         
     | 
| 
      
 15 
     | 
    
         
            +
                end
         
     | 
| 
      
 16 
     | 
    
         
            +
              end
         
     | 
| 
      
 17 
     | 
    
         
            +
            end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
       1 
19 
     | 
    
         
             
            module VestalVersions
         
     | 
| 
       2 
20 
     | 
    
         
             
              # An extension module for the +has_many+ association with versions.
         
     | 
| 
       3 
21 
     | 
    
         
             
              module Versions
         
     | 
| 
         @@ -13,16 +31,13 @@ module VestalVersions 
     | 
|
| 
       13 
31 
     | 
    
         
             
                  return [] if from_number.nil? || to_number.nil?
         
     | 
| 
       14 
32 
     | 
    
         | 
| 
       15 
33 
     | 
    
         
             
                  condition = (from_number == to_number) ? to_number : Range.new(*[from_number, to_number].sort)
         
     | 
| 
       16 
     | 
    
         
            -
                   
     | 
| 
       17 
     | 
    
         
            -
                    :conditions => {:number => condition},
         
     | 
| 
       18 
     | 
    
         
            -
                    :order => "#{aliased_table_name}.number #{(from_number > to_number) ? 'DESC' : 'ASC'}"
         
     | 
| 
       19 
     | 
    
         
            -
                  )
         
     | 
| 
      
 34 
     | 
    
         
            +
                  where(:number => condition).order("#{table_name}.#{connection.quote_column_name('number')} #{(from_number > to_number) ? 'DESC' : 'ASC'}").to_a
         
     | 
| 
       20 
35 
     | 
    
         
             
                end
         
     | 
| 
       21 
36 
     | 
    
         | 
| 
       22 
37 
     | 
    
         
             
                # Returns all version records created before the version associated with the given value.
         
     | 
| 
       23 
38 
     | 
    
         
             
                def before(value)
         
     | 
| 
       24 
39 
     | 
    
         
             
                  return [] if (number = number_at(value)).nil?
         
     | 
| 
       25 
     | 
    
         
            -
                   
     | 
| 
      
 40 
     | 
    
         
            +
                  where("#{table_name}.#{connection.quote_column_name('number')} < #{number}").to_a
         
     | 
| 
       26 
41 
     | 
    
         
             
                end
         
     | 
| 
       27 
42 
     | 
    
         | 
| 
       28 
43 
     | 
    
         
             
                # Returns all version records created after the version associated with the given value.
         
     | 
| 
         @@ -30,7 +45,7 @@ module VestalVersions 
     | 
|
| 
       30 
45 
     | 
    
         
             
                # This is useful for dissociating records during use of the +reset_to!+ method.
         
     | 
| 
       31 
46 
     | 
    
         
             
                def after(value)
         
     | 
| 
       32 
47 
     | 
    
         
             
                  return [] if (number = number_at(value)).nil?
         
     | 
| 
       33 
     | 
    
         
            -
                   
     | 
| 
      
 48 
     | 
    
         
            +
                  where("#{table_name}.#{connection.quote_column_name('number')} > #{number}").to_a
         
     | 
| 
       34 
49 
     | 
    
         
             
                end
         
     | 
| 
       35 
50 
     | 
    
         | 
| 
       36 
51 
     | 
    
         
             
                # Returns a single version associated with the given value. The following formats are valid:
         
     | 
| 
         @@ -49,7 +64,7 @@ module VestalVersions 
     | 
|
| 
       49 
64 
     | 
    
         
             
                #   untouched.
         
     | 
| 
       50 
65 
     | 
    
         
             
                def at(value)
         
     | 
| 
       51 
66 
     | 
    
         
             
                  case value
         
     | 
| 
       52 
     | 
    
         
            -
                    when Date, Time then  
     | 
| 
      
 67 
     | 
    
         
            +
                    when Date, Time then where("#{table_name}.created_at <= ?", value.to_time).last
         
     | 
| 
       53 
68 
     | 
    
         
             
                    when Numeric then find_by_number(value.floor)
         
     | 
| 
       54 
69 
     | 
    
         
             
                    when String then find_by_tag(value)
         
     | 
| 
       55 
70 
     | 
    
         
             
                    when Symbol then respond_to?(value) ? send(value) : nil
         
     | 
    
        data/spec/spec_helper.rb
    ADDED
    
    | 
         @@ -0,0 +1,28 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            if ENV['COVERAGE']
         
     | 
| 
      
 2 
     | 
    
         
            +
              require 'coveralls'
         
     | 
| 
      
 3 
     | 
    
         
            +
              Coveralls.wear!
         
     | 
| 
      
 4 
     | 
    
         
            +
            end
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            require 'vestal_versions'
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            require 'bundler'
         
     | 
| 
      
 9 
     | 
    
         
            +
            Bundler.require(:test)
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            RSpec.configure do |c|
         
     | 
| 
      
 12 
     | 
    
         
            +
              c.before(:suite) do
         
     | 
| 
      
 13 
     | 
    
         
            +
                CreateSchema.suppress_messages{ CreateSchema.migrate(:up) }
         
     | 
| 
      
 14 
     | 
    
         
            +
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
              c.after(:suite) do
         
     | 
| 
      
 17 
     | 
    
         
            +
                FileUtils.rm_rf(File.expand_path('../test.db', __FILE__))
         
     | 
| 
      
 18 
     | 
    
         
            +
              end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
              c.after(:each) do
         
     | 
| 
      
 21 
     | 
    
         
            +
                VestalVersions::Version.config.clear
         
     | 
| 
      
 22 
     | 
    
         
            +
                User.prepare_versioned_options({})
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
              c.order = 'random'
         
     | 
| 
      
 26 
     | 
    
         
            +
            end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
            Dir[File.expand_path('../support/*.rb', __FILE__)].each{|f| require f }
         
     | 
| 
         @@ -0,0 +1,19 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class User < ActiveRecord::Base
         
     | 
| 
      
 2 
     | 
    
         
            +
              versioned
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
              def name
         
     | 
| 
      
 5 
     | 
    
         
            +
                [first_name, last_name].compact.join(' ')
         
     | 
| 
      
 6 
     | 
    
         
            +
              end
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
              def name= names
         
     | 
| 
      
 9 
     | 
    
         
            +
                self[:first_name], self[:last_name] = names.split(' ', 2)
         
     | 
| 
      
 10 
     | 
    
         
            +
              end
         
     | 
| 
      
 11 
     | 
    
         
            +
            end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            class DeletedUser < ActiveRecord::Base
         
     | 
| 
      
 14 
     | 
    
         
            +
              self.table_name = 'users'
         
     | 
| 
      
 15 
     | 
    
         
            +
              versioned :dependent => :tracking
         
     | 
| 
      
 16 
     | 
    
         
            +
            end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            class MyCustomVersion < VestalVersions::Version
         
     | 
| 
      
 19 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,25 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            ActiveRecord::Base.establish_connection(
         
     | 
| 
      
 2 
     | 
    
         
            +
              :adapter  => 'sqlite3',
         
     | 
| 
      
 3 
     | 
    
         
            +
              :database => File.expand_path('../../test.db', __FILE__)
         
     | 
| 
      
 4 
     | 
    
         
            +
            )
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            class CreateSchema < ActiveRecord::Migration
         
     | 
| 
      
 7 
     | 
    
         
            +
              def self.up
         
     | 
| 
      
 8 
     | 
    
         
            +
                create_table :users, :force => true do |t|
         
     | 
| 
      
 9 
     | 
    
         
            +
                  t.string :first_name
         
     | 
| 
      
 10 
     | 
    
         
            +
                  t.string :last_name
         
     | 
| 
      
 11 
     | 
    
         
            +
                  t.timestamps
         
     | 
| 
      
 12 
     | 
    
         
            +
                end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                create_table :versions, :force => true do |t|
         
     | 
| 
      
 15 
     | 
    
         
            +
                  t.belongs_to :versioned, :polymorphic => true
         
     | 
| 
      
 16 
     | 
    
         
            +
                  t.belongs_to :user, :polymorphic => true
         
     | 
| 
      
 17 
     | 
    
         
            +
                  t.string :user_name
         
     | 
| 
      
 18 
     | 
    
         
            +
                  t.text :modifications
         
     | 
| 
      
 19 
     | 
    
         
            +
                  t.integer :number
         
     | 
| 
      
 20 
     | 
    
         
            +
                  t.integer :reverted_from
         
     | 
| 
      
 21 
     | 
    
         
            +
                  t.string :tag
         
     | 
| 
      
 22 
     | 
    
         
            +
                  t.timestamps
         
     | 
| 
      
 23 
     | 
    
         
            +
                end
         
     | 
| 
      
 24 
     | 
    
         
            +
              end
         
     | 
| 
      
 25 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,134 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'spec_helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            describe VestalVersions::Changes do
         
     | 
| 
      
 4 
     | 
    
         
            +
              context "a version's changes" do
         
     | 
| 
      
 5 
     | 
    
         
            +
                let(:user){ User.create(:name => 'Steve Richert') }
         
     | 
| 
      
 6 
     | 
    
         
            +
                subject{ user.versions.last.changes }
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                before do
         
     | 
| 
      
 9 
     | 
    
         
            +
                  user.update_attribute(:last_name, 'Jobs')
         
     | 
| 
      
 10 
     | 
    
         
            +
                end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                it { should be_a(Hash) }
         
     | 
| 
      
 13 
     | 
    
         
            +
                it { should_not be_empty }
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                it 'has string keys' do
         
     | 
| 
      
 16 
     | 
    
         
            +
                  subject.keys.each{ |key| key.should be_a(String) }
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                it 'has two-element array values' do
         
     | 
| 
      
 20 
     | 
    
         
            +
                  subject.values.each do |key|
         
     | 
| 
      
 21 
     | 
    
         
            +
                    key.should be_a(Array)
         
     | 
| 
      
 22 
     | 
    
         
            +
                    key.size.should == 2
         
     | 
| 
      
 23 
     | 
    
         
            +
                  end
         
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                it 'has unique-element values' do
         
     | 
| 
      
 27 
     | 
    
         
            +
                  subject.values.each{ |v| v.uniq.should == v }
         
     | 
| 
      
 28 
     | 
    
         
            +
                end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                it "equals the model's changes" do
         
     | 
| 
      
 31 
     | 
    
         
            +
                  user.first_name = 'Stephen'
         
     | 
| 
      
 32 
     | 
    
         
            +
                  model_changes = user.changes
         
     | 
| 
      
 33 
     | 
    
         
            +
                  user.save
         
     | 
| 
      
 34 
     | 
    
         
            +
                  changes = user.versions.last.changes
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                  model_changes.should == changes
         
     | 
| 
      
 37 
     | 
    
         
            +
                end
         
     | 
| 
      
 38 
     | 
    
         
            +
              end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
              context 'a hash of changes' do
         
     | 
| 
      
 41 
     | 
    
         
            +
                let(:changes){ {'first_name' => ['Steve', 'Stephen']} }
         
     | 
| 
      
 42 
     | 
    
         
            +
                let(:other){ {'first_name' => ['Catie', 'Catherine']} }
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                it 'properly appends other changes' do
         
     | 
| 
      
 45 
     | 
    
         
            +
                  expected = {'first_name' => ['Steve', 'Catherine']}
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                  changes.append_changes(other).should == expected
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                  changes.append_changes!(other)
         
     | 
| 
      
 50 
     | 
    
         
            +
                  changes.should == expected
         
     | 
| 
      
 51 
     | 
    
         
            +
                end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                it 'properly prepends other changes' do
         
     | 
| 
      
 54 
     | 
    
         
            +
                  expected = {'first_name' => ['Catie', 'Stephen']}
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
                  changes.prepend_changes(other).should == expected
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                  changes.prepend_changes!(other)
         
     | 
| 
      
 59 
     | 
    
         
            +
                  changes.should == expected
         
     | 
| 
      
 60 
     | 
    
         
            +
                end
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                it 'is reversible' do
         
     | 
| 
      
 63 
     | 
    
         
            +
                  expected = {'first_name' => ['Stephen', 'Steve']}
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                  changes.reverse_changes.should == expected
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
                  changes.reverse_changes!
         
     | 
| 
      
 68 
     | 
    
         
            +
                  changes.should == expected
         
     | 
| 
      
 69 
     | 
    
         
            +
                end
         
     | 
| 
      
 70 
     | 
    
         
            +
              end
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
              context 'the changes between two versions' do
         
     | 
| 
      
 73 
     | 
    
         
            +
                let(:name){ 'Steve Richert' }
         
     | 
| 
      
 74 
     | 
    
         
            +
                let(:user){ User.create(:name => name) }          # 1
         
     | 
| 
      
 75 
     | 
    
         
            +
                let(:version){ user.version }
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
                before do
         
     | 
| 
      
 78 
     | 
    
         
            +
                  user.update_attribute(:last_name, 'Jobs')       # 2
         
     | 
| 
      
 79 
     | 
    
         
            +
                  user.update_attribute(:first_name, 'Stephen')   # 3
         
     | 
| 
      
 80 
     | 
    
         
            +
                  user.update_attribute(:last_name, 'Richert')    # 4
         
     | 
| 
      
 81 
     | 
    
         
            +
                  user.update_attribute(:name, name)              # 5
         
     | 
| 
      
 82 
     | 
    
         
            +
                end
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                it 'is a hash' do
         
     | 
| 
      
 85 
     | 
    
         
            +
                  1.upto(version) do |i|
         
     | 
| 
      
 86 
     | 
    
         
            +
                    1.upto(version) do |j|
         
     | 
| 
      
 87 
     | 
    
         
            +
                      user.changes_between(i, j).should be_a(Hash)
         
     | 
| 
      
 88 
     | 
    
         
            +
                    end
         
     | 
| 
      
 89 
     | 
    
         
            +
                  end
         
     | 
| 
      
 90 
     | 
    
         
            +
                end
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
                it 'has string keys' do
         
     | 
| 
      
 93 
     | 
    
         
            +
                  1.upto(version) do |i|
         
     | 
| 
      
 94 
     | 
    
         
            +
                    1.upto(version) do |j|
         
     | 
| 
      
 95 
     | 
    
         
            +
                      user.changes_between(i, j).keys.each{ |key| key.should be_a(String) }
         
     | 
| 
      
 96 
     | 
    
         
            +
                    end
         
     | 
| 
      
 97 
     | 
    
         
            +
                  end
         
     | 
| 
      
 98 
     | 
    
         
            +
                end
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
                it 'has two-element arrays with unique values' do
         
     | 
| 
      
 101 
     | 
    
         
            +
                  1.upto(version) do |i|
         
     | 
| 
      
 102 
     | 
    
         
            +
                    1.upto(version) do |j|
         
     | 
| 
      
 103 
     | 
    
         
            +
                      user.changes_between(i, j).values.each do |value|
         
     | 
| 
      
 104 
     | 
    
         
            +
                        value.should be_a(Array)
         
     | 
| 
      
 105 
     | 
    
         
            +
                        value.size.should == 2
         
     | 
| 
      
 106 
     | 
    
         
            +
                        value.uniq.should == value
         
     | 
| 
      
 107 
     | 
    
         
            +
                      end
         
     | 
| 
      
 108 
     | 
    
         
            +
                    end
         
     | 
| 
      
 109 
     | 
    
         
            +
                  end
         
     | 
| 
      
 110 
     | 
    
         
            +
                end
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
                it 'is empty between identical versions' do
         
     | 
| 
      
 113 
     | 
    
         
            +
                  user.changes_between(1, version).should be_empty
         
     | 
| 
      
 114 
     | 
    
         
            +
                  user.changes_between(version, 1).should be_empty
         
     | 
| 
      
 115 
     | 
    
         
            +
                end
         
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
      
 117 
     | 
    
         
            +
                it 'is should reverse with direction' do
         
     | 
| 
      
 118 
     | 
    
         
            +
                  1.upto(version) do |i|
         
     | 
| 
      
 119 
     | 
    
         
            +
                    i.upto(version) do |j|
         
     | 
| 
      
 120 
     | 
    
         
            +
                      up    = user.changes_between(i, j)
         
     | 
| 
      
 121 
     | 
    
         
            +
                      down  = user.changes_between(j, i)
         
     | 
| 
      
 122 
     | 
    
         
            +
                      up.should == down.reverse_changes
         
     | 
| 
      
 123 
     | 
    
         
            +
                    end
         
     | 
| 
      
 124 
     | 
    
         
            +
                  end
         
     | 
| 
      
 125 
     | 
    
         
            +
                end
         
     | 
| 
      
 126 
     | 
    
         
            +
             
     | 
| 
      
 127 
     | 
    
         
            +
                it 'is empty with invalid arguments' do
         
     | 
| 
      
 128 
     | 
    
         
            +
                  1.upto(version) do |i|
         
     | 
| 
      
 129 
     | 
    
         
            +
                    user.changes_between(i, nil).should be_blank
         
     | 
| 
      
 130 
     | 
    
         
            +
                    user.changes_between(nil, i).should be_blank
         
     | 
| 
      
 131 
     | 
    
         
            +
                  end
         
     | 
| 
      
 132 
     | 
    
         
            +
                end
         
     | 
| 
      
 133 
     | 
    
         
            +
              end
         
     | 
| 
      
 134 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,103 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'spec_helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            describe VestalVersions::Conditions do
         
     | 
| 
      
 4 
     | 
    
         
            +
              shared_examples_for 'a conditional option' do |option|
         
     | 
| 
      
 5 
     | 
    
         
            +
                before do
         
     | 
| 
      
 6 
     | 
    
         
            +
                  User.class_eval do
         
     | 
| 
      
 7 
     | 
    
         
            +
                    def true; true; end
         
     | 
| 
      
 8 
     | 
    
         
            +
                  end
         
     | 
| 
      
 9 
     | 
    
         
            +
                end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                it 'is an array' do
         
     | 
| 
      
 12 
     | 
    
         
            +
                  User.vestal_versions_options[option].should be_a(Array)
         
     | 
| 
      
 13 
     | 
    
         
            +
                  User.prepare_versioned_options(option => :true)
         
     | 
| 
      
 14 
     | 
    
         
            +
                  User.vestal_versions_options[option].should be_a(Array)
         
     | 
| 
      
 15 
     | 
    
         
            +
                end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                it 'has proc values' do
         
     | 
| 
      
 18 
     | 
    
         
            +
                  User.prepare_versioned_options(option => :true)
         
     | 
| 
      
 19 
     | 
    
         
            +
                  User.vestal_versions_options[option].each{|i| i.should be_a(Proc) }
         
     | 
| 
      
 20 
     | 
    
         
            +
                end
         
     | 
| 
      
 21 
     | 
    
         
            +
              end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
              it_should_behave_like 'a conditional option', :if
         
     | 
| 
      
 24 
     | 
    
         
            +
              it_should_behave_like 'a conditional option', :unless
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
              context 'a new version' do
         
     | 
| 
      
 27 
     | 
    
         
            +
                subject{ User.create(:name => 'Steve Richert') }
         
     | 
| 
      
 28 
     | 
    
         
            +
                let(:count){ subject.versions.count }
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                before do
         
     | 
| 
      
 31 
     | 
    
         
            +
                  User.class_eval do
         
     | 
| 
      
 32 
     | 
    
         
            +
                    def true; true; end
         
     | 
| 
      
 33 
     | 
    
         
            +
                    def false; false; end
         
     | 
| 
      
 34 
     | 
    
         
            +
                  end
         
     | 
| 
      
 35 
     | 
    
         
            +
                  count # memoize this value
         
     | 
| 
      
 36 
     | 
    
         
            +
                end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                after do
         
     | 
| 
      
 39 
     | 
    
         
            +
                  User.prepare_versioned_options(:if => [], :unless => [])
         
     | 
| 
      
 40 
     | 
    
         
            +
                end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                context 'with :if conditions' do
         
     | 
| 
      
 43 
     | 
    
         
            +
                  context 'that pass' do
         
     | 
| 
      
 44 
     | 
    
         
            +
                    before do
         
     | 
| 
      
 45 
     | 
    
         
            +
                      User.prepare_versioned_options(:if => [:true])
         
     | 
| 
      
 46 
     | 
    
         
            +
                      subject.update_attribute(:last_name, 'Jobs')
         
     | 
| 
      
 47 
     | 
    
         
            +
                    end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                    its('versions.count'){ should == count + 1 }
         
     | 
| 
      
 50 
     | 
    
         
            +
                  end
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                  context 'that fail' do
         
     | 
| 
      
 53 
     | 
    
         
            +
                    before do
         
     | 
| 
      
 54 
     | 
    
         
            +
                      User.prepare_versioned_options(:if => [:false])
         
     | 
| 
      
 55 
     | 
    
         
            +
                      subject.update_attribute(:last_name, 'Jobs')
         
     | 
| 
      
 56 
     | 
    
         
            +
                    end
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                    its('versions.count'){ should == count }
         
     | 
| 
      
 59 
     | 
    
         
            +
                  end
         
     | 
| 
      
 60 
     | 
    
         
            +
                end
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                context 'with :unless conditions' do
         
     | 
| 
      
 63 
     | 
    
         
            +
                  context 'that pass' do
         
     | 
| 
      
 64 
     | 
    
         
            +
                    before do
         
     | 
| 
      
 65 
     | 
    
         
            +
                      User.prepare_versioned_options(:unless => [:true])
         
     | 
| 
      
 66 
     | 
    
         
            +
                      subject.update_attribute(:last_name, 'Jobs')
         
     | 
| 
      
 67 
     | 
    
         
            +
                    end
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                    its('versions.count'){ should == count }
         
     | 
| 
      
 70 
     | 
    
         
            +
                  end
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                  context 'that fail' do
         
     | 
| 
      
 73 
     | 
    
         
            +
                    before do
         
     | 
| 
      
 74 
     | 
    
         
            +
                      User.prepare_versioned_options(:unless => [:false])
         
     | 
| 
      
 75 
     | 
    
         
            +
                      subject.update_attribute(:last_name, 'Jobs')
         
     | 
| 
      
 76 
     | 
    
         
            +
                    end
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
                    its('versions.count'){ should == count + 1 }
         
     | 
| 
      
 79 
     | 
    
         
            +
                  end
         
     | 
| 
      
 80 
     | 
    
         
            +
                end
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
                context 'with :if and :unless conditions' do
         
     | 
| 
      
 83 
     | 
    
         
            +
                  context 'that pass' do
         
     | 
| 
      
 84 
     | 
    
         
            +
                    before do
         
     | 
| 
      
 85 
     | 
    
         
            +
                      User.prepare_versioned_options(:if => [:true], :unless => [:true])
         
     | 
| 
      
 86 
     | 
    
         
            +
                      subject.update_attribute(:last_name, 'Jobs')
         
     | 
| 
      
 87 
     | 
    
         
            +
                    end
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
                    its('versions.count'){ should == count }
         
     | 
| 
      
 90 
     | 
    
         
            +
                  end
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
                  context 'that fail' do
         
     | 
| 
      
 93 
     | 
    
         
            +
                    before do
         
     | 
| 
      
 94 
     | 
    
         
            +
                      User.prepare_versioned_options(:if => [:false], :unless => [:false])
         
     | 
| 
      
 95 
     | 
    
         
            +
                      subject.update_attribute(:last_name, 'Jobs')
         
     | 
| 
      
 96 
     | 
    
         
            +
                    end
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
                    its('versions.count'){ should == count }
         
     | 
| 
      
 99 
     | 
    
         
            +
                  end
         
     | 
| 
      
 100 
     | 
    
         
            +
                end
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
      
 102 
     | 
    
         
            +
              end
         
     | 
| 
      
 103 
     | 
    
         
            +
            end
         
     |