dm-migrations 0.10.2 → 1.0.0.rc1

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.
Files changed (33) hide show
  1. data/.gitignore +36 -0
  2. data/Gemfile +141 -0
  3. data/Rakefile +2 -3
  4. data/VERSION +1 -1
  5. data/dm-migrations.gemspec +50 -18
  6. data/lib/dm-migrations.rb +2 -0
  7. data/lib/dm-migrations/adapters/dm-do-adapter.rb +276 -0
  8. data/lib/dm-migrations/adapters/dm-mysql-adapter.rb +283 -0
  9. data/lib/dm-migrations/adapters/dm-oracle-adapter.rb +321 -0
  10. data/lib/dm-migrations/adapters/dm-postgres-adapter.rb +159 -0
  11. data/lib/dm-migrations/adapters/dm-sqlite-adapter.rb +96 -0
  12. data/lib/dm-migrations/adapters/dm-sqlserver-adapter.rb +177 -0
  13. data/lib/dm-migrations/adapters/dm-yaml-adapter.rb +23 -0
  14. data/lib/dm-migrations/auto_migration.rb +238 -0
  15. data/lib/dm-migrations/migration.rb +3 -3
  16. data/lib/dm-migrations/sql.rb +2 -2
  17. data/lib/dm-migrations/sql/mysql.rb +3 -3
  18. data/lib/dm-migrations/sql/{postgresql.rb → postgres.rb} +3 -3
  19. data/lib/dm-migrations/sql/{sqlite3.rb → sqlite.rb} +3 -3
  20. data/spec/integration/auto_migration_spec.rb +506 -0
  21. data/spec/integration/migration_runner_spec.rb +12 -2
  22. data/spec/integration/migration_spec.rb +28 -14
  23. data/spec/integration/sql_spec.rb +22 -21
  24. data/spec/isolated/require_after_setup_spec.rb +30 -0
  25. data/spec/isolated/require_before_setup_spec.rb +30 -0
  26. data/spec/isolated/require_spec.rb +25 -0
  27. data/spec/spec_helper.rb +10 -25
  28. data/spec/unit/migration_spec.rb +320 -319
  29. data/spec/unit/sql/{postgresql_spec.rb → postgres_spec.rb} +17 -17
  30. data/spec/unit/sql/{sqlite3_extensions_spec.rb → sqlite_extensions_spec.rb} +14 -14
  31. data/tasks/local_gemfile.rake +18 -0
  32. data/tasks/spec.rake +0 -3
  33. metadata +72 -32
@@ -1,16 +1,26 @@
1
1
  require 'spec_helper'
2
2
 
3
- ADAPTERS.each do |adapter|
4
- describe "Using Adapter #{adapter}, " do
3
+ describe 'The migration runner' do
4
+
5
+ supported_by :postgres, :mysql, :sqlite, :oracle, :sqlserver do
6
+
7
+ before(:all) do
8
+ @adapter = DataMapper::Spec.adapter
9
+ @repository = DataMapper.repository(@adapter.name)
10
+ end
11
+
5
12
  describe 'empty migration runner' do
6
13
  it "should return an empty array if no migrations have been defined" do
7
14
  migrations.should be_kind_of(Array)
8
15
  migrations.should have(0).item
9
16
  end
10
17
  end
18
+
11
19
  describe 'migration runnner' do
12
20
  # set up some 'global' setup and teardown tasks
13
21
  before(:each) do
22
+ # FIXME workaround because dm-migrations can only handle the :default repo
23
+ #DataMapper::Repository.adapters[:default] = DataMapper::Repository.adapters[adapter.to_sym]
14
24
  migration( 1, :create_people_table) { }
15
25
  end
16
26
 
@@ -1,8 +1,15 @@
1
1
  require 'spec_helper'
2
2
 
3
- ADAPTERS.each do |adapter|
4
- describe "Using Adapter #{adapter}, " do
3
+ describe "A Migration" do
4
+
5
+ supported_by :postgres, :mysql, :sqlite, :oracle, :sqlserver do
6
+
5
7
  describe DataMapper::Migration, 'interface' do
8
+
9
+ before(:all) do
10
+ @adapter = DataMapper::Spec.adapter
11
+ end
12
+
6
13
  before do
7
14
  @migration = DataMapper::Migration.new(1, :create_people_table, :verbose => false) { }
8
15
  end
@@ -20,10 +27,9 @@ ADAPTERS.each do |adapter|
20
27
  end
21
28
 
22
29
  it "should have a :database option" do
23
- DataMapper.setup(:other, "sqlite3://#{Dir.pwd}/migration_other.db")
24
-
25
- m = DataMapper::Migration.new(2, :create_dogs_table, :database => :other) {}
26
- m.instance_variable_get(:@database).name.should == :other
30
+ adapter = DataMapper::Spec.adapter(:alternate)
31
+ m = DataMapper::Migration.new(2, :create_dogs_table, :database => :alternate) {}
32
+ m.instance_variable_get(:@adapter).should == adapter
27
33
  end
28
34
 
29
35
  it "should use the default database by default" do
@@ -49,15 +55,21 @@ ADAPTERS.each do |adapter|
49
55
  [m1, m2, m3, m4].sort.should == [m1, m3, m2, m4]
50
56
  end
51
57
 
52
- expected_module = {
53
- :sqlite3 => lambda { SQL::Sqlite3 },
54
- :mysql => lambda { SQL::Mysql },
55
- :postgres => lambda { SQL::Postgresql }
56
- }[adapter][]
58
+ adapter = DataMapper::Spec.adapter_name
59
+
60
+ expected_module_lambda = {
61
+ :sqlite => lambda { SQL::Sqlite },
62
+ :mysql => lambda { SQL::Mysql },
63
+ :postgres => lambda { SQL::Postgres }
64
+ }[adapter.to_sym]
65
+
66
+ expected_module = expected_module_lambda ? expected_module_lambda.call : nil
57
67
 
