diff --git a/ModuleManager/Extensions/StringExtensions.cs b/ModuleManager/Extensions/StringExtensions.cs
index 634fab7a..13ce804c 100644
--- a/ModuleManager/Extensions/StringExtensions.cs
+++ b/ModuleManager/Extensions/StringExtensions.cs
@@ -30,7 +30,7 @@ public static bool Contains(this string str, string value, out int index)
if (str == null) throw new ArgumentNullException(nameof(str));
if (value == null) throw new ArgumentNullException(nameof(value));
- index = str.IndexOf(value, StringComparison.CurrentCultureIgnoreCase);
+ index = str.IndexOf(value, StringComparison.OrdinalIgnoreCase);
return index != -1;
}
}
diff --git a/ModuleManager/Patches/PassSpecifiers/AfterPassSpecifier.cs b/ModuleManager/Patches/PassSpecifiers/AfterPassSpecifier.cs
index a50b99c5..02605d70 100644
--- a/ModuleManager/Patches/PassSpecifiers/AfterPassSpecifier.cs
+++ b/ModuleManager/Patches/PassSpecifiers/AfterPassSpecifier.cs
@@ -24,6 +24,6 @@ public bool CheckNeeds(INeedsChecker needsChecker, IPatchProgress progress)
return result;
}
- public string Descriptor => $":AFTER[{mod.ToUpper()}]";
+ public string Descriptor => $":AFTER[{mod.ToUpperInvariant()}]";
}
}
diff --git a/ModuleManager/Patches/PassSpecifiers/BeforePassSpecifier.cs b/ModuleManager/Patches/PassSpecifiers/BeforePassSpecifier.cs
index 9f509f43..6bbf9eb2 100644
--- a/ModuleManager/Patches/PassSpecifiers/BeforePassSpecifier.cs
+++ b/ModuleManager/Patches/PassSpecifiers/BeforePassSpecifier.cs
@@ -24,6 +24,6 @@ public bool CheckNeeds(INeedsChecker needsChecker, IPatchProgress progress)
return result;
}
- public string Descriptor => $":BEFORE[{mod.ToUpper()}]";
+ public string Descriptor => $":BEFORE[{mod.ToUpperInvariant()}]";
}
}
diff --git a/ModuleManager/Patches/PassSpecifiers/ForPassSpecifier.cs b/ModuleManager/Patches/PassSpecifiers/ForPassSpecifier.cs
index 3256a072..b170aaaa 100644
--- a/ModuleManager/Patches/PassSpecifiers/ForPassSpecifier.cs
+++ b/ModuleManager/Patches/PassSpecifiers/ForPassSpecifier.cs
@@ -24,6 +24,6 @@ public bool CheckNeeds(INeedsChecker needsChecker, IPatchProgress progress)
return result;
}
- public string Descriptor => $":FOR[{mod.ToUpper()}]";
+ public string Descriptor => $":FOR[{mod.ToUpperInvariant()}]";
}
}
diff --git a/ModuleManager/Patches/PassSpecifiers/LastPassSpecifier.cs b/ModuleManager/Patches/PassSpecifiers/LastPassSpecifier.cs
index e0d4fcc4..2fb29832 100644
--- a/ModuleManager/Patches/PassSpecifiers/LastPassSpecifier.cs
+++ b/ModuleManager/Patches/PassSpecifiers/LastPassSpecifier.cs
@@ -14,6 +14,6 @@ public LastPassSpecifier(string mod)
}
public bool CheckNeeds(INeedsChecker needsChecker, IPatchProgress progress) => true;
- public string Descriptor => $":LAST[{mod.ToUpper()}]";
+ public string Descriptor => $":LAST[{mod.ToUpperInvariant()}]";
}
}
diff --git a/ModuleManager/Patches/ProtoPatchBuilder.cs b/ModuleManager/Patches/ProtoPatchBuilder.cs
index 377855fa..15889ebe 100644
--- a/ModuleManager/Patches/ProtoPatchBuilder.cs
+++ b/ModuleManager/Patches/ProtoPatchBuilder.cs
@@ -55,7 +55,7 @@ public ProtoPatch Build(UrlDir.UrlConfig urlConfig, Command command, ITagList ta
if (tag.trailer != null)
progress.Warning(urlConfig, "unrecognized trailer: '" + tag.trailer + "' on: " + urlConfig.SafeUrl());
- if (tag.key.Equals("NEEDS", StringComparison.CurrentCultureIgnoreCase))
+ if (tag.key.Equals("NEEDS", StringComparison.OrdinalIgnoreCase))
{
if (needs != null)
{
@@ -71,7 +71,7 @@ public ProtoPatch Build(UrlDir.UrlConfig urlConfig, Command command, ITagList ta
needs = tag.value;
}
- else if (tag.key.Equals("HAS", StringComparison.CurrentCultureIgnoreCase))
+ else if (tag.key.Equals("HAS", StringComparison.OrdinalIgnoreCase))
{
if (command == Command.Insert)
{
@@ -93,7 +93,7 @@ public ProtoPatch Build(UrlDir.UrlConfig urlConfig, Command command, ITagList ta
has = tag.value;
}
- else if (tag.key.Equals("FIRST", StringComparison.CurrentCultureIgnoreCase))
+ else if (tag.key.Equals("FIRST", StringComparison.OrdinalIgnoreCase))
{
if (tag.value != null)
{
@@ -114,7 +114,7 @@ public ProtoPatch Build(UrlDir.UrlConfig urlConfig, Command command, ITagList ta
passSpecifier = new FirstPassSpecifier();
}
- else if (tag.key.Equals("BEFORE", StringComparison.CurrentCultureIgnoreCase))
+ else if (tag.key.Equals("BEFORE", StringComparison.OrdinalIgnoreCase))
{
if (string.IsNullOrEmpty(tag.value))
{
@@ -137,7 +137,7 @@ public ProtoPatch Build(UrlDir.UrlConfig urlConfig, Command command, ITagList ta
passSpecifier = new BeforePassSpecifier(tag.value, urlConfig);
}
- else if (tag.key.Equals("FOR", StringComparison.CurrentCultureIgnoreCase))
+ else if (tag.key.Equals("FOR", StringComparison.OrdinalIgnoreCase))
{
if (string.IsNullOrEmpty(tag.value))
{
@@ -160,7 +160,7 @@ public ProtoPatch Build(UrlDir.UrlConfig urlConfig, Command command, ITagList ta
passSpecifier = new ForPassSpecifier(tag.value, urlConfig);
}
- else if (tag.key.Equals("AFTER", StringComparison.CurrentCultureIgnoreCase))
+ else if (tag.key.Equals("AFTER", StringComparison.OrdinalIgnoreCase))
{
if (string.IsNullOrEmpty(tag.value))
{
@@ -183,7 +183,7 @@ public ProtoPatch Build(UrlDir.UrlConfig urlConfig, Command command, ITagList ta
passSpecifier = new AfterPassSpecifier(tag.value, urlConfig);
}
- else if (tag.key.Equals("LAST", StringComparison.CurrentCultureIgnoreCase))
+ else if (tag.key.Equals("LAST", StringComparison.OrdinalIgnoreCase))
{
if (string.IsNullOrEmpty(tag.value))
{
@@ -206,7 +206,7 @@ public ProtoPatch Build(UrlDir.UrlConfig urlConfig, Command command, ITagList ta
passSpecifier = new LastPassSpecifier(tag.value);
}
- else if (tag.key.Equals("FINAL", StringComparison.CurrentCultureIgnoreCase))
+ else if (tag.key.Equals("FINAL", StringComparison.OrdinalIgnoreCase))
{
if (tag.value != null)
{
diff --git a/ModuleManagerTests/Extensions/StringExtensionsTest.cs b/ModuleManagerTests/Extensions/StringExtensionsTest.cs
index acf9274e..7fc22891 100644
--- a/ModuleManagerTests/Extensions/StringExtensionsTest.cs
+++ b/ModuleManagerTests/Extensions/StringExtensionsTest.cs
@@ -51,6 +51,31 @@ public void TestContains(string str, string test, bool expectedResult, int expec
Assert.Equal(expectedIndex, index);
}
+ [InlineData("abc:first", ":FIRST", 3)]
+ [InlineData("abc:FINAL", ":final", 3)]
+ [InlineData("abc:Has[def]", ":HAS[", 3)]
+ [Theory]
+ public void TestContains__CaseInsensitive(string str, string test, int expectedIndex)
+ {
+ bool result = str.Contains(test, out int index);
+ Assert.True(result);
+ Assert.Equal(expectedIndex, index);
+ }
+
+ [InlineData("abc:first", ":FIRST", 3)]
+ [InlineData("abc:FINAL", ":final", 3)]
+ [InlineData("abc:Has[def]", ":HAS[", 3)]
+ [Theory]
+ public void TestContains__CaseInsensitive__TurkishCulture(string str, string test, int expectedIndex)
+ {
+ using (new TemporaryCulture(TemporaryCulture.TURKISH))
+ {
+ bool result = str.Contains(test, out int index);
+ Assert.True(result);
+ Assert.Equal(expectedIndex, index);
+ }
+ }
+
[Fact]
public void TestContains__NullStr()
{
diff --git a/ModuleManagerTests/ModuleManagerTests.csproj b/ModuleManagerTests/ModuleManagerTests.csproj
index f3afbbf5..2ebab704 100644
--- a/ModuleManagerTests/ModuleManagerTests.csproj
+++ b/ModuleManagerTests/ModuleManagerTests.csproj
@@ -95,6 +95,7 @@
+
diff --git a/ModuleManagerTests/Patches/PassSpecifiers/AfterPassSpecifierTest.cs b/ModuleManagerTests/Patches/PassSpecifiers/AfterPassSpecifierTest.cs
index 6e086b57..1b8016d0 100644
--- a/ModuleManagerTests/Patches/PassSpecifiers/AfterPassSpecifierTest.cs
+++ b/ModuleManagerTests/Patches/PassSpecifiers/AfterPassSpecifierTest.cs
@@ -101,5 +101,14 @@ public void TestDescriptor()
{
Assert.Equal(":AFTER[MOD1]", passSpecifier.Descriptor);
}
+
+ [Fact]
+ public void TestDescriptor__TurkishCulture()
+ {
+ using (new TemporaryCulture(TemporaryCulture.TURKISH))
+ {
+ Assert.Equal(":AFTER[MINI]", new AfterPassSpecifier("mini", urlConfig).Descriptor);
+ }
+ }
}
}
diff --git a/ModuleManagerTests/Patches/PassSpecifiers/BeforePassSpecifierTest.cs b/ModuleManagerTests/Patches/PassSpecifiers/BeforePassSpecifierTest.cs
index 937da7c2..87ac547d 100644
--- a/ModuleManagerTests/Patches/PassSpecifiers/BeforePassSpecifierTest.cs
+++ b/ModuleManagerTests/Patches/PassSpecifiers/BeforePassSpecifierTest.cs
@@ -101,5 +101,14 @@ public void TestDescriptor()
{
Assert.Equal(":BEFORE[MOD1]", passSpecifier.Descriptor);
}
+
+ [Fact]
+ public void TestDescriptor__TurkishCulture()
+ {
+ using (new TemporaryCulture(TemporaryCulture.TURKISH))
+ {
+ Assert.Equal(":BEFORE[MINI]", new BeforePassSpecifier("mini", urlConfig).Descriptor);
+ }
+ }
}
}
diff --git a/ModuleManagerTests/Patches/PassSpecifiers/ForPassSpecifierTest.cs b/ModuleManagerTests/Patches/PassSpecifiers/ForPassSpecifierTest.cs
index cec25628..c3c6f041 100644
--- a/ModuleManagerTests/Patches/PassSpecifiers/ForPassSpecifierTest.cs
+++ b/ModuleManagerTests/Patches/PassSpecifiers/ForPassSpecifierTest.cs
@@ -101,5 +101,14 @@ public void TestDescriptor()
{
Assert.Equal(":FOR[MOD1]", passSpecifier.Descriptor);
}
+
+ [Fact]
+ public void TestDescriptor__TurkishCulture()
+ {
+ using (new TemporaryCulture(TemporaryCulture.TURKISH))
+ {
+ Assert.Equal(":FOR[MINI]", new ForPassSpecifier("mini", urlConfig).Descriptor);
+ }
+ }
}
}
diff --git a/ModuleManagerTests/Patches/PassSpecifiers/LastPassSpecifierTest.cs b/ModuleManagerTests/Patches/PassSpecifiers/LastPassSpecifierTest.cs
index bdf6bee5..6f0b6b8b 100644
--- a/ModuleManagerTests/Patches/PassSpecifiers/LastPassSpecifierTest.cs
+++ b/ModuleManagerTests/Patches/PassSpecifiers/LastPassSpecifierTest.cs
@@ -54,5 +54,14 @@ public void TestDescriptor()
{
Assert.Equal(":LAST[MOD1]", passSpecifier.Descriptor);
}
+
+ [Fact]
+ public void TestDescriptor__TurkishCulture()
+ {
+ using (new TemporaryCulture(TemporaryCulture.TURKISH))
+ {
+ Assert.Equal(":LAST[MINI]", new LastPassSpecifier("mini").Descriptor);
+ }
+ }
}
}
diff --git a/ModuleManagerTests/Patches/ProtoPatchBuilderTest.cs b/ModuleManagerTests/Patches/ProtoPatchBuilderTest.cs
index fd2ff4ab..dad317dd 100644
--- a/ModuleManagerTests/Patches/ProtoPatchBuilderTest.cs
+++ b/ModuleManagerTests/Patches/ProtoPatchBuilderTest.cs
@@ -259,6 +259,32 @@ public void TestBuild__First__Case2()
Assert.IsType(protoPatch.passSpecifier);
}
+ [Fact]
+ public void TestBuild__First__TurkishCulture()
+ {
+ ITagList tagList = Substitute.For();
+ tagList.PrimaryTag.Returns(new Tag("NODE", null, null));
+ tagList.GetEnumerator().Returns(new ArrayEnumerator(
+ new Tag("first", null, null)
+ ));
+
+ ProtoPatch protoPatch;
+ using (new TemporaryCulture(TemporaryCulture.TURKISH))
+ {
+ protoPatch = builder.Build(urlConfig, Command.Copy, tagList);
+ }
+
+ EnsureNoErrors();
+
+ Assert.Same(urlConfig, protoPatch.urlConfig);
+ Assert.Equal(Command.Copy, protoPatch.command);
+ Assert.Equal("NODE", protoPatch.nodeType);
+ Assert.Null(protoPatch.nodeName);
+ Assert.Null(protoPatch.needs);
+ Assert.Null(protoPatch.has);
+ Assert.IsType(protoPatch.passSpecifier);
+ }
+
[Fact]
public void TestBuild__Before()
{
@@ -610,6 +636,32 @@ public void TestBuild__Final__Case2()
Assert.IsType(protoPatch.passSpecifier);
}
+ [Fact]
+ public void TestBuild__Final__TurkishCulture()
+ {
+ ITagList tagList = Substitute.For();
+ tagList.PrimaryTag.Returns(new Tag("NODE", null, null));
+ tagList.GetEnumerator().Returns(new ArrayEnumerator(
+ new Tag("final", null, null)
+ ));
+
+ ProtoPatch protoPatch;
+ using (new TemporaryCulture(TemporaryCulture.TURKISH))
+ {
+ protoPatch = builder.Build(urlConfig, Command.Copy, tagList);
+ }
+
+ EnsureNoErrors();
+
+ Assert.Same(urlConfig, protoPatch.urlConfig);
+ Assert.Equal(Command.Copy, protoPatch.command);
+ Assert.Equal("NODE", protoPatch.nodeType);
+ Assert.Null(protoPatch.nodeName);
+ Assert.Null(protoPatch.needs);
+ Assert.Null(protoPatch.has);
+ Assert.IsType(protoPatch.passSpecifier);
+ }
+
[Fact]
public void TestBuild__Insert__InsertPass()
{
diff --git a/ModuleManagerTests/TemporaryCulture.cs b/ModuleManagerTests/TemporaryCulture.cs
new file mode 100644
index 00000000..2fd7791c
--- /dev/null
+++ b/ModuleManagerTests/TemporaryCulture.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Globalization;
+using System.Threading;
+
+namespace ModuleManagerTests
+{
+ public sealed class TemporaryCulture : IDisposable
+ {
+ // Lowercase i and uppercase I are not a case pair in this culture
+ public const string TURKISH = "tr-TR";
+
+ private readonly CultureInfo originalCulture;
+
+ public TemporaryCulture(string name)
+ {
+ originalCulture = Thread.CurrentThread.CurrentCulture;
+ Thread.CurrentThread.CurrentCulture = new CultureInfo(name);
+ }
+
+ public void Dispose()
+ {
+ Thread.CurrentThread.CurrentCulture = originalCulture;
+ }
+ }
+}