package com.nanri.aiimage.config; import org.junit.jupiter.api.Test; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import static org.junit.jupiter.api.Assertions.assertTrue; /** * task-192:迁移规范模板契约。 * docs/flyway-migration-template.md 存在且六项必填(目的/影响表与数据量/锁表风险/验证 SQL/ * 回滚步骤/上线窗口)齐全,含示例 SQL,可被新迁移文件头注释引用。 */ class FlywayMigrationTemplateDocTest { private static final String DOC = "docs/flyway-migration-template.md"; private String doc() throws IOException { return Files.readString(Path.of(System.getProperty("user.dir"), DOC)); } @Test void templateExists() throws IOException { assertTrue(Files.exists(Path.of(System.getProperty("user.dir"), DOC)), "模板文件应存在"); } @Test void sixMandatoryFieldsPresent() throws IOException { String text = doc(); for (int i = 1; i <= 6; i++) { assertTrue(text.contains(i + ". "), "头注释应含第 " + i + " 项必填"); } } @Test void fieldNamesListed() throws IOException { String text = doc(); assertTrue(text.contains("变更目的")); assertTrue(text.contains("影响表与数据量")); assertTrue(text.contains("锁表风险")); assertTrue(text.contains("验证 SQL")); assertTrue(text.contains("回滚步骤")); assertTrue(text.contains("上线窗口")); } @Test void hasCopyableHeaderComment() throws IOException { assertTrue(doc().contains("复制以下头注释"), "模板应提供可复制头注释"); assertTrue(doc().contains("V{N+1}__"), "头注释示例应含占位版本号"); } @Test void hasValidationSqlExample() throws IOException { assertTrue(doc().contains("SELECT COUNT(*)"), "应含验证 SQL 示例"); } @Test void hasRollbackField() throws IOException { assertTrue(doc().contains("回滚步骤"), "应含回滚步骤说明"); } @Test void hasUpgradeWindowField() throws IOException { assertTrue(doc().contains("上线窗口"), "应含上线窗口说明"); } @Test void templateUsableByNewMigrations() throws IOException { String text = doc(); assertTrue(text.contains("src/main/resources/db/"), "应说明迁移文件目录"); assertTrue(text.contains("只追加"), "应强调只追加不改历史"); assertTrue(text.contains("V109") || text.contains("最大现有版本"), "应说明版本号取最大现有版本+1"); } }