migratrix 0.0.9 → 0.8.1
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/lib/migratrix.rb +62 -6
- data/lib/migratrix/exceptions.rb +4 -1
- data/lib/migratrix/{extractors → extractions}/active_record.rb +14 -10
- data/lib/migratrix/{extractors/extractor.rb → extractions/extraction.rb} +21 -20
- data/lib/migratrix/loads/load.rb +43 -0
- data/lib/migratrix/loads/yaml.rb +15 -0
- data/lib/migratrix/migration.rb +115 -27
- data/lib/migratrix/migratrix.rb +43 -84
- data/lib/migratrix/registry.rb +20 -0
- data/lib/migratrix/transforms/map.rb +57 -0
- data/lib/migratrix/transforms/transform.rb +268 -0
- data/lib/migratrix/valid_options.rb +22 -0
- data/lib/patches/object_ext.rb +0 -4
- data/spec/fixtures/migrations/marbles_migration.rb +6 -4
- data/spec/lib/migratrix/{loggable_spec.rb → _loggable_spec.rb} +0 -0
- data/spec/lib/migratrix/extractions/active_record_spec.rb +146 -0
- data/spec/lib/migratrix/extractions/extraction_spec.rb +71 -0
- data/spec/lib/migratrix/loads/load_spec.rb +59 -0
- data/spec/lib/migratrix/loads/yaml_spec.rb +39 -0
- data/spec/lib/migratrix/migration_spec.rb +195 -27
- data/spec/lib/migratrix/migratrix_spec.rb +57 -85
- data/spec/lib/migratrix/registry_spec.rb +28 -0
- data/spec/lib/migratrix/transforms/map_spec.rb +55 -0
- data/spec/lib/migratrix/transforms/transform_spec.rb +134 -0
- data/spec/lib/migratrix_spec.rb +98 -0
- data/spec/lib/patches/object_ext_spec.rb +0 -7
- data/spec/spec_helper.rb +18 -13
- metadata +21 -10
- data/spec/lib/migratrix/extractors/active_record_spec.rb +0 -43
- data/spec/lib/migratrix/extractors/extractor_spec.rb +0 -63
- data/spec/lib/migratrix_module_spec.rb +0 -63
@@ -1,106 +1,83 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
it "exists (sanity check)" do
|
7
|
-
Migratrix.should_not be_nil
|
8
|
-
Migratrix.class.should == Module
|
9
|
-
Migratrix.class.should_not == Class
|
10
|
-
Migratrix::Migratrix.class.should_not == Module
|
11
|
-
Migratrix::Migratrix.class.should == Class
|
12
|
-
Migratrix.const_defined?("Migratrix").should be_true
|
13
|
-
end
|
14
|
-
|
15
|
-
describe "MigrationRegistry (needs to be extracted)" do
|
16
|
-
before do
|
17
|
-
reset_migratrix! migratrix
|
18
|
-
Migratrix.class_eval("class PantsMigration < Migration; end")
|
19
|
-
migratrix.register_migration "PantsMigration", Migratrix::PantsMigration
|
20
|
-
end
|
21
|
-
|
22
|
-
it "can register migrations by name" do
|
23
|
-
migratrix.loaded?("PantsMigration").should be_true
|
24
|
-
Migratrix.const_defined?("PantsMigration").should be_true
|
25
|
-
end
|
3
|
+
class TestExtraction < Migratrix::Extractions::Extraction
|
4
|
+
end
|
26
5
|
|
27
|
-
|
28
|
-
|
29
|
-
end
|
6
|
+
class TestTransform < Migratrix::Transforms::Transform
|
7
|
+
end
|
30
8
|
|
31
|
-
|
32
|
-
|
33
|
-
end
|
34
|
-
end
|
9
|
+
class TestLoad < Migratrix::Loads::Load
|
10
|
+
end
|
35
11
|
|
36
|
-
|
37
|
-
|
38
|
-
migratrix.migrations_path.should == ROOT + "db/legacy"
|
39
|
-
end
|
12
|
+
describe Migratrix::Migratrix do
|
13
|
+
let (:migratrix) { Migratrix::Migratrix.new }
|
40
14
|
|
41
|
-
|
42
|
-
|
43
|
-
|
15
|
+
describe "sanity check cat" do
|
16
|
+
it "is sanity checked" do
|
17
|
+
Migratrix.should_not be_nil
|
18
|
+
Migratrix.class.should == Module
|
19
|
+
Migratrix.class.should_not == Class
|
20
|
+
Migratrix::Migratrix.class.should_not == Module
|
21
|
+
Migratrix::Migratrix.class.should == Class
|
22
|
+
Migratrix.const_defined?("Migratrix").should be_true
|
44
23
|
end
|
45
24
|
end
|
46
25
|
|
47
|
-
describe "
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
26
|
+
describe "Migration Component Registry" do
|
27
|
+
describe ".register_extraction" do
|
28
|
+
before do
|
29
|
+
Migratrix::Migratrix.register_extraction :test_extraction, TestExtraction, { :source => Object }
|
30
|
+
end
|
52
31
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
options.should_not have_key("pants")
|
58
|
-
end
|
59
|
-
end
|
32
|
+
it "registers the extraction" do
|
33
|
+
Migratrix::Migratrix.extractions.registered?(:test_extraction).should be_true
|
34
|
+
Migratrix::Migratrix.extractions.class_for(:test_extraction).should == TestExtraction
|
35
|
+
end
|
60
36
|
|
61
|
-
|
62
|
-
|
63
|
-
|
37
|
+
it "creates the extraction with given options" do
|
38
|
+
extraction = TestExtraction.new :test
|
39
|
+
Migratrix::Migratrix.extractions.registered?(:test_extraction).should be_true
|
40
|
+
Migratrix::Migratrix.extractions.class_for(:test_extraction).should == TestExtraction
|
41
|
+
end
|
64
42
|
end
|
65
43
|
|
66
|
-
|
67
|
-
|
68
|
-
|
44
|
+
describe ".register_transform" do
|
45
|
+
before do
|
46
|
+
Migratrix::Migratrix.register_transform :test_transform, TestTransform, { :source => Object }
|
47
|
+
end
|
69
48
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
end
|
49
|
+
it "registers the transform" do
|
50
|
+
Migratrix::Migratrix.transforms.registered?(:test_transform).should be_true
|
51
|
+
Migratrix::Migratrix.transforms.class_for(:test_transform).should == TestTransform
|
52
|
+
end
|
75
53
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
54
|
+
it "creates the transform with given options" do
|
55
|
+
transform = TestTransform.new :monkeys
|
56
|
+
Migratrix::Migratrix.transforms.registered?(:test_transform).should be_true
|
57
|
+
Migratrix::Migratrix.transforms.class_for(:test_transform).should == TestTransform
|
58
|
+
end
|
80
59
|
end
|
81
60
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
migration.options.should == { "where" => "id > 100", "limit" => "100" }
|
87
|
-
end
|
88
|
-
end
|
61
|
+
describe ".register_load" do
|
62
|
+
before do
|
63
|
+
Migratrix::Migratrix.register_load :test_load, TestLoad
|
64
|
+
end
|
89
65
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
end
|
66
|
+
it "registers the load" do
|
67
|
+
Migratrix::Migratrix.loads.registered?(:test_load).should be_true
|
68
|
+
Migratrix::Migratrix.loads.class_for(:test_load).should == TestLoad
|
69
|
+
end
|
95
70
|
|
96
|
-
|
97
|
-
|
98
|
-
|
71
|
+
it "creates the load with given options" do
|
72
|
+
load = TestLoad.new :monkeys
|
73
|
+
Migratrix::Migratrix.loads.registered?(:test_load).should be_true
|
74
|
+
Migratrix::Migratrix.loads.class_for(:test_load).should == TestLoad
|
75
|
+
end
|
99
76
|
end
|
100
77
|
end
|
101
78
|
|
102
79
|
describe "with logger as a singleton" do
|
103
|
-
let (:migration) {
|
80
|
+
let (:migration) { Migratrix::MarblesMigration.new }
|
104
81
|
let (:buffer) { StringIO.new }
|
105
82
|
|
106
83
|
def spec_all_loggers_are(this_logger)
|
@@ -111,11 +88,6 @@ describe Migratrix::Migratrix do
|
|
111
88
|
Migratrix::MarblesMigration.logger.should == this_logger
|
112
89
|
end
|
113
90
|
|
114
|
-
before do
|
115
|
-
reset_migratrix! migratrix
|
116
|
-
migratrix.migrations_path = SPEC + "fixtures/migrations"
|
117
|
-
end
|
118
|
-
|
119
91
|
describe ".logger=" do
|
120
92
|
it "sets logger globally across all Migratrices, the Migratrix module, Migrators and Models" do
|
121
93
|
logger = Migratrix::Migratrix.create_logger(buffer)
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Migratrix::Registry do
|
4
|
+
describe "sanity check cat" do
|
5
|
+
it "is sanity checked" do
|
6
|
+
::Migratrix::Registry.should_not be_nil
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "#register" do
|
11
|
+
let(:registry) { ::Migratrix::Registry.new }
|
12
|
+
before do
|
13
|
+
registry.register(:test, Array, 3)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "registers the class by name" do
|
17
|
+
registry.registered?(:test).should be_true
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "#class_for" do
|
21
|
+
it "returns the registered class" do
|
22
|
+
registry.class_for(:test).should == Array
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class TestMap < Migratrix::Transforms::Map
|
4
|
+
end
|
5
|
+
|
6
|
+
describe Migratrix::Transforms::Map do
|
7
|
+
describe "sanity check cat" do
|
8
|
+
it "is sanity checked" do
|
9
|
+
Migratrix::Transforms::Map.should_not be_nil
|
10
|
+
TestMap.should_not be_nil
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
let(:loggable) { TestMap.new(:loggable) }
|
15
|
+
it_should_behave_like "loggable"
|
16
|
+
|
17
|
+
describe ".local_valid_options" do
|
18
|
+
it "returns the valid set of option keys" do
|
19
|
+
Migratrix::Transforms::Map.local_valid_options.should == []
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe ".valid_options" do
|
24
|
+
it "returns the valide set of options plus those of the superclass" do
|
25
|
+
Migratrix::Transforms::Map.valid_options.should == Migratrix::Transforms::Transform.local_valid_options
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "with pet types fixture" do
|
30
|
+
let(:extracted_pets) {
|
31
|
+
[
|
32
|
+
{ :pet_type_id => 42, :pet_species => 'Dog' },
|
33
|
+
{ :pet_type_id => 43, :pet_species => 'Cat' },
|
34
|
+
{ :pet_type_id => 44, :pet_species => 'Rat' },
|
35
|
+
{ :pet_type_id => 45, :pet_species => 'Parrot' }
|
36
|
+
]
|
37
|
+
}
|
38
|
+
let(:map) { { :id => :pet_type_id, :name => :pet_species } }
|
39
|
+
let(:expected_transform) { {
|
40
|
+
42 => { :id => 42, :name => 'Dog' },
|
41
|
+
43 => { :id => 43, :name => 'Cat' },
|
42
|
+
44 => { :id => 44, :name => 'Rat' },
|
43
|
+
45 => { :id => 45, :name => 'Parrot' }
|
44
|
+
}
|
45
|
+
}
|
46
|
+
let(:transform) { Migratrix::Transforms::Map.new(:pet_types, :transform => map) }
|
47
|
+
|
48
|
+
it "transforms data correctly" do
|
49
|
+
with_logging_to(StringIO.new) do
|
50
|
+
transform.transform(extracted_pets).should == expected_transform
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
@@ -0,0 +1,134 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class TestTransform < Migratrix::Transforms::Transform
|
4
|
+
include Migratrix::Loggable
|
5
|
+
end
|
6
|
+
|
7
|
+
describe Migratrix::Transforms::Transform do
|
8
|
+
describe "sanity check cat" do
|
9
|
+
it "is sanity checked" do
|
10
|
+
Migratrix::Transforms::Transform.should_not be_nil
|
11
|
+
TestTransform.should_not be_nil
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
let(:loggable) { TestTransform.new(:loggable) }
|
16
|
+
it_should_behave_like "loggable"
|
17
|
+
|
18
|
+
describe ".local_valid_options" do
|
19
|
+
it "returns the valid set of option keys" do
|
20
|
+
Migratrix::Transforms::Transform.local_valid_options.should == [:apply_attribute, :extract_attribute, :extraction, :final_class, :finalize_object, :store_transform, :target, :transform, :transform_class, :transform_collection]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
describe "#extraction" do
|
26
|
+
it "returns extraction name when set" do
|
27
|
+
transform = Migratrix::Transforms::Transform.new(:pants_transform, { extraction: :pants_extraction })
|
28
|
+
transform.extraction.should == :pants_extraction
|
29
|
+
end
|
30
|
+
|
31
|
+
it "#returns transform name when no extraction name is set" do
|
32
|
+
transform = Migratrix::Transforms::Transform.new(:pants_transform)
|
33
|
+
transform.extraction.should == :pants_transform
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "unimplemented methods:" do
|
38
|
+
[ [:create_transformed_collection, []],
|
39
|
+
[:create_new_object, [:extracted_row]],
|
40
|
+
[:apply_attribute, [:object, :value, :attribute_or_apply]],
|
41
|
+
[:extract_attribute, [:object, :attribute_or_extract]],
|
42
|
+
[:store_transformed_object, [:object, :collection]] ].each do |method, args|
|
43
|
+
describe "#{method}(#{args.map(&:inspect)*','})" do
|
44
|
+
let(:object_with_not_implemented_methods) { Migratrix::Transforms::Transform.new(:brain_damaged_transform) }
|
45
|
+
it "raises NotImplementedError" do
|
46
|
+
lambda { object_with_not_implemented_methods.send(method, *args) }.should raise_error(NotImplementedError)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "TypeError methods" do
|
53
|
+
[:transform_collection, :transform_class, :extract_attribute, :apply_attribute, :final_class, :finalize_object, :store_transformed_object].each do |method|
|
54
|
+
describe "With #{method} set to a string" do
|
55
|
+
let(:transform_options) { {
|
56
|
+
extraction: :test_stream,
|
57
|
+
transform: { id: :src_id, name: :src_name },
|
58
|
+
transform_collection: Array,
|
59
|
+
transform_class: Hash,
|
60
|
+
extract_attribute: ->(object, attribute) { object[attribute] },
|
61
|
+
apply_attribute: ->(object, attribute, value) { object[attribute] = value },
|
62
|
+
final_class: Set,
|
63
|
+
finalize_object: ->(object) { object.to_a },
|
64
|
+
store_transformed_object: :<<
|
65
|
+
}.merge( method => "cheese")
|
66
|
+
}
|
67
|
+
let(:transform) { TestTransform.new :test, transform_options }
|
68
|
+
let(:test_stream) { [{src_id: 42, src_name: "Alice"}, {src_id: 43, src_name: "Bob"} ] }
|
69
|
+
let(:extractions) { { test_stream: mock("extraction", name: "test_stream", extract: test_stream )}}
|
70
|
+
|
71
|
+
it "should raise TypeError" do
|
72
|
+
lambda { transform.transform(test_stream) }.should raise_error(TypeError)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe "with Proc options" do
|
79
|
+
let(:transform) { TestTransform.new :test, {
|
80
|
+
extraction: :test_stream,
|
81
|
+
transform: { id: :src_id, name: :src_name },
|
82
|
+
transform_collection: ->{ Array.new },
|
83
|
+
transform_class: ->(row) { Hash.new },
|
84
|
+
extract_attribute: ->(object, attribute) { object[attribute] },
|
85
|
+
apply_attribute: ->(object, attribute, value) { object[attribute] = value },
|
86
|
+
final_class: Set,
|
87
|
+
finalize_object: ->(object) { object.to_a },
|
88
|
+
store_transformed_object: ->(object, collection) { collection << object }
|
89
|
+
}
|
90
|
+
}
|
91
|
+
|
92
|
+
let(:test_stream) { [{src_id: 42, src_name: "Alice"}, {src_id: 43, src_name: "Bob"} ] }
|
93
|
+
let(:extractions) { { test_stream: mock("extraction", name: "test_stream", extract: test_stream )}}
|
94
|
+
|
95
|
+
before do
|
96
|
+
TestTransform.stub!(:extractions).and_return(extractions)
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should delegate to procs" do
|
100
|
+
transform.transform(test_stream).should == [
|
101
|
+
Set.new([[:id, 42], [:name, "Alice"]]),
|
102
|
+
Set.new([[:id, 43], [:name, "Bob"]])
|
103
|
+
]
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
describe "with symbol and class options" do
|
108
|
+
let(:transform) { TestTransform.new :test, {
|
109
|
+
extraction: :test_stream,
|
110
|
+
transform: { id: :src_id, name: :src_name },
|
111
|
+
transform_collection: Array,
|
112
|
+
transform_class: Hash,
|
113
|
+
extract_attribute: :[],
|
114
|
+
apply_attribute: :[]=,
|
115
|
+
store_transformed_object: :<<
|
116
|
+
}
|
117
|
+
}
|
118
|
+
|
119
|
+
let(:test_stream) { [{src_id: 42, src_name: "Alice"}, {src_id: 43, src_name: "Bob"} ] }
|
120
|
+
let(:extractions) { { test_stream: mock("extraction", name: "test_stream", extract: test_stream )}}
|
121
|
+
|
122
|
+
before do
|
123
|
+
TestTransform.stub!(:extractions).and_return(extractions)
|
124
|
+
end
|
125
|
+
|
126
|
+
it "should delegate to procs" do
|
127
|
+
transform.transform(test_stream).should == [
|
128
|
+
{id: 42, name: "Alice"},
|
129
|
+
{id: 43, name: "Bob"}
|
130
|
+
]
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Migratrix do
|
4
|
+
describe "sanity check cat" do
|
5
|
+
it "is sanity checked" do
|
6
|
+
Migratrix.should_not be_nil
|
7
|
+
Migratrix.class.should == Module
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "convenience delegator methods" do
|
12
|
+
def spec_delegates_to_migratrix_class(method, *args)
|
13
|
+
if args.size > 0
|
14
|
+
Migratrix::Migratrix.should_receive(method).with(*args).once
|
15
|
+
else
|
16
|
+
Migratrix::Migratrix.should_receive(method).once
|
17
|
+
end
|
18
|
+
Migratrix.send(method, *args)
|
19
|
+
end
|
20
|
+
|
21
|
+
describe ".logger" do
|
22
|
+
it "delegates to Migratrix::Migratrix" do
|
23
|
+
spec_delegates_to_migratrix_class :logger
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe ".logger=" do
|
28
|
+
let (:logger) { Logger.new(StringIO.new) }
|
29
|
+
it "delegates to Migratrix::Migratrix" do
|
30
|
+
spec_delegates_to_migratrix_class :logger=, logger
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe ".log_to" do
|
35
|
+
let (:buffer) { StringIO.new }
|
36
|
+
it "delegates to Migratrix::Migratrix" do
|
37
|
+
spec_delegates_to_migratrix_class :log_to, buffer
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe ".register_extraction" do
|
42
|
+
it "delegates to Migratrix::Migratrix" do
|
43
|
+
spec_delegates_to_migratrix_class :register_extraction, :marbles, Array, 3
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe ".extractions" do
|
48
|
+
it "delegates to Migratrix::Migratrix" do
|
49
|
+
spec_delegates_to_migratrix_class :extractions
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe ".register_transform" do
|
54
|
+
it "delegates to Migratrix::Migratrix" do
|
55
|
+
spec_delegates_to_migratrix_class :register_transform, :marbles, Array, 3
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe ".transforms" do
|
60
|
+
it "delegates to Migratrix::Migratrix" do
|
61
|
+
spec_delegates_to_migratrix_class :transforms
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe ".register_load" do
|
66
|
+
it "delegates to Migratrix::Migratrix" do
|
67
|
+
spec_delegates_to_migratrix_class :register_load, :marbles, Array, 3
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe ".loads" do
|
72
|
+
it "delegates to Migratrix::Migratrix" do
|
73
|
+
spec_delegates_to_migratrix_class :loads
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe "gem-installed components:" do
|
79
|
+
describe "extractions" do
|
80
|
+
it ":active_record is registered" do
|
81
|
+
Migratrix.extractions.class_for(:active_record).should == ::Migratrix::Extractions::ActiveRecord
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe "transforms" do
|
86
|
+
it ":transform is registered" do
|
87
|
+
Migratrix.transforms.class_for(:transform).should == ::Migratrix::Transforms::Transform
|
88
|
+
end
|
89
|
+
|
90
|
+
it ":map is registered" do
|
91
|
+
Migratrix.transforms.class_for(:map).should == ::Migratrix::Transforms::Map
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# transforms: map, transform
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|