parent
276f59ae8c
commit
d50e08b1e3
@ -0,0 +1,116 @@
|
|||||||
|
using System.IO.Abstractions;
|
||||||
|
using System.IO.Abstractions.TestingHelpers;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using Common.Extensions;
|
||||||
|
using FluentAssertions;
|
||||||
|
using NUnit.Framework;
|
||||||
|
|
||||||
|
namespace Common.Tests.Extensions;
|
||||||
|
|
||||||
|
[TestFixture]
|
||||||
|
[Parallelizable(ParallelScope.All)]
|
||||||
|
public class FileSystemExtensionsTest
|
||||||
|
{
|
||||||
|
private static IEnumerable<string> ReRootFiles(IFileSystem fs, IEnumerable<string> files,
|
||||||
|
string oldRoot, string newRoot)
|
||||||
|
{
|
||||||
|
return files.Select(x =>
|
||||||
|
{
|
||||||
|
var strippedPath = Regex.Replace(x, $"^{oldRoot}", newRoot);
|
||||||
|
return fs.Path.GetFullPath(strippedPath);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ICollection<string> NormalizePaths(IEnumerable<string> paths)
|
||||||
|
=> paths.Select(NormalizePath).ToList();
|
||||||
|
|
||||||
|
private static string NormalizePath(string path)
|
||||||
|
{
|
||||||
|
if (MockUnixSupport.IsUnixPlatform())
|
||||||
|
{
|
||||||
|
return Regex.Replace(path, @"^C:\\", "/").Replace("\\", "/");
|
||||||
|
}
|
||||||
|
|
||||||
|
return Regex.Replace(path, @"^/", @"C:\").Replace("/", "\\");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static MockFileSystem NewMockFileSystem(IEnumerable<string> files, string cwd)
|
||||||
|
{
|
||||||
|
return NewMockFileSystem(files, Array.Empty<string>(), cwd);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static MockFileSystem NewMockFileSystem(IEnumerable<string> files, IEnumerable<string> dirs, string cwd)
|
||||||
|
{
|
||||||
|
var dirData = dirs.Select(x => (x, (MockFileData) new MockDirectoryData()));
|
||||||
|
var fileData = files.Select(x => (x, new MockFileData("")));
|
||||||
|
|
||||||
|
return new MockFileSystem(fileData.Concat(dirData)
|
||||||
|
.ToDictionary(x => x.Item1, y => y.Item2), NormalizePath(cwd));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Merge_directories_works()
|
||||||
|
{
|
||||||
|
var files = NormalizePaths(new[]
|
||||||
|
{
|
||||||
|
@"path1\1\file1.txt",
|
||||||
|
@"path1\1\file2.txt",
|
||||||
|
@"path1\1\2\3\4\file3.txt",
|
||||||
|
@"path1\file4.txt"
|
||||||
|
});
|
||||||
|
|
||||||
|
var dirs = NormalizePaths(new[]
|
||||||
|
{
|
||||||
|
@"path1\empty1",
|
||||||
|
@"path1\empty2",
|
||||||
|
@"path1\1\2\empty3",
|
||||||
|
@"path1\1\2\3\4\empty4"
|
||||||
|
});
|
||||||
|
|
||||||
|
var fs = NewMockFileSystem(files, dirs, @"C:\root\path");
|
||||||
|
|
||||||
|
fs.MergeDirectory("path1", "path2");
|
||||||
|
|
||||||
|
fs.AllDirectories.Select(MockUnixSupport.Path).Should()
|
||||||
|
.NotContain(x => x.Contains("path1") || x.Contains("empty"));
|
||||||
|
|
||||||
|
fs.AllFiles.Should().BeEquivalentTo(ReRootFiles(fs, files, "path1", "path2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Fail_if_file_already_exists()
|
||||||
|
{
|
||||||
|
var files = NormalizePaths(new[]
|
||||||
|
{
|
||||||
|
@"path1\1\file1.txt",
|
||||||
|
@"path1\1\file2.txt",
|
||||||
|
@"path2\1\file1.txt"
|
||||||
|
});
|
||||||
|
|
||||||
|
var fs = NewMockFileSystem(files, @"C:\root\path");
|
||||||
|
|
||||||
|
var act = () => fs.MergeDirectory("path1", "path2");
|
||||||
|
|
||||||
|
act.Should().Throw<IOException>();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Fail_if_directory_exists_where_file_goes()
|
||||||
|
{
|
||||||
|
var files = NormalizePaths(new[]
|
||||||
|
{
|
||||||
|
@"path1\1\file1"
|
||||||
|
});
|
||||||
|
|
||||||
|
var dirs = NormalizePaths(new[]
|
||||||
|
{
|
||||||
|
@"path2\1\file1"
|
||||||
|
});
|
||||||
|
|
||||||
|
var fs = NewMockFileSystem(files, dirs, @"C:\root\path");
|
||||||
|
|
||||||
|
var act = () => fs.MergeDirectory("path1", "path2");
|
||||||
|
|
||||||
|
act.Should().Throw<IOException>();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
using System.IO.Abstractions;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
namespace Common.Extensions;
|
||||||
|
|
||||||
|
public static class FileSystemExtensions
|
||||||
|
{
|
||||||
|
public static void MergeDirectory(this IFileSystem fs, string targetDir, string destDir)
|
||||||
|
{
|
||||||
|
targetDir = fs.Path.GetFullPath(targetDir);
|
||||||
|
destDir = fs.Path.GetFullPath(destDir);
|
||||||
|
|
||||||
|
var directories = fs.DirectoryInfo.FromDirectoryName(targetDir)
|
||||||
|
.EnumerateDirectories("*", SearchOption.AllDirectories)
|
||||||
|
.Append(fs.DirectoryInfo.FromDirectoryName(targetDir))
|
||||||
|
.OrderByDescending(x => x.FullName.Count(y => y is '/' or '\\'));
|
||||||
|
|
||||||
|
foreach (var dir in directories)
|
||||||
|
{
|
||||||
|
foreach (var file in dir.EnumerateFiles())
|
||||||
|
{
|
||||||
|
var newPath = Regex.Replace(file.FullName, $"^{Regex.Escape(targetDir)}", destDir);
|
||||||
|
fs.Directory.CreateDirectory(fs.Path.GetDirectoryName(newPath));
|
||||||
|
file.MoveTo(newPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
dir.Delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in new issue