Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

run writingsystem tests against dotnet 8 to show a bug in the integration between icu.net and SIL.WritingSystems #1330

Closed
2 changes: 1 addition & 1 deletion SIL.Core/Reflection/ReflectionHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,7 @@ public static string LongVersionNumberString
}

private static readonly bool RunningFromUnitTest = AppDomain.CurrentDomain.GetAssemblies()
.Any(assem =>
.Any(assem =>
assem.FullName.StartsWith("nunit.framework", StringComparison.OrdinalIgnoreCase)
|| assem.FullName.StartsWith("Microsoft.VisualStudio.QualityTools.UnitTestFramework", StringComparison.OrdinalIgnoreCase)
|| assem.FullName.StartsWith("Microsoft.VisualStudio.TestPlatform.TestFramework", StringComparison.OrdinalIgnoreCase)
Expand Down
11 changes: 11 additions & 0 deletions SIL.WritingSystems.Tests/AddSortKeysToXmlTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Xml;
using System.Xml.XPath;
using NUnit.Framework;
using SIL.Base32;

namespace SIL.WritingSystems.Tests
{
Expand Down Expand Up @@ -40,6 +41,16 @@ public void Setup()
_sortKeyGenerator = CultureInfo.InvariantCulture.CompareInfo.GetSortKey;
}

[Test]
public void VerifySortKeyGenerator()
{
var sortKey = _sortKeyGenerator("z");
var sortKeyBase32 = Base32Convert.ToBase32HexString(sortKey.KeyData, Base32FormattingOptions.None);
//this may be over specified, but all the tests expect this to pass
Assert.AreEqual("1QKG20810400", sortKeyBase32);
Assert.AreEqual("z", sortKey.OriginalString);
}

[Test]
public void AddSortKeys()
{
Expand Down
16 changes: 16 additions & 0 deletions SIL.WritingSystems.Tests/IcuRulesCollationDefinitionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,5 +80,21 @@ public void Validate_ImportInvalidRules_NotValid()
Assert.That(collation.Validate(out message), Is.False);
Assert.That(message, Is.EqualTo("Unable to import the private collation rules from en-US."));
}

[Test]
public void Collation_GetSortKeyWorks()
{
var ws = new WritingSystemDefinition("en-US");
ws.Collations.Add(new IcuRulesCollationDefinition("private")
{ IcuRules = "&B<t<<<T<s<<<S<e<<<E\r\n" });
var collation = new IcuRulesCollationDefinition("standard")
{
OwningWritingSystemDefinition = ws,
Imports = { new IcuCollationImport("en-US", "private") },
IcuRules = "&C<k<<<K<x<<<X<i<<<I\r\n"
};
var sortKey = collation.Collator.GetSortKey("test");
Assert.That(sortKey, Is.Not.Null);
}
}
}
6 changes: 6 additions & 0 deletions SIL.WritingSystems.Tests/SIL.WritingSystems.Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>$(TargetFrameworks);net8.0</TargetFrameworks>
<Description>Unit tests for SIL.WritingSystems</Description>
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
<RuntimeHostConfigurationOption Include="System.Globalization.UseNls" Value="true"/>
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
Expand All @@ -11,6 +15,8 @@
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
<PackageReference Include="NDesk.DBus" Version="0.15.0" />
<PackageReference Include="NUnit" Version="3.13.3" />
<!-- this reference is required to exhibit an issue where the icu.net version for net8.0 conflicts with the version used by SIL.WritingSystems-->
<PackageReference Include="icu.net" Version="2.10.1-beta.6"/>
<PackageReference Include="NUnit3TestAdapter" Version="4.3.2" PrivateAssets="All" />
<PackageReference Include="SIL.ReleaseTasks" Version="2.5.0" PrivateAssets="All" />
<PackageReference Include="Spart" Version="1.0.0" />
Expand Down
18 changes: 18 additions & 0 deletions SIL.WritingSystems/CultureInfoExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System.Globalization;

