archivist 1.0.5.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. data/MIT-LICENSE +17 -15
  2. data/README.rdoc +3 -0
  3. data/Rakefile +36 -0
  4. data/lib/archivist.rb +0 -1
  5. data/lib/archivist/archive.rb +10 -4
  6. data/lib/archivist/base.rb +59 -51
  7. data/lib/archivist/migration.rb +1 -1
  8. data/lib/archivist/version.rb +3 -0
  9. data/lib/tasks/archivist_tasks.rake +4 -0
  10. data/test/archive_test.rb +16 -0
  11. data/test/archivist_test.rb +17 -0
  12. data/test/base_test.rb +342 -0
  13. data/test/db/migrate/01_add_to_some_models.rb +11 -0
  14. data/test/db_test.rb +42 -0
  15. data/test/dummy/README.rdoc +261 -0
  16. data/test/dummy/Rakefile +7 -0
  17. data/test/dummy/app/assets/javascripts/application.js +15 -0
  18. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  19. data/test/dummy/app/controllers/application_controller.rb +3 -0
  20. data/test/dummy/app/helpers/application_helper.rb +2 -0
  21. data/test/dummy/app/models/another_model.rb +4 -0
  22. data/test/dummy/app/models/some_model.rb +12 -0
  23. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  24. data/test/dummy/config.ru +4 -0
  25. data/test/dummy/config/application.rb +61 -0
  26. data/test/dummy/config/boot.rb +10 -0
  27. data/test/dummy/config/database.yml +19 -0
  28. data/test/dummy/config/environment.rb +5 -0
  29. data/test/dummy/config/environments/development.rb +37 -0
  30. data/test/dummy/config/environments/production.rb +67 -0
  31. data/test/dummy/config/environments/test.rb +37 -0
  32. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  33. data/test/dummy/config/initializers/inflections.rb +15 -0
  34. data/test/dummy/config/initializers/mime_types.rb +5 -0
  35. data/test/dummy/config/initializers/secret_token.rb +7 -0
  36. data/test/dummy/config/initializers/session_store.rb +8 -0
  37. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  38. data/test/dummy/config/locales/en.yml +5 -0
  39. data/test/dummy/config/routes.rb +58 -0
  40. data/test/dummy/db/schema.rb +41 -0
  41. data/test/dummy/db/test.sqlite3 +0 -0
  42. data/test/dummy/lib/this_module.rb +3 -0
  43. data/test/dummy/log/development.log +7 -0
  44. data/test/dummy/log/test.log +35228 -0
  45. data/test/dummy/public/404.html +26 -0
  46. data/test/dummy/public/422.html +26 -0
  47. data/test/dummy/public/500.html +25 -0
  48. data/test/dummy/public/favicon.ico +0 -0
  49. data/test/dummy/script/rails +6 -0
  50. data/test/dummy/test/fixtures/another_models.yml +9 -0
  51. data/test/dummy/test/fixtures/some_models.yml +13 -0
  52. data/test/dummy/test/unit/another_model_test.rb +7 -0
  53. data/test/dummy/test/unit/some_model_test.rb +7 -0
  54. data/test/factories/some_model_factory.rb +8 -0
  55. data/test/migration_test.rb +69 -0
  56. data/test/test_helper.rb +27 -0
  57. metadata +210 -16
  58. data/README.md +0 -162
@@ -1,18 +1,20 @@
1
- Copyright (c) 2010 Tyler Pickett
1
+ Copyright 2012 YOURNAME
2
2
 
3
- Permission is hereby granted, free of charge, to any person obtaining a copy of
4
- this software and associated documentation files (the "Software"), to deal in
5
- the Software without restriction, including without limitation the rights to
6
- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7
- the Software, and to permit persons to whom the Software is furnished to do so,
8
- subject to the following conditions:
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
9
10
 
10
- The above copyright notice and this permission notice shall be included in all
11
- copies or substantial portions of the Software.
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
12
13
 
