diff --git a/src/TestableIO.System.IO.Abstractions.TestingHelpers/IMockFileDataAccessor.cs b/src/TestableIO.System.IO.Abstractions.TestingHelpers/IMockFileDataAccessor.cs index 533e28be0..03b2af206 100644 --- a/src/TestableIO.System.IO.Abstractions.TestingHelpers/IMockFileDataAccessor.cs +++ b/src/TestableIO.System.IO.Abstractions.TestingHelpers/IMockFileDataAccessor.cs @@ -23,6 +23,13 @@ public interface IMockFileDataAccessor : IFileSystem /// The file. if the file does not exist. MockFileData GetFile(string path); + /// + /// Gets a drive. + /// + /// The name of the drive to get. + /// The drive. if the drive does not exist. + MockDriveData GetDrive(string name); + /// /// void AddFile(string path, MockFileData mockFile); @@ -31,6 +38,10 @@ public interface IMockFileDataAccessor : IFileSystem /// void AddDirectory(string path); + /// + /// + void AddDrive(string name, MockDriveData mockDrive); + /// /// void AddFileFromEmbeddedResource(string path, Assembly resourceAssembly, string embeddedResourcePath); @@ -74,6 +85,11 @@ public interface IMockFileDataAccessor : IFileSystem /// IEnumerable AllDirectories { get; } + /// + /// Gets the names of all drives. + /// + IEnumerable AllDrives { get; } + /// /// Gets a helper for string operations. /// diff --git a/src/TestableIO.System.IO.Abstractions.TestingHelpers/MockDriveData.cs b/src/TestableIO.System.IO.Abstractions.TestingHelpers/MockDriveData.cs new file mode 100644 index 000000000..9d3dc169e --- /dev/null +++ b/src/TestableIO.System.IO.Abstractions.TestingHelpers/MockDriveData.cs @@ -0,0 +1,76 @@ + +namespace System.IO.Abstractions.TestingHelpers +{ + /// + /// The class represents the associated data of a drive. + /// +#if FEATURE_SERIALIZABLE + [Serializable] +#endif + public class MockDriveData + { + /// + /// Initializes a new instance of the class. + /// + public MockDriveData() + { + IsReady = true; + } + + /// + /// Initializes a new instance of the class by copying the given . + /// + /// The template instance. + /// Thrown if is . + public MockDriveData(MockDriveData template) + { + if (template == null) + { + throw new ArgumentNullException(nameof(template)); + } + + AvailableFreeSpace = template.AvailableFreeSpace; + DriveFormat = template.DriveFormat; + DriveType = template.DriveType; + IsReady = template.IsReady; + TotalFreeSpace = template.TotalFreeSpace; + TotalSize = template.TotalSize; + VolumeLabel = template.VolumeLabel; + } + + /// + /// Gets or sets the amount of available free space of the , in bytes. + /// + public long AvailableFreeSpace { get; set; } + + /// + /// Gets or sets the name of the file system of the , such as NTFS or FAT32. + /// + public string DriveFormat { get; set; } + + /// + /// Gets or sets the drive type of the , such as CD-ROM, removable, network, or fixed. + /// + public DriveType DriveType { get; set; } + + /// + /// Gets or sets the value that indicates whether the is ready. + /// + public bool IsReady { get; set; } + + /// + /// Gets or sets the total amount of free space available on the , in bytes. + /// + public long TotalFreeSpace { get; set; } + + /// + /// Gets or sets the total size of storage space on the , in bytes. + /// + public long TotalSize { get; set; } + + /// + /// Gets or sets the volume label of the . + /// + public string VolumeLabel { get; set; } + } +} diff --git a/src/TestableIO.System.IO.Abstractions.TestingHelpers/MockDriveInfo.cs b/src/TestableIO.System.IO.Abstractions.TestingHelpers/MockDriveInfo.cs index 60cc6dbe1..fcacd5472 100644 --- a/src/TestableIO.System.IO.Abstractions.TestingHelpers/MockDriveInfo.cs +++ b/src/TestableIO.System.IO.Abstractions.TestingHelpers/MockDriveInfo.cs @@ -7,51 +7,60 @@ public class MockDriveInfo : DriveInfoBase { private readonly IMockFileDataAccessor mockFileDataAccessor; + private readonly string name; /// public MockDriveInfo(IMockFileDataAccessor mockFileDataAccessor, string name) : base(mockFileDataAccessor?.FileSystem) { this.mockFileDataAccessor = mockFileDataAccessor ?? throw new ArgumentNullException(nameof(mockFileDataAccessor)); + this.name = mockFileDataAccessor.PathVerifier.NormalizeDriveName(name); + } - if (name == null) + /// + public override long AvailableFreeSpace + { + get { - throw new ArgumentNullException(nameof(name)); + var mockDriveData = GetMockDriveData(); + return mockDriveData.AvailableFreeSpace; } + } - const string DRIVE_SEPARATOR = @":\"; - - if (name.Length == 1 - || (name.Length == 2 && name[1] == ':') - || (name.Length == 3 && mockFileDataAccessor.StringOperations.EndsWith(name, DRIVE_SEPARATOR))) + /// + public override string DriveFormat + { + get { - name = name[0] + DRIVE_SEPARATOR; + var mockDriveData = GetMockDriveData(); + return mockDriveData.DriveFormat; } - else - { - mockFileDataAccessor.PathVerifier.CheckInvalidPathChars(name); - name = mockFileDataAccessor.Path.GetPathRoot(name); + } - if (string.IsNullOrEmpty(name) || mockFileDataAccessor.StringOperations.StartsWith(name, @"\\")) - { - throw new ArgumentException( - @"Object must be a root directory (""C:\"") or a drive letter (""C"")."); - } + /// + public override DriveType DriveType + { + get + { + var mockDriveData = GetMockDriveData(); + return mockDriveData.DriveType; } - - Name = name; - IsReady = true; } /// - public new long AvailableFreeSpace { get; set; } - /// - public new string DriveFormat { get; set; } - /// - public new DriveType DriveType { get; set; } - /// - public new bool IsReady { get; protected set; } + public override bool IsReady + { + get + { + var mockDriveData = GetMockDriveData(); + return mockDriveData.IsReady; + } + } + /// - public override string Name { get; protected set; } + public override string Name + { + get { return name; } + } /// public override IDirectoryInfo RootDirectory @@ -63,16 +72,50 @@ public override IDirectoryInfo RootDirectory } /// - public override string ToString() + public override long TotalFreeSpace { - return Name; + get + { + var mockDriveData = GetMockDriveData(); + return mockDriveData.TotalFreeSpace; + } } /// - public new long TotalFreeSpace { get; protected set; } + public override long TotalSize + { + get + { + var mockDriveData = GetMockDriveData(); + return mockDriveData.TotalSize; + } + } + /// - public new long TotalSize { get; protected set; } + public override string VolumeLabel + { + get + { + var mockDriveData = GetMockDriveData(); + return mockDriveData.VolumeLabel; + } + set + { + var mockDriveData = GetMockDriveData(); + mockDriveData.VolumeLabel = value; + } + } + /// - public override string VolumeLabel { get; set; } + public override string ToString() + { + return Name; + } + + private MockDriveData GetMockDriveData() + { + return mockFileDataAccessor.GetDrive(name) + ?? throw CommonExceptions.FileNotFound(name); + } } } diff --git a/src/TestableIO.System.IO.Abstractions.TestingHelpers/MockDriveInfoFactory.cs b/src/TestableIO.System.IO.Abstractions.TestingHelpers/MockDriveInfoFactory.cs index 0ebc24070..9fafc539d 100644 --- a/src/TestableIO.System.IO.Abstractions.TestingHelpers/MockDriveInfoFactory.cs +++ b/src/TestableIO.System.IO.Abstractions.TestingHelpers/MockDriveInfoFactory.cs @@ -23,15 +23,8 @@ public IFileSystem FileSystem /// public IDriveInfo[] GetDrives() { - var driveLetters = new HashSet(new DriveEqualityComparer(mockFileSystem)); - foreach (var path in mockFileSystem.AllPaths) - { - var pathRoot = mockFileSystem.Path.GetPathRoot(path); - driveLetters.Add(pathRoot); - } - var result = new List(); - foreach (string driveLetter in driveLetters) + foreach (string driveLetter in mockFileSystem.AllDrives) { try { diff --git a/src/TestableIO.System.IO.Abstractions.TestingHelpers/MockFileSystem.cs b/src/TestableIO.System.IO.Abstractions.TestingHelpers/MockFileSystem.cs index 1e977d517..cac9b0648 100644 --- a/src/TestableIO.System.IO.Abstractions.TestingHelpers/MockFileSystem.cs +++ b/src/TestableIO.System.IO.Abstractions.TestingHelpers/MockFileSystem.cs @@ -17,6 +17,7 @@ public class MockFileSystem : FileSystemBase, IMockFileDataAccessor private const string TEMP_DIRECTORY = @"C:\temp"; private readonly IDictionary files; + private readonly IDictionary drives; private readonly PathVerifier pathVerifier; #if FEATURE_SERIALIZABLE [NonSerialized] @@ -58,6 +59,7 @@ public MockFileSystem(IDictionary files, MockFileSystemOpt StringOperations = new StringOperations(XFS.IsUnixPlatform()); pathVerifier = new PathVerifier(this); this.files = new Dictionary(StringOperations.Comparer); + drives = new Dictionary(StringOperations.Comparer); Path = new MockPath(this, defaultTempDirectory); File = new MockFile(this); @@ -188,43 +190,66 @@ public MockFileData GetFile(string path) return GetFileWithoutFixingPath(path); } - private void SetEntry(string path, MockFileData mockFile) + /// + public MockDriveData GetDrive(string name) { - path = FixPath(path, true).TrimSlashes(); - files[path] = new FileSystemEntry { Path = path, Data = mockFile }; + name = PathVerifier.NormalizeDriveName(name); + lock (drives) + { + return drives.TryGetValue(name, out var result) ? result : null; + } } - /// - public void AddFile(string path, MockFileData mockFile) + private void SetEntry(string path, MockFileData mockFile) { - var fixedPath = FixPath(path, true); + path = FixPath(path, true).TrimSlashes(); + lock (files) { - mockFile ??= new MockFileData(string.Empty); - var file = GetFile(fixedPath); + files[path] = new FileSystemEntry { Path = path, Data = mockFile }; + } - if (file != null) + lock (drives) + { + if (PathVerifier.TryNormalizeDriveName(path, out string driveLetter)) { - var isReadOnly = (file.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly; - var isHidden = (file.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden; - - if (isReadOnly || isHidden) + if (!drives.ContainsKey(driveLetter)) { - throw CommonExceptions.AccessDenied(path); + drives[driveLetter] = new MockDriveData(); } - file.CheckFileAccess(fixedPath, FileAccess.Write); - mockFile.CreationTime = file.CreationTime; } + } + } + + /// + public void AddFile(string path, MockFileData mockFile) + { + var fixedPath = FixPath(path, true); - var directoryPath = Path.GetDirectoryName(fixedPath); + mockFile ??= new MockFileData(string.Empty); + var file = GetFile(fixedPath); + + if (file != null) + { + var isReadOnly = (file.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly; + var isHidden = (file.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden; - if (!DirectoryExistsWithoutFixingPath(directoryPath)) + if (isReadOnly || isHidden) { - AddDirectory(directoryPath); + throw CommonExceptions.AccessDenied(path); } + file.CheckFileAccess(fixedPath, FileAccess.Write); + mockFile.CreationTime = file.CreationTime; + } - SetEntry(fixedPath, mockFile); + var directoryPath = Path.GetDirectoryName(fixedPath); + + if (!DirectoryExistsWithoutFixingPath(directoryPath)) + { + AddDirectory(directoryPath); } + + SetEntry(fixedPath, mockFile); } /// @@ -283,45 +308,42 @@ public void AddDirectory(string path) var fixedPath = FixPath(path, true); var separator = Path.DirectorySeparatorChar.ToString(); - lock (files) + if (FileExists(fixedPath) && FileIsReadOnly(fixedPath)) { - if (FileExists(fixedPath) && FileIsReadOnly(fixedPath)) - { - throw CommonExceptions.AccessDenied(fixedPath); - } - var lastIndex = 0; - var isUnc = - StringOperations.StartsWith(fixedPath, @"\\") || - StringOperations.StartsWith(fixedPath, @"//"); - - if (isUnc) - { - //First, confirm they aren't trying to create '\\server\' - lastIndex = StringOperations.IndexOf(fixedPath, separator, 2); + throw CommonExceptions.AccessDenied(fixedPath); + } + var lastIndex = 0; + var isUnc = + StringOperations.StartsWith(fixedPath, @"\\") || + StringOperations.StartsWith(fixedPath, @"//"); - if (lastIndex < 0) - { - throw CommonExceptions.InvalidUncPath(nameof(path)); - } + if (isUnc) + { + //First, confirm they aren't trying to create '\\server\' + lastIndex = StringOperations.IndexOf(fixedPath, separator, 2); - /* - * Although CreateDirectory(@"\\server\share\") is not going to work in real code, we allow it here for the purposes of setting up test doubles. - * See PR https://github.com/TestableIO/System.IO.Abstractions/pull/90 for conversation - */ + if (lastIndex < 0) + { + throw CommonExceptions.InvalidUncPath(nameof(path)); } - while ((lastIndex = StringOperations.IndexOf(fixedPath, separator, lastIndex + 1)) > -1) + /* + * Although CreateDirectory(@"\\server\share\") is not going to work in real code, we allow it here for the purposes of setting up test doubles. + * See PR https://github.com/TestableIO/System.IO.Abstractions/pull/90 for conversation + */ + } + + while ((lastIndex = StringOperations.IndexOf(fixedPath, separator, lastIndex + 1)) > -1) + { + var segment = fixedPath.Substring(0, lastIndex + 1); + if (!DirectoryExistsWithoutFixingPath(segment)) { - var segment = fixedPath.Substring(0, lastIndex + 1); - if (!DirectoryExistsWithoutFixingPath(segment)) - { - SetEntry(segment, new MockDirectoryData()); - } + SetEntry(segment, new MockDirectoryData()); } - - var s = StringOperations.EndsWith(fixedPath, separator) ? fixedPath : fixedPath + separator; - SetEntry(s, new MockDirectoryData()); } + + var s = StringOperations.EndsWith(fixedPath, separator) ? fixedPath : fixedPath + separator; + SetEntry(s, new MockDirectoryData()); } /// @@ -359,6 +381,16 @@ public void AddFilesFromEmbeddedNamespace(string path, Assembly resourceAssembly } } + /// + public void AddDrive(string name, MockDriveData mockDrive) + { + name = PathVerifier.NormalizeDriveName(name); + lock (drives) + { + drives[name] = mockDrive; + } + } + /// public void MoveDirectory(string sourcePath, string destPath) { @@ -483,6 +515,18 @@ public IEnumerable AllDirectories } } + /// + public IEnumerable AllDrives + { + get + { + lock (drives) + { + return drives.Keys.ToArray(); + } + } + } + [OnDeserializing] private void OnDeserializing(StreamingContext c) { diff --git a/src/TestableIO.System.IO.Abstractions.TestingHelpers/PathVerifier.cs b/src/TestableIO.System.IO.Abstractions.TestingHelpers/PathVerifier.cs index a635399b1..d33c295e3 100644 --- a/src/TestableIO.System.IO.Abstractions.TestingHelpers/PathVerifier.cs +++ b/src/TestableIO.System.IO.Abstractions.TestingHelpers/PathVerifier.cs @@ -118,5 +118,51 @@ public void CheckInvalidPathChars(string path, bool checkAdditional = false) throw CommonExceptions.IllegalCharactersInPath(); } } + + /// + /// Determines the normalized drive name used for drive identification. + /// + /// Thrown if the is not a valid drive name. + public string NormalizeDriveName(string name) + { + return TryNormalizeDriveName(name, out var result) + ? result + : throw new ArgumentException( + @"Object must be a root directory (""C:\"") or a drive letter (""C"")."); + } + + /// + /// Tries to determine the normalized drive name used for drive identification. + /// + public bool TryNormalizeDriveName(string name, out string result) + { + if (name == null) + { + throw new ArgumentNullException(nameof(name)); + } + + const string DRIVE_SEPARATOR = @":\"; + + if (name.Length == 1 + || (name.Length == 2 && name[1] == ':') + || (name.Length == 3 && _mockFileDataAccessor.StringOperations.EndsWith(name, DRIVE_SEPARATOR))) + { + name = name[0] + DRIVE_SEPARATOR; + } + else + { + CheckInvalidPathChars(name); + name = _mockFileDataAccessor.Path.GetPathRoot(name); + + if (string.IsNullOrEmpty(name) || _mockFileDataAccessor.StringOperations.StartsWith(name, @"\\")) + { + result = null; + return false; + } + } + + result = name; + return true; + } } } diff --git a/src/TestableIO.System.IO.Abstractions.Wrappers/DriveInfoBase.cs b/src/TestableIO.System.IO.Abstractions.Wrappers/DriveInfoBase.cs index 15830733a..14ac46b76 100644 --- a/src/TestableIO.System.IO.Abstractions.Wrappers/DriveInfoBase.cs +++ b/src/TestableIO.System.IO.Abstractions.Wrappers/DriveInfoBase.cs @@ -20,118 +20,32 @@ internal DriveInfoBase() { } /// public IFileSystem FileSystem { get; } - /// - /// - /// Gets or sets the amount of available free space on a drive, in bytes. - /// - /// The amount of free space available on the drive, in bytes. - /// - /// This property indicates the amount of free space available on the drive. - /// Note that this number may be different from the TotalFreeSpace number because this property takes into account disk quotas. - /// - /// Thrown if the access to the drive information is denied. - /// Thrown if an I/O error occurred (for example, a disk error or a drive was not ready). - public virtual long AvailableFreeSpace { get; protected set; } + /// + public abstract long AvailableFreeSpace { get; } - /// - /// - /// Gets or sets the name of the file system, such as NTFS or FAT32. - /// - /// - /// Use DriveFormat to determine what formatting a drive uses. - /// - /// The name of the file system on the specified drive. - /// Thrown if the access to the drive information is denied. - /// Thrown if the drive does not exist or is not mapped. - /// Thrown if an I/O error occurred (for example, a disk error or a drive was not ready). - public virtual string DriveFormat { get; protected set; } + /// + public abstract string DriveFormat { get; } - /// - /// - /// Gets or sets the drive type, such as CD-ROM, removable, network, or fixed. - /// - /// One of the enumeration values that specifies a drive type. - /// - /// The DriveType property indicates whether a drive is one of the following: CDRom, Fixed, Network, NoRootDirectory, Ram, Removable, or Unknown. - /// These values are described in the DriveType enumeration. - /// - public virtual DriveType DriveType { get; protected set; } + /// + public abstract DriveType DriveType { get; } - /// - /// - /// Gets or sets a value indicating whether a drive is ready. - /// - /// - /// if the drive is ready; if the drive is not ready. - /// - /// - /// IsReady indicates whether a drive is ready. - /// For example, it indicates whether a CD is in a CD drive or whether a removable storage device is ready for read/write operations. - /// If you do not test whether a drive is ready, and it is not ready, querying the drive using will raise an IOException. - /// Do not rely on IsReady to avoid catching exceptions from other members such as TotalSize, TotalFreeSpace, and . - /// Between the time that your code checks IsReady and then accesses one of the other properties (even if the access occurs immediately after the check), - /// a drive may have been disconnected or a disk may have been removed. - /// - public virtual bool IsReady { get; protected set; } + /// + public abstract bool IsReady { get; } - /// - /// - /// Gets or sets the name of a drive, such as C:\. - /// - /// The name of the drive. - /// - /// This property is the name assigned to the drive, such as C:\ or E:\. - /// - public virtual string Name { get; protected set; } + /// + public abstract string Name { get; } - /// - /// - /// Gets or sets the root directory of a drive. - /// - /// An object that contains the root directory of the drive. - public virtual IDirectoryInfo RootDirectory { get; protected set; } + /// + public abstract IDirectoryInfo RootDirectory { get; } - /// - /// - /// Gets or sets the total amount of free space available on a drive, in bytes. - /// - /// The total free space available on a drive, in bytes. - /// This property indicates the total amount of free space available on the drive, not just what is available to the current user. - /// Thrown if the access to the drive information is denied. - /// Thrown if the drive does not exist or is not mapped. - /// Thrown if an I/O error occurred (for example, a disk error or a drive was not ready). - public virtual long TotalFreeSpace { get; protected set; } + /// + public abstract long TotalFreeSpace { get; } - /// - /// - /// Gets or sets the total size of storage space on a drive, in bytes. - /// - /// The total size of the drive, in bytes. - /// - /// This property indicates the total size of the drive in bytes, not just what is available to the current user. - /// - /// Thrown if the access to the drive information is denied. - /// Thrown if the drive does not exist or is not mapped. - /// Thrown if an I/O error occurred (for example, a disk error or a drive was not ready). - public virtual long TotalSize { get; protected set; } + /// + public abstract long TotalSize { get; } - /// - /// - /// Gets or sets the volume label of a drive. - /// - /// The volume label. - /// - /// The label length is determined by the operating system. For example, NTFS allows a volume label to be up to 32 characters long. Note that is a valid VolumeLabel. - /// - /// Thrown if an I/O error occurred (for example, a disk error or a drive was not ready). - /// Thrown if the drive does not exist or is not mapped. - /// Thrown if the caller does not have the required permission. - /// - /// Thrown if the volume label is being set on a network or CD-ROM drive - /// -or- - /// Access to the drive information is denied. - /// - public virtual string VolumeLabel { get; set; } + /// + public abstract string VolumeLabel { get; set; } /// /// Converts a into a . diff --git a/tests/TestableIO.System.IO.Abstractions.TestingHelpers.Tests/MockDriveInfoTests.cs b/tests/TestableIO.System.IO.Abstractions.TestingHelpers.Tests/MockDriveInfoTests.cs index 5b95cea13..ec172c381 100644 --- a/tests/TestableIO.System.IO.Abstractions.TestingHelpers.Tests/MockDriveInfoTests.cs +++ b/tests/TestableIO.System.IO.Abstractions.TestingHelpers.Tests/MockDriveInfoTests.cs @@ -1,4 +1,5 @@ using NUnit.Framework; +using System.Linq; namespace System.IO.Abstractions.TestingHelpers.Tests { @@ -84,5 +85,138 @@ public void MockDriveInfo_ToString_ShouldReturnTheDrivePath(string path, string // Assert Assert.That(mockDriveInfo.ToString(), Is.EqualTo(expectedPath)); } + + [Test] + public void MockDriveInfo_AvailableFreeSpace_ShouldReturnAvailableFreeSpaceOfDriveInMemoryFileSystem() + { + // Arrange + var availableFreeSpace = 1024L; + var driveData = new MockDriveData { AvailableFreeSpace = availableFreeSpace }; + var fileSystem = new MockFileSystem(); + fileSystem.AddDrive("C:", driveData); + var driveInfo = fileSystem.DriveInfo + .GetDrives() + .Single(x => x.Name == @"C:\"); + + // Act + var result = driveInfo.AvailableFreeSpace; + + // Assert + Assert.That(result, Is.EqualTo(availableFreeSpace)); + } + + [Test] + public void MockDriveInfo_DriveFormat_ShouldReturnDriveFormatOfDriveInMemoryFileSystem() + { + // Arrange + var driveFormat = "NTFS"; + var driveData = new MockDriveData { DriveFormat = driveFormat }; + var fileSystem = new MockFileSystem(); + fileSystem.AddDrive("C:", driveData); + var driveInfo = fileSystem.DriveInfo + .GetDrives() + .Single(x => x.Name == @"C:\"); + + // Act + var result = driveInfo.DriveFormat; + + // Assert + Assert.That(result, Is.EqualTo(driveFormat)); + } + + [Test] + public void MockDriveInfo_DriveType_ShouldReturnDriveTypeOfDriveInMemoryFileSystem() + { + // Arrange + var driveType = DriveType.Fixed; + var driveData = new MockDriveData { DriveType = driveType }; + var fileSystem = new MockFileSystem(); + fileSystem.AddDrive("C:", driveData); + var driveInfo = fileSystem.DriveInfo + .GetDrives() + .Single(x => x.Name == @"C:\"); + + // Act + var result = driveInfo.DriveType; + + // Assert + Assert.That(result, Is.EqualTo(driveType)); + } + + [TestCase(true)] + [TestCase(false)] + public void MockDriveInfo_IsReady_ShouldReturnIsReadyOfDriveInMemoryFileSystem(bool isReady) + { + // Arrange + var driveData = new MockDriveData { IsReady = isReady }; + var fileSystem = new MockFileSystem(); + fileSystem.AddDrive("C:", driveData); + var driveInfo = fileSystem.DriveInfo + .GetDrives() + .Single(x => x.Name == @"C:\"); + + // Act + var result = driveInfo.IsReady; + + // Assert + Assert.That(result, Is.EqualTo(isReady)); + } + + [Test] + public void MockDriveInfo_TotalFreeSpace_ShouldReturnTotalFreeSpaceOfDriveInMemoryFileSystem() + { + // Arrange + var totalFreeSpace = 4096L; + var driveData = new MockDriveData { TotalFreeSpace = totalFreeSpace }; + var fileSystem = new MockFileSystem(); + fileSystem.AddDrive("C:", driveData); + var driveInfo = fileSystem.DriveInfo + .GetDrives() + .Single(x => x.Name == @"C:\"); + + // Act + var result = driveInfo.TotalFreeSpace; + + // Assert + Assert.That(result, Is.EqualTo(totalFreeSpace)); + } + + [Test] + public void MockDriveInfo_TotalSize_ShouldReturnTotalSizeOfDriveInMemoryFileSystem() + { + // Arrange + var totalSize = 8192L; + var driveData = new MockDriveData { TotalSize = totalSize }; + var fileSystem = new MockFileSystem(); + fileSystem.AddDrive("C:", driveData); + var driveInfo = fileSystem.DriveInfo + .GetDrives() + .Single(x => x.Name == @"C:\"); + + // Act + var result = driveInfo.TotalSize; + + // Assert + Assert.That(result, Is.EqualTo(totalSize)); + } + + [Test] + public void MockDriveInfo_VolumeLabel_ShouldReturnVolumeLabelOfDriveInMemoryFileSystem() + { + // Arrange + var volumeLabel = "Windows"; + var driveData = new MockDriveData { VolumeLabel = volumeLabel }; + var fileSystem = new MockFileSystem(); + fileSystem.AddDrive("C:", driveData); + var driveInfo = fileSystem.DriveInfo + .GetDrives() + .Single(x => x.Name == @"C:\"); + + // Act + var result = driveInfo.VolumeLabel; + + // Assert + Assert.That(result, Is.EqualTo(volumeLabel)); + } } } diff --git a/tests/TestableIO.System.IO.Abstractions.TestingHelpers.Tests/MockFileSystemTests.cs b/tests/TestableIO.System.IO.Abstractions.TestingHelpers.Tests/MockFileSystemTests.cs index 0294d092d..28fed6d61 100644 --- a/tests/TestableIO.System.IO.Abstractions.TestingHelpers.Tests/MockFileSystemTests.cs +++ b/tests/TestableIO.System.IO.Abstractions.TestingHelpers.Tests/MockFileSystemTests.cs @@ -207,6 +207,18 @@ public void MockFileSystem_AddDirectory_ShouldThrowExceptionIfDirectoryIsReadOnl Assert.Throws(action); } + [Test] + public void MockFileSystem_AddDrive_ShouldExist() + { + string name = @"D:\"; + var fileSystem = new MockFileSystem(); + fileSystem.AddDrive(name, new MockDriveData()); + + var actualResults = fileSystem.DriveInfo.GetDrives().Select(d => d.Name); + + Assert.That(actualResults, Does.Contain(name)); + } + [Test] public void MockFileSystem_DriveInfo_ShouldNotThrowAnyException() {