using System.Reflection; using Omika.Data.HfSql.Metadata; using Omika.Data.HfSql.Models.Batik; using Omika.Data.Repositories.Batik; namespace Omika.Tests.Repositories; /// /// Test miroir Batik (non-régression) : vérifie que les colonnes référencées /// par les SELECT de existent dans les /// modèles physiques Batik. Miroir du garde-fou Omika. /// public class BatikRendezVousSqlConsistencyTests { public static IEnumerable Cases() { yield return [typeof(BatikRendezVousRepository), "SqlSelectRendezVousColumns", typeof(PlanningRDVRow)]; yield return [typeof(BatikRendezVousRepository), "SqlSelectPersonneColumns", typeof(PlanningRDVPersonneRow)]; yield return [typeof(BatikRendezVousRepository), "SqlSelectParametreMetierColumns", typeof(ParametreMetierRow)]; } [Theory] [MemberData(nameof(Cases))] public void ColonnesSelect_ExistentDansLeModelePhysique(Type repositoryType, string fieldName, Type rowType) { FieldInfo? field = repositoryType.GetField( fieldName, BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Public); Assert.True(field is not null, $"Champ « {fieldName} » introuvable dans {repositoryType.Name}."); string sql = (string)field!.GetRawConstantValue()!; var physicalColumns = new HashSet(StringComparer.OrdinalIgnoreCase); foreach (PropertyInfo property in rowType.GetProperties()) { HfSqlColumnAttribute? attr = property.GetCustomAttribute(); if (attr is not null) { physicalColumns.Add(attr.ColumnName); } } Assert.NotEmpty(physicalColumns); foreach (string column in sql.Split(',', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries)) { Assert.True( physicalColumns.Contains(column), $"{repositoryType.Name}.{fieldName} référence la colonne « {column} » absente du modèle {rowType.Name}."); } } }