13
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15
- FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16
- COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
- IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,3 @@
1
+ = Archivist
2
+
3
+ This project rocks and uses MIT-LICENSE.
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+
8
+ begin
9
+ require 'rdoc/task'
10
+ rescue LoadError
11
+ require 'rdoc/rdoc'
12
+ require 'rake/rdoctask'
13
+ RDoc::Task = Rake::RDocTask
14
+ end
15
+
16
+ RDoc::Task.new(:rdoc) do |rdoc|
17
+ rdoc.rdoc_dir = 'rdoc'
18
+ rdoc.title = 'Archivist'
19
+ rdoc.options << '--line-numbers'
20
+ rdoc.rdoc_files.include('README.rdoc')
21
+ rdoc.rdoc_files.include('lib/**/*.rb')
22
+ end
23
+
24
+ Bundler::GemHelper.install_tasks
25
+
26
+ require 'appraisal'
27
+ require 'rake/testtask'
28
+
29
+ Rake::TestTask.new(:test) do |t|
30
+ t.libs << 'lib'
31
+ t.libs << 'test'
32
+ t.pattern = 'test/**/*_test.rb'
33
+ t.verbose = false
34
+ end
35
+
36
+ task :default => :test
@@ -1,6 +1,5 @@
1
1
  #require dependencies even though starting a rails app will already have them in place
2
2
  require 'rubygems'
3
- gem 'activerecord','~>3.0.1' #enforce rails 3+
4
3
  require 'active_record'
5
4
 
6
5
  #require the rest of Archivist's files
@@ -8,7 +8,7 @@ module Archivist
8
8
  end
9
9
 
10
10
  def method_missing(method,*args,&block)
11
- if get_klass_instance_methods.include?(method.to_s)
11
+ if get_klass_instance_methods.include?(method)
12
12
  build_proxy_method(method.to_s)
13
13
  self.method(method).call(*args,&block)
14
14
  else
@@ -17,7 +17,7 @@ module Archivist
17
17
  end
18
18
 
19
19
  def respond_to?(method,include_private=false)
20
- if get_klass_instance_methods.include?(method.to_s)
20
+ if get_klass_instance_methods.include?(method)
21
21
  return true
22
22
  else
23
23
  super(method,include_private)
@@ -32,8 +32,14 @@ module Archivist
32
32
  @klass_name ||= self.class.to_s.split("::").first
33
33
  end
34
34
 
35
- def get_klass_instance_methods
36
- @klass_instance_methods ||= get_klass.instance_methods(false)
35
+ if RUBY_VERSION >= "1.9"
36
+ def get_klass_instance_methods
37
+ @klass_instance_methods ||= get_klass.instance_methods(false)
38
+ end
39
+ else
40
+ def get_klass_instance_methods
41
+ @klass_instance_methods ||= get_klass.instance_methods(false).map(&:to_sym)
42
+ end
37
43
  end
38
44
 
39
45
  def build_proxy_method(method_name)
@@ -7,7 +7,7 @@ end
7
7
  module Archivist
8
8
  module Base
9
9
 
10
- DEFAULT_OPTIONS = {:associate_with_original=>false,:allow_multiple_archives=>false}
10
+ ARCHIVIST_DEFAULTS = {:associate_with_original=>false,:allow_multiple_archives=>false}
11
11
 
12
12
  def self.included(base)
13
13
  base.extend ClassMethods
@@ -15,47 +15,51 @@ module Archivist
15
15
 
16
16
  module ClassMethods
17
17
  def has_archive(options={})
18
- options = DEFAULT_OPTIONS.merge(options)
18
+ options = ARCHIVIST_DEFAULTS.merge(options)
19
19
  options[:allow_multiple_archives] = true if options[:associate_with_original]
