From 595f37ebd10a428e60e876909dc9361a520072ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Wed, 20 May 2026 17:32:50 +0200 Subject: [PATCH 1/6] chore(deps): bump aweXpect.Testably to 0.15.0 Pulls in the new IFileInfo/IDirectoryInfo attribute, IDriveInfo, IFileVersionInfo, and ITimerMock expectations introduced in 0.15.0. --- Directory.Packages.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 773d53d0..a719b1f1 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -46,7 +46,7 @@ - + From 3e6dd9d22d36863c0fe40247a8d6ff566e95dc9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Wed, 20 May 2026 17:43:25 +0200 Subject: [PATCH 2/6] refactor(tests): use Timer.Executed().Within() in TimerMockTests Replaces SemaphoreSlim + Interlocked + Volatile.Read coordination in two DisableAutoAdvance tests with the new ITimerMock.Executed() assertion from aweXpect.Testably 0.15.0. Drops 25 lines of synchronisation plumbing while preserving the exact-count verification via the ExecutionCount property. ShouldNotBeAffectedByTimeChange and DisableAutoAdvance_ShouldStart... stay as-is - they need per-tick coordination or capture the callback timestamp, which the new API does not expose. --- .../TimeSystem/TimerMockTests.cs | 51 +++++-------------- 1 file changed, 13 insertions(+), 38 deletions(-) diff --git a/Tests/Testably.Abstractions.Testing.Tests/TimeSystem/TimerMockTests.cs b/Tests/Testably.Abstractions.Testing.Tests/TimeSystem/TimerMockTests.cs index 8eb1f1a6..3ad1e61d 100644 --- a/Tests/Testably.Abstractions.Testing.Tests/TimeSystem/TimerMockTests.cs +++ b/Tests/Testably.Abstractions.Testing.Tests/TimeSystem/TimerMockTests.cs @@ -1,4 +1,5 @@ using aweXpect.Chronology; +using aweXpect.Core; using System.Threading; using Testably.Abstractions.Testing.TimeSystem; using ITimer = Testably.Abstractions.TimeSystem.ITimer; @@ -51,62 +52,36 @@ public async Task Change_ValidPeriodValue_ShouldNotThrowException(int period) [Test] public async Task DisableAutoAdvance_ShouldExecuteTimerLimitedNumberOfTimes() { - int callbackCount = 0; MockTimeSystem timeSystem = new(o => o.DisableAutoAdvance()); - using CancellationTokenSource cts = CancellationTokenSource - .CreateLinkedTokenSource(TestContext.Current!.Execution.CancellationToken); - cts.CancelAfter(30.Seconds()); - CancellationToken token = cts.Token; - using SemaphoreSlim callbackExecuted = new(0); - using ITimer timer = timeSystem.Timer.New(_ => - { - // ReSharper disable once AccessToModifiedClosure - Interlocked.Increment(ref callbackCount); - // ReSharper disable once AccessToDisposedClosure - callbackExecuted.Release(); - }, null, 1.Seconds(), 2.Seconds()); + using ITimerMock timer = (ITimerMock)timeSystem.Timer.New( + _ => { }, null, 1.Seconds(), 2.Seconds()); - await Task.Delay(50.Milliseconds(), token); - await That(Volatile.Read(ref callbackCount)).IsEqualTo(0); + await That(timer).Executed().Never().Within(50.Milliseconds()); // Advance past dueTime (1s): should trigger first callback timeSystem.TimeProvider.AdvanceBy(2.Seconds()); - await callbackExecuted.WaitAsync(token); - await That(Volatile.Read(ref callbackCount)).IsEqualTo(1); + await That(timer).Executed().AtLeast(1.Times()).Within(10.Seconds()); + await That(timer.ExecutionCount).IsEqualTo(1L); // Advance past one period (2s): should trigger second callback - await Task.Delay(50.Milliseconds(), token); timeSystem.TimeProvider.AdvanceBy(2.Seconds()); - await callbackExecuted.WaitAsync(token); - await That(Volatile.Read(ref callbackCount)).IsEqualTo(2); + await That(timer).Executed().AtLeast(2.Times()).Within(10.Seconds()); + await That(timer.ExecutionCount).IsEqualTo(2L); // Advance past two periods (4s): should trigger two more callbacks - await Task.Delay(50.Milliseconds(), token); timeSystem.TimeProvider.AdvanceBy(4.Seconds()); - await callbackExecuted.WaitAsync(token); - await Task.Delay(50.Milliseconds(), token); - timeSystem.TimeProvider.AdvanceBy(0.Seconds()); - await callbackExecuted.WaitAsync(token); - await That(Volatile.Read(ref callbackCount)).IsEqualTo(4); + await That(timer).Executed().AtLeast(4.Times()).Within(10.Seconds()); + await That(timer.ExecutionCount).IsEqualTo(4L); } [Test] public async Task DisableAutoAdvance_ShouldNotExecuteTimerBeforeTimeElapsed() { - int callbackCount = 0; MockTimeSystem timeSystem = new(o => o.DisableAutoAdvance()); - using CancellationTokenSource cts = CancellationTokenSource - .CreateLinkedTokenSource(TestContext.Current!.Execution.CancellationToken); - cts.CancelAfter(30.Seconds()); - CancellationToken token = cts.Token; - using ITimer timer = timeSystem.Timer.New(_ => - { - // ReSharper disable once AccessToModifiedClosure - Interlocked.Increment(ref callbackCount); - }, null, 1.Seconds(), 2.Seconds()); + using ITimerMock timer = (ITimerMock)timeSystem.Timer.New( + _ => { }, null, 1.Seconds(), 2.Seconds()); - await Task.Delay(50.Milliseconds(), token); - await That(Volatile.Read(ref callbackCount)).IsEqualTo(0); + await That(timer).Executed().Never().Within(50.Milliseconds()); } [Test] From 983782110c6e363d7d30d0eec295973cd536b48c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Wed, 20 May 2026 17:48:52 +0200 Subject: [PATCH 3/6] refactor(tests): use HasAttribute/DoesNotHaveAttribute on file system info Replaces assertions of the form await That(sut.Attributes).HasFlag(FileAttributes.X) with the typed extension await That(sut).HasAttribute(FileAttributes.X) (and the negated variant) introduced for IFileInfo/IDirectoryInfo in aweXpect.Testably 0.15.0. The subject becomes the file/directory itself, yielding clearer failure messages. InMemoryContainerTests is intentionally left alone - its subject is IStorageContainer, which the new extensions do not target. --- .../FileSystem/DirectoryInfo/AttributesTests.cs | 2 +- .../FileSystem/FileInfo/AttributesTests.cs | 4 ++-- .../FileSystem/FileInfo/EncryptDecryptTests.cs | 4 ++-- .../FileSystem/FileInfo/Tests.cs | 10 +++++----- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Tests/Testably.Abstractions.Tests/FileSystem/DirectoryInfo/AttributesTests.cs b/Tests/Testably.Abstractions.Tests/FileSystem/DirectoryInfo/AttributesTests.cs index 09680527..ba8fe909 100644 --- a/Tests/Testably.Abstractions.Tests/FileSystem/DirectoryInfo/AttributesTests.cs +++ b/Tests/Testably.Abstractions.Tests/FileSystem/DirectoryInfo/AttributesTests.cs @@ -16,7 +16,7 @@ public async Task Attributes_ClearAllAttributes_ShouldRemainDirectory(string pat await That(FileSystem.Directory.Exists(path)).IsTrue(); await That(FileSystem.File.Exists(path)).IsFalse(); - await That(sut.Attributes).HasFlag(FileAttributes.Directory); + await That(sut).HasAttribute(FileAttributes.Directory); } [Test] diff --git a/Tests/Testably.Abstractions.Tests/FileSystem/FileInfo/AttributesTests.cs b/Tests/Testably.Abstractions.Tests/FileSystem/FileInfo/AttributesTests.cs index ede79e61..8601e452 100644 --- a/Tests/Testably.Abstractions.Tests/FileSystem/FileInfo/AttributesTests.cs +++ b/Tests/Testably.Abstractions.Tests/FileSystem/FileInfo/AttributesTests.cs @@ -14,7 +14,7 @@ public async Task Attributes_SetDirectoryAttribute_ShouldRemainFile(string path) sut.Attributes = FileAttributes.Directory; - await That(sut.Attributes).DoesNotHaveFlag(FileAttributes.Directory); + await That(sut).DoesNotHaveAttribute(FileAttributes.Directory); } [Test] @@ -24,6 +24,6 @@ public async Task Attributes_ShouldNotHaveDirectoryAttribute(string path) FileSystem.File.WriteAllText(path, "foo"); IFileInfo sut = FileSystem.FileInfo.New(path); - await That(sut.Attributes).DoesNotHaveFlag(FileAttributes.Directory); + await That(sut).DoesNotHaveAttribute(FileAttributes.Directory); } } diff --git a/Tests/Testably.Abstractions.Tests/FileSystem/FileInfo/EncryptDecryptTests.cs b/Tests/Testably.Abstractions.Tests/FileSystem/FileInfo/EncryptDecryptTests.cs index 4af750f0..04e285bb 100644 --- a/Tests/Testably.Abstractions.Tests/FileSystem/FileInfo/EncryptDecryptTests.cs +++ b/Tests/Testably.Abstractions.Tests/FileSystem/FileInfo/EncryptDecryptTests.cs @@ -54,9 +54,9 @@ public async Task Encrypt_Decrypt_ShouldChangeEncryptedFileAttribute( IFileInfo sut = FileSystem.FileInfo.New(path); sut.Encrypt(); - await That(sut.Attributes).HasFlag(FileAttributes.Encrypted); + await That(sut).HasAttribute(FileAttributes.Encrypted); sut.Decrypt(); - await That(sut.Attributes).DoesNotHaveFlag(FileAttributes.Encrypted); + await That(sut).DoesNotHaveAttribute(FileAttributes.Encrypted); } [Test] diff --git a/Tests/Testably.Abstractions.Tests/FileSystem/FileInfo/Tests.cs b/Tests/Testably.Abstractions.Tests/FileSystem/FileInfo/Tests.cs index f3e43263..a4b8e484 100644 --- a/Tests/Testably.Abstractions.Tests/FileSystem/FileInfo/Tests.cs +++ b/Tests/Testably.Abstractions.Tests/FileSystem/FileInfo/Tests.cs @@ -116,17 +116,17 @@ public async Task IsReadOnly_SetToTrue_ShouldAddReadOnlyAttribute(string path) fileInfo.IsReadOnly = true; await That(fileInfo.IsReadOnly).IsTrue(); - await That(fileInfo.Attributes).HasFlag(FileAttributes.ReadOnly); + await That(fileInfo).HasAttribute(FileAttributes.ReadOnly); fileInfo.IsReadOnly = true; await That(fileInfo.IsReadOnly).IsTrue(); - await That(fileInfo.Attributes).HasFlag(FileAttributes.ReadOnly); + await That(fileInfo).HasAttribute(FileAttributes.ReadOnly); fileInfo.IsReadOnly = false; await That(fileInfo.IsReadOnly).IsFalse(); - await That(fileInfo.Attributes).DoesNotHaveFlag(FileAttributes.ReadOnly); + await That(fileInfo).DoesNotHaveAttribute(FileAttributes.ReadOnly); } [Test] @@ -139,7 +139,7 @@ public async Task IsReadOnly_ShouldChangeWhenSettingReadOnlyAttribute(string pat fileInfo.Attributes = FileAttributes.ReadOnly | FileAttributes.Encrypted; await That(fileInfo.IsReadOnly).IsTrue(); - await That(fileInfo.Attributes).HasFlag(FileAttributes.ReadOnly); + await That(fileInfo).HasAttribute(FileAttributes.ReadOnly); } [Test] @@ -150,7 +150,7 @@ public async Task IsReadOnly_ShouldInitializeToReadOnlyAttribute(string path) IFileInfo fileInfo = FileSystem.FileInfo.New(path); await That(fileInfo.IsReadOnly).IsFalse(); - await That(fileInfo.Attributes).DoesNotHaveFlag(FileAttributes.ReadOnly); + await That(fileInfo).DoesNotHaveAttribute(FileAttributes.ReadOnly); } [Test] From e310e7c19dfd688cb1f0afe1a80c6501f5877b78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Wed, 20 May 2026 17:57:08 +0200 Subject: [PATCH 4/6] refactor(tests): use IDriveInfo expectations from aweXpect.Testably Replaces property-then-IsEqualTo patterns with the typed IDriveInfo extensions introduced in 0.15.0: - That(drive.AvailableFreeSpace).IsEqualTo(x) -> That(drive).HasAvailableFreeSpace(x) - That(drive.TotalSize).IsEqualTo(x) -> That(drive).HasTotalSize(x) - That(drive.TotalFreeSpace).IsEqualTo(x) -> That(drive).HasTotalFreeSpace(x) - That(drive.VolumeLabel).IsEqualTo(x) -> That(drive).HasVolumeLabel(x) - That(drive.DriveFormat).IsEqualTo(x) -> That(drive).HasDriveFormat(x) - That(drive.DriveType).IsEqualTo(x) -> That(drive).HasDriveType(x) - That(drive.Name).IsEqualTo(x) -> That(drive).HasName(x) - That(drive.IsReady).IsTrue() -> That(drive).IsReady() Assertions that the new API does not cover (IsGreaterThan, IsNotEmpty, IsNotNull, IsNotNullOrEmpty, IsEqualTo with a runtime bool) are left unchanged. --- .../FileSystem/DriveInfoMockTests.cs | 26 +++++++++---------- .../MockFileSystemTests.cs | 18 ++++++------- .../FileSystem/DriveInfo/Tests.cs | 2 +- .../FileSystem/DriveInfoFactory/Tests.cs | 4 +-- 4 files changed, 25 insertions(+), 25 deletions(-) diff --git a/Tests/Testably.Abstractions.Testing.Tests/FileSystem/DriveInfoMockTests.cs b/Tests/Testably.Abstractions.Testing.Tests/FileSystem/DriveInfoMockTests.cs index dd1c8c96..59e6d092 100644 --- a/Tests/Testably.Abstractions.Testing.Tests/FileSystem/DriveInfoMockTests.cs +++ b/Tests/Testably.Abstractions.Testing.Tests/FileSystem/DriveInfoMockTests.cs @@ -21,7 +21,7 @@ public async Task AvailableFreeSpace_CannotGetNegative(long size) FileSystem.WithDrive(d => d.ChangeUsedBytes(-1)); - await That(drive.AvailableFreeSpace).IsEqualTo(size); + await That(drive).HasAvailableFreeSpace(size); } [Test] @@ -38,7 +38,7 @@ void Act() IDriveInfo drive = FileSystem.GetDefaultDrive(); await That(Act).ThrowsExactly().WithMessage($"*'{drive.Name}'*").AsWildcard(); - await That(drive.AvailableFreeSpace).IsEqualTo(fileSize - 1); + await That(drive).HasAvailableFreeSpace(fileSize - 1); } [Test] @@ -54,10 +54,10 @@ public async Task AvailableFreeSpace_ShouldBeChangedWhenAppendingToAFile( IDriveInfo drive = FileSystem.GetDefaultDrive(); FileSystem.File.WriteAllText(path, fileContent1, encoding); - await That(drive.AvailableFreeSpace).IsEqualTo(expectedRemainingBytes + fileSize2); + await That(drive).HasAvailableFreeSpace(expectedRemainingBytes + fileSize2); FileSystem.File.AppendAllText(path, fileContent2, encoding); - await That(drive.AvailableFreeSpace).IsEqualTo(expectedRemainingBytes); + await That(drive).HasAvailableFreeSpace(expectedRemainingBytes); } [Test] @@ -78,7 +78,7 @@ public async Task AvailableFreeSpace_ShouldBeChangedWhenWorkingWithStreams( stream.SetLength(stream.Length - reduceLength); } - await That(drive.AvailableFreeSpace).IsEqualTo(previousFreeSpace + reduceLength); + await That(drive).HasAvailableFreeSpace(previousFreeSpace + reduceLength); } [Test] @@ -94,7 +94,7 @@ public async Task AvailableFreeSpace_ShouldBeReducedByWritingToFile( IDriveInfo drive = FileSystem.GetDefaultDrive(); - await That(drive.AvailableFreeSpace).IsEqualTo(0); + await That(drive).HasAvailableFreeSpace(0); } [Test] @@ -111,7 +111,7 @@ public async Task AvailableFreeSpace_ShouldBeReleasedWhenDeletingAFile( IDriveInfo drive = FileSystem.GetDefaultDrive(); - await That(drive.AvailableFreeSpace).IsEqualTo(fileSize); + await That(drive).HasAvailableFreeSpace(fileSize); } [Test] @@ -122,7 +122,7 @@ public async Task AvailableFreeSpace_ShouldBeSetTotalSize(long size) IDriveInfo drive = FileSystem.GetDefaultDrive(); - await That(drive.AvailableFreeSpace).IsEqualTo(size); + await That(drive).HasAvailableFreeSpace(size); } [Test] @@ -220,7 +220,7 @@ public async Task SetDriveFormat_Default_ShouldBeNTFS() FileSystem.WithDrive(d => d.SetDriveFormat()); IDriveInfo drive = FileSystem.GetDefaultDrive(); - await That(drive.DriveFormat).IsEqualTo("NTFS"); + await That(drive).HasDriveFormat("NTFS"); } [Test] @@ -230,7 +230,7 @@ public async Task SetDriveFormat_ShouldChangeDriveFormat(string driveFormat) FileSystem.WithDrive(d => d.SetDriveFormat(driveFormat)); IDriveInfo drive = FileSystem.GetDefaultDrive(); - await That(drive.DriveFormat).IsEqualTo(driveFormat); + await That(drive).HasDriveFormat(driveFormat); } [Test] @@ -239,7 +239,7 @@ public async Task SetDriveType_Default_ShouldBeFixed() FileSystem.WithDrive(d => d.SetDriveType()); IDriveInfo drive = FileSystem.GetDefaultDrive(); - await That(drive.DriveType).IsEqualTo(DriveType.Fixed); + await That(drive).HasDriveType(DriveType.Fixed); } [Test] @@ -249,7 +249,7 @@ public async Task SetDriveType_ShouldChangeDriveType(DriveType driveType) FileSystem.WithDrive(d => d.SetDriveType(driveType)); IDriveInfo drive = FileSystem.GetDefaultDrive(); - await That(drive.DriveType).IsEqualTo(driveType); + await That(drive).HasDriveType(driveType); } [Test] @@ -270,6 +270,6 @@ public async Task SetTotalSize_Default_ShouldBe1Gigabyte() IDriveInfo drive = FileSystem.GetDefaultDrive(); - await That(drive.AvailableFreeSpace).IsEqualTo(1024 * 1024 * 1024); + await That(drive).HasAvailableFreeSpace(1024 * 1024 * 1024); } } diff --git a/Tests/Testably.Abstractions.Testing.Tests/MockFileSystemTests.cs b/Tests/Testably.Abstractions.Testing.Tests/MockFileSystemTests.cs index f8294fce..8ae9c281 100644 --- a/Tests/Testably.Abstractions.Testing.Tests/MockFileSystemTests.cs +++ b/Tests/Testably.Abstractions.Testing.Tests/MockFileSystemTests.cs @@ -84,10 +84,10 @@ public async Task FileSystemMock_ShouldBeInitializedWithADefaultDrive() IDriveInfo drive = sut.GetDefaultDrive(); await That(drives).IsNotEmpty(); - await That(drive.Name).IsEqualTo(expectedDriveName); + await That(drive).HasName(expectedDriveName); await That(drive.AvailableFreeSpace).IsGreaterThan(0); - await That(drive.DriveFormat).IsEqualTo(DriveInfoMock.DefaultDriveFormat); - await That(drive.DriveType).IsEqualTo(DriveInfoMock.DefaultDriveType); + await That(drive).HasDriveFormat(DriveInfoMock.DefaultDriveFormat); + await That(drive).HasDriveType(DriveInfoMock.DefaultDriveType); await That(drive.VolumeLabel).IsNotNullOrEmpty(); } @@ -188,11 +188,11 @@ public async Task WithDrive_Duplicate_ShouldUpdateExistingDrive(string driveName await That(sut.DriveInfo.GetDrives().Length).IsEqualTo(2); IDriveInfo drive = sut.DriveInfo.GetDrives() .Single(x => string.Equals(x.Name, driveName, StringComparison.Ordinal)); - await That(drive.TotalSize).IsEqualTo(100); + await That(drive).HasTotalSize(100); sut.WithDrive(driveName, d => d.SetTotalSize(200)); await That(sut.DriveInfo.GetDrives().Length).IsEqualTo(2); - await That(drive.TotalSize).IsEqualTo(200); + await That(drive).HasTotalSize(200); } [Test] @@ -266,9 +266,9 @@ public async Task WithDrive_WithCallback_ShouldUpdateDrive(long totalSize) IDriveInfo drive = sut.GetDefaultDrive(); - await That(drive.TotalSize).IsEqualTo(totalSize); - await That(drive.TotalFreeSpace).IsEqualTo(totalSize); - await That(drive.AvailableFreeSpace).IsEqualTo(totalSize); + await That(drive).HasTotalSize(totalSize); + await That(drive).HasTotalFreeSpace(totalSize); + await That(drive).HasAvailableFreeSpace(totalSize); } #if NET6_0_OR_GREATER @@ -368,7 +368,7 @@ public async Task WithUncDrive_WriteBytes_ShouldReduceAvailableFreeSpace( sut.File.WriteAllBytes(Path.Combine(uncDrive, path), bytes); - await That(drive.AvailableFreeSpace).IsEqualTo(previousFreeSpace - bytes.Length); + await That(drive).HasAvailableFreeSpace(previousFreeSpace - bytes.Length); } #if FEATURE_FILESYSTEM_UNIXFILEMODE diff --git a/Tests/Testably.Abstractions.Tests/FileSystem/DriveInfo/Tests.cs b/Tests/Testably.Abstractions.Tests/FileSystem/DriveInfo/Tests.cs index 649597fa..a56bad0e 100644 --- a/Tests/Testably.Abstractions.Tests/FileSystem/DriveInfo/Tests.cs +++ b/Tests/Testably.Abstractions.Tests/FileSystem/DriveInfo/Tests.cs @@ -35,7 +35,7 @@ void Act() if (Test.RunsOnWindows) { await That(Act).DoesNotThrow(); - await That(result.VolumeLabel).IsEqualTo("TEST"); + await That(result).HasVolumeLabel("TEST"); } else { diff --git a/Tests/Testably.Abstractions.Tests/FileSystem/DriveInfoFactory/Tests.cs b/Tests/Testably.Abstractions.Tests/FileSystem/DriveInfoFactory/Tests.cs index dfeff104..df5b476c 100644 --- a/Tests/Testably.Abstractions.Tests/FileSystem/DriveInfoFactory/Tests.cs +++ b/Tests/Testably.Abstractions.Tests/FileSystem/DriveInfoFactory/Tests.cs @@ -67,8 +67,8 @@ public async Task New_DefaultDrive_ShouldBeFixed() await That(result.AvailableFreeSpace).IsGreaterThan(0); await That(result.DriveFormat).IsNotNull(); - await That(result.DriveType).IsEqualTo(DriveType.Fixed); - await That(result.IsReady).IsTrue(); + await That(result).HasDriveType(DriveType.Fixed); + await That(result).IsReady(); await That(result.RootDirectory.FullName).IsEqualTo(FileTestHelper.RootDrive(Test)); await That(result.TotalFreeSpace).IsGreaterThan(0); await That(result.TotalSize).IsGreaterThan(0); From ed39cfd417c9858380d2cf5a1b9e551175ffef15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Wed, 20 May 2026 18:00:55 +0200 Subject: [PATCH 5/6] refactor(tests): use IFileVersionInfo expectations from aweXpect.Testably Replaces property-then-IsEqualTo patterns with typed extensions added to IFileVersionInfo in 0.15.0: - HasCompanyName, HasFileDescription, HasFileVersion, HasLanguage, HasOriginalFilename, HasProductName, HasProductVersion Properties without dedicated extensions (Comments, InternalName, LegalCopyright, LegalTrademarks, PrivateBuild, SpecialBuild, IsDebug/IsPatched/IsPreRelease/IsPrivateBuild/IsSpecialBuild, FileMajor/Minor/Build/PrivatePart, ProductMajor/Minor/Build/PrivatePart) keep the original IsEqualTo form. --- .../FileVersionInfoBuilderTests.cs | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/Tests/Testably.Abstractions.Testing.Tests/FileSystemInitializer/FileVersionInfoBuilderTests.cs b/Tests/Testably.Abstractions.Testing.Tests/FileSystemInitializer/FileVersionInfoBuilderTests.cs index cdfc9f15..88066f62 100644 --- a/Tests/Testably.Abstractions.Testing.Tests/FileSystemInitializer/FileVersionInfoBuilderTests.cs +++ b/Tests/Testably.Abstractions.Testing.Tests/FileSystemInitializer/FileVersionInfoBuilderTests.cs @@ -50,21 +50,21 @@ public async Task ShouldBePossibleToChainMethods( IFileVersionInfo result = fileSystem.FileVersionInfo.GetVersionInfo("foo"); await That(result.Comments).IsEqualTo(comments); - await That(result.CompanyName).IsEqualTo(companyName); - await That(result.FileDescription).IsEqualTo(fileDescription); - await That(result.FileVersion).IsEqualTo(fileVersion); + await That(result).HasCompanyName(companyName); + await That(result).HasFileDescription(fileDescription); + await That(result).HasFileVersion(fileVersion); await That(result.InternalName).IsEqualTo(internalName); await That(result.IsDebug).IsEqualTo(isDebug); await That(result.IsPatched).IsEqualTo(isPatched); await That(result.IsPreRelease).IsEqualTo(isPreRelease); await That(result.IsSpecialBuild).IsEqualTo(isSpecialBuild); - await That(result.Language).IsEqualTo(language); + await That(result).HasLanguage(language); await That(result.LegalCopyright).IsEqualTo(legalCopyright); await That(result.LegalTrademarks).IsEqualTo(legalTrademarks); - await That(result.OriginalFilename).IsEqualTo(originalFilename); + await That(result).HasOriginalFilename(originalFilename); await That(result.PrivateBuild).IsEqualTo(privateBuild); - await That(result.ProductName).IsEqualTo(productName); - await That(result.ProductVersion).IsEqualTo(productVersion); + await That(result).HasProductName(productName); + await That(result).HasProductVersion(productVersion); await That(result.SpecialBuild).IsEqualTo(specialBuild); } @@ -91,7 +91,7 @@ public async Task WithCompanyName_ShouldSetCompanyName(string? companyName) IFileVersionInfo result = fileSystem.FileVersionInfo.GetVersionInfo("foo"); - await That(result.CompanyName).IsEqualTo(companyName); + await That(result).HasCompanyName(companyName); } [Test] @@ -104,7 +104,7 @@ public async Task WithFileDescription_ShouldSetFileDescription(string? fileDescr IFileVersionInfo result = fileSystem.FileVersionInfo.GetVersionInfo("foo"); - await That(result.FileDescription).IsEqualTo(fileDescription); + await That(result).HasFileDescription(fileDescription); } [Test] @@ -123,7 +123,7 @@ public async Task WithFileVersion_ShouldSetFileVersion( b => b.SetFileVersion("9.8.7.6").SetFileVersion(fileVersion)); IFileVersionInfo result = fileSystem.FileVersionInfo.GetVersionInfo("foo"); - await That(result.FileVersion).IsEqualTo(fileVersion); + await That(result).HasFileVersion(fileVersion); await That(result.FileMajorPart).IsEqualTo(fileMajorPart); await That(result.FileMinorPart).IsEqualTo(fileMinorPart); await That(result.FileBuildPart).IsEqualTo(fileBuildPart); @@ -155,7 +155,7 @@ public async Task WithFileVersion_WhenContainsPreReleaseInfo_ShouldIgnorePreRele fileSystem.WithFileVersionInfo("*", b => b.SetFileVersion(fileVersion)); IFileVersionInfo result = fileSystem.FileVersionInfo.GetVersionInfo("foo"); - await That(result.FileVersion).IsEqualTo(fileVersion); + await That(result).HasFileVersion(fileVersion); await That(result.FileMajorPart).IsEqualTo(fileMajorPart); await That(result.FileMinorPart).IsEqualTo(fileMinorPart); await That(result.FileBuildPart).IsEqualTo(fileBuildPart); @@ -176,7 +176,7 @@ public async Task WithFileVersion_WhenStringIsInvalid_ShouldNotSetFileVersionPar .SetFileVersion(fileVersion)); IFileVersionInfo result = fileSystem.FileVersionInfo.GetVersionInfo("foo"); - await That(result.FileVersion).IsEqualTo(fileVersion); + await That(result).HasFileVersion(fileVersion); await That(result.FileMajorPart).IsEqualTo(0); await That(result.FileMinorPart).IsEqualTo(0); await That(result.FileBuildPart).IsEqualTo(0); @@ -271,7 +271,7 @@ public async Task WithLanguage_ShouldSetLanguage(string? language) IFileVersionInfo result = fileSystem.FileVersionInfo.GetVersionInfo("foo"); - await That(result.Language).IsEqualTo(language); + await That(result).HasLanguage(language); } [Test] @@ -310,7 +310,7 @@ public async Task WithOriginalFilename_ShouldSetOriginalFilename(string? origina IFileVersionInfo result = fileSystem.FileVersionInfo.GetVersionInfo("foo"); - await That(result.OriginalFilename).IsEqualTo(originalFilename); + await That(result).HasOriginalFilename(originalFilename); } [Test] @@ -336,7 +336,7 @@ public async Task WithProductName_ShouldSetProductName(string? productName) IFileVersionInfo result = fileSystem.FileVersionInfo.GetVersionInfo("foo"); - await That(result.ProductName).IsEqualTo(productName); + await That(result).HasProductName(productName); } [Test] @@ -355,7 +355,7 @@ public async Task WithProductVersion_ShouldSetProductVersion( b => b.SetProductVersion("9.8.7.6").SetProductVersion(productVersion)); IFileVersionInfo result = fileSystem.FileVersionInfo.GetVersionInfo("foo"); - await That(result.ProductVersion).IsEqualTo(productVersion); + await That(result).HasProductVersion(productVersion); await That(result.ProductMajorPart).IsEqualTo(fileMajorPart); await That(result.ProductMinorPart).IsEqualTo(fileMinorPart); await That(result.ProductBuildPart).IsEqualTo(fileBuildPart); @@ -387,7 +387,7 @@ public async Task WithProductVersion_WhenContainsPreReleaseInfo_ShouldIgnorePreR fileSystem.WithFileVersionInfo("*", b => b.SetProductVersion(productVersion)); IFileVersionInfo result = fileSystem.FileVersionInfo.GetVersionInfo("foo"); - await That(result.ProductVersion).IsEqualTo(productVersion); + await That(result).HasProductVersion(productVersion); await That(result.ProductMajorPart).IsEqualTo(fileMajorPart); await That(result.ProductMinorPart).IsEqualTo(fileMinorPart); await That(result.ProductBuildPart).IsEqualTo(fileBuildPart); @@ -408,7 +408,7 @@ public async Task WithProductVersion_WhenStringIsInvalid_ShouldNotSetProductVers .SetProductVersion(productVersion)); IFileVersionInfo result = fileSystem.FileVersionInfo.GetVersionInfo("foo"); - await That(result.ProductVersion).IsEqualTo(productVersion); + await That(result).HasProductVersion(productVersion); await That(result.ProductMajorPart).IsEqualTo(0); await That(result.ProductMinorPart).IsEqualTo(0); await That(result.ProductBuildPart).IsEqualTo(0); From 456f4180784ed7747b5405c02957210f2054cd84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Wed, 20 May 2026 18:04:47 +0200 Subject: [PATCH 6/6] refactor(tests): use IFileSystem.HasDrive in MockFileSystemTests Replaces await That(drives).HasSingle() .Matching(d => string.Equals(d.Name, driveName, StringComparison.Ordinal)); with await That(sut).HasDrive(driveName); introduced for IFileSystem in 0.15.0. Drive names are unique within a file system, so HasDrive's "at least one drive with this name" is equivalent to the prior "exactly one matching" check. The accompanying length assertion is kept to preserve the test's count semantics. Tests intentionally targeting an exact ordinal name form (e.g. WithDrive_ShouldHavePathSeparatorSuffix, which verifies the trailing separator) are left alone since HasDrive normalizes trailing slashes. --- .../MockFileSystemTests.cs | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/Tests/Testably.Abstractions.Testing.Tests/MockFileSystemTests.cs b/Tests/Testably.Abstractions.Testing.Tests/MockFileSystemTests.cs index 8ae9c281..f02fa867 100644 --- a/Tests/Testably.Abstractions.Testing.Tests/MockFileSystemTests.cs +++ b/Tests/Testably.Abstractions.Testing.Tests/MockFileSystemTests.cs @@ -202,11 +202,8 @@ public async Task WithDrive_ExistingName_ShouldUpdateDrive() string driveName = "".PrefixRoot(sut); sut.WithDrive(driveName); - IDriveInfo[] drives = sut.DriveInfo.GetDrives(); - - await That(drives.Length).IsGreaterThanOrEqualTo(1); - await That(drives).HasSingle() - .Matching(d => string.Equals(d.Name, driveName, StringComparison.Ordinal)); + await That(sut.DriveInfo.GetDrives().Length).IsGreaterThanOrEqualTo(1); + await That(sut).HasDrive(driveName); } [Test] @@ -218,11 +215,8 @@ public async Task WithDrive_NewName_ShouldCreateNewDrives(string driveName) MockFileSystem sut = new(); sut.WithDrive(driveName); - IDriveInfo[] drives = sut.DriveInfo.GetDrives(); - - await That(drives.Length).IsEqualTo(2); - await That(drives).HasSingle() - .Matching(d => string.Equals(d.Name, driveName, StringComparison.Ordinal)); + await That(sut.DriveInfo.GetDrives().Length).IsEqualTo(2); + await That(sut).HasDrive(driveName); } [Test]