58
- it "should extend with #{expected_module} when adapter is #{adapter}" do
59
- migration = DataMapper::Migration.new(1, :"#{adapter}_adapter_test", :database => adapter) { }
60
- (class << migration.adapter; self; end).included_modules.should include(expected_module)
68
+ if expected_module
69
+ it "should extend with #{expected_module} when adapter is #{adapter}" do
70
+ migration = DataMapper::Migration.new(1, :"#{adapter}_adapter_test") { }
71
+ (class << migration.adapter; self; end).included_modules.should include(expected_module)
72
+ end
61
73
  end
62
74
  end
63
75
 
@@ -120,5 +132,7 @@ ADAPTERS.each do |adapter|
120
132
  end
121
133
 
122
134
  end
135
+
123
136
  end
137
+
124
138
  end
@@ -1,24 +1,26 @@
1
1
  require 'spec_helper'
2
2
 
3
- ADAPTERS.each do |adapter|
4
- describe "Using Adapter #{adapter}," do
3
+ describe "SQL generation" do
5
4
 
6
- def repository(*args)
7
- DataMapper.repository(*args)
8
- end
5
+ supported_by :postgres, :mysql, :sqlite, :oracle, :sqlserver do
9
6
 
10
7
  describe DataMapper::Migration, "#create_table helper" do
11
8
  before :all do
12
- case adapter
13
- when :sqlite3 then repository(adapter).adapter.extend(SQL::Sqlite3)
14
- when :mysql then repository(adapter).adapter.extend(SQL::Mysql)
15
- when :postgres then repository(adapter).adapter.extend(SQL::Postgresql)
9
+
10
+ @adapter = DataMapper::Spec.adapter
11
+ @repository = DataMapper.repository(@adapter.name)
12
+
13
+ case DataMapper::Spec.adapter_name.to_sym
14
+ when :sqlite then @adapter.extend(SQL::Sqlite)
15
+ when :mysql then @adapter.extend(SQL::Mysql)
16
+ when :postgres then @adapter.extend(SQL::Postgres)
16
17
  end
18
+
17
19
  end
18
20
 
19
21
  before do
20
- @creator = DataMapper::Migration::TableCreator.new(repository(adapter).adapter, :people) do
21
- column :id, DataMapper::Types::Serial
22
+ @creator = DataMapper::Migration::TableCreator.new(@adapter, :people) do
23
+ column :id, DataMapper::Property::Serial
22
24
  column :name, 'VARCHAR(50)', :allow_nil => false
23
25
  column :long_string, String, :size => 200
24
26
  end
@@ -34,7 +36,7 @@ ADAPTERS.each do |adapter|
34
36
  end
35
37
 
36
38
  it "should have an adapter" do
37
- @creator.instance_eval("@adapter").should == repository(adapter).adapter
39
+ @creator.instance_eval("@adapter").should == @adapter
38
40
  end
39
41
 
40
42
  it "should have an options hash" do
@@ -49,7 +51,7 @@ ADAPTERS.each do |adapter|
49
51
  end
50
52
 
51
53
  it "should quote the table name for the adapter" do
52
- @creator.quoted_table_name.should == (adapter == :mysql ? '`people`' : '"people"')
54
+ @creator.quoted_table_name.should == (DataMapper::Spec.adapter_name.to_sym == :mysql ? '`people`' : '"people"')
53
55
  end
54
56
 
55
57
  it "should allow for custom options" do
@@ -62,7 +64,7 @@ ADAPTERS.each do |adapter|
62
64
  @creator.instance_eval("@columns")[1].type.should match(/NOT NULL/)
63
65
  end
64
66
 
65
- case adapter
67
+ case DataMapper::Spec.adapter_name.to_sym
66
68
  when :mysql
67
69
  it "should create an InnoDB database for MySQL" do
68
70
  #can't get an exact == comparison here because character set and collation may differ per connection
@@ -102,7 +104,7 @@ ADAPTERS.each do |adapter|
102
104
  end
103
105
 
104
106
  describe DataMapper::Migration, "version tracking" do
105
- before do
107
+ before(:each) do
106
108
  @migration = DataMapper::Migration.new(1, :create_people_table, :verbose => false) do
107
109
  up { :ran_up }
108
110
  down { :ran_down }
@@ -111,8 +113,10 @@ ADAPTERS.each do |adapter|
111
113
  @migration.send(:create_migration_info_table_if_needed)
112
114
  end
113
115
 
116
+ after(:each) { DataMapper::Spec.adapter.execute("DROP TABLE migration_info") rescue nil }
117
+
114
118
  def insert_migration_record
115
- DataMapper.repository.adapter.execute("INSERT INTO migration_info (migration_name) VALUES ('create_people_table')")
119
+ DataMapper::Spec.adapter.execute("INSERT INTO migration_info (migration_name) VALUES ('create_people_table')")
116
120
  end
117
121
 
118
122
  it "should know if the migration_info table exists" do
@@ -120,7 +124,7 @@ ADAPTERS.each do |adapter|
120
124
  end
121
125
 
122
126
  it "should know if the migration_info table does not exist" do
123
- repository.adapter.execute("DROP TABLE migration_info") rescue nil
127
+ DataMapper::Spec.adapter.execute("DROP TABLE migration_info") rescue nil
124
128
  @migration.send(:migration_info_table_exists?).should be_false
125
129
  end
126
130
 
@@ -153,7 +157,7 @@ ADAPTERS.each do |adapter|
153
157
  # TODO how to i call the adapter's #escape_sql method?
154
158
 
155
159
  it "should create the migration_info table if it doesn't exist" do
156
- repository.adapter.execute("DROP TABLE migration_info")
160
+ DataMapper::Spec.adapter.execute("DROP TABLE migration_info")
157
161
  @migration.send(:migration_info_table_exists?).should be_false
158
162
  @migration.send(:create_migration_info_table_if_needed)
159
163
  @migration.send(:migration_info_table_exists?).should be_true
@@ -181,9 +185,6 @@ ADAPTERS.each do |adapter|
181
185
  @migration.perform_down.should_not == :ran_down
182
186
  end
183
187
 
184
- after do
185
- repository.adapter.execute("DELETE FROM migration_info") if @migration.send(:migration_info_table_exists?)
186
- end
187
188
  end
188
189
  end
189
190
  end
