public void TestMigration1()
        {
            // Arrange
            MigrationDescription[] migrations = new MigrationDescription[]
            {
                new MigrationDescription {
                    MigrationID = 101, MigrationSql = @"INSERT INTO dbo.Messages(MessageText) VALUES('Ran migration 101')"
                }
            };

            MoqMigrationUtils utils = new MoqMigrationUtils(migrations);

            using (IDbConnection db = new SqlConnection(config.ConnectionString))
            {
                MigrationRunner <int> runner = new MigrationRunner <int>(db, utils);

                // Act
                runner.BringToVersion(101);

                // Assert
                // Check messages (this ensures that the migration itself is run)
                string[] messages = db.Query <Message>("Select * From Messages").Select(x => x.MessageText).ToArray();

                messages.Should().HaveCount(1);
                messages[0].Should().Be("Ran migration 101");

                // Check that the Migrations table was updated (this ensures that othe SetDBVersionQuery is run)
                MigrationHistory[] dbMigrations = db.Query <MigrationHistory>("Select * From MigrationHistories").ToArray();

                dbMigrations.Select(x => x.MigrationID).Should().BeEquivalentTo(new int[] { 100, -101, 101 });

                dbMigrations.Single(x => x.MigrationID == 101).UpdateUTC.Should().Be(utils.TimeVersionLastSet);
            }
        }
        public void TestMigration_ExceptionsShouldCauseRollback()
        {
            using (IDbConnection db = new SqlConnection(config.ConnectionString))
            {
                // Arrange
                DBUtils.AddMessage(db, "Message added before migration");

                MigrationDescription[] migrations = new MigrationDescription[]
                {
                    new MigrationDescription {
                        MigrationID = 101, MigrationSql =
                            @"INSERT INTO dbo.Messages(MessageText) VALUES('This should be rolled back');
                          SELECT * from dbo.UNKNOWNTABLE;"         // SQL error
                    }
                };

                MoqMigrationUtils utils = new MoqMigrationUtils(migrations);

                MigrationRunner <int> runner = new MigrationRunner <int>(db, utils);

                // Act
                runner.BringToVersion(101);

                // Assert
                // Check messages (this ensures that the migration itself is run)
                string[] messages = db.Query <Message>("Select * From Messages order by MessageID").Select(x => x.MessageText).ToArray();

                messages.Should().BeEquivalentTo(new string[]
                {
                    "Message added before migration"
                    // Note the message 'This should be rolled back' added during the migration should not appear
                });
            }
        }
        public void TestMigration_ShouldLogAllExecutedBatches()
        {
            using (IDbConnection db = new SqlConnection(config.ConnectionString))
            {
                // Arrange
                MigrationDescription[] migrations = new MigrationDescription[]
                {
                    new MigrationDescription {
                        MigrationID = 101, MigrationSql =
                            "INSERT INTO dbo.Messages(MessageText) VALUES('Batch 1');\n" +    // 1 row affected
                            "GO\n" +
                            "INSERT INTO dbo.Messages(MessageText) VALUES('Batch 2');\n" +    // 1 row affected
                            "GO\n" +
                            "Update dbo.Messages set MessageText = 'updated message'\n"       // 2 rows affected
                    }
                };

                MoqMigrationUtils utils = new MoqMigrationUtils(migrations);

                MigrationRunner <int> runner = new MigrationRunner <int>(db, utils);

                // Act
                runner.BringToVersion(101);

                // Assert
                utils.ExecutingBatches.Should().HaveCount(3);        // 3 batches

                utils.ExecutingBatches[0].ExecutedSql.Should().Be("INSERT INTO dbo.Messages(MessageText) VALUES('Batch 1');");
                utils.ExecutingBatches[1].ExecutedSql.Should().Be("INSERT INTO dbo.Messages(MessageText) VALUES('Batch 2');");
                utils.ExecutingBatches[2].ExecutedSql.Should().Be("Update dbo.Messages set MessageText = 'updated message'");

                utils.ExecutingBatches.Select(x => x.BatchNumber).ShouldBeEquivalentTo(new int[] { 1, 2, 3 }, options => options.WithStrictOrdering());
            }
        }
        public void TestMigration_ExceptionsShouldBeLogged()
        {
            MigrationDescription[] migrations = new MigrationDescription[]
            {
                new MigrationDescription {
                    MigrationID = 101, MigrationSql =
                        @"SELECT * from dbo.UNKNOWNTABLE;"
                }
            };

            MoqMigrationUtils utils = new MoqMigrationUtils(migrations);

            using (IDbConnection db = new SqlConnection(config.ConnectionString))
            {
                MigrationRunner <int> runner = new MigrationRunner <int>(db, utils);

                // Act
                runner.BringToVersion(101);

                // Assert
                utils.LastErrorMessage.Should().BeEquivalentTo("Invalid object name 'dbo.UNKNOWNTABLE'.");
            }
        }
        public void TestMigration_ShouldExcludeComments()
        {
            MigrationDescription[] migrations = new MigrationDescription[]
            {
                new MigrationDescription {
                    MigrationID = 101, MigrationSql =
                        @"INSERT INTO dbo.Messages(MessageText) VALUES('Message 1');
                      --INSERT INTO dbo.Messages(MessageText) VALUES('Should not appear 1');
                      /*
                         INSERT INTO dbo.Messages(MessageText) VALUES('Should not appear 1');
                         INSERT INTO dbo.Messages(MessageText) VALUES('Should not appear 2');
                       */
                       INSERT INTO dbo.Messages(MessageText) VALUES('Message 2');
                     "
                }
            };

            MoqMigrationUtils utils = new MoqMigrationUtils(migrations);

            using (IDbConnection db = new SqlConnection(config.ConnectionString))
            {
                MigrationRunner <int> runner = new MigrationRunner <int>(db, utils);

                // Act
                runner.BringToVersion(101);

                // Assert
                // Check messages (this ensures that the migration itself is run)
                string[] messages = db.Query <Message>("Select * From Messages order by MessageID").Select(x => x.MessageText).ToArray();

                messages.Should().BeEquivalentTo(new string[]
                {
                    "Message 1",
                    "Message 2"
                });
            }
        }