diff --git a/src/Ocelot.Provider.Consul/DefaultConsulServiceBuilder.cs b/src/Ocelot.Provider.Consul/DefaultConsulServiceBuilder.cs index 4d9abe7a7..e7e3b8fbb 100644 --- a/src/Ocelot.Provider.Consul/DefaultConsulServiceBuilder.cs +++ b/src/Ocelot.Provider.Consul/DefaultConsulServiceBuilder.cs @@ -102,7 +102,7 @@ protected virtual string GetServiceId(ServiceEntry entry, Node node) protected virtual string GetServiceVersion(ServiceEntry entry, Node node) => entry.Service.Tags ?.FirstOrDefault(tag => tag.StartsWith(VersionPrefix, StringComparison.Ordinal)) - ?.TrimStart(VersionPrefix) + ?.TrimPrefix(VersionPrefix) ?? string.Empty; protected virtual IEnumerable GetServiceTags(ServiceEntry entry, Node node) diff --git a/src/Ocelot/Infrastructure/Extensions/StringExtensions.cs b/src/Ocelot/Infrastructure/Extensions/StringExtensions.cs index 7980712e4..a67d11f41 100644 --- a/src/Ocelot/Infrastructure/Extensions/StringExtensions.cs +++ b/src/Ocelot/Infrastructure/Extensions/StringExtensions.cs @@ -2,29 +2,32 @@ public static class StringExtensions { - public static string TrimStart(this string source, string trim, StringComparison stringComparison = StringComparison.Ordinal) + /// Removes the prefix from the beginning of the string repeatedly until all occurrences are eliminated. + /// The string to trim. + /// The prefix string to remove. + /// The 2nd argument of the method. + /// A new without the prefix all occurrences. + public static string TrimPrefix(this string source, string prefix, StringComparison comparison = StringComparison.Ordinal) { - if (source == null) + if (source == null || string.IsNullOrEmpty(prefix)) { - return null; + return source; } var s = source; - while (s.StartsWith(trim, stringComparison)) + while (s.StartsWith(prefix, comparison)) { - s = s.Substring(trim.Length); + s = s[prefix.Length..]; } return s; } - public static string LastCharAsForwardSlash(this string source) - { - if (source.EndsWith('/')) - { - return source; - } + public const char Slash = '/'; - return $"{source}/"; - } + /// Ensures that the last char of the string is forward slash, '/'. + /// The string to check its last slash char. + /// A witl the last forward slash. + public static string LastCharAsForwardSlash(this string source) + => source.EndsWith(Slash) ? source : source + Slash; } diff --git a/test/Ocelot.UnitTests/Infrastructure/StringExtensionsTests.cs b/test/Ocelot.UnitTests/Infrastructure/StringExtensionsTests.cs index a91f8bc4d..2a926d6e1 100644 --- a/test/Ocelot.UnitTests/Infrastructure/StringExtensionsTests.cs +++ b/test/Ocelot.UnitTests/Infrastructure/StringExtensionsTests.cs @@ -5,22 +5,25 @@ namespace Ocelot.UnitTests.Infrastructure; public class StringExtensionsTests { [Fact] - public void should_trim_start() + public void TrimPrefix_ArgsCheck_ReturnedSource() { - var test = "/string"; - - test = test.TrimStart("/"); - - test.ShouldBe("string"); + ((string)null).TrimPrefix("/").ShouldBeNull(); + "x".TrimPrefix(null).ShouldBe("x"); + "x".TrimPrefix(string.Empty).ShouldBe("x"); } [Fact] - public void should_return_source() + public void TrimPrefix_HasPrefix_HappyPath() { - var test = "string"; - - test = test.LastCharAsForwardSlash(); + "/string".TrimPrefix("/").ShouldBe("string"); + "///string".TrimPrefix("/").ShouldBe("string"); + "ABABstring".TrimPrefix("AB").ShouldBe("string"); + } - test.ShouldBe("string/"); + [Fact] + public void LastCharAsForwardSlash_HappyPath() + { + "string".LastCharAsForwardSlash().ShouldBe("string/"); + "string/".LastCharAsForwardSlash().ShouldBe("string/"); } }