@@ -0,0 +1,30 @@
1
+ require 'spec'
2
+ require 'isolated/require_spec'
3
+ require 'dm-core/spec/setup'
4
+ require 'dm-core/spec/lib/adapter_helpers'
5
+
6
+ # To really test this behavior, this spec needs to be run in isolation and not
7
+ # as part of the typical rake spec run, which requires dm-transactions upfront
8
+
9
+ describe "require 'dm-migrations' after calling DataMapper.setup" do
10
+ extend DataMapper::Spec::Adapters::Helpers
11
+
12
+ before(:all) do
13
+
14
+ @adapter = DataMapper::Spec.adapter
15
+ require 'dm-migrations'
16
+
17
+ class ::Person
18
+ include DataMapper::Resource
19
+ property :id, Serial
20
+ end
21
+
22
+ @model = Person
23
+
24
+ end
25
+
26
+ supported_by :postgres, :mysql, :sqlite, :oracle, :sqlserver do
27
+ it_should_behave_like "require 'dm-migrations'"
28
+ end
29
+
30
+ end
@@ -0,0 +1,30 @@
1
+ require 'spec'
2
+ require 'isolated/require_spec'
3
+ require 'dm-core/spec/setup'
4
+ require 'dm-core/spec/lib/adapter_helpers'
5
+
6
+ # To really test this behavior, this spec needs to be run in isolation and not
7
+ # as part of the typical rake spec run, which requires dm-transactions upfront
8
+
9
+ describe "require 'dm-migrations' before calling DataMapper.setup" do
10
+ extend DataMapper::Spec::Adapters::Helpers
11
+
12
+ before(:all) do
13
+
14
+ require 'dm-migrations'
15
+ @adapter = DataMapper::Spec.adapter
16
+
17
+ class ::Person
18
+ include DataMapper::Resource
19
+ property :id, Serial
20
+ end
21
+
22
+ @model = Person
23
+
24
+ end
25
+
26
+ supported_by :postgres, :mysql, :sqlite, :oracle, :sqlserver do
27
+ it_should_behave_like "require 'dm-migrations'"
28
+ end
29
+
30
+ end
@@ -0,0 +1,25 @@
1
+ shared_examples_for "require 'dm-migrations'" do
2
+
3
+ it "should include the migration api in the DataMapper namespace" do
4
+ DataMapper.respond_to?(:migrate! ).should be_true
5
+ DataMapper.respond_to?(:auto_migrate! ).should be_true
6
+ DataMapper.respond_to?(:auto_upgrade! ).should be_true
7
+ DataMapper.respond_to?(:auto_migrate_up!, true).should be_true
8
+ DataMapper.respond_to?(:auto_migrate_down!, true).should be_true
9
+ end
10
+
11
+ %w[Repository Model].each do |name|
12
+ it "should include the migration api in DataMapper::#{name}" do
13
+ (DataMapper.const_get(name) < DataMapper::Migrations.const_get(name)).should be_true
14
+ end
15
+ end
16
+
17
+ it "should include the migration api into the adapter" do
18
+ @adapter.respond_to?(:storage_exists? ).should be_true
19
+ @adapter.respond_to?(:field_exists? ).should be_true
20
+ @adapter.respond_to?(:upgrade_model_storage).should be_true
21
+ @adapter.respond_to?(:create_model_storage ).should be_true
22
+ @adapter.respond_to?(:destroy_model_storage).should be_true
23
+ end
24
+
25
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,31 +1,16 @@
1
- require 'rubygems'
1
+ require 'dm-migrations'
2
+ require 'dm-migrations/migration_runner'
2
3
 
3
- # use local dm-core if running from a typical dev checkout.
4
- lib = File.join('..', '..', 'dm-core', 'lib')
5
- $LOAD_PATH.unshift(lib) if File.directory?(lib)
6
- require 'dm-core'
4
+ require 'dm-core/spec/setup'
5
+ require 'dm-core/spec/lib/adapter_helpers'
6
+ require 'dm-core/spec/lib/spec_helper'
7
7
 
8
- # Support running specs with 'rake spec' and 'spec'
9
- $LOAD_PATH.unshift('lib') unless $LOAD_PATH.include?('lib')
8
+ Spec::Runner.configure do |config|
10
9
 
11
- require 'dm-migrations'
12
- require 'dm-migrations/migration_runner'
10
+ config.extend(DataMapper::Spec::Adapters::Helpers)
13
11
 
14
- ADAPTERS = []
15
- def load_driver(name, default_uri)
16
- begin
17
- DataMapper.setup(name, default_uri)
18
- DataMapper::Repository.adapters[:default] = DataMapper::Repository.adapters[name]
19
- ADAPTERS << name
20
- true
21
- rescue LoadError => e
22
- warn "Could not load do_#{name}: #{e}"
23
- false
12
+ config.after :all do
13
+ DataMapper::Spec.cleanup_models
24
14
  end
25
- end
26
-
27
- ENV['ADAPTER'] ||= 'sqlite3'
28
15
 
29
- load_driver(:sqlite3, 'sqlite3::memory:')
30
- load_driver(:mysql, 'mysql://localhost/dm_core_test')
31
- load_driver(:postgres, 'postgres://postgres@localhost/dm_core_test')
16
+ end
@@ -1,443 +1,444 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe 'Migration' do
4
-
5
- before do
6
- @adapter = mock('adapter', :class => DataMapper::Adapters::Sqlite3Adapter)
7
- @repo = mock('DataMapper.repository', :adapter => @adapter)
8
- DataMapper.stub!(:repository).and_return(@repo)
9
- @m = DataMapper::Migration.new(1, :do_nothing, {}) {}
10
- @m.stub!(:write) # silence any output
11
- end
12
-
13
- [:position, :name, :database, :adapter].each do |meth|
14
- it "should respond to ##{meth}" do
15
- @m.should respond_to(meth)
16
- end
17
- end
18
-
19
- describe 'initialization' do
20
- it 'should set @position from the given position' do
21
- @m.instance_variable_get(:@position).should == 1
22
- end
23
-
24
- it 'should set @name from the given name' do
25
- @m.instance_variable_get(:@name).should == :do_nothing
26
- end
27
-
28
- it 'should set @options from the options hash' do
29
- @m.instance_variable_get(:@options).should == {}
4
+ supported_by :postgres, :mysql, :sqlite do
5
+ before do
6
+ @adapter = mock('adapter', :class => DataMapper::Spec.adapter.class)
7
+ @repo = mock('DataMapper.repository', :adapter => @adapter)
8
+ DataMapper.stub!(:repository).and_return(@repo)
9
+ @m = DataMapper::Migration.new(1, :do_nothing, {}) {}
10
+ @m.stub!(:write) # silence any output
30
11
  end
