require File.join(File.dirname(__FILE__), 'spec_helper') context "Migration classes" do setup do Sequel::Migration.descendants.clear end specify "should be registred in Migration.descendants" do @class = Class.new(Sequel::Migration) Sequel::Migration.descendants.should == [@class] end specify "should be registered in the right order" do @c1 = Class.new(Sequel::Migration) @c2 = Class.new(Sequel::Migration) @c3 = Class.new(Sequel::Migration) Sequel::Migration.descendants.should == [@c1, @c2, @c3] end end context "Migration#apply" do setup do @c = Class.new do define_method(:one) {|x| [1111, x]} define_method(:two) {|x| [2222, x]} end @db = @c.new @migration = Class.new(Sequel::Migration) do define_method(:up) {one(3333)} define_method(:down) {two(4444)} end end specify "should raise for an invalid direction" do proc {@migration.apply(@db, :hahaha)}.should raise_error(SequelError) end specify "should apply the up direction correctly" do @migration.apply(@db, :up).should == [1111, 3333] end specify "should apply the down direction correctly" do @migration.apply(@db, :down).should == [2222, 4444] end end class DummyMigrationDataset attr_reader :from def initialize(x); @from = x; end @@version = nil def version; @@version; end def version=(x); @@version = x; end def first; @@version ? {:version => @@version} : nil; end def update(h); @@version = h[:version]; end def <<(h); @@version = h[:version]; end end class DummyMigrationDB attr_reader :creates, :drops, :table_created def initialize @creates = [] @drops = [] end def create(x); @creates << x; end def drop(x); @drops << x; end def [](x); DummyMigrationDataset.new(x); end def create_table(x); raise if @table_created == x; @table_created = x; end def table_exists?(x); @table_created == x; end def transaction; yield; end end MIGRATION_001 = %[ class CreateSessions < Sequel::Migration def up create(1111) end def down drop(1111) end end ] MIGRATION_002 = %[ class CreateNodes < Sequel::Migration def up create(2222) end def down drop(2222) end end ] MIGRATION_003 = %[ class CreateUsers < Sequel::Migration def up create(3333) end def down drop(3333) end end ] MIGRATION_005 = %[ class CreateAttributes < Sequel::Migration def up create(5555) end def down drop(5555) end end ] context "Sequel::Migrator" do setup do @db = DummyMigrationDB.new File.open('001_create_sessions.rb', 'w') {|f| f << MIGRATION_001} File.open('002_create_nodes.rb', 'w') {|f| f << MIGRATION_002} File.open('003_create_users.rb', 'w') {|f| f << MIGRATION_003} File.open('005_create_attributes.rb', 'w') {|f| f << MIGRATION_005} @db[:schema_info].version = nil end teardown do Object.send(:remove_const, "CreateSessions") if Object.const_defined?("CreateSessions") Object.send(:remove_const, "CreateNodes") if Object.const_defined?("CreateNodes") Object.send(:remove_const, "CreateUsers") if Object.const_defined?("CreateUsers") Object.send(:remove_const, "CreateAttributes") if Object.const_defined?("CreateAttributes") FileUtils.rm('001_create_sessions.rb') FileUtils.rm('002_create_nodes.rb') FileUtils.rm('003_create_users.rb') FileUtils.rm('005_create_attributes.rb') end specify "should return the list of files for a specified version range" do Sequel::Migrator.migration_files('.', 1..1).should == \ ['./001_create_sessions.rb'] Sequel::Migrator.migration_files('.', 1..3).should == \ ['./001_create_sessions.rb', './002_create_nodes.rb', './003_create_users.rb'] Sequel::Migrator.migration_files('.', 3..5).should == \ ['./003_create_users.rb', './005_create_attributes.rb'] Sequel::Migrator.migration_files('.', 7..8).should == [] end specify "should return the latest version available" do Sequel::Migrator.latest_migration_version('.').should == 5 end specify "should load the migration classes for the specified range" do Sequel::Migrator.migration_classes('.', 3, 0, :up).should == \ [CreateSessions, CreateNodes, CreateUsers] end specify "should load the migration classes for the specified range" do Sequel::Migrator.migration_classes('.', 0, 5, :down).should == \ [CreateAttributes, CreateUsers, CreateNodes, CreateSessions] end specify "should start from current + 1 for the up direction" do Sequel::Migrator.migration_classes('.', 3, 1, :up).should == \ [CreateNodes, CreateUsers] end specify "should end on current + 1 for the down direction" do Sequel::Migrator.migration_classes('.', 2, 5, :down).should == \ [CreateAttributes, CreateUsers] end specify "should automatically create the schema_info table" do @db.table_exists?(:schema_info).should be_false Sequel::Migrator.schema_info_dataset(@db) @db.table_exists?(:schema_info).should be_true # should not raise if table already exists proc {Sequel::Migrator.schema_info_dataset(@db)}.should_not raise_error end specify "should return a dataset for the schema_info table" do d = Sequel::Migrator.schema_info_dataset(@db) d.from.should == :schema_info end specify "should get the migration version stored in the database" do # default is 0 Sequel::Migrator.get_current_migration_version(@db).should == 0 Sequel::Migrator.schema_info_dataset(@db) << {:version => 4321} Sequel::Migrator.get_current_migration_version(@db).should == 4321 end specify "should set the migration version stored in the database" do Sequel::Migrator.get_current_migration_version(@db).should == 0 Sequel::Migrator.set_current_migration_version(@db, 6666) Sequel::Migrator.get_current_migration_version(@db).should == 6666 end specify "should apply migrations correctly in the up direction" do Sequel::Migrator.apply(@db, '.', 3, 2) @db.creates.should == [3333] Sequel::Migrator.get_current_migration_version(@db).should == 3 Sequel::Migrator.apply(@db, '.', 5) @db.creates.should == [3333, 5555] Sequel::Migrator.get_current_migration_version(@db).should == 5 end specify "should apply migrations correctly in the down direction" do Sequel::Migrator.apply(@db, '.', 1, 5) @db.drops.should == [5555, 3333, 2222] Sequel::Migrator.get_current_migration_version(@db).should == 1 end specify "should apply migrations up to the latest version if no target is given" do Sequel::Migrator.apply(@db, '.') @db.creates.should == [1111, 2222, 3333, 5555] Sequel::Migrator.get_current_migration_version(@db).should == 5 end specify "should apply migrations down to 0 version correctly" do Sequel::Migrator.apply(@db, '.', 0, 5) @db.drops.should == [5555, 3333, 2222, 1111] Sequel::Migrator.get_current_migration_version(@db).should == 0 end specify "should return the target version" do Sequel::Migrator.apply(@db, '.', 3, 2).should == 3 Sequel::Migrator.apply(@db, '.', 0).should == 0 Sequel::Migrator.apply(@db, '.').should == 5 end end