undestroy 0.0.2 → 0.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/ARCH.md +13 -24
- data/README.md +72 -27
- data/lib/undestroy/binding.rb +1 -0
- data/lib/undestroy/binding/active_record.rb +53 -11
- data/lib/undestroy/binding/active_record/migration_statement.rb +118 -0
- data/lib/undestroy/binding/active_record/restorable.rb +28 -0
- data/lib/undestroy/config.rb +32 -8
- data/lib/undestroy/config/field.rb +20 -0
- data/lib/undestroy/restore.rb +44 -0
- data/lib/undestroy/version.rb +1 -1
- data/lib/undestroy/without_binding.rb +1 -0
- data/test/fixtures/ar.rb +8 -4
- data/test/fixtures/load_test/models1/test_model001.rb +2 -0
- data/test/fixtures/load_test/models1/test_model002.rb +2 -0
- data/test/fixtures/load_test/models1/test_module001.rb +2 -0
- data/test/fixtures/load_test/models1/test_module001/test_model003.rb +2 -0
- data/test/fixtures/load_test/models2/test_model001.rb +2 -0
- data/test/fixtures/load_test/models2/test_model002.rb +2 -0
- data/test/fixtures/load_test/models2/test_module001.rb +2 -0
- data/test/fixtures/load_test/models2/test_module001/test_model003.rb +2 -0
- data/test/helper.rb +12 -0
- data/test/helpers/model_loading.rb +20 -0
- data/test/integration/active_record_test.rb +50 -1
- data/test/irb.rb +2 -0
- data/test/unit/archive_test.rb +1 -1
- data/test/unit/binding/active_record/migration_statement_test.rb +306 -0
- data/test/unit/binding/active_record/restorable_test.rb +132 -0
- data/test/unit/binding/active_record_test.rb +187 -19
- data/test/unit/config/field_test.rb +86 -0
- data/test/unit/config_test.rb +114 -8
- data/test/unit/restore_test.rb +95 -0
- metadata +35 -3
data/lib/undestroy/config.rb
CHANGED
@@ -1,23 +1,34 @@
|
|
1
1
|
class Undestroy::Config
|
2
2
|
OPTIONS = [
|
3
|
-
:table_name, :abstract_class, :fields, :migrate,
|
4
|
-
:source_class, :target_class, :internals
|
3
|
+
:table_name, :abstract_class, :fields, :migrate, :indexes, :prefix,
|
4
|
+
:source_class, :target_class, :internals, :model_paths
|
5
5
|
]
|
6
6
|
attr_accessor *OPTIONS
|
7
7
|
|
8
8
|
def initialize(options={})
|
9
|
+
self.indexes = false
|
9
10
|
self.migrate = true
|
10
|
-
self.
|
11
|
-
|
12
|
-
|
11
|
+
self.prefix = "archive_"
|
12
|
+
self.fields = {}
|
13
|
+
self.model_paths = []
|
13
14
|
self.internals = {
|
14
15
|
:archive => Undestroy::Archive,
|
15
16
|
:transfer => Undestroy::Transfer,
|
17
|
+
:restore => Undestroy::Restore
|
16
18
|
}
|
17
19
|
|
20
|
+
add_field :deleted_at, :datetime do |instance|
|
21
|
+
Time.now
|
22
|
+
end
|
23
|
+
|
24
|
+
# Default for Rails apps
|
25
|
+
self.model_paths << Rails.root.join('app', 'models') if defined?(Rails)
|
26
|
+
|
18
27
|
options.each do |key, value|
|
19
|
-
self[key] = value
|
28
|
+
self[key] = value.duplicable? ? value.dup : value
|
20
29
|
end
|
30
|
+
|
31
|
+
self.class.catalog << self
|
21
32
|
end
|
22
33
|
|
23
34
|
def [](key)
|
@@ -37,11 +48,15 @@ class Undestroy::Config
|
|
37
48
|
end
|
38
49
|
|
39
50
|
def primitive_fields(object)
|
40
|
-
self.fields.inject({}) do |hash, (key,
|
41
|
-
hash.merge(key =>
|
51
|
+
self.fields.inject({}) do |hash, (key, field)|
|
52
|
+
hash.merge(key => field.value(object))
|
42
53
|
end
|
43
54
|
end
|
44
55
|
|
56
|
+
def add_field(name, *args, &block)
|
57
|
+
self.fields[name.to_sym] = Field.new(name, *args, &block)
|
58
|
+
end
|
59
|
+
|
45
60
|
def self.configure
|
46
61
|
yield(config) if block_given?
|
47
62
|
end
|
@@ -50,5 +65,14 @@ class Undestroy::Config
|
|
50
65
|
@config ||= self.new
|
51
66
|
end
|
52
67
|
|
68
|
+
def self.catalog
|
69
|
+
@@catalog ||= []
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.reset_catalog
|
73
|
+
@@catalog = []
|
74
|
+
end
|
75
|
+
|
53
76
|
end
|
54
77
|
|
78
|
+
require 'undestroy/config/field'
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class Undestroy::Config::Field
|
2
|
+
|
3
|
+
attr_accessor :name, :type, :raw_value
|
4
|
+
|
5
|
+
def <=>(b)
|
6
|
+
name.to_s <=> b.name.to_s
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(name, type, value=nil, &block)
|
10
|
+
self.name = name
|
11
|
+
self.type = type
|
12
|
+
self.raw_value = block || value || raise(ArgumentError, "Must pass a value or block")
|
13
|
+
end
|
14
|
+
|
15
|
+
def value(*args)
|
16
|
+
raw_value.is_a?(Proc) ? raw_value.call(*args) : raw_value
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
@@ -0,0 +1,44 @@
|
|
1
|
+
|
2
|
+
class Undestroy::Restore
|
3
|
+
|
4
|
+
attr_accessor :target, :config, :transfer
|
5
|
+
|
6
|
+
def initialize(args={})
|
7
|
+
validate_arguments(args)
|
8
|
+
|
9
|
+
self.target = args[:target]
|
10
|
+
self.config = args[:config]
|
11
|
+
self.transfer = args[:transfer]
|
12
|
+
end
|
13
|
+
|
14
|
+
def transfer
|
15
|
+
@transfer ||= config.internals[:transfer].new(
|
16
|
+
:klass => config.source_class,
|
17
|
+
:fields => transfer_fields
|
18
|
+
)
|
19
|
+
end
|
20
|
+
|
21
|
+
def run
|
22
|
+
transfer.run
|
23
|
+
end
|
24
|
+
|
25
|
+
protected
|
26
|
+
|
27
|
+
def validate_arguments(args)
|
28
|
+
unless (args.keys & [:target, :config]).size == 2
|
29
|
+
raise ArgumentError, ":target and :config are required keys"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def transfer_fields
|
34
|
+
self.target.attributes.inject({}) do |hash, (key, value)|
|
35
|
+
if config.fields.keys.include?(key.to_sym)
|
36
|
+
hash
|
37
|
+
else
|
38
|
+
hash.merge(key => value)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
data/lib/undestroy/version.rb
CHANGED
data/test/fixtures/ar.rb
CHANGED
@@ -7,21 +7,25 @@ class Undestroy::Test::Fixtures::ARFixture
|
|
7
7
|
|
8
8
|
def initialize(attributes={})
|
9
9
|
@saved = false
|
10
|
-
self.attributes = attributes
|
10
|
+
self.attributes = HashWithIndifferentAccess.new(attributes)
|
11
11
|
self.attributes.delete(:id)
|
12
12
|
end
|
13
13
|
|
14
14
|
def [](key)
|
15
|
-
|
15
|
+
@attributes[key]
|
16
16
|
end
|
17
17
|
|
18
18
|
def []=(key, val)
|
19
|
-
|
19
|
+
@attributes[key] = val
|
20
20
|
end
|
21
21
|
|
22
22
|
# Method missing won't catch this one
|
23
23
|
def id
|
24
|
-
self
|
24
|
+
self[:id]
|
25
|
+
end
|
26
|
+
|
27
|
+
def attributes
|
28
|
+
@attributes.stringify_keys
|
25
29
|
end
|
26
30
|
|
27
31
|
def save
|
data/test/helper.rb
CHANGED
@@ -15,6 +15,10 @@ module Undestroy::Test
|
|
15
15
|
|
16
16
|
class Base < Assert::Context
|
17
17
|
|
18
|
+
teardown do
|
19
|
+
Undestroy::Config.reset_catalog
|
20
|
+
end
|
21
|
+
|
18
22
|
teardown_once do
|
19
23
|
`rm -f tmp/*.db`
|
20
24
|
end
|
@@ -31,6 +35,10 @@ module Undestroy::Test
|
|
31
35
|
establish_connection 'alt'
|
32
36
|
end
|
33
37
|
|
38
|
+
module Helpers
|
39
|
+
autoload :ModelLoading, 'test/helpers/model_loading'
|
40
|
+
end
|
41
|
+
|
34
42
|
module Integration
|
35
43
|
end
|
36
44
|
|
@@ -39,5 +47,9 @@ module Undestroy::Test
|
|
39
47
|
autoload :ARFixture, 'test/fixtures/ar'
|
40
48
|
autoload :Archive, 'test/fixtures/archive'
|
41
49
|
end
|
50
|
+
|
51
|
+
def self.fixtures_path(*paths)
|
52
|
+
File.join(File.expand_path(File.join(File.dirname(__FILE__), 'fixtures')), *paths)
|
53
|
+
end
|
42
54
|
end
|
43
55
|
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Undestroy::Test::Helpers::ModelLoading
|
2
|
+
|
3
|
+
def assert_loads_models(path, &block)
|
4
|
+
require 'active_support/dependencies'
|
5
|
+
ActiveSupport::Dependencies.hook!
|
6
|
+
ActiveSupport::Dependencies.autoload_paths += [path]
|
7
|
+
|
8
|
+
block.call
|
9
|
+
|
10
|
+
assert defined?(TestModel001), "TestModel001 did not load"
|
11
|
+
assert defined?(TestModel002), "TestModel002 did not load"
|
12
|
+
assert defined?(TestModule001), "TestModule001 did not load"
|
13
|
+
assert defined?(TestModule001::TestModel003), "Testmodule001::TestModel003 did not load"
|
14
|
+
ensure
|
15
|
+
ActiveSupport::Dependencies.autoload_paths -= [path]
|
16
|
+
ActiveSupport::Dependencies.remove_unloadable_constants!
|
17
|
+
ActiveSupport::Dependencies.unhook!
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -16,7 +16,12 @@ module Undestroy::Test::Integration::ActiveRecordTest
|
|
16
16
|
desc 'extensions'
|
17
17
|
|
18
18
|
should "add extensions to AR" do
|
19
|
-
assert_respond_to :
|
19
|
+
assert_respond_to :undestroy, ActiveRecord::Base
|
20
|
+
end
|
21
|
+
|
22
|
+
should "add alias method chain in method_missing on AR::Migration" do
|
23
|
+
assert_respond_to :method_missing_with_undestroy, ActiveRecord::Migration.new
|
24
|
+
assert ActiveRecord::Migration.new.method(:method_missing_without_undestroy)
|
20
25
|
end
|
21
26
|
end
|
22
27
|
|
@@ -79,6 +84,50 @@ module Undestroy::Test::Integration::ActiveRecordTest
|
|
79
84
|
assert (Time.now - archive.deleted_at) < 1.second
|
80
85
|
assert_equal 0, @model.all.size
|
81
86
|
end
|
87
|
+
|
88
|
+
should "restore an archived record removing the archive" do
|
89
|
+
@model.undestroy
|
90
|
+
@model.create(:name => "Fart")
|
91
|
+
original = @model.first
|
92
|
+
original.destroy
|
93
|
+
|
94
|
+
assert_equal 0, @model.count
|
95
|
+
@model.restore(1)
|
96
|
+
|
97
|
+
assert_equal 0, @model.archived.count
|
98
|
+
assert_equal 1, @model.count
|
99
|
+
assert_equal 1, @model.first.id
|
100
|
+
assert_equal "Fart", @model.first.name
|
101
|
+
end
|
102
|
+
|
103
|
+
should "restore an archived record and leave the archive when restore_copy called" do
|
104
|
+
@model.undestroy
|
105
|
+
@model.create(:name => "Fart")
|
106
|
+
original = @model.first
|
107
|
+
original.destroy
|
108
|
+
|
109
|
+
assert_equal 0, @model.count
|
110
|
+
@model.archived.first.restore_copy
|
111
|
+
|
112
|
+
assert_equal 1, @model.archived.count
|
113
|
+
assert_equal 1, @model.count
|
114
|
+
end
|
115
|
+
|
116
|
+
should "restore a relation of items when restore_all called" do
|
117
|
+
@model.undestroy
|
118
|
+
@model.create(:name => "Bobby")
|
119
|
+
@model.create(:name => "Billy")
|
120
|
+
@model.create(:name => "Jan")
|
121
|
+
|
122
|
+
assert_equal 3, @model.count
|
123
|
+
@model.destroy_all
|
124
|
+
assert_equal 0, @model.count
|
125
|
+
|
126
|
+
@model.archived.where("name LIKE ?", "B%").restore_all
|
127
|
+
|
128
|
+
assert_equal 2, @model.count
|
129
|
+
assert_equal 1, @model.archived.count
|
130
|
+
end
|
82
131
|
end
|
83
132
|
|
84
133
|
class BasicModelWithDifferentBase < Base
|
data/test/irb.rb
ADDED
data/test/unit/archive_test.rb
CHANGED
@@ -75,7 +75,7 @@ module Undestroy::Archive::Test
|
|
75
75
|
|
76
76
|
should "eval lambdas with source instance as argument" do
|
77
77
|
val = nil
|
78
|
-
@archive.config.
|
78
|
+
@archive.config.add_field(:test, :string) { |arg| val = arg; "FOO" }
|
79
79
|
target = @archive.transfer.target
|
80
80
|
assert_equal @archive.source, val
|
81
81
|
assert_equal "FOO", target.attributes[:test]
|
@@ -0,0 +1,306 @@
|
|
1
|
+
require 'assert'
|
2
|
+
|
3
|
+
module Undestroy::Binding::ActiveRecord::MigrationStatement::Test
|
4
|
+
|
5
|
+
class Base < Undestroy::Test::Base
|
6
|
+
desc 'Binding::ActiveRecord::MigrationStatement class'
|
7
|
+
subject { @subject_class }
|
8
|
+
|
9
|
+
setup do
|
10
|
+
@subject_class = Undestroy::Binding::ActiveRecord::MigrationStatement
|
11
|
+
@catalog = Undestroy::Config.catalog
|
12
|
+
|
13
|
+
@source_class = Class.new(Undestroy::Test::ARMain)
|
14
|
+
end
|
15
|
+
|
16
|
+
def config
|
17
|
+
@source_class.undestroy_model_binding.config
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
class BasicInstance < Base
|
23
|
+
desc 'basic instance'
|
24
|
+
subject { @subject_class.new :foo }
|
25
|
+
|
26
|
+
should have_accessor :method_name, :arguments, :block
|
27
|
+
end
|
28
|
+
|
29
|
+
class AddClassMethod < Base
|
30
|
+
desc 'add class method'
|
31
|
+
|
32
|
+
setup do
|
33
|
+
@klass = Class.new do
|
34
|
+
@@method_missing_calls = []
|
35
|
+
|
36
|
+
def method_missing(*args, &block)
|
37
|
+
@@method_missing_calls << [args, block]
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.method_missing_calls
|
41
|
+
@@method_missing_calls
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
should "add method method_missing_with_undestroy" do
|
47
|
+
subject.add(@klass)
|
48
|
+
assert_respond_to :method_missing_with_undestroy, @klass.new
|
49
|
+
end
|
50
|
+
|
51
|
+
should "alias original method_missing as method_missing_without_undestroy" do
|
52
|
+
subject.add(@klass)
|
53
|
+
assert @klass.new.method(:method_missing_without_undestroy)
|
54
|
+
end
|
55
|
+
|
56
|
+
should "always call original method_missing" do
|
57
|
+
subject.add(@klass)
|
58
|
+
@klass.new.foo(:bar) { }
|
59
|
+
assert_equal 1, @klass.method_missing_calls.size
|
60
|
+
assert_equal [:foo, :bar], @klass.method_missing_calls[0].first
|
61
|
+
assert_instance_of Proc, @klass.method_missing_calls[0].last
|
62
|
+
end
|
63
|
+
|
64
|
+
should "always create an instance of MethodStatement and call run! if run?" do
|
65
|
+
@source_class.table_name = 'source'
|
66
|
+
@source_class.undestroy
|
67
|
+
subject.add(@klass)
|
68
|
+
@klass.new.add_column :source, :foo, :string
|
69
|
+
assert_equal 2, @klass.method_missing_calls.size
|
70
|
+
assert_equal [:add_column, 'archive_source', :foo, :string], @klass.method_missing_calls[1].first
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
class InitMethod < Base
|
75
|
+
desc 'init method'
|
76
|
+
include Undestroy::Test::Helpers::ModelLoading
|
77
|
+
|
78
|
+
should "set required arg1 to method_name attr" do
|
79
|
+
obj = subject.new :method
|
80
|
+
assert_equal :method, obj.method_name
|
81
|
+
end
|
82
|
+
|
83
|
+
should "set remaining args to arguments attr as Array" do
|
84
|
+
obj = subject.new :method, :arg1, 'arg2', 3, :four => :val1, :five => :val2
|
85
|
+
assert_equal [:arg1, 'arg2', 3, { :four => :val1, :five => :val2 }], obj.arguments
|
86
|
+
end
|
87
|
+
|
88
|
+
should "set optional block to block attr" do
|
89
|
+
block = proc { "FOOO" }
|
90
|
+
obj = subject.new :method, &block
|
91
|
+
assert_equal block, obj.block
|
92
|
+
assert_equal "FOOO", obj.block.call
|
93
|
+
end
|
94
|
+
|
95
|
+
should "call load_models on all Config.config.model_paths if not loaded yet" do
|
96
|
+
path = Undestroy::Test.fixtures_path('load_test', 'models2')
|
97
|
+
Undestroy::Config.config.model_paths = [path]
|
98
|
+
assert_loads_models(path) do
|
99
|
+
subject.new :method
|
100
|
+
end
|
101
|
+
Undestroy::Config.config.model_paths = []
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
class SourceTableNameMethod < Base
|
106
|
+
desc 'source_table_name method'
|
107
|
+
|
108
|
+
should "return arguments[0]" do
|
109
|
+
obj = subject.new :method, 'table_name', 1
|
110
|
+
assert_equal 'table_name', obj.source_table_name
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
class TargetTableNameMethod < Base
|
115
|
+
desc 'target_table_name method'
|
116
|
+
|
117
|
+
should 'return "archive_#{original_table_name}" when :table_name config not set' do
|
118
|
+
@source_class.table_name = 'poop'
|
119
|
+
@source_class.undestroy
|
120
|
+
assert_equal 'archive_poop', subject.new(:method, 'poop').target_table_name
|
121
|
+
end
|
122
|
+
|
123
|
+
should 'return :table_name config value when set' do
|
124
|
+
@source_class.table_name = 'poop'
|
125
|
+
@source_class.undestroy :table_name => 'old_poop_table'
|
126
|
+
assert_equal 'old_poop_table', subject.new(:method, 'poop').target_table_name
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
class ConfigMethod < Base
|
131
|
+
desc 'config method'
|
132
|
+
|
133
|
+
should "fetch config object for the given table name from Undestroy::Config.catalog" do
|
134
|
+
@source_class.table_name = 'foobar'
|
135
|
+
@source_class.undestroy
|
136
|
+
assert_equal config, subject.new(:method, 'foobar').config
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
class SchemaActionMethod < Base
|
141
|
+
desc 'schema_action? method'
|
142
|
+
|
143
|
+
should "return true if method_name is a schema modification method" do
|
144
|
+
[
|
145
|
+
:create_table, :drop_table, :rename_table,
|
146
|
+
:add_column, :rename_column, :change_column, :remove_column
|
147
|
+
].each do |method|
|
148
|
+
obj = subject.new method
|
149
|
+
assert obj.schema_action?
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
should "return false otherwise" do
|
154
|
+
obj = subject.new :method
|
155
|
+
assert_not obj.schema_action?
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
class IndexActionMethod < Base
|
160
|
+
desc 'index_action? method'
|
161
|
+
|
162
|
+
should "return true if method_name is an index modification method" do
|
163
|
+
[
|
164
|
+
:add_index, :remove_index
|
165
|
+
].each do |method|
|
166
|
+
obj = subject.new method
|
167
|
+
assert obj.index_action?
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
should "return false otherwise" do
|
172
|
+
obj = subject.new :method
|
173
|
+
assert_not obj.index_action?
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
class RunQueryMethod < Base
|
178
|
+
desc 'run? method'
|
179
|
+
|
180
|
+
should "always return false if arguments are empty" do
|
181
|
+
obj = subject.new :method
|
182
|
+
assert_not obj.run?
|
183
|
+
end
|
184
|
+
|
185
|
+
should "always return false if no configuration is present for this *source* table name" do
|
186
|
+
@source_class.table_name = 'bar'
|
187
|
+
@source_class.undestroy
|
188
|
+
obj = subject.new :method, 'foo'
|
189
|
+
assert_not obj.run?
|
190
|
+
end
|
191
|
+
|
192
|
+
should "return true if :migrate is configured and schema_action? is true" do
|
193
|
+
@source_class.table_name = 'bar'
|
194
|
+
@source_class.undestroy
|
195
|
+
obj = subject.new :add_column, :bar, :name, :string
|
196
|
+
assert obj.schema_action?
|
197
|
+
assert obj.run?
|
198
|
+
end
|
199
|
+
|
200
|
+
should "return false if :migrate is configured and schema_action? is false" do
|
201
|
+
@source_class.table_name = 'bar'
|
202
|
+
@source_class.undestroy
|
203
|
+
obj = subject.new :method, :bar, :name, :string
|
204
|
+
assert_not obj.run?
|
205
|
+
end
|
206
|
+
|
207
|
+
should "return false if :migrate not configured for this table" do
|
208
|
+
@source_class.table_name = 'bar'
|
209
|
+
@source_class.undestroy :migrate => false
|
210
|
+
obj = subject.new :add_column, :bar, :name, :string
|
211
|
+
assert obj.schema_action?
|
212
|
+
assert_not obj.run?
|
213
|
+
end
|
214
|
+
|
215
|
+
should "return true if :index is configured and index_action? is true" do
|
216
|
+
@source_class.table_name = 'bar'
|
217
|
+
@source_class.undestroy :indexes => true
|
218
|
+
obj = subject.new :add_index, :bar
|
219
|
+
assert obj.index_action?
|
220
|
+
assert obj.run?
|
221
|
+
end
|
222
|
+
|
223
|
+
should "return false if :index is configured and index_action? is false" do
|
224
|
+
@source_class.table_name = 'bar'
|
225
|
+
@source_class.undestroy :indexes => true
|
226
|
+
obj = subject.new :method, :bar
|
227
|
+
assert_not obj.index_action?
|
228
|
+
assert_not obj.run?
|
229
|
+
end
|
230
|
+
|
231
|
+
should "return false if :index is not configured for this table" do
|
232
|
+
@source_class.table_name = 'bar'
|
233
|
+
@source_class.undestroy
|
234
|
+
obj = subject.new :add_index, :bar
|
235
|
+
assert obj.index_action?
|
236
|
+
assert_not obj.run?
|
237
|
+
end
|
238
|
+
|
239
|
+
# We will not rename a table that has been configured to a specific name
|
240
|
+
should "return false if :method_name is rename_table and :table_name configuration is set explicitly" do
|
241
|
+
@source_class.table_name = 'bar'
|
242
|
+
@source_class.undestroy :table_name => 'old_bar'
|
243
|
+
obj = subject.new :rename_table, :bar, :baz
|
244
|
+
assert_not obj.run?
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
class TargetArgsMethod < Base
|
249
|
+
desc 'target_arguments method'
|
250
|
+
|
251
|
+
setup do
|
252
|
+
@source_class.table_name = 'source'
|
253
|
+
@source_class.undestroy
|
254
|
+
end
|
255
|
+
|
256
|
+
should "leave original arguments alone" do
|
257
|
+
obj = subject.new :add_column, :source, :foo, :string
|
258
|
+
args = obj.arguments.dup
|
259
|
+
obj.target_arguments
|
260
|
+
assert_equal args, obj.arguments
|
261
|
+
end
|
262
|
+
|
263
|
+
should "substitute source table_name for target table_name" do
|
264
|
+
obj = subject.new :add_column, :source, :foo, :string
|
265
|
+
assert_equal ['archive_source', :foo, :string], obj.target_arguments
|
266
|
+
end
|
267
|
+
|
268
|
+
should "substitute arg[1] for target table_name on rename_table method" do
|
269
|
+
obj = subject.new :rename_table, :source, :new_source
|
270
|
+
assert_equal ['archive_source', 'archive_new_source'], obj.target_arguments
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
class RunBangMethod < Base
|
275
|
+
desc 'run! method'
|
276
|
+
|
277
|
+
setup do
|
278
|
+
@source_class.table_name = 'source'
|
279
|
+
@source_class.undestroy
|
280
|
+
end
|
281
|
+
|
282
|
+
should "accept callable argument to run on and call with (method_name, target_args, block)" do
|
283
|
+
called = false
|
284
|
+
callable = proc { |*args, &block| called = [args, block] }
|
285
|
+
block = proc { }
|
286
|
+
obj = subject.new :add_column, :source, :foo, :string, &block
|
287
|
+
obj.run!(callable)
|
288
|
+
assert_equal [obj.method_name, obj.target_arguments, block].flatten, called.flatten
|
289
|
+
end
|
290
|
+
|
291
|
+
should "run additional add_column calls for all config.fields on :create_table method" do
|
292
|
+
config.add_field :deleted_by_id, :integer, 1
|
293
|
+
calls = []
|
294
|
+
callable = proc { |*args, &block| calls << [args, block] }
|
295
|
+
obj = subject.new :create_table, :source
|
296
|
+
obj.run!(callable)
|
297
|
+
assert_equal 3, calls.size
|
298
|
+
assert_equal [:create_table, 'archive_source', nil], calls[0].flatten
|
299
|
+
assert_equal [:add_column, 'archive_source', :deleted_at, :datetime, nil], calls[1].flatten
|
300
|
+
assert_equal [:add_column, 'archive_source', :deleted_by_id, :integer, nil], calls[2].flatten
|
301
|
+
end
|
302
|
+
|
303
|
+
end
|
304
|
+
|
305
|
+
end
|
306
|
+
|