From 992c3a8deddfc02c648daa52eae6bfcf6eac562b Mon Sep 17 00:00:00 2001 From: Jens Weiermann Date: Wed, 19 Dec 2018 16:15:50 +0100 Subject: [PATCH 01/10] Fix (and test) for #429 --- .../DirectoryInfoTests.cs | 21 +++++++++++++++++++ .../DirectoryInfoWrapper.cs | 8 ++++++- 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 System.IO.Abstractions.TestingHelpers.Tests/DirectoryInfoTests.cs diff --git a/System.IO.Abstractions.TestingHelpers.Tests/DirectoryInfoTests.cs b/System.IO.Abstractions.TestingHelpers.Tests/DirectoryInfoTests.cs new file mode 100644 index 000000000..423b9565f --- /dev/null +++ b/System.IO.Abstractions.TestingHelpers.Tests/DirectoryInfoTests.cs @@ -0,0 +1,21 @@ +using NUnit.Framework; +using System; +using System.Collections.Generic; +using System.Text; + +namespace System.IO.Abstractions.TestingHelpers.Tests +{ + [TestFixture] + public class DirectoryInfoTests + { + [Test] + public void Parent_ForRootDirectory_ShouldReturnNull() + { + var wrapperFilesystem = new FileSystem(); + + var directoryInfo = wrapperFilesystem.DirectoryInfo.FromDirectoryName("C:\\"); + var rootsParent = directoryInfo.Parent; + Assert.IsNull(rootsParent); + } + } +} diff --git a/System.IO.Abstractions/DirectoryInfoWrapper.cs b/System.IO.Abstractions/DirectoryInfoWrapper.cs index ec7e4d5e8..6eaa8db85 100644 --- a/System.IO.Abstractions/DirectoryInfoWrapper.cs +++ b/System.IO.Abstractions/DirectoryInfoWrapper.cs @@ -227,7 +227,13 @@ public override void SetAccessControl(DirectorySecurity directorySecurity) public override DirectoryInfoBase Parent { - get { return new DirectoryInfoWrapper(FileSystem, instance.Parent); } + get + { + if (instance.Parent == null) + return null; + else + return new DirectoryInfoWrapper(FileSystem, instance.Parent); + } } public override DirectoryInfoBase Root From 9d716b7bba692115611ae8d5b8d31642c0be0758 Mon Sep 17 00:00:00 2001 From: Jens Weiermann Date: Wed, 19 Dec 2018 16:30:05 +0100 Subject: [PATCH 02/10] Updated test to (hopfully) also work on linux machines --- .../DirectoryInfoTests.cs | 5 +++-- System.IO.Abstractions/DirectoryInfoWrapper.cs | 4 ++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/System.IO.Abstractions.TestingHelpers.Tests/DirectoryInfoTests.cs b/System.IO.Abstractions.TestingHelpers.Tests/DirectoryInfoTests.cs index 423b9565f..820b2d66a 100644 --- a/System.IO.Abstractions.TestingHelpers.Tests/DirectoryInfoTests.cs +++ b/System.IO.Abstractions.TestingHelpers.Tests/DirectoryInfoTests.cs @@ -13,8 +13,9 @@ public void Parent_ForRootDirectory_ShouldReturnNull() { var wrapperFilesystem = new FileSystem(); - var directoryInfo = wrapperFilesystem.DirectoryInfo.FromDirectoryName("C:\\"); - var rootsParent = directoryInfo.Parent; + var current = wrapperFilesystem.Directory.GetCurrentDirectory(); + var root = wrapperFilesystem.DirectoryInfo.FromDirectoryName(current).Root; + var rootsParent = root.Parent; Assert.IsNull(rootsParent); } } diff --git a/System.IO.Abstractions/DirectoryInfoWrapper.cs b/System.IO.Abstractions/DirectoryInfoWrapper.cs index 6eaa8db85..2fe120a22 100644 --- a/System.IO.Abstractions/DirectoryInfoWrapper.cs +++ b/System.IO.Abstractions/DirectoryInfoWrapper.cs @@ -230,9 +230,13 @@ public override DirectoryInfoBase Parent get { if (instance.Parent == null) + { return null; + } else + { return new DirectoryInfoWrapper(FileSystem, instance.Parent); + } } } From 1375888d06b880f7125ba8ebd69ec9e7020c4814 Mon Sep 17 00:00:00 2001 From: Jens Weiermann Date: Wed, 6 Mar 2019 16:49:32 +0100 Subject: [PATCH 03/10] added IFileSystemWatcher --- .../MockFileSystemTests.cs | 4 ++-- .../MockFileSystemWatcherFactory.cs | 4 ++-- .../FileSystemWatcherBase.cs | 2 +- .../FileSystemWatcherFactory.cs | 4 ++-- System.IO.Abstractions/IFileSystemWatcher.cs | 21 +++++++++++++++++++ .../IFileSystemWatcherFactory.cs | 4 ++-- 6 files changed, 30 insertions(+), 9 deletions(-) create mode 100644 System.IO.Abstractions/IFileSystemWatcher.cs diff --git a/System.IO.Abstractions.TestingHelpers.Tests/MockFileSystemTests.cs b/System.IO.Abstractions.TestingHelpers.Tests/MockFileSystemTests.cs index 108ef2fe7..d5fd008be 100644 --- a/System.IO.Abstractions.TestingHelpers.Tests/MockFileSystemTests.cs +++ b/System.IO.Abstractions.TestingHelpers.Tests/MockFileSystemTests.cs @@ -352,8 +352,8 @@ public void MockFileSystem_FileSystemWatcher_ShouldBeAssignable() private class TestFileSystemWatcherFactory : IFileSystemWatcherFactory { - public FileSystemWatcherBase CreateNew() => new TestFileSystemWatcher(null); - public FileSystemWatcherBase FromPath(string path) => new TestFileSystemWatcher(path); + public IFileSystemWatcher CreateNew() => new TestFileSystemWatcher(null); + public IFileSystemWatcher FromPath(string path) => new TestFileSystemWatcher(path); } private class TestFileSystemWatcher : FileSystemWatcherBase diff --git a/System.IO.Abstractions.TestingHelpers/MockFileSystemWatcherFactory.cs b/System.IO.Abstractions.TestingHelpers/MockFileSystemWatcherFactory.cs index fa832ba13..247114442 100644 --- a/System.IO.Abstractions.TestingHelpers/MockFileSystemWatcherFactory.cs +++ b/System.IO.Abstractions.TestingHelpers/MockFileSystemWatcherFactory.cs @@ -3,10 +3,10 @@ [Serializable] public class MockFileSystemWatcherFactory : IFileSystemWatcherFactory { - public FileSystemWatcherBase CreateNew() => + public IFileSystemWatcher CreateNew() => throw new NotImplementedException(StringResources.Manager.GetString("FILE_SYSTEM_WATCHER_NOT_IMPLEMENTED_EXCEPTION")); - public FileSystemWatcherBase FromPath(string path) => + public IFileSystemWatcher FromPath(string path) => throw new NotImplementedException(StringResources.Manager.GetString("FILE_SYSTEM_WATCHER_NOT_IMPLEMENTED_EXCEPTION")); } } diff --git a/System.IO.Abstractions/FileSystemWatcherBase.cs b/System.IO.Abstractions/FileSystemWatcherBase.cs index cca10924d..5d7db3d94 100644 --- a/System.IO.Abstractions/FileSystemWatcherBase.cs +++ b/System.IO.Abstractions/FileSystemWatcherBase.cs @@ -4,7 +4,7 @@ namespace System.IO.Abstractions { /// [Serializable] - public abstract class FileSystemWatcherBase : IDisposable + public abstract class FileSystemWatcherBase : IDisposable, IFileSystemWatcher { /// public abstract bool IncludeSubdirectories { get; set; } diff --git a/System.IO.Abstractions/FileSystemWatcherFactory.cs b/System.IO.Abstractions/FileSystemWatcherFactory.cs index f42a37e11..c18e5c460 100644 --- a/System.IO.Abstractions/FileSystemWatcherFactory.cs +++ b/System.IO.Abstractions/FileSystemWatcherFactory.cs @@ -8,12 +8,12 @@ namespace System.IO.Abstractions [Serializable] public class FileSystemWatcherFactory : IFileSystemWatcherFactory { - public FileSystemWatcherBase CreateNew() + public IFileSystemWatcher CreateNew() { return new FileSystemWatcherWrapper(); } - public FileSystemWatcherBase FromPath(string path) + public IFileSystemWatcher FromPath(string path) { return new FileSystemWatcherWrapper(path); } diff --git a/System.IO.Abstractions/IFileSystemWatcher.cs b/System.IO.Abstractions/IFileSystemWatcher.cs new file mode 100644 index 000000000..ce77a2bb6 --- /dev/null +++ b/System.IO.Abstractions/IFileSystemWatcher.cs @@ -0,0 +1,21 @@ +namespace System.IO.Abstractions +{ + public interface IFileSystemWatcher + { + bool EnableRaisingEvents { get; set; } + string Filter { get; set; } + bool IncludeSubdirectories { get; set; } + int InternalBufferSize { get; set; } + NotifyFilters NotifyFilter { get; set; } + string Path { get; set; } + + event FileSystemEventHandler Changed; + event FileSystemEventHandler Created; + event FileSystemEventHandler Deleted; + event ErrorEventHandler Error; + event RenamedEventHandler Renamed; + + WaitForChangedResult WaitForChanged(WatcherChangeTypes changeType); + WaitForChangedResult WaitForChanged(WatcherChangeTypes changeType, int timeout); + } +} \ No newline at end of file diff --git a/System.IO.Abstractions/IFileSystemWatcherFactory.cs b/System.IO.Abstractions/IFileSystemWatcherFactory.cs index b947c93a5..e9612b206 100644 --- a/System.IO.Abstractions/IFileSystemWatcherFactory.cs +++ b/System.IO.Abstractions/IFileSystemWatcherFactory.cs @@ -11,13 +11,13 @@ public interface IFileSystemWatcherFactory /// Initializes a new instance of the class, which acts as a wrapper for a FileSystemWatcher /// /// - FileSystemWatcherBase CreateNew(); + IFileSystemWatcher CreateNew(); /// /// Initializes a new instance of the class, which acts as a wrapper for a FileSystemWatcher /// /// Path to generate the FileSystemWatcherBase for /// - FileSystemWatcherBase FromPath(string path); + IFileSystemWatcher FromPath(string path); } } From 565a75e315d344d2847c552d9b95b5bd0b9b52c4 Mon Sep 17 00:00:00 2001 From: Jens Weiermann Date: Thu, 7 Mar 2019 09:39:02 +0100 Subject: [PATCH 04/10] Added IFile and IDirectory interfaces --- .../MockDirectoryArgumentPathTests.cs | 4 +- .../MockFileArgumentPathTests.cs | 4 +- .../IMockFileDataAccessor.cs | 4 +- .../MockFileSystem.cs | 4 +- System.IO.Abstractions/DirectoryBase.cs | 2 +- System.IO.Abstractions/FileBase.cs | 2 +- System.IO.Abstractions/FileSystem.cs | 4 +- System.IO.Abstractions/IDirectory.cs | 58 +++++++++++++++ System.IO.Abstractions/IFile.cs | 70 +++++++++++++++++++ System.IO.Abstractions/IFileSystem.cs | 4 +- 10 files changed, 142 insertions(+), 14 deletions(-) create mode 100644 System.IO.Abstractions/IDirectory.cs create mode 100644 System.IO.Abstractions/IFile.cs diff --git a/System.IO.Abstractions.TestingHelpers.Tests/MockDirectoryArgumentPathTests.cs b/System.IO.Abstractions.TestingHelpers.Tests/MockDirectoryArgumentPathTests.cs index b390fbf70..a9401f093 100644 --- a/System.IO.Abstractions.TestingHelpers.Tests/MockDirectoryArgumentPathTests.cs +++ b/System.IO.Abstractions.TestingHelpers.Tests/MockDirectoryArgumentPathTests.cs @@ -6,7 +6,7 @@ namespace System.IO.Abstractions.TestingHelpers.Tests { public class MockDirectoryArgumentPathTests { - private static IEnumerable> GetFileSystemActionsForArgumentNullException() + private static IEnumerable> GetFileSystemActionsForArgumentNullException() { yield return ds => ds.Delete(null); yield return ds => ds.Delete(null, true); @@ -26,7 +26,7 @@ private static IEnumerable> GetFileSystemActionsForArgumen } [TestCaseSource("GetFileSystemActionsForArgumentNullException")] - public void Operations_ShouldThrowArgumentNullExceptionIfPathIsNull(Action action) + public void Operations_ShouldThrowArgumentNullExceptionIfPathIsNull(Action action) { // Arrange var fileSystem = new MockFileSystem(); diff --git a/System.IO.Abstractions.TestingHelpers.Tests/MockFileArgumentPathTests.cs b/System.IO.Abstractions.TestingHelpers.Tests/MockFileArgumentPathTests.cs index 0d97899f7..8e368689b 100644 --- a/System.IO.Abstractions.TestingHelpers.Tests/MockFileArgumentPathTests.cs +++ b/System.IO.Abstractions.TestingHelpers.Tests/MockFileArgumentPathTests.cs @@ -7,7 +7,7 @@ namespace System.IO.Abstractions.TestingHelpers.Tests { public class MockFileArgumentPathTests { - private static IEnumerable> GetFileSystemActionsForArgumentNullException() + private static IEnumerable> GetFileSystemActionsForArgumentNullException() { yield return fs => fs.AppendAllLines(null, new[] { "does not matter" }); yield return fs => fs.AppendAllLines(null, new[] { "does not matter" }, Encoding.ASCII); @@ -57,7 +57,7 @@ private static IEnumerable> GetFileSystemActionsForArgumentNull } [TestCaseSource("GetFileSystemActionsForArgumentNullException")] - public void Operations_ShouldThrowArgumentNullExceptionIfPathIsNull(Action action) + public void Operations_ShouldThrowArgumentNullExceptionIfPathIsNull(Action action) { // Arrange var fileSystem = new MockFileSystem(); diff --git a/System.IO.Abstractions.TestingHelpers/IMockFileDataAccessor.cs b/System.IO.Abstractions.TestingHelpers/IMockFileDataAccessor.cs index 6c2c6350a..d61691784 100644 --- a/System.IO.Abstractions.TestingHelpers/IMockFileDataAccessor.cs +++ b/System.IO.Abstractions.TestingHelpers/IMockFileDataAccessor.cs @@ -56,8 +56,8 @@ public interface IMockFileDataAccessor StringOperations StringOperations { get; } - FileBase File { get; } - DirectoryBase Directory { get; } + IFile File { get; } + IDirectory Directory { get; } IFileInfoFactory FileInfo {get; } PathBase Path { get; } IDirectoryInfoFactory DirectoryInfo { get; } diff --git a/System.IO.Abstractions.TestingHelpers/MockFileSystem.cs b/System.IO.Abstractions.TestingHelpers/MockFileSystem.cs index d4bde1869..ebe53c614 100644 --- a/System.IO.Abstractions.TestingHelpers/MockFileSystem.cs +++ b/System.IO.Abstractions.TestingHelpers/MockFileSystem.cs @@ -53,8 +53,8 @@ public MockFileSystem(IDictionary files, string currentDir } public StringOperations StringOperations { get; } - public FileBase File { get; } - public DirectoryBase Directory { get; } + public IFile File { get; } + public IDirectory Directory { get; } public IFileInfoFactory FileInfo { get; } public IFileStreamFactory FileStream { get; } public PathBase Path { get; } diff --git a/System.IO.Abstractions/DirectoryBase.cs b/System.IO.Abstractions/DirectoryBase.cs index c4a9b08fc..9250e1b2b 100644 --- a/System.IO.Abstractions/DirectoryBase.cs +++ b/System.IO.Abstractions/DirectoryBase.cs @@ -5,7 +5,7 @@ namespace System.IO.Abstractions { /// [Serializable] - public abstract class DirectoryBase + public abstract class DirectoryBase : IDirectory { protected DirectoryBase(IFileSystem fileSystem) { diff --git a/System.IO.Abstractions/FileBase.cs b/System.IO.Abstractions/FileBase.cs index 0c6626163..0716ef500 100644 --- a/System.IO.Abstractions/FileBase.cs +++ b/System.IO.Abstractions/FileBase.cs @@ -6,7 +6,7 @@ namespace System.IO.Abstractions { /// [Serializable] - public abstract class FileBase + public abstract class FileBase : IFile { protected FileBase(IFileSystem fileSystem) { diff --git a/System.IO.Abstractions/FileSystem.cs b/System.IO.Abstractions/FileSystem.cs index 144876350..cf09a1be6 100644 --- a/System.IO.Abstractions/FileSystem.cs +++ b/System.IO.Abstractions/FileSystem.cs @@ -15,9 +15,9 @@ public FileSystem() FileSystemWatcher = new FileSystemWatcherFactory(); } - public DirectoryBase Directory { get; } + public IDirectory Directory { get; } - public FileBase File { get; } + public IFile File { get; } public IFileInfoFactory FileInfo { get; } diff --git a/System.IO.Abstractions/IDirectory.cs b/System.IO.Abstractions/IDirectory.cs new file mode 100644 index 000000000..631f310d9 --- /dev/null +++ b/System.IO.Abstractions/IDirectory.cs @@ -0,0 +1,58 @@ +using System.Collections.Generic; +using System.Security.AccessControl; + +namespace System.IO.Abstractions +{ + public interface IDirectory + { + IFileSystem FileSystem { get; } + + DirectoryInfoBase CreateDirectory(string path); + void Delete(string path); + void Delete(string path, bool recursive); + IEnumerable EnumerateDirectories(string path); + IEnumerable EnumerateDirectories(string path, string searchPattern); + IEnumerable EnumerateDirectories(string path, string searchPattern, SearchOption searchOption); + IEnumerable EnumerateFiles(string path); + IEnumerable EnumerateFiles(string path, string searchPattern); + IEnumerable EnumerateFiles(string path, string searchPattern, SearchOption searchOption); + IEnumerable EnumerateFileSystemEntries(string path); + IEnumerable EnumerateFileSystemEntries(string path, string searchPattern); + IEnumerable EnumerateFileSystemEntries(string path, string searchPattern, SearchOption searchOption); + bool Exists(string path); + DirectorySecurity GetAccessControl(string path); + DirectorySecurity GetAccessControl(string path, AccessControlSections includeSections); + DateTime GetCreationTime(string path); + DateTime GetCreationTimeUtc(string path); + string GetCurrentDirectory(); + string[] GetDirectories(string path); + string[] GetDirectories(string path, string searchPattern); + string[] GetDirectories(string path, string searchPattern, SearchOption searchOption); + string GetDirectoryRoot(string path); + string[] GetFiles(string path); + string[] GetFiles(string path, string searchPattern); + string[] GetFiles(string path, string searchPattern, SearchOption searchOption); + string[] GetFileSystemEntries(string path); + string[] GetFileSystemEntries(string path, string searchPattern); + DateTime GetLastAccessTime(string path); + DateTime GetLastAccessTimeUtc(string path); + DateTime GetLastWriteTime(string path); + DateTime GetLastWriteTimeUtc(string path); + DirectoryInfoBase GetParent(string path); + void Move(string sourceDirName, string destDirName); + void SetAccessControl(string path, DirectorySecurity directorySecurity); + void SetCreationTime(string path, DateTime creationTime); + void SetCreationTimeUtc(string path, DateTime creationTimeUtc); + void SetCurrentDirectory(string path); + void SetLastAccessTime(string path, DateTime lastAccessTime); + void SetLastAccessTimeUtc(string path, DateTime lastAccessTimeUtc); + void SetLastWriteTime(string path, DateTime lastWriteTime); + void SetLastWriteTimeUtc(string path, DateTime lastWriteTimeUtc); + +#if NET40 + DirectoryInfoBase CreateDirectory(string path, DirectorySecurity directorySecurity); + string[] GetLogicalDrives(); +#endif + + } +} \ No newline at end of file diff --git a/System.IO.Abstractions/IFile.cs b/System.IO.Abstractions/IFile.cs new file mode 100644 index 000000000..246cf78ce --- /dev/null +++ b/System.IO.Abstractions/IFile.cs @@ -0,0 +1,70 @@ +using System.Collections.Generic; +using System.Security.AccessControl; +using System.Text; + +namespace System.IO.Abstractions +{ + public interface IFile + { + IFileSystem FileSystem { get; } + + void AppendAllLines(string path, IEnumerable contents); + void AppendAllLines(string path, IEnumerable contents, Encoding encoding); + void AppendAllText(string path, string contents); + void AppendAllText(string path, string contents, Encoding encoding); + StreamWriter AppendText(string path); + void Copy(string sourceFileName, string destFileName); + void Copy(string sourceFileName, string destFileName, bool overwrite); + Stream Create(string path); + Stream Create(string path, int bufferSize); + Stream Create(string path, int bufferSize, FileOptions options); + StreamWriter CreateText(string path); + void Delete(string path); + bool Exists(string path); + FileSecurity GetAccessControl(string path); + FileSecurity GetAccessControl(string path, AccessControlSections includeSections); + FileAttributes GetAttributes(string path); + DateTime GetCreationTime(string path); + DateTime GetCreationTimeUtc(string path); + DateTime GetLastAccessTime(string path); + DateTime GetLastAccessTimeUtc(string path); + DateTime GetLastWriteTime(string path); + DateTime GetLastWriteTimeUtc(string path); + void Move(string sourceFileName, string destFileName); + Stream Open(string path, FileMode mode); + Stream Open(string path, FileMode mode, FileAccess access); + Stream Open(string path, FileMode mode, FileAccess access, FileShare share); + Stream OpenRead(string path); + StreamReader OpenText(string path); + Stream OpenWrite(string path); + byte[] ReadAllBytes(string path); + string[] ReadAllLines(string path); + string[] ReadAllLines(string path, Encoding encoding); + string ReadAllText(string path); + string ReadAllText(string path, Encoding encoding); + IEnumerable ReadLines(string path); + IEnumerable ReadLines(string path, Encoding encoding); + void SetAccessControl(string path, FileSecurity fileSecurity); + void SetAttributes(string path, FileAttributes fileAttributes); + void SetCreationTime(string path, DateTime creationTime); + void SetCreationTimeUtc(string path, DateTime creationTimeUtc); + void SetLastAccessTime(string path, DateTime lastAccessTime); + void SetLastAccessTimeUtc(string path, DateTime lastAccessTimeUtc); + void SetLastWriteTime(string path, DateTime lastWriteTime); + void SetLastWriteTimeUtc(string path, DateTime lastWriteTimeUtc); + void WriteAllBytes(string path, byte[] bytes); + void WriteAllLines(string path, IEnumerable contents); + void WriteAllLines(string path, IEnumerable contents, Encoding encoding); + void WriteAllLines(string path, string[] contents); + void WriteAllLines(string path, string[] contents, Encoding encoding); + void WriteAllText(string path, string contents); + void WriteAllText(string path, string contents, Encoding encoding); + +#if NET40 + void Decrypt(string path); + void Encrypt(string path); + void Replace(string sourceFileName, string destinationFileName, string destinationBackupFileName); + void Replace(string sourceFileName, string destinationFileName, string destinationBackupFileName, bool ignoreMetadataErrors); +#endif + } +} \ No newline at end of file diff --git a/System.IO.Abstractions/IFileSystem.cs b/System.IO.Abstractions/IFileSystem.cs index 32472125e..ce432f0e7 100644 --- a/System.IO.Abstractions/IFileSystem.cs +++ b/System.IO.Abstractions/IFileSystem.cs @@ -2,8 +2,8 @@ { public interface IFileSystem { - FileBase File { get; } - DirectoryBase Directory { get; } + IFile File { get; } + IDirectory Directory { get; } IFileInfoFactory FileInfo { get; } IFileStreamFactory FileStream { get; } PathBase Path { get; } From 5dca0c29fd6522a75beb4538abf134bcfdef9ce6 Mon Sep 17 00:00:00 2001 From: Weiermann Date: Tue, 19 Mar 2019 17:37:35 +0100 Subject: [PATCH 05/10] Added IDirectoryInfo, IDriveInfo, IFileInfo, IFileSystemInfo and IPath and changed source accordingly --- .../IMockFileDataAccessor.cs | 2 +- .../MockDirectory.cs | 8 +- .../MockDirectoryInfo.cs | 48 +++++------ .../MockDirectoryInfoFactory.cs | 2 +- .../MockDriveInfo.cs | 2 +- .../MockDriveInfoFactory.cs | 4 +- .../MockFileInfo.cs | 12 +-- .../MockFileInfoFactory.cs | 2 +- .../MockFileSystem.cs | 2 +- System.IO.Abstractions/DirectoryBase.cs | 12 +-- System.IO.Abstractions/DirectoryInfoBase.cs | 48 ++++++----- .../DirectoryInfoFactory.cs | 2 +- .../DirectoryInfoWrapper.cs | 44 +++++----- System.IO.Abstractions/DirectoryWrapper.cs | 6 +- System.IO.Abstractions/DriveInfoBase.cs | 4 +- System.IO.Abstractions/DriveInfoFactory.cs | 4 +- System.IO.Abstractions/DriveInfoWrapper.cs | 2 +- System.IO.Abstractions/FileInfoBase.cs | 12 +-- System.IO.Abstractions/FileInfoFactory.cs | 2 +- System.IO.Abstractions/FileInfoWrapper.cs | 10 +-- System.IO.Abstractions/FileSystem.cs | 2 +- System.IO.Abstractions/FileSystemInfoBase.cs | 2 +- .../FileSystemWatcherBase.cs | 4 +- System.IO.Abstractions/IDirectory.cs | 81 +++++++++++++++---- System.IO.Abstractions/IDirectoryInfo.cs | 71 ++++++++++++++++ .../IDirectoryInfoFactory.cs | 2 +- System.IO.Abstractions/IDriveInfo.cs | 28 +++++++ System.IO.Abstractions/IDriveInfoFactory.cs | 4 +- System.IO.Abstractions/IFile.cs | 79 ++++++++++++++++-- System.IO.Abstractions/IFileInfo.cs | 58 +++++++++++++ System.IO.Abstractions/IFileInfoFactory.cs | 2 +- System.IO.Abstractions/IFileSystem.cs | 2 +- System.IO.Abstractions/IFileSystemInfo.cs | 36 +++++++++ System.IO.Abstractions/IFileSystemWatcher.cs | 37 ++++++++- System.IO.Abstractions/IPath.cs | 55 +++++++++++++ System.IO.Abstractions/PathBase.cs | 2 +- 36 files changed, 541 insertions(+), 152 deletions(-) create mode 100644 System.IO.Abstractions/IDirectoryInfo.cs create mode 100644 System.IO.Abstractions/IDriveInfo.cs create mode 100644 System.IO.Abstractions/IFileInfo.cs create mode 100644 System.IO.Abstractions/IFileSystemInfo.cs create mode 100644 System.IO.Abstractions/IPath.cs diff --git a/System.IO.Abstractions.TestingHelpers/IMockFileDataAccessor.cs b/System.IO.Abstractions.TestingHelpers/IMockFileDataAccessor.cs index d61691784..d42063fd8 100644 --- a/System.IO.Abstractions.TestingHelpers/IMockFileDataAccessor.cs +++ b/System.IO.Abstractions.TestingHelpers/IMockFileDataAccessor.cs @@ -59,7 +59,7 @@ public interface IMockFileDataAccessor IFile File { get; } IDirectory Directory { get; } IFileInfoFactory FileInfo {get; } - PathBase Path { get; } + IPath Path { get; } IDirectoryInfoFactory DirectoryInfo { get; } IDriveInfoFactory DriveInfo { get; } diff --git a/System.IO.Abstractions.TestingHelpers/MockDirectory.cs b/System.IO.Abstractions.TestingHelpers/MockDirectory.cs index cd3b2519b..cffef30ab 100644 --- a/System.IO.Abstractions.TestingHelpers/MockDirectory.cs +++ b/System.IO.Abstractions.TestingHelpers/MockDirectory.cs @@ -25,19 +25,19 @@ public MockDirectory(IMockFileDataAccessor mockFileDataAccessor, string currentD this.mockFileDataAccessor = mockFileDataAccessor ?? throw new ArgumentNullException(nameof(mockFileDataAccessor)); } - public override DirectoryInfoBase CreateDirectory(string path) + public override IDirectoryInfo CreateDirectory(string path) { return CreateDirectoryInternal(path, null); } #if NET40 - public override DirectoryInfoBase CreateDirectory(string path, DirectorySecurity directorySecurity) + public override IDirectoryInfo CreateDirectory(string path, DirectorySecurity directorySecurity) { return CreateDirectoryInternal(path, directorySecurity); } #endif - private DirectoryInfoBase CreateDirectoryInternal(string path, DirectorySecurity directorySecurity) + private IDirectoryInfo CreateDirectoryInternal(string path, DirectorySecurity directorySecurity) { if (path == null) { @@ -312,7 +312,7 @@ public override string[] GetLogicalDrives() } #endif - public override DirectoryInfoBase GetParent(string path) + public override IDirectoryInfo GetParent(string path) { if (path == null) { diff --git a/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs b/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs index a105d2217..ac6c94ad4 100644 --- a/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs +++ b/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs @@ -127,13 +127,13 @@ public override void Create(DirectorySecurity directorySecurity) } #endif - public override DirectoryInfoBase CreateSubdirectory(string path) + public override IDirectoryInfo CreateSubdirectory(string path) { return mockFileDataAccessor.Directory.CreateDirectory(Path.Combine(FullName, path)); } #if NET40 - public override DirectoryInfoBase CreateSubdirectory(string path, DirectorySecurity directorySecurity) + public override IDirectoryInfo CreateSubdirectory(string path, DirectorySecurity directorySecurity) { return mockFileDataAccessor.Directory.CreateDirectory(Path.Combine(FullName, path), directorySecurity); } @@ -144,47 +144,47 @@ public override void Delete(bool recursive) mockFileDataAccessor.Directory.Delete(directoryPath, recursive); } - public override IEnumerable EnumerateDirectories() + public override IEnumerable EnumerateDirectories() { return GetDirectories(); } - public override IEnumerable EnumerateDirectories(string searchPattern) + public override IEnumerable EnumerateDirectories(string searchPattern) { return GetDirectories(searchPattern); } - public override IEnumerable EnumerateDirectories(string searchPattern, SearchOption searchOption) + public override IEnumerable EnumerateDirectories(string searchPattern, SearchOption searchOption) { return GetDirectories(searchPattern, searchOption); } - public override IEnumerable EnumerateFiles() + public override IEnumerable EnumerateFiles() { return GetFiles(); } - public override IEnumerable EnumerateFiles(string searchPattern) + public override IEnumerable EnumerateFiles(string searchPattern) { return GetFiles(searchPattern); } - public override IEnumerable EnumerateFiles(string searchPattern, SearchOption searchOption) + public override IEnumerable EnumerateFiles(string searchPattern, SearchOption searchOption) { return GetFiles(searchPattern, searchOption); } - public override IEnumerable EnumerateFileSystemInfos() + public override IEnumerable EnumerateFileSystemInfos() { return GetFileSystemInfos(); } - public override IEnumerable EnumerateFileSystemInfos(string searchPattern) + public override IEnumerable EnumerateFileSystemInfos(string searchPattern) { return GetFileSystemInfos(searchPattern); } - public override IEnumerable EnumerateFileSystemInfos(string searchPattern, SearchOption searchOption) + public override IEnumerable EnumerateFileSystemInfos(string searchPattern, SearchOption searchOption) { return GetFileSystemInfos(searchPattern, searchOption); } @@ -199,17 +199,17 @@ public override DirectorySecurity GetAccessControl(AccessControlSections include return mockFileDataAccessor.Directory.GetAccessControl(directoryPath, includeSections); } - public override DirectoryInfoBase[] GetDirectories() + public override IDirectoryInfo[] GetDirectories() { return ConvertStringsToDirectories(mockFileDataAccessor.Directory.GetDirectories(directoryPath)); } - public override DirectoryInfoBase[] GetDirectories(string searchPattern) + public override IDirectoryInfo[] GetDirectories(string searchPattern) { return ConvertStringsToDirectories(mockFileDataAccessor.Directory.GetDirectories(directoryPath, searchPattern)); } - public override DirectoryInfoBase[] GetDirectories(string searchPattern, SearchOption searchOption) + public override IDirectoryInfo[] GetDirectories(string searchPattern, SearchOption searchOption) { return ConvertStringsToDirectories(mockFileDataAccessor.Directory.GetDirectories(directoryPath, searchPattern, searchOption)); } @@ -222,41 +222,41 @@ private DirectoryInfoBase[] ConvertStringsToDirectories(IEnumerable path .ToArray(); } - public override FileInfoBase[] GetFiles() + public override IFileInfo[] GetFiles() { return ConvertStringsToFiles(mockFileDataAccessor.Directory.GetFiles(FullName)); } - public override FileInfoBase[] GetFiles(string searchPattern) + public override IFileInfo[] GetFiles(string searchPattern) { return ConvertStringsToFiles(mockFileDataAccessor.Directory.GetFiles(FullName, searchPattern)); } - public override FileInfoBase[] GetFiles(string searchPattern, SearchOption searchOption) + public override IFileInfo[] GetFiles(string searchPattern, SearchOption searchOption) { return ConvertStringsToFiles(mockFileDataAccessor.Directory.GetFiles(FullName, searchPattern, searchOption)); } - FileInfoBase[] ConvertStringsToFiles(IEnumerable paths) + IFileInfo[] ConvertStringsToFiles(IEnumerable paths) { return paths .Select(mockFileDataAccessor.FileInfo.FromFileName) .ToArray(); } - public override FileSystemInfoBase[] GetFileSystemInfos() + public override IFileSystemInfo[] GetFileSystemInfos() { return GetFileSystemInfos("*"); } - public override FileSystemInfoBase[] GetFileSystemInfos(string searchPattern) + public override IFileSystemInfo[] GetFileSystemInfos(string searchPattern) { return GetFileSystemInfos(searchPattern, SearchOption.TopDirectoryOnly); } - public override FileSystemInfoBase[] GetFileSystemInfos(string searchPattern, SearchOption searchOption) + public override IFileSystemInfo[] GetFileSystemInfos(string searchPattern, SearchOption searchOption) { - return GetDirectories(searchPattern, searchOption).OfType().Concat(GetFiles(searchPattern, searchOption)).ToArray(); + return GetDirectories(searchPattern, searchOption).OfType().Concat(GetFiles(searchPattern, searchOption)).ToArray(); } public override void MoveTo(string destDirName) @@ -269,7 +269,7 @@ public override void SetAccessControl(DirectorySecurity directorySecurity) mockFileDataAccessor.Directory.SetAccessControl(directoryPath, directorySecurity); } - public override DirectoryInfoBase Parent + public override IDirectoryInfo Parent { get { @@ -277,7 +277,7 @@ public override DirectoryInfoBase Parent } } - public override DirectoryInfoBase Root + public override IDirectoryInfo Root { get { diff --git a/System.IO.Abstractions.TestingHelpers/MockDirectoryInfoFactory.cs b/System.IO.Abstractions.TestingHelpers/MockDirectoryInfoFactory.cs index 51f638feb..b42080e37 100644 --- a/System.IO.Abstractions.TestingHelpers/MockDirectoryInfoFactory.cs +++ b/System.IO.Abstractions.TestingHelpers/MockDirectoryInfoFactory.cs @@ -10,7 +10,7 @@ public MockDirectoryInfoFactory(IMockFileDataAccessor mockFileSystem) this.mockFileSystem = mockFileSystem; } - public DirectoryInfoBase FromDirectoryName(string directoryName) + public IDirectoryInfo FromDirectoryName(string directoryName) { return new MockDirectoryInfo(mockFileSystem, directoryName); } diff --git a/System.IO.Abstractions.TestingHelpers/MockDriveInfo.cs b/System.IO.Abstractions.TestingHelpers/MockDriveInfo.cs index 61ec413b4..6b9d8a870 100644 --- a/System.IO.Abstractions.TestingHelpers/MockDriveInfo.cs +++ b/System.IO.Abstractions.TestingHelpers/MockDriveInfo.cs @@ -44,7 +44,7 @@ public MockDriveInfo(IMockFileDataAccessor mockFileDataAccessor, string name) : public new bool IsReady { get; protected set; } public override string Name { get; protected set; } - public override DirectoryInfoBase RootDirectory + public override IDirectoryInfo RootDirectory { get { diff --git a/System.IO.Abstractions.TestingHelpers/MockDriveInfoFactory.cs b/System.IO.Abstractions.TestingHelpers/MockDriveInfoFactory.cs index bd1596a00..adc8cb0d5 100644 --- a/System.IO.Abstractions.TestingHelpers/MockDriveInfoFactory.cs +++ b/System.IO.Abstractions.TestingHelpers/MockDriveInfoFactory.cs @@ -12,7 +12,7 @@ public MockDriveInfoFactory(IMockFileDataAccessor mockFileSystem) this.mockFileSystem = mockFileSystem ?? throw new ArgumentNullException(nameof(mockFileSystem)); } - public DriveInfoBase[] GetDrives() + public IDriveInfo[] GetDrives() { var driveLetters = new HashSet(new DriveEqualityComparer(mockFileSystem)); foreach (var path in mockFileSystem.AllPaths) @@ -38,7 +38,7 @@ public DriveInfoBase[] GetDrives() return result.ToArray(); } - public DriveInfoBase FromDriveName(string driveName) + public IDriveInfo FromDriveName(string driveName) { var drive = mockFileSystem.Path.GetPathRoot(driveName); diff --git a/System.IO.Abstractions.TestingHelpers/MockFileInfo.cs b/System.IO.Abstractions.TestingHelpers/MockFileInfo.cs index 03d7e809e..5b61106d5 100644 --- a/System.IO.Abstractions.TestingHelpers/MockFileInfo.cs +++ b/System.IO.Abstractions.TestingHelpers/MockFileInfo.cs @@ -153,12 +153,12 @@ public override StreamWriter AppendText() return new StreamWriter(new MockFileStream(mockFileSystem, FullName, MockFileStream.StreamType.APPEND)); } - public override FileInfoBase CopyTo(string destFileName) + public override IFileInfo CopyTo(string destFileName) { return CopyTo(destFileName, false); } - public override FileInfoBase CopyTo(string destFileName, bool overwrite) + public override IFileInfo CopyTo(string destFileName, bool overwrite) { if (!Exists) { @@ -210,7 +210,7 @@ public override FileSecurity GetAccessControl(AccessControlSections includeSecti public override void MoveTo(string destFileName) { - var movedFileInfo = CopyTo(destFileName); + var movedFileInfo = CopyTo(destFileName) as MockFileInfo; if (destFileName == FullName) { return; @@ -251,12 +251,12 @@ public override Stream OpenWrite() } #if NET40 - public override FileInfoBase Replace(string destinationFileName, string destinationBackupFileName) + public override IFileInfo Replace(string destinationFileName, string destinationBackupFileName) { return Replace(destinationFileName, destinationBackupFileName, false); } - public override FileInfoBase Replace(string destinationFileName, string destinationBackupFileName, bool ignoreMetadataErrors) + public override IFileInfo Replace(string destinationFileName, string destinationBackupFileName, bool ignoreMetadataErrors) { mockFileSystem.File.Replace(path, destinationFileName, destinationBackupFileName, ignoreMetadataErrors); return mockFileSystem.FileInfo.FromFileName(destinationFileName); @@ -268,7 +268,7 @@ public override void SetAccessControl(FileSecurity fileSecurity) mockFileSystem.File.SetAccessControl(this.path, fileSecurity); } - public override DirectoryInfoBase Directory + public override IDirectoryInfo Directory { get { diff --git a/System.IO.Abstractions.TestingHelpers/MockFileInfoFactory.cs b/System.IO.Abstractions.TestingHelpers/MockFileInfoFactory.cs index ffdec272f..9c5504ccd 100644 --- a/System.IO.Abstractions.TestingHelpers/MockFileInfoFactory.cs +++ b/System.IO.Abstractions.TestingHelpers/MockFileInfoFactory.cs @@ -10,7 +10,7 @@ public MockFileInfoFactory(IMockFileDataAccessor mockFileSystem) this.mockFileSystem = mockFileSystem ?? throw new ArgumentNullException(nameof(mockFileSystem)); } - public FileInfoBase FromFileName(string fileName) + public IFileInfo FromFileName(string fileName) { return new MockFileInfo(mockFileSystem, fileName); } diff --git a/System.IO.Abstractions.TestingHelpers/MockFileSystem.cs b/System.IO.Abstractions.TestingHelpers/MockFileSystem.cs index ebe53c614..dc301f859 100644 --- a/System.IO.Abstractions.TestingHelpers/MockFileSystem.cs +++ b/System.IO.Abstractions.TestingHelpers/MockFileSystem.cs @@ -57,7 +57,7 @@ public MockFileSystem(IDictionary files, string currentDir public IDirectory Directory { get; } public IFileInfoFactory FileInfo { get; } public IFileStreamFactory FileStream { get; } - public PathBase Path { get; } + public IPath Path { get; } public IDirectoryInfoFactory DirectoryInfo { get; } public IDriveInfoFactory DriveInfo { get; } public IFileSystemWatcherFactory FileSystemWatcher { get; set; } diff --git a/System.IO.Abstractions/DirectoryBase.cs b/System.IO.Abstractions/DirectoryBase.cs index 9250e1b2b..8c8283cdc 100644 --- a/System.IO.Abstractions/DirectoryBase.cs +++ b/System.IO.Abstractions/DirectoryBase.cs @@ -21,11 +21,11 @@ internal DirectoryBase() { } public IFileSystem FileSystem { get; } /// - public abstract DirectoryInfoBase CreateDirectory(string path); + public abstract IDirectoryInfo CreateDirectory(string path); #if NET40 /// - public abstract DirectoryInfoBase CreateDirectory(string path, DirectorySecurity directorySecurity); + public abstract IDirectoryInfo CreateDirectory(string path, DirectorySecurity directorySecurity); #endif /// @@ -97,7 +97,7 @@ internal DirectoryBase() { } #endif /// - public abstract DirectoryInfoBase GetParent(string path); + public abstract IDirectoryInfo GetParent(string path); /// public abstract void Move(string sourceDirName, string destDirName); @@ -127,13 +127,13 @@ internal DirectoryBase() { } public abstract void SetLastWriteTimeUtc(string path, DateTime lastWriteTimeUtc); /// - public abstract IEnumerable EnumerateDirectories(String path); + public abstract IEnumerable EnumerateDirectories(string path); /// - public abstract IEnumerable EnumerateDirectories(String path, String searchPattern); + public abstract IEnumerable EnumerateDirectories(string path, string searchPattern); /// - public abstract IEnumerable EnumerateDirectories(String path, String searchPattern, SearchOption searchOption); + public abstract IEnumerable EnumerateDirectories(string path, string searchPattern, SearchOption searchOption); /// public abstract IEnumerable EnumerateFiles(string path); diff --git a/System.IO.Abstractions/DirectoryInfoBase.cs b/System.IO.Abstractions/DirectoryInfoBase.cs index c5b40ea65..555d6d5db 100644 --- a/System.IO.Abstractions/DirectoryInfoBase.cs +++ b/System.IO.Abstractions/DirectoryInfoBase.cs @@ -5,7 +5,7 @@ namespace System.IO.Abstractions { /// [Serializable] - public abstract class DirectoryInfoBase : FileSystemInfoBase + public abstract class DirectoryInfoBase : FileSystemInfoBase, IDirectoryInfo { protected DirectoryInfoBase(IFileSystem fileSystem) : base(fileSystem) { @@ -17,48 +17,46 @@ internal DirectoryInfoBase() { } /// public abstract void Create(); #if NET40 - /// public abstract void Create(DirectorySecurity directorySecurity); #endif /// - public abstract DirectoryInfoBase CreateSubdirectory(string path); + public abstract IDirectoryInfo CreateSubdirectory(string path); #if NET40 - /// - public abstract DirectoryInfoBase CreateSubdirectory(string path, DirectorySecurity directorySecurity); + public abstract IDirectoryInfo CreateSubdirectory(string path, DirectorySecurity directorySecurity); #endif /// public abstract void Delete(bool recursive); /// - public abstract IEnumerable EnumerateDirectories(); + public abstract IEnumerable EnumerateDirectories(); /// - public abstract IEnumerable EnumerateDirectories(string searchPattern); + public abstract IEnumerable EnumerateDirectories(string searchPattern); /// - public abstract IEnumerable EnumerateDirectories(string searchPattern, SearchOption searchOption); + public abstract IEnumerable EnumerateDirectories(string searchPattern, SearchOption searchOption); /// - public abstract IEnumerable EnumerateFiles(); + public abstract IEnumerable EnumerateFiles(); /// - public abstract IEnumerable EnumerateFiles(string searchPattern); + public abstract IEnumerable EnumerateFiles(string searchPattern); /// - public abstract IEnumerable EnumerateFiles(string searchPattern, SearchOption searchOption); + public abstract IEnumerable EnumerateFiles(string searchPattern, SearchOption searchOption); /// - public abstract IEnumerable EnumerateFileSystemInfos(); + public abstract IEnumerable EnumerateFileSystemInfos(); /// - public abstract IEnumerable EnumerateFileSystemInfos(string searchPattern); + public abstract IEnumerable EnumerateFileSystemInfos(string searchPattern); /// - public abstract IEnumerable EnumerateFileSystemInfos(string searchPattern, SearchOption searchOption); + public abstract IEnumerable EnumerateFileSystemInfos(string searchPattern, SearchOption searchOption); /// public abstract DirectorySecurity GetAccessControl(); @@ -67,31 +65,31 @@ internal DirectoryInfoBase() { } public abstract DirectorySecurity GetAccessControl(AccessControlSections includeSections); /// - public abstract DirectoryInfoBase[] GetDirectories(); + public abstract IDirectoryInfo[] GetDirectories(); /// - public abstract DirectoryInfoBase[] GetDirectories(string searchPattern); + public abstract IDirectoryInfo[] GetDirectories(string searchPattern); /// - public abstract DirectoryInfoBase[] GetDirectories(string searchPattern, SearchOption searchOption); + public abstract IDirectoryInfo[] GetDirectories(string searchPattern, SearchOption searchOption); /// - public abstract FileInfoBase[] GetFiles(); + public abstract IFileInfo[] GetFiles(); /// - public abstract FileInfoBase[] GetFiles(string searchPattern); + public abstract IFileInfo[] GetFiles(string searchPattern); /// - public abstract FileInfoBase[] GetFiles(string searchPattern, SearchOption searchOption); + public abstract IFileInfo[] GetFiles(string searchPattern, SearchOption searchOption); /// - public abstract FileSystemInfoBase[] GetFileSystemInfos(); + public abstract IFileSystemInfo[] GetFileSystemInfos(); /// - public abstract FileSystemInfoBase[] GetFileSystemInfos(string searchPattern); + public abstract IFileSystemInfo[] GetFileSystemInfos(string searchPattern); /// - public abstract FileSystemInfoBase[] GetFileSystemInfos(string searchPattern, SearchOption searchOption); + public abstract IFileSystemInfo[] GetFileSystemInfos(string searchPattern, SearchOption searchOption); /// public abstract void MoveTo(string destDirName); @@ -100,10 +98,10 @@ internal DirectoryInfoBase() { } public abstract void SetAccessControl(DirectorySecurity directorySecurity); /// - public abstract DirectoryInfoBase Parent { get; } + public abstract IDirectoryInfo Parent { get; } /// - public abstract DirectoryInfoBase Root { get; } + public abstract IDirectoryInfo Root { get; } public static implicit operator DirectoryInfoBase(DirectoryInfo directoryInfo) { diff --git a/System.IO.Abstractions/DirectoryInfoFactory.cs b/System.IO.Abstractions/DirectoryInfoFactory.cs index 72e5bb161..8d1655298 100644 --- a/System.IO.Abstractions/DirectoryInfoFactory.cs +++ b/System.IO.Abstractions/DirectoryInfoFactory.cs @@ -10,7 +10,7 @@ public DirectoryInfoFactory(IFileSystem fileSystem) this.fileSystem = fileSystem; } - public DirectoryInfoBase FromDirectoryName(string directoryName) + public IDirectoryInfo FromDirectoryName(string directoryName) { var realDirectoryInfo = new DirectoryInfo(directoryName); return new DirectoryInfoWrapper(fileSystem, realDirectoryInfo); diff --git a/System.IO.Abstractions/DirectoryInfoWrapper.cs b/System.IO.Abstractions/DirectoryInfoWrapper.cs index 2fe120a22..d59c32a79 100644 --- a/System.IO.Abstractions/DirectoryInfoWrapper.cs +++ b/System.IO.Abstractions/DirectoryInfoWrapper.cs @@ -98,13 +98,13 @@ public override void Create(DirectorySecurity directorySecurity) } #endif - public override DirectoryInfoBase CreateSubdirectory(string path) + public override IDirectoryInfo CreateSubdirectory(string path) { return new DirectoryInfoWrapper(FileSystem, instance.CreateSubdirectory(path)); } #if NET40 - public override DirectoryInfoBase CreateSubdirectory(string path, DirectorySecurity directorySecurity) + public override IDirectoryInfo CreateSubdirectory(string path, DirectorySecurity directorySecurity) { return new DirectoryInfoWrapper(FileSystem, instance.CreateSubdirectory(path, directorySecurity)); } @@ -115,47 +115,47 @@ public override void Delete(bool recursive) instance.Delete(recursive); } - public override IEnumerable EnumerateDirectories() + public override IEnumerable EnumerateDirectories() { return instance.EnumerateDirectories().Select(directoryInfo => new DirectoryInfoWrapper(FileSystem, directoryInfo)); } - public override IEnumerable EnumerateDirectories(string searchPattern) + public override IEnumerable EnumerateDirectories(string searchPattern) { return instance.EnumerateDirectories(searchPattern).Select(directoryInfo => new DirectoryInfoWrapper(FileSystem, directoryInfo)); } - public override IEnumerable EnumerateDirectories(string searchPattern, SearchOption searchOption) + public override IEnumerable EnumerateDirectories(string searchPattern, SearchOption searchOption) { return instance.EnumerateDirectories(searchPattern, searchOption).Select(directoryInfo => new DirectoryInfoWrapper(FileSystem, directoryInfo)); } - public override IEnumerable EnumerateFiles() + public override IEnumerable EnumerateFiles() { return instance.EnumerateFiles().Select(fileInfo => new FileInfoWrapper(FileSystem, fileInfo)); } - public override IEnumerable EnumerateFiles(string searchPattern) + public override IEnumerable EnumerateFiles(string searchPattern) { return instance.EnumerateFiles(searchPattern).Select(fileInfo => new FileInfoWrapper(FileSystem, fileInfo)); } - public override IEnumerable EnumerateFiles(string searchPattern, SearchOption searchOption) + public override IEnumerable EnumerateFiles(string searchPattern, SearchOption searchOption) { return instance.EnumerateFiles(searchPattern, searchOption).Select(fileInfo => new FileInfoWrapper(FileSystem, fileInfo)); } - public override IEnumerable EnumerateFileSystemInfos() + public override IEnumerable EnumerateFileSystemInfos() { return instance.EnumerateFileSystemInfos().WrapFileSystemInfos(FileSystem); } - public override IEnumerable EnumerateFileSystemInfos(string searchPattern) + public override IEnumerable EnumerateFileSystemInfos(string searchPattern) { return instance.EnumerateFileSystemInfos(searchPattern).WrapFileSystemInfos(FileSystem); } - public override IEnumerable EnumerateFileSystemInfos(string searchPattern, SearchOption searchOption) + public override IEnumerable EnumerateFileSystemInfos(string searchPattern, SearchOption searchOption) { return instance.EnumerateFileSystemInfos(searchPattern, searchOption).WrapFileSystemInfos(FileSystem); } @@ -170,47 +170,47 @@ public override DirectorySecurity GetAccessControl(AccessControlSections include return instance.GetAccessControl(includeSections); } - public override DirectoryInfoBase[] GetDirectories() + public override IDirectoryInfo[] GetDirectories() { return instance.GetDirectories().WrapDirectories(FileSystem); } - public override DirectoryInfoBase[] GetDirectories(string searchPattern) + public override IDirectoryInfo[] GetDirectories(string searchPattern) { return instance.GetDirectories(searchPattern).WrapDirectories(FileSystem); } - public override DirectoryInfoBase[] GetDirectories(string searchPattern, SearchOption searchOption) + public override IDirectoryInfo[] GetDirectories(string searchPattern, SearchOption searchOption) { return instance.GetDirectories(searchPattern, searchOption).WrapDirectories(FileSystem); } - public override FileInfoBase[] GetFiles() + public override IFileInfo[] GetFiles() { return instance.GetFiles().WrapFiles(FileSystem); } - public override FileInfoBase[] GetFiles(string searchPattern) + public override IFileInfo[] GetFiles(string searchPattern) { return instance.GetFiles(searchPattern).WrapFiles(FileSystem); } - public override FileInfoBase[] GetFiles(string searchPattern, SearchOption searchOption) + public override IFileInfo[] GetFiles(string searchPattern, SearchOption searchOption) { return instance.GetFiles(searchPattern, searchOption).WrapFiles(FileSystem); } - public override FileSystemInfoBase[] GetFileSystemInfos() + public override IFileSystemInfo[] GetFileSystemInfos() { return instance.GetFileSystemInfos().WrapFileSystemInfos(FileSystem); } - public override FileSystemInfoBase[] GetFileSystemInfos(string searchPattern) + public override IFileSystemInfo[] GetFileSystemInfos(string searchPattern) { return instance.GetFileSystemInfos(searchPattern).WrapFileSystemInfos(FileSystem); } - public override FileSystemInfoBase[] GetFileSystemInfos(string searchPattern, SearchOption searchOption) + public override IFileSystemInfo[] GetFileSystemInfos(string searchPattern, SearchOption searchOption) { return instance.GetFileSystemInfos(searchPattern, searchOption).WrapFileSystemInfos(FileSystem); } @@ -225,7 +225,7 @@ public override void SetAccessControl(DirectorySecurity directorySecurity) instance.SetAccessControl(directorySecurity); } - public override DirectoryInfoBase Parent + public override IDirectoryInfo Parent { get { @@ -240,7 +240,7 @@ public override DirectoryInfoBase Parent } } - public override DirectoryInfoBase Root + public override IDirectoryInfo Root { get { return new DirectoryInfoWrapper(FileSystem, instance.Root); } } diff --git a/System.IO.Abstractions/DirectoryWrapper.cs b/System.IO.Abstractions/DirectoryWrapper.cs index 4f4d65d40..ffe5cda0a 100644 --- a/System.IO.Abstractions/DirectoryWrapper.cs +++ b/System.IO.Abstractions/DirectoryWrapper.cs @@ -10,13 +10,13 @@ public DirectoryWrapper(IFileSystem fileSystem) : base(fileSystem) { } - public override DirectoryInfoBase CreateDirectory(string path) + public override IDirectoryInfo CreateDirectory(string path) { return new DirectoryInfoWrapper(FileSystem, Directory.CreateDirectory(path)); } #if NET40 - public override DirectoryInfoBase CreateDirectory(string path, DirectorySecurity directorySecurity) + public override IDirectoryInfo CreateDirectory(string path, DirectorySecurity directorySecurity) { return new DirectoryInfoWrapper(FileSystem, Directory.CreateDirectory(path, directorySecurity)); } @@ -133,7 +133,7 @@ public override string[] GetLogicalDrives() } #endif - public override DirectoryInfoBase GetParent(string path) + public override IDirectoryInfo GetParent(string path) { return new DirectoryInfoWrapper(FileSystem, Directory.GetParent(path)); } diff --git a/System.IO.Abstractions/DriveInfoBase.cs b/System.IO.Abstractions/DriveInfoBase.cs index 55e2463d1..7b2b7083e 100644 --- a/System.IO.Abstractions/DriveInfoBase.cs +++ b/System.IO.Abstractions/DriveInfoBase.cs @@ -1,7 +1,7 @@ namespace System.IO.Abstractions { [Serializable] - public abstract class DriveInfoBase + public abstract class DriveInfoBase : IDriveInfo { protected DriveInfoBase(IFileSystem fileSystem) { @@ -85,7 +85,7 @@ internal DriveInfoBase() { } /// Gets or sets the root directory of a drive. /// /// An object that contains the root directory of the drive. - public virtual DirectoryInfoBase RootDirectory { get; protected set; } + public virtual IDirectoryInfo RootDirectory { get; protected set; } /// /// diff --git a/System.IO.Abstractions/DriveInfoFactory.cs b/System.IO.Abstractions/DriveInfoFactory.cs index aed165a1c..9603a31a9 100644 --- a/System.IO.Abstractions/DriveInfoFactory.cs +++ b/System.IO.Abstractions/DriveInfoFactory.cs @@ -14,7 +14,7 @@ public DriveInfoFactory(IFileSystem fileSystem) /// Retrieves the drive names of all logical drives on a computer. /// /// An array of type that represents the logical drives on a computer. - public DriveInfoBase[] GetDrives() + public IDriveInfo[] GetDrives() { var driveInfos = DriveInfo.GetDrives(); var driveInfoWrappers = new DriveInfoBase[driveInfos.Length]; @@ -31,7 +31,7 @@ public DriveInfoBase[] GetDrives() /// Initializes a new instance of the class, which acts as a wrapper for a logical drive. /// /// A valid drive path or drive letter. - public DriveInfoBase FromDriveName(string driveName) + public IDriveInfo FromDriveName(string driveName) { var realDriveInfo = new DriveInfo(driveName); return new DriveInfoWrapper(fileSystem, realDriveInfo); diff --git a/System.IO.Abstractions/DriveInfoWrapper.cs b/System.IO.Abstractions/DriveInfoWrapper.cs index 5d213cd02..dfc97b1b0 100644 --- a/System.IO.Abstractions/DriveInfoWrapper.cs +++ b/System.IO.Abstractions/DriveInfoWrapper.cs @@ -127,7 +127,7 @@ public override long TotalSize /// Gets or sets the root directory of a drive. /// /// An object that contains the root directory of the drive. - public override DirectoryInfoBase RootDirectory + public override IDirectoryInfo RootDirectory { get { return new DirectoryInfoWrapper(FileSystem, instance.RootDirectory); } } diff --git a/System.IO.Abstractions/FileInfoBase.cs b/System.IO.Abstractions/FileInfoBase.cs index cfd1508f4..c5b01c44e 100644 --- a/System.IO.Abstractions/FileInfoBase.cs +++ b/System.IO.Abstractions/FileInfoBase.cs @@ -4,7 +4,7 @@ namespace System.IO.Abstractions { /// [Serializable] - public abstract class FileInfoBase : FileSystemInfoBase + public abstract class FileInfoBase : FileSystemInfoBase, IFileInfo { protected FileInfoBase(IFileSystem fileSystem) : base(fileSystem) { @@ -17,10 +17,10 @@ internal FileInfoBase() { } public abstract StreamWriter AppendText(); /// - public abstract FileInfoBase CopyTo(string destFileName); + public abstract IFileInfo CopyTo(string destFileName); /// - public abstract FileInfoBase CopyTo(string destFileName, bool overwrite); + public abstract IFileInfo CopyTo(string destFileName, bool overwrite); /// public abstract Stream Create(); @@ -65,17 +65,17 @@ internal FileInfoBase() { } #if NET40 /// - public abstract FileInfoBase Replace(string destinationFileName, string destinationBackupFileName); + public abstract IFileInfo Replace(string destinationFileName, string destinationBackupFileName); /// - public abstract FileInfoBase Replace(string destinationFileName, string destinationBackupFileName, bool ignoreMetadataErrors); + public abstract IFileInfo Replace(string destinationFileName, string destinationBackupFileName, bool ignoreMetadataErrors); #endif /// public abstract void SetAccessControl(FileSecurity fileSecurity); /// - public abstract DirectoryInfoBase Directory { get; } + public abstract IDirectoryInfo Directory { get; } /// public abstract string DirectoryName { get; } diff --git a/System.IO.Abstractions/FileInfoFactory.cs b/System.IO.Abstractions/FileInfoFactory.cs index fcebf596f..32e372e4c 100644 --- a/System.IO.Abstractions/FileInfoFactory.cs +++ b/System.IO.Abstractions/FileInfoFactory.cs @@ -10,7 +10,7 @@ public FileInfoFactory(IFileSystem fileSystem) this.fileSystem = fileSystem; } - public FileInfoBase FromFileName(string fileName) + public IFileInfo FromFileName(string fileName) { var realFileInfo = new FileInfo(fileName); return new FileInfoWrapper(fileSystem, realFileInfo); diff --git a/System.IO.Abstractions/FileInfoWrapper.cs b/System.IO.Abstractions/FileInfoWrapper.cs index 264c2033f..bd9de53ea 100644 --- a/System.IO.Abstractions/FileInfoWrapper.cs +++ b/System.IO.Abstractions/FileInfoWrapper.cs @@ -89,12 +89,12 @@ public override StreamWriter AppendText() return instance.AppendText(); } - public override FileInfoBase CopyTo(string destFileName) + public override IFileInfo CopyTo(string destFileName) { return new FileInfoWrapper(FileSystem, instance.CopyTo(destFileName)); } - public override FileInfoBase CopyTo(string destFileName, bool overwrite) + public override IFileInfo CopyTo(string destFileName, bool overwrite) { return new FileInfoWrapper(FileSystem, instance.CopyTo(destFileName, overwrite)); } @@ -167,12 +167,12 @@ public override Stream OpenWrite() } #if NET40 - public override FileInfoBase Replace(string destinationFileName, string destinationBackupFileName) + public override IFileInfo Replace(string destinationFileName, string destinationBackupFileName) { return new FileInfoWrapper(FileSystem, instance.Replace(destinationFileName, destinationBackupFileName)); } - public override FileInfoBase Replace(string destinationFileName, string destinationBackupFileName, bool ignoreMetadataErrors) + public override IFileInfo Replace(string destinationFileName, string destinationBackupFileName, bool ignoreMetadataErrors) { return new FileInfoWrapper(FileSystem, instance.Replace(destinationFileName, destinationBackupFileName, ignoreMetadataErrors)); } @@ -183,7 +183,7 @@ public override void SetAccessControl(FileSecurity fileSecurity) instance.SetAccessControl(fileSecurity); } - public override DirectoryInfoBase Directory + public override IDirectoryInfo Directory { get { return new DirectoryInfoWrapper(FileSystem, instance.Directory); } } diff --git a/System.IO.Abstractions/FileSystem.cs b/System.IO.Abstractions/FileSystem.cs index cf09a1be6..3c29b1563 100644 --- a/System.IO.Abstractions/FileSystem.cs +++ b/System.IO.Abstractions/FileSystem.cs @@ -23,7 +23,7 @@ public FileSystem() public IFileStreamFactory FileStream { get; } - public PathBase Path { get; } + public IPath Path { get; } public IDirectoryInfoFactory DirectoryInfo { get; } diff --git a/System.IO.Abstractions/FileSystemInfoBase.cs b/System.IO.Abstractions/FileSystemInfoBase.cs index 586b2f726..ce9358fda 100644 --- a/System.IO.Abstractions/FileSystemInfoBase.cs +++ b/System.IO.Abstractions/FileSystemInfoBase.cs @@ -2,7 +2,7 @@ { /// [Serializable] - public abstract class FileSystemInfoBase + public abstract class FileSystemInfoBase : IFileSystemInfo { protected FileSystemInfoBase(IFileSystem fileSystem) { diff --git a/System.IO.Abstractions/FileSystemWatcherBase.cs b/System.IO.Abstractions/FileSystemWatcherBase.cs index 5d7db3d94..5d7836c6e 100644 --- a/System.IO.Abstractions/FileSystemWatcherBase.cs +++ b/System.IO.Abstractions/FileSystemWatcherBase.cs @@ -1,4 +1,6 @@ -using System.ComponentModel; +#if NET40 +using System.ComponentModel; +#endif namespace System.IO.Abstractions { diff --git a/System.IO.Abstractions/IDirectory.cs b/System.IO.Abstractions/IDirectory.cs index 631f310d9..5e7af2826 100644 --- a/System.IO.Abstractions/IDirectory.cs +++ b/System.IO.Abstractions/IDirectory.cs @@ -5,54 +5,101 @@ namespace System.IO.Abstractions { public interface IDirectory { + /// + /// Exposes the underlying filesystem implementation. This is useful for implementing extension methods. + /// IFileSystem FileSystem { get; } - DirectoryInfoBase CreateDirectory(string path); + /// + IDirectoryInfo CreateDirectory(string path); + +#if NET40 + /// + IDirectoryInfo CreateDirectory(string path, DirectorySecurity directorySecurity); +#endif + /// void Delete(string path); + /// void Delete(string path, bool recursive); - IEnumerable EnumerateDirectories(string path); - IEnumerable EnumerateDirectories(string path, string searchPattern); - IEnumerable EnumerateDirectories(string path, string searchPattern, SearchOption searchOption); - IEnumerable EnumerateFiles(string path); - IEnumerable EnumerateFiles(string path, string searchPattern); - IEnumerable EnumerateFiles(string path, string searchPattern, SearchOption searchOption); - IEnumerable EnumerateFileSystemEntries(string path); - IEnumerable EnumerateFileSystemEntries(string path, string searchPattern); - IEnumerable EnumerateFileSystemEntries(string path, string searchPattern, SearchOption searchOption); + /// bool Exists(string path); + /// DirectorySecurity GetAccessControl(string path); + /// DirectorySecurity GetAccessControl(string path, AccessControlSections includeSections); + /// DateTime GetCreationTime(string path); + /// DateTime GetCreationTimeUtc(string path); + /// string GetCurrentDirectory(); + /// string[] GetDirectories(string path); + /// string[] GetDirectories(string path, string searchPattern); + /// string[] GetDirectories(string path, string searchPattern, SearchOption searchOption); + /// string GetDirectoryRoot(string path); + /// string[] GetFiles(string path); + /// string[] GetFiles(string path, string searchPattern); + /// string[] GetFiles(string path, string searchPattern, SearchOption searchOption); + /// string[] GetFileSystemEntries(string path); + /// string[] GetFileSystemEntries(string path, string searchPattern); + /// DateTime GetLastAccessTime(string path); + /// DateTime GetLastAccessTimeUtc(string path); + /// DateTime GetLastWriteTime(string path); + /// DateTime GetLastWriteTimeUtc(string path); - DirectoryInfoBase GetParent(string path); +#if NET40 + /// + string[] GetLogicalDrives(); +#endif + /// + IDirectoryInfo GetParent(string path); + /// void Move(string sourceDirName, string destDirName); + /// void SetAccessControl(string path, DirectorySecurity directorySecurity); + /// void SetCreationTime(string path, DateTime creationTime); + /// void SetCreationTimeUtc(string path, DateTime creationTimeUtc); + /// void SetCurrentDirectory(string path); + /// void SetLastAccessTime(string path, DateTime lastAccessTime); + /// void SetLastAccessTimeUtc(string path, DateTime lastAccessTimeUtc); + /// void SetLastWriteTime(string path, DateTime lastWriteTime); + /// void SetLastWriteTimeUtc(string path, DateTime lastWriteTimeUtc); - -#if NET40 - DirectoryInfoBase CreateDirectory(string path, DirectorySecurity directorySecurity); - string[] GetLogicalDrives(); -#endif - + /// + IEnumerable EnumerateDirectories(string path); + /// + IEnumerable EnumerateDirectories(string path, string searchPattern); + /// + IEnumerable EnumerateDirectories(string path, string searchPattern, SearchOption searchOption); + /// + IEnumerable EnumerateFiles(string path); + /// + IEnumerable EnumerateFiles(string path, string searchPattern); + /// + IEnumerable EnumerateFiles(string path, string searchPattern, SearchOption searchOption); + /// + IEnumerable EnumerateFileSystemEntries(string path); + /// + IEnumerable EnumerateFileSystemEntries(string path, string searchPattern); + /// + IEnumerable EnumerateFileSystemEntries(string path, string searchPattern, SearchOption searchOption); } } \ No newline at end of file diff --git a/System.IO.Abstractions/IDirectoryInfo.cs b/System.IO.Abstractions/IDirectoryInfo.cs new file mode 100644 index 000000000..434b38778 --- /dev/null +++ b/System.IO.Abstractions/IDirectoryInfo.cs @@ -0,0 +1,71 @@ +using System.Collections.Generic; +using System.Security.AccessControl; + +namespace System.IO.Abstractions +{ + public interface IDirectoryInfo: IFileSystemInfo + { + /// + void Create(); +#if NET40 + /// + void Create(DirectorySecurity directorySecurity); +#endif + /// + IDirectoryInfo CreateSubdirectory(string path); +#if NET40 + /// + IDirectoryInfo CreateSubdirectory(string path, DirectorySecurity directorySecurity); +#endif + /// + void Delete(bool recursive); + /// + IEnumerable EnumerateDirectories(); + /// + IEnumerable EnumerateDirectories(string searchPattern); + /// + IEnumerable EnumerateDirectories(string searchPattern, SearchOption searchOption); + /// + IEnumerable EnumerateFiles(); + /// + IEnumerable EnumerateFiles(string searchPattern); + /// + IEnumerable EnumerateFiles(string searchPattern, SearchOption searchOption); + /// + IEnumerable EnumerateFileSystemInfos(); + /// + IEnumerable EnumerateFileSystemInfos(string searchPattern); + /// + IEnumerable EnumerateFileSystemInfos(string searchPattern, SearchOption searchOption); + /// + DirectorySecurity GetAccessControl(); + /// + DirectorySecurity GetAccessControl(AccessControlSections includeSections); + /// + IDirectoryInfo[] GetDirectories(); + /// + IDirectoryInfo[] GetDirectories(string searchPattern); + /// + IDirectoryInfo[] GetDirectories(string searchPattern, SearchOption searchOption); + /// + IFileInfo[] GetFiles(); + /// + IFileInfo[] GetFiles(string searchPattern); + /// + IFileInfo[] GetFiles(string searchPattern, SearchOption searchOption); + /// + IFileSystemInfo[] GetFileSystemInfos(); + /// + IFileSystemInfo[] GetFileSystemInfos(string searchPattern); + /// + IFileSystemInfo[] GetFileSystemInfos(string searchPattern, SearchOption searchOption); + /// + void MoveTo(string destDirName); + /// + void SetAccessControl(DirectorySecurity directorySecurity); + /// + IDirectoryInfo Parent { get; } + /// + IDirectoryInfo Root { get; } + } +} \ No newline at end of file diff --git a/System.IO.Abstractions/IDirectoryInfoFactory.cs b/System.IO.Abstractions/IDirectoryInfoFactory.cs index 9f6e9e32e..acc575965 100644 --- a/System.IO.Abstractions/IDirectoryInfoFactory.cs +++ b/System.IO.Abstractions/IDirectoryInfoFactory.cs @@ -6,6 +6,6 @@ public interface IDirectoryInfoFactory /// Initializes a new instance of the class, which acts as a wrapper for a directory path. /// /// The fully qualified name of the new directory, or the relative directory name. - DirectoryInfoBase FromDirectoryName(string directoryName); + IDirectoryInfo FromDirectoryName(string directoryName); } } \ No newline at end of file diff --git a/System.IO.Abstractions/IDriveInfo.cs b/System.IO.Abstractions/IDriveInfo.cs new file mode 100644 index 000000000..356c1a845 --- /dev/null +++ b/System.IO.Abstractions/IDriveInfo.cs @@ -0,0 +1,28 @@ +namespace System.IO.Abstractions +{ + public interface IDriveInfo + { + /// + /// Exposes the underlying filesystem implementation. This is useful for implementing extension methods. + /// + IFileSystem FileSystem { get; } + /// + long AvailableFreeSpace { get; } + /// + string DriveFormat { get; } + /// + DriveType DriveType { get; } + /// + bool IsReady { get; } + /// + string Name { get; } + /// + IDirectoryInfo RootDirectory { get; } + /// + long TotalFreeSpace { get; } + /// + long TotalSize { get; } + /// + string VolumeLabel { get; set; } + } +} \ No newline at end of file diff --git a/System.IO.Abstractions/IDriveInfoFactory.cs b/System.IO.Abstractions/IDriveInfoFactory.cs index 53c3bb2b3..7a2cca36a 100644 --- a/System.IO.Abstractions/IDriveInfoFactory.cs +++ b/System.IO.Abstractions/IDriveInfoFactory.cs @@ -9,12 +9,12 @@ public interface IDriveInfoFactory /// Retrieves the drive names of all logical drives on a computer. /// /// An array of type that represents the logical drives on a computer. - DriveInfoBase[] GetDrives(); + IDriveInfo[] GetDrives(); /// /// Initializes a new instance of the class, which acts as a wrapper for a logical drive. /// /// A valid drive path or drive letter. - DriveInfoBase FromDriveName(string driveName); + IDriveInfo FromDriveName(string driveName); } } diff --git a/System.IO.Abstractions/IFile.cs b/System.IO.Abstractions/IFile.cs index 246cf78ce..169add2c2 100644 --- a/System.IO.Abstractions/IFile.cs +++ b/System.IO.Abstractions/IFile.cs @@ -6,65 +6,130 @@ namespace System.IO.Abstractions { public interface IFile { + /// + /// Exposes the underlying filesystem implementation. This is useful for implementing extension methods. + /// IFileSystem FileSystem { get; } + /// void AppendAllLines(string path, IEnumerable contents); + /// void AppendAllLines(string path, IEnumerable contents, Encoding encoding); + /// void AppendAllText(string path, string contents); + /// void AppendAllText(string path, string contents, Encoding encoding); + /// StreamWriter AppendText(string path); + /// void Copy(string sourceFileName, string destFileName); + /// void Copy(string sourceFileName, string destFileName, bool overwrite); + /// Stream Create(string path); + /// Stream Create(string path, int bufferSize); + /// Stream Create(string path, int bufferSize, FileOptions options); +#if NET40 + /// + Stream Create(string path, int bufferSize, FileOptions options, FileSecurity fileSecurity); +#endif + /// StreamWriter CreateText(string path); +#if NET40 + /// + void Decrypt(string path); +#endif + /// void Delete(string path); +#if NET40 + /// + void Encrypt(string path); +#endif + /// bool Exists(string path); + /// FileSecurity GetAccessControl(string path); + /// FileSecurity GetAccessControl(string path, AccessControlSections includeSections); + /// FileAttributes GetAttributes(string path); + /// DateTime GetCreationTime(string path); + /// DateTime GetCreationTimeUtc(string path); + /// DateTime GetLastAccessTime(string path); + /// DateTime GetLastAccessTimeUtc(string path); + /// DateTime GetLastWriteTime(string path); + /// DateTime GetLastWriteTimeUtc(string path); + /// void Move(string sourceFileName, string destFileName); + /// Stream Open(string path, FileMode mode); + /// Stream Open(string path, FileMode mode, FileAccess access); + /// Stream Open(string path, FileMode mode, FileAccess access, FileShare share); + /// Stream OpenRead(string path); + /// StreamReader OpenText(string path); + /// Stream OpenWrite(string path); + /// byte[] ReadAllBytes(string path); + /// string[] ReadAllLines(string path); + /// string[] ReadAllLines(string path, Encoding encoding); + /// string ReadAllText(string path); + /// string ReadAllText(string path, Encoding encoding); + /// IEnumerable ReadLines(string path); + /// IEnumerable ReadLines(string path, Encoding encoding); +#if NET40 + /// + void Replace(string sourceFileName, string destinationFileName, string destinationBackupFileName); + /// + void Replace(string sourceFileName, string destinationFileName, string destinationBackupFileName, bool ignoreMetadataErrors); +#endif + /// void SetAccessControl(string path, FileSecurity fileSecurity); + /// void SetAttributes(string path, FileAttributes fileAttributes); + /// void SetCreationTime(string path, DateTime creationTime); + /// void SetCreationTimeUtc(string path, DateTime creationTimeUtc); + /// void SetLastAccessTime(string path, DateTime lastAccessTime); + /// void SetLastAccessTimeUtc(string path, DateTime lastAccessTimeUtc); + /// void SetLastWriteTime(string path, DateTime lastWriteTime); + /// void SetLastWriteTimeUtc(string path, DateTime lastWriteTimeUtc); + /// void WriteAllBytes(string path, byte[] bytes); + /// void WriteAllLines(string path, IEnumerable contents); + /// void WriteAllLines(string path, IEnumerable contents, Encoding encoding); + /// void WriteAllLines(string path, string[] contents); + /// void WriteAllLines(string path, string[] contents, Encoding encoding); + /// void WriteAllText(string path, string contents); + /// void WriteAllText(string path, string contents, Encoding encoding); - -#if NET40 - void Decrypt(string path); - void Encrypt(string path); - void Replace(string sourceFileName, string destinationFileName, string destinationBackupFileName); - void Replace(string sourceFileName, string destinationFileName, string destinationBackupFileName, bool ignoreMetadataErrors); -#endif } } \ No newline at end of file diff --git a/System.IO.Abstractions/IFileInfo.cs b/System.IO.Abstractions/IFileInfo.cs new file mode 100644 index 000000000..184b9ac11 --- /dev/null +++ b/System.IO.Abstractions/IFileInfo.cs @@ -0,0 +1,58 @@ +using System.Security.AccessControl; + +namespace System.IO.Abstractions +{ + public interface IFileInfo: IFileSystemInfo + { + /// + StreamWriter AppendText(); + /// + IFileInfo CopyTo(string destFileName); + /// + IFileInfo CopyTo(string destFileName, bool overwrite); + /// + Stream Create(); + /// + StreamWriter CreateText(); +#if NET40 + /// + void Decrypt(); + /// + void Encrypt(); +#endif + /// + FileSecurity GetAccessControl(); + /// + FileSecurity GetAccessControl(AccessControlSections includeSections); + /// + void MoveTo(string destFileName); + /// + Stream Open(FileMode mode); + /// + Stream Open(FileMode mode, FileAccess access); + /// + Stream Open(FileMode mode, FileAccess access, FileShare share); + /// + Stream OpenRead(); + /// + StreamReader OpenText(); + /// + Stream OpenWrite(); +#if NET40 + /// + IFileInfo Replace(string destinationFileName, string destinationBackupFileName); + /// + IFileInfo Replace(string destinationFileName, string destinationBackupFileName, bool ignoreMetadataErrors); +#endif + /// + void SetAccessControl(FileSecurity fileSecurity); + /// + IDirectoryInfo Directory { get; } + /// + string DirectoryName { get; } + /// + bool IsReadOnly { get; set; } + /// + long Length { get; } + } +} \ No newline at end of file diff --git a/System.IO.Abstractions/IFileInfoFactory.cs b/System.IO.Abstractions/IFileInfoFactory.cs index aeeeded04..f371f1087 100644 --- a/System.IO.Abstractions/IFileInfoFactory.cs +++ b/System.IO.Abstractions/IFileInfoFactory.cs @@ -6,6 +6,6 @@ public interface IFileInfoFactory /// Initializes a new instance of the class, which acts as a wrapper for a file path. /// /// The fully qualified name of the new file, or the relative file name. - FileInfoBase FromFileName(string fileName); + IFileInfo FromFileName(string fileName); } } \ No newline at end of file diff --git a/System.IO.Abstractions/IFileSystem.cs b/System.IO.Abstractions/IFileSystem.cs index ce432f0e7..48ad19b07 100644 --- a/System.IO.Abstractions/IFileSystem.cs +++ b/System.IO.Abstractions/IFileSystem.cs @@ -6,7 +6,7 @@ public interface IFileSystem IDirectory Directory { get; } IFileInfoFactory FileInfo { get; } IFileStreamFactory FileStream { get; } - PathBase Path { get; } + IPath Path { get; } IDirectoryInfoFactory DirectoryInfo { get; } IDriveInfoFactory DriveInfo { get; } IFileSystemWatcherFactory FileSystemWatcher { get; } diff --git a/System.IO.Abstractions/IFileSystemInfo.cs b/System.IO.Abstractions/IFileSystemInfo.cs new file mode 100644 index 000000000..9331ad04c --- /dev/null +++ b/System.IO.Abstractions/IFileSystemInfo.cs @@ -0,0 +1,36 @@ +namespace System.IO.Abstractions +{ + public interface IFileSystemInfo + { + /// + /// Exposes the underlying filesystem implementation. This is useful for implementing extension methods. + /// + IFileSystem FileSystem { get; } + /// + void Delete(); + /// + void Refresh(); + /// + FileAttributes Attributes { get; set; } + /// + DateTime CreationTime { get; set; } + /// + DateTime CreationTimeUtc { get; set; } + /// + bool Exists { get; } + /// + string Extension { get; } + /// + string FullName { get; } + /// + DateTime LastAccessTime { get; set; } + /// + DateTime LastAccessTimeUtc { get; set; } + /// + DateTime LastWriteTime { get; set; } + /// + DateTime LastWriteTimeUtc { get; set; } + /// + string Name { get; } + } +} \ No newline at end of file diff --git a/System.IO.Abstractions/IFileSystemWatcher.cs b/System.IO.Abstractions/IFileSystemWatcher.cs index ce77a2bb6..8faae96c9 100644 --- a/System.IO.Abstractions/IFileSystemWatcher.cs +++ b/System.IO.Abstractions/IFileSystemWatcher.cs @@ -1,21 +1,50 @@ -namespace System.IO.Abstractions +#if NET40 +using System.ComponentModel; +#endif + +namespace System.IO.Abstractions { public interface IFileSystemWatcher { + /// + bool IncludeSubdirectories { get; set; } + /// bool EnableRaisingEvents { get; set; } + /// string Filter { get; set; } - bool IncludeSubdirectories { get; set; } + /// int InternalBufferSize { get; set; } + /// NotifyFilters NotifyFilter { get; set; } + /// string Path { get; set; } - +#if NET40 + /// + ISite Site { get; set; } + /// + ISynchronizeInvoke SynchronizingObject { get; set; } +#endif + /// event FileSystemEventHandler Changed; + /// event FileSystemEventHandler Created; + /// event FileSystemEventHandler Deleted; + /// event ErrorEventHandler Error; + /// event RenamedEventHandler Renamed; - +#if NET40 + /// + void BeginInit(); +#endif +#if NET40 + /// + void EndInit(); +#endif + /// WaitForChangedResult WaitForChanged(WatcherChangeTypes changeType); + /// WaitForChangedResult WaitForChanged(WatcherChangeTypes changeType, int timeout); } } \ No newline at end of file diff --git a/System.IO.Abstractions/IPath.cs b/System.IO.Abstractions/IPath.cs new file mode 100644 index 000000000..3f694f045 --- /dev/null +++ b/System.IO.Abstractions/IPath.cs @@ -0,0 +1,55 @@ +namespace System.IO.Abstractions +{ + public interface IPath + { + /// + char AltDirectorySeparatorChar { get; } + /// + char DirectorySeparatorChar { get; } + /// + /// Exposes the underlying filesystem implementation. This is useful for implementing extension methods. + /// + IFileSystem FileSystem { get; } + /// + char PathSeparator { get; } + /// + char VolumeSeparatorChar { get; } + + /// + string ChangeExtension(string path, string extension); + /// + string Combine(params string[] paths); + /// + string Combine(string path1, string path2); + /// + string Combine(string path1, string path2, string path3); + /// + string Combine(string path1, string path2, string path3, string path4); + /// + string GetDirectoryName(string path); + /// + string GetExtension(string path); + /// + string GetFileName(string path); + /// + string GetFileNameWithoutExtension(string path); + /// + string GetFullPath(string path); + /// + char[] GetInvalidFileNameChars(); + /// + char[] GetInvalidPathChars(); + /// + string GetPathRoot(string path); + /// + string GetRandomFileName(); + /// + string GetTempFileName(); + /// + string GetTempPath(); + /// + bool HasExtension(string path); + /// + bool IsPathRooted(string path); + } +} \ No newline at end of file diff --git a/System.IO.Abstractions/PathBase.cs b/System.IO.Abstractions/PathBase.cs index 87b8b687e..18a523728 100644 --- a/System.IO.Abstractions/PathBase.cs +++ b/System.IO.Abstractions/PathBase.cs @@ -2,7 +2,7 @@ { /// [Serializable] - public abstract class PathBase + public abstract class PathBase : IPath { protected PathBase(IFileSystem fileSystem) { From 3e31d240d12639b62b48da2e36c74df19eee7c1c Mon Sep 17 00:00:00 2001 From: Weiermann Date: Tue, 19 Mar 2019 17:37:55 +0100 Subject: [PATCH 06/10] Version-Bump to 4.0 --- version.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.json b/version.json index 292054aac..63af7b263 100644 --- a/version.json +++ b/version.json @@ -1,6 +1,6 @@ { "$schema": "https://raw.githubusercontent.com/AArnott/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", - "version": "3.0", + "version": "4.0", "assemblyVersion": { "precision": "major" }, From a31f0f24d663a2d28df527c32d2e3b97e18102cd Mon Sep 17 00:00:00 2001 From: Weiermann Date: Tue, 19 Mar 2019 17:40:22 +0100 Subject: [PATCH 07/10] Added small note about 4.0 and a little example --- README.md | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/README.md b/README.md index 4aa074087..851521433 100644 --- a/README.md +++ b/README.md @@ -88,3 +88,50 @@ void MyFancyMethod() ... } ``` + +### New in 4.0: +In version 4.0, the api introduces yet another layer of abstraction; instead of using abstract base classes (these still exist, though), things were changed to use interfaces instead. + +Using these allows you to completely mock the file system using your mocking library of choice. Here's a small example (using Moq): + +```csharp +using Moq; +using NUnit.Framework; +using System.IO.Abstractions; + +namespace Tests +{ + public class Tests + { + [Test] + public void Test1() + { + var watcher = Mock.Of(); + + var unitUnderTest = new SomeClassUsingFileSystemWatcher(watcher); + + Mock.Get(watcher).Raise(w => w.Created += null, new System.IO.FileSystemEventArgs(System.IO.WatcherChangeTypes.Created, @"C:\Some\Directory", "Some.File")); + + Assert.True(unitUnderTest.FileWasCreated); + } + } + + public class SomeClassUsingFileSystemWatcher + { + private readonly IFileSystemWatcher watcher; + + public bool FileWasCreated { get; private set; } + + public SomeClassUsingFileSystemWatcher(IFileSystemWatcher watcher) + { + this.watcher = watcher; + this.watcher.Created += Watcher_Created; + } + + private void Watcher_Created(object sender, System.IO.FileSystemEventArgs e) + { + FileWasCreated = true; + } + } +} +``` \ No newline at end of file From 59d9376a5ddccffa4b0edc5ca03fb906d3b8c19b Mon Sep 17 00:00:00 2001 From: Weiermann Date: Wed, 20 Mar 2019 08:42:26 +0100 Subject: [PATCH 08/10] Removed unnecessary cast --- System.IO.Abstractions.TestingHelpers/MockFileInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/System.IO.Abstractions.TestingHelpers/MockFileInfo.cs b/System.IO.Abstractions.TestingHelpers/MockFileInfo.cs index 29c2f9a24..6d5da990e 100644 --- a/System.IO.Abstractions.TestingHelpers/MockFileInfo.cs +++ b/System.IO.Abstractions.TestingHelpers/MockFileInfo.cs @@ -210,7 +210,7 @@ public override FileSecurity GetAccessControl(AccessControlSections includeSecti public override void MoveTo(string destFileName) { - var movedFileInfo = CopyTo(destFileName) as MockFileInfo; + var movedFileInfo = CopyTo(destFileName); if (destFileName == FullName) { return; From 2cddc4cfaaab3f45f4aa98dc3551e7089f4fb2da Mon Sep 17 00:00:00 2001 From: Weiermann Date: Wed, 20 Mar 2019 08:49:52 +0100 Subject: [PATCH 09/10] Made a bit more elaborate example --- README.md | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 851521433..0d9bf1dba 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,7 @@ Using these allows you to completely mock the file system using your mocking lib ```csharp using Moq; using NUnit.Framework; +using System; using System.IO.Abstractions; namespace Tests @@ -107,10 +108,18 @@ namespace Tests public void Test1() { var watcher = Mock.Of(); + var file = Mock.Of(); - var unitUnderTest = new SomeClassUsingFileSystemWatcher(watcher); + Mock.Get(file).Setup(f => f.Exists(It.IsAny())).Returns(true); + Mock.Get(file).Setup(f => f.ReadAllText(It.IsAny())).Throws(); - Mock.Get(watcher).Raise(w => w.Created += null, new System.IO.FileSystemEventArgs(System.IO.WatcherChangeTypes.Created, @"C:\Some\Directory", "Some.File")); + var unitUnderTest = new SomeClassUsingFileSystemWatcher(watcher, file); + + Assert.Throws(() => { + Mock.Get(watcher).Raise(w => w.Created += null, new System.IO.FileSystemEventArgs(System.IO.WatcherChangeTypes.Created, @"C:\Some\Directory", "Some.File")); + }); + + Mock.Get(file).Verify(f => f.Exists(It.IsAny()), Times.Once); Assert.True(unitUnderTest.FileWasCreated); } @@ -118,20 +127,28 @@ namespace Tests public class SomeClassUsingFileSystemWatcher { - private readonly IFileSystemWatcher watcher; + private readonly IFileSystemWatcher _watcher; + private readonly IFile _file; public bool FileWasCreated { get; private set; } - public SomeClassUsingFileSystemWatcher(IFileSystemWatcher watcher) + public SomeClassUsingFileSystemWatcher(IFileSystemWatcher watcher, IFile file) { - this.watcher = watcher; - this.watcher.Created += Watcher_Created; + this._file = file; + this._watcher = watcher; + this._watcher.Created += Watcher_Created; } private void Watcher_Created(object sender, System.IO.FileSystemEventArgs e) { FileWasCreated = true; + + if(_file.Exists(e.FullPath)) + { + var text = _file.ReadAllText(e.FullPath); + } } } } + ``` \ No newline at end of file From 980a57a5ebd146a92a9f05dc70da46b313e324a1 Mon Sep 17 00:00:00 2001 From: Florian Greinacher Date: Sun, 24 Mar 2019 12:13:38 +0100 Subject: [PATCH 10/10] Clean up readme a bit --- README.md | 86 +++++++++++++++++++++++-------------------------------- 1 file changed, 36 insertions(+), 50 deletions(-) diff --git a/README.md b/README.md index 0d9bf1dba..1d095b02e 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ and/or: Install-Package System.IO.Abstractions.TestingHelpers -At the core of the library is IFileSystem and FileSystem. Instead of calling methods like `File.ReadAllText` directly, use `IFileSystem.File.ReadAllText`. We have exactly the same API, except that ours is injectable and testable. +At the core of the library is `IFileSystem` and `FileSystem`. Instead of calling methods like `File.ReadAllText` directly, use `IFileSystem.File.ReadAllText`. We have exactly the same API, except that ours is injectable and testable. ```csharp public class MyComponent @@ -28,7 +28,7 @@ public class MyComponent /// Create MyComponent public MyComponent() : this( fileSystem: new FileSystem() //use default implementation which calls System.IO - ) + ) { } @@ -74,81 +74,67 @@ public void MyComponent_Validate_ShouldThrowNotSupportedExceptionIfTestingIsNotA Assert.Fail("The expected exception was not thrown."); } ``` + We even support casting from the .NET Framework's untestable types to our testable wrappers: ```csharp -FileInfo SomeBadApiMethodThatReturnsFileInfo() +FileInfo SomeApiMethodThatReturnsFileInfo() { return new FileInfo("a"); } void MyFancyMethod() { - var testableFileInfo = (FileInfoBase)SomeBadApiMethodThatReturnsFileInfo(); + var testableFileInfo = (FileInfoBase)SomeApiMethodThatReturnsFileInfo(); ... } ``` -### New in 4.0: -In version 4.0, the api introduces yet another layer of abstraction; instead of using abstract base classes (these still exist, though), things were changed to use interfaces instead. - -Using these allows you to completely mock the file system using your mocking library of choice. Here's a small example (using Moq): +Since version 4.0 the top-level APIs expose interfaces instead of abstract base classes (these still exist, though), allowing you to completely mock the file system. Here's a small example, using [Moq](https://github.com/moq/moq4): ```csharp -using Moq; -using NUnit.Framework; -using System; -using System.IO.Abstractions; - -namespace Tests +[Test] +public void Test1() { - public class Tests - { - [Test] - public void Test1() - { - var watcher = Mock.Of(); - var file = Mock.Of(); + var watcher = Mock.Of(); + var file = Mock.Of(); - Mock.Get(file).Setup(f => f.Exists(It.IsAny())).Returns(true); - Mock.Get(file).Setup(f => f.ReadAllText(It.IsAny())).Throws(); + Mock.Get(file).Setup(f => f.Exists(It.IsAny())).Returns(true); + Mock.Get(file).Setup(f => f.ReadAllText(It.IsAny())).Throws(); - var unitUnderTest = new SomeClassUsingFileSystemWatcher(watcher, file); + var unitUnderTest = new SomeClassUsingFileSystemWatcher(watcher, file); - Assert.Throws(() => { - Mock.Get(watcher).Raise(w => w.Created += null, new System.IO.FileSystemEventArgs(System.IO.WatcherChangeTypes.Created, @"C:\Some\Directory", "Some.File")); - }); + Assert.Throws(() => { + Mock.Get(watcher).Raise(w => w.Created += null, new System.IO.FileSystemEventArgs(System.IO.WatcherChangeTypes.Created, @"C:\Some\Directory", "Some.File")); + }); - Mock.Get(file).Verify(f => f.Exists(It.IsAny()), Times.Once); + Mock.Get(file).Verify(f => f.Exists(It.IsAny()), Times.Once); - Assert.True(unitUnderTest.FileWasCreated); - } - } + Assert.True(unitUnderTest.FileWasCreated); +} - public class SomeClassUsingFileSystemWatcher - { - private readonly IFileSystemWatcher _watcher; - private readonly IFile _file; +public class SomeClassUsingFileSystemWatcher +{ + private readonly IFileSystemWatcher _watcher; + private readonly IFile _file; - public bool FileWasCreated { get; private set; } + public bool FileWasCreated { get; private set; } - public SomeClassUsingFileSystemWatcher(IFileSystemWatcher watcher, IFile file) - { - this._file = file; - this._watcher = watcher; - this._watcher.Created += Watcher_Created; - } + public SomeClassUsingFileSystemWatcher(IFileSystemWatcher watcher, IFile file) + { + this._file = file; + this._watcher = watcher; + this._watcher.Created += Watcher_Created; + } - private void Watcher_Created(object sender, System.IO.FileSystemEventArgs e) - { - FileWasCreated = true; + private void Watcher_Created(object sender, System.IO.FileSystemEventArgs e) + { + FileWasCreated = true; - if(_file.Exists(e.FullPath)) - { - var text = _file.ReadAllText(e.FullPath); - } + if(_file.Exists(e.FullPath)) + { + var text = _file.ReadAllText(e.FullPath); } } } - ``` \ No newline at end of file