diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index aa1f8f706..b26eb84ed 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -9,6 +9,7 @@ jobs: unit-tests: name: "Unit tests" strategy: + fail-fast: false matrix: os: [ ubuntu-latest, windows-latest, macos-latest ] runs-on: ${{ matrix.os }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f2908434e..c06ead140 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,6 +9,7 @@ jobs: unit-tests: name: "Unit tests" strategy: + fail-fast: false matrix: os: [ ubuntu-latest, windows-latest, macos-latest ] runs-on: ${{ matrix.os }} diff --git a/Directory.Packages.props b/Directory.Packages.props index 63a6ccf92..fc4a59781 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -21,7 +21,7 @@ - + diff --git a/Source/Testably.Abstractions.Testing/FileSystem/FileVersionInfoFactoryMock.cs b/Source/Testably.Abstractions.Testing/FileSystem/FileVersionInfoFactoryMock.cs index f39326985..99aa4286c 100644 --- a/Source/Testably.Abstractions.Testing/FileSystem/FileVersionInfoFactoryMock.cs +++ b/Source/Testably.Abstractions.Testing/FileSystem/FileVersionInfoFactoryMock.cs @@ -1,4 +1,6 @@ using System; +using Testably.Abstractions.Testing.Helpers; +using Testably.Abstractions.Testing.Storage; namespace Testably.Abstractions.Testing.FileSystem; @@ -24,7 +26,15 @@ public IFileVersionInfo GetVersionInfo(string fileName) using IDisposable registration = _fileSystem.StatisticsRegistration .FileVersionInfo.RegisterMethod(nameof(GetVersionInfo), fileName); - return FileVersionInfoMock.New(_fileSystem.Storage.GetLocation(fileName), _fileSystem); + fileName.EnsureValidFormat(_fileSystem, nameof(fileName)); + IStorageLocation location = _fileSystem.Storage.GetLocation(fileName); + location.ThrowExceptionIfNotFound(_fileSystem); + + FileVersionInfoContainer container = _fileSystem.Storage.GetVersionInfo(location) + ?? FileVersionInfoContainer.None; + + return FileVersionInfoMock.New(_fileSystem.Storage.GetLocation(fileName), container, + _fileSystem); } #endregion diff --git a/Source/Testably.Abstractions.Testing/FileSystem/FileVersionInfoMock.cs b/Source/Testably.Abstractions.Testing/FileSystem/FileVersionInfoMock.cs index 2ae496bb3..229b8acab 100644 --- a/Source/Testably.Abstractions.Testing/FileSystem/FileVersionInfoMock.cs +++ b/Source/Testably.Abstractions.Testing/FileSystem/FileVersionInfoMock.cs @@ -1,4 +1,5 @@ using System; +using System.Text; using Testably.Abstractions.Testing.Statistics; using Testably.Abstractions.Testing.Storage; @@ -13,11 +14,16 @@ internal sealed class FileVersionInfoMock : IFileVersionInfo public IFileSystem FileSystem => _fileSystem; + private readonly FileVersionInfoContainer _container; private readonly MockFileSystem _fileSystem; private readonly string _path; - private FileVersionInfoMock(IStorageLocation location, MockFileSystem fileSystem) + private FileVersionInfoMock( + IStorageLocation location, + FileVersionInfoContainer container, + MockFileSystem fileSystem) { + _container = container; _fileSystem = fileSystem; _path = location.FullPath; } @@ -33,7 +39,7 @@ public string? Comments .FileVersionInfo.RegisterPathProperty(_path, nameof(Comments), PropertyAccess.Get); - return ""; + return _container.Comments; } } @@ -46,7 +52,7 @@ public string? CompanyName .FileVersionInfo.RegisterPathProperty(_path, nameof(CompanyName), PropertyAccess.Get); - return ""; + return _container.CompanyName; } } @@ -59,7 +65,7 @@ public int FileBuildPart .FileVersionInfo.RegisterPathProperty(_path, nameof(FileBuildPart), PropertyAccess.Get); - return 0; + return _container.FileBuildPart; } } @@ -72,7 +78,7 @@ public string? FileDescription .FileVersionInfo.RegisterPathProperty(_path, nameof(FileDescription), PropertyAccess.Get); - return ""; + return _container.FileDescription; } } @@ -85,7 +91,7 @@ public int FileMajorPart .FileVersionInfo.RegisterPathProperty(_path, nameof(FileMajorPart), PropertyAccess.Get); - return 0; + return _container.FileMajorPart; } } @@ -98,7 +104,7 @@ public int FileMinorPart .FileVersionInfo.RegisterPathProperty(_path, nameof(FileMinorPart), PropertyAccess.Get); - return 0; + return _container.FileMinorPart; } } @@ -111,7 +117,7 @@ public string FileName .FileVersionInfo.RegisterPathProperty(_path, nameof(FileName), PropertyAccess.Get); - return ""; + return _path; } } @@ -124,7 +130,7 @@ public int FilePrivatePart .FileVersionInfo.RegisterPathProperty(_path, nameof(FilePrivatePart), PropertyAccess.Get); - return 0; + return _container.FilePrivatePart; } } @@ -137,7 +143,7 @@ public string? FileVersion .FileVersionInfo.RegisterPathProperty(_path, nameof(FileVersion), PropertyAccess.Get); - return ""; + return _container.FileVersion; } } @@ -150,7 +156,7 @@ public string? InternalName .FileVersionInfo.RegisterPathProperty(_path, nameof(InternalName), PropertyAccess.Get); - return ""; + return _container.InternalName; } } @@ -163,7 +169,7 @@ public bool IsDebug .FileVersionInfo.RegisterPathProperty(_path, nameof(IsDebug), PropertyAccess.Get); - return false; + return _container.IsDebug; } } @@ -176,7 +182,7 @@ public bool IsPatched .FileVersionInfo.RegisterPathProperty(_path, nameof(IsPatched), PropertyAccess.Get); - return false; + return _container.IsPatched; } } @@ -189,7 +195,7 @@ public bool IsPreRelease .FileVersionInfo.RegisterPathProperty(_path, nameof(IsPreRelease), PropertyAccess.Get); - return false; + return _container.IsPreRelease; } } @@ -202,7 +208,7 @@ public bool IsPrivateBuild .FileVersionInfo.RegisterPathProperty(_path, nameof(IsPrivateBuild), PropertyAccess.Get); - return false; + return _container.IsPrivateBuild; } } @@ -215,7 +221,7 @@ public bool IsSpecialBuild .FileVersionInfo.RegisterPathProperty(_path, nameof(IsSpecialBuild), PropertyAccess.Get); - return false; + return _container.IsSpecialBuild; } } @@ -228,7 +234,7 @@ public string? Language .FileVersionInfo.RegisterPathProperty(_path, nameof(Language), PropertyAccess.Get); - return ""; + return _container.Language; } } @@ -241,7 +247,7 @@ public string? LegalCopyright .FileVersionInfo.RegisterPathProperty(_path, nameof(LegalCopyright), PropertyAccess.Get); - return ""; + return _container.LegalCopyright; } } @@ -254,7 +260,7 @@ public string? LegalTrademarks .FileVersionInfo.RegisterPathProperty(_path, nameof(LegalTrademarks), PropertyAccess.Get); - return ""; + return _container.LegalTrademarks; } } @@ -267,7 +273,7 @@ public string? OriginalFilename .FileVersionInfo.RegisterPathProperty(_path, nameof(OriginalFilename), PropertyAccess.Get); - return ""; + return _container.OriginalFilename; } } @@ -280,7 +286,7 @@ public string? PrivateBuild .FileVersionInfo.RegisterPathProperty(_path, nameof(PrivateBuild), PropertyAccess.Get); - return ""; + return _container.PrivateBuild; } } @@ -293,7 +299,7 @@ public int ProductBuildPart .FileVersionInfo.RegisterPathProperty(_path, nameof(ProductBuildPart), PropertyAccess.Get); - return 0; + return _container.ProductBuildPart; } } @@ -306,7 +312,7 @@ public int ProductMajorPart .FileVersionInfo.RegisterPathProperty(_path, nameof(ProductMajorPart), PropertyAccess.Get); - return 0; + return _container.ProductMajorPart; } } @@ -319,7 +325,7 @@ public int ProductMinorPart .FileVersionInfo.RegisterPathProperty(_path, nameof(ProductMinorPart), PropertyAccess.Get); - return 0; + return _container.ProductMinorPart; } } @@ -332,7 +338,7 @@ public string? ProductName .FileVersionInfo.RegisterPathProperty(_path, nameof(ProductName), PropertyAccess.Get); - return ""; + return _container.ProductName; } } @@ -345,7 +351,7 @@ public int ProductPrivatePart .FileVersionInfo.RegisterPathProperty(_path, nameof(ProductPrivatePart), PropertyAccess.Get); - return 0; + return _container.ProductPrivatePart; } } @@ -358,7 +364,7 @@ public string? ProductVersion .FileVersionInfo.RegisterPathProperty(_path, nameof(ProductVersion), PropertyAccess.Get); - return ""; + return _container.ProductVersion; } } @@ -371,12 +377,38 @@ public string? SpecialBuild .FileVersionInfo.RegisterPathProperty(_path, nameof(SpecialBuild), PropertyAccess.Get); - return ""; + return _container.SpecialBuild; } } #endregion - internal static FileVersionInfoMock New(IStorageLocation location, MockFileSystem fileSystem) - => new(location, fileSystem); + /// + public override string ToString() + { + // An initial capacity of 512 was chosen because it is large enough to cover + // the size of the static strings with enough capacity left over to cover + // average length property values. + StringBuilder sb = new(512); + sb.Append("File: ").AppendLine(FileName); + sb.Append("InternalName: ").AppendLine(InternalName); + sb.Append("OriginalFilename: ").AppendLine(OriginalFilename); + sb.Append("FileVersion: ").AppendLine(FileVersion); + sb.Append("FileDescription: ").AppendLine(FileDescription); + sb.Append("Product: ").AppendLine(ProductName); + sb.Append("ProductVersion: ").AppendLine(ProductVersion); + sb.Append("Debug: ").AppendLine(IsDebug.ToString()); + sb.Append("Patched: ").AppendLine(IsPatched.ToString()); + sb.Append("PreRelease: ").AppendLine(IsPreRelease.ToString()); + sb.Append("PrivateBuild: ").AppendLine(IsPrivateBuild.ToString()); + sb.Append("SpecialBuild: ").AppendLine(IsSpecialBuild.ToString()); + sb.Append("Language: ").AppendLine(Language); + return sb.ToString(); + } + + internal static FileVersionInfoMock New( + IStorageLocation location, + FileVersionInfoContainer container, + MockFileSystem fileSystem) + => new(location, container, fileSystem); } diff --git a/Source/Testably.Abstractions.Testing/Initializer/FileVersionInfoBuilder.cs b/Source/Testably.Abstractions.Testing/Initializer/FileVersionInfoBuilder.cs new file mode 100644 index 000000000..3d98efb14 --- /dev/null +++ b/Source/Testably.Abstractions.Testing/Initializer/FileVersionInfoBuilder.cs @@ -0,0 +1,176 @@ +using Testably.Abstractions.Testing.Storage; + +namespace Testably.Abstractions.Testing.Initializer; + +/// +/// The builder for registering a on the . +/// +public sealed class FileVersionInfoBuilder +{ + private readonly FileVersionInfoContainer _container = new(); + + /// + /// Sets the . + /// + public FileVersionInfoBuilder SetComments(string? comments) + { + _container.Comments = comments; + return this; + } + + /// + /// Sets the . + /// + public FileVersionInfoBuilder SetCompanyName(string? companyName) + { + _container.CompanyName = companyName; + return this; + } + + /// + /// Sets the . + /// + public FileVersionInfoBuilder SetFileDescription(string? fileDescription) + { + _container.FileDescription = fileDescription; + return this; + } + + /// + /// Sets the . + /// + public FileVersionInfoBuilder SetFileVersion(string? fileVersion) + { + _container.FileVersion = fileVersion; + return this; + } + + /// + /// Sets the . + /// + public FileVersionInfoBuilder SetInternalName(string? internalName) + { + _container.InternalName = internalName; + return this; + } + + /// + /// Sets the . + /// + public FileVersionInfoBuilder SetIsDebug(bool isDebug) + { + _container.IsDebug = isDebug; + return this; + } + + /// + /// Sets the . + /// + public FileVersionInfoBuilder SetIsPatched(bool isPatched) + { + _container.IsPatched = isPatched; + return this; + } + + /// + /// Sets the . + /// + public FileVersionInfoBuilder SetIsPreRelease(bool isPreRelease) + { + _container.IsPreRelease = isPreRelease; + return this; + } + + /// + /// Sets the . + /// + public FileVersionInfoBuilder SetIsPrivateBuild(bool isPrivateBuild) + { + _container.IsPrivateBuild = isPrivateBuild; + return this; + } + + /// + /// Sets the . + /// + public FileVersionInfoBuilder SetIsSpecialBuild(bool isSpecialBuild) + { + _container.IsSpecialBuild = isSpecialBuild; + return this; + } + + /// + /// Sets the . + /// + public FileVersionInfoBuilder SetLanguage(string? language) + { + _container.Language = language; + return this; + } + + /// + /// Sets the . + /// + public FileVersionInfoBuilder SetLegalCopyright(string? legalCopyright) + { + _container.LegalCopyright = legalCopyright; + return this; + } + + /// + /// Sets the . + /// + public FileVersionInfoBuilder SetLegalTrademarks(string? legalTrademarks) + { + _container.LegalTrademarks = legalTrademarks; + return this; + } + + /// + /// Sets the . + /// + public FileVersionInfoBuilder SetOriginalFilename(string? originalFilename) + { + _container.OriginalFilename = originalFilename; + return this; + } + + /// + /// Sets the . + /// + public FileVersionInfoBuilder SetPrivateBuild(string? privateBuild) + { + _container.PrivateBuild = privateBuild; + return this; + } + + /// + /// Sets the . + /// + public FileVersionInfoBuilder SetProductName(string? productName) + { + _container.ProductName = productName; + return this; + } + + /// + /// Sets the . + /// + public FileVersionInfoBuilder SetProductVersion(string? productVersion) + { + _container.ProductVersion = productVersion; + return this; + } + + /// + /// Sets the . + /// + public FileVersionInfoBuilder SetSpecialBuild(string? specialBuild) + { + _container.SpecialBuild = specialBuild; + return this; + } + + internal FileVersionInfoContainer Create() + => _container; +} diff --git a/Source/Testably.Abstractions.Testing/MockFileSystem.cs b/Source/Testably.Abstractions.Testing/MockFileSystem.cs index c6faf9557..49c72fef6 100644 --- a/Source/Testably.Abstractions.Testing/MockFileSystem.cs +++ b/Source/Testably.Abstractions.Testing/MockFileSystem.cs @@ -4,6 +4,7 @@ using System.IO; using Testably.Abstractions.Testing.FileSystem; using Testably.Abstractions.Testing.Helpers; +using Testably.Abstractions.Testing.Initializer; using Testably.Abstractions.Testing.RandomSystem; using Testably.Abstractions.Testing.Statistics; using Testably.Abstractions.Testing.Storage; @@ -74,6 +75,8 @@ internal IAccessControlStrategy AccessControlStrategy /// internal Execute Execute { get; } + internal FileSystemRegistration Registration { get; } + internal ISafeFileHandleStrategy SafeFileHandleStrategy { get; @@ -93,8 +96,6 @@ internal ISafeFileHandleStrategy SafeFileHandleStrategy internal IReadOnlyList StorageContainers => _storage.GetContainers(); - internal FileSystemRegistration Registration { get; } - private readonly DirectoryMock _directoryMock; private readonly FileMock _fileMock; private readonly PathMock _pathMock; @@ -212,6 +213,21 @@ public MockFileSystem WithDrive(string? drive, return this; } + /// + /// Registers a new with values from + /// the returned for + /// all files matching the . + /// + public MockFileSystem WithFileVersionInfo(string searchPattern, + Action fileVersionInfoBuilder) + { + FileVersionInfoBuilder builder = new(); + fileVersionInfoBuilder(builder); + FileVersionInfoContainer container = builder.Create(); + _storage.AddFileVersion(searchPattern, container); + return this; + } + /// /// Registers the strategy how to deal with s in the . /// @@ -240,7 +256,7 @@ private void InitializeFileSystem(MockFileSystemOptions initialization) catch (IOException) { // Ignore any IOException, when trying to read the current directory - // due to brittle tests on MacOS + // due to brittle tests on macOS } } diff --git a/Source/Testably.Abstractions.Testing/Storage/FileVersionInfoContainer.cs b/Source/Testably.Abstractions.Testing/Storage/FileVersionInfoContainer.cs new file mode 100644 index 000000000..061360a86 --- /dev/null +++ b/Source/Testably.Abstractions.Testing/Storage/FileVersionInfoContainer.cs @@ -0,0 +1,171 @@ +using System; +using System.Globalization; +using System.Linq; + +namespace Testably.Abstractions.Testing.Storage; + +internal sealed class FileVersionInfoContainer +{ + /// + public string? Comments { get; set; } + + /// + public string? CompanyName { get; set; } + + /// + public int FileBuildPart { get; private set; } + + /// + public string? FileDescription { get; set; } + + /// + public int FileMajorPart { get; private set; } + + /// + public int FileMinorPart { get; private set; } + + /// + public int FilePrivatePart { get; private set; } + + /// + public string? FileVersion + { + get => _fileVersion; + set + { + _fileVersion = value; + if (value != null) + { + string cleanedFileVersion = CleanVersion(value); + if (Version.TryParse(cleanedFileVersion, out Version? version)) + { + FileMajorPart = Math.Max(0, version.Major); + FileMinorPart = Math.Max(0, version.Minor); + FileBuildPart = Math.Max(0, version.Build); + FilePrivatePart = Math.Max(0, version.Revision); + } + else if (int.TryParse(cleanedFileVersion, NumberStyles.Integer, + CultureInfo.InvariantCulture, out int majorPart)) + { + FileMajorPart = Math.Max(0, majorPart); + FileMinorPart = 0; + FileBuildPart = 0; + FilePrivatePart = 0; + } + else + { + FileMajorPart = 0; + FileMinorPart = 0; + FileBuildPart = 0; + FilePrivatePart = 0; + } + } + } + } + + /// + public string? InternalName { get; set; } + + /// + public bool IsDebug { get; set; } + + /// + public bool IsPatched { get; set; } + + /// + public bool IsPreRelease { get; set; } + + /// + public bool IsPrivateBuild { get; set; } + + /// + public bool IsSpecialBuild { get; set; } + + /// + public string? Language { get; set; } + + /// + public string? LegalCopyright { get; set; } + + /// + public string? LegalTrademarks { get; set; } + + public static FileVersionInfoContainer None => new(); + + /// + public string? OriginalFilename { get; set; } + + /// + public string? PrivateBuild { get; set; } + + /// + public int ProductBuildPart { get; set; } + + /// + public int ProductMajorPart { get; set; } + + /// + public int ProductMinorPart { get; set; } + + /// + public string? ProductName { get; set; } + + /// + public int ProductPrivatePart { get; set; } + + /// + public string? ProductVersion + { + get => _productVersion; + set + { + _productVersion = value; + if (value != null) + { + string cleanedFileVersion = CleanVersion(value); + if (Version.TryParse(cleanedFileVersion, out Version? version)) + { + ProductMajorPart = Math.Max(0, version.Major); + ProductMinorPart = Math.Max(0, version.Minor); + ProductBuildPart = Math.Max(0, version.Build); + ProductPrivatePart = Math.Max(0, version.Revision); + } + else if (int.TryParse(cleanedFileVersion, NumberStyles.Integer, + CultureInfo.InvariantCulture, out int majorPart)) + { + ProductMajorPart = Math.Max(0, majorPart); + ProductMinorPart = 0; + ProductBuildPart = 0; + ProductPrivatePart = 0; + } + else + { + ProductMajorPart = 0; + ProductMinorPart = 0; + ProductBuildPart = 0; + ProductPrivatePart = 0; + } + } + } + } + + /// + public string? SpecialBuild { get; set; } + + private string? _fileVersion; + private string? _productVersion; + + private static string CleanVersion(string version) + { + char[] validVersionChars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.']; + for (int i = 0; i < version.Length; i++) + { + if (!validVersionChars.Contains(version[i])) + { + return version.Substring(0, i); + } + } + + return version; + } +} diff --git a/Source/Testably.Abstractions.Testing/Storage/IStorage.cs b/Source/Testably.Abstractions.Testing/Storage/IStorage.cs index 8e2b3b811..31c477a17 100644 --- a/Source/Testably.Abstractions.Testing/Storage/IStorage.cs +++ b/Source/Testably.Abstractions.Testing/Storage/IStorage.cs @@ -128,6 +128,13 @@ IStorageContainer GetOrCreateContainer(IStorageLocation location, Func containerGenerator, IFileSystemExtensibility? fileSystemExtensibility = null); + /// + /// Get an associated for the given . + /// + /// The location of the . + /// The if one was registered; or otherwise. + FileVersionInfoContainer? GetVersionInfo(IStorageLocation location); + /// /// Moves a specified file or directory to a new location and potentially a new file name.
/// This method does work across volumes. diff --git a/Source/Testably.Abstractions.Testing/Storage/InMemoryStorage.cs b/Source/Testably.Abstractions.Testing/Storage/InMemoryStorage.cs index 1726a9ae6..ab2cfcee7 100644 --- a/Source/Testably.Abstractions.Testing/Storage/InMemoryStorage.cs +++ b/Source/Testably.Abstractions.Testing/Storage/InMemoryStorage.cs @@ -21,6 +21,9 @@ private readonly ConcurrentDictionary private readonly ConcurrentDictionary> _fileHandles = new(); + private readonly List<(string, FileVersionInfoContainer)> + _fileVersions = new(); + private readonly ConcurrentDictionary _drives = new(StringComparer.OrdinalIgnoreCase); @@ -382,6 +385,29 @@ public IStorageContainer GetOrCreateContainer( return container; } + /// + public FileVersionInfoContainer? GetVersionInfo(IStorageLocation location) + { + EnumerationOptions enumerationOptions = new(); + foreach (var (searchPattern, container) in _fileVersions) + { + if (EnumerationOptionsHelper.MatchesPattern( + _fileSystem.Execute, + enumerationOptions, + location.FullPath, + searchPattern) || + (_fileSystem.Execute.IsNetFramework && + SearchPatternMatchesFileExtensionOnNetFramework( + searchPattern, + _fileSystem.Execute.Path.GetExtension(location.FullPath)))) + { + return container; + } + } + + return null; + } + /// public IStorageLocation? Move(IStorageLocation source, IStorageLocation destination, @@ -444,7 +470,8 @@ public IStorageContainer GetOrCreateContainer( if (_fileSystem.Execute.IsMac && source.FullPath.Equals(destination.FullPath, StringComparison.OrdinalIgnoreCase)) { - throw ExceptionFactory.ReplaceSourceMustBeDifferentThanDestination(source.FullPath, destination.FullPath); + throw ExceptionFactory.ReplaceSourceMustBeDifferentThanDestination(source.FullPath, + destination.FullPath); } using (_ = sourceContainer.RequestAccess( @@ -599,12 +626,11 @@ public bool TryGetFileAccess( if (CanGetAccess(location, access, share, deleteAccess, ignoreFileShare)) { Guid guid = Guid.NewGuid(); - FileHandle handle = new FileHandle(_fileSystem, guid, g => ReleaseAccess(g, location), + FileHandle handle = new(_fileSystem, guid, g => ReleaseAccess(g, location), access, share, deleteAccess); _fileHandles.AddOrUpdate(location, _ => { - ConcurrentDictionary dict = - new ConcurrentDictionary(); + ConcurrentDictionary dict = new(); dict.TryAdd(guid, handle); return dict; }, (_, dict) => @@ -659,6 +685,12 @@ private bool CanGetAccess( public override string ToString() => $"directories: {_containers.Count(x => x.Value.Type == FileSystemTypes.Directory)}, files: {_containers.Count(x => x.Value.Type == FileSystemTypes.File)}"; + /// + /// Register a file version. + /// + internal void AddFileVersion(string searchPattern, FileVersionInfoContainer container) + => _fileVersions.Add((searchPattern, container)); + /// /// Returns an ordered list of all stored containers. /// diff --git a/Source/Testably.Abstractions/FileSystem/FileVersionInfoWrapper.cs b/Source/Testably.Abstractions/FileSystem/FileVersionInfoWrapper.cs index 53a11bfe2..3217965a2 100644 --- a/Source/Testably.Abstractions/FileSystem/FileVersionInfoWrapper.cs +++ b/Source/Testably.Abstractions/FileSystem/FileVersionInfoWrapper.cs @@ -5,6 +5,9 @@ namespace Testably.Abstractions.FileSystem; internal sealed class FileVersionInfoWrapper : IFileVersionInfo { + /// + public IFileSystem FileSystem { get; } + private readonly FileVersionInfo _instance; private FileVersionInfoWrapper(FileVersionInfo fileSystemWatcher, @@ -48,9 +51,6 @@ public string FileName public int FilePrivatePart => _instance.FilePrivatePart; - /// - public IFileSystem FileSystem { get; } - /// public string? FileVersion => _instance.FileVersion; @@ -129,6 +129,10 @@ public string? SpecialBuild #endregion + /// + public override string ToString() + => _instance.ToString(); + [return: NotNullIfNotNull("instance")] internal static FileVersionInfoWrapper? FromFileVersionInfo( FileVersionInfo? instance, IFileSystem fileSystem) diff --git a/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions.Testing_net6.0.txt b/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions.Testing_net6.0.txt index a30b42d2c..e343dc9d3 100644 --- a/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions.Testing_net6.0.txt +++ b/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions.Testing_net6.0.txt @@ -112,6 +112,7 @@ namespace Testably.Abstractions.Testing public override string ToString() { } public Testably.Abstractions.Testing.MockFileSystem WithAccessControlStrategy(Testably.Abstractions.Testing.FileSystem.IAccessControlStrategy accessControlStrategy) { } public Testably.Abstractions.Testing.MockFileSystem WithDrive(string? drive, System.Action? driveCallback = null) { } + public Testably.Abstractions.Testing.MockFileSystem WithFileVersionInfo(string searchPattern, System.Action fileVersionInfoBuilder) { } public Testably.Abstractions.Testing.MockFileSystem WithSafeFileHandleStrategy(Testably.Abstractions.Testing.FileSystem.ISafeFileHandleStrategy safeFileHandleStrategy) { } public class MockFileSystemOptions { @@ -230,6 +231,28 @@ namespace Testably.Abstractions.Testing.Initializer public abstract Testably.Abstractions.Testing.Initializer.FileSystemInfoDescription this[string path] { get; } public string Name { get; } } + public sealed class FileVersionInfoBuilder + { + public FileVersionInfoBuilder() { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetComments(string? comments) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetCompanyName(string? companyName) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetFileDescription(string? fileDescription) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetFileVersion(string? fileVersion) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetInternalName(string? internalName) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetIsDebug(bool isDebug) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetIsPatched(bool isPatched) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetIsPreRelease(bool isPreRelease) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetIsPrivateBuild(bool isPrivateBuild) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetIsSpecialBuild(bool isSpecialBuild) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetLanguage(string? language) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetLegalCopyright(string? legalCopyright) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetLegalTrademarks(string? legalTrademarks) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetOriginalFilename(string? originalFilename) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetPrivateBuild(string? privateBuild) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetProductName(string? productName) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetProductVersion(string? productVersion) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetSpecialBuild(string? specialBuild) { } + } public interface IDirectoryCleaner : System.IDisposable { string BasePath { get; } diff --git a/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions.Testing_net7.0.txt b/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions.Testing_net7.0.txt index 31a2fa9a3..ce295f21c 100644 --- a/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions.Testing_net7.0.txt +++ b/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions.Testing_net7.0.txt @@ -112,6 +112,7 @@ namespace Testably.Abstractions.Testing public override string ToString() { } public Testably.Abstractions.Testing.MockFileSystem WithAccessControlStrategy(Testably.Abstractions.Testing.FileSystem.IAccessControlStrategy accessControlStrategy) { } public Testably.Abstractions.Testing.MockFileSystem WithDrive(string? drive, System.Action? driveCallback = null) { } + public Testably.Abstractions.Testing.MockFileSystem WithFileVersionInfo(string searchPattern, System.Action fileVersionInfoBuilder) { } public Testably.Abstractions.Testing.MockFileSystem WithSafeFileHandleStrategy(Testably.Abstractions.Testing.FileSystem.ISafeFileHandleStrategy safeFileHandleStrategy) { } public class MockFileSystemOptions { @@ -230,6 +231,28 @@ namespace Testably.Abstractions.Testing.Initializer public abstract Testably.Abstractions.Testing.Initializer.FileSystemInfoDescription this[string path] { get; } public string Name { get; } } + public sealed class FileVersionInfoBuilder + { + public FileVersionInfoBuilder() { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetComments(string? comments) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetCompanyName(string? companyName) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetFileDescription(string? fileDescription) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetFileVersion(string? fileVersion) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetInternalName(string? internalName) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetIsDebug(bool isDebug) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetIsPatched(bool isPatched) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetIsPreRelease(bool isPreRelease) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetIsPrivateBuild(bool isPrivateBuild) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetIsSpecialBuild(bool isSpecialBuild) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetLanguage(string? language) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetLegalCopyright(string? legalCopyright) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetLegalTrademarks(string? legalTrademarks) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetOriginalFilename(string? originalFilename) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetPrivateBuild(string? privateBuild) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetProductName(string? productName) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetProductVersion(string? productVersion) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetSpecialBuild(string? specialBuild) { } + } public interface IDirectoryCleaner : System.IDisposable { string BasePath { get; } diff --git a/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions.Testing_net8.0.txt b/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions.Testing_net8.0.txt index 81697dc82..267f07ba2 100644 --- a/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions.Testing_net8.0.txt +++ b/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions.Testing_net8.0.txt @@ -112,6 +112,7 @@ namespace Testably.Abstractions.Testing public override string ToString() { } public Testably.Abstractions.Testing.MockFileSystem WithAccessControlStrategy(Testably.Abstractions.Testing.FileSystem.IAccessControlStrategy accessControlStrategy) { } public Testably.Abstractions.Testing.MockFileSystem WithDrive(string? drive, System.Action? driveCallback = null) { } + public Testably.Abstractions.Testing.MockFileSystem WithFileVersionInfo(string searchPattern, System.Action fileVersionInfoBuilder) { } public Testably.Abstractions.Testing.MockFileSystem WithSafeFileHandleStrategy(Testably.Abstractions.Testing.FileSystem.ISafeFileHandleStrategy safeFileHandleStrategy) { } public class MockFileSystemOptions { @@ -230,6 +231,28 @@ namespace Testably.Abstractions.Testing.Initializer public abstract Testably.Abstractions.Testing.Initializer.FileSystemInfoDescription this[string path] { get; } public string Name { get; } } + public sealed class FileVersionInfoBuilder + { + public FileVersionInfoBuilder() { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetComments(string? comments) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetCompanyName(string? companyName) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetFileDescription(string? fileDescription) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetFileVersion(string? fileVersion) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetInternalName(string? internalName) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetIsDebug(bool isDebug) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetIsPatched(bool isPatched) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetIsPreRelease(bool isPreRelease) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetIsPrivateBuild(bool isPrivateBuild) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetIsSpecialBuild(bool isSpecialBuild) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetLanguage(string? language) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetLegalCopyright(string? legalCopyright) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetLegalTrademarks(string? legalTrademarks) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetOriginalFilename(string? originalFilename) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetPrivateBuild(string? privateBuild) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetProductName(string? productName) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetProductVersion(string? productVersion) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetSpecialBuild(string? specialBuild) { } + } public interface IDirectoryCleaner : System.IDisposable { string BasePath { get; } diff --git a/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions.Testing_netstandard2.0.txt b/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions.Testing_netstandard2.0.txt index 4d0e8139d..8b0a7a0a9 100644 --- a/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions.Testing_netstandard2.0.txt +++ b/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions.Testing_netstandard2.0.txt @@ -110,6 +110,7 @@ namespace Testably.Abstractions.Testing public override string ToString() { } public Testably.Abstractions.Testing.MockFileSystem WithAccessControlStrategy(Testably.Abstractions.Testing.FileSystem.IAccessControlStrategy accessControlStrategy) { } public Testably.Abstractions.Testing.MockFileSystem WithDrive(string? drive, System.Action? driveCallback = null) { } + public Testably.Abstractions.Testing.MockFileSystem WithFileVersionInfo(string searchPattern, System.Action fileVersionInfoBuilder) { } public Testably.Abstractions.Testing.MockFileSystem WithSafeFileHandleStrategy(Testably.Abstractions.Testing.FileSystem.ISafeFileHandleStrategy safeFileHandleStrategy) { } public class MockFileSystemOptions { @@ -227,6 +228,28 @@ namespace Testably.Abstractions.Testing.Initializer public abstract Testably.Abstractions.Testing.Initializer.FileSystemInfoDescription this[string path] { get; } public string Name { get; } } + public sealed class FileVersionInfoBuilder + { + public FileVersionInfoBuilder() { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetComments(string? comments) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetCompanyName(string? companyName) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetFileDescription(string? fileDescription) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetFileVersion(string? fileVersion) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetInternalName(string? internalName) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetIsDebug(bool isDebug) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetIsPatched(bool isPatched) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetIsPreRelease(bool isPreRelease) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetIsPrivateBuild(bool isPrivateBuild) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetIsSpecialBuild(bool isSpecialBuild) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetLanguage(string? language) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetLegalCopyright(string? legalCopyright) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetLegalTrademarks(string? legalTrademarks) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetOriginalFilename(string? originalFilename) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetPrivateBuild(string? privateBuild) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetProductName(string? productName) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetProductVersion(string? productVersion) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetSpecialBuild(string? specialBuild) { } + } public interface IDirectoryCleaner : System.IDisposable { string BasePath { get; } diff --git a/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions.Testing_netstandard2.1.txt b/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions.Testing_netstandard2.1.txt index f90b10c57..f04ec7373 100644 --- a/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions.Testing_netstandard2.1.txt +++ b/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions.Testing_netstandard2.1.txt @@ -110,6 +110,7 @@ namespace Testably.Abstractions.Testing public override string ToString() { } public Testably.Abstractions.Testing.MockFileSystem WithAccessControlStrategy(Testably.Abstractions.Testing.FileSystem.IAccessControlStrategy accessControlStrategy) { } public Testably.Abstractions.Testing.MockFileSystem WithDrive(string? drive, System.Action? driveCallback = null) { } + public Testably.Abstractions.Testing.MockFileSystem WithFileVersionInfo(string searchPattern, System.Action fileVersionInfoBuilder) { } public Testably.Abstractions.Testing.MockFileSystem WithSafeFileHandleStrategy(Testably.Abstractions.Testing.FileSystem.ISafeFileHandleStrategy safeFileHandleStrategy) { } public class MockFileSystemOptions { @@ -227,6 +228,28 @@ namespace Testably.Abstractions.Testing.Initializer public abstract Testably.Abstractions.Testing.Initializer.FileSystemInfoDescription this[string path] { get; } public string Name { get; } } + public sealed class FileVersionInfoBuilder + { + public FileVersionInfoBuilder() { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetComments(string? comments) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetCompanyName(string? companyName) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetFileDescription(string? fileDescription) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetFileVersion(string? fileVersion) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetInternalName(string? internalName) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetIsDebug(bool isDebug) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetIsPatched(bool isPatched) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetIsPreRelease(bool isPreRelease) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetIsPrivateBuild(bool isPrivateBuild) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetIsSpecialBuild(bool isSpecialBuild) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetLanguage(string? language) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetLegalCopyright(string? legalCopyright) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetLegalTrademarks(string? legalTrademarks) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetOriginalFilename(string? originalFilename) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetPrivateBuild(string? privateBuild) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetProductName(string? productName) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetProductVersion(string? productVersion) { } + public Testably.Abstractions.Testing.Initializer.FileVersionInfoBuilder SetSpecialBuild(string? specialBuild) { } + } public interface IDirectoryCleaner : System.IDisposable { string BasePath { get; } diff --git a/Tests/Testably.Abstractions.Testing.Tests/FileSystem/FileVersionInfoFactoryMockTests.cs b/Tests/Testably.Abstractions.Testing.Tests/FileSystem/FileVersionInfoFactoryMockTests.cs new file mode 100644 index 000000000..631d74305 --- /dev/null +++ b/Tests/Testably.Abstractions.Testing.Tests/FileSystem/FileVersionInfoFactoryMockTests.cs @@ -0,0 +1,34 @@ +using System.Diagnostics; + +namespace Testably.Abstractions.Testing.Tests.FileSystem; + +public sealed class FileVersionInfoFactoryMockTests +{ + [Theory] + [AutoData] + public void WhenRegistered_ShouldReturnFileVersionInfoWithRegisteredValues( + string comments) + { + MockFileSystem fileSystem = new(); + fileSystem.Initialize().WithFile("abc.foo"); + fileSystem.WithFileVersionInfo("*.foo", b => b.SetComments(comments)); + + IFileVersionInfo result = fileSystem.FileVersionInfo.GetVersionInfo("abc.foo"); + + result.Comments.Should().Be(comments); + } + + [Theory] + [AutoData] + public void WhenRegisteredUnderDifferentName_ShouldReturnDefaultValues( + string comments) + { + MockFileSystem fileSystem = new(); + fileSystem.Initialize().WithFile("abc.bar"); + fileSystem.WithFileVersionInfo("*.foo", b => b.SetComments(comments)); + + IFileVersionInfo result = fileSystem.FileVersionInfo.GetVersionInfo("abc.bar"); + + result.Comments.Should().BeNull(); + } +} diff --git a/Tests/Testably.Abstractions.Testing.Tests/FileSystemInitializer/FileVersionInfoBuilderTests.cs b/Tests/Testably.Abstractions.Testing.Tests/FileSystemInitializer/FileVersionInfoBuilderTests.cs new file mode 100644 index 000000000..62691bac3 --- /dev/null +++ b/Tests/Testably.Abstractions.Testing.Tests/FileSystemInitializer/FileVersionInfoBuilderTests.cs @@ -0,0 +1,428 @@ +namespace Testably.Abstractions.Testing.Tests.FileSystemInitializer; + +public class FileVersionInfoBuilderTests +{ + [Theory] + [AutoData] + public void WithComments_ShouldSetComments(string comments) + { + MockFileSystem fileSystem = new(); + fileSystem.File.WriteAllText("foo", ""); + fileSystem.WithFileVersionInfo("*", b => b.SetComments(comments)); + + IFileVersionInfo result = fileSystem.FileVersionInfo.GetVersionInfo("foo"); + + result.Comments.Should().Be(comments); + } + + [Theory] + [AutoData] + public void WithCompanyName_ShouldSetCompanyName(string? companyName) + { + MockFileSystem fileSystem = new(); + fileSystem.File.WriteAllText("foo", ""); + fileSystem.WithFileVersionInfo("*", b => b.SetCompanyName(companyName)); + + IFileVersionInfo result = fileSystem.FileVersionInfo.GetVersionInfo("foo"); + + result.CompanyName.Should().Be(companyName); + } + + [Theory] + [AutoData] + public void WithFileDescription_ShouldSetFileDescription(string? fileDescription) + { + MockFileSystem fileSystem = new(); + fileSystem.File.WriteAllText("foo", ""); + fileSystem.WithFileVersionInfo("*", b => b.SetFileDescription(fileDescription)); + + IFileVersionInfo result = fileSystem.FileVersionInfo.GetVersionInfo("foo"); + + result.FileDescription.Should().Be(fileDescription); + } + + [Theory] + [InlineData("1", 1, 0)] + [InlineData("0.1", 0, 1)] + [InlineData("1.2", 1, 2)] + [InlineData("1.2.3", 1, 2, 3)] + [InlineData("1.2.3.4", 1, 2, 3, 4)] + public void WithFileVersion_ShouldSetFileVersion( + string? fileVersion, + int fileMajorPart, int fileMinorPart, int fileBuildPart = 0, int filePrivatePart = 0) + { + MockFileSystem fileSystem = new(); + fileSystem.File.WriteAllText("foo", ""); + fileSystem.WithFileVersionInfo("*", b => b.SetFileVersion("9.8.7.6").SetFileVersion(fileVersion)); + + IFileVersionInfo result = fileSystem.FileVersionInfo.GetVersionInfo("foo"); + result.FileVersion.Should().Be(fileVersion); + result.FileMajorPart.Should().Be(fileMajorPart); + result.FileMinorPart.Should().Be(fileMinorPart); + result.FileBuildPart.Should().Be(fileBuildPart); + result.FilePrivatePart.Should().Be(filePrivatePart); + } + + [Theory] + [InlineData("1-foo", 1, 0)] + [InlineData("1+bar", 1, 0)] + [InlineData("1some-text", 1, 0)] + [InlineData("0.1-foo", 0, 1)] + [InlineData("0.1+bar", 0, 1)] + [InlineData("0.1some-text", 0, 1)] + [InlineData("1.2-foo", 1, 2)] + [InlineData("1.2+bar", 1, 2)] + [InlineData("1.2some-text", 1, 2)] + [InlineData("1.2.3-foo", 1, 2, 3)] + [InlineData("1.2.3+bar", 1, 2, 3)] + [InlineData("1.2.3some-text", 1, 2, 3)] + [InlineData("1.2.3.4-foo", 1, 2, 3, 4)] + [InlineData("1.2.3.4+bar", 1, 2, 3, 4)] + [InlineData("1.2.3.4some-text", 1, 2, 3, 4)] + public void WithFileVersion_WhenContainsPreReleaseInfo_ShouldIgnorePreReleaseInfo( + string? fileVersion, + int fileMajorPart, int fileMinorPart, int fileBuildPart = 0, int filePrivatePart = 0) + { + MockFileSystem fileSystem = new(); + fileSystem.File.WriteAllText("foo", ""); + fileSystem.WithFileVersionInfo("*", b => b.SetFileVersion(fileVersion)); + + IFileVersionInfo result = fileSystem.FileVersionInfo.GetVersionInfo("foo"); + result.FileVersion.Should().Be(fileVersion); + result.FileMajorPart.Should().Be(fileMajorPart); + result.FileMinorPart.Should().Be(fileMinorPart); + result.FileBuildPart.Should().Be(fileBuildPart); + result.FilePrivatePart.Should().Be(filePrivatePart); + } + + [Theory] + [InlineData("")] + [InlineData("-1")] + [InlineData("+1.2.3-bar")] + [InlineData("abc")] + public void WithFileVersion_WhenStringIsInvalid_ShouldNotSetFileVersionParts( + string? fileVersion) + { + MockFileSystem fileSystem = new(); + fileSystem.File.WriteAllText("foo", ""); + fileSystem.WithFileVersionInfo("*", b => b.SetFileVersion("1.2.3.4") + .SetFileVersion(fileVersion)); + + IFileVersionInfo result = fileSystem.FileVersionInfo.GetVersionInfo("foo"); + result.FileVersion.Should().Be(fileVersion); + result.FileMajorPart.Should().Be(0); + result.FileMinorPart.Should().Be(0); + result.FileBuildPart.Should().Be(0); + result.FilePrivatePart.Should().Be(0); + } + + [Theory] + [AutoData] + public void WithInternalName_ShouldSetInternalName(string? internalName) + { + MockFileSystem fileSystem = new(); + fileSystem.File.WriteAllText("foo", ""); + fileSystem.WithFileVersionInfo("*", b => b.SetInternalName(internalName)); + + IFileVersionInfo result = fileSystem.FileVersionInfo.GetVersionInfo("foo"); + + result.InternalName.Should().Be(internalName); + } + + [Theory] + [AutoData] + public void WithIsDebug_ShouldSetIsDebug(bool isDebug) + { + MockFileSystem fileSystem = new(); + fileSystem.File.WriteAllText("foo", ""); + fileSystem.WithFileVersionInfo("*", b => b.SetIsDebug(isDebug)); + + IFileVersionInfo result = fileSystem.FileVersionInfo.GetVersionInfo("foo"); + + result.IsDebug.Should().Be(isDebug); + } + + [Theory] + [AutoData] + public void WithIsPatched_ShouldSetIsPatched(bool isPatched) + { + MockFileSystem fileSystem = new(); + fileSystem.File.WriteAllText("foo", ""); + fileSystem.WithFileVersionInfo("*", b => b.SetIsPatched(isPatched)); + + IFileVersionInfo result = fileSystem.FileVersionInfo.GetVersionInfo("foo"); + + result.IsPatched.Should().Be(isPatched); + } + + [Theory] + [AutoData] + public void WithIsPreRelease_ShouldSetIsPreRelease(bool isPreRelease) + { + MockFileSystem fileSystem = new(); + fileSystem.File.WriteAllText("foo", ""); + fileSystem.WithFileVersionInfo("*", b => b.SetIsPreRelease(isPreRelease)); + + IFileVersionInfo result = fileSystem.FileVersionInfo.GetVersionInfo("foo"); + + result.IsPreRelease.Should().Be(isPreRelease); + } + + [Theory] + [AutoData] + public void WithIsPrivateBuild_ShouldSetIsPrivateBuild(bool isPrivateBuild) + { + MockFileSystem fileSystem = new(); + fileSystem.File.WriteAllText("foo", ""); + fileSystem.WithFileVersionInfo("*", b => b.SetIsPrivateBuild(isPrivateBuild)); + + IFileVersionInfo result = fileSystem.FileVersionInfo.GetVersionInfo("foo"); + + result.IsPrivateBuild.Should().Be(isPrivateBuild); + } + + [Theory] + [AutoData] + public void WithIsSpecialBuild_ShouldSetIsSpecialBuild(bool isSpecialBuild) + { + MockFileSystem fileSystem = new(); + fileSystem.File.WriteAllText("foo", ""); + fileSystem.WithFileVersionInfo("*", b => b.SetIsSpecialBuild(isSpecialBuild)); + + IFileVersionInfo result = fileSystem.FileVersionInfo.GetVersionInfo("foo"); + + result.IsSpecialBuild.Should().Be(isSpecialBuild); + } + + [Theory] + [AutoData] + public void WithLanguage_ShouldSetLanguage(string? language) + { + MockFileSystem fileSystem = new(); + fileSystem.File.WriteAllText("foo", ""); + fileSystem.WithFileVersionInfo("*", b => b.SetLanguage(language)); + + IFileVersionInfo result = fileSystem.FileVersionInfo.GetVersionInfo("foo"); + + result.Language.Should().Be(language); + } + + [Theory] + [AutoData] + public void WithLegalCopyright_ShouldSetLegalCopyright(string? legalCopyright) + { + MockFileSystem fileSystem = new(); + fileSystem.File.WriteAllText("foo", ""); + fileSystem.WithFileVersionInfo("*", b => b.SetLegalCopyright(legalCopyright)); + + IFileVersionInfo result = fileSystem.FileVersionInfo.GetVersionInfo("foo"); + + result.LegalCopyright.Should().Be(legalCopyright); + } + + [Theory] + [AutoData] + public void WithLegalTrademarks_ShouldSetLegalTrademarks(string? legalTrademarks) + { + MockFileSystem fileSystem = new(); + fileSystem.File.WriteAllText("foo", ""); + fileSystem.WithFileVersionInfo("*", b => b.SetLegalTrademarks(legalTrademarks)); + + IFileVersionInfo result = fileSystem.FileVersionInfo.GetVersionInfo("foo"); + + result.LegalTrademarks.Should().Be(legalTrademarks); + } + + [Theory] + [AutoData] + public void WithOriginalFilename_ShouldSetOriginalFilename(string? originalFilename) + { + MockFileSystem fileSystem = new(); + fileSystem.File.WriteAllText("foo", ""); + fileSystem.WithFileVersionInfo("*", b => b.SetOriginalFilename(originalFilename)); + + IFileVersionInfo result = fileSystem.FileVersionInfo.GetVersionInfo("foo"); + + result.OriginalFilename.Should().Be(originalFilename); + } + + [Theory] + [AutoData] + public void WithPrivateBuild_ShouldSetPrivateBuild(string? privateBuild) + { + MockFileSystem fileSystem = new(); + fileSystem.File.WriteAllText("foo", ""); + fileSystem.WithFileVersionInfo("*", b => b.SetPrivateBuild(privateBuild)); + + IFileVersionInfo result = fileSystem.FileVersionInfo.GetVersionInfo("foo"); + + result.PrivateBuild.Should().Be(privateBuild); + } + + [Theory] + [AutoData] + public void WithProductName_ShouldSetProductName(string? productName) + { + MockFileSystem fileSystem = new(); + fileSystem.File.WriteAllText("foo", ""); + fileSystem.WithFileVersionInfo("*", b => b.SetProductName(productName)); + + IFileVersionInfo result = fileSystem.FileVersionInfo.GetVersionInfo("foo"); + + result.ProductName.Should().Be(productName); + } + + [Theory] + [InlineData("1", 1, 0)] + [InlineData("0.1", 0, 1)] + [InlineData("1.2", 1, 2)] + [InlineData("1.2.3", 1, 2, 3)] + [InlineData("1.2.3.4", 1, 2, 3, 4)] + public void WithProductVersion_ShouldSetProductVersion( + string? productVersion, + int fileMajorPart, int fileMinorPart, int fileBuildPart = 0, int filePrivatePart = 0) + { + MockFileSystem fileSystem = new(); + fileSystem.File.WriteAllText("foo", ""); + fileSystem.WithFileVersionInfo("*", b => b.SetProductVersion("9.8.7.6").SetProductVersion(productVersion)); + + IFileVersionInfo result = fileSystem.FileVersionInfo.GetVersionInfo("foo"); + result.ProductVersion.Should().Be(productVersion); + result.ProductMajorPart.Should().Be(fileMajorPart); + result.ProductMinorPart.Should().Be(fileMinorPart); + result.ProductBuildPart.Should().Be(fileBuildPart); + result.ProductPrivatePart.Should().Be(filePrivatePart); + } + + [Theory] + [InlineData("1-foo", 1, 0)] + [InlineData("1+bar", 1, 0)] + [InlineData("1some-text", 1, 0)] + [InlineData("0.1-foo", 0, 1)] + [InlineData("0.1+bar", 0, 1)] + [InlineData("0.1some-text", 0, 1)] + [InlineData("1.2-foo", 1, 2)] + [InlineData("1.2+bar", 1, 2)] + [InlineData("1.2some-text", 1, 2)] + [InlineData("1.2.3-foo", 1, 2, 3)] + [InlineData("1.2.3+bar", 1, 2, 3)] + [InlineData("1.2.3some-text", 1, 2, 3)] + [InlineData("1.2.3.4-foo", 1, 2, 3, 4)] + [InlineData("1.2.3.4+bar", 1, 2, 3, 4)] + [InlineData("1.2.3.4some-text", 1, 2, 3, 4)] + public void WithProductVersion_WhenContainsPreReleaseInfo_ShouldIgnorePreReleaseInfo( + string? productVersion, + int fileMajorPart, int fileMinorPart, int fileBuildPart = 0, int filePrivatePart = 0) + { + MockFileSystem fileSystem = new(); + fileSystem.File.WriteAllText("foo", ""); + fileSystem.WithFileVersionInfo("*", b => b.SetProductVersion(productVersion)); + + IFileVersionInfo result = fileSystem.FileVersionInfo.GetVersionInfo("foo"); + result.ProductVersion.Should().Be(productVersion); + result.ProductMajorPart.Should().Be(fileMajorPart); + result.ProductMinorPart.Should().Be(fileMinorPart); + result.ProductBuildPart.Should().Be(fileBuildPart); + result.ProductPrivatePart.Should().Be(filePrivatePart); + } + + [Theory] + [InlineData("")] + [InlineData("-1")] + [InlineData("+1.2.3-bar")] + [InlineData("abc")] + public void WithProductVersion_WhenStringIsInvalid_ShouldNotSetProductVersionParts( + string? productVersion) + { + MockFileSystem fileSystem = new(); + fileSystem.File.WriteAllText("foo", ""); + fileSystem.WithFileVersionInfo("*", b => b.SetProductVersion("1.2.3.4") + .SetProductVersion(productVersion)); + + IFileVersionInfo result = fileSystem.FileVersionInfo.GetVersionInfo("foo"); + result.ProductVersion.Should().Be(productVersion); + result.ProductMajorPart.Should().Be(0); + result.ProductMinorPart.Should().Be(0); + result.ProductBuildPart.Should().Be(0); + result.ProductPrivatePart.Should().Be(0); + } + + [Theory] + [AutoData] + public void WithSpecialBuild_ShouldSetSpecialBuild(string? specialBuild) + { + MockFileSystem fileSystem = new(); + fileSystem.File.WriteAllText("foo", ""); + fileSystem.WithFileVersionInfo("*", b => b.SetSpecialBuild(specialBuild)); + + IFileVersionInfo result = fileSystem.FileVersionInfo.GetVersionInfo("foo"); + + result.SpecialBuild.Should().Be(specialBuild); + } + + [Theory] + [AutoData] + public void ShouldBePossibleToChainMethods( + string comments, + string companyName, + string fileDescription, + string internalName, + bool isDebug, + bool isPatched, + bool isPreRelease, + bool isPrivateBuild, + bool isSpecialBuild, + string language, + string legalCopyright, + string legalTrademarks, + string originalFilename, + string privateBuild, + string productName, + string specialBuild) + { + string fileVersion = "1.2.3.4-foo"; + string productVersion = "255.255.255.65432+bar"; + MockFileSystem fileSystem = new(); + fileSystem.File.WriteAllText("foo", ""); + fileSystem.WithFileVersionInfo("*", b => b + .SetComments(comments) + .SetCompanyName(companyName) + .SetFileDescription(fileDescription) + .SetFileVersion(fileVersion) + .SetInternalName(internalName) + .SetIsDebug(isDebug) + .SetIsPatched(isPatched) + .SetIsPreRelease(isPreRelease) + .SetIsPrivateBuild(isPrivateBuild) + .SetIsSpecialBuild(isSpecialBuild) + .SetLanguage(language) + .SetLegalCopyright(legalCopyright) + .SetLegalTrademarks(legalTrademarks) + .SetOriginalFilename(originalFilename) + .SetPrivateBuild(privateBuild) + .SetProductName(productName) + .SetProductVersion(productVersion) + .SetSpecialBuild(specialBuild) + .SetComments(comments)); + + IFileVersionInfo result = fileSystem.FileVersionInfo.GetVersionInfo("foo"); + + result.Comments.Should().Be(comments); + result.CompanyName.Should().Be(companyName); + result.FileDescription.Should().Be(fileDescription); + result.FileVersion.Should().Be(fileVersion); + result.InternalName.Should().Be(internalName); + result.IsDebug.Should().Be(isDebug); + result.IsPatched.Should().Be(isPatched); + result.IsPreRelease.Should().Be(isPreRelease); + result.IsSpecialBuild.Should().Be(isSpecialBuild); + result.Language.Should().Be(language); + result.LegalCopyright.Should().Be(legalCopyright); + result.LegalTrademarks.Should().Be(legalTrademarks); + result.OriginalFilename.Should().Be(originalFilename); + result.PrivateBuild.Should().Be(privateBuild); + result.ProductName.Should().Be(productName); + result.ProductVersion.Should().Be(productVersion); + result.SpecialBuild.Should().Be(specialBuild); + } +} diff --git a/Tests/Testably.Abstractions.Testing.Tests/Statistics/FileSystem/FileVersionInfoFactoryStatisticsTests.cs b/Tests/Testably.Abstractions.Testing.Tests/Statistics/FileSystem/FileVersionInfoFactoryStatisticsTests.cs index 02aff7bb0..73c5faba1 100644 --- a/Tests/Testably.Abstractions.Testing.Tests/Statistics/FileSystem/FileVersionInfoFactoryStatisticsTests.cs +++ b/Tests/Testably.Abstractions.Testing.Tests/Statistics/FileSystem/FileVersionInfoFactoryStatisticsTests.cs @@ -9,6 +9,7 @@ public void Method_GetVersionInfo_String_ShouldRegisterCall() { MockFileSystem sut = new(); string fileName = "foo"; + sut.Initialize().WithFile(fileName); sut.FileVersionInfo.GetVersionInfo(fileName); diff --git a/Tests/Testably.Abstractions.Testing.Tests/Statistics/FileSystem/FileVersionInfoStatisticsTests.cs b/Tests/Testably.Abstractions.Testing.Tests/Statistics/FileSystem/FileVersionInfoStatisticsTests.cs index 6491647ed..093775ac1 100644 --- a/Tests/Testably.Abstractions.Testing.Tests/Statistics/FileSystem/FileVersionInfoStatisticsTests.cs +++ b/Tests/Testably.Abstractions.Testing.Tests/Statistics/FileSystem/FileVersionInfoStatisticsTests.cs @@ -9,6 +9,7 @@ public class FileVersionInfoStatisticsTests public void Property_Comments_Get_ShouldRegisterPropertyAccess() { MockFileSystem sut = new(); + sut.Initialize().WithFile("foo"); _ = sut.FileVersionInfo.GetVersionInfo("foo").Comments; @@ -20,6 +21,7 @@ public void Property_Comments_Get_ShouldRegisterPropertyAccess() public void Property_CompanyName_Get_ShouldRegisterPropertyAccess() { MockFileSystem sut = new(); + sut.Initialize().WithFile("foo"); _ = sut.FileVersionInfo.GetVersionInfo("foo").CompanyName; @@ -31,6 +33,7 @@ public void Property_CompanyName_Get_ShouldRegisterPropertyAccess() public void Property_FileBuildPart_Get_ShouldRegisterPropertyAccess() { MockFileSystem sut = new(); + sut.Initialize().WithFile("foo"); _ = sut.FileVersionInfo.GetVersionInfo("foo").FileBuildPart; @@ -42,6 +45,7 @@ public void Property_FileBuildPart_Get_ShouldRegisterPropertyAccess() public void Property_FileDescription_Get_ShouldRegisterPropertyAccess() { MockFileSystem sut = new(); + sut.Initialize().WithFile("foo"); _ = sut.FileVersionInfo.GetVersionInfo("foo").FileDescription; @@ -53,6 +57,7 @@ public void Property_FileDescription_Get_ShouldRegisterPropertyAccess() public void Property_FileMajorPart_Get_ShouldRegisterPropertyAccess() { MockFileSystem sut = new(); + sut.Initialize().WithFile("foo"); _ = sut.FileVersionInfo.GetVersionInfo("foo").FileMajorPart; @@ -64,6 +69,7 @@ public void Property_FileMajorPart_Get_ShouldRegisterPropertyAccess() public void Property_FileMinorPart_Get_ShouldRegisterPropertyAccess() { MockFileSystem sut = new(); + sut.Initialize().WithFile("foo"); _ = sut.FileVersionInfo.GetVersionInfo("foo").FileMinorPart; @@ -75,6 +81,7 @@ public void Property_FileMinorPart_Get_ShouldRegisterPropertyAccess() public void Property_FileName_Get_ShouldRegisterPropertyAccess() { MockFileSystem sut = new(); + sut.Initialize().WithFile("foo"); _ = sut.FileVersionInfo.GetVersionInfo("foo").FileName; @@ -86,6 +93,7 @@ public void Property_FileName_Get_ShouldRegisterPropertyAccess() public void Property_FilePrivatePart_Get_ShouldRegisterPropertyAccess() { MockFileSystem sut = new(); + sut.Initialize().WithFile("foo"); _ = sut.FileVersionInfo.GetVersionInfo("foo").FilePrivatePart; @@ -97,6 +105,7 @@ public void Property_FilePrivatePart_Get_ShouldRegisterPropertyAccess() public void Property_FileVersion_Get_ShouldRegisterPropertyAccess() { MockFileSystem sut = new(); + sut.Initialize().WithFile("foo"); _ = sut.FileVersionInfo.GetVersionInfo("foo").FileVersion; @@ -108,6 +117,7 @@ public void Property_FileVersion_Get_ShouldRegisterPropertyAccess() public void Property_InternalName_Get_ShouldRegisterPropertyAccess() { MockFileSystem sut = new(); + sut.Initialize().WithFile("foo"); _ = sut.FileVersionInfo.GetVersionInfo("foo").InternalName; @@ -119,6 +129,7 @@ public void Property_InternalName_Get_ShouldRegisterPropertyAccess() public void Property_IsDebug_Get_ShouldRegisterPropertyAccess() { MockFileSystem sut = new(); + sut.Initialize().WithFile("foo"); _ = sut.FileVersionInfo.GetVersionInfo("foo").IsDebug; @@ -130,6 +141,7 @@ public void Property_IsDebug_Get_ShouldRegisterPropertyAccess() public void Property_IsPatched_Get_ShouldRegisterPropertyAccess() { MockFileSystem sut = new(); + sut.Initialize().WithFile("foo"); _ = sut.FileVersionInfo.GetVersionInfo("foo").IsPatched; @@ -141,6 +153,7 @@ public void Property_IsPatched_Get_ShouldRegisterPropertyAccess() public void Property_IsPreRelease_Get_ShouldRegisterPropertyAccess() { MockFileSystem sut = new(); + sut.Initialize().WithFile("foo"); _ = sut.FileVersionInfo.GetVersionInfo("foo").IsPreRelease; @@ -152,6 +165,7 @@ public void Property_IsPreRelease_Get_ShouldRegisterPropertyAccess() public void Property_IsPrivateBuild_Get_ShouldRegisterPropertyAccess() { MockFileSystem sut = new(); + sut.Initialize().WithFile("foo"); _ = sut.FileVersionInfo.GetVersionInfo("foo").IsPrivateBuild; @@ -163,6 +177,7 @@ public void Property_IsPrivateBuild_Get_ShouldRegisterPropertyAccess() public void Property_IsSpecialBuild_Get_ShouldRegisterPropertyAccess() { MockFileSystem sut = new(); + sut.Initialize().WithFile("foo"); _ = sut.FileVersionInfo.GetVersionInfo("foo").IsSpecialBuild; @@ -174,6 +189,7 @@ public void Property_IsSpecialBuild_Get_ShouldRegisterPropertyAccess() public void Property_Language_Get_ShouldRegisterPropertyAccess() { MockFileSystem sut = new(); + sut.Initialize().WithFile("foo"); _ = sut.FileVersionInfo.GetVersionInfo("foo").Language; @@ -185,6 +201,7 @@ public void Property_Language_Get_ShouldRegisterPropertyAccess() public void Property_LegalCopyright_Get_ShouldRegisterPropertyAccess() { MockFileSystem sut = new(); + sut.Initialize().WithFile("foo"); _ = sut.FileVersionInfo.GetVersionInfo("foo").LegalCopyright; @@ -196,6 +213,7 @@ public void Property_LegalCopyright_Get_ShouldRegisterPropertyAccess() public void Property_LegalTrademarks_Get_ShouldRegisterPropertyAccess() { MockFileSystem sut = new(); + sut.Initialize().WithFile("foo"); _ = sut.FileVersionInfo.GetVersionInfo("foo").LegalTrademarks; @@ -207,6 +225,7 @@ public void Property_LegalTrademarks_Get_ShouldRegisterPropertyAccess() public void Property_OriginalFilename_Get_ShouldRegisterPropertyAccess() { MockFileSystem sut = new(); + sut.Initialize().WithFile("foo"); _ = sut.FileVersionInfo.GetVersionInfo("foo").OriginalFilename; @@ -218,6 +237,7 @@ public void Property_OriginalFilename_Get_ShouldRegisterPropertyAccess() public void Property_PrivateBuild_Get_ShouldRegisterPropertyAccess() { MockFileSystem sut = new(); + sut.Initialize().WithFile("foo"); _ = sut.FileVersionInfo.GetVersionInfo("foo").PrivateBuild; @@ -229,6 +249,7 @@ public void Property_PrivateBuild_Get_ShouldRegisterPropertyAccess() public void Property_ProductBuildPart_Get_ShouldRegisterPropertyAccess() { MockFileSystem sut = new(); + sut.Initialize().WithFile("foo"); _ = sut.FileVersionInfo.GetVersionInfo("foo").ProductBuildPart; @@ -240,6 +261,7 @@ public void Property_ProductBuildPart_Get_ShouldRegisterPropertyAccess() public void Property_ProductMajorPart_Get_ShouldRegisterPropertyAccess() { MockFileSystem sut = new(); + sut.Initialize().WithFile("foo"); _ = sut.FileVersionInfo.GetVersionInfo("foo").ProductMajorPart; @@ -251,6 +273,7 @@ public void Property_ProductMajorPart_Get_ShouldRegisterPropertyAccess() public void Property_ProductMinorPart_Get_ShouldRegisterPropertyAccess() { MockFileSystem sut = new(); + sut.Initialize().WithFile("foo"); _ = sut.FileVersionInfo.GetVersionInfo("foo").ProductMinorPart; @@ -262,6 +285,7 @@ public void Property_ProductMinorPart_Get_ShouldRegisterPropertyAccess() public void Property_ProductName_Get_ShouldRegisterPropertyAccess() { MockFileSystem sut = new(); + sut.Initialize().WithFile("foo"); _ = sut.FileVersionInfo.GetVersionInfo("foo").ProductName; @@ -273,6 +297,7 @@ public void Property_ProductName_Get_ShouldRegisterPropertyAccess() public void Property_ProductPrivatePart_Get_ShouldRegisterPropertyAccess() { MockFileSystem sut = new(); + sut.Initialize().WithFile("foo"); _ = sut.FileVersionInfo.GetVersionInfo("foo").ProductPrivatePart; @@ -284,6 +309,7 @@ public void Property_ProductPrivatePart_Get_ShouldRegisterPropertyAccess() public void Property_ProductVersion_Get_ShouldRegisterPropertyAccess() { MockFileSystem sut = new(); + sut.Initialize().WithFile("foo"); _ = sut.FileVersionInfo.GetVersionInfo("foo").ProductVersion; @@ -295,6 +321,7 @@ public void Property_ProductVersion_Get_ShouldRegisterPropertyAccess() public void Property_SpecialBuild_Get_ShouldRegisterPropertyAccess() { MockFileSystem sut = new(); + sut.Initialize().WithFile("foo"); _ = sut.FileVersionInfo.GetVersionInfo("foo").SpecialBuild; diff --git a/Tests/Testably.Abstractions.Tests/FileSystem/FileVersionInfo/Tests.cs b/Tests/Testably.Abstractions.Tests/FileSystem/FileVersionInfo/Tests.cs new file mode 100644 index 000000000..0b2a4b13f --- /dev/null +++ b/Tests/Testably.Abstractions.Tests/FileSystem/FileVersionInfo/Tests.cs @@ -0,0 +1,20 @@ +namespace Testably.Abstractions.Tests.FileSystem.FileVersionInfo; + +// ReSharper disable once PartialTypeWithSinglePart +public abstract partial class Tests + : FileSystemTestBase + where TFileSystem : IFileSystem +{ + [SkippableTheory] + [AutoData] + public void ToString_ShouldReturnProvidedPath(string fileName) + { + FileSystem.File.WriteAllText(fileName, ""); + string fullPath = FileSystem.Path.GetFullPath(fileName); + IFileVersionInfo fileInfo = FileSystem.FileVersionInfo.GetVersionInfo(fullPath); + + string? result = fileInfo.ToString(); + + result.Should().Contain(fullPath); + } +} diff --git a/Tests/Testably.Abstractions.Tests/FileSystem/FileVersionInfoFactory/ExceptionTests.cs b/Tests/Testably.Abstractions.Tests/FileSystem/FileVersionInfoFactory/ExceptionTests.cs new file mode 100644 index 000000000..3be96c80e --- /dev/null +++ b/Tests/Testably.Abstractions.Tests/FileSystem/FileVersionInfoFactory/ExceptionTests.cs @@ -0,0 +1,99 @@ +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; + +namespace Testably.Abstractions.Tests.FileSystem.FileVersionInfoFactory; + +// ReSharper disable once PartialTypeWithSinglePart +public abstract partial class ExceptionTests + : FileSystemTestBase + where TFileSystem : IFileSystem +{ + [SkippableTheory] + [MemberData(nameof(GetFileVersionInfoFactoryCallbacks), parameters: "")] + public void Operations_WhenValueIsEmpty_ShouldThrowArgumentException( + Expression> callback, string paramName, + bool ignoreParamCheck) + { + Exception? exception = Record.Exception(() => + { + callback.Compile().Invoke(FileSystem.FileVersionInfo); + }); + + exception.Should().BeException( + hResult: -2147024809, + paramName: ignoreParamCheck || Test.IsNetFramework ? null : paramName, + because: + $"\n{callback}\n has empty parameter for '{paramName}' (ignored: {ignoreParamCheck})"); + } + + [SkippableTheory] + [MemberData(nameof(GetFileVersionInfoFactoryCallbacks), parameters: (string?)null)] + public void Operations_WhenValueIsNull_ShouldThrowArgumentNullException( + Expression> callback, string paramName, + bool ignoreParamCheck) + { + Exception? exception = Record.Exception(() => + { + callback.Compile().Invoke(FileSystem.FileVersionInfo); + }); + + exception.Should().BeException( + paramName: ignoreParamCheck ? null : paramName, + because: + $"\n{callback}\n has `null` parameter for '{paramName}' (ignored: {ignoreParamCheck})"); + } + + [SkippableTheory] + [MemberData(nameof(GetFileVersionInfoFactoryCallbacks), parameters: " ")] + public void Operations_WhenValueIsWhitespace_ShouldThrowArgumentException( + Expression> callback, string paramName, + bool ignoreParamCheck) + { + Skip.IfNot(Test.RunsOnWindows); + + Exception? exception = Record.Exception(() => + { + callback.Compile().Invoke(FileSystem.FileVersionInfo); + }); + + exception.Should().BeException( + hResult: -2147024809, + paramName: ignoreParamCheck || Test.IsNetFramework ? null : paramName, + because: + $"\n{callback}\n has whitespace parameter for '{paramName}' (ignored: {ignoreParamCheck})"); + } + + #region Helpers + + #pragma warning disable MA0018 + public static TheoryData>, string, bool> + GetFileVersionInfoFactoryCallbacks(string? path) + { + TheoryData>, string, bool> theoryData = new(); + foreach ((ExceptionTestHelper.TestTypes TestType, + string ParamName, + Expression> Callback) item in + GetFileVersionInfoFactoryCallbackTestParameters(path!) + .Where(item => item.TestType.HasFlag(path.ToTestType()))) + { + theoryData.Add( + item.Callback, + item.ParamName, + item.TestType.HasFlag(ExceptionTestHelper.TestTypes.IgnoreParamNameCheck)); + } + + return theoryData; + } + #pragma warning restore MA0018 + + private static IEnumerable<(ExceptionTestHelper.TestTypes TestType, string ParamName, + Expression> Callback)> + GetFileVersionInfoFactoryCallbackTestParameters(string value) + { + yield return (ExceptionTestHelper.TestTypes.IgnoreParamNameCheck | ExceptionTestHelper.TestTypes.All, "fileName", fileVersionInfoFactory + => fileVersionInfoFactory.GetVersionInfo(value)); + } + + #endregion +} diff --git a/Tests/Testably.Abstractions.Tests/FileSystem/FileVersionInfoFactory/Tests.cs b/Tests/Testably.Abstractions.Tests/FileSystem/FileVersionInfoFactory/Tests.cs new file mode 100644 index 000000000..0b6011fa5 --- /dev/null +++ b/Tests/Testably.Abstractions.Tests/FileSystem/FileVersionInfoFactory/Tests.cs @@ -0,0 +1,44 @@ +using System.IO; + +namespace Testably.Abstractions.Tests.FileSystem.FileVersionInfoFactory; + +// ReSharper disable once PartialTypeWithSinglePart +public abstract partial class Tests + : FileSystemTestBase + where TFileSystem : IFileSystem +{ + [SkippableTheory] + [AutoData] + public void GetVersionInfo_ArbitraryFile_ShouldHaveFileNameSet(string fileName) + { + string filePath = FileSystem.Path.GetFullPath(fileName); + FileSystem.File.WriteAllText(fileName, "foo"); + if (Test.IsNetFramework) + { + // On .NET Framework an absolute path is required + fileName = filePath; + } + + IFileVersionInfo result = FileSystem.FileVersionInfo.GetVersionInfo(fileName); + + result.FileName.Should().Be(filePath); + } + + [SkippableTheory] + [AutoData] + public void GetVersionInfo_MissingFile_ShouldThrowFileNotFoundException( + string path) + { + if (Test.IsNetFramework) + { + path = FileSystem.Path.GetFullPath(path); + } + + Exception? exception = Record.Exception(() => + FileSystem.FileVersionInfo.GetVersionInfo(path)); + + exception.Should().BeException( + FileSystem.Path.GetFullPath(path), + hResult: -2147024894); + } +}