versions 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -3,4 +3,4 @@ coverage
3
3
  rdoc
4
4
  pkg
5
5
  *.gem
6
- test/test.log
6
+ log
data/History.txt CHANGED
@@ -1,3 +1,12 @@
1
+ == 0.3.0 2010-05-27
2
+
3
+ * 1 major enhancement
4
+ * Added 'destroy' module to destroy with __destroy nested attribute.
5
+
6
+ * 2 minor enhancements
7
+ * Moved filepath generation in a class method.
8
+ * Hook to define previous number on increase.
9
+
1
10
  == 0.2.1 2010-02-16
2
11
 
3
12
  * 1 major enhancement
data/lib/versions/auto.rb CHANGED
@@ -30,8 +30,7 @@ module Versions
30
30
  self[:number] = 1
31
31
  elsif changed? && should_clone?
32
32
  @previous_id = self[:id]
33
- @previous_number ||= self[:number]
34
- self[:number] = @previous_number + 1
33
+ self[:number] = self.previous_number + 1
35
34
 
36
35
  self[:id] = nil
37
36
  self[:created_at] = nil
@@ -48,5 +47,9 @@ module Versions
48
47
  @previous_number = nil
49
48
  true
50
49
  end
50
+
51
+ def previous_number
52
+ @previous_number ||= self[:number]
53
+ end
51
54
  end # Auto
52
55
  end # Versions
@@ -2,62 +2,24 @@ module Versions
2
2
  # If you include this module in your model (which should also include Versions::Multi), deleting
3
3
  # the last version will destroy the model.
4
4
  module Destroy
5
-
6
- # This module should be included in the model that serves as version.
7
- module Version
8
- def self.included(base)
9
-
10
- base.class_eval do
11
- attr_accessor :__destroy
12
- belongs_to :node
13
- before_create :setup_version_on_create
14
- attr_protected :number, :user_id
15
-
16
- alias_method_chain :save, :destroy
17
- end
18
- end
19
-
20
- def save_with_destroy(*args)
21
- if @__destroy
22
- node = self.node
23
- if destroy
24
- # reset @version
25
- node.send(:version_destroyed)
26
- true
27
- end
28
- else
29
- save_without_destroy(*args)
30
- end
31
- end
32
-
33
- private
34
- def setup_version_on_create
35
- raise "You should define 'setup_version_on_create' method in '#{self.class}' class."
36
- end
37
- end
38
-
39
5
  def self.included(base)
40
- base.alias_method_chain :save, :destroy
6
+ base.class_eval do
7
+ before_destroy :check_can_destroy
8
+ alias_method_chain :attributes=, :destroy
9
+ end
41
10
  end
42
11
 
43
- def save_with_destroy(*args)
44
- version = self.version
45
- # TODO: we could use 'version.mark_for_destruction' instead of __destroy...
46
- if version.__destroy && versions.count == 1
47
- destroy # will destroy last version
48
- else
49
- save_without_destroy(*args)
12
+ def attributes_with_destroy=(hash)
13
+ if hash.delete(:__destroy) || hash.delete('__destroy')
14
+ self.mark_for_destruction
50
15
  end
16
+ self.attributes_without_destroy = hash
51
17
  end
52
-
18
+
53
19
  private
54
- # This is called after a version is destroyed
55
- def version_destroyed
56
- # remove from versions list
57
- if versions.loaded?
58
- node.versions -= [@version]
59
- end
20
+ # Default is to forbid destruction
21
+ def check_can_destroy
22
+ raise Exception.new("You should implement 'check_can_destroy' in #{self.class}")
60
23
  end
61
-
62
24
  end
63
25
  end
@@ -31,27 +31,27 @@ module Versions
31
31
  # local key to get the current page. Note that the local key does not need to live in the database if the model
32
32
  # defines <tt>set_current_[assoc]_before_update</tt> and <tt>set_current_[assoc]_after_create</tt> where '[assoc]'
33
33
  # represents the association name.
