55 lines
2.6 KiB
C#
55 lines
2.6 KiB
C#
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;
|
|
|
|
/// <summary>
|
|
/// 19차 UI 계약 검증 파이프라인 엔진:
|
|
/// 단순 파일 문자열 검색의 취약점을 제거하고, XAML 파싱, 리소스 딕셔너리 검증,
|
|
/// 타입/속성 리플렉션을 정밀하게 수행하여 UI 계약(Contract)을 파이프라인으로 일괄 검증한다.
|
|
/// </summary>
|
|
public static class UiContractPipeline
|
|
{
|
|
private static readonly Lazy<XDocument> _mainWindowDoc = new(() => XDocument.Load(SourceTree.AppPath("MainWindow.xaml")));
|
|
private static readonly Lazy<XDocument> _settingsDoc = new(() => XDocument.Load(SourceTree.AppPath("SettingsWindow.xaml")));
|
|
private static readonly Lazy<XDocument> _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;
|
|
|
|
/// <summary>XAML 내에 특정 x:Name 또는 Name 속성을 가진 요소가 존재하는지 검증</summary>
|
|
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);
|
|
}
|
|
|
|
/// <summary>XAML 내에 특정 x:Key 리소스가 존재하는지 검증</summary>
|
|
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);
|
|
}
|
|
|
|
/// <summary>타입 내에 명시된 속성이 존재하는지 검증</summary>
|
|
public static bool HasProperty(Type type, string propertyName)
|
|
=> type.GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static) != null;
|
|
|
|
/// <summary>타입 내에 명시된 메서드가 존재하는지 검증</summary>
|
|
public static bool HasMethod(Type type, string methodName)
|
|
=> type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)
|
|
.Any(m => m.Name == methodName);
|
|
|
|
/// <summary>유즈케이스 계약 어설션 파이프라인</summary>
|
|
public static void AssertContract(bool condition, string usecaseId, string message)
|
|
{
|
|
Xunit.Assert.True(condition, $"[계약 위반: {usecaseId}] {message}");
|
|
}
|
|
}
|