diff --git a/README.md b/README.md index 4aa074087..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,17 +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(); ... } ``` + +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 +[Test] +public void Test1() +{ + 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(); + + 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); +} + +public class SomeClassUsingFileSystemWatcher +{ + private readonly IFileSystemWatcher _watcher; + private readonly IFile _file; + + public bool FileWasCreated { get; private set; } + + 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; + + if(_file.Exists(e.FullPath)) + { + var text = _file.ReadAllText(e.FullPath); + } + } +} +``` \ No newline at end of file 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.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/IMockFileDataAccessor.cs b/System.IO.Abstractions.TestingHelpers/IMockFileDataAccessor.cs index 6c2c6350a..d42063fd8 100644 --- a/System.IO.Abstractions.TestingHelpers/IMockFileDataAccessor.cs +++ b/System.IO.Abstractions.TestingHelpers/IMockFileDataAccessor.cs @@ -56,10 +56,10 @@ public interface IMockFileDataAccessor StringOperations StringOperations { get; } - FileBase File { get; } - DirectoryBase Directory { get; } + 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 34691af01..6d5da990e 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) { @@ -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 8e4edc7d1..83957f0d8 100644 --- a/System.IO.Abstractions.TestingHelpers/MockFileSystem.cs +++ b/System.IO.Abstractions.TestingHelpers/MockFileSystem.cs @@ -53,11 +53,11 @@ 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; } + public IPath Path { get; } public IDirectoryInfoFactory DirectoryInfo { get; } public IDriveInfoFactory DriveInfo { get; } public IFileSystemWatcherFactory FileSystemWatcher { get; set; } 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/DirectoryBase.cs b/System.IO.Abstractions/DirectoryBase.cs index c4a9b08fc..8c8283cdc 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) { @@ -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/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/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 144876350..3c29b1563 100644 --- a/System.IO.Abstractions/FileSystem.cs +++ b/System.IO.Abstractions/FileSystem.cs @@ -15,15 +15,15 @@ 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; } 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 cca10924d..5d7836c6e 100644 --- a/System.IO.Abstractions/FileSystemWatcherBase.cs +++ b/System.IO.Abstractions/FileSystemWatcherBase.cs @@ -1,10 +1,12 @@ -using System.ComponentModel; +#if NET40 +using System.ComponentModel; +#endif 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/IDirectory.cs b/System.IO.Abstractions/IDirectory.cs new file mode 100644 index 000000000..5e7af2826 --- /dev/null +++ b/System.IO.Abstractions/IDirectory.cs @@ -0,0 +1,105 @@ +using System.Collections.Generic; +using System.Security.AccessControl; + +namespace System.IO.Abstractions +{ + public interface IDirectory + { + /// + /// Exposes the underlying filesystem implementation. This is useful for implementing extension methods. + /// + IFileSystem FileSystem { get; } + + /// + IDirectoryInfo CreateDirectory(string path); + +#if NET40 + /// + IDirectoryInfo CreateDirectory(string path, DirectorySecurity directorySecurity); +#endif + /// + void Delete(string path); + /// + void Delete(string path, bool recursive); + /// + 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); +#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); + /// + 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 new file mode 100644 index 000000000..169add2c2 --- /dev/null +++ b/System.IO.Abstractions/IFile.cs @@ -0,0 +1,135 @@ +using System.Collections.Generic; +using System.Security.AccessControl; +using System.Text; + +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); + } +} \ 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 32472125e..48ad19b07 100644 --- a/System.IO.Abstractions/IFileSystem.cs +++ b/System.IO.Abstractions/IFileSystem.cs @@ -2,11 +2,11 @@ { public interface IFileSystem { - FileBase File { get; } - DirectoryBase Directory { get; } + IFile File { get; } + 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 new file mode 100644 index 000000000..8faae96c9 --- /dev/null +++ b/System.IO.Abstractions/IFileSystemWatcher.cs @@ -0,0 +1,50 @@ +#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; } + /// + 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/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); } } 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) { diff --git a/version.json b/version.json index 785fbb59a..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.1", + "version": "4.0", "assemblyVersion": { "precision": "major" },