using System.Reflection; using Omika.Core.Observability; namespace Omika.Tests.Observability; /// /// Contrat structurel de la façade d'observabilité : les méthodes exposées au /// métier sont strictement void (never-throw, non bloquantes, sans await). /// Aucune méthode Task ...Async ne doit apparaître. /// public class ObservabilityContractTests { [Fact] public void AllTelemetryInterfaces_ExposeOnlyVoidMethods() { Type[] interfaces = [typeof(IOmikaTelemetry), typeof(IEventTracker), typeof(IDiagnosticLogger)]; foreach (Type type in interfaces) { foreach (MethodInfo method in type.GetMethods()) { Assert.True( method.ReturnType == typeof(void), $"{type.Name}.{method.Name} doit retourner void (jamais Task)."); } } } [Fact] public void NoAsyncTrackOrLogMethod_IsExposed() { MethodInfo[] methods = typeof(IEventTracker).GetMethods() .Concat(typeof(IDiagnosticLogger).GetMethods()) .Concat(typeof(IOmikaTelemetry).GetMethods()) .ToArray(); Assert.DoesNotContain(methods, m => m.Name.EndsWith("Async", StringComparison.Ordinal)); } [Fact] public void EventTracker_ExposesTrack_ReturningVoid() { MethodInfo track = typeof(IEventTracker).GetMethod(nameof(IEventTracker.Track))!; Assert.NotNull(track); Assert.Equal(typeof(void), track.ReturnType); Assert.Equal(typeof(TelemetryEvent), track.GetParameters().Single().ParameterType); } [Fact] public void DiagnosticLogger_ExposesLog_ReturningVoid() { MethodInfo log = typeof(IDiagnosticLogger).GetMethod(nameof(IDiagnosticLogger.Log))!; Assert.NotNull(log); Assert.Equal(typeof(void), log.ReturnType); Assert.Equal(typeof(DiagnosticEvent), log.GetParameters().Single().ParameterType); } }