Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,9 @@ protected override ValidationResult ValidateValue(string value)
return ValidationResult.Success();
}

// Use TextInfo.ToTitleCase and compare with original
string titleCase = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(value.ToLowerInvariant());
// Title-case with invariant rules, as the lowercasing does, so the result does not depend
// on the thread culture (Turkish title-cases "istanbul" to "İstanbul")
string titleCase = CultureInfo.InvariantCulture.TextInfo.ToTitleCase(value.ToLowerInvariant());
bool isValid = string.Equals(value, titleCase, StringComparison.Ordinal);
return isValid
? ValidationResult.Success()
Expand Down
21 changes: 21 additions & 0 deletions Semantics.Test/CasingValidatorsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace ktsu.Semantics.Test;

using System.Globalization;
using ktsu.Semantics.Strings;
using Microsoft.VisualStudio.TestTools.UnitTesting;

Expand Down Expand Up @@ -66,6 +67,26 @@ public void TitleCase_Valid_Invalid_Empty()
Assert.AreEqual("", empty.WeakString);
}

[TestMethod]
[DataRow("en-US")]
[DataRow("tr-TR")]
[DataRow("az-Latn-AZ")]
public void TitleCase_DoesNotDependOnThreadCulture(string cultureName)
{
CultureInfo original = CultureInfo.CurrentCulture;
try
{
CultureInfo.CurrentCulture = new CultureInfo(cultureName);
TitleCaseString valid = SemanticString<TitleCaseString>.Create<TitleCaseString>("Istanbul Is Lovely");
Assert.AreEqual("Istanbul Is Lovely", valid.WeakString);
Assert.ThrowsExactly<ArgumentException>(() => SemanticString<TitleCaseString>.Create<TitleCaseString>("istanbul"));
}
finally
{
CultureInfo.CurrentCulture = original;
}
}

[TestMethod]
public void SentenceCase_Valid_Invalid_Empty()
{
Expand Down
7 changes: 7 additions & 0 deletions Semantics.Test/Semantics.Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@
<TestingPlatformShowTestsFailure>true</TestingPlatformShowTestsFailure>
<TestingPlatformShowTestsFailureDetails>true</TestingPlatformShowTestsFailureDetails>
<NoWarn>$(NoWarn);MSTEST0032</NoWarn>
<!-- ktsu.Sdk turns on invariant globalization, where every culture but the invariant one fails
to construct. The libraries are consumed by projects that do not, so the tests that prove a
validator ignores the thread culture (tr-TR, az) need real cultures to set. With it off, the
analyzers start flagging culture-sensitive calls (CA1304, CA1307); SemanticStringTests makes
those calls on purpose, to cover SemanticString's own culture-default overloads. -->
<InvariantGlobalization>false</InvariantGlobalization>
<NoWarn>$(NoWarn);CA1304;CA1307</NoWarn>
</PropertyGroup>

<ItemGroup>
Expand Down
Loading