diff --git a/AppScaffolding/AppScaffolding.csproj b/AppScaffolding/AppScaffolding.csproj index 964a66e3..f573ee3c 100644 --- a/AppScaffolding/AppScaffolding.csproj +++ b/AppScaffolding/AppScaffolding.csproj @@ -3,7 +3,7 @@ net6.0 - 6.7.2.1 + 6.7.3.1 diff --git a/FileManager/FileUtility.cs b/FileManager/FileUtility.cs index 2ca30279..844c7513 100644 --- a/FileManager/FileUtility.cs +++ b/FileManager/FileUtility.cs @@ -139,7 +139,7 @@ namespace FileManager return path[0] + remainder; } - private static string removeInvalidWhitespace_pattern { get; } = $@"\s*\{Path.DirectorySeparatorChar}\s*"; + private static string removeInvalidWhitespace_pattern { get; } = $@"[\s\.]*\{Path.DirectorySeparatorChar}\s*"; private static Regex removeInvalidWhitespace_regex { get; } = new(removeInvalidWhitespace_pattern, RegexOptions.Compiled | RegexOptions.IgnorePatternWhitespace); /// no part of the path may begin or end in whitespace @@ -149,14 +149,20 @@ namespace FileManager // replace whitespace around path slashes // regex (with space added for clarity) // \s* \\ \s* => \ - fullfilename = fullfilename.Trim(); - - fullfilename = removeInvalidWhitespace_regex.Replace(fullfilename, @"\"); + // no ending dots. beginning dots are valid + + // regex is easier by ending with separator + fullfilename += Path.DirectorySeparatorChar; + fullfilename = removeInvalidWhitespace_regex.Replace(fullfilename, Path.DirectorySeparatorChar.ToString()); + // take seperator back off + fullfilename = RemoveLastCharacter(fullfilename); fullfilename = removeDoubleSlashes(fullfilename); return fullfilename; } + public static string RemoveLastCharacter(this string str) => string.IsNullOrEmpty(str) ? str : str[..^1]; + /// /// Move file. ///
- Ensure valid file name path: remove invalid chars, ensure uniqueness, enforce max file length diff --git a/_Tests/FileManager.Tests/FileUtilityTests.cs b/_Tests/FileManager.Tests/FileUtilityTests.cs index 49ef3a2f..ad0b3d2d 100644 --- a/_Tests/FileManager.Tests/FileUtilityTests.cs +++ b/_Tests/FileManager.Tests/FileUtilityTests.cs @@ -113,4 +113,51 @@ namespace FileUtilityTests public void Tests(string input, string expected) => FileUtility.GetStandardizedExtension(input).Should().Be(expected); } + + [TestClass] + public class GetValidFilename + { + [TestMethod] + // dot-files + [DataRow(@"C:\a bc\x y z\.f i l e.txt")] + // dot-folders + [DataRow(@"C:\a bc\.x y z\f i l e.txt")] + public void Valid(string input) => Tests(input, input); + + [TestMethod] + // folder spaces + [DataRow(@"C:\ a bc \x y z ", @"C:\a bc\x y z")] + // file spaces + [DataRow(@"C:\a bc\x y z\ f i l e.txt ", @"C:\a bc\x y z\f i l e.txt")] + // eliminate beginning space and end dots and spaces + [DataRow(@"C:\a bc\ . . . x y z . . . \f i l e.txt", @"C:\a bc\. . . x y z\f i l e.txt")] + // file end dots + [DataRow(@"C:\a bc\x y z\f i l e.txt . . .", @"C:\a bc\x y z\f i l e.txt")] + public void Tests(string input, string expected) + => FileUtility.GetValidFilename(input).Should().Be(expected); + } + + [TestClass] + public class RemoveLastCharacter + { + [TestMethod] + public void is_null() => Tests(null, null); + + [TestMethod] + public void empty() => Tests("", ""); + + [TestMethod] + public void single_space() => Tests(" ", ""); + + [TestMethod] + public void multiple_space() => Tests(" ", " "); + + [TestMethod] + [DataRow("1", "")] + [DataRow("1 ", "1")] + [DataRow("12", "1")] + [DataRow("123", "12")] + public void Tests(string input, string expected) + => FileUtility.RemoveLastCharacter(input).Should().Be(expected); + } }