archivist 1.0.5.1 → 1.1.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/MIT-LICENSE +17 -15
- data/README.rdoc +3 -0
- data/Rakefile +36 -0
- data/lib/archivist.rb +0 -1
- data/lib/archivist/archive.rb +10 -4
- data/lib/archivist/base.rb +59 -51
- data/lib/archivist/migration.rb +1 -1
- data/lib/archivist/version.rb +3 -0
- data/lib/tasks/archivist_tasks.rake +4 -0
- data/test/archive_test.rb +16 -0
- data/test/archivist_test.rb +17 -0
- data/test/base_test.rb +342 -0
- data/test/db/migrate/01_add_to_some_models.rb +11 -0
- data/test/db_test.rb +42 -0
- data/test/dummy/README.rdoc +261 -0
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/app/assets/javascripts/application.js +15 -0
- data/test/dummy/app/assets/stylesheets/application.css +13 -0
- data/test/dummy/app/controllers/application_controller.rb +3 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/models/another_model.rb +4 -0
- data/test/dummy/app/models/some_model.rb +12 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +61 -0
- data/test/dummy/config/boot.rb +10 -0
- data/test/dummy/config/database.yml +19 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +37 -0
- data/test/dummy/config/environments/production.rb +67 -0
- data/test/dummy/config/environments/test.rb +37 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/inflections.rb +15 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +7 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +5 -0
- data/test/dummy/config/routes.rb +58 -0
- data/test/dummy/db/schema.rb +41 -0
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/lib/this_module.rb +3 -0
- data/test/dummy/log/development.log +7 -0
- data/test/dummy/log/test.log +35228 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +25 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/script/rails +6 -0
- data/test/dummy/test/fixtures/another_models.yml +9 -0
- data/test/dummy/test/fixtures/some_models.yml +13 -0
- data/test/dummy/test/unit/another_model_test.rb +7 -0
- data/test/dummy/test/unit/some_model_test.rb +7 -0
- data/test/factories/some_model_factory.rb +8 -0
- data/test/migration_test.rb +69 -0
- data/test/test_helper.rb +27 -0
- metadata +210 -16
- data/README.md +0 -162
data/MIT-LICENSE
CHANGED
@@ -1,18 +1,20 @@
|
|
1
|
-
Copyright
|
1
|
+
Copyright 2012 YOURNAME
|
2
2
|
|
3
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
-
this software and associated documentation files (the
|
5
|
-
the Software without restriction, including
|
6
|
-
use, copy, modify, merge, publish,
|
7
|
-
|
8
|
-
|
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
|
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,
|
14
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
15
|
-
FOR A PARTICULAR PURPOSE AND
|
16
|
-
|
17
|
-
|
18
|
-
|
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.
|
data/README.rdoc
ADDED
data/Rakefile
ADDED
@@ -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
|
data/lib/archivist.rb
CHANGED
data/lib/archivist/archive.rb
CHANGED
@@ -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
|
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
|
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
|
-
|
36
|
-
|
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)
|
data/lib/archivist/base.rb
CHANGED
@@ -7,7 +7,7 @@ end
|
|
7
7
|
module Archivist
|
8
8
|
module Base
|
9
9
|
|
10
|
-
|
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 =
|
18
|
+
options = ARCHIVIST_DEFAULTS.merge(options)
|
19
19
|
options[:allow_multiple_archives] = true if options[:associate_with_original]
|
20
|
-
|
21
|
-
class_eval
|
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
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
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
|
-
|
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
|
69
|
-
|
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
|
78
|
-
|
79
|
-
|
80
|
-
|
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
|
86
|
-
|
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
|
90
|
-
|
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 :
|
127
|
-
:
|
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
|
data/lib/archivist/migration.rb
CHANGED
@@ -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,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
|
data/test/base_test.rb
ADDED
@@ -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
|