LANCommander/LANCommander.SDK.Tests/Extensions/StringExtensionsTests.cs
2026-04-13 03:24:40 -05:00

117 lines
3.4 KiB
C#

using LANCommander.SDK.Extensions;
namespace LANCommander.SDK.Tests.Extensions;
public class StringExtensionsTests
{
// ── SanitizeFilename ───────────────────────────────────────────────────────
[Theory]
[InlineData("Half-Life 2: Episode One", "Half-Life 2 - Episode One")]
[InlineData("Game: The Sequel", "Game - The Sequel")]
[InlineData("Foo: Bar", "Foo - Bar")]
public void SanitizeFilename_ColonSpacePattern_IsReplacedWithDash(string input, string expected)
{
Assert.Equal(expected, input.SanitizeFilename());
}
[Fact]
public void SanitizeFilename_ColonWithNoSpaceAfter_IsNotChanged()
{
// Only "word: word" (colon-space) triggers the replacement, not bare colons.
// On Linux, ':' is not an invalid filename character so it is left as-is.
var result = "http://example".SanitizeFilename();
// No "word: word" match → colon stays; '/' is invalid on all platforms.
Assert.DoesNotContain("/", result);
}
[Fact]
public void SanitizeFilename_TrailingDot_IsRemoved()
{
var result = "GameTitle.".SanitizeFilename();
Assert.Equal("GameTitle", result);
}
[Fact]
public void SanitizeFilename_NonTrailingDot_IsPreserved()
{
var result = "game.exe".SanitizeFilename();
Assert.Equal("game.exe", result);
}
[Fact]
public void SanitizeFilename_MultipleDots_OnlyLastRemoved()
{
var result = "game...".SanitizeFilename();
Assert.Equal("game..", result);
}
[Fact]
public void SanitizeFilename_ForwardSlash_IsRemoved()
{
// '/' is in Path.GetInvalidFileNameChars() on all platforms.
var result = "foo/bar".SanitizeFilename();
Assert.Equal("foobar", result);
}
[Fact]
public void SanitizeFilename_ForwardSlash_ReplacedWithCustomString()
{
var result = "foo/bar".SanitizeFilename("_");
Assert.Equal("foo_bar", result);
}
[Fact]
public void SanitizeFilename_NoInvalidChars_ReturnsUnchanged()
{
var result = "NormalTitle".SanitizeFilename();
Assert.Equal("NormalTitle", result);
}
[Fact]
public void SanitizeFilename_ColonAndTrailingDot_BothHandled()
{
var result = "Game: Edition.".SanitizeFilename();
Assert.Equal("Game - Edition", result);
}
// ── FastReverse ────────────────────────────────────────────────────────────
[Theory]
[InlineData("hello", "olleh")]
[InlineData("abcde", "edcba")]
[InlineData("12345", "54321")]
[InlineData("a", "a")]
public void FastReverse_ReversesString(string input, string expected)
{
Assert.Equal(expected, input.FastReverse());
}
[Fact]
public void FastReverse_EmptyString_ReturnsEmpty()
{
Assert.Equal("", "".FastReverse());
}
[Fact]
public void FastReverse_Palindrome_ReturnsSameValue()
{
Assert.Equal("racecar", "racecar".FastReverse());
}
[Fact]
public void FastReverse_TwiceProducesOriginal()
{
const string original = "LANCommander";
Assert.Equal(original, original.FastReverse().FastReverse());
}
}