undestroy 0.0.1 → 0.0.2
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/ARCH.md +84 -0
- data/Gemfile +2 -1
- data/LICENSE +1 -1
- data/README.md +58 -48
- data/lib/undestroy.rb +3 -4
- data/lib/undestroy/archive.rb +36 -0
- data/lib/undestroy/binding.rb +8 -0
- data/lib/undestroy/binding/active_record.rb +63 -0
- data/lib/undestroy/config.rb +54 -0
- data/lib/undestroy/transfer.rb +22 -0
- data/lib/undestroy/version.rb +2 -1
- data/lib/undestroy/with_binding.rb +5 -0
- data/lib/undestroy/without_binding.rb +10 -0
- data/test/fixtures/active_record_models.rb +42 -0
- data/test/fixtures/ar.rb +41 -0
- data/test/fixtures/archive.rb +21 -0
- data/test/helper.rb +42 -1
- data/test/integration/active_record_test.rb +180 -0
- data/test/unit/archive_test.rb +115 -0
- data/test/unit/binding/active_record_test.rb +188 -0
- data/test/unit/config_test.rb +146 -0
- data/test/unit/transfer_test.rb +65 -0
- data/undestroy.gemspec +2 -1
- metadata +29 -6
- data/test/unit/undestroy_test.rb +0 -10
@@ -0,0 +1,188 @@
|
|
1
|
+
require 'assert'
|
2
|
+
|
3
|
+
module Undestroy::Binding::ActiveRecord::Test
|
4
|
+
|
5
|
+
class Base < Undestroy::Test::Base
|
6
|
+
desc 'Binding::ActiveRecord class'
|
7
|
+
subject { Undestroy::Binding::ActiveRecord }
|
8
|
+
|
9
|
+
setup do
|
10
|
+
@model = Class.new(Undestroy::Test::ARMain)
|
11
|
+
@model.table_name = 'foobar'
|
12
|
+
@model.connection.create_table :foobar, :force => true
|
13
|
+
@model.connection.create_table :archive_foobar, :force => true
|
14
|
+
end
|
15
|
+
|
16
|
+
teardown do
|
17
|
+
@model.connection.execute 'drop table if exists foobar'
|
18
|
+
@model.connection.execute 'drop table if exists archive_foobar'
|
19
|
+
Undestroy::Config.instance_variable_set(:@config, nil)
|
20
|
+
Undestroy::Test::Fixtures::Archive.reset
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class BasicInstance < Base
|
25
|
+
desc 'basic instance'
|
26
|
+
subject { Undestroy::Binding::ActiveRecord.new @model }
|
27
|
+
|
28
|
+
should have_accessors :config, :model
|
29
|
+
end
|
30
|
+
|
31
|
+
class AddClassMethod < Base
|
32
|
+
desc 'add class method'
|
33
|
+
|
34
|
+
setup do
|
35
|
+
@model.class_eval do
|
36
|
+
undef_method :undestroy_model_binding if respond_to?(:undestroy_model_binding)
|
37
|
+
remove_possible_method :undestroy_model_binding=
|
38
|
+
class << self
|
39
|
+
undef_method :undestroy_model_binding
|
40
|
+
undef_method :undestroy
|
41
|
+
end
|
42
|
+
end
|
43
|
+
@model._destroy_callbacks = []
|
44
|
+
end
|
45
|
+
|
46
|
+
should "add class_attr called `undestroy_model_binding`" do
|
47
|
+
subject.add @model
|
48
|
+
assert_respond_to :undestroy_model_binding, @model
|
49
|
+
assert_respond_to :undestroy_model_binding=, @model
|
50
|
+
end
|
51
|
+
|
52
|
+
should "add undestroy class method to AR::Base initializing this binding" do
|
53
|
+
subject.add @model
|
54
|
+
assert_respond_to :undestroy, @model
|
55
|
+
|
56
|
+
@model.undestroy :fields => {}
|
57
|
+
|
58
|
+
assert_instance_of subject, @model.undestroy_model_binding
|
59
|
+
assert_equal Hash.new, @model.undestroy_model_binding.config.fields
|
60
|
+
end
|
61
|
+
|
62
|
+
should "add before_destroy callback when undestroy called" do
|
63
|
+
subject.add @model
|
64
|
+
archive_class = Undestroy::Test::Fixtures::Archive
|
65
|
+
@model.undestroy :internals => { :archive => archive_class }
|
66
|
+
|
67
|
+
callback = @model._destroy_callbacks.first
|
68
|
+
assert callback, "No destroy callbacks defined"
|
69
|
+
assert_equal :before, callback.kind
|
70
|
+
assert_instance_of Proc, callback.raw_filter
|
71
|
+
|
72
|
+
instance = @model.new
|
73
|
+
instance.instance_eval(&callback.raw_filter)
|
74
|
+
assert_equal [[:run]], archive_class.data[:calls]
|
75
|
+
end
|
76
|
+
|
77
|
+
should "only add callbacks once" do
|
78
|
+
subject.add @model
|
79
|
+
@model.undestroy
|
80
|
+
@model.undestroy
|
81
|
+
assert_equal 1, @model._destroy_callbacks.size
|
82
|
+
end
|
83
|
+
|
84
|
+
should "allow adding to other classes" do
|
85
|
+
new_model = Class.new(@model)
|
86
|
+
subject.add(new_model)
|
87
|
+
assert_respond_to :undestroy_model_binding, new_model
|
88
|
+
assert_not_respond_to :undestroy_model_binding, @model
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
class InitMethod < Base
|
93
|
+
desc 'init method'
|
94
|
+
|
95
|
+
should "require first argument and set it to model" do
|
96
|
+
assert_raises(ArgumentError) { subject.new }
|
97
|
+
binding = subject.new @model
|
98
|
+
assert_equal @model, binding.model
|
99
|
+
end
|
100
|
+
|
101
|
+
should "validate model argument is AR::Base" do
|
102
|
+
assert_raises(ArgumentError) { subject.new Class.new }
|
103
|
+
end
|
104
|
+
|
105
|
+
should "accept optional hash of config options" do
|
106
|
+
assert_not_raises { subject.new @model, {} }
|
107
|
+
end
|
108
|
+
|
109
|
+
should "set config attr to new config object" do
|
110
|
+
binding = subject.new @model
|
111
|
+
assert_instance_of Undestroy::Config, binding.config
|
112
|
+
end
|
113
|
+
|
114
|
+
should "merge config options onto global config" do
|
115
|
+
Undestroy::Config.configure do |config|
|
116
|
+
config.fields = {}
|
117
|
+
end
|
118
|
+
assert_equal Hash.new, subject.new(@model).config.fields
|
119
|
+
assert_not_equal subject.new(@model).config.object_id, Undestroy::Config.config.object_id
|
120
|
+
assert_equal({ :foo => :bar }, subject.new(@model, :fields => { :foo => :bar }).config.fields)
|
121
|
+
end
|
122
|
+
|
123
|
+
should "set config.source_class to value of model" do
|
124
|
+
binding = subject.new(@model)
|
125
|
+
assert_equal @model, binding.config.source_class
|
126
|
+
end
|
127
|
+
|
128
|
+
should "default :table_name to 'archive_{source.table_name}'" do
|
129
|
+
@model.table_name = :foobar
|
130
|
+
binding = subject.new(@model)
|
131
|
+
assert_equal 'archive_foobar', binding.config.table_name
|
132
|
+
end
|
133
|
+
|
134
|
+
should "create a target_class if none provided" do
|
135
|
+
binding = subject.new(@model)
|
136
|
+
assert binding.config.target_class.ancestors.include?(ActiveRecord::Base)
|
137
|
+
end
|
138
|
+
|
139
|
+
should "use target_class if provided" do
|
140
|
+
target = Class.new(Undestroy::Test::ARAlt)
|
141
|
+
target.table_name = "target_class_test"
|
142
|
+
binding = subject.new(@model, :target_class => target)
|
143
|
+
|
144
|
+
assert_equal target, binding.config.target_class
|
145
|
+
assert_equal 'target_class_test', binding.config.target_class.table_name
|
146
|
+
assert_equal 'tmp/alt.db', binding.config.target_class.connection_config[:database]
|
147
|
+
end
|
148
|
+
|
149
|
+
should "validate target_class is AR::Base if provided" do
|
150
|
+
target = Class.new
|
151
|
+
assert_raises(ArgumentError) { subject.new(@model, :target_class => target) }
|
152
|
+
end
|
153
|
+
|
154
|
+
should "set target class's table_name to :table_name attr" do
|
155
|
+
binding = subject.new(@model, :table_name => "foo_foo_archive")
|
156
|
+
assert_equal "foo_foo_archive", binding.config.target_class.table_name
|
157
|
+
end
|
158
|
+
|
159
|
+
should "set target class's parent class to :abstract_class attr" do
|
160
|
+
@model.table_name = :foobar
|
161
|
+
binding = subject.new(@model, :abstract_class => Undestroy::Test::ARAlt)
|
162
|
+
assert_equal 'tmp/alt.db', binding.config.target_class.connection_config[:database]
|
163
|
+
end
|
164
|
+
|
165
|
+
end
|
166
|
+
|
167
|
+
class BeforeDestroy < Base
|
168
|
+
desc 'before_destroy method'
|
169
|
+
subject { @binding ||= Undestroy::Binding::ActiveRecord.new(@model) }
|
170
|
+
|
171
|
+
should "exist and require one param" do
|
172
|
+
assert_respond_to :before_destroy, subject
|
173
|
+
assert_equal 1, subject.method(:before_destroy).arity
|
174
|
+
end
|
175
|
+
|
176
|
+
should "instantiate config[:archive] instance with config and model instance and call `run`" do
|
177
|
+
test_class = Undestroy::Test::Fixtures::Archive
|
178
|
+
ar_source = Undestroy::Test::Fixtures::ARFixture.new
|
179
|
+
subject.config.internals[:archive] = test_class
|
180
|
+
subject.before_destroy(ar_source)
|
181
|
+
|
182
|
+
assert_equal({ :config => subject.config, :source => ar_source }, test_class.data[:args])
|
183
|
+
assert_equal [[:run]], test_class.data[:calls]
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
end
|
188
|
+
|
@@ -0,0 +1,146 @@
|
|
1
|
+
require 'assert'
|
2
|
+
|
3
|
+
class Undestroy::Config::Test
|
4
|
+
|
5
|
+
class Base < Undestroy::Test::Base
|
6
|
+
desc 'Undestroy::Config class'
|
7
|
+
subject { Undestroy::Config }
|
8
|
+
|
9
|
+
teardown do
|
10
|
+
Undestroy::Config.instance_variable_set(:@config, nil)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class ConfigureClassMethod < Base
|
15
|
+
desc 'configure class method'
|
16
|
+
|
17
|
+
should "exist" do
|
18
|
+
assert subject.respond_to?(:configure)
|
19
|
+
end
|
20
|
+
|
21
|
+
should "call the block with an instance of Config" do
|
22
|
+
called = false
|
23
|
+
subject.configure do |object|
|
24
|
+
called = true
|
25
|
+
assert_instance_of subject, object
|
26
|
+
end
|
27
|
+
assert called, "Block was not called"
|
28
|
+
end
|
29
|
+
|
30
|
+
should "store result in global config" do
|
31
|
+
subject.configure do |object|
|
32
|
+
object.table_name = "FOO"
|
33
|
+
end
|
34
|
+
config = subject.instance_variable_get(:@config)
|
35
|
+
assert config
|
36
|
+
assert_equal "FOO", config.table_name
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class ConfigClassMethod < Base
|
41
|
+
desc 'return the global Config'
|
42
|
+
|
43
|
+
should "exist" do
|
44
|
+
assert subject.respond_to?(:config)
|
45
|
+
end
|
46
|
+
|
47
|
+
should "return Config object" do
|
48
|
+
assert_instance_of subject, subject.config
|
49
|
+
end
|
50
|
+
|
51
|
+
should "return the same Config object" do
|
52
|
+
assert_equal subject.config.object_id, subject.config.object_id
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
class BasicInstance < Base
|
57
|
+
desc 'basic instance'
|
58
|
+
subject { Undestroy::Config.new }
|
59
|
+
|
60
|
+
should have_accessors :table_name, :abstract_class, :fields, :migrate
|
61
|
+
should have_accessors :source_class, :target_class, :internals
|
62
|
+
end
|
63
|
+
|
64
|
+
class InitMethod < Base
|
65
|
+
desc 'init method'
|
66
|
+
|
67
|
+
should "default migrate to true" do
|
68
|
+
config = subject.new
|
69
|
+
assert config.migrate
|
70
|
+
end
|
71
|
+
|
72
|
+
should "default fields to delayed deleted_at" do
|
73
|
+
config = subject.new
|
74
|
+
assert_equal [:deleted_at], config.fields.keys
|
75
|
+
assert_instance_of Proc, config.fields[:deleted_at]
|
76
|
+
assert_instance_of Time, config.fields[:deleted_at].call
|
77
|
+
assert Time.now - config.fields[:deleted_at].call < 1
|
78
|
+
end
|
79
|
+
|
80
|
+
should "default internals to internal classes" do
|
81
|
+
config = subject.new
|
82
|
+
assert config.internals
|
83
|
+
assert_instance_of Hash, config.internals
|
84
|
+
assert_equal Undestroy::Archive, config.internals[:archive]
|
85
|
+
assert_equal Undestroy::Transfer, config.internals[:transfer]
|
86
|
+
end
|
87
|
+
|
88
|
+
should "set config options using provided hash" do
|
89
|
+
config = subject.new :table_name => "foo",
|
90
|
+
:abstract_class => "test_archive",
|
91
|
+
:target_class => "foo",
|
92
|
+
:fields => {},
|
93
|
+
:migrate => false
|
94
|
+
|
95
|
+
assert_equal "foo", config.table_name
|
96
|
+
assert_equal "foo", config.target_class
|
97
|
+
assert_equal "test_archive", config.abstract_class
|
98
|
+
assert_equal Hash.new, config.fields
|
99
|
+
assert_equal false, config.migrate
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
class MergeMethod < Base
|
105
|
+
desc 'merge method'
|
106
|
+
|
107
|
+
should "accept config option and return merged config options" do
|
108
|
+
config1 = subject.new :abstract_class => 'foo', :migrate => false
|
109
|
+
config2 = subject.new :abstract_class => 'bar', :fields => {}, :internals => {}
|
110
|
+
config3 = config1.merge(config2)
|
111
|
+
|
112
|
+
assert_equal 'bar', config3.abstract_class
|
113
|
+
assert_equal true, config3.migrate
|
114
|
+
assert_equal Hash.new, config3.fields
|
115
|
+
assert_equal Hash.new, config3.internals
|
116
|
+
assert_equal 'foo', config1.abstract_class
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
|
121
|
+
class PrimitiveFields < Base
|
122
|
+
desc 'primitive_fields method'
|
123
|
+
subject { @config ||= Undestroy::Config.new }
|
124
|
+
|
125
|
+
should "exist" do
|
126
|
+
assert_respond_to :primitive_fields, subject
|
127
|
+
end
|
128
|
+
|
129
|
+
should "require 1 parameter" do
|
130
|
+
assert_equal 1, subject.method(:primitive_fields).arity
|
131
|
+
end
|
132
|
+
|
133
|
+
should "return fields with any procs evaled" do
|
134
|
+
assert_instance_of Hash, subject.primitive_fields(1)
|
135
|
+
assert_instance_of Time, subject.primitive_fields(1)[:deleted_at]
|
136
|
+
end
|
137
|
+
|
138
|
+
should "pass argument in to proc" do
|
139
|
+
val = {}
|
140
|
+
subject.fields = { :test => proc { |arg| val[:arg] = arg } }
|
141
|
+
subject.primitive_fields("FOOO!")
|
142
|
+
assert_equal "FOOO!", val[:arg]
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'assert'
|
2
|
+
|
3
|
+
module Undestroy::Transfer::Test
|
4
|
+
|
5
|
+
class Base < Undestroy::Test::Base
|
6
|
+
desc 'Undestroy::Transfer class'
|
7
|
+
subject { Undestroy::Transfer }
|
8
|
+
end
|
9
|
+
|
10
|
+
class BasicInstance < Base
|
11
|
+
subject { Undestroy::Transfer.new :klass => Undestroy::Test::Fixtures::ARFixture }
|
12
|
+
desc 'basic instance'
|
13
|
+
|
14
|
+
should have_accessors :target
|
15
|
+
end
|
16
|
+
|
17
|
+
class InitMethod < Base
|
18
|
+
desc 'init method'
|
19
|
+
|
20
|
+
setup do
|
21
|
+
@fields = {
|
22
|
+
:id => 123,
|
23
|
+
:name => "Foo",
|
24
|
+
:description => "Foo Description"
|
25
|
+
}
|
26
|
+
@transfer = subject.new :klass => Undestroy::Test::Fixtures::ARFixture, :fields => @fields
|
27
|
+
end
|
28
|
+
|
29
|
+
should "raise ArgumentError if no :klass key" do
|
30
|
+
assert_raises(ArgumentError) { subject.new }
|
31
|
+
end
|
32
|
+
|
33
|
+
should "default :fields to empty hash" do
|
34
|
+
assert_not_raises { subject.new :klass => Undestroy::Test::Fixtures::ARFixture }
|
35
|
+
end
|
36
|
+
|
37
|
+
should "create :klass instance with :fields" do
|
38
|
+
assert_instance_of Undestroy::Test::Fixtures::ARFixture, @transfer.target
|
39
|
+
assert_equal @fields[:id], @transfer.target[:id]
|
40
|
+
assert_equal @fields[:name], @transfer.target[:name]
|
41
|
+
assert_equal @fields[:description], @transfer.target[:description]
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
class RunMethod < Base
|
47
|
+
desc 'run method'
|
48
|
+
|
49
|
+
setup do
|
50
|
+
@fields = {
|
51
|
+
:id => 1,
|
52
|
+
:name => "Bar",
|
53
|
+
:a_field => "some_thing"
|
54
|
+
}
|
55
|
+
@transfer = subject.new :klass => Undestroy::Test::Fixtures::ARFixture, :fields => @fields
|
56
|
+
end
|
57
|
+
|
58
|
+
should "call save on built record" do
|
59
|
+
@transfer.run
|
60
|
+
self.assert @transfer.target.saved?
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
data/undestroy.gemspec
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: undestroy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 27
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 2
|
10
|
+
version: 0.0.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Travis Petticrew
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-03-
|
18
|
+
date: 2012-03-15 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
type: :runtime
|
@@ -73,14 +73,30 @@ extra_rdoc_files: []
|
|
73
73
|
|
74
74
|
files:
|
75
75
|
- .gitignore
|
76
|
+
- ARCH.md
|
76
77
|
- Gemfile
|
77
78
|
- LICENSE
|
78
79
|
- README.md
|
79
80
|
- Rakefile
|
80
81
|
- lib/undestroy.rb
|
82
|
+
- lib/undestroy/archive.rb
|
83
|
+
- lib/undestroy/binding.rb
|
84
|
+
- lib/undestroy/binding/active_record.rb
|
85
|
+
- lib/undestroy/config.rb
|
86
|
+
- lib/undestroy/transfer.rb
|
81
87
|
- lib/undestroy/version.rb
|
88
|
+
- lib/undestroy/with_binding.rb
|
89
|
+
- lib/undestroy/without_binding.rb
|
90
|
+
- test/fixtures/active_record_models.rb
|
91
|
+
- test/fixtures/ar.rb
|
92
|
+
- test/fixtures/archive.rb
|
82
93
|
- test/helper.rb
|
83
|
-
- test/
|
94
|
+
- test/integration/active_record_test.rb
|
95
|
+
- test/unit/archive_test.rb
|
96
|
+
- test/unit/binding/active_record_test.rb
|
97
|
+
- test/unit/config_test.rb
|
98
|
+
- test/unit/transfer_test.rb
|
99
|
+
- tmp/.gitkeep
|
84
100
|
- undestroy.gemspec
|
85
101
|
homepage: ""
|
86
102
|
licenses: []
|
@@ -116,5 +132,12 @@ signing_key:
|
|
116
132
|
specification_version: 3
|
117
133
|
summary: Allow AR records to be undestroyed by archiving their data in a seperate table when destroying the original data
|
118
134
|
test_files:
|
135
|
+
- test/fixtures/active_record_models.rb
|
136
|
+
- test/fixtures/ar.rb
|
137
|
+
- test/fixtures/archive.rb
|
119
138
|
- test/helper.rb
|
120
|
-
- test/
|
139
|
+
- test/integration/active_record_test.rb
|
140
|
+
- test/unit/archive_test.rb
|
141
|
+
- test/unit/binding/active_record_test.rb
|
142
|
+
- test/unit/config_test.rb
|
143
|
+
- test/unit/transfer_test.rb
|