20
-
21
- class_eval <<-EOF
20
+
21
+ class_eval(%Q{
22
22
  alias_method :delete!, :delete
23
-
23
+
24
24
  class << self
25
25
  alias_method :delete_all!, :delete_all
26
- end
27
-
28
- def self.archive_indexes
29
- #{Array(options[:indexes]).collect{|i| i.to_s}.inspect}
30
- end
31
26
 
32
- def self.archive_options
33
- #{options.inspect}
34
- end
35
-
36
- def self.has_archive?
37
- true
38
- end
39
-
40
- def self.acts_as_archive?
41
- warn "DEPRECATION WARNING: #acts_as_archive is provided for compatibility with AAA and will be removed soon, please use has_archive?"
42
- has_archive?
27
+ def archive_indexes
28
+ #{Array(options[:indexes]).collect{|i| i.to_s}.inspect}
29
+ end
30
+
31
+ def archive_options
32
+ #{options.inspect}
33
+ end
34
+
35
+ def has_archive?
36
+ true
37
+ end
38
+
39
+ def acts_as_archive?
40
+ warn("DEPRECATION WARNING: #acts_as_archive is provided for compatibility with AAA and will be removed soon, please use has_archive?",caller )
41
+ has_archive?
42
+ end
43
43
  end
44
44
 
45
45
  class Archive < ActiveRecord::Base
46
46
  self.record_timestamps = false
47
47
  self.table_name = "archived_#{self.table_name}"
48
- #{build_serialization_strings(self.serialized_attributes)}
49
- #{build_belongs_to_association(options[:associate_with_original])}
50
- #{build_inclusion_strings(options[:included_modules])}
51
48
  include Archivist::ArchiveMethods
52
49
  end
53
-
54
- #{build_has_many_association(options[:associate_with_original])}
55
50
 
56
51
  #{build_copy_self_to_archive(options[:allow_multiple_archives])}
57
- EOF
58
-
52
+ },File.expand_path(__FILE__),21)
53
+
54
+ if ActiveRecord::VERSION::STRING >= "3.1.0"
55
+ enable_archive_mass_assignment!(self)
56
+ end
57
+
58
+ attach_serializations!(self)
59
+ include_modules!(self,options[:included_modules]) if options[:included_modules]
60
+
61
+ build_associations!(self) if options[:associate_with_original]
62
+
59
63
  include InstanceMethods
60
64
  extend ClassExtensions
61
65
  include DB
@@ -65,31 +69,36 @@ module Archivist
65
69
  has_archive(options)
66
70
  end
67
71
 
68
- def build_inclusion_strings(included_modules)
69
- modules = ""
70
- included_modules = [included_modules] unless included_modules.is_a?(Array)
71
- included_modules.each do |mod|
72
- modules << "include #{mod.to_s}\n"
73
- end
74
- return modules
72
+ def archive_for(klass)
73
+ "#{klass.to_s}::Archive".constantize
75
74
  end
76
-
77
- def build_serialization_strings(serializde_attributes)
78
- serializations = ""
79
- self.serialized_attributes.each do |key,value|
80
- serializations << "serialize(:#{key},#{value.to_s})\n"
75
+
76
+ def enable_archive_mass_assignment!(klass)
77
+ archive_class = archive_for(klass)
78
+ attrs = archive_class.attribute_names
79
+ archive_class.send(:attr_accessible,*attrs.map(&:to_sym))
80
+ end
81
+
82
+ def attach_serializations!(klass)
83
+ archive_class = archive_for(klass)
84
+ klass.serialized_attributes.each do |column,type|
85
+ archive_class.send(:serialize,column,type)
81
86
  end
82
- return serializations
83
87
  end
84
-
85
- def build_has_many_association(associate=false)
86
- associate ? "has_many :archived_#{self.table_name},:class_name=>'#{self.new.class.to_s}::Archive'" : ""
88
+
89
+ def include_modules!(klass,modules)
90
+ archive_class = archive_for(klass)
91
+ [*modules].each do |mod|
92
+ archive_class.send(:include,mod)
93
+ end
87
94
  end
