Skip to content

Implement better way to test for in-memory file #645

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Mar 25, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 20 additions & 12 deletions src/PowerShellEditorServices/Workspace/Workspace.cs
Original file line number Diff line number Diff line change
Expand Up @@ -390,22 +390,30 @@ internal static bool IsPathInMemory(string filePath)
// view of the current file or an untitled file.
try
{
// NotSupportedException or ArgumentException gets thrown when
// given an invalid path. Since any non-standard path will
// trigger this, assume that it means it's an in-memory file
// unless the path starts with file:
Path.GetFullPath(filePath);
// File system absoulute paths will have a URI scheme of file:.
// Other schemes like "untitled:" and "gitlens-git:" will return false for IsFile.
var uri = new Uri(filePath);
isInMemory = !uri.IsFile;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: maybe combine these into 1 line since uri isn't used? I don't feel strongly either way but it's something I thought about.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having uri as a variable makes it easier to inspect the entire URI when debugging - not just the resulting string.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point 👍

}
catch (ArgumentException)
catch (UriFormatException)
{
isInMemory = true;
}
catch (NotSupportedException)
{
isInMemory = true;
// Relative file paths cause a UriFormatException.
// In this case, fallback to using Path.GetFullPath().
try
{
Path.GetFullPath(filePath);
}
catch (Exception ex) when (ex is ArgumentException || ex is NotSupportedException)
{
isInMemory = true;
}
catch (PathTooLongException)
{
// If we ever get here, it should be an actual file so, not in memory
}
}

return !filePath.ToLower().StartsWith("file:") && isInMemory;
return isInMemory;
}

private string GetBaseFilePath(string filePath)
Expand Down
40 changes: 37 additions & 3 deletions test/PowerShellEditorServices.Test/Session/WorkspaceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//

using Microsoft.PowerShell.EditorServices;
using System;
using System.IO;
using System.Linq;
using Xunit;
using Microsoft.PowerShell.EditorServices.Utility;
using Xunit;

namespace Microsoft.PowerShell.EditorServices.Test.Session
{
Expand All @@ -35,5 +33,41 @@ public void CanResolveWorkspaceRelativePath()
Assert.Equal(@"..\PeerPath\FilePath.ps1", workspace.GetRelativePath(testPathOutside));
Assert.Equal(testPathAnotherDrive, workspace.GetRelativePath(testPathAnotherDrive));
}

[Fact]
public void CanDetermineIsPathInMemory()
{
var tempDir = Environment.GetEnvironmentVariable("TEMP");
var shortDirPath = Path.Combine(tempDir, "GitHub", "PowerShellEditorServices");
var shortFilePath = Path.Combine(shortDirPath, "foo.ps1");
var shortUriForm = "git:/c%3A/Users/Keith/GitHub/dahlbyk/posh-git/src/PoshGitTypes.ps1?%7B%22path%22%3A%22c%3A%5C%5CUsers%5C%5CKeith%5C%5CGitHub%5C%5Cdahlbyk%5C%5Cposh-git%5C%5Csrc%5C%5CPoshGitTypes.ps1%22%2C%22ref%22%3A%22~%22%7D";
var longUriForm = "gitlens-git:c%3A%5CUsers%5CKeith%5CGitHub%5Cdahlbyk%5Cposh-git%5Csrc%5CPoshGitTypes%3Ae0022701.ps1?%7B%22fileName%22%3A%22src%2FPoshGitTypes.ps1%22%2C%22repoPath%22%3A%22c%3A%2FUsers%2FKeith%2FGitHub%2Fdahlbyk%2Fposh-git%22%2C%22sha%22%3A%22e0022701fa12e0bc22d0458673d6443c942b974a%22%7D";

var testCases = new[] {
// Test short file absolute paths
new { IsInMemory = false, Path = shortDirPath },
new { IsInMemory = false, Path = shortFilePath },
new { IsInMemory = false, Path = new Uri(shortDirPath).ToString() },
new { IsInMemory = false, Path = new Uri(shortFilePath).ToString() },

// Test short file relative paths - not sure we'll ever get these but just in case
new { IsInMemory = false, Path = "foo.ps1" },
new { IsInMemory = false, Path = ".." + Path.DirectorySeparatorChar + "foo.ps1" },

// Test short non-file paths
new { IsInMemory = true, Path = "untitled:untitled-1" },
new { IsInMemory = true, Path = shortUriForm },

// Test long non-file path - known to have crashed PSES
new { IsInMemory = true, Path = longUriForm },
};

foreach (var testCase in testCases)
{
Assert.True(
Workspace.IsPathInMemory(testCase.Path) == testCase.IsInMemory,
$"Testing path {testCase.Path}");
}
}
}
}