using System.IO; using System.Reflection; using System.Text.RegularExpressions; using System.Xml.Linq; using Paca.App; using Paca.Browser; using Paca.Core.Config; namespace Paca.Tests.Infrastructure; /// /// 19차 UI 계약 검증 파이프라인 엔진: /// 단순 파일 문자열 검색의 취약점을 제거하고, XAML 파싱, 리소스 딕셔너리 검증, /// 타입/속성 리플렉션을 정밀하게 수행하여 UI 계약(Contract)을 파이프라인으로 일괄 검증한다. /// public static class UiContractPipeline { private static readonly Lazy _mainWindowDoc = new(() => XDocument.Load(SourceTree.AppPath("MainWindow.xaml"))); private static readonly Lazy _settingsDoc = new(() => XDocument.Load(SourceTree.AppPath("SettingsWindow.xaml"))); private static readonly Lazy _sharedDoc = new(() => XDocument.Load(SourceTree.AppPath("Themes/Shared.xaml"))); public static XDocument MainWindowDoc => _mainWindowDoc.Value; public static XDocument SettingsDoc => _settingsDoc.Value; public static XDocument SharedDoc => _sharedDoc.Value; /// XAML 내에 특정 x:Name 또는 Name 속성을 가진 요소가 존재하는지 검증 public static bool HasElementNamed(XDocument doc, string name) { return doc.Descendants().Any(e => (string?)e.Attribute("Name") == name || (string?)e.Attribute(XName.Get("Name", "http://schemas.microsoft.com/winfx/2006/xaml")) == name); } /// XAML 내에 특정 x:Key 리소스가 존재하는지 검증 public static bool HasResourceKey(XDocument doc, string key) { return doc.Descendants().Any(e => (string?)e.Attribute(XName.Get("Key", "http://schemas.microsoft.com/winfx/2006/xaml")) == key); } /// 타입 내에 명시된 속성이 존재하는지 검증 public static bool HasProperty(Type type, string propertyName) => type.GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static) != null; /// 타입 내에 명시된 메서드가 존재하는지 검증 public static bool HasMethod(Type type, string methodName) => type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static) .Any(m => m.Name == methodName); /// 유즈케이스 계약 어설션 파이프라인 public static void AssertContract(bool condition, string usecaseId, string message) { Xunit.Assert.True(condition, $"[계약 위반: {usecaseId}] {message}"); } }