31
12
 
32
- it 'should set @database from the default repository if no :database option is given' do
33
- DataMapper.should_receive(:repository).with(:default).and_return(@repo)
34
- DataMapper::Migration.new(1, :do_nothing, {}) {}
13
+ [:position, :name, :database, :adapter].each do |meth|
14
+ it "should respond to ##{meth}" do
15
+ @m.should respond_to(meth)
16
+ end
35
17
  end
36
18
 
37
- it 'should set @database to the repository specified with the :database option' do
38
- DataMapper.should_receive(:repository).with(:foobar).and_return(@repo)
39
- DataMapper::Migration.new(1, :do_nothing, :database => :foobar) {}
40
- end
19
+ describe 'initialization' do
20
+ it 'should set @position from the given position' do
21
+ @m.instance_variable_get(:@position).should == 1
22
+ end
41
23
 
42
- it 'should determine the class of the adapter to be extended' do
43
- @adapter.should_receive(:class).and_return(DataMapper::Adapters::Sqlite3Adapter)
44
- DataMapper::Migration.new(1, :do_nothing, {}) {}
45
- end
24
+ it 'should set @name from the given name' do
25
+ @m.instance_variable_get(:@name).should == :do_nothing
26
+ end
46
27
 
47
- it 'should extend the adapter with the right module' do
48
- @adapter.should_receive(:extend).with(SQL::Sqlite3)
49
- DataMapper::Migration.new(1, :do_nothing, {}) {}
50
- end
28
+ it 'should set @options from the options hash' do
29
+ @m.instance_variable_get(:@options).should == {}
30
+ end
51
31
 
52
- it 'should raise "Unsupported adapter" on an unknown adapter' do
53
- @adapter.should_receive(:class).any_number_of_times.and_return("InvalidAdapter")
54
- lambda {
32
+ it 'should set @database from the default repository if no :database option is given' do
33
+ DataMapper.should_receive(:repository).with(:default).and_return(@repo)
55
34
  DataMapper::Migration.new(1, :do_nothing, {}) {}
56
- }.should raise_error
57
- end
58
-
59
- it 'should set @verbose from the options hash' do
60
- m = DataMapper::Migration.new(1, :do_nothing, :verbose => false) {}
61
- m.instance_variable_get(:@verbose).should be_false
62
- end
35
+ end
63
36
 
64
- it 'should set @verbose to true by default' do
65
- @m.instance_variable_get(:@verbose).should be_true
66
- end
37
+ it 'should set @database to the repository specified with the :database option' do
38
+ DataMapper.should_receive(:repository).with(:foobar).and_return(@repo)
39
+ DataMapper::Migration.new(1, :do_nothing, :database => :foobar) {}
40
+ end
67
41
 
68
- it 'should set the @up_action to an empty block' do
69
- @m.instance_variable_get(:@up_action).should be_kind_of(Proc)
70
- end
42
+ it 'should determine the class of the adapter to be extended' do
43
+ @adapter.should_receive(:class).and_return(DataMapper::Spec.adapter.class)
44
+ DataMapper::Migration.new(1, :do_nothing, {}) {}
45
+ end
71
46
 
72
- it 'should set the @down_action to an empty block' do
73
- @m.instance_variable_get(:@down_action).should be_kind_of(Proc)
74
- end
47
+ it 'should extend the adapter with the right module' do
48
+ @adapter.should_receive(:extend).with(SQL.const_get(DataMapper::Spec.adapter_name.capitalize))
49
+ DataMapper::Migration.new(1, :do_nothing, {}) {}
50
+ end
75
51
 
76
- it 'should evaluate the given block'
52
+ it 'should raise "Unsupported adapter" on an unknown adapter' do
53
+ @adapter.should_receive(:class).any_number_of_times.and_return("InvalidAdapter")
54
+ lambda {
55
+ DataMapper::Migration.new(1, :do_nothing, {}) {}
56
+ }.should raise_error
57
+ end
77
58
 
78
- end
59
+ it 'should set @verbose from the options hash' do
60
+ m = DataMapper::Migration.new(1, :do_nothing, :verbose => false) {}
61
+ m.instance_variable_get(:@verbose).should be_false
62
+ end
79
63
 
80
- it 'should set the @up_action when #up is called with a block' do
81
- action = lambda {}
82
- @m.up(&action)
83
- @m.instance_variable_get(:@up_action).should == action
84
- end
64
+ it 'should set @verbose to true by default' do
65
+ @m.instance_variable_get(:@verbose).should be_true
66
+ end
85
67
 
86
- it 'should set the @up_action when #up is called with a block' do
87
- action = lambda {}
88
- @m.down(&action)
89
- @m.instance_variable_get(:@down_action).should == action
90
- end
68
+ it 'should set the @up_action to an empty block' do
69
+ @m.instance_variable_get(:@up_action).should be_kind_of(Proc)
70
+ end
91
71
 
92
- describe 'perform_up' do
93
- before do
94
- @up_action = mock('proc', :call => true)
95
- @m.instance_variable_set(:@up_action, @up_action)
96
- @m.stub!(:needs_up?).and_return(true)
97
- @m.stub!(:update_migration_info)
98
- end
72
+ it 'should set the @down_action to an empty block' do
73
+ @m.instance_variable_get(:@down_action).should be_kind_of(Proc)
74
+ end
99
75
 
100
- it 'should call the action assigned to @up_action and return the result' do
101
- @up_action.should_receive(:call).and_return(:result)
102
- @m.perform_up.should == :result
103
- end
76
+ it 'should evaluate the given block'
104
77
 