34
- def has_multiple(versions, options = {})
35
- name = versions.to_s.singularize
36
- klass = (options[:class_name] || name.capitalize).constantize
37
- owner_name = options[:inverse] || self.to_s.split('::').last.underscore
34
+ def has_multiple(association_name, options = {})
35
+ name = association_name.to_s.singularize
36
+ klass = (options[:class_name] || name.capitalize).constantize
37
+ owner_name = options[:inverse] || self.to_s.split('::').last.underscore
38
38
  foreign_key = (options[:foreign_key] || "#{owner_name}_id").to_s
39
39
  local_key = (options[:local_key] || "#{name}_id").to_s
40
40
 
41
41
  raise TypeError.new("Missing 'number' field in table #{klass.table_name}.") unless klass.column_names.include?('number')
42
42
  raise TypeError.new("Missing '#{foreign_key}' in table #{klass.table_name}.") unless klass.column_names.include?(foreign_key)
43
43
 
44
- has_many versions, :order => 'number DESC', :class_name => klass.to_s, :foreign_key => foreign_key, :dependent => :destroy
44
+ has_many association_name, :order => 'number DESC', :class_name => klass.to_s, :foreign_key => foreign_key, :dependent => :destroy
45
45
  validate :"validate_#{name}"
46
46
  after_create :"save_#{name}_after_create"
47
47
  before_update :"save_#{name}_before_update"
48
48
 
49
- include module_for_multiple(name, klass, owner_name, foreign_key, local_key)
49
+ include module_for_multiple(name, klass, owner_name, foreign_key, local_key, association_name)
50
50
  klass.belongs_to owner_name, :class_name => self.to_s
51
51
  end
52
52
 
53
53
  protected
54
- def module_for_multiple(name, klass, owner_name, foreign_key, local_key)
54
+ def module_for_multiple(name, klass, owner_name, foreign_key, local_key, association_name)
55
55
 
56
56
  # Eval is ugly, but it's the fastest solution I know of
57
57
  line = __LINE__
@@ -84,6 +84,15 @@ module Versions
84
84
  end # end
85
85
 
86
86
  def save_#{name}_before_update # def save_version_before_update
87
+ return true unless @#{name} # return true unless @version
88
+ if @#{name}.marked_for_destruction? # if @version.marked_for_destruction?
89
+ if @#{name}.destroy # if @version.destroy
90
+ set_current_#{name}_before_update # set_current_version_before_update
91
+ return true # return true
92
+ else # else
93
+ return false # return false
94
+ end # end
95
+ end # end
87
96
  return true if !@#{name}.changed? # return true if !@version.changed?
88
97
  @#{name}.#{foreign_key} = self[:id] # @version.owner_id = self[:id]
89
98
  if !@#{name}.save(false) # if !@version.save_with_validation(false)
@@ -113,7 +122,16 @@ module Versions
113
122
  # master record is updated. This method is usually overwritten
114
123
  # in the class.
115
124
  def set_current_#{name}_before_update # def set_current_version_before_update
