diff --git a/Source/Testably.Abstractions.Interface/Helpers/GuidSystemBase.cs b/Source/Testably.Abstractions.Interface/Helpers/GuidSystemBase.cs index f37736b9e..9cdc33156 100644 --- a/Source/Testably.Abstractions.Interface/Helpers/GuidSystemBase.cs +++ b/Source/Testably.Abstractions.Interface/Helpers/GuidSystemBase.cs @@ -41,7 +41,7 @@ public Guid Parse(string input) #endif #if FEATURE_GUID_PARSE -#pragma warning disable MA0011 + #pragma warning disable MA0011 /// public Guid Parse(ReadOnlySpan input) => Guid.Parse(input); diff --git a/Source/Testably.Abstractions.Testing/FileSystem/FileSystemWatcherMock.cs b/Source/Testably.Abstractions.Testing/FileSystem/FileSystemWatcherMock.cs index b0b112ca5..0ff3cb4c5 100644 --- a/Source/Testably.Abstractions.Testing/FileSystem/FileSystemWatcherMock.cs +++ b/Source/Testably.Abstractions.Testing/FileSystem/FileSystemWatcherMock.cs @@ -595,6 +595,7 @@ private bool TryMakeRenamedEventArgs( .GetField("_oldFullPath", BindingFlags.Instance | BindingFlags.NonPublic)? .SetValue(eventArgs, oldFullPath); } + return _fileSystem.Execute.Path.GetDirectoryName(changeDescription.Path)? .Equals(_fileSystem.Execute.Path.GetDirectoryName(changeDescription.OldPath), _fileSystem.Execute.StringComparisonMode) ?? true; diff --git a/Source/Testably.Abstractions.Testing/Helpers/Execute.NativePath.cs b/Source/Testably.Abstractions.Testing/Helpers/Execute.NativePath.cs index f5463a80f..28ed33561 100644 --- a/Source/Testably.Abstractions.Testing/Helpers/Execute.NativePath.cs +++ b/Source/Testably.Abstractions.Testing/Helpers/Execute.NativePath.cs @@ -132,17 +132,15 @@ public string GetFullPath(string path) string? pathRoot = System.IO.Path.GetPathRoot(path); string? directoryRoot = System.IO.Path.GetPathRoot(fileSystem.Storage.CurrentDirectory); - if (!string.IsNullOrEmpty(pathRoot) && !string.IsNullOrEmpty(directoryRoot)) + if (pathRoot?.Length < directoryRoot?.Length) { - if (char.ToUpperInvariant(pathRoot[0]) != char.ToUpperInvariant(directoryRoot[0])) + if (pathRoot.Length > 0 && + char.ToUpperInvariant(pathRoot[0]) != char.ToUpperInvariant(directoryRoot[0])) { return System.IO.Path.GetFullPath(path); } - if (pathRoot.Length < directoryRoot.Length) - { - path = path.Substring(pathRoot.Length); - } + path = path.Substring(pathRoot.Length); } return System.IO.Path.GetFullPath(System.IO.Path.Combine( @@ -183,7 +181,6 @@ public string GetRandomFileName() public string GetRelativePath(string relativeTo, string path) { relativeTo.EnsureValidArgument(fileSystem, nameof(relativeTo)); - path.EnsureValidArgument(fileSystem, nameof(path)); relativeTo = fileSystem.Execute.Path.GetFullPath(relativeTo); path = fileSystem.Execute.Path.GetFullPath(path); diff --git a/Source/Testably.Abstractions.Testing/Helpers/Execute.SimulatedPath.cs b/Source/Testably.Abstractions.Testing/Helpers/Execute.SimulatedPath.cs index 0bfff8f08..5242af70d 100644 --- a/Source/Testably.Abstractions.Testing/Helpers/Execute.SimulatedPath.cs +++ b/Source/Testably.Abstractions.Testing/Helpers/Execute.SimulatedPath.cs @@ -290,17 +290,10 @@ public string GetRandomFileName() public string GetRelativePath(string relativeTo, string path) { relativeTo.EnsureValidArgument(fileSystem, nameof(relativeTo)); - path.EnsureValidArgument(fileSystem, nameof(path)); relativeTo = fileSystem.Execute.Path.GetFullPath(relativeTo); path = fileSystem.Execute.Path.GetFullPath(path); - // Need to check if the roots are different- if they are we need to return the "to" path. - if (!AreRootsEqual(relativeTo, path, fileSystem.Execute.StringComparisonMode)) - { - return path; - } - Func charComparer = (c1, c2) => c1 == c2; if (fileSystem.Execute.StringComparisonMode == StringComparison.OrdinalIgnoreCase) { @@ -505,35 +498,10 @@ public bool TryJoin(ReadOnlySpan path1, #endregion - /// - /// Returns true if the two paths have the same root - /// - private bool AreRootsEqual(string first, string second, StringComparison comparisonType) - { - int firstRootLength = GetRootLength(first); - int secondRootLength = GetRootLength(second); - - return firstRootLength == secondRootLength - && string.Compare( - strA: first, - indexA: 0, - strB: second, - indexB: 0, - length: firstRootLength, - comparisonType: comparisonType) == 0; - } - private string CombineInternal(string[] paths) { - string NormalizePath(string path, bool ignoreStartingSeparator) + string NormalizePath(string path) { - if (!ignoreStartingSeparator && ( - path[0] == DirectorySeparatorChar || - path[0] == AltDirectorySeparatorChar)) - { - path = path.Substring(1); - } - if (path[path.Length - 1] == DirectorySeparatorChar || path[path.Length - 1] == AltDirectorySeparatorChar) { @@ -550,7 +518,6 @@ string NormalizePath(string path, bool ignoreStartingSeparator) StringBuilder sb = new(); - bool isFirst = true; bool endsWithDirectorySeparator = false; foreach (string path in paths) { @@ -567,10 +534,9 @@ string NormalizePath(string path, bool ignoreStartingSeparator) if (IsPathRooted(path)) { sb.Clear(); - isFirst = true; } - sb.Append(NormalizePath(path, isFirst)); + sb.Append(NormalizePath(path)); sb.Append(DirectorySeparatorChar); endsWithDirectorySeparator = path.EndsWith(DirectorySeparatorChar) || path.EndsWith(AltDirectorySeparatorChar); @@ -650,7 +616,7 @@ private int GetCommonPathLength(string first, string second, int commonChars = 0; for (; commonChars < first.Length; commonChars++) { - if (second.Length < commonChars) + if (second.Length <= commonChars) { break; } @@ -668,13 +634,13 @@ private int GetCommonPathLength(string first, string second, } // Or we're a full string and equal length or match to a separator - if (commonChars == first.Length - && (commonChars == second.Length || IsDirectorySeparator(second[commonChars]))) + if (commonChars == first.Length && commonChars == second.Length) { return commonChars; } - if (commonChars == second.Length && IsDirectorySeparator(first[commonChars])) + if ((second.Length > commonChars && IsDirectorySeparator(second[commonChars])) || + IsDirectorySeparator(first[commonChars - 1])) { return commonChars; } diff --git a/Source/Testably.Abstractions.Testing/Helpers/Execute.cs b/Source/Testably.Abstractions.Testing/Helpers/Execute.cs index c0b479a5c..e70ed4f7f 100644 --- a/Source/Testably.Abstractions.Testing/Helpers/Execute.cs +++ b/Source/Testably.Abstractions.Testing/Helpers/Execute.cs @@ -43,12 +43,13 @@ internal partial class Execute #if !CAN_SIMULATE_OTHER_OS [Obsolete("Simulating other operating systems is not supported on .NET Framework")] #endif - internal Execute(MockFileSystem fileSystem, SimulationMode simulationMode) + internal Execute(MockFileSystem fileSystem, SimulationMode simulationMode, + bool isNetFramework = false) { IsLinux = simulationMode == SimulationMode.Linux; IsMac = simulationMode == SimulationMode.MacOS; IsWindows = simulationMode == SimulationMode.Windows; - IsNetFramework = false; + IsNetFramework = IsWindows && isNetFramework; StringComparisonMode = IsLinux ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase; @@ -67,7 +68,7 @@ internal Execute(MockFileSystem fileSystem, SimulationMode simulationMode) else { throw new NotSupportedException( - "The operating system must be one of Linux, OSX or Windows"); + "The operating system must be one of Linux, MacOS or Windows"); } } diff --git a/Source/Testably.Abstractions.Testing/Helpers/FileSystemExtensions.cs b/Source/Testably.Abstractions.Testing/Helpers/FileSystemExtensions.cs index 9fefac34f..4665e9636 100644 --- a/Source/Testably.Abstractions.Testing/Helpers/FileSystemExtensions.cs +++ b/Source/Testably.Abstractions.Testing/Helpers/FileSystemExtensions.cs @@ -66,7 +66,8 @@ internal static string GetSubdirectoryPath(this MockFileSystem fileSystem, { fullFilePath = fullFilePath.Substring(currentDirectory.Length); } - else if (fullFilePath.StartsWith(currentDirectory + fileSystem.Execute.Path.DirectorySeparatorChar, + else if (fullFilePath.StartsWith( + currentDirectory + fileSystem.Execute.Path.DirectorySeparatorChar, fileSystem.Execute.StringComparisonMode)) { fullFilePath = fullFilePath.Substring(currentDirectory.Length + 1); @@ -75,11 +76,13 @@ internal static string GetSubdirectoryPath(this MockFileSystem fileSystem, { string? parentName = currentDirectory; while (parentName != null && - !fullFilePath.StartsWith(parentName + fileSystem.Execute.Path.DirectorySeparatorChar, + !fullFilePath.StartsWith( + parentName + fileSystem.Execute.Path.DirectorySeparatorChar, fileSystem.Execute.StringComparisonMode)) { parentName = fileSystem.Execute.Path.GetDirectoryName(parentName); - int lastIndex = givenPath.LastIndexOf(fileSystem.Execute.Path.DirectorySeparatorChar); + int lastIndex = + givenPath.LastIndexOf(fileSystem.Execute.Path.DirectorySeparatorChar); if (lastIndex >= 0) { givenPath = givenPath.Substring(0, lastIndex); diff --git a/Source/Testably.Abstractions.Testing/Statistics/CallStatistics.cs b/Source/Testably.Abstractions.Testing/Statistics/CallStatistics.cs index 4fe64d274..81169b230 100644 --- a/Source/Testably.Abstractions.Testing/Statistics/CallStatistics.cs +++ b/Source/Testably.Abstractions.Testing/Statistics/CallStatistics.cs @@ -16,7 +16,7 @@ public CallStatistics(IStatisticsGate statisticsGate, string name) _name = name; } - #region IStatistics Members + #region IStatistics Members /// public MethodStatistic[] Methods => _methods.ToArray(); diff --git a/Source/Testably.Abstractions.Testing/Statistics/PathStatistics.cs b/Source/Testably.Abstractions.Testing/Statistics/PathStatistics.cs index f6a6da025..19f788bc7 100644 --- a/Source/Testably.Abstractions.Testing/Statistics/PathStatistics.cs +++ b/Source/Testably.Abstractions.Testing/Statistics/PathStatistics.cs @@ -5,7 +5,8 @@ namespace Testably.Abstractions.Testing.Statistics; -internal class PathStatistics : CallStatistics, IPathStatistics +internal class PathStatistics : CallStatistics, + IPathStatistics { private readonly MockFileSystem _fileSystem; @@ -26,7 +27,7 @@ public PathStatistics( _fileSystem = fileSystem; } - #region IPathStatistics Members + #region IPathStatistics Members /// public IStatistics this[string path] diff --git a/Source/Testably.Abstractions.Testing/Storage/InMemoryContainer.cs b/Source/Testably.Abstractions.Testing/Storage/InMemoryContainer.cs index adea56cd5..edf339759 100644 --- a/Source/Testably.Abstractions.Testing/Storage/InMemoryContainer.cs +++ b/Source/Testably.Abstractions.Testing/Storage/InMemoryContainer.cs @@ -290,7 +290,11 @@ internal FileAttributes AdjustAttributes(FileAttributes attributes) return attributes; } - private bool CanGetAccess(FileAccess access, FileShare share, bool deleteAccess, bool ignoreFileShare) + private bool CanGetAccess( + FileAccess access, + FileShare share, + bool deleteAccess, + bool ignoreFileShare) { foreach (KeyValuePair fileHandle in _fileHandles) { @@ -386,7 +390,11 @@ public void Dispose() #endregion - public bool GrantAccess(FileAccess access, FileShare share, bool deleteAccess, bool ignoreFileShare) + public bool GrantAccess( + FileAccess access, + FileShare share, + bool deleteAccess, + bool ignoreFileShare) { FileShare usedShare = share; FileShare currentShare = Share; diff --git a/Source/Testably.Abstractions.Testing/Storage/StorageExtensions.cs b/Source/Testably.Abstractions.Testing/Storage/StorageExtensions.cs index fe8b168d7..e4037096c 100644 --- a/Source/Testably.Abstractions.Testing/Storage/StorageExtensions.cs +++ b/Source/Testably.Abstractions.Testing/Storage/StorageExtensions.cs @@ -27,9 +27,11 @@ public static AdjustedLocation AdjustLocationFromSearchPattern( StringBuilder givenPathPrefix = new(); while (searchPattern.StartsWith( - ".." + fileSystem.Execute.Path.DirectorySeparatorChar, StringComparison.Ordinal) || + ".." + fileSystem.Execute.Path.DirectorySeparatorChar, + StringComparison.Ordinal) || searchPattern.StartsWith( - ".." + fileSystem.Execute.Path.AltDirectorySeparatorChar, StringComparison.Ordinal)) + ".." + fileSystem.Execute.Path.AltDirectorySeparatorChar, + StringComparison.Ordinal)) { fileSystem.Execute.OnNetFramework( () => throw ExceptionFactory.SearchPatternCannotContainTwoDots()); diff --git a/Tests/Helpers/Testably.Abstractions.Tests.SourceGenerator/ClassGenerators/FileSystemClassGenerator.cs b/Tests/Helpers/Testably.Abstractions.Tests.SourceGenerator/ClassGenerators/FileSystemClassGenerator.cs index 5569f7be6..b914e6e1b 100644 --- a/Tests/Helpers/Testably.Abstractions.Tests.SourceGenerator/ClassGenerators/FileSystemClassGenerator.cs +++ b/Tests/Helpers/Testably.Abstractions.Tests.SourceGenerator/ClassGenerators/FileSystemClassGenerator.cs @@ -147,8 +147,8 @@ public sealed class LinuxFileSystemTests : {@class.Name}, IDispo private readonly IDirectoryCleaner _directoryCleaner; - public LinuxFileSystemTests() : this(new MockFileSystem(i => - i.SimulatingOperatingSystem(SimulationMode.Linux))) + public LinuxFileSystemTests() : this(new MockFileSystem(o => + o.SimulatingOperatingSystem(SimulationMode.Linux))) {{ }} @@ -187,8 +187,8 @@ public sealed class MacFileSystemTests : {@class.Name}, IDisposa private readonly IDirectoryCleaner _directoryCleaner; - public MacFileSystemTests() : this(new MockFileSystem(i => - i.SimulatingOperatingSystem(SimulationMode.MacOS))) + public MacFileSystemTests() : this(new MockFileSystem(o => + o.SimulatingOperatingSystem(SimulationMode.MacOS))) {{ }} private MacFileSystemTests(MockFileSystem mockFileSystem) : base( @@ -226,8 +226,8 @@ public sealed class WindowsFileSystemTests : {@class.Name}, IDis private readonly IDirectoryCleaner _directoryCleaner; - public WindowsFileSystemTests() : this(new MockFileSystem(i => - i.SimulatingOperatingSystem(SimulationMode.Windows))) + public WindowsFileSystemTests() : this(new MockFileSystem(o => + o.SimulatingOperatingSystem(SimulationMode.Windows))) {{ }} private WindowsFileSystemTests(MockFileSystem mockFileSystem) : base( diff --git a/Tests/Testably.Abstractions.Compression.Tests/Internal/ZipUtilitiesTests.cs b/Tests/Testably.Abstractions.Compression.Tests/Internal/ZipUtilitiesTests.cs index 3ec44a582..c1e6ed302 100644 --- a/Tests/Testably.Abstractions.Compression.Tests/Internal/ZipUtilitiesTests.cs +++ b/Tests/Testably.Abstractions.Compression.Tests/Internal/ZipUtilitiesTests.cs @@ -46,14 +46,17 @@ private sealed class DummyZipArchiveEntry( Stream? stream = null) : IZipArchiveEntry { + /// + public string Comment { get; set; } = comment; + + /// + public bool IsEncrypted { get; } = isEncrypted; + #region IZipArchiveEntry Members /// public IZipArchive Archive => archive ?? throw new NotSupportedException(); - /// - public string Comment { get; set; } = comment; - /// public long CompressedLength => stream?.Length ?? 0L; @@ -69,9 +72,6 @@ private sealed class DummyZipArchiveEntry( /// public string FullName { get; } = fullName ?? ""; - /// - public bool IsEncrypted { get; } = isEncrypted; - /// public DateTimeOffset LastWriteTime { get; set; } diff --git a/Tests/Testably.Abstractions.Testing.Tests/FileSystem/FileSystemWatcherMockTests.cs b/Tests/Testably.Abstractions.Testing.Tests/FileSystem/FileSystemWatcherMockTests.cs index fd49cf14e..4572ffc02 100644 --- a/Tests/Testably.Abstractions.Testing.Tests/FileSystem/FileSystemWatcherMockTests.cs +++ b/Tests/Testably.Abstractions.Testing.Tests/FileSystem/FileSystemWatcherMockTests.cs @@ -234,7 +234,7 @@ public void InternalBufferSize_ShouldResetQueue(string path1, string path2) result.Should().BeNull(); } -#if !NETFRAMEWORK +#if CAN_SIMULATE_OTHER_OS public sealed class EventArgsTests { [SkippableTheory] @@ -244,8 +244,7 @@ public sealed class EventArgsTests public void FileSystemEventArgs_ShouldUseDirectorySeparatorFromSimulatedFileSystem( SimulationMode simulationMode, string parentDirectory, string directoryName) { - MockFileSystem fileSystem = - new MockFileSystem(s => s.SimulatingOperatingSystem(simulationMode)); + MockFileSystem fileSystem = new(o => o.SimulatingOperatingSystem(simulationMode)); fileSystem.Directory.CreateDirectory(parentDirectory); FileSystemEventArgs? result = null; string expectedFullPath = fileSystem.Path.GetFullPath( @@ -278,7 +277,9 @@ public void FileSystemEventArgs_ShouldUseDirectorySeparatorFromSimulatedFileSyst result.Name.Should().Be(expectedName); result.ChangeType.Should().Be(WatcherChangeTypes.Created); } +#endif +#if CAN_SIMULATE_OTHER_OS [SkippableTheory] [InlineAutoData(SimulationMode.Linux)] [InlineAutoData(SimulationMode.MacOS)] @@ -287,8 +288,7 @@ public void RenamedEventArgs_ShouldUseDirectorySeparatorFromSimulatedFileSystem( SimulationMode simulationMode, string parentDirectory, string sourceName, string destinationName) { - MockFileSystem fileSystem = - new MockFileSystem(s => s.SimulatingOperatingSystem(simulationMode)); + MockFileSystem fileSystem = new(o => o.SimulatingOperatingSystem(simulationMode)); fileSystem.Directory.CreateDirectory(parentDirectory); RenamedEventArgs? result = null; string expectedOldFullPath = fileSystem.Path.GetFullPath( diff --git a/Tests/Testably.Abstractions.Testing.Tests/FileSystem/PathMockTests.cs b/Tests/Testably.Abstractions.Testing.Tests/FileSystem/PathMockTests.cs index 611ad26cc..d7af85106 100644 --- a/Tests/Testably.Abstractions.Testing.Tests/FileSystem/PathMockTests.cs +++ b/Tests/Testably.Abstractions.Testing.Tests/FileSystem/PathMockTests.cs @@ -6,7 +6,7 @@ public sealed class PathMockTests { [Theory] [InlineAutoData(SimulationMode.Native)] -#if !NETFRAMEWORK +#if CAN_SIMULATE_OTHER_OS [InlineAutoData(SimulationMode.Linux)] [InlineAutoData(SimulationMode.MacOS)] [InlineAutoData(SimulationMode.Windows)] @@ -15,7 +15,7 @@ public void GetTempFileName_WithCollisions_ShouldThrowIOException( SimulationMode simulationMode, int fixedRandomValue) { #pragma warning disable CS0618 - MockFileSystem fileSystem = new(i => i + MockFileSystem fileSystem = new(o => o .SimulatingOperatingSystem(simulationMode) .UseRandomProvider(RandomProvider.Generate( intGenerator: new RandomProvider.Generator(() => fixedRandomValue)))); diff --git a/Tests/Testably.Abstractions.Testing.Tests/Helpers/ExceptionFactoryTests.cs b/Tests/Testably.Abstractions.Testing.Tests/Helpers/ExceptionFactoryTests.cs index 23b4127ac..fe17fa623 100644 --- a/Tests/Testably.Abstractions.Testing.Tests/Helpers/ExceptionFactoryTests.cs +++ b/Tests/Testably.Abstractions.Testing.Tests/Helpers/ExceptionFactoryTests.cs @@ -20,6 +20,29 @@ public void OperationNotSupportedOnThisPlatform_ShouldMentionPlatform() sut.Message.Should().Contain("platform"); } + [Theory] + [InlineAutoData(SimulationMode.Windows, false)] + [InlineAutoData(SimulationMode.Windows, true)] + public void PathCannotBeEmpty_ShouldSetParamNameExceptOnNetFramework( + SimulationMode type, bool isNetFramework, string paramName) + { + #pragma warning disable CS0618 + Execute execute = new(new MockFileSystem(), type, isNetFramework); + #pragma warning restore CS0618 + ArgumentException sut = ExceptionFactory.PathCannotBeEmpty(execute, paramName); + + sut.Message.Should().Contain("Path cannot be the empty string or all whitespace"); + sut.HResult.Should().Be(-2147024809); + if (isNetFramework) + { + sut.ParamName.Should().BeNull(); + } + else + { + sut.ParamName.Should().Be(paramName); + } + } + [Fact] public void SearchPatternCannotContainTwoDots_ShouldMentionTwoDots() { diff --git a/Tests/Testably.Abstractions.Testing.Tests/Helpers/ExecuteExtensionsTests.cs b/Tests/Testably.Abstractions.Testing.Tests/Helpers/ExecuteExtensionsTests.cs index 41ebad319..f3c74d672 100644 --- a/Tests/Testably.Abstractions.Testing.Tests/Helpers/ExecuteExtensionsTests.cs +++ b/Tests/Testably.Abstractions.Testing.Tests/Helpers/ExecuteExtensionsTests.cs @@ -5,14 +5,17 @@ namespace Testably.Abstractions.Testing.Tests.Helpers; public sealed class ExecuteExtensionsTests { [Theory] - [InlineData(SimulationMode.Linux, true)] - [InlineData(SimulationMode.MacOS, true)] - [InlineData(SimulationMode.Windows, true)] + [InlineData(SimulationMode.Linux, false, true)] + [InlineData(SimulationMode.MacOS, false, true)] + [InlineData(SimulationMode.Windows, false, true)] + [InlineData(SimulationMode.Linux, true, true)] + [InlineData(SimulationMode.MacOS, true, true)] + [InlineData(SimulationMode.Windows, true, false)] public void NotOnNetFramework_ShouldExecuteDependingOnOperatingSystem( - SimulationMode type, bool shouldExecute) + SimulationMode type, bool isNetFramework, bool shouldExecute) { bool isExecuted = false; - Execute sut = FromType(type); + Execute sut = FromType(type, isNetFramework); sut.NotOnNetFramework(() => { isExecuted = true; }); @@ -20,14 +23,15 @@ public void NotOnNetFramework_ShouldExecuteDependingOnOperatingSystem( } [Theory] - [InlineData(SimulationMode.Linux, true)] - [InlineData(SimulationMode.MacOS, true)] - [InlineData(SimulationMode.Windows, false)] + [InlineData(SimulationMode.Linux, false, true)] + [InlineData(SimulationMode.MacOS, false, true)] + [InlineData(SimulationMode.Windows, false, false)] + [InlineData(SimulationMode.Windows, true, false)] public void NotOnWindows_ShouldExecuteDependingOnOperatingSystem( - SimulationMode type, bool shouldExecute) + SimulationMode type, bool isNetFramework, bool shouldExecute) { bool isExecuted = false; - Execute sut = FromType(type); + Execute sut = FromType(type, isNetFramework); sut.NotOnWindows(() => { isExecuted = true; }); @@ -35,17 +39,19 @@ public void NotOnWindows_ShouldExecuteDependingOnOperatingSystem( } [Theory] - [InlineData(SimulationMode.Linux, false, false)] - [InlineData(SimulationMode.Linux, true, true)] - [InlineData(SimulationMode.MacOS, false, false)] - [InlineData(SimulationMode.MacOS, true, true)] - [InlineData(SimulationMode.Windows, false, false)] - [InlineData(SimulationMode.Windows, true, false)] + [InlineData(SimulationMode.Linux, false, false, false)] + [InlineData(SimulationMode.Linux, false, true, true)] + [InlineData(SimulationMode.MacOS, false, false, false)] + [InlineData(SimulationMode.MacOS, false, true, true)] + [InlineData(SimulationMode.Windows, false, false, false)] + [InlineData(SimulationMode.Windows, false, true, false)] + [InlineData(SimulationMode.Windows, true, false, false)] + [InlineData(SimulationMode.Windows, true, true, false)] public void NotOnWindowsIf_ShouldExecuteDependingOnOperatingSystem( - SimulationMode type, bool predicate, bool shouldExecute) + SimulationMode type, bool isNetFramework, bool predicate, bool shouldExecute) { bool isExecuted = false; - Execute sut = FromType(type); + Execute sut = FromType(type, isNetFramework); sut.NotOnWindowsIf(predicate, () => { isExecuted = true; }); @@ -53,14 +59,14 @@ public void NotOnWindowsIf_ShouldExecuteDependingOnOperatingSystem( } [Theory] - [InlineData(SimulationMode.Linux, true)] - [InlineData(SimulationMode.MacOS, false)] - [InlineData(SimulationMode.Windows, false)] + [InlineData(SimulationMode.Linux, false, true)] + [InlineData(SimulationMode.MacOS, false, false)] + [InlineData(SimulationMode.Windows, false, false)] public void OnLinux_ShouldExecuteDependingOnOperatingSystem( - SimulationMode type, bool shouldExecute) + SimulationMode type, bool isNetFramework, bool shouldExecute) { bool isExecuted = false; - Execute sut = FromType(type); + Execute sut = FromType(type, isNetFramework); sut.OnLinux(() => { isExecuted = true; }); @@ -68,13 +74,17 @@ public void OnLinux_ShouldExecuteDependingOnOperatingSystem( } [Theory] - [InlineData(SimulationMode.Linux, 3, 4, 3)] - [InlineData(SimulationMode.MacOS, 5, 6, 6)] - [InlineData(SimulationMode.Windows, 1, 2, 2)] + [InlineData(SimulationMode.Linux, false, 3, 4, 3)] + [InlineData(SimulationMode.MacOS, false, 5, 6, 6)] + [InlineData(SimulationMode.Windows, false, 1, 2, 2)] public void OnLinux_WithValue_ShouldExecuteDependingOnOperatingSystem( - SimulationMode type, int value, int alternativeValue, int expectedValue) + SimulationMode type, + bool isNetFramework, + int value, + int alternativeValue, + int expectedValue) { - Execute sut = FromType(type); + Execute sut = FromType(type, isNetFramework); int result = sut.OnLinux(() => value, () => alternativeValue); @@ -82,14 +92,14 @@ public void OnLinux_WithValue_ShouldExecuteDependingOnOperatingSystem( } [Theory] - [InlineData(SimulationMode.Linux, false)] - [InlineData(SimulationMode.MacOS, true)] - [InlineData(SimulationMode.Windows, false)] + [InlineData(SimulationMode.Linux, false, false)] + [InlineData(SimulationMode.MacOS, false, true)] + [InlineData(SimulationMode.Windows, false, false)] public void OnMac_ShouldExecuteDependingOnOperatingSystem( - SimulationMode type, bool shouldExecute) + SimulationMode type, bool isNetFramework, bool shouldExecute) { bool isExecuted = false; - Execute sut = FromType(type); + Execute sut = FromType(type, isNetFramework); sut.OnMac(() => { isExecuted = true; }); @@ -97,14 +107,17 @@ public void OnMac_ShouldExecuteDependingOnOperatingSystem( } [Theory] - [InlineData(SimulationMode.Linux, false)] - [InlineData(SimulationMode.MacOS, false)] - [InlineData(SimulationMode.Windows, false)] + [InlineData(SimulationMode.Linux, false, false)] + [InlineData(SimulationMode.MacOS, false, false)] + [InlineData(SimulationMode.Windows, false, false)] + [InlineData(SimulationMode.Linux, true, false)] + [InlineData(SimulationMode.MacOS, true, false)] + [InlineData(SimulationMode.Windows, true, true)] public void OnNetFramework_ShouldExecuteDependingOnOperatingSystem( - SimulationMode type, bool shouldExecute) + SimulationMode type, bool isNetFramework, bool shouldExecute) { bool isExecuted = false; - Execute sut = FromType(type); + Execute sut = FromType(type, isNetFramework); sut.OnNetFramework(() => { isExecuted = true; }); @@ -112,13 +125,20 @@ public void OnNetFramework_ShouldExecuteDependingOnOperatingSystem( } [Theory] - [InlineData(SimulationMode.Linux, 3, 4, 4)] - [InlineData(SimulationMode.MacOS, 5, 6, 6)] - [InlineData(SimulationMode.Windows, 1, 2, 2)] + [InlineData(SimulationMode.Linux, false, 3, 4, 4)] + [InlineData(SimulationMode.MacOS, false, 5, 6, 6)] + [InlineData(SimulationMode.Windows, false, 1, 2, 2)] + [InlineData(SimulationMode.Linux, true, 3, 4, 4)] + [InlineData(SimulationMode.MacOS, true, 5, 6, 6)] + [InlineData(SimulationMode.Windows, true, 1, 2, 1)] public void OnNetFramework_WithValue_ShouldExecuteDependingOnOperatingSystem( - SimulationMode type, int value, int alternativeValue, int expectedValue) + SimulationMode type, + bool isNetFramework, + int value, + int alternativeValue, + int expectedValue) { - Execute sut = FromType(type); + Execute sut = FromType(type, isNetFramework); int result = sut.OnNetFramework(() => value, () => alternativeValue); @@ -126,17 +146,23 @@ public void OnNetFramework_WithValue_ShouldExecuteDependingOnOperatingSystem( } [Theory] - [InlineData(SimulationMode.Linux, false, false)] - [InlineData(SimulationMode.Linux, true, false)] - [InlineData(SimulationMode.MacOS, false, false)] - [InlineData(SimulationMode.MacOS, true, false)] - [InlineData(SimulationMode.Windows, false, false)] - [InlineData(SimulationMode.Windows, true, false)] + [InlineData(SimulationMode.Linux, false, false, false)] + [InlineData(SimulationMode.Linux, false, true, false)] + [InlineData(SimulationMode.MacOS, false, false, false)] + [InlineData(SimulationMode.MacOS, false, true, false)] + [InlineData(SimulationMode.Windows, false, false, false)] + [InlineData(SimulationMode.Windows, false, true, false)] + [InlineData(SimulationMode.Linux, true, false, false)] + [InlineData(SimulationMode.Linux, true, true, false)] + [InlineData(SimulationMode.MacOS, true, false, false)] + [InlineData(SimulationMode.MacOS, true, true, false)] + [InlineData(SimulationMode.Windows, true, false, false)] + [InlineData(SimulationMode.Windows, true, true, true)] public void OnNetFrameworkIf_ShouldExecuteDependingOnOperatingSystem( - SimulationMode type, bool predicate, bool shouldExecute) + SimulationMode type, bool isNetFramework, bool predicate, bool shouldExecute) { bool isExecuted = false; - Execute sut = FromType(type); + Execute sut = FromType(type, isNetFramework); sut.OnNetFrameworkIf(predicate, () => { isExecuted = true; }); @@ -144,14 +170,15 @@ public void OnNetFrameworkIf_ShouldExecuteDependingOnOperatingSystem( } [Theory] - [InlineData(SimulationMode.Linux, false)] - [InlineData(SimulationMode.MacOS, false)] - [InlineData(SimulationMode.Windows, true)] + [InlineData(SimulationMode.Linux, false, false)] + [InlineData(SimulationMode.MacOS, false, false)] + [InlineData(SimulationMode.Windows, false, true)] + [InlineData(SimulationMode.Windows, true, true)] public void OnWindows_ShouldExecuteDependingOnOperatingSystem( - SimulationMode type, bool shouldExecute) + SimulationMode type, bool isNetFramework, bool shouldExecute) { bool isExecuted = false; - Execute sut = FromType(type); + Execute sut = FromType(type, isNetFramework); sut.OnWindows(() => { isExecuted = true; }); @@ -159,13 +186,18 @@ public void OnWindows_ShouldExecuteDependingOnOperatingSystem( } [Theory] - [InlineData(SimulationMode.Linux, 3, 4, 4)] - [InlineData(SimulationMode.MacOS, 5, 6, 6)] - [InlineData(SimulationMode.Windows, 1, 2, 1)] + [InlineData(SimulationMode.Linux, false, 3, 4, 4)] + [InlineData(SimulationMode.MacOS, false, 5, 6, 6)] + [InlineData(SimulationMode.Windows, false, 1, 2, 1)] + [InlineData(SimulationMode.Windows, true, 1, 2, 1)] public void OnWindows_WithValue_ShouldExecuteDependingOnOperatingSystem( - SimulationMode type, int value, int alternativeValue, int expectedValue) + SimulationMode type, + bool isNetFramework, + int value, + int alternativeValue, + int expectedValue) { - Execute sut = FromType(type); + Execute sut = FromType(type, isNetFramework); int result = sut.OnWindows(() => value, () => alternativeValue); @@ -173,17 +205,19 @@ public void OnWindows_WithValue_ShouldExecuteDependingOnOperatingSystem( } [Theory] - [InlineData(SimulationMode.Linux, false, false)] - [InlineData(SimulationMode.Linux, true, false)] - [InlineData(SimulationMode.MacOS, false, false)] - [InlineData(SimulationMode.MacOS, true, false)] - [InlineData(SimulationMode.Windows, false, false)] - [InlineData(SimulationMode.Windows, true, true)] + [InlineData(SimulationMode.Linux, false, false, false)] + [InlineData(SimulationMode.Linux, false, true, false)] + [InlineData(SimulationMode.MacOS, false, false, false)] + [InlineData(SimulationMode.MacOS, false, true, false)] + [InlineData(SimulationMode.Windows, false, false, false)] + [InlineData(SimulationMode.Windows, false, true, true)] + [InlineData(SimulationMode.Windows, true, false, false)] + [InlineData(SimulationMode.Windows, true, true, true)] public void OnWindowsIf_ShouldExecuteDependingOnOperatingSystem( - SimulationMode type, bool predicate, bool shouldExecute) + SimulationMode type, bool isNetFramework, bool predicate, bool shouldExecute) { bool isExecuted = false; - Execute sut = FromType(type); + Execute sut = FromType(type, isNetFramework); sut.OnWindowsIf(predicate, () => { isExecuted = true; }); @@ -193,8 +227,8 @@ public void OnWindowsIf_ShouldExecuteDependingOnOperatingSystem( #region Helpers #pragma warning disable CS0618 - private static Execute FromType(SimulationMode type) - => new(new MockFileSystem(), type); + private static Execute FromType(SimulationMode type, bool isNetFramework) + => new(new MockFileSystem(), type, isNetFramework); #pragma warning restore CS0618 #endregion diff --git a/Tests/Testably.Abstractions.Testing.Tests/Helpers/ExecuteTests.SimulatedPathTests.cs b/Tests/Testably.Abstractions.Testing.Tests/Helpers/ExecuteTests.SimulatedPathTests.cs new file mode 100644 index 000000000..d8aec5ae1 --- /dev/null +++ b/Tests/Testably.Abstractions.Testing.Tests/Helpers/ExecuteTests.SimulatedPathTests.cs @@ -0,0 +1,20 @@ +namespace Testably.Abstractions.Testing.Tests.Helpers; + +public sealed partial class ExecuteTests +{ + public sealed class SimulatedPathTests + { +#if CAN_SIMULATE_OTHER_OS + [Theory] + [InlineData(SimulationMode.Linux)] + [InlineData(SimulationMode.MacOS)] + [InlineData(SimulationMode.Windows)] + public void FileSystem_ShouldBeMockFileSystem(SimulationMode simulationMode) + { + MockFileSystem sut = new(o => o.SimulatingOperatingSystem(simulationMode)); + + sut.Execute.Path.FileSystem.Should().BeSameAs(sut); + } +#endif + } +} diff --git a/Tests/Testably.Abstractions.Testing.Tests/Helpers/ExecuteTests.cs b/Tests/Testably.Abstractions.Testing.Tests/Helpers/ExecuteTests.cs index dac7bae73..5719f389e 100644 --- a/Tests/Testably.Abstractions.Testing.Tests/Helpers/ExecuteTests.cs +++ b/Tests/Testably.Abstractions.Testing.Tests/Helpers/ExecuteTests.cs @@ -2,7 +2,7 @@ namespace Testably.Abstractions.Testing.Tests.Helpers; -public sealed class ExecuteTests +public sealed partial class ExecuteTests { [Fact] public void Constructor_ForLinux_ShouldInitializeAccordingly() @@ -45,4 +45,21 @@ public void Constructor_ForWindows_ShouldInitializeAccordingly() sut.IsWindows.Should().BeTrue(); sut.StringComparisonMode.Should().Be(StringComparison.OrdinalIgnoreCase); } + + [Fact] + public void Constructor_UnsupportedSimulationMode_ShouldThrowNotSupportedException() + { + Exception? exception = Record.Exception(() => + { + #pragma warning disable CS0618 + _ = new Execute(new MockFileSystem(), (SimulationMode)42); + #pragma warning restore CS0618 + }); + + exception.Should().BeOfType() + .Which.Message.Should() + .Contain(nameof(SimulationMode.Linux)).And + .Contain(nameof(SimulationMode.MacOS)).And + .Contain(nameof(SimulationMode.Windows)); + } } diff --git a/Tests/Testably.Abstractions.Testing.Tests/Helpers/PathHelperTests.cs b/Tests/Testably.Abstractions.Testing.Tests/Helpers/PathHelperTests.cs index 9e59c3028..e636981f9 100644 --- a/Tests/Testably.Abstractions.Testing.Tests/Helpers/PathHelperTests.cs +++ b/Tests/Testably.Abstractions.Testing.Tests/Helpers/PathHelperTests.cs @@ -120,7 +120,7 @@ public void .Which.Message.Should().Contain($"'{path}'"); } -#if !NETFRAMEWORK +#if CAN_SIMULATE_OTHER_OS [SkippableTheory] [InlineData('|')] [InlineData((char)1)] @@ -128,7 +128,7 @@ public void public void ThrowCommonExceptionsIfPathIsInvalid_WithInvalidCharacters( char invalidChar) { - MockFileSystem fileSystem = new(i => i + MockFileSystem fileSystem = new(o => o .SimulatingOperatingSystem(SimulationMode.Windows)); string path = invalidChar + "path"; diff --git a/Tests/Testably.Abstractions.Testing.Tests/MockFileSystemInitializationTests.cs b/Tests/Testably.Abstractions.Testing.Tests/MockFileSystemInitializationTests.cs index 75a26b864..ee413291c 100644 --- a/Tests/Testably.Abstractions.Testing.Tests/MockFileSystemInitializationTests.cs +++ b/Tests/Testably.Abstractions.Testing.Tests/MockFileSystemInitializationTests.cs @@ -7,7 +7,7 @@ namespace Testably.Abstractions.Testing.Tests; public class MockFileSystemInitializationTests { -#if !NETFRAMEWORK +#if CAN_SIMULATE_OTHER_OS [SkippableFact] public void MockFileSystem_WhenSimulatingLinux_ShouldBeLinux() { @@ -21,7 +21,7 @@ public void MockFileSystem_WhenSimulatingLinux_ShouldBeLinux() } #endif -#if !NETFRAMEWORK +#if CAN_SIMULATE_OTHER_OS [SkippableFact] public void MockFileSystem_WhenSimulatingMacOS_ShouldBeMac() { @@ -35,7 +35,7 @@ public void MockFileSystem_WhenSimulatingMacOS_ShouldBeMac() } #endif -#if !NETFRAMEWORK +#if CAN_SIMULATE_OTHER_OS [SkippableFact] public void MockFileSystem_WhenSimulatingWindows_ShouldBeWindows() { diff --git a/Tests/Testably.Abstractions.Testing.Tests/MockFileSystemTests.cs b/Tests/Testably.Abstractions.Testing.Tests/MockFileSystemTests.cs index 03aa6ce20..72f3441e1 100644 --- a/Tests/Testably.Abstractions.Testing.Tests/MockFileSystemTests.cs +++ b/Tests/Testably.Abstractions.Testing.Tests/MockFileSystemTests.cs @@ -92,7 +92,7 @@ public void FileSystemMock_ShouldBeInitializedWithADefaultDrive() drive.VolumeLabel.Should().NotBeNullOrEmpty(); } -#if NETFRAMEWORK +#if !CAN_SIMULATE_OTHER_OS [SkippableTheory] [InlineData(SimulationMode.Linux)] [InlineData(SimulationMode.MacOS)] @@ -103,7 +103,7 @@ public void FileSystemMock_ShouldNotSupportSimulatingOtherOperatingSystemsOnNetF Exception? exception = Record.Exception(() => { #pragma warning disable CS0618 - _ = new MockFileSystem(i => i.SimulatingOperatingSystem(simulationMode)); + _ = new MockFileSystem(o => o.SimulatingOperatingSystem(simulationMode)); #pragma warning restore CS0618 }); diff --git a/Tests/Testably.Abstractions.Testing.Tests/NotificationTests.cs b/Tests/Testably.Abstractions.Testing.Tests/NotificationTests.cs index e81b84fd0..9d6d1cac4 100644 --- a/Tests/Testably.Abstractions.Testing.Tests/NotificationTests.cs +++ b/Tests/Testably.Abstractions.Testing.Tests/NotificationTests.cs @@ -207,6 +207,23 @@ public void AwaitableCallback_TimeoutExpired_ShouldThrowTimeoutException() ms.Set(); } + [SkippableFact] + public void AwaitableCallback_Wait_AfterDispose_ShouldThrowObjectDisposedException() + { + MockTimeSystem timeSystem = new(); + Notification.IAwaitableCallback wait = + timeSystem.On.ThreadSleep(); + + wait.Dispose(); + + Exception? exception = Record.Exception(() => + { + wait.Wait(timeout: 100); + }); + + exception.Should().BeOfType(); + } + [SkippableFact] public void AwaitableCallback_WaitedPreviously_ShouldWaitAgainForCallbackExecution() { diff --git a/Tests/Testably.Abstractions.Tests/FileSystem/FileSystemInfo/ExceptionTests.cs b/Tests/Testably.Abstractions.Tests/FileSystem/FileSystemInfo/ExceptionTests.cs index 2bf860416..feb7100ab 100644 --- a/Tests/Testably.Abstractions.Tests/FileSystem/FileSystemInfo/ExceptionTests.cs +++ b/Tests/Testably.Abstractions.Tests/FileSystem/FileSystemInfo/ExceptionTests.cs @@ -45,10 +45,10 @@ public void Operations_WhenValueIsNull_ShouldThrowArgumentNullException( $"\n{callback}\n has `null` parameter for '{paramName}' (ignored: {ignoreParamCheck})"); } - #region Helpers + #region Helpers - #pragma warning disable MA0018 - public static TheoryData>, string, bool> + #pragma warning disable MA0018 + public static TheoryData>, string, bool> GetFileSystemInfoCallbacks(string? path) { TheoryData>, string, bool> theoryData = new(); @@ -68,7 +68,7 @@ public static TheoryData>, string, bool> } #pragma warning restore MA0018 - private static IEnumerable<(ExceptionTestHelper.TestTypes TestType, string ParamName, + private static IEnumerable<(ExceptionTestHelper.TestTypes TestType, string ParamName, Expression> Callback)> GetFileSystemInfoCallbackTestParameters(string value) { diff --git a/Tests/Testably.Abstractions.Tests/FileSystem/Path/GetExtensionTests.cs b/Tests/Testably.Abstractions.Tests/FileSystem/Path/GetExtensionTests.cs index d0190bbf3..bab9bbad7 100644 --- a/Tests/Testably.Abstractions.Tests/FileSystem/Path/GetExtensionTests.cs +++ b/Tests/Testably.Abstractions.Tests/FileSystem/Path/GetExtensionTests.cs @@ -51,25 +51,25 @@ public void GetExtension_Span_ShouldReturnExtensionWithLeadingDot( [SkippableTheory] [AutoData] - public void GetExtension_TrailingDot_ShouldReturnEmptyString( + public void GetExtension_StartingDot_ShouldReturnCompleteFileName( string directory, string filename) { - string path = directory + FileSystem.Path.DirectorySeparatorChar + filename + "."; + string path = directory + FileSystem.Path.DirectorySeparatorChar + "." + filename; string result = FileSystem.Path.GetExtension(path); - result.Should().Be(""); + result.Should().Be("." + filename); } [SkippableTheory] [AutoData] - public void GetExtension_StartingDot_ShouldReturnCompleteFileName( + public void GetExtension_TrailingDot_ShouldReturnEmptyString( string directory, string filename) { - string path = directory + FileSystem.Path.DirectorySeparatorChar + "." + filename; + string path = directory + FileSystem.Path.DirectorySeparatorChar + filename + "."; string result = FileSystem.Path.GetExtension(path); - result.Should().Be("." + filename); + result.Should().Be(""); } } diff --git a/Tests/Testably.Abstractions.Tests/FileSystem/Path/GetFullPathTests.cs b/Tests/Testably.Abstractions.Tests/FileSystem/Path/GetFullPathTests.cs index a25289ec2..9309051b0 100644 --- a/Tests/Testably.Abstractions.Tests/FileSystem/Path/GetFullPathTests.cs +++ b/Tests/Testably.Abstractions.Tests/FileSystem/Path/GetFullPathTests.cs @@ -15,6 +15,28 @@ public void GetFullPath_Dot_ShouldReturnToCurrentDirectory() result.Should().Be(expectedFullPath); } + [SkippableTheory] + [InlineData(@"C:\foo", @"C:\foo", TestOS.Windows)] + [InlineData(@"C:\foo\", @"C:\foo\", TestOS.Windows)] + [InlineData(@"\\?\foo", @"\\?\foo", TestOS.Windows)] + [InlineData(@"\??\BAR", @"\??\BAR", TestOS.Windows)] + [InlineData("/foo", "/foo", TestOS.Linux | TestOS.Mac)] + [InlineData("/foo/", "/foo/", TestOS.Linux | TestOS.Mac)] + public void GetFullPath_EdgeCases_ShouldReturnExpectedValue(string path, + string expected, TestOS operatingSystem) + { + Skip.IfNot(Test.RunsOn(operatingSystem)); + + if (operatingSystem == TestOS.All) + { + expected = expected.Replace('/', FileSystem.Path.DirectorySeparatorChar); + } + + string result = FileSystem.Path.GetFullPath(path); + + result.Should().Be(expected); + } + #if FEATURE_PATH_RELATIVE [SkippableFact] public void GetFullPath_Relative_NullBasePath_ShouldThrowArgumentNullException() @@ -66,6 +88,23 @@ public void GetFullPath_Relative_ShouldNormalizeProvidedPath(string input, strin } #endif +#if FEATURE_PATH_RELATIVE + [SkippableTheory] + [InlineData(@"C:\top\..\most\file", @"C:\foo\bar", @"C:\most\file", TestOS.Windows)] + [InlineData(@"C:\top\..\most\file", @"D:\foo\bar", @"C:\most\file", TestOS.Windows)] + [InlineData("/top/../most/file", "/foo/bar", "/most/file", TestOS.Linux | TestOS.Mac)] + public void GetFullPath_Relative_WithRootedPath_ShouldIgnoreBasePath( + string path, string basePath, string expected, TestOS operatingSystem) + { + Skip.IfNot(Test.RunsOn(operatingSystem)); + + string result = FileSystem.Path + .GetFullPath(path, basePath); + + result.Should().Be(expected); + } +#endif + [SkippableFact] public void GetFullPath_RelativePathWithDrive_ShouldReturnExpectedValue() { diff --git a/Tests/Testably.Abstractions.Tests/FileSystem/Path/GetPathRootTests.cs b/Tests/Testably.Abstractions.Tests/FileSystem/Path/GetPathRootTests.cs index ae832a11a..b66b759ca 100644 --- a/Tests/Testably.Abstractions.Tests/FileSystem/Path/GetPathRootTests.cs +++ b/Tests/Testably.Abstractions.Tests/FileSystem/Path/GetPathRootTests.cs @@ -28,7 +28,8 @@ public void GetPathRoot_RootedDrive_ShouldReturnDriveOnWindows(string path) [SkippableTheory] [InlineData("D:some-path", "D:")] [InlineData("D:\\some-path", "D:\\")] - public void GetPathRoot_RootedDriveWithPath_ShouldReturnDriveOnWindows(string path, string expected) + public void GetPathRoot_RootedDriveWithPath_ShouldReturnDriveOnWindows( + string path, string expected) { Skip.IfNot(Test.RunsOnWindows); @@ -43,7 +44,7 @@ public void GetPathRoot_ShouldReturnDefaultValue(string path) { string? result = FileSystem.Path.GetPathRoot(path); - result.Should().Be(System.IO.Path.GetPathRoot(path)); + result.Should().Be(""); } #if FEATURE_SPAN diff --git a/Tests/Testably.Abstractions.Tests/FileSystem/Path/GetRelativePathTests.cs b/Tests/Testably.Abstractions.Tests/FileSystem/Path/GetRelativePathTests.cs index 45f605465..17a607e83 100644 --- a/Tests/Testably.Abstractions.Tests/FileSystem/Path/GetRelativePathTests.cs +++ b/Tests/Testably.Abstractions.Tests/FileSystem/Path/GetRelativePathTests.cs @@ -40,12 +40,18 @@ public void GetRelativePath_DifferentDrives_ShouldReturnAbsolutePath( [InlineData("/FOO", "/foo", "../foo", TestOS.Linux)] [InlineData("/FOO", "/foo", ".", TestOS.Mac)] [InlineData("foo", "foo/", ".", TestOS.All)] + [InlineData("foo/", "foo/", ".", TestOS.All)] [InlineData(@"C:\Foo", @"C:\Bar", @"..\Bar", TestOS.Windows)] + [InlineData(@"C:\Foo", @"C:\Bar\", @"..\Bar\", TestOS.Windows)] [InlineData(@"C:\Foo", @"C:\Foo\Bar", "Bar", TestOS.Windows)] + [InlineData(@"C:\Foo\Bar", @"C:\Foo\", "..", TestOS.Windows)] + [InlineData(@"C:\Foo", @"C:\Foo\Bar\", @"Bar\", TestOS.Windows)] [InlineData(@"C:\Foo\Bar", @"C:\Bar\Bar", @"..\..\Bar\Bar", TestOS.Windows)] [InlineData(@"C:\Foo\Foo", @"C:\Foo\Bar", @"..\Bar", TestOS.Windows)] [InlineData("/Foo", "/Bar", "../Bar", TestOS.Linux | TestOS.Mac)] + [InlineData("/Foo", "/Bar/", "../Bar/", TestOS.Linux | TestOS.Mac)] [InlineData("/Foo", "/Foo/Bar", "Bar", TestOS.Linux | TestOS.Mac)] + [InlineData("/Foo", "/Foo/Bar/", "Bar/", TestOS.Linux | TestOS.Mac)] [InlineData("/Foo/Bar", "/Bar/Bar", "../../Bar/Bar", TestOS.Linux | TestOS.Mac)] [InlineData("/Foo/Foo", "/Foo/Bar", "../Bar", TestOS.Linux | TestOS.Mac)] public void GetRelativePath_EdgeCases_ShouldReturnExpectedValue(string relativeTo, string path, diff --git a/Tests/Testably.Abstractions.Tests/FileSystem/Path/IsPathFullyQualifiedTests.cs b/Tests/Testably.Abstractions.Tests/FileSystem/Path/IsPathFullyQualifiedTests.cs index a72d88253..0e8483e59 100644 --- a/Tests/Testably.Abstractions.Tests/FileSystem/Path/IsPathFullyQualifiedTests.cs +++ b/Tests/Testably.Abstractions.Tests/FileSystem/Path/IsPathFullyQualifiedTests.cs @@ -6,6 +6,25 @@ public abstract partial class IsPathFullyQualifiedTests : FileSystemTestBase where TFileSystem : IFileSystem { + [SkippableTheory] + [InlineData("C", false, TestOS.Windows)] + [InlineData("//", true, TestOS.All)] + [InlineData("/Foo", true, TestOS.Linux | TestOS.Mac)] + [InlineData("/Foo", false, TestOS.Windows)] + [InlineData(@"\\", true, TestOS.Windows)] + [InlineData("/?", true, TestOS.Windows)] + [InlineData(@"\?", true, TestOS.Windows)] + public void IsPathFullyQualified_EdgeCases_ShouldReturnExpectedValue( + string path, bool expected, TestOS operatingSystem) + { + Skip.IfNot(Test.RunsOn(operatingSystem)); + + bool result = FileSystem.Path + .IsPathFullyQualified(path); + + result.Should().Be(expected); + } + [SkippableTheory] [AutoData] public void IsPathFullyQualified_PrefixedRoot_ShouldReturnTrue( diff --git a/Tests/Testably.Abstractions.Tests/RandomSystem/GuidTests.cs b/Tests/Testably.Abstractions.Tests/RandomSystem/GuidTests.cs index f86052f1b..5bec1aff5 100644 --- a/Tests/Testably.Abstractions.Tests/RandomSystem/GuidTests.cs +++ b/Tests/Testably.Abstractions.Tests/RandomSystem/GuidTests.cs @@ -1,8 +1,8 @@ +using System.Collections.Concurrent; +using System.Threading.Tasks; #if FEATURE_GUID_PARSE using System.Collections.Generic; #endif -using System.Collections.Concurrent; -using System.Threading.Tasks; #if FEATURE_GUID_FORMATPROVIDER using System.Globalization; #endif @@ -41,10 +41,10 @@ public void Parse_SpanArray_ShouldReturnCorrectGuid(Guid guid) ReadOnlySpan serializedGuid = guid.ToString().AsSpan(); #pragma warning disable MA0011 - Guid result = RandomSystem.Guid.Parse(serializedGuid); - #pragma warning restore MA0011 + Guid result = RandomSystem.Guid.Parse(serializedGuid); + #pragma warning restore MA0011 - result.Should().Be(guid); + result.Should().Be(guid); } #endif @@ -56,10 +56,10 @@ public void Parse_String_ShouldReturnCorrectGuid(Guid guid) string serializedGuid = guid.ToString(); #pragma warning disable MA0011 - Guid result = RandomSystem.Guid.Parse(serializedGuid); - #pragma warning restore MA0011 + Guid result = RandomSystem.Guid.Parse(serializedGuid); + #pragma warning restore MA0011 - result.Should().Be(guid); + result.Should().Be(guid); } #endif @@ -124,10 +124,10 @@ public void TryParse_SpanArray_ShouldReturnTrue(Guid guid) ReadOnlySpan serializedGuid = guid.ToString().AsSpan(); #pragma warning disable MA0011 - bool result = RandomSystem.Guid.TryParse(serializedGuid, out Guid value); - #pragma warning restore MA0011 + bool result = RandomSystem.Guid.TryParse(serializedGuid, out Guid value); + #pragma warning restore MA0011 - result.Should().BeTrue(); + result.Should().BeTrue(); value.Should().Be(guid); } #endif @@ -140,10 +140,10 @@ public void TryParse_String_ShouldReturnTrue(Guid guid) string serializedGuid = guid.ToString(); #pragma warning disable MA0011 - bool result = RandomSystem.Guid.TryParse(serializedGuid, out Guid value); - #pragma warning restore MA0011 + bool result = RandomSystem.Guid.TryParse(serializedGuid, out Guid value); + #pragma warning restore MA0011 - result.Should().BeTrue(); + result.Should().BeTrue(); value.Should().Be(guid); } #endif diff --git a/Tests/Testably.Abstractions.Tests/TestHelpers/TestExtensions.cs b/Tests/Testably.Abstractions.Tests/TestHelpers/TestExtensions.cs index be04d276a..a05a512c4 100644 --- a/Tests/Testably.Abstractions.Tests/TestHelpers/TestExtensions.cs +++ b/Tests/Testably.Abstractions.Tests/TestHelpers/TestExtensions.cs @@ -20,6 +20,7 @@ public static T DependsOnOS(this Test test, T windows, T macOS, T linux) public static bool RunsOn(this Test test, TestOS operatingSystem) => (operatingSystem.HasFlag(TestOS.Linux) && test.RunsOnLinux) || (operatingSystem.HasFlag(TestOS.Mac) && test.RunsOnMac) || - (operatingSystem.HasFlag(TestOS.Windows) && test is { RunsOnWindows: true, IsNetFramework: false }) || + (operatingSystem.HasFlag(TestOS.Windows) && + test is { RunsOnWindows: true, IsNetFramework: false }) || (operatingSystem.HasFlag(TestOS.Framework) && test.IsNetFramework); }