105
- it 'should output a status message with the position and name of the migration' do
106
- @m.should_receive(:write).with(/Performing Up Migration #1: do_nothing/)
107
- @m.perform_up
108
78
  end
109
79
 
110
- it 'should not run if it doesnt need to be' do
111
- @m.should_receive(:needs_up?).and_return(false)
112
- @up_action.should_not_receive(:call)
113
- @m.perform_up
80
+ it 'should set the @up_action when #up is called with a block' do
81
+ action = lambda {}
82
+ @m.up(&action)
83
+ @m.instance_variable_get(:@up_action).should == action
114
84
  end
115
85
 
116
- it 'should update the migration info table' do
117
- @m.should_receive(:update_migration_info).with(:up)
118
- @m.perform_up
86
+ it 'should set the @up_action when #up is called with a block' do
87
+ action = lambda {}
88
+ @m.down(&action)
89
+ @m.instance_variable_get(:@down_action).should == action
119
90
  end
120
91
 
121
- it 'should not update the migration info table if the migration does not need run' do
122
- @m.should_receive(:needs_up?).and_return(false)
123
- @m.should_not_receive(:update_migration_info)
124
- @m.perform_up
125
- end
92
+ describe 'perform_up' do
93
+ before do
94
+ @up_action = mock('proc', :call => true)
95
+ @m.instance_variable_set(:@up_action, @up_action)
96
+ @m.stub!(:needs_up?).and_return(true)
97
+ @m.stub!(:update_migration_info)
98
+ end
126
99
 
127
- end
100
+ it 'should call the action assigned to @up_action and return the result' do
101
+ @up_action.should_receive(:call).and_return(:result)
102
+ @m.perform_up.should == :result
103
+ end
128
104
 
129
- describe 'perform_down' do
130
- before do
131
- @down_action = mock('proc', :call => true)
132
- @m.instance_variable_set(:@down_action, @down_action)
133
- @m.stub!(:needs_down?).and_return(true)
134
- @m.stub!(:update_migration_info)
135
- end
105
+ it 'should output a status message with the position and name of the migration' do
106
+ @m.should_receive(:write).with(/Performing Up Migration #1: do_nothing/)
107
+ @m.perform_up
108
+ end
136
109
 
137
- it 'should call the action assigned to @down_action and return the result' do
138
- @down_action.should_receive(:call).and_return(:result)
139
- @m.perform_down.should == :result
140
- end
110
+ it 'should not run if it doesnt need to be' do
111
+ @m.should_receive(:needs_up?).and_return(false)
112
+ @up_action.should_not_receive(:call)
113
+ @m.perform_up
114
+ end
141
115
 
142
- it 'should output a status message with the position and name of the migration' do
143
- @m.should_receive(:write).with(/Performing Down Migration #1: do_nothing/)
144
- @m.perform_down
145
- end
116
+ it 'should update the migration info table' do
117
+ @m.should_receive(:update_migration_info).with(:up)
118
+ @m.perform_up
119
+ end
146
120
 
147
- it 'should not run if it doesnt need to be' do
148
- @m.should_receive(:needs_down?).and_return(false)
149
- @down_action.should_not_receive(:call)
150
- @m.perform_down
151
- end
121
+ it 'should not update the migration info table if the migration does not need run' do
122
+ @m.should_receive(:needs_up?).and_return(false)
123
+ @m.should_not_receive(:update_migration_info)
124
+ @m.perform_up
125
+ end
152
126
 
153
- it 'should update the migration info table' do
154
- @m.should_receive(:update_migration_info).with(:down)
155
- @m.perform_down
156
127
  end
157
128
 
158
- it 'should not update the migration info table if the migration does not need run' do
159
- @m.should_receive(:needs_down?).and_return(false)
160
- @m.should_not_receive(:update_migration_info)
161
- @m.perform_down
162
- end
129
+ describe 'perform_down' do
130
+ before do
131
+ @down_action = mock('proc', :call => true)
132
+ @m.instance_variable_set(:@down_action, @down_action)
133
+ @m.stub!(:needs_down?).and_return(true)
134
+ @m.stub!(:update_migration_info)
135
+ end
163
136
 
164
- end
137
+ it 'should call the action assigned to @down_action and return the result' do
138
+ @down_action.should_receive(:call).and_return(:result)
139
+ @m.perform_down.should == :result
140
+ end
165
141
 
166
- describe 'methods used in the action blocks' do
142
+ it 'should output a status message with the position and name of the migration' do
143
+ @m.should_receive(:write).with(/Performing Down Migration #1: do_nothing/)
144
+ @m.perform_down
145
+ end
167
146
 
168
- describe '#execute' do
169
- before do
170
- @adapter.stub!(:execute)
147
+ it 'should not run if it doesnt need to be' do
148
+ @m.should_receive(:needs_down?).and_return(false)
149
+ @down_action.should_not_receive(:call)
150
+ @m.perform_down
171
151
  end
172
152
 
173
- it 'should send the SQL it its executing to the adapter execute method' do
174
- @adapter.should_receive(:execute).with('SELECT SOME SQL')
175
- @m.execute('SELECT SOME SQL')
153
+ it 'should update the migration info table' do
154
+ @m.should_receive(:update_migration_info).with(:down)
155
+ @m.perform_down
176
156
  end
177
157
 
178
- it 'should output the SQL it is executing' do
179
- @m.should_receive(:write).with(/SELECT SOME SQL/)
180
- @m.execute('SELECT SOME SQL')
158
+ it 'should not update the migration info table if the migration does not need run' do
159
+ @m.should_receive(:needs_down?).and_return(false)
160
+ @m.should_not_receive(:update_migration_info)
161
+ @m.perform_down
181
162
  end
163
+
182
164
  end
183
165
 
184
- describe 'helpers' do
185
- before do
186
- @m.stub!(:execute) # don't actually run anything
187
- end
166
+ describe 'methods used in the action blocks' do
188
167
 
189
- describe '#create_table' do
168
+ describe '#execute' do
190
169
  before do
191
- @tc = mock('TableCreator', :to_sql => 'CREATE TABLE')
192
- SQL::TableCreator.stub!(:new).and_return(@tc)
170
+ @adapter.stub!(:execute)
193
171
  end
194
172
 
195
- it 'should create a new TableCreator object' do
196
- SQL::TableCreator.should_receive(:new).with(@adapter, :users, {}).and_return(@tc)
197
- @m.create_table(:users) { }
173
+ it 'should send the SQL it its executing to the adapter execute method' do
174
+ @adapter.should_receive(:execute).with('SELECT SOME SQL')
175
+ @m.execute('SELECT SOME SQL')
198
176
  end
199
177
 
200
- it 'should convert the TableCreator object to an sql statement' do
201
- @tc.should_receive(:to_sql).and_return('CREATE TABLE')
202
- @m.create_table(:users) { }
178
+ it 'should output the SQL it is executing' do
179
+ @m.should_receive(:write).with(/SELECT SOME SQL/)
180
+ @m.execute('SELECT SOME SQL')
203
181
  end
182
+ end
204
183
 
205
- it 'should execute the create table sql' do
206
- @m.should_receive(:execute).with('CREATE TABLE')
207
- @m.create_table(:users) { }
184
+ describe 'helpers' do
185
+ before do
186
+ @m.stub!(:execute) # don't actually run anything
208
187
  end
209
188
 
210
- end
189
+ describe '#create_table' do
190
+ before do
191
+ @tc = mock('TableCreator', :to_sql => 'CREATE TABLE')
192
+ SQL::TableCreator.stub!(:new).and_return(@tc)
193
+ end
211
194
 
212
- describe '#drop_table' do
213
- it 'should quote the table name' do
214
- @adapter.should_receive(:quote_name).with('users')
215
- @m.drop_table :users
216
- end
195
+ it 'should create a new TableCreator object' do
196
+ SQL::TableCreator.should_receive(:new).with(@adapter, :users, {}).and_return(@tc)
197
+ @m.create_table(:users) { }
198
+ end
217
199
 
218
- it 'should execute the DROP TABLE sql for the table' do
219
- @adapter.stub!(:quote_name).and_return("'users'")
220
- @m.should_receive(:execute).with(%{DROP TABLE 'users'})
221
- @m.drop_table :users
222
- end
200
+ it 'should convert the TableCreator object to an sql statement' do
201
+ @tc.should_receive(:to_sql).and_return('CREATE TABLE')
202
+ @m.create_table(:users) { }
203
+ end
223
204
 
224
- end
205
+ it 'should execute the create table sql' do
206
+ @m.should_receive(:execute).with('CREATE TABLE')
207
+ @m.create_table(:users) { }
208
+ end
225
209
 
226
- describe '#modify_table' do
227
- before do
228
- @tm = mock('TableModifier', :statements => [])
229
- SQL::TableModifier.stub!(:new).and_return(@tm)
230
210
  end
231
211
 
232
- it 'should create a new TableModifier object' do
233
- SQL::TableModifier.should_receive(:new).with(@adapter, :users, {}).and_return(@tm)
234
- @m.modify_table(:users){ }
235
- end
212
+ describe '#drop_table' do
213
+ it 'should quote the table name' do
214
+ @adapter.should_receive(:quote_name).with('users')
215
+ @m.drop_table :users
216
+ end
236
217
 
237
- it 'should get the statements from the TableModifier object' do
238
- @tm.should_receive(:statements).and_return([])
239
- @m.modify_table(:users){ }
240
- end
218
+ it 'should execute the DROP TABLE sql for the table' do
219
+ @adapter.stub!(:quote_name).and_return("'users'")
220
+ @m.should_receive(:execute).with(%{DROP TABLE 'users'})
221
+ @m.drop_table :users
222
+ end
241
223
 
242
- it 'should iterate over the statements and execute each one' do
243
- @tm.should_receive(:statements).and_return(['SELECT 1', 'SELECT 2'])
244
- @m.should_receive(:execute).with('SELECT 1')
245
- @m.should_receive(:execute).with('SELECT 2')
246
- @m.modify_table(:users){ }
247
224
  end
248
225
 
249
- end
226
+ describe '#modify_table' do
227
+ before do
228
+ @tm = mock('TableModifier', :statements => [])
229
+ SQL::TableModifier.stub!(:new).and_return(@tm)
230
+ end
250
231
 
251
- describe 'sorting' do
252
- it 'should order things by position' do
253
- m1 = DataMapper::Migration.new(1, :do_nothing){}
254
- m2 = DataMapper::Migration.new(2, :do_nothing_else){}
232
+ it 'should create a new TableModifier object' do
233
+ SQL::TableModifier.should_receive(:new).with(@adapter, :users, {}).and_return(@tm)
234
+ @m.modify_table(:users){ }
235
+ end
255
236
 
256
- (m1 <=> m2).should == -1
257
- end
237
+ it 'should get the statements from the TableModifier object' do
238
+ @tm.should_receive(:statements).and_return([])
239
+ @m.modify_table(:users){ }
240
+ end
258
241
 
259
- it 'should order things by name when they have the same position' do
260
- m1 = DataMapper::Migration.new(1, :do_nothing_a){}
261
- m2 = DataMapper::Migration.new(1, :do_nothing_b){}
242
+ it 'should iterate over the statements and execute each one' do
243
+ @tm.should_receive(:statements).and_return(['SELECT 1', 'SELECT 2'])
244
+ @m.should_receive(:execute).with('SELECT 1')
245
+ @m.should_receive(:execute).with('SELECT 2')
246
+ @m.modify_table(:users){ }
247
+ end
262
248
 
263
- (m1 <=> m2).should == -1
264
249
  end
265
250
 
266
- end
251
+ describe 'sorting' do
252
+ it 'should order things by position' do
253
+ m1 = DataMapper::Migration.new(1, :do_nothing){}
254
+ m2 = DataMapper::Migration.new(2, :do_nothing_else){}
267
255
 
268
- describe 'formatting output' do
269
- describe '#say' do
270
- it 'should output the message' do
271
- @m.should_receive(:write).with(/Paul/)
272
- @m.say("Paul")
256
+ (m1 <=> m2).should == -1
273
257
  end
274
258
 
275
- it 'should indent the message with 4 spaces by default' do
276
- @m.should_receive(:write).with(/^\s{4}/)
277
- @m.say("Paul")
278
- end
259
+ it 'should order things by name when they have the same position' do
260
+ m1 = DataMapper::Migration.new(1, :do_nothing_a){}
261
+ m2 = DataMapper::Migration.new(1, :do_nothing_b){}
279
262
 
280
- it 'should indext the message with a given number of spaces' do
281
- @m.should_receive(:write).with(/^\s{3}/)
282
- @m.say("Paul", 3)
263
+ (m1 <=> m2).should == -1
283
264
  end
265
+
284
266
  end
285
267
 
286
- describe '#say_with_time' do
287
- before do
288
- @m.stub!(:say)
268
+ describe 'formatting output' do
269
+ describe '#say' do
270
+ it 'should output the message' do
271
+ @m.should_receive(:write).with(/Paul/)
272
+ @m.say("Paul")
273
+ end
274
+
275
+ it 'should indent the message with 4 spaces by default' do
276
+ @m.should_receive(:write).with(/^\s{4}/)
277
+ @m.say("Paul")
278
+ end
279
+
280
+ it 'should indext the message with a given number of spaces' do
281
+ @m.should_receive(:write).with(/^\s{3}/)
282
+ @m.say("Paul", 3)
283
+ end
289
284
  end
290
285
 
291
- it 'should say the message with an indent of 2' do
292
- @m.should_receive(:say).with("Paul", 2)
293
- @m.say_with_time("Paul"){}
294
- end
286
+ describe '#say_with_time' do
287
+ before do
288
+ @m.stub!(:say)
289
+ end
295
290
 
296
- it 'should output the time it took' do
297
- @m.should_receive(:say).with(/\d+/, 2)
298
- @m.say_with_time("Paul"){}
299
- end
300
- end
291
+ it 'should say the message with an indent of 2' do
292
+ @m.should_receive(:say).with("Paul", 2)
293
+ @m.say_with_time("Paul"){}
294
+ end
301
295
 
302
- describe '#write' do
303
- before do
304
- # need a new migration object, because the main one had #write stubbed to silence output
305
- @m = DataMapper::Migration.new(1, :do_nothing) {}
296
+ it 'should output the time it took' do
297
+ @m.should_receive(:say).with(/\d+/, 2)
298
+ @m.say_with_time("Paul"){}
299
+ end
306
300
  end
307
301
 
308
- it 'should puts the message' do
309
- @m.should_receive(:puts).with("Paul")
310
- @m.write("Paul")
311
- end
302
+ describe '#write' do
303
+ before do
304
+ # need a new migration object, because the main one had #write stubbed to silence output
305
+ @m = DataMapper::Migration.new(1, :do_nothing) {}
306
+ end
312
307
 
313
- it 'should not puts the message if @verbose is false' do
314
- @m.instance_variable_set(:@verbose, false)
315
- @m.should_not_receive(:puts)
316
- @m.write("Paul")
317
- end
308
+ it 'should puts the message' do
309
+ @m.should_receive(:puts).with("Paul")
310
+ @m.write("Paul")
311
+ end
318
312
 
319
- end
313
+ it 'should not puts the message if @verbose is false' do
314
+ @m.instance_variable_set(:@verbose, false)
315
+ @m.should_not_receive(:puts)
316
+ @m.write("Paul")
317
+ end
320
318
 
321
- end
319
+ end
322
320
 
323
- describe 'working with the migration_info table' do
324
- before do
325
- @adapter.stub!(:storage_exists?).and_return(true)
326
- # --- Please remove stubs ---
327
- @adapter.stub!(:quote_name).and_return { |name| "'#{name}'" }
328
321
  end
329
322
 
330
- describe '#update_migration_info' do
331
- it 'should add a record of the migration' do
332
- @m.should_receive(:execute).with(
333
- %Q{INSERT INTO 'migration_info' ('migration_name') VALUES ('do_nothing')}
334
- )
335
- @m.update_migration_info(:up)
323
+ describe 'working with the migration_info table' do
324
+ before do
325
+ @adapter.stub!(:storage_exists?).and_return(true)
326
+ # --- Please remove stubs ---
327
+ @adapter.stub!(:quote_name).and_return { |name| "'#{name}'" }
336
328
  end
337
329
 
338
- it 'should remove the record of the migration' do
339
- @m.should_receive(:execute).with(
340
- %Q{DELETE FROM 'migration_info' WHERE 'migration_name' = 'do_nothing'}
341
- )
342
- @m.update_migration_info(:down)
330
+ describe '#update_migration_info' do
331
+ it 'should add a record of the migration' do
332
+ @m.should_receive(:execute).with(
333
+ %Q{INSERT INTO 'migration_info' ('migration_name') VALUES ('do_nothing')}
334
+ )
335
+ @m.update_migration_info(:up)
336
+ end
337
+
338
+ it 'should remove the record of the migration' do
339
+ @m.should_receive(:execute).with(
340
+ %Q{DELETE FROM 'migration_info' WHERE 'migration_name' = 'do_nothing'}
341
+ )
342
+ @m.update_migration_info(:down)
343
+ end
344
+
345
+ it 'should try to create the migration_info table' do
346
+ @m.should_receive(:create_migration_info_table_if_needed)
347
+ @m.update_migration_info(:up)
348
+ end
343
349
  end
344
350
 
345
- it 'should try to create the migration_info table' do
346
- @m.should_receive(:create_migration_info_table_if_needed)
347
- @m.update_migration_info(:up)
351
+ describe '#create_migration_info_table_if_needed' do
352
+ it 'should create the migration info table' do
353
+ @m.should_receive(:migration_info_table_exists?).and_return(false)
354
+ @m.should_receive(:execute).with(
355
+ %Q{CREATE TABLE 'migration_info' ('migration_name' VARCHAR(255) UNIQUE)}
356
+ )
357
+ @m.create_migration_info_table_if_needed
358
+ end
359
+
360
+ it 'should not try to create the migration info table if it already exists' do
361
+ @m.should_receive(:migration_info_table_exists?).and_return(true)
362
+ @m.should_not_receive(:execute)
363
+ @m.create_migration_info_table_if_needed
364
+ end
348
365
  end
349
- end
350
366
 
351
- describe '#create_migration_info_table_if_needed' do
352
- it 'should create the migration info table' do
353
- @m.should_receive(:migration_info_table_exists?).and_return(false)
354
- @m.should_receive(:execute).with(
355
- %Q{CREATE TABLE 'migration_info' ('migration_name' VARCHAR(255) UNIQUE)}
356
- )
357
- @m.create_migration_info_table_if_needed
367
+ it 'should quote the name of the migration for use in sql' do
368
+ @m.quoted_name.should == %{'do_nothing'}
358
369
  end
359
370
 
360
- it 'should not try to create the migration info table if it already exists' do
361
- @m.should_receive(:migration_info_table_exists?).and_return(true)
362
- @m.should_not_receive(:execute)
363
- @m.create_migration_info_table_if_needed
371
+ it 'should query the adapter to see if the migration_info table exists' do
372
+ @adapter.should_receive(:storage_exists?).with('migration_info').and_return(true)
373
+ @m.migration_info_table_exists?.should == true
364
374
  end
365
- end
366
375
 
367
- it 'should quote the name of the migration for use in sql' do
368
- @m.quoted_name.should == %{'do_nothing'}
369
- end
376
+ describe '#migration_record' do
377
+ it 'should query for the migration' do
378
+ @adapter.should_receive(:select).with(
379
+ %Q{SELECT 'migration_name' FROM 'migration_info' WHERE 'migration_name' = 'do_nothing'}
380
+ )
381
+ @m.migration_record
382
+ end
370
383
 
371
- it 'should query the adapter to see if the migration_info table exists' do
372
- @adapter.should_receive(:storage_exists?).with('migration_info').and_return(true)
373
- @m.migration_info_table_exists?.should == true
374
- end
384
+ it 'should not try to query if the table does not exist' do
385
+ @m.stub!(:migration_info_table_exists?).and_return(false)
386
+ @adapter.should_not_receive(:select)
387
+ @m.migration_record
388
+ end
375
389
 
376
- describe '#migration_record' do
377
- it 'should query for the migration' do
378
- @adapter.should_receive(:select).with(
379
- %Q{SELECT 'migration_name' FROM 'migration_info' WHERE 'migration_name' = 'do_nothing'}
380
- )
381
- @m.migration_record
382
390
  end
383
391
 
384
- it 'should not try to query if the table does not exist' do
385
- @m.stub!(:migration_info_table_exists?).and_return(false)
386
- @adapter.should_not_receive(:select)
387
- @m.migration_record
388
- end
392
+ describe '#needs_up?' do
393
+ it 'should be true if there is no record' do
394
+ @m.should_receive(:migration_record).and_return([])
395
+ @m.needs_up?.should == true
396
+ end
389
397
 
390
- end
398
+ it 'should be false if the record exists' do
399
+ @m.should_receive(:migration_record).and_return([:not_empty])
400
+ @m.needs_up?.should == false
401
+ end
391
402
 
392
- describe '#needs_up?' do
393
- it 'should be true if there is no record' do
394
- @m.should_receive(:migration_record).and_return([])
395
- @m.needs_up?.should == true
396
- end
403
+ it 'should be true if there is no migration_info table' do
404
+ @m.should_receive(:migration_info_table_exists?).and_return(false)
405
+ @m.needs_up?.should == true
406
+ end
397
407
 
398
- it 'should be false if the record exists' do
399
- @m.should_receive(:migration_record).and_return([:not_empty])
400
- @m.needs_up?.should == false
401
408
  end
402
409
 
403
- it 'should be true if there is no migration_info table' do
404
- @m.should_receive(:migration_info_table_exists?).and_return(false)
405
- @m.needs_up?.should == true
406
- end
410
+ describe '#needs_down?' do
411
+ it 'should be false if there is no record' do
412
+ @m.should_receive(:migration_record).and_return([])
413
+ @m.needs_down?.should == false
414
+ end
407
415
 
408
- end
416
+ it 'should be true if the record exists' do
417
+ @m.should_receive(:migration_record).and_return([:not_empty])
418
+ @m.needs_down?.should == true
419
+ end
409
420
 
410
- describe '#needs_down?' do
411
- it 'should be false if there is no record' do
412
- @m.should_receive(:migration_record).and_return([])
413
- @m.needs_down?.should == false
414
- end
421
+ it 'should be false if there is no migration_info table' do
422
+ @m.should_receive(:migration_info_table_exists?).and_return(false)
423
+ @m.needs_down?.should == false
424
+ end
415
425
 
416
- it 'should be true if the record exists' do
417
- @m.should_receive(:migration_record).and_return([:not_empty])
418
- @m.needs_down?.should == true
419
426
  end
420
427
 
421
- it 'should be false if there is no migration_info table' do
422
- @m.should_receive(:migration_info_table_exists?).and_return(false)
423
- @m.needs_down?.should == false
428
+ it 'should have the adapter quote the migration_info table' do
429
+ @adapter.should_receive(:quote_name).with('migration_info').and_return("'migration_info'")
430
+ @m.migration_info_table.should == "'migration_info'"
424
431
  end
425
432
 
426
- end
427
-
428
- it 'should have the adapter quote the migration_info table' do
429
- @adapter.should_receive(:quote_name).with('migration_info').and_return("'migration_info'")
430
- @m.migration_info_table.should == "'migration_info'"
431
- end
433
+ it 'should have a quoted migration_name_column' do
434
+ @adapter.should_receive(:quote_name).with('migration_name').and_return("'migration_name'")
435
+ @m.migration_name_column.should == "'migration_name'"
436
+ end
432
437
 
433
- it 'should have a quoted migration_name_column' do
434
- @adapter.should_receive(:quote_name).with('migration_name').and_return("'migration_name'")
435
- @m.migration_name_column.should == "'migration_name'"
436
438
  end
437
439
 
438
440
  end
439
441
 
440
442
  end
441
-
442
443
  end
443
444
  end