From c5e4c1ee5f10bcf5a192183ea1843e3d5fafadc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Sun, 30 Jul 2023 07:32:10 +0200 Subject: [PATCH 1/3] Fix sonar issue --- .../MockFileSystem.cs | 10 +-- .../Storage/InMemoryStorage.cs | 75 +++++++++++-------- 2 files changed, 47 insertions(+), 38 deletions(-) diff --git a/Source/Testably.Abstractions.Testing/MockFileSystem.cs b/Source/Testably.Abstractions.Testing/MockFileSystem.cs index 94992e864..d07cb196d 100644 --- a/Source/Testably.Abstractions.Testing/MockFileSystem.cs +++ b/Source/Testably.Abstractions.Testing/MockFileSystem.cs @@ -1,7 +1,6 @@ using Microsoft.Win32.SafeHandles; using System; using System.Collections.Generic; -using System.Linq; using Testably.Abstractions.Testing.FileSystem; using Testably.Abstractions.Testing.Storage; @@ -45,11 +44,8 @@ public sealed class MockFileSystem : IFileSystem /// /// The registered containers in the in-Memory . /// - internal IReadOnlyList Containers - => _storage.Containers - .OrderBy(x => x.Key.FullPath) - .Select(x => x.Value) - .ToList(); + internal IReadOnlyList StorageContainers + => _storage.GetContainers(); private readonly DirectoryMock _directoryMock; private readonly FileMock _fileMock; @@ -123,7 +119,7 @@ public IPath Path /// public override string ToString() - => $"MockFileSystem (directories: {_storage.Containers.Count(x => x.Value.Type == FileSystemTypes.Directory)}, files: {_storage.Containers.Count(x => x.Value.Type == FileSystemTypes.File)})"; + => $"MockFileSystem ({_storage})"; /// /// Implements a custom access control (ACL) mechanism. diff --git a/Source/Testably.Abstractions.Testing/Storage/InMemoryStorage.cs b/Source/Testably.Abstractions.Testing/Storage/InMemoryStorage.cs index 4ed2a7119..e331d5e42 100644 --- a/Source/Testably.Abstractions.Testing/Storage/InMemoryStorage.cs +++ b/Source/Testably.Abstractions.Testing/Storage/InMemoryStorage.cs @@ -15,8 +15,8 @@ namespace Testably.Abstractions.Testing.Storage; /// internal sealed class InMemoryStorage : IStorage { - internal readonly ConcurrentDictionary - Containers = new(); + private readonly ConcurrentDictionary + _containers = new(); private readonly ConcurrentDictionary _drives = new(StringComparer.OrdinalIgnoreCase); @@ -45,7 +45,7 @@ public InMemoryStorage(MockFileSystem fileSystem) { ThrowIfParentDoesNotExist(destination, _ => ExceptionFactory.DirectoryNotFound()); - if (!Containers.TryGetValue(source, + if (!_containers.TryGetValue(source, out IStorageContainer? sourceContainer)) { return null; @@ -59,7 +59,7 @@ public InMemoryStorage(MockFileSystem fileSystem) using (_ = sourceContainer.RequestAccess(FileAccess.ReadWrite, FileShare.None)) { if (overwrite && - Containers.TryRemove(destination, + _containers.TryRemove(destination, out IStorageContainer? existingContainer)) { existingContainer.ClearBytes(); @@ -67,7 +67,7 @@ public InMemoryStorage(MockFileSystem fileSystem) IStorageContainer copiedContainer = InMemoryContainer.NewFile(destination, _fileSystem); - if (Containers.TryAdd(destination, copiedContainer)) + if (_containers.TryAdd(destination, copiedContainer)) { copiedContainer.WriteBytes(sourceContainer.GetBytes().ToArray()); Execute.OnMac( @@ -99,11 +99,11 @@ public InMemoryStorage(MockFileSystem fileSystem) /// public bool DeleteContainer(IStorageLocation location, bool recursive = false) { - if (!Containers.TryGetValue(location, out IStorageContainer? container)) + if (!_containers.TryGetValue(location, out IStorageContainer? container)) { IStorageLocation? parentLocation = location.GetParent(); if (parentLocation != null && - !Containers.TryGetValue(parentLocation, out _)) + !_containers.TryGetValue(parentLocation, out _)) { throw ExceptionFactory.DirectoryNotFound(parentLocation.FullPath); } @@ -140,7 +140,7 @@ public bool DeleteContainer(IStorageLocation location, bool recursive = false) using (container.RequestAccess(FileAccess.Write, FileShare.ReadWrite, deleteAccess: true)) { - if (Containers.TryRemove(location, out IStorageContainer? removed)) + if (_containers.TryRemove(location, out IStorageContainer? removed)) { removed.ClearBytes(); _fileSystem.ChangeHandler.NotifyCompletedChange(fileSystemChange); @@ -160,7 +160,7 @@ public IEnumerable EnumerateLocations( EnumerationOptions? enumerationOptions = null) { ValidateExpression(searchPattern); - if (!Containers.ContainsKey(location)) + if (!_containers.ContainsKey(location)) { throw ExceptionFactory.DirectoryNotFound(location.FullPath); } @@ -177,7 +177,7 @@ public IEnumerable EnumerateLocations( fullPath += _fileSystem.Path.DirectorySeparatorChar; } - foreach (KeyValuePair item in Containers + foreach (KeyValuePair item in _containers .Where(x => x.Key.FullPath.StartsWith(fullPath, InMemoryLocation.StringComparisonMode) && !x.Key.Equals(location))) @@ -215,7 +215,7 @@ public IEnumerable EnumerateLocations( return null; } - if (Containers.TryGetValue(location, out IStorageContainer? container)) + if (_containers.TryGetValue(location, out IStorageContainer? container)) { return container; } @@ -287,7 +287,7 @@ public IStorageContainer GetOrCreateContainer( IFileSystemExtensibility? fileSystemExtensibility = null) { ChangeDescription? fileSystemChange = null; - IStorageContainer container = Containers.GetOrAdd(location, + IStorageContainer container = _containers.GetOrAdd(location, loc => { IStorageContainer container = @@ -302,7 +302,7 @@ public IStorageContainer GetOrCreateContainer( { IStorageLocation? parentLocation = loc.GetParent(); if (parentLocation is { IsRooted: false } && - !Containers.ContainsKey(parentLocation)) + !_containers.ContainsKey(parentLocation)) { throw ExceptionFactory.DirectoryNotFound(loc.FullPath); } @@ -359,13 +359,13 @@ public IStorageContainer GetOrCreateContainer( () => ExceptionFactory.DirectoryNotFound(location.FullPath), () => ExceptionFactory.FileNotFound(location.FullPath))); - if (!Containers.TryGetValue(source, + if (!_containers.TryGetValue(source, out IStorageContainer? sourceContainer)) { return null; } - if (!Containers.TryGetValue(destination, + if (!_containers.TryGetValue(destination, out IStorageContainer? destinationContainer)) { return null; @@ -383,14 +383,14 @@ public IStorageContainer GetOrCreateContainer( using (_ = destinationContainer.RequestAccess(FileAccess.ReadWrite, FileShare.None, ignoreMetadataErrors: ignoreMetadataErrors)) { - if (Containers.TryRemove(destination, + if (_containers.TryRemove(destination, out IStorageContainer? existingDestinationContainer)) { int destinationBytesLength = existingDestinationContainer.GetBytes().Length; destination.Drive?.ChangeUsedBytes(-1 * destinationBytesLength); if (backup != null && - Containers.TryAdd(backup, existingDestinationContainer)) + _containers.TryAdd(backup, existingDestinationContainer)) { Execute.OnWindowsIf(sourceContainer.Type == FileSystemTypes.File, () => existingDestinationContainer.Attributes |= @@ -398,7 +398,7 @@ public IStorageContainer GetOrCreateContainer( backup.Drive?.ChangeUsedBytes(destinationBytesLength); } - if (Containers.TryRemove(source, + if (_containers.TryRemove(source, out IStorageContainer? existingSourceContainer)) { int sourceBytesLength = existingSourceContainer.GetBytes().Length; @@ -414,7 +414,7 @@ public IStorageContainer GetOrCreateContainer( DateTimeKind.Utc), DateTimeKind.Utc); }); - Containers.TryAdd(destination, existingSourceContainer); + _containers.TryAdd(destination, existingSourceContainer); return destination; } } @@ -429,13 +429,13 @@ public IStorageContainer GetOrCreateContainer( public IStorageLocation? ResolveLinkTarget(IStorageLocation location, bool returnFinalTarget = false) { - if (Containers.TryGetValue(location, + if (_containers.TryGetValue(location, out IStorageContainer? initialContainer) && initialContainer.LinkTarget != null) { IStorageLocation? nextLocation = _fileSystem.Storage.GetLocation(initialContainer.LinkTarget); - if (Containers.TryGetValue(nextLocation, + if (_containers.TryGetValue(nextLocation, out IStorageContainer? container)) { if (returnFinalTarget) @@ -462,14 +462,14 @@ public bool TryAddContainer( { IStorageLocation? parentLocation = location.GetParent(); if (parentLocation is { IsRooted: false } && - !Containers.ContainsKey(parentLocation)) + !_containers.ContainsKey(parentLocation)) { throw ExceptionFactory.DirectoryNotFound(location.FullPath); } ChangeDescription? fileSystemChange = null; - container = Containers.GetOrAdd( + container = _containers.GetOrAdd( location, _ => { @@ -499,6 +499,19 @@ public bool TryAddContainer( #endregion + /// + public override string ToString() + => $"directories: {_containers.Count(x => x.Value.Type == FileSystemTypes.Directory)}, files: {_containers.Count(x => x.Value.Type == FileSystemTypes.File)}"; + + /// + /// Returns an ordered list of all stored containers. + /// + internal IReadOnlyList GetContainers() + => _containers + .OrderBy(x => x.Key.FullPath) + .Select(x => x.Value) + .ToList(); + private void CheckAndAdjustParentDirectoryTimes(IStorageLocation location) { IStorageContainer? parentContainer = GetContainer(location.GetParent()); @@ -535,7 +548,7 @@ private void CreateParents(MockFileSystem fileSystem, IStorageLocation location) ChangeDescription? fileSystemChange = null; IStorageLocation parentLocation = _fileSystem.Storage.GetLocation(parentPath); - _ = Containers.AddOrUpdate( + _ = _containers.AddOrUpdate( parentLocation, loc => { @@ -571,7 +584,7 @@ private void CreateParents(MockFileSystem fileSystem, IStorageLocation location) FileSystemTypes? sourceType, List? rollbacks = null) { - if (!Containers.TryGetValue(source, + if (!_containers.TryGetValue(source, out IStorageContainer? container)) { return null; @@ -615,16 +628,16 @@ private void CreateParents(MockFileSystem fileSystem, IStorageLocation location) NotifyFilters.FileName, destination, source); - if (Containers.TryRemove(source, out IStorageContainer? sourceContainer)) + if (_containers.TryRemove(source, out IStorageContainer? sourceContainer)) { if (overwrite && - Containers.TryRemove(destination, + _containers.TryRemove(destination, out IStorageContainer? existingContainer)) { existingContainer.ClearBytes(); } - if (Containers.TryAdd(destination, sourceContainer)) + if (_containers.TryAdd(destination, sourceContainer)) { int bytesLength = sourceContainer.GetBytes().Length; source.Drive?.ChangeUsedBytes(-1 * bytesLength); @@ -638,7 +651,7 @@ private void CreateParents(MockFileSystem fileSystem, IStorageLocation location) return destination; } - Containers.TryAdd(source, sourceContainer); + _containers.TryAdd(source, sourceContainer); throw ExceptionFactory.CannotCreateFileWhenAlreadyExists( sourceType == FileSystemTypes.Directory ? -2147024891 @@ -665,7 +678,7 @@ private void CreateParents(MockFileSystem fileSystem, IStorageLocation location) } nextLocation = _fileSystem.Storage.GetLocation(container.LinkTarget); - if (!Containers.TryGetValue(nextLocation, + if (!_containers.TryGetValue(nextLocation, out IStorageContainer? nextContainer)) { return nextLocation; @@ -692,7 +705,7 @@ private void ThrowIfParentDoesNotExist(IStorageLocation location, if (parentLocation != null && _fileSystem.Path.GetPathRoot(parentLocation.FullPath) != parentLocation.FullPath && - !Containers.TryGetValue(parentLocation, out _)) + !_containers.TryGetValue(parentLocation, out _)) { throw exceptionCallback(parentLocation); } From 1c511bcbd3679c9cf375d93a855ed42f206d5efb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Sun, 30 Jul 2023 07:39:06 +0200 Subject: [PATCH 2/3] Add ToString to `TimeProviderMock` --- Source/Testably.Abstractions.Testing/MockTimeSystem.cs | 4 ++-- Source/Testably.Abstractions.Testing/TimeProvider.cs | 8 ++++---- .../TimeSystem/TimeProviderMock.cs | 8 +++++++- .../TimeProviderTests.cs | 4 ++-- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/Source/Testably.Abstractions.Testing/MockTimeSystem.cs b/Source/Testably.Abstractions.Testing/MockTimeSystem.cs index 146a52f73..1748d4978 100644 --- a/Source/Testably.Abstractions.Testing/MockTimeSystem.cs +++ b/Source/Testably.Abstractions.Testing/MockTimeSystem.cs @@ -43,7 +43,7 @@ public MockTimeSystem() : this(Testing.TimeProvider.Random()) /// /// Initializes the with the specified . /// - public MockTimeSystem(DateTime time) : this(Testing.TimeProvider.Use(time)) + public MockTimeSystem(DateTime time) : this(Testing.TimeProvider.Fixed(time)) { } @@ -82,7 +82,7 @@ public ITimerFactory Timer /// public override string ToString() - => $"MockTimeSystem (now: {DateTime.UtcNow}Z)"; + => $"MockTimeSystem (provider: {TimeProvider}, now: {DateTime.UtcNow}Z)"; /// /// Specifies the to use when dealing with timers. diff --git a/Source/Testably.Abstractions.Testing/TimeProvider.cs b/Source/Testably.Abstractions.Testing/TimeProvider.cs index f24a0e922..f8790358b 100644 --- a/Source/Testably.Abstractions.Testing/TimeProvider.cs +++ b/Source/Testably.Abstractions.Testing/TimeProvider.cs @@ -14,7 +14,7 @@ public static class TimeProvider /// public static ITimeProvider Now() { - return new TimeProviderMock(DateTime.UtcNow); + return new TimeProviderMock(DateTime.UtcNow, "Now"); } /// @@ -26,14 +26,14 @@ public static ITimeProvider Random() { DateTime randomTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc) .AddSeconds(RandomFactory.Shared.Next()); - return new TimeProviderMock(randomTime); + return new TimeProviderMock(randomTime, "Random"); } /// /// Initializes the with the specified . /// - public static ITimeProvider Use(DateTime time) + public static ITimeProvider Fixed(DateTime time) { - return new TimeProviderMock(time); + return new TimeProviderMock(time, "Fixed"); } } diff --git a/Source/Testably.Abstractions.Testing/TimeSystem/TimeProviderMock.cs b/Source/Testably.Abstractions.Testing/TimeSystem/TimeProviderMock.cs index 55438f0c9..c33347633 100644 --- a/Source/Testably.Abstractions.Testing/TimeSystem/TimeProviderMock.cs +++ b/Source/Testably.Abstractions.Testing/TimeSystem/TimeProviderMock.cs @@ -8,11 +8,13 @@ namespace Testably.Abstractions.Testing.TimeSystem; internal sealed class TimeProviderMock : ITimeProvider { private DateTime _now; + private readonly string _description; private readonly object _lock = new(); - public TimeProviderMock(DateTime now) + public TimeProviderMock(DateTime now, string description) { _now = now; + _description = description; } #region ITimeProvider Members @@ -57,4 +59,8 @@ public void SetTo(DateTime value) } #endregion + + /// + public override string ToString() + => _description; } diff --git a/Tests/Testably.Abstractions.Testing.Tests/TimeProviderTests.cs b/Tests/Testably.Abstractions.Testing.Tests/TimeProviderTests.cs index 47db4fbba..d0ca2ecf1 100644 --- a/Tests/Testably.Abstractions.Testing.Tests/TimeProviderTests.cs +++ b/Tests/Testably.Abstractions.Testing.Tests/TimeProviderTests.cs @@ -38,7 +38,7 @@ public void Random_ShouldReturnRandomDateTime() [AutoData] public void SetTo_ShouldChangeTimeForRead(DateTime time1, DateTime time2) { - ITimeProvider timeProvider = TimeProvider.Use(time1); + ITimeProvider timeProvider = TimeProvider.Fixed(time1); DateTime result1 = timeProvider.Read(); timeProvider.SetTo(time2); @@ -52,7 +52,7 @@ public void SetTo_ShouldChangeTimeForRead(DateTime time1, DateTime time2) public void Use_ShouldReturnFixedDateTime() { DateTime now = TimeTestHelper.GetRandomTime(); - ITimeProvider timeProvider = TimeProvider.Use(now); + ITimeProvider timeProvider = TimeProvider.Fixed(now); DateTime result1 = timeProvider.Read(); DateTime result2 = timeProvider.Read(); From ac1508a5021f11de37ac35c0cc190ed08d072636 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Sun, 30 Jul 2023 07:43:46 +0200 Subject: [PATCH 3/3] Undo accidental rename --- Source/Testably.Abstractions.Testing/MockTimeSystem.cs | 2 +- Source/Testably.Abstractions.Testing/TimeProvider.cs | 2 +- .../Testably.Abstractions.Testing.Tests/TimeProviderTests.cs | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Source/Testably.Abstractions.Testing/MockTimeSystem.cs b/Source/Testably.Abstractions.Testing/MockTimeSystem.cs index 1748d4978..5eee0bc3d 100644 --- a/Source/Testably.Abstractions.Testing/MockTimeSystem.cs +++ b/Source/Testably.Abstractions.Testing/MockTimeSystem.cs @@ -43,7 +43,7 @@ public MockTimeSystem() : this(Testing.TimeProvider.Random()) /// /// Initializes the with the specified . /// - public MockTimeSystem(DateTime time) : this(Testing.TimeProvider.Fixed(time)) + public MockTimeSystem(DateTime time) : this(Testing.TimeProvider.Use(time)) { } diff --git a/Source/Testably.Abstractions.Testing/TimeProvider.cs b/Source/Testably.Abstractions.Testing/TimeProvider.cs index f8790358b..6c94e4084 100644 --- a/Source/Testably.Abstractions.Testing/TimeProvider.cs +++ b/Source/Testably.Abstractions.Testing/TimeProvider.cs @@ -32,7 +32,7 @@ public static ITimeProvider Random() /// /// Initializes the with the specified . /// - public static ITimeProvider Fixed(DateTime time) + public static ITimeProvider Use(DateTime time) { return new TimeProviderMock(time, "Fixed"); } diff --git a/Tests/Testably.Abstractions.Testing.Tests/TimeProviderTests.cs b/Tests/Testably.Abstractions.Testing.Tests/TimeProviderTests.cs index d0ca2ecf1..47db4fbba 100644 --- a/Tests/Testably.Abstractions.Testing.Tests/TimeProviderTests.cs +++ b/Tests/Testably.Abstractions.Testing.Tests/TimeProviderTests.cs @@ -38,7 +38,7 @@ public void Random_ShouldReturnRandomDateTime() [AutoData] public void SetTo_ShouldChangeTimeForRead(DateTime time1, DateTime time2) { - ITimeProvider timeProvider = TimeProvider.Fixed(time1); + ITimeProvider timeProvider = TimeProvider.Use(time1); DateTime result1 = timeProvider.Read(); timeProvider.SetTo(time2); @@ -52,7 +52,7 @@ public void SetTo_ShouldChangeTimeForRead(DateTime time1, DateTime time2) public void Use_ShouldReturnFixedDateTime() { DateTime now = TimeTestHelper.GetRandomTime(); - ITimeProvider timeProvider = TimeProvider.Fixed(now); + ITimeProvider timeProvider = TimeProvider.Use(now); DateTime result1 = timeProvider.Read(); DateTime result2 = timeProvider.Read();