Skip to content

Commit 0a0d474

Browse files
shanselmanCopilot
andcommitted
Add XAML localization resource regression coverage
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent ef6ac8a commit 0a0d474

2 files changed

Lines changed: 58 additions & 1 deletion

File tree

src/OpenClaw.Tray.WinUI/Pages/AgentEventsPage.xaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
<StackPanel Orientation="Horizontal" Spacing="8">
5353
<FontIcon Glyph="{x:Bind helpers:FluentIconCatalog.Clear, Mode=OneTime}"
5454
FontSize="14" IsTextScaleFactorEnabled="False"/>
55-
<TextBlock x:Uid="ClearButton" Text="Clear"/>
55+
<TextBlock Text="Clear"/>
5656
</StackPanel>
5757
</Button>
5858
</Grid>

tests/OpenClaw.Tray.Tests/LocalizationValidationTests.cs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@ public class LocalizationValidationTests
2323
"Title",
2424
};
2525

26+
private static readonly IReadOnlyDictionary<string, HashSet<string>> SupportedLocalizablePropertiesByElement =
27+
new Dictionary<string, HashSet<string>>(StringComparer.Ordinal)
28+
{
29+
["TextBlock"] = new(StringComparer.Ordinal) { "Text" },
30+
};
31+
2632
private static readonly HashSet<string> InvariantOrDeferredResourceKeys = new(StringComparer.Ordinal)
2733
{
2834
"AboutPage_TextBlock_19.Text",
@@ -366,6 +372,57 @@ public void XamlControlsWithXUid_HaveMatchingEnUsResources()
366372
string.Join("; ", missing.Take(50)));
367373
}
368374

375+
[Fact]
376+
public void XamlControlsWithXUid_DoNotUseUnsupportedLocalizationProperties()
377+
{
378+
var winUiRoot = Path.Combine(GetRepositoryRoot(), "src", "OpenClaw.Tray.WinUI");
379+
var resourceKeys = LoadResw(Path.Combine(GetStringsDirectory(), "en-us", "Resources.resw"))
380+
.Keys
381+
.ToList();
382+
var invalid = new List<string>();
383+
384+
foreach (var xamlPath in Directory.EnumerateFiles(winUiRoot, "*.xaml", SearchOption.AllDirectories)
385+
.Where(IsSourceXaml)
386+
.OrderBy(p => p, StringComparer.OrdinalIgnoreCase))
387+
{
388+
var relativePath = Path.GetRelativePath(GetRepositoryRoot(), xamlPath);
389+
var doc = XDocument.Load(xamlPath, LoadOptions.SetLineInfo);
390+
391+
foreach (var element in doc.Descendants())
392+
{
393+
var elementName = element.Name.LocalName;
394+
var uid = element.Attribute(XamlNamespace + "Uid")?.Value;
395+
if (string.IsNullOrWhiteSpace(uid) ||
396+
!SupportedLocalizablePropertiesByElement.TryGetValue(elementName, out var supportedProperties))
397+
{
398+
continue;
399+
}
400+
401+
var resourcePrefix = $"{uid}.";
402+
foreach (var key in resourceKeys.Where(k => k.StartsWith(resourcePrefix, StringComparison.Ordinal)))
403+
{
404+
var propertyName = key[resourcePrefix.Length..];
405+
if (!LocalizableXamlAttributes.Contains(propertyName) ||
406+
supportedProperties.Contains(propertyName))
407+
{
408+
continue;
409+
}
410+
411+
var line = element is IXmlLineInfo lineInfo && lineInfo.HasLineInfo()
412+
? lineInfo.LineNumber
413+
: 0;
414+
invalid.Add(
415+
$"{relativePath}:{line} {elementName} x:Uid=\"{uid}\" cannot use resource '{key}'. " +
416+
$"Supported localizable properties: {string.Join(", ", supportedProperties.OrderBy(p => p, StringComparer.Ordinal))}");
417+
}
418+
}
419+
}
420+
421+
Assert.True(invalid.Count == 0,
422+
"XAML localization resources must target properties that exist on the x:Uid element. Invalid: " +
423+
string.Join("; ", invalid.Take(50)));
424+
}
425+
369426
private static bool IsSourceXaml(string path)
370427
{
371428
var relative = Path.GetRelativePath(GetRepositoryRoot(), path);

0 commit comments

Comments
 (0)