diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7fcaf9cdb..c7f9bd098 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -21,7 +21,7 @@ jobs: with: distribution: 'temurin' java-version: '17' - - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4 + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 with: fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - name: Cache SonarCloud packages @@ -66,7 +66,7 @@ jobs: runs-on: macos-latest steps: - name: Checkout sources - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 with: fetch-depth: 0 - name: Setup .NET @@ -94,7 +94,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout sources - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 with: fetch-depth: 0 - name: Setup .NET @@ -122,7 +122,7 @@ jobs: runs-on: windows-latest steps: - name: Checkout sources - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 with: fetch-depth: 0 - name: Setup .NET @@ -150,7 +150,7 @@ jobs: runs-on: windows-latest steps: - name: Checkout sources - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 with: fetch-depth: 0 - name: Setup .NET @@ -176,7 +176,7 @@ jobs: runs-on: windows-latest steps: - name: Checkout sources - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 with: fetch-depth: 0 - name: Setup .NET @@ -202,7 +202,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout sources - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 with: fetch-depth: 0 - name: Download code coverage files (MacOS) diff --git a/.github/workflows/ci-stryker.yml b/.github/workflows/ci-stryker.yml index a5aec4b74..ecdad6e24 100644 --- a/.github/workflows/ci-stryker.yml +++ b/.github/workflows/ci-stryker.yml @@ -10,7 +10,7 @@ jobs: timeout-minutes: 300 steps: - name: Checkout sources - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 with: fetch-depth: 0 - name: Setup .NET diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1a5eb6f8f..bbb561aff 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,7 +11,7 @@ jobs: runs-on: macos-latest steps: - name: Checkout sources - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 with: fetch-depth: 0 - name: Setup .NET @@ -45,7 +45,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout sources - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 with: fetch-depth: 0 - name: Setup .NET @@ -79,7 +79,7 @@ jobs: runs-on: windows-latest steps: - name: Checkout sources - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 with: fetch-depth: 0 - name: Setup .NET @@ -113,7 +113,7 @@ jobs: runs-on: windows-latest steps: - name: Checkout sources - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 with: fetch-depth: 0 - name: Setup MSBuild @@ -138,7 +138,7 @@ jobs: runs-on: windows-latest steps: - name: Checkout sources - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 with: fetch-depth: 0 - name: Save PR number to file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4824ebdab..a22450f53 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -22,7 +22,7 @@ jobs: with: distribution: 'temurin' java-version: '17' - - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4 + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 with: fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - name: Tag current commit @@ -72,7 +72,7 @@ jobs: runs-on: macos-latest steps: - name: Checkout sources - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 with: fetch-depth: 0 - name: Tag current commit @@ -100,7 +100,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout sources - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 with: fetch-depth: 0 - name: Tag current commit @@ -128,7 +128,7 @@ jobs: runs-on: windows-latest steps: - name: Checkout sources - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 with: fetch-depth: 0 - name: Tag current commit @@ -156,7 +156,7 @@ jobs: runs-on: windows-latest steps: - name: Checkout sources - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 with: fetch-depth: 0 - name: Tag current commit @@ -180,7 +180,7 @@ jobs: runs-on: windows-latest steps: - name: Checkout sources - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 with: fetch-depth: 0 - name: Tag current commit @@ -211,7 +211,7 @@ jobs: timeout-minutes: 300 steps: - name: Checkout sources - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 with: fetch-depth: 0 - name: Setup .NET @@ -239,7 +239,7 @@ jobs: timeout-minutes: 300 steps: - name: Checkout sources - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 with: fetch-depth: 0 - name: Setup .NET @@ -282,7 +282,7 @@ jobs: needs: [analyze, test-macos, test-ubuntu, test-windows, test-net-framework, test-examples] steps: - name: Checkout sources - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 with: fetch-depth: 0 - name: Tag current commit @@ -348,7 +348,7 @@ jobs: label-template: | state: released - name: Checkout sources - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 with: fetch-depth: 0 - name: Delete release branch diff --git a/.github/workflows/stryker.yml b/.github/workflows/stryker.yml index cf2c9642e..d087953f7 100644 --- a/.github/workflows/stryker.yml +++ b/.github/workflows/stryker.yml @@ -12,7 +12,7 @@ jobs: timeout-minutes: 300 steps: - name: Checkout sources - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 with: fetch-depth: 0 - name: Setup .NET @@ -40,7 +40,7 @@ jobs: timeout-minutes: 300 steps: - name: Checkout sources - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 with: fetch-depth: 0 - name: Setup .NET diff --git a/Directory.Packages.props b/Directory.Packages.props index 5d40dedab..1ea20beac 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -28,8 +28,8 @@ - - + + diff --git a/Source/Testably.Abstractions.Testing/FileSystem/PathMock.cs b/Source/Testably.Abstractions.Testing/FileSystem/PathMock.cs index f1789cb4c..5d7a7a03e 100644 --- a/Source/Testably.Abstractions.Testing/FileSystem/PathMock.cs +++ b/Source/Testably.Abstractions.Testing/FileSystem/PathMock.cs @@ -37,6 +37,21 @@ public override string GetFullPath(string path) { path.EnsureValidArgument(FileSystem, nameof(path)); + string? pathRoot = Path.GetPathRoot(path); + string? directoryRoot = Path.GetPathRoot(_fileSystem.Storage.CurrentDirectory); + if (!string.IsNullOrEmpty(pathRoot) && !string.IsNullOrEmpty(directoryRoot)) + { + if (char.ToUpperInvariant(pathRoot[0]) != char.ToUpperInvariant(directoryRoot[0])) + { + return Path.GetFullPath(path); + } + + if (pathRoot.Length < directoryRoot.Length) + { + path = path.Substring(pathRoot.Length); + } + } + return Path.GetFullPath(Path.Combine( _fileSystem.Storage.CurrentDirectory, path)); diff --git a/Source/Testably.Abstractions.Testing/Storage/InMemoryStorage.cs b/Source/Testably.Abstractions.Testing/Storage/InMemoryStorage.cs index f85f45beb..12d5e9be5 100644 --- a/Source/Testably.Abstractions.Testing/Storage/InMemoryStorage.cs +++ b/Source/Testably.Abstractions.Testing/Storage/InMemoryStorage.cs @@ -173,6 +173,7 @@ public IEnumerable EnumerateLocations( enumerationOptions ??= EnumerationOptionsHelper.Compatible; string fullPath = location.FullPath; + string fullPathWithoutTrailingSlash = fullPath; #if NETSTANDARD2_0 if (!fullPath.EndsWith($"{_fileSystem.Path.DirectorySeparatorChar}")) #else @@ -181,6 +182,10 @@ public IEnumerable EnumerateLocations( { fullPath += _fileSystem.Path.DirectorySeparatorChar; } + else if (_fileSystem.Path.GetPathRoot(fullPath) != fullPath) + { + fullPathWithoutTrailingSlash = fullPathWithoutTrailingSlash.TrimEnd(_fileSystem.Path.DirectorySeparatorChar); + } foreach (KeyValuePair item in _containers .Where(x => x.Key.FullPath.StartsWith(fullPath, @@ -192,7 +197,7 @@ public IEnumerable EnumerateLocations( item.Key.FullPath.TrimEnd(_fileSystem.Path .DirectorySeparatorChar)); if (!enumerationOptions.RecurseSubdirectories && - parentPath?.Equals(location.FullPath, + parentPath?.Equals(fullPathWithoutTrailingSlash, InMemoryLocation.StringComparisonMode) != true) { continue; diff --git a/Tests/Testably.Abstractions.Tests/FileSystem/Directory/EnumerateDirectoriesTests.cs b/Tests/Testably.Abstractions.Tests/FileSystem/Directory/EnumerateDirectoriesTests.cs index 179f5b011..cd1593bcf 100644 --- a/Tests/Testably.Abstractions.Tests/FileSystem/Directory/EnumerateDirectoriesTests.cs +++ b/Tests/Testably.Abstractions.Tests/FileSystem/Directory/EnumerateDirectoriesTests.cs @@ -246,4 +246,16 @@ public void result.Count().Should().Be(2); } + + [SkippableFact] + public void EnumerateDirectories_WithTrailingSlash_ShouldEnumerateSubdirectories() + { + string queryPath = @"foo" + FileSystem.Path.DirectorySeparatorChar; + string expectedPath = FileSystem.Path.Combine("foo", "bar"); + FileSystem.Directory.CreateDirectory(expectedPath); + + IEnumerable actualResult = FileSystem.Directory.EnumerateDirectories(queryPath); + + actualResult.Should().BeEquivalentTo(expectedPath); + } } diff --git a/Tests/Testably.Abstractions.Tests/FileSystem/Path/GetFullPathTests.cs b/Tests/Testably.Abstractions.Tests/FileSystem/Path/GetFullPathTests.cs index 9b6e8daec..2ffecf0de 100644 --- a/Tests/Testably.Abstractions.Tests/FileSystem/Path/GetFullPathTests.cs +++ b/Tests/Testably.Abstractions.Tests/FileSystem/Path/GetFullPathTests.cs @@ -5,6 +5,49 @@ public abstract partial class GetFullPathTests : FileSystemTestBase where TFileSystem : IFileSystem { + [SkippableFact] + public void GetFullPath_Dot_ShouldReturnToCurrentDirectory() + { + string expectedFullPath = FileSystem.Directory.GetCurrentDirectory(); + + string result = FileSystem.Path.GetFullPath("."); + + result.Should().Be(expectedFullPath); + } + + [SkippableFact] + public void GetFullPath_RelativePathWithDrive_ShouldReturnExpectedValue() + { + Skip.IfNot(Test.RunsOnWindows); + + string currentDirectory = FileSystem.Directory.GetCurrentDirectory(); + string drive = currentDirectory.Substring(0, 1); + string input = $"{drive}:test.txt"; + string expectedFullPath = FileSystem.Path.Combine(currentDirectory, "test.txt"); + + string result = FileSystem.Path.GetFullPath(input); + + result.Should().Be(expectedFullPath); + } + + [SkippableFact] + public void + GetFullPath_RelativePathWithDrive_WhenCurrentDirectoryIsDifferent_ShouldReturnExpectedValue() + { + Skip.IfNot(Test.RunsOnWindows); + + string currentDirectory = FileSystem.Directory.GetCurrentDirectory(); + string otherDrive = currentDirectory + .Substring(0,1) + .Equals("x", StringComparison.OrdinalIgnoreCase) ? "Y" : "X"; + string input = $"{otherDrive}:test.txt"; + string expectedFullPath = $@"{otherDrive}:\test.txt"; + + string result = FileSystem.Path.GetFullPath(input); + + result.Should().Be(expectedFullPath); + } + [SkippableTheory] [InlineData(@"top/../most/file", @"most/file")] [InlineData(@"top/../most/../dir/file", @"dir/file")]