using System.Linq; using QuantEngine.Infrastructure.Data; namespace QuantEngine.Core.Tests; public class MigrationScriptNameComparerTests { [Fact] public void Sorts_DoubleDigit_Version_After_SingleDigit_Versions() { var scripts = new[] { "QuantEngine.Infrastructure.Migrations.V10__Normalize_Snapshots_Schema.sql", "QuantEngine.Infrastructure.Migrations.V2__Add_Kis_Collections.sql", "QuantEngine.Infrastructure.Migrations.V9__Add_Audit_Trail_Tables.sql", "QuantEngine.Infrastructure.Migrations.V1__Initial_Schema.sql", "QuantEngine.Infrastructure.Migrations.V8__PostgreSQL_History_First_Schema.sql", }; var sorted = scripts.OrderBy(s => s, new MigrationScriptNameComparer()).ToArray(); Assert.Equal(new[] { "QuantEngine.Infrastructure.Migrations.V1__Initial_Schema.sql", "QuantEngine.Infrastructure.Migrations.V2__Add_Kis_Collections.sql", "QuantEngine.Infrastructure.Migrations.V8__PostgreSQL_History_First_Schema.sql", "QuantEngine.Infrastructure.Migrations.V9__Add_Audit_Trail_Tables.sql", "QuantEngine.Infrastructure.Migrations.V10__Normalize_Snapshots_Schema.sql", }, sorted); } [Fact] public void Regression_ZeroPadded_Script_No_Longer_Sorts_Before_V1() { // This is the exact bug that shipped 2026-07-24: "V003_..." sorted before "V1__..." // under plain ordinal comparison, so a migration with unmet table dependencies ran // first. The comparer must treat "V003" as version 3, landing it between V2 and V4. var scripts = new[] { "QuantEngine.Infrastructure.Migrations.V003_add_audit_trail_tables.sql", "QuantEngine.Infrastructure.Migrations.V1__Initial_Schema.sql", "QuantEngine.Infrastructure.Migrations.V4__Add_Initial_Admin.sql", }; var sorted = scripts.OrderBy(s => s, new MigrationScriptNameComparer()).ToArray(); Assert.Equal("QuantEngine.Infrastructure.Migrations.V1__Initial_Schema.sql", sorted[0]); Assert.Equal("QuantEngine.Infrastructure.Migrations.V003_add_audit_trail_tables.sql", sorted[1]); Assert.Equal("QuantEngine.Infrastructure.Migrations.V4__Add_Initial_Admin.sql", sorted[2]); } }