Skip to content

Commit

Permalink
Tests that columns can be made unversioned using an :exclude paramete…
Browse files Browse the repository at this point in the history
…r to simply_versioned.

git-svn-id: http://rubymatt.rubyforge.org/svn/simply_versioned@15 9890f43a-5319-0410-996d-de745e0c2bc8
  • Loading branch information
mmower committed Jan 24, 2008
1 parent 2d84cc2 commit 2073a40
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 16 deletions.
5 changes: 5 additions & 0 deletions CHANGES
@@ -1,3 +1,8 @@
0.9.1 - 24-01-2008

Improved implementation of revert_to_version with further tests.
Provided clean aliases for methods in VersionProxy.

0.9 - 24-01-2008

Added an :exclude option (default: [])
Expand Down
13 changes: 11 additions & 2 deletions README
@@ -1,7 +1,7 @@
SimplyVersioned
===============

Release: 0.9
Release: 0.9.1
Date: 24-01-2008
Author: Matt Mower <self@mattmower.com>

Expand Down Expand Up @@ -43,7 +43,7 @@ Usage
If you do not specify a limit then old versions are never automatically deleted. You can
manually delete them like this:

thing.versions.clean_old_version( 10 )
thing.versions.purge( 10 )

which would delete all the but the last ten versions.

Expand Down Expand Up @@ -91,7 +91,16 @@ Usage
7. Revert to a previous version

thing.revert_to_version( 5 )

If a specific reversion needs to avoid overwriting some column values pass
an :except option, e.g.

thing.revert_to_version( 1, :except => [:name,:age] )

The revert_to_version method also takes an existing Version instance, e.g.

version = thing.versions.find( ... )
thing.revert_to_version( version )

8. Traverse versions

Expand Down
34 changes: 21 additions & 13 deletions lib/simply_versioned.rb
@@ -1,4 +1,4 @@
# SimplyVersioned 0.9
# SimplyVersioned 0.9.1
#
# Simple ActiveRecord versioning
# Copyright (c) 2007,2008 Matt Mower <self@mattmower.com>
Expand All @@ -16,7 +16,7 @@ def initialize( keys )
super( "Keys: #{keys.join( "," )} are not known by SimplyVersioned" )
end
end

module ClassMethods

# Marks this ActiveRecord model as being versioned. Calls to +create+ or +save+ will,
Expand Down Expand Up @@ -76,27 +76,29 @@ def versioning_enabled?
# Methods that will be defined on the ActiveRecord model being versioned
module InstanceMethods

# Revert this model instance to the attributes it had at the specified version number.
# Revert the attributes of this model to their values as of an earlier version.
#
# Pass either a Version instance or a version number.
#
# options:
# +except+ specify a list of attributes that are not restored (default: created_at, updated_at)
#
def revert_to_version( version, options = {} )
version = if version.kind_of?( Version )
version
else
version = self.versions.find( :first, :conditions => { :number => Integer( version ) } )
end

options.reverse_merge!({
:except => [:created_at,:updated_at]
})

reversion_data = YAML::load( version.yaml )
reversion_data.delete_if { |key,value| options[:except].include? key.to_sym }
reversion_data.each do |key,value|
self.__send__( "#{key}=", value )
version = if version.kind_of?( Version )
version
elsif version.kind_of?( Fixnum )
self.versions.find_by_number( version )
end

raise "Invalid version (#{version.inspect}) specified!" unless version

options[:except] = options[:except].map( &:to_s )

self.update_attributes( YAML::load( version.yaml ).except( *options[:except] ) )
end

# Invoke the supplied block passing the receiver as the sole block argument with
Expand Down Expand Up @@ -139,33 +141,39 @@ module VersionsProxyMethods
def get_version( number )
find_by_number( number )
end
alias_method :get, :get_version

# Get the first Version corresponding to this model.
def first_version
find( :first, :order => 'number ASC' )
end
alias_method :first, :first_version

# Get the current Version corresponding to this model.
def current_version
find( :first, :order => 'number DESC' )
end
alias_method :current, :current_version

# If the model instance has more versions than the limit specified, delete all excess older versions.
def clean_old_versions( versions_to_keep )
find( :all, :conditions => [ 'number <= ?', self.maximum( :number ) - versions_to_keep ] ).each do |version|
version.destroy
end
end
alias_method :purge, :clean_old_versions

# Return the Version for this model with the next higher version
def next_version( number )
find( :first, :order => 'number ASC', :conditions => [ "number > ?", number ] )
end
alias_method :next, :next_version

# Return the Version for this model with the next lower version
def previous_version( number )
find( :first, :order => 'number DESC', :conditions => [ "number < ?", number ] )
end
alias_method :previous, :previous_version
end

def self.included( receiver )
Expand Down
2 changes: 1 addition & 1 deletion lib/version.rb
@@ -1,4 +1,4 @@
# SimplyVersioned 0.9
# SimplyVersioned 0.9.1
#
# Simple ActiveRecord versioning
# Copyright (c) 2007,2008 Matt Mower <self@mattmower.com>
Expand Down
25 changes: 25 additions & 0 deletions test/simply_versioned_test.rb
Expand Up @@ -96,13 +96,17 @@ def test_should_get_versions
anthony.save!

assert_equal 35, anthony.versions.get_version(1).model.age
assert_equal 35, anthony.versions.get(1).model.age

assert_equal 36, anthony.versions.get_version(2).model.age
assert_equal 36, anthony.versions.get(2).model.age
end

def test_should_version_on_create
anthony = Aardvark.create!( :name => 'Anthony', :age => 35 )
assert_equal 1, anthony.versions.count
assert_equal 1, anthony.versions.current_version.number
assert_equal 1, anthony.versions.current.number
end

def test_should_version_on_save
Expand All @@ -125,7 +129,9 @@ def test_should_trim_versions

assert_equal 3, anthony.versions.count
assert_equal 36, anthony.versions.first_version.model.age
assert_equal 36, anthony.versions.first.model.age
assert_equal 38, anthony.versions.current_version.model.age
assert_equal 38, anthony.versions.current.model.age
end

def test_should_revert
Expand All @@ -149,6 +155,25 @@ def test_should_revert_except
assert_equal 35, anthony.age
end

def test_should_raise_on_reversion_to_bad_version
anthony = Aardvark.create!( :name => 'Anthony', :age => 35 ) # v1
anthony.name = "Tony"
anthony.age = 45
anthony.save! # v2

assert_raise RuntimeError do
anthony.revert_to_version( -1 )
end

assert_raise RuntimeError do
anthony.revert_to_version( "a" )
end

assert_raise RuntimeError do
anthony.revert_to_version( nil )
end
end

def test_should_delete_dependent_versions
anthony = Aardvark.create!( :name => 'Anthony', :age => 35 ) # v1
anthony.age += 1
Expand Down

0 comments on commit 2073a40

Please sign in to comment.