using System.Reflection; using AtomUI.Desktop.Controls.Localization; using AtomUI.Localization; using Avalonia; using Shouldly; using Xunit; namespace AtomUI.Desktop.Controls.Tests.Localization; public class DesktopCatalogCoverageTests { static DesktopCatalogCoverageTests() { AvaloniaTestApp.EnsureInitialized(); } [Fact] public void Calendar_Catalog_Preserves_All_Translations() { AssertCatalog( "AtomUI.Desktop.Controls.CalendarControlLang", new ExpectedEntry(CalendarControlLangResourceKind.Month, "Month", "月", "月"), new ExpectedEntry(CalendarControlLangResourceKind.Year, "Year", "年", "年"), new ExpectedEntry(CalendarControlLangResourceKind.YearSuffix, "", "年", "年"), new ExpectedEntry(CalendarControlLangResourceKind.Week, "Week", "周", "週")); } [Fact] public void DatePicker_Catalog_Preserves_All_Translations() { AssertCatalog( "AtomUI.Desktop.Controls.DatePickerLang", new ExpectedEntry(DatePickerLangResourceKind.Today, "Today", "今天", "今天"), new ExpectedEntry(DatePickerLangResourceKind.Now, "Now", "现在", "現在")); } [Fact] public void Dialog_Catalog_Preserves_All_Translations() { AssertCatalog( "AtomUI.Desktop.Controls.DialogLang", new ExpectedEntry(DialogLangResourceKind.Ok, "OK", "确定", "確定"), new ExpectedEntry(DialogLangResourceKind.Open, "Open", "打开", "打開"), new ExpectedEntry(DialogLangResourceKind.Save, "Save", "保存", "保存"), new ExpectedEntry(DialogLangResourceKind.Cancel, "Cancel", "取消", "取消"), new ExpectedEntry(DialogLangResourceKind.Close, "Close", "关闭", "關閉"), new ExpectedEntry(DialogLangResourceKind.Discard, "Discard", "丢弃", "丟棄"), new ExpectedEntry(DialogLangResourceKind.Apply, "Apply", "应用", "應用"), new ExpectedEntry(DialogLangResourceKind.Reset, "Reset", "重置", "重置"), new ExpectedEntry(DialogLangResourceKind.Reload, "Reload", "重新加载", "重新加載"), new ExpectedEntry(DialogLangResourceKind.RestoreDefaults, "Restore Defaults", "恢复默认值", "恢復默認值"), new ExpectedEntry(DialogLangResourceKind.Help, "Help", "帮助", "幫助"), new ExpectedEntry(DialogLangResourceKind.SaveAll, "Save All", "全部保存", "全部保存"), new ExpectedEntry(DialogLangResourceKind.Yes, "Yes", "是", "是"), new ExpectedEntry(DialogLangResourceKind.YesToAll, "Yes to All", "全部是", "全部是"), new ExpectedEntry(DialogLangResourceKind.No, "No", "否", "否"), new ExpectedEntry(DialogLangResourceKind.NoToAll, "No to All", "全部否", "全部否"), new ExpectedEntry(DialogLangResourceKind.Abort, "Abort", "中止", "中止"), new ExpectedEntry(DialogLangResourceKind.Retry, "Retry", "重试", "重試"), new ExpectedEntry(DialogLangResourceKind.Ignore, "Ignore", "忽略", "忽略")); } [Fact] public void ImagePreviewer_Catalog_Preserves_All_Translations() { AssertCatalog( "AtomUI.Desktop.Controls.ImagePreviewerLang", new ExpectedEntry(ImagePreviewerLangResourceKind.ImageLoadFailed, "Image load failed", "图片加载失败", "圖片載入失敗"), new ExpectedEntry(ImagePreviewerLangResourceKind.Preview, "Preview", "预览", "預覽")); } [Fact] public void Pagination_Catalog_Preserves_All_Translations() { AssertCatalog( "AtomUI.Desktop.Controls.PaginationLang", new ExpectedEntry(PaginationLangResourceKind.JumpToText, "Go to", "跳至", "跳至"), new ExpectedEntry(PaginationLangResourceKind.PageText, "Page", "页", "頁"), new ExpectedEntry(PaginationLangResourceKind.TotalInfoFormat, "Total ${Total} items", "共 ${Total} 项", "共 ${Total} 項")); } [Fact] public void QRCode_Catalog_Preserves_All_Translations() { AssertCatalog( "AtomUI.Desktop.Controls.QRCodeLang", new ExpectedEntry(QRCodeLangResourceKind.Refresh, "Refresh", "点击刷新", "點擊刷新"), new ExpectedEntry(QRCodeLangResourceKind.Expired, "QR code expired", "二维码过期", "二維碼過期"), new ExpectedEntry(QRCodeLangResourceKind.Scanned, "Scanned", "已扫描", "已掃描")); } [Fact] public void TimePicker_Catalog_Preserves_All_Translations() { AssertCatalog( "AtomUI.Desktop.Controls.TimePickerLang", new ExpectedEntry(TimePickerLangResourceKind.AMText, "AM", "上午", "上午"), new ExpectedEntry(TimePickerLangResourceKind.PMText, "PM", "下午", "下午"), new ExpectedEntry(TimePickerLangResourceKind.Now, "Now", "现在", "現在")); } [Fact] public void Tour_Catalog_Preserves_All_Translations() { AssertCatalog( "AtomUI.Desktop.Controls.TourLang", new ExpectedEntry(TourLangResourceKind.Previous, "Previous", "上一步", "上一步"), new ExpectedEntry(TourLangResourceKind.Next, "Next", "下一步", "下一步"), new ExpectedEntry(TourLangResourceKind.Finish, "Finish", "结束导览", "結束導覽")); } [Fact] public void Transfer_Catalog_Preserves_All_Translations() { AssertCatalog( "AtomUI.Desktop.Controls.TransferLang", new ExpectedEntry(TransferLangResourceKind.Item, "item", "项", "項"), new ExpectedEntry(TransferLangResourceKind.Items, "items", "项", "項"), new ExpectedEntry(TransferLangResourceKind.SelectAll, "select all data", "全选所有", "全選所有"), new ExpectedEntry(TransferLangResourceKind.DeSelectAll, "deselect all data", "取消全选", "取消全選"), new ExpectedEntry(TransferLangResourceKind.RemoveCurrentPage, "remove current page", "删除当页", "刪除當頁"), new ExpectedEntry(TransferLangResourceKind.RemoveAll, "remove all data", "删除所有", "刪除所有"), new ExpectedEntry(TransferLangResourceKind.InvertSelectCurrentPage, "invert current page", "反选当页", "反選當頁"), new ExpectedEntry(TransferLangResourceKind.SelectCurrentPage, "select current page", "选择当页", "選擇當頁")); } [Fact] public void Upload_Catalog_Preserves_All_Translations() { AssertCatalog( "AtomUI.Desktop.Controls.UploadLang", new ExpectedEntry(UploadLangResourceKind.Uploading, "Uploading...", "上传中...", "上傳中..."), new ExpectedEntry(UploadLangResourceKind.Pending, "Pending...", "等待调度...", "等待調度..."), new ExpectedEntry(UploadLangResourceKind.DragUploadHead, "Click or drag file to this area to upload", "点击或拖动文件到此区域进行上传", "點擊或拖動文件到此區域進行上傳")); } [Fact] public void ColorPicker_Catalog_Preserves_All_Translations() { AssertCatalog( "AtomUI.Desktop.Controls.ColorPickerLang", new ExpectedEntry(ColorPickerLangResourceKind.EmptyColorText, "Transparent", "无色", "無色")); } private static void AssertCatalog( string legacyProviderNamespace, params ExpectedEntry[] expected) where TResourceKind : struct, Enum { var resourceKindType = typeof(TResourceKind); resourceKindType.GetCustomAttribute().ShouldNotBeNull(); Enum.GetNames().ShouldBe( expected.Select(static entry => entry.Kind.ToString())); var extensionName = resourceKindType.Name.EndsWith("Kind", StringComparison.Ordinal) ? resourceKindType.Name[..^"Kind".Length] + "Extension" : resourceKindType.Name + "Extension"; var extensionType = resourceKindType.Assembly.GetType( $"{resourceKindType.Namespace}.{extensionName}").ShouldNotBeNull(); extensionType.IsSealed.ShouldBeTrue(); extensionType.BaseType.ShouldBe(typeof(LanguageResourceExtension)); var application = Application.Current.ShouldNotBeNull(); var languageManager = application.GetLanguageManager().ShouldNotBeNull(); var localizer = application.GetLocalizer().ShouldNotBeNull(); AssertLanguage(LanguageTags.EnUS, expected.Select(static entry => (entry.Kind, entry.En)), languageManager, localizer); AssertLanguage(LanguageTags.ZhCN, expected.Select(static entry => (entry.Kind, entry.ZhCn)), languageManager, localizer); AssertLanguage(LanguageTags.ZhTW, expected.Select(static entry => (entry.Kind, entry.ZhTw)), languageManager, localizer); resourceKindType.Assembly.GetType($"{legacyProviderNamespace}.en_US").ShouldBeNull(); resourceKindType.Assembly.GetType($"{legacyProviderNamespace}.zh_CN").ShouldBeNull(); resourceKindType.Assembly.GetType($"{legacyProviderNamespace}.zh_TW").ShouldBeNull(); } private static void AssertLanguage( LanguageTag language, IEnumerable<(TResourceKind Kind, string Text)> expected, ILanguageManager languageManager, ILocalizer localizer) where TResourceKind : struct, Enum { languageManager.ChangeLanguage(language); foreach (var (kind, text) in expected) { localizer.Get(kind).ShouldBe(text); } } private readonly record struct ExpectedEntry( TResourceKind Kind, string En, string ZhCn, string ZhTw) where TResourceKind : struct, Enum; }