From 6aa13be4a28ccaba618add82186b89c68012effa Mon Sep 17 00:00:00 2001 From: "Dylan R. E. Moonfire" Date: Sun, 5 Jun 2022 14:03:28 -0500 Subject: [PATCH] fix: fixed replacements so they are applied first to allow "C#" to become "c-sharp" --- Nitride.sln | 15 +++++ src/Nitride.Slugs/SimpleSlugConverter.cs | 40 ++++++++----- .../Nitride.Slugs.Tests.csproj | 30 ++++++++++ .../UnicodeNormalizingSlugConverterTest.cs | 59 +++++++++++++++++++ 4 files changed, 130 insertions(+), 14 deletions(-) create mode 100644 tests/Nitride.Slugs.Tests/Nitride.Slugs.Tests.csproj create mode 100644 tests/Nitride.Slugs.Tests/UnicodeNormalizingSlugConverterTest.cs diff --git a/Nitride.sln b/Nitride.sln index b12eaa1..358859c 100644 --- a/Nitride.sln +++ b/Nitride.sln @@ -41,6 +41,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{47 EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CopyFiles", "examples\CopyFiles\CopyFiles.csproj", "{2C92A626-7A14-4FDB-906B-E7FA5FF18CC1}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nitride.Slugs.Tests", "tests\Nitride.Slugs.Tests\Nitride.Slugs.Tests.csproj", "{C49E07D0-CD32-4332-90FA-07494195CAC4}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -246,6 +248,18 @@ Global {2C92A626-7A14-4FDB-906B-E7FA5FF18CC1}.Release|x64.Build.0 = Release|Any CPU {2C92A626-7A14-4FDB-906B-E7FA5FF18CC1}.Release|x86.ActiveCfg = Release|Any CPU {2C92A626-7A14-4FDB-906B-E7FA5FF18CC1}.Release|x86.Build.0 = Release|Any CPU + {C49E07D0-CD32-4332-90FA-07494195CAC4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C49E07D0-CD32-4332-90FA-07494195CAC4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C49E07D0-CD32-4332-90FA-07494195CAC4}.Debug|x64.ActiveCfg = Debug|Any CPU + {C49E07D0-CD32-4332-90FA-07494195CAC4}.Debug|x64.Build.0 = Debug|Any CPU + {C49E07D0-CD32-4332-90FA-07494195CAC4}.Debug|x86.ActiveCfg = Debug|Any CPU + {C49E07D0-CD32-4332-90FA-07494195CAC4}.Debug|x86.Build.0 = Debug|Any CPU + {C49E07D0-CD32-4332-90FA-07494195CAC4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C49E07D0-CD32-4332-90FA-07494195CAC4}.Release|Any CPU.Build.0 = Release|Any CPU + {C49E07D0-CD32-4332-90FA-07494195CAC4}.Release|x64.ActiveCfg = Release|Any CPU + {C49E07D0-CD32-4332-90FA-07494195CAC4}.Release|x64.Build.0 = Release|Any CPU + {C49E07D0-CD32-4332-90FA-07494195CAC4}.Release|x86.ActiveCfg = Release|Any CPU + {C49E07D0-CD32-4332-90FA-07494195CAC4}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {D480943C-764D-4A8A-B546-642ED10586BB} = {570184FD-ECE4-4EC8-86E1-C1265E17D647} @@ -264,5 +278,6 @@ Global {F940CD28-6867-4E5B-BC27-F476B3BEB49A} = {251D9C68-34EB-439D-B167-688BCC47DA17} {29743817-A401-458F-9DD0-AF3579965953} = {251D9C68-34EB-439D-B167-688BCC47DA17} {2C92A626-7A14-4FDB-906B-E7FA5FF18CC1} = {47461A29-E502-4B0E-AAF5-D87C4B93AB6D} + {C49E07D0-CD32-4332-90FA-07494195CAC4} = {251D9C68-34EB-439D-B167-688BCC47DA17} EndGlobalSection EndGlobal diff --git a/src/Nitride.Slugs/SimpleSlugConverter.cs b/src/Nitride.Slugs/SimpleSlugConverter.cs index 4ac3202..11cd35f 100644 --- a/src/Nitride.Slugs/SimpleSlugConverter.cs +++ b/src/Nitride.Slugs/SimpleSlugConverter.cs @@ -12,30 +12,41 @@ namespace Nitride.Slugs; /// public class SimpleSlugConverter : ISlugConverter, IEnumerable { - private readonly List<(string, string)> replacements; + private readonly List<(string, string, StringComparison)> replacements; public SimpleSlugConverter() { - this.replacements = new List<(string, string)>(); + this.replacements = new List<(string, string, StringComparison)>(); } - public SimpleSlugConverter(IDictionary replacements) + public SimpleSlugConverter( + IDictionary replacements, + StringComparison comparison = StringComparison.InvariantCultureIgnoreCase) : this() { foreach (KeyValuePair pair in replacements) { - this.Add(pair.Key, pair.Value); + this.Add(pair.Key, pair.Value, comparison); } } /// - /// Adds a replacement for the resulting slug. + /// Adds a replacement for the resulting slug. This is applied before the final + /// conversion + /// into a slug but after any other added replacements. /// /// The text to search for. /// The replacement string. - public void Add(string search, string replace) + /// + /// The comparison to use, defaults to invariant ignore + /// case. + /// + public void Add( + string search, + string replace, + StringComparison comparison = StringComparison.InvariantCultureIgnoreCase) { - this.replacements.Add((search, replace)); + this.replacements.Add((search, replace, comparison)); } /// @@ -53,16 +64,17 @@ public class SimpleSlugConverter : ISlugConverter, IEnumerable throw new ArgumentException("Cannot have a blank or null input", nameof(input)); } - // Create a slug.. + // We need to do the replacements before we slugify. + // Perform any additional replacements. + foreach ((string search, string replace, StringComparison comparison) in this.replacements) + { + input = input.Replace(search, replace, comparison); + } + + // Create a slug. var helper = new SlugHelper(); string output = helper.GenerateSlug(input); - // Perform any additional replacements. - foreach ((string search, string replace) in this.replacements) - { - output = output.Replace(search, replace); - } - return output; } diff --git a/tests/Nitride.Slugs.Tests/Nitride.Slugs.Tests.csproj b/tests/Nitride.Slugs.Tests/Nitride.Slugs.Tests.csproj new file mode 100644 index 0000000..88424b4 --- /dev/null +++ b/tests/Nitride.Slugs.Tests/Nitride.Slugs.Tests.csproj @@ -0,0 +1,30 @@ + + + + net6.0 + enable + + + + + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + diff --git a/tests/Nitride.Slugs.Tests/UnicodeNormalizingSlugConverterTest.cs b/tests/Nitride.Slugs.Tests/UnicodeNormalizingSlugConverterTest.cs new file mode 100644 index 0000000..ea0630e --- /dev/null +++ b/tests/Nitride.Slugs.Tests/UnicodeNormalizingSlugConverterTest.cs @@ -0,0 +1,59 @@ +using System.Collections.Generic; + +using Nitride.Tests; + +using Xunit; +using Xunit.Abstractions; + +namespace Nitride.Slugs.Tests; + +/// +/// Tests the functionality of the WriteFiles(). +/// +public class UnicodeNormalizingSlugConverterTest : NitrideTestBase +{ + public UnicodeNormalizingSlugConverterTest(ITestOutputHelper output) + : base(output) + { + } + + [Fact] + public void DefaultConversions() + { + var slug = new UnicodeNormalizingSlugConverter(); + var expected = new List(); + var actual = new List(); + + this.Test(slug, expected, actual, "One", "one"); + this.Test(slug, expected, actual, "Two-Words", "two-words"); + this.Test(slug, expected, actual, "Rutejìmo", "rutejimo"); + this.Test(slug, expected, actual, "C#", "c"); + + Assert.Equal(expected, actual); + } + + [Fact] + public void ReplacementConversions() + { + var slug = new UnicodeNormalizingSlugConverter( + new Dictionary + { + ["#"] = "-sharp", + }); + var expected = new List(); + var actual = new List(); + + this.Test(slug, expected, actual, "One", "one"); + this.Test(slug, expected, actual, "Two-Words", "two-words"); + this.Test(slug, expected, actual, "Rutejìmo", "rutejimo"); + this.Test(slug, expected, actual, "C#", "c-sharp"); + + Assert.Equal(expected, actual); + } + + private void Test(ISlugConverter slug, List expected, List actual, string input, string output) + { + expected.Add(output); + actual.Add(slug.ToSlug(input)); + } +}