88
-
89
- def build_belongs_to_association(associate=false)
90
- associate ? "belongs_to :#{self.table_name},:class_name=>'#{self.new.class.to_s}'" : ""
95
+
96
+ def build_associations!(klass)
97
+ archive_class = archive_for(klass)
98
+ klass.send(:has_many,"archived_#{klass.table_name}".to_sym,:class_name => archive_class.to_s)
99
+ archive_class.send(:belongs_to, klass.table_name.to_sym, :class_name => klass.to_s)
91
100
  end
92
-
101
+
93
102
  def build_copy_self_to_archive(allow_multiple=false)
94
103
  if allow_multiple #we put the original pk in the fk instead
95
104
  "def copy_self_to_archive
@@ -123,9 +132,8 @@ module Archivist
123
132
  archived.save"
124
133
  end
125
134
 
126
- private :build_inclusion_strings,:build_serialization_strings,
127
- :build_has_many_association,:build_belongs_to_association,
128
- :build_copy_self_to_archive,:yield_and_save
135
+ private :include_modules!,:attach_serializations!, :build_associations!,
136
+ :archive_for,:build_copy_self_to_archive,:yield_and_save
129
137
  end
130
138
 
131
139
  module InstanceMethods #these defs can't happen untill after we've aliased their respective originals
@@ -14,7 +14,6 @@ module Archivist
14
14
 
15
15
  module ClassMethods
16
16
  def method_missing_with_archive(method, *arguments, &block)
