Skip to content

Commit 65df148

Browse files
committed
Improve GetLabel fallback logic and add comprehensive tests
Refactored ScribanExtensions.GetLabel to enhance label resolution: it now prioritizes the requested language, then user-localized, and finally any non-empty label, avoiding empty or missing labels in generated code. Added ScribanExtensionsTests to cover these scenarios and updated documentation to clarify the fallback logic.
1 parent 910a163 commit 65df148

2 files changed

Lines changed: 89 additions & 1 deletion

File tree

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
namespace XrmTools.Tests.Xrm.Generators;
2+
3+
using FluentAssertions;
4+
using XrmTools.WebApi.Types;
5+
using XrmTools.Xrm.Generators;
6+
using Xunit;
7+
8+
public class ScribanExtensionsTests
9+
{
10+
[Fact]
11+
public void GetLabel_ReturnsRequestedLanguage_WhenPresent()
12+
{
13+
var label = new Label
14+
{
15+
LocalizedLabels =
16+
[
17+
new LocalizedLabel { LanguageCode = 1036, Label = "Statut" },
18+
new LocalizedLabel { LanguageCode = 1033, Label = "Status" },
19+
]
20+
};
21+
22+
ScribanExtensions.GetLabel(label, 1033).Should().Be("Status");
23+
}
24+
25+
[Fact]
26+
public void GetLabel_FallsBackToUserLocalizedLabel_WhenRequestedLanguageMissing()
27+
{
28+
var label = new Label
29+
{
30+
UserLocalizedLabel = new LocalizedLabel { LanguageCode = 1036, Label = "Statut" },
31+
LocalizedLabels =
32+
[
33+
new LocalizedLabel { LanguageCode = 1036, Label = "Statut" },
34+
]
35+
};
36+
37+
ScribanExtensions.GetLabel(label, 1033).Should().Be("Statut");
38+
}
39+
40+
[Fact]
41+
public void GetLabel_FallsBackToFirstNonEmptyLabel_WhenRequestedAndUserLabelMissing()
42+
{
43+
var label = new Label
44+
{
45+
UserLocalizedLabel = new LocalizedLabel { LanguageCode = 1036, Label = string.Empty },
46+
LocalizedLabels =
47+
[
48+
new LocalizedLabel { LanguageCode = 1036, Label = "Statut" },
49+
]
50+
};
51+
52+
ScribanExtensions.GetLabel(label, 1033).Should().Be("Statut");
53+
}
54+
55+
[Fact]
56+
public void GetLabel_ReturnsNull_WhenLabelIsNull()
57+
{
58+
ScribanExtensions.GetLabel(null, 1033).Should().BeNull();
59+
}
60+
61+
[Fact]
62+
public void GetLabel_ReturnsNull_WhenNoLabelsAvailable()
63+
{
64+
var label = new Label
65+
{
66+
UserLocalizedLabel = new LocalizedLabel { Label = string.Empty },
67+
LocalizedLabels = []
68+
};
69+
70+
ScribanExtensions.GetLabel(label, 1033).Should().BeNull();
71+
}
72+
}

src/XrmTools/Xrm/Generators/ScribanExtensions.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,24 @@ public static IEnumerable<EnumAttributeMetadata> FilterLocalEnumAttributes(this
147147

148148
public static bool IsEnumAttribute(AttributeMetadata a) => (a.AttributeType is AttributeTypeCode.Picklist or AttributeTypeCode.Virtual or AttributeTypeCode.State or AttributeTypeCode.Status or AttributeTypeCode.EntityName) && a.IsLogical == false;
149149

150+
/// <summary>
151+
/// Resolves a localized label for the requested language, falling back to the user-localized
152+
/// label (typically the environment base language) and then to any available non-empty label.
153+
/// This prevents empty identifiers/labels in generated code when an option set has no label for
154+
/// the requested language (e.g. no English/1033 label in a non-English environment).
155+
/// </summary>
150156
public static string? GetLabel(Label? label, int language)
151-
=> label?.LocalizedLabels?.FirstOrDefault(l => l.LanguageCode == language)?.Label;
157+
{
158+
if (label is null) return null;
159+
160+
var requested = label.LocalizedLabels?.FirstOrDefault(l => l.LanguageCode == language)?.Label;
161+
if (!string.IsNullOrEmpty(requested)) return requested;
162+
163+
var userLocalized = label.UserLocalizedLabel?.Label;
164+
if (!string.IsNullOrEmpty(userLocalized)) return userLocalized;
165+
166+
return label.LocalizedLabels?.FirstOrDefault(l => !string.IsNullOrEmpty(l.Label))?.Label;
167+
}
152168

153169
public static string EscapeVerbatim(string input)
154170
=> string.IsNullOrEmpty(input) ? string.Empty : input.Replace("\"", "\"\"");

0 commit comments

Comments
 (0)