116
- self[:#{local_key}] = @#{name}.id # self[:version_id] = @version.id
125
+ if @#{name}.marked_for_destruction? # if @version.marked_for_destruction?
126
+ if last = #{association_name}.last # if last = versions.last
127
+ self[:#{local_key}] = last.id # self[:version_id] = versions.last.id
128
+ else # else
129
+ self[:#{local_key}] = nil # self[:version_id] = nil
130
+ end # end
131
+ @#{name} = nil # @version = nil
132
+ else # else
133
+ self[:#{local_key}] = @#{name}.id # self[:version_id] = @version.id
134
+ end # end
117
135
  end # end
118
136
 
119
137
  # This method is triggered when the version is saved, after the
@@ -6,6 +6,11 @@ module Versions
6
6
  after_destroy :destroy_file
7
7
  after_save :write_file
8
8
 
9
+ def self.filepath(id, filename)
10
+ digest = ::Digest::SHA1.hexdigest(id.to_s)
11
+ "#{digest[0..0]}/#{digest[1..1]}/#{filename}"
12
+ end
13
+
9
14
  def unlink(model)
10
15
  link_count = model.class.count(:conditions => ["attachment_id = ? AND id != ?", self.id, model.id])
11
16
  if link_count == 0
@@ -15,7 +20,16 @@ module Versions
15
20
 
16
21
  def file=(file)
17
22
  @file = file
18
- self[:filename] = get_filename(file)
23
+ self.filename = get_filename(file)
24
+ end
25
+
26
+ def filename=(name)
27
+ fname = name.gsub(/[^a-zA-Z\-_0-9\.]/,'')
28
+ if fname[0..0] == '.'
29
+ # Forbid names starting with a dot
30
+ fname = Digest::SHA1.hexdigest(Time.now.to_i.to_s)[0..6]
31
+ end
32
+ self[:filename] = fname
19
33
  end
20
34
 
21
35
  def file
@@ -23,9 +37,7 @@ module Versions
23
37
  end
24
38
 
25
39
  def filepath
26
- @filepath ||= begin digest = ::Digest::SHA1.hexdigest(self[:id].to_s)
27
- "#{digest[0..0]}/#{digest[1..1]}/#{filename}"
28
- end
40
+ @filepath ||= self.class.filepath(self[:id], filename)
29
41
  end
30
42
 
31
43
  private
@@ -45,10 +57,15 @@ module Versions
45
57
  FileUtils::mkpath(File.dirname(path)) unless File.exist?(File.dirname(path))
46
58
  if data.respond_to?(:rewind)
47
59
  data.rewind
48
- end
49
- File.open(path, "wb") do |file|
50
- while buffer = data.read(2_024_000)
51
- file.syswrite(buffer)
60
+
61
+ File.open(path, "wb") do |file|
62
+ while buffer = data.read(2_024_000)
63
+ file.syswrite(buffer)
64
+ end
65
+ end
66
+ else
67
+ File.open(path, "wb") do |file|
68
+ file.syswrite(data.read)
52
69
  end
53
70
  end
54
71
  end
@@ -58,13 +75,7 @@ module Versions
58
75
  end
59
76
 
60
77
  def get_filename(file)
61
- # make sure name is not corrupted
62
- fname = file.original_filename.gsub(/[^a-zA-Z\-_0-9\.]/,'')
63
- if fname[0..0] == '.'
64
- # Forbid names starting with a dot
65
- fname = Digest::SHA1.hexdigest(Time.now.to_i.to_s)[0..6]
66
- end
67
- fname
78
+ file.original_filename
68
79
  end
69
80
  end # SharedAttachment
70
81
  end # Versions
@@ -1,3 +1,3 @@
1
1
  module Versions
2
- VERSION = '0.2.1'
2
+ VERSION = '0.3.0'
3
3
  end
data/lib/versions.rb CHANGED
@@ -4,3 +4,4 @@ require 'versions/attachment'
4
4
  require 'versions/auto'
5
5
  require 'versions/multi'
6
6
  require 'versions/version'
7
+ require 'versions/destroy'
data/test/fixtures.rb CHANGED
@@ -20,7 +20,6 @@ begin
20
20
  def self.up
21
21
  create_table 'pages' do |t|
22
22
  t.integer 'version_id'
23
- t.integer 'foo_id'
24
23
  t.string 'name'
25
24
  t.timestamps
26
25
  end
@@ -44,10 +43,10 @@ begin
44
43
  end
45
44
 
46
45
  ActiveRecord::Base.establish_connection(:adapter=>'sqlite3', :database=>':memory:')
47
- ActiveRecord::Base.logger = Logger.new(File.open(Pathname(__FILE__).dirname + 'test.log', 'wb'))
48
- #if !ActiveRecord::Base.connection.table_exists?('pages')
49
- ActiveRecord::Migration.verbose = false
50
- VersionsMigration.migrate(:up)
51
- ActiveRecord::Migration.verbose = true
52
- #end
46
+ log_path = Pathname(__FILE__).dirname + '../log/test.log'
47
+ Dir.mkdir(log_path.dirname) unless File.exist?(log_path.dirname)
48
+ ActiveRecord::Base.logger = Logger.new(File.open(log_path, 'wb'))
49
+ ActiveRecord::Migration.verbose = false
50
+ VersionsMigration.migrate(:up)
51
+ ActiveRecord::Migration.verbose = true
53
52
  end
@@ -112,6 +112,17 @@ class AutoTest < Test::Unit::TestCase
112
112
  subject.update_attributes('title' => 'Kierkegaard')
113
113
  assert_equal 3, subject.number
114
114
  end
115
+
116
+ should 'call previous_number to build number' do
117
+ class << subject
118
+ def previous_number
119
+ 5
120
+ end
121
+ end
122
+
123
+ subject.update_attributes('title' => 'Aristotle')
124
+ assert_equal 6, subject.number
125
+ end
115
126
  end
116
127
  end
117
128
  end
@@ -0,0 +1,94 @@
1
+ require 'helper'
2
+
3
+ class DestroyTest < Test::Unit::TestCase
4
+ class Version < ActiveRecord::Base
5
+ attr_accessor :can_destroy
6
+ set_table_name :versions
7
+ include Versions::Auto
8
+ include Versions::Destroy
9
+
10
+ def check_can_destroy
11
+ defined?(@can_destroy) ? @can_destroy : true
12
+ end
13
+ end
14
+
15
+ class Page < ActiveRecord::Base
16
+ set_table_name :pages
17
+ include Versions::Multi
18
+ has_multiple :versions, :class_name => 'DestroyTest::Version'
19
+ end
20
+
21
+ class VersionWithoutCanDestroy < ActiveRecord::Base
22
+ attr_accessor :can_destroy
23
+ set_table_name :versions
24
+ include Versions::Auto
25
+ include Versions::Destroy
26
+ end
27
+
28
+ class Page2 < ActiveRecord::Base
29
+ set_table_name :pages
30
+ include Versions::Multi
31
+ has_multiple :versions, :class_name => 'DestroyTest::VersionWithoutCanDestroy', :foreign_key => 'page_id'
32
+ end
33
+
34
+ context 'A page with a version' do
35
+ subject do
36
+ Page.create('name' => 'one', 'version_attributes' => {'title' => 'First'})
37
+ end
38
+
39
+ should 'destroy version on __destroy nested attribute' do
40
+ subject
41
+ assert_difference('Version.count', -1) do
42
+ subject.update_attributes('version_attributes' => {:__destroy => true})
43
+ end
44
+ end
45
+
46
+ should 'not destroy if not allowed' do
47
+ subject.version.can_destroy = false
48
+ assert_difference('Version.count', 0) do
49
+ subject.update_attributes('version_attributes' => {:__destroy => true})
50
+ end
51
+ end
52
+ end # A page with a version
53
+
54
+ context 'A version without can destroy' do
55
+ subject do
56
+ Page2.create('name' => 'one', 'version_attributes' => {'title' => 'First'})
57
+ end
58
+
59
+ should 'raise an exception on __destroy' do
60
+ assert_raise(Exception) do
61
+ subject.update_attributes('version_attributes' => {:__destroy => true})
62
+ end
63
+ end
64
+ end
65
+
66
+ context 'A page with many versions' do
67
+ subject do
68
+ p = Page.create('name' => 'one', 'version_attributes' => {'title' => 'first'})
69
+ p.update_attributes('version_attributes' => {'title' => 'second'})
70
+ p
71
+ end
72
+
73
+ should 'remove version from versions on destroy' do
74
+ # This also loads versions association
75
+ assert_equal 2, subject.versions.count
76
+
77
+ assert_difference('Version.count', -1) do
78
+ subject.update_attributes('version_attributes' => {'__destroy' => true})
79
+ end
80
+
81
+ assert_equal 1, subject.versions.count
82
+ assert_equal 'first', subject.versions.first.title
83
+ end
84
+
85
+ should 'update current version on destroy' do
86
+ old_version_id = subject.version_id
87
+
88
+ assert subject.update_attributes('version_attributes' => {'__destroy' => true})
89
+
90
+ assert_not_equal old_version_id, subject.version_id
91
+ assert_equal 'first', subject.version.title
92
+ end
93
+ end # A page with a version
94
+ end
@@ -19,103 +19,112 @@ class MultiTest < Test::Unit::TestCase
19
19
  end
20
20
  end
21
21
  end
22
+
22
23
  class SimplePage < ActiveRecord::Base
24
+ set_table_name :pages
23
25
  include Versions::Multi
24
26
 
25
- set_table_name :pages
26
- has_multiple :foos, :class_name => 'MultiTest::SimpleVersion', :inverse => 'node'
27
+ has_multiple :simple_versions, :class_name => 'MultiTest::SimpleVersion', :inverse => 'node', :local_key => 'version_id'
27
28
  end
28
29
 
29
30
  class Version < ActiveRecord::Base
30
31
  set_table_name :versions
31
32
  include Versions::Auto
32
33
  end
34
+
33
35
  class Page < ActiveRecord::Base
34
36
  set_table_name :pages
35
37
  include Versions::Multi
36
38
  has_multiple :versions, :class_name => 'MultiTest::Version'
37
39
  end
38
40
 
39
- context 'A class with multiple foos' do
40
-
41
- should 'accept foo nested attributes' do
42
- assert_nothing_raised { SimplePage.create('name' => 'one', 'foo_attributes' => {'title' => 'First'}) }
41
+ context 'Creating a page with versions' do
42
+ should 'accept simple_version nested attributes' do
43
+ assert_nothing_raised { SimplePage.create('name' => 'one', 'simple_version_attributes' => {'title' => 'First'}) }
43
44
  end
44
45
 
45
- should 'create a foo instance of the given type' do
46
+ should 'create a simple_version instance of the given type' do
46
47
  page = SimplePage.create
47
48
  assert page.valid?
48
- assert_kind_of MultiTest::SimpleVersion, page.foo
49
+ assert_kind_of MultiTest::SimpleVersion, page.simple_version
49
50
  end
50
51
 
51
- should 'set foo_id after_create' do
52
+ should 'set version_id after_create' do
52
53
  page = SimplePage.create
53
- foo_id = page.foo_id
54
- assert foo_id
54
+ version_id = page.version_id
55
+ assert version_id
55
56
  page = SimplePage.find(page)
56
- assert_equal foo_id, page.foo_id
57
+ assert_equal version_id, page.version_id
57
58
  end
58
59
 
59
- should 'replace current instance on new foos' do
60
+ should 'replace current instance on new simple_versions' do
60
61
  page = SimplePage.create
61
- first_foo = page.foo.id
62
- page.foo = SimpleVersion.new('title' => 'hello')
62
+ first_simple_version = page.simple_version.id
63
+ page.simple_version = SimpleVersion.new('title' => 'hello')
63
64
  assert page.save
64
65
  page = SimplePage.find(page.id)
65
- assert_not_equal first_foo, page.foo.id
66
+ assert_not_equal first_simple_version, page.simple_version.id
66
67
  end
67
68
 
68
- should 'merge foo errors in model on create' do
69
- page = SimplePage.create('foo_attributes' => {'title' => 'Fox'})
69
+ should 'merge simple_version errors in model on create' do
70
+ page = SimplePage.create('simple_version_attributes' => {'title' => 'Fox'})
70
71
  assert !page.valid?
71
- assert_equal 'should not contain letter x', page.errors['foo_title']
72
+ assert_equal 'should not contain letter x', page.errors['simple_version_title']
72
73
  end
73
74
 
74
- should 'merge foo errors in model on update' do
75
- page = SimplePage.create('foo_attributes' => {'title' => 'phone'})
75
+ should 'merge simple_version errors in model on update' do
76
+ page = SimplePage.create('simple_version_attributes' => {'title' => 'phone'})
76
77
  assert page.valid?
77
- assert !page.update_attributes('foo_attributes' => {'title' => 'fax'})
78
- assert_equal 'should not contain letter x', page.errors['foo_title']
78
+ assert !page.update_attributes('simple_version_attributes' => {'title' => 'fax'})
79
+ assert_equal 'should not contain letter x', page.errors['simple_version_title']
79
80
  end
80
81
 
81
- should 'rollback if foo save fails on create' do
82
+ should 'rollback if simple_version save fails on create' do
82
83
  page = nil
83
84
  assert_difference('MultiTest::SimpleVersion.count', 0) do
84
85
  assert_difference('MultiTest::SimplePage.count', 0) do
85
- page = SimplePage.new('foo_attributes' => {'title' => 'Fly'})
86
+ page = SimplePage.new('simple_version_attributes' => {'title' => 'Fly'})
86
87
  assert !page.save
87
- assert_contains page.errors.full_messages, 'Foo title should not contain letter y'
88
+ assert_contains page.errors[:simple_version_title], 'should not contain letter y'
88
89
  end
89
90
  end
90
91
  end
91
92
 
92
- should 'abort if foo save fails on update' do
93
- page = SimplePage.create('foo_attributes' => {'title' => 'mosquito'})
93
+ should 'abort if version save fails on update' do
94
+ page = SimplePage.create('simple_version_attributes' => {'title' => 'mosquito'})
94
95
  assert page.valid?
95
- assert !page.update_attributes('foo_attributes' => {'title' => 'fly'})
96
- assert_equal 'should not contain letter y', page.errors['foo_title']
96
+ assert !page.update_attributes('simple_version_attributes' => {'title' => 'fly'})
97
+ assert_equal 'should not contain letter y', page.errors['simple_version_title']
97
98
  end
98
99
 
99
100
  should 'find owner back using inverse' do
100
101
  page = SimplePage.create
101
- assert_equal page, page.foo.node
102
+ assert_equal page, page.simple_version.node
102
103
  end
103
104
 
104
- should 'list foos' do
105
- page = SimplePage.create('foo_attributes' => {'title' => 'One'})
106
- page.foo = SimpleVersion.new('title' => 'Two')
105
+ should 'list simple_versions' do
106
+ page = SimplePage.create('simple_version_attributes' => {'title' => 'One'})
107
+ page.simple_version = SimpleVersion.new('title' => 'Two')
107
108
  page.save
108
- assert_equal 2, page.foos.size
109
+ assert_equal 2, page.simple_versions.size
109
110
  end
110
- end
111
+ end # Creating a page with versions
111
112
 
112
- context 'A class with multiple auto versions' do
113
- should 'create new versions on update' do
114
- page = Page.create
115
- assert_difference('Version.count', 1) do
116
- assert page.update_attributes('version_attributes' => {'title' => 'newTitle'})
113
+ context 'A simple page with a version' do
114
+ subject do
115
+ p = SimplePage.create('simple_version_attributes' => {'title' => 'Buz'})
116
+ SimplePage.find(p.id)
117
+ end
118
+
119
+ should 'save without validations' do
120
+ subject.name = 'hop'
121
+ assert_difference('SimpleVersion.count', 0) do
122
+ assert subject.save_with_validation(false)
117
123
  end
118
124
  end
125
+ end # A page with a version
126
+
127
+ context 'Creating an object with multiple auto versions' do
119
128
 
120
129
  should 'mark new version as not dirty after create' do
121
130
  page = Page.create
@@ -128,28 +137,64 @@ class MultiTest < Test::Unit::TestCase
128
137
  assert !page.version.changed?
129
138
  end
130
139
 
131
- should 'find latest version' do
132
- page = Page.create
133
- v_id = page.version.id
134
- assert page.update_attributes('version_attributes' => {'title' => 'newTitle'})
135
- assert_not_equal v_id, page.version.id
136
- end
137
-
138
140
  should 'not create new versions on update if content did not change' do
139
141
  page = Page.create('version_attributes' => {'title' => 'One'})
140
142
  assert_difference('Version.count', 0) do
141
143
  assert page.update_attributes('version_attributes' => {'title' => 'One'})
142
144
  end
143
145
  end
146
+ end
144
147
 
148
+ context 'A page' do
145
149
 
146
- should 'list versions' do
147
- page = Page.create('version_attributes' => {'title' => 'One'})
148
- assert page.update_attributes('version_attributes' => {'title' => 'Two'})
149
- assert page.update_attributes('version_attributes' => {'title' => 'Three'})
150
- assert_equal 3, page.versions.size
150
+ context 'with a version' do
151
+ subject do
152
+ p = Page.create('version_attributes' => {'title' => 'Fly'})
153
+ Page.find(p.id)
154
+ end
155
+
156
+ should 'create new versions on update' do
157
+ subject # create
158
+ assert_difference('Version.count', 1) do
159
+ assert subject.update_attributes('version_attributes' => {'title' => 'newTitle'})
160
+ end
161
+ end
162
+
163
+ should 'save without validations' do
164
+ subject.name = 'hop'
165
+ assert_difference('Version.count', 0) do
166
+ assert subject.save_with_validation(false)
167
+ end
168
+ end
169
+
170
+ should 'find latest version' do
171
+ v_id = subject.version.id
172
+ assert subject.update_attributes('version_attributes' => {'title' => 'newTitle'})
173
+ assert_not_equal v_id, subject.version.id
174
+ end
175
+
176
+
177
+ should 'save master model if version only changed' do
178
+ subject # create
179
+ assert_difference('Version.count', 1) do
180
+ assert subject.update_attributes('version_attributes' => {'title' => 'Two'})
181
+ end
182
+ end
151
183
  end
152
- end
184
+
185
+ context 'with many versions' do
186
+ subject do
187
+ page = Page.create('version_attributes' => {'title' => 'One'})
188
+ page.update_attributes('version_attributes' => {'title' => 'Two'})
189
+ page.update_attributes('version_attributes' => {'title' => 'Three'})
190
+ page
191
+ end
192
+
193
+ should 'list versions' do
194
+ assert_equal 3, subject.versions.size
195
+ end
196
+ end # with many versions
197
+ end # A page with a version
153
198
 
154
199
  context 'Defining association with custom foreign_key' do
155
200
  should 'not raise an exception if the key exists' do
data/versions.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{versions}
8
- s.version = "0.2.1"
8
+ s.version = "0.3.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Gaspard Bucher"]
12
- s.date = %q{2010-02-22}
12
+ s.date = %q{2010-05-27}
13
13
  s.description = %q{A list of libraries to work with ActiveRecord model versioning: Auto (duplicate on save), Multi (hide many versions behind a single one), Transparent (hide versions from outside world), Property (define properties on model, store them in versions)}
14
14
  s.email = %q{gaspard@teti.ch}
15
15
  s.extra_rdoc_files = [
@@ -38,6 +38,7 @@ Gem::Specification.new do |s|
38
38
  "test/unit/after_commit_test.rb",
39
39
  "test/unit/attachment_test.rb",
40
40
  "test/unit/auto_test.rb",
41
+ "test/unit/destroy_test.rb",
41
42
  "test/unit/multi_test.rb",
42
43
  "test/unit/property_test.rb",
43
44
  "test/unit/transparent_test.rb",
@@ -46,7 +47,7 @@ Gem::Specification.new do |s|
46
47
  s.homepage = %q{http://zenadmin.org/650}
47
48
  s.rdoc_options = ["--charset=UTF-8"]
48
49
  s.require_paths = ["lib"]
49
- s.rubygems_version = %q{1.3.5}
50
+ s.rubygems_version = %q{1.3.6}
50
51
  s.summary = %q{A list of libraries to work with ActiveRecord model versioning}
51
52
  s.test_files = [
52
53
  "test/fixtures.rb",
@@ -54,6 +55,7 @@ Gem::Specification.new do |s|
54
55
  "test/unit/after_commit_test.rb",
55
56
  "test/unit/attachment_test.rb",
56
57
  "test/unit/auto_test.rb",
58
+ "test/unit/destroy_test.rb",
57
59
  "test/unit/multi_test.rb",
58
60
  "test/unit/property_test.rb",
59
61
  "test/unit/transparent_test.rb"
metadata CHANGED
@@ -1,7 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: versions
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 3
8
+ - 0
9
+ version: 0.3.0
5
10
  platform: ruby
6
11
  authors:
7
12
  - Gaspard Bucher
@@ -9,49 +14,59 @@ autorequire:
9
14
  bindir: bin
10
15
  cert_chain: []
11
16
 
12
- date: 2010-02-22 00:00:00 +01:00
17
+ date: 2010-05-27 00:00:00 +02:00
13
18
  default_executable:
14
19
  dependencies:
15
20
  - !ruby/object:Gem::Dependency
16
21
  name: shoulda
17
- type: :development
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
20
24
  requirements:
21
25
  - - ">="
22
26
  - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
23
29
  version: "0"
24
- version:
30
+ type: :development
31
+ version_requirements: *id001
25
32
  - !ruby/object:Gem::Dependency
26
33
  name: property
27
- type: :development
28
- version_requirement:
29
- version_requirements: !ruby/object:Gem::Requirement
34
+ prerelease: false
35
+ requirement: &id002 !ruby/object:Gem::Requirement
30
36
  requirements:
31
37
  - - ">="
32
38
  - !ruby/object:Gem::Version
39
+ segments:
40
+ - 0
41
+ - 8
42
+ - 1
33
43
  version: 0.8.1
34
- version:
44
+ type: :development
45
+ version_requirements: *id002
35
46
  - !ruby/object:Gem::Dependency
36
47
  name: activesupport
37
- type: :development
38
- version_requirement:
39
- version_requirements: !ruby/object:Gem::Requirement
48
+ prerelease: false
49
+ requirement: &id003 !ruby/object:Gem::Requirement
40
50
  requirements:
41
51
  - - ">="
42
52
  - !ruby/object:Gem::Version
53
+ segments:
54
+ - 0
43
55
  version: "0"
44
- version:
56
+ type: :development
57
+ version_requirements: *id003
45
58
  - !ruby/object:Gem::Dependency
46
59
  name: activerecord
47
- type: :runtime
48
- version_requirement:
49
- version_requirements: !ruby/object:Gem::Requirement
60
+ prerelease: false
61
+ requirement: &id004 !ruby/object:Gem::Requirement
50
62
  requirements:
51
63
  - - ">="
52
64
  - !ruby/object:Gem::Version
65
+ segments:
66
+ - 0
53
67
  version: "0"
54
- version:
68
+ type: :runtime
69
+ version_requirements: *id004
55
70
  description: "A list of libraries to work with ActiveRecord model versioning: Auto (duplicate on save), Multi (hide many versions behind a single one), Transparent (hide versions from outside world), Property (define properties on model, store them in versions)"
56
71
  email: gaspard@teti.ch
57
72
  executables: []
@@ -83,6 +98,7 @@ files:
83
98
  - test/unit/after_commit_test.rb
84
99
  - test/unit/attachment_test.rb
85
100
  - test/unit/auto_test.rb
101
+ - test/unit/destroy_test.rb
86
102
  - test/unit/multi_test.rb
87
103
  - test/unit/property_test.rb
88
104
  - test/unit/transparent_test.rb
@@ -100,18 +116,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
100
116
  requirements:
101
117
  - - ">="
102
118
  - !ruby/object:Gem::Version
119
+ segments:
120
+ - 0
103
121
  version: "0"
104
- version:
105
122
  required_rubygems_version: !ruby/object:Gem::Requirement
106
123
  requirements:
107
124
  - - ">="
108
125
  - !ruby/object:Gem::Version
126
+ segments:
127
+ - 0
109
128
  version: "0"
110
- version:
111
129
  requirements: []
112
130
 
113
131
  rubyforge_project:
114
- rubygems_version: 1.3.5
132
+ rubygems_version: 1.3.6
115
133
  signing_key:
116
134
  specification_version: 3
117
135
  summary: A list of libraries to work with ActiveRecord model versioning
@@ -121,6 +139,7 @@ test_files:
121
139
  - test/unit/after_commit_test.rb
122
140
  - test/unit/attachment_test.rb
123
141
  - test/unit/auto_test.rb
142
+ - test/unit/destroy_test.rb
124
143
  - test/unit/multi_test.rb
125
144
  - test/unit/property_test.rb
126
145
  - test/unit/transparent_test.rb