namespace SIL.WritingSystems
{
public static class CultureInfoExtensions
{
public static bool IsUnknownCulture(this CultureInfo cultureInfo)
{
// Windows 10 changed the behavior of CultureInfo, in that unknown cultures no longer return a CultureInfo containing an "Unknown Language" indication.
// The proper way to detect fully unknown cultures (for Windows 11 and prior) is to:
// 1. Check for the custom culture flag
// 2. Check if the three-letter language name is set to default
// Source: https://stackoverflow.com/a/71388328/1964319
return cultureInfo.CultureTypes.HasFlag(CultureTypes.UserCustomCulture) &&
cultureInfo.ThreeLetterWindowsLanguageName == "ZZZ";
}
}
}
49 changes: 0 additions & 49 deletions SIL.WritingSystems/IcuRulesCollator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,37 +62,7 @@ public static bool ValidateSortRules(string rules, out string message)

public SortKey GetSortKey(string source)
{
#if NET461
return _collator.GetSortKey(source);
#elif NETSTANDARD2_0
Icu.SortKey icuSortKey = _collator.GetSortKey(source);
SortKey sortKey = CultureInfo.InvariantCulture.CompareInfo.GetSortKey(string.Empty, CompareOptions.None);
string keyDataFieldName, origStringFieldName;
if (Platform.IsDotNetFramework)
{
keyDataFieldName = "m_KeyData";
origStringFieldName = "m_String";
}
else if (Platform.IsDotNetCore)
{
keyDataFieldName = "_keyData";
origStringFieldName = "_string";
}
else if (Platform.IsMono)
{
keyDataFieldName = "key";
origStringFieldName = "source";
}
else
{
throw new PlatformNotSupportedException();
}

SetInternalFieldForPublicProperty(sortKey, "SortKey.KeyData", keyDataFieldName, icuSortKey.KeyData);
SetInternalFieldForPublicProperty(sortKey, "SortKey.OriginalString", origStringFieldName,
icuSortKey.OriginalString);
return sortKey;
#endif
}

///<summary>Compares two strings and returns a value indicating whether one is less than,
Expand All @@ -114,24 +84,5 @@ public int Compare(object x, object y)
{
return Compare((string) x, (string) y);
}

#if NETSTANDARD2_0
private static void SetInternalFieldForPublicProperty(object instance, string propertyName, string fieldName,
object value)
{
Type type = instance.GetType();

FieldInfo fieldInfo = type.GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic);

Debug.Assert(fieldInfo != null,
"Unsupported runtime",
"Could not figure out an internal field for" + propertyName);

if (fieldInfo == null)
throw new PlatformNotSupportedException();

fieldInfo.SetValue(instance, value);
}
#endif
}
}
4 changes: 2 additions & 2 deletions SIL.WritingSystems/IetfLanguageTag.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1350,7 +1350,7 @@ public static string GetLocalizedLanguageName(string languageTag, string uiLangu
}
if (IsNullOrWhiteSpace(langName))
langName = ci.EnglishName;
if (!ci.EnglishName.StartsWith("Unknown Language")) // Windows .Net behavior
if (!ci.IsUnknownCulture())
{
MapIsoCodesToLanguageName.Add(key, langName);
return langName;
Expand Down Expand Up @@ -1435,7 +1435,7 @@ public static string GetNativeLanguageNameWithEnglishSubtitle(string code)
englishNameSuffix = englishNameSuffix.Substring(0, idxCountry) + "))";
}
langName = nativeName + englishNameSuffix;
if (!ci.EnglishName.StartsWith("Unknown Language")) // Windows .Net behavior
if (!ci.IsUnknownCulture())
{
MapIsoCodeToSubtitledLanguageName.Add(code, langName);
return langName;
Expand Down
2 changes: 1 addition & 1 deletion SIL.WritingSystems/SIL.WritingSystems.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
</PackageReference>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
<PackageReference Include="SIL.ReleaseTasks" Version="2.5.0" PrivateAssets="All" />
<PackageReference Include="icu.net" Version="2.8.1" />
<PackageReference Include="icu.net" Version="2.10.1-beta.6" />
<PackageReference Include="Spart" Version="1.0.0" />
<PackageReference Include="System.IO.FileSystem.AccessControl" Version="5.0.0" />
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="6.0.0" />
Expand Down
Loading