17
- method_missing_without_archive(method, *arguments, &block)
18
17
  allowed = [:add_column,:add_timestamps,:change_column,
19
18
  :change_column_default,:change_table,:drop_table,
20
19
  :remove_column, :remove_columns, :remove_timestamps,
@@ -30,6 +29,7 @@ module Archivist
30
29
  ActiveRecord::Base.connection.send(method, *args, &block)
31
30
  end
32
31
  end
32
+ method_missing_without_archive(method, *arguments, &block)
33
33
  end
34
34
  end
35
35
  end
@@ -0,0 +1,3 @@
1
+ module Archivist
2
+ VERSION = "1.0.1.beta1"
3
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :archivist do
3
+ # # Task goes here
4
+ # end
@@ -0,0 +1,16 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
2
+
3
+ class ArchiveTest < ActiveSupport::TestCase
4
+ context "The module Archivist::ArchiveMethods" do
5
+ should "give the Archive subclass the super's methods" do
6
+ assert_nothing_raised do
7
+ model = SomeModel::Archive.new(:first_name=>"Steve",:last_name=>"Smith")
8
+ model.full_name
9
+ end
10
+ end
11
+
12
+ should "make the Archive subclass respond_to? correctly" do
13
+ assert SomeModel::Archive.new.respond_to?(:full_name)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,17 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
2
+
3
+ class ArchivistTest < Test::Unit::TestCase
4
+ context "The Archivist" do
5
+ should "include Archivist::Base in ActiveRecord::Base" do
6
+ assert ActiveRecord::Base.include?(Archivist::Base)
7
+ end
8
+
9
+ should "include Archivist::Migration in ActiveRecord::Migration" do
10
+ assert ActiveRecord::Migration.include?(Archivist::Migration)
11
+ end
12
+
13
+ should "respond to Archivist.update" do
14
+ assert Archivist.respond_to?(:update)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,342 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
2
+
3
+ class BaseTest < ActiveSupport::TestCase
4
+
5
+ context "The module Archivist::Base" do
6
+ should "make ActiveRecord::Base respond to has_archive" do
7
+ assert ActiveRecord::Base.respond_to?(:has_archive)
8
+ end
9
+
10
+ should "make ActiveRecord::Base respond to acts_as_archive" do
11
+ assert ActiveRecord::Base.respond_to?(:acts_as_archive)
12
+ end
13
+ end
14
+
15
+ context "Models that call has_archive" do
16
+ should "have subclass Archive" do
17
+ assert_nothing_raised do
18
+ archive = SomeModel::Archive
19
+ end
20
+ end
21
+
22
+ should "respond to archive_indexes as a class method" do
23
+ assert SomeModel.respond_to?(:archive_indexes)
24
+ end
25
+
26
+ should "respond to acts_as_archive?" do
27
+ assert SomeModel.respond_to?(:acts_as_archive?)
28
+ end
29
+
30
+ should "respond to has_archive?" do
31
+ assert SomeModel.respond_to?(:has_archive?)
32
+ end
33
+
34
+ should "respond to has_archive? with true" do
35
+ assert SomeModel.has_archive?
36
+ end
37
+
38
+ should "respond_to? archive_options" do
39
+ assert SomeModel.respond_to?(:archive_options)
40
+ end
41
+
42
+ should "return the options hash when archive_options is called" do
43
+ options_hash = Archivist::Base::ARCHIVIST_DEFAULTS.merge({:associate_with_original=>true,:allow_multiple_archives=>true})
44
+ assert_equal options_hash,AnotherModel.archive_options
45
+ end
46
+
47
+ context "with the associate_with_original option set to true" do
48
+ should "cause the main class to have a has_many reflection to the achive class" do
49
+ reflections = AnotherModel.reflect_on_all_associations(:has_many).map{|r| r.name}
50
+ assert_match /archived_another_models/,reflections.join(',')
51
+ end
52
+
53
+ should "cause the Archive class to have a belongs_to reflection to the main class" do
54
+ reflections = AnotherModel::Archive.reflect_on_all_associations(:belongs_to).map{|r| r.name}
55
+ assert_match /another_models/,reflections.join(',')
56
+ end
57
+ end
58
+ end
59
+
60
+ context "The Archive subclass" do
61
+ should "not write updated timestamps" do
62
+ assert !SomeModel::Archive.record_timestamps
63
+ end
64
+
65
+ should "have the same serialized attributes as the parent" do
66
+ assert_equal SomeModel.serialized_attributes,SomeModel::Archive.serialized_attributes
67
+ end
68
+
69
+ should "have the Archivist::Base::Archive included in it" do
70
+ assert SomeModel::Archive.include?(Archivist::ArchiveMethods)
71
+ end
72
+
73
+ should "have the correct modules included when the included_modules option is set" do
74
+ assert SomeModel::Archive.include?(ThisModule)
75
+ end
76
+ end
77
+
78
+ context "The archiving functionality" do
79
+ context "when using copy_self_to_archive and the associate_with_original option is set to true" do
80
+ setup do
81
+ @zapp = AnotherModel.create!(:first_name=>"Zapp",:last_name=>"Brannigan")
82
+ @zapp.copy_self_to_archive
83
+ end
84
+
85
+ should "create a new archive record" do
86
+ assert_equal 1,AnotherModel::Archive.count
87
+ end
88
+
89
+ should "create a child record" do
90
+ assert_equal 1,@zapp.archived_another_models.size
91
+ end
92
+ end
93
+
94
+ context "when calling #copy_to_archive directly" do
95
+ setup do
96
+ @my_model = FactoryGirl.create(:some_model)
97
+ end
98
+
99
+ should "not delete the original if told not to" do
100
+ SomeModel.copy_to_archive({:id=>@my_model.id},false)
101
+ assert SomeModel.exists?(@my_model.id)
102
+ end
103
+
104
+ should "allow the user to pass in a block" do
105
+ block_called = false
106
+ SomeModel.copy_to_archive({:id=>@my_model.id},false) do |archive|
107
+ block_called = true
108
+ end
109
+ assert block_called
110
+ end
111
+
112
+ should "create a new entry in the archive when told not to delete" do
113
+ SomeModel.copy_to_archive({:id=>@my_model.id},false)
114
+ assert !SomeModel::Archive.where({:id=>@my_model.id}).empty?
115
+ end
116
+
117
+ should "delete the original if not specified" do
118
+ SomeModel.copy_to_archive({:id=>@my_model.id})
119
+ assert SomeModel.where({:id=>@my_model.id}).empty?
120
+ end
121
+
122
+ should "create a new entry in the archive if delete is not specified" do
123
+ SomeModel.copy_to_archive({:id=>@my_model.id})
124
+ assert !SomeModel::Archive.where({:id=>@my_model.id}).empty?
125
+ end
126
+
127
+ should "update the archived info when previously archived" do
128
+ SomeModel.copy_to_archive({:id=>@my_model.id},false)
129
+ SomeModel.where({:id=>@my_model.id}).first.update_attributes!(:first_name=>"Cindy",:last_name=>"Crawford")
130
+ SomeModel.copy_to_archive({:id=>@my_model.id})
131
+ m = SomeModel::Archive.where({:id=>@my_model.id}).first
132
+ assert_equal "Crawford",m.last_name
133
+ end
134
+
135
+ should "not create duplicate entries when previously copied" do
136
+ SomeModel.copy_to_archive({:id=>@my_model.id},false)
137
+ SomeModel.where({:id=>@my_model.id}).first.update_attributes!(:first_name=>"Cindy",:last_name=>"Crawford")
138
+ SomeModel.copy_to_archive({:id=>@my_model.id})
139
+ assert_equal 1,SomeModel::Archive.all.size
140
+ end
141
+ end
142
+
143
+ context "when calling #delete on an existing record" do
144
+ setup do
145
+ @my_model = FactoryGirl.create(:some_model)
146
+ @my_model.delete
147
+ end
148
+
149
+ should "archive the record in question" do
150
+ assert SomeModel::Archive.exists?(@my_model.id)
151
+ end
152
+
153
+ should "remove the original record" do
154
+ assert !SomeModel.exists?(@my_model.id)
155
+ end
156
+
157
+ should "not change a model's id" do
158
+ @original = SomeModel.new
159
+ @original.id = 15
160
+ @original.first_name = "Clark"
161
+ @original.last_name = "Wayne"
162
+ @original.save
163
+ SomeModel.where(:id=>15).first.destroy
164
+ @archived = SomeModel::Archive.where(:id=>15)
165
+ assert_equal "Wayne",@archived.first.last_name
166
+ end
167
+ end
168
+
169
+ context "when calling #delete! on an existing record" do
170
+ setup do
171
+ @my_model = FactoryGirl.create(:some_model)
172
+ @my_model.delete!
173
+ end
174
+
175
+ should "NOT archive the record in question" do
176
+ assert !SomeModel::Archive.exists?(@my_model.id)
177
+ end
178
+
179
+ should "remove the original record" do
180
+ assert !SomeModel.exists?(@my_model.id)
181
+ end
182
+ end
183
+
184
+ context "when calling delete on a new record" do
185
+ setup do
186
+ m = SomeModel.new(:first_name=>"Fabio",:last_name=>"Lanzoni")
187
+ m.delete
188
+ end
189
+
190
+ should "not archive the record" do
191
+ assert SomeModel::Archive.where(:first_name=>"Fabio").empty?
192
+ end
193
+ end
194
+
195
+ context "when calling destroy on an existing record" do
196
+ setup do
197
+ @my_model = FactoryGirl.create(:some_model)
198
+ @my_model.destroy
199
+ end
200
+
201
+ should "archive the record in question" do
202
+ assert SomeModel::Archive.exists?(@my_model.id)
203
+ end
204
+
205
+ should "remove the original record" do
206
+ assert !SomeModel.exists?(@my_model.id)
207
+ end
208
+ end
209
+
210
+ context "when calling destroy! on an existing record" do
211
+ setup do
212
+ @my_model = FactoryGirl.create(:some_model)
213
+ @my_model.destroy!
214
+ end
215
+
216
+ should "NOT archive the record in question" do
217
+ assert !SomeModel::Archive.exists?(@my_model.id)
218
+ end
219
+
220
+ should "remove the original record" do
221
+ assert !SomeModel.exists?(@my_model.id)
222
+ end
223
+ end
224
+
225
+ context "when calling delete_all without conditions" do
226
+ setup do
227
+ 3.times do
228
+ FactoryGirl.create(:some_model)
229
+ end
230
+ @count = SomeModel.count
231
+ SomeModel.delete_all
232
+ end
233
+
234
+ should "empty the original table" do
235
+ assert SomeModel.all.empty?
236
+ end
237
+
238
+ should "fill the archive table" do
239
+ assert_equal @count,SomeModel::Archive.count
240
+ end
241
+ end
242
+
243
+ context "when calling delete_all with conditions" do
244
+ setup do
245
+ @models = []
246
+ 2.times do
247
+ @models << FactoryGirl.create(:some_model)
248
+ end
249
+ @mid = @models[1].id
250
+ SomeModel.delete_all(:id=>@mid)
251
+ end
252
+
253
+ should "leave non_matching items in table" do
254
+ assert_equal 1,SomeModel.all.size
255
+ end
256
+
257
+ should "remove matching items" do
258
+ assert SomeModel.where(:id=>@mid).empty?
259
+ end
260
+
261
+ should "fill the archive table" do
262
+ assert_equal 1,SomeModel::Archive.count
263
+ end
264
+ end
265
+
266
+ context "when calling delete_all! without conditions" do
267
+ setup do
268
+ 2.times do
269
+ FactoryGirl.create(:some_model)
270
+ end
271
+ SomeModel.delete_all!
272
+ end
273
+
274
+ should "empty the original table" do
275
+ assert SomeModel.all.empty?
276
+ end
277
+
278
+ should "NOT fill the archive table" do
279
+ assert SomeModel::Archive.all.empty?
280
+ end
281
+ end
282
+
283
+ context "when calling delete_all! with conditions" do
284
+ setup do
285
+ @models = []
286
+ 2.times do
287
+ @models << FactoryGirl.create(:some_model)
288
+ end
289
+ @mid = @models[1].id
290
+ SomeModel.delete_all!(:id=>@mid)
291
+ end
292
+
293
+ should "NOT fill the archive table" do
294
+ assert_equal 0,SomeModel::Archive.count
295
+ end
296
+ end
297
+
298
+ context "when restoring from the archive" do
299
+ setup do
300
+ @models = []
301
+ 2.times do
302
+ @models << FactoryGirl.create(:some_model)
303
+ end
304
+ @mid = @models[1].id
305
+ SomeModel.delete_all
306
+ end
307
+
308
+ context "with conditions" do
309
+ setup do
310
+ @mod = SomeModel::Archive.where(:id=>@mid).first
311
+ SomeModel.copy_from_archive(:id=>@mid)
312
+ end
313
+
314
+ should "re-populate the original table" do
315
+ assert_equal 1,SomeModel.count
316
+ end
317
+
318
+ should "remove the archived record" do
319
+ assert SomeModel::Archive.where(:id=>@mid).empty?
320
+ end
321
+
322
+ should "restore with original id" do
323
+ assert_equal @mod.first_name,SomeModel.where(:id=>@mid).first.first_name
324
+ end
325
+ end
326
+
327
+ context "using restore_all" do
328
+ setup do
329
+ SomeModel.restore_all
330
+ end
331
+
332
+ should "repopulate the original table" do
333
+ assert_equal 2,SomeModel.count
334
+ end
335
+
336
+ should "empty the archive table" do
337
+ assert SomeModel::Archive.all.empty?
338
+ end
339
+ end
340
+ end
341
+ end
342
+ end