Add support for base path in FindHiearchicalItems
Required for https://github.com/aspnet/Mvc/issues/5915
This commit is contained in:
parent
7d43bfc709
commit
2fc88fe9c1
|
|
@ -39,8 +39,27 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
||||||
/// e.g.
|
/// e.g.
|
||||||
/// /Views/Home/View.cshtml -> [ /Views/Home/FileName.cshtml, /Views/FileName.cshtml, /FileName.cshtml ]
|
/// /Views/Home/View.cshtml -> [ /Views/Home/FileName.cshtml, /Views/FileName.cshtml, /FileName.cshtml ]
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public virtual IEnumerable<RazorProjectItem> FindHierarchicalItems(string path, string fileName)
|
public IEnumerable<RazorProjectItem> FindHierarchicalItems(string path, string fileName)
|
||||||
{
|
{
|
||||||
|
return FindHierarchicalItems(basePath: "/", path: path, fileName: fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the sequence of files named <paramref name="fileName"/> that are applicable to the specified path.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="basePath">The base path.</param>
|
||||||
|
/// <param name="path">The path of a project item.</param>
|
||||||
|
/// <param name="fileName">The file name to seek.</param>
|
||||||
|
/// <returns>A sequence of applicable <see cref="RazorProjectItem"/> instances.</returns>
|
||||||
|
/// <remarks>
|
||||||
|
/// This method returns paths starting from the directory of <paramref name="path"/> and
|
||||||
|
/// traverses to the <paramref name="basePath"/>.
|
||||||
|
/// e.g.
|
||||||
|
/// (/Views, /Views/Home/View.cshtml) -> [ /Views/Home/FileName.cshtml, /Views/FileName.cshtml ]
|
||||||
|
/// </remarks>
|
||||||
|
public virtual IEnumerable<RazorProjectItem> FindHierarchicalItems(string basePath, string path, string fileName)
|
||||||
|
{
|
||||||
|
EnsureValidPath(basePath);
|
||||||
EnsureValidPath(path);
|
EnsureValidPath(path);
|
||||||
if (string.IsNullOrEmpty(fileName))
|
if (string.IsNullOrEmpty(fileName))
|
||||||
{
|
{
|
||||||
|
|
@ -53,6 +72,11 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
||||||
yield break;
|
yield break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!path.StartsWith(basePath, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
yield break;
|
||||||
|
}
|
||||||
|
|
||||||
StringBuilder builder;
|
StringBuilder builder;
|
||||||
var fileNameIndex = path.LastIndexOf('/');
|
var fileNameIndex = path.LastIndexOf('/');
|
||||||
var length = path.Length;
|
var length = path.Length;
|
||||||
|
|
@ -69,8 +93,9 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
||||||
builder = new StringBuilder(path);
|
builder = new StringBuilder(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var maxDepth = 255;
|
||||||
var index = length;
|
var index = length;
|
||||||
while (index > 0 && (index = path.LastIndexOf('/', index - 1)) != -1)
|
while (maxDepth-- > 0 && index > basePath.Length && (index = path.LastIndexOf('/', index - 1)) != -1)
|
||||||
{
|
{
|
||||||
builder.Length = index + 1;
|
builder.Length = index + 1;
|
||||||
builder.Append(fileName);
|
builder.Append(fileName);
|
||||||
|
|
|
||||||
|
|
@ -188,6 +188,127 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("/Areas")]
|
||||||
|
[InlineData("/Areas/")]
|
||||||
|
public void FindHierarchicalItems_WithBasePath(string basePath)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var path = "/Areas/MyArea/Views/Home/Test.cshtml";
|
||||||
|
var items = new Dictionary<string, RazorProjectItem>
|
||||||
|
{
|
||||||
|
{ "/Areas/MyArea/File.cshtml", CreateProjectItem("/Areas/MyArea/File.cshtml") },
|
||||||
|
{ "/File.cshtml", CreateProjectItem("/File.cshtml") },
|
||||||
|
};
|
||||||
|
var project = new TestRazorProject(items);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = project.FindHierarchicalItems(basePath, path, "File.cshtml");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Collection(
|
||||||
|
result,
|
||||||
|
item =>
|
||||||
|
{
|
||||||
|
Assert.Equal("/Areas/MyArea/Views/Home/File.cshtml", item.Path);
|
||||||
|
Assert.False(item.Exists);
|
||||||
|
},
|
||||||
|
item =>
|
||||||
|
{
|
||||||
|
Assert.Equal("/Areas/MyArea/Views/File.cshtml", item.Path);
|
||||||
|
Assert.False(item.Exists);
|
||||||
|
},
|
||||||
|
item =>
|
||||||
|
{
|
||||||
|
Assert.Equal("/Areas/MyArea/File.cshtml", item.Path);
|
||||||
|
Assert.True(item.Exists);
|
||||||
|
},
|
||||||
|
item =>
|
||||||
|
{
|
||||||
|
Assert.Equal("/Areas/File.cshtml", item.Path);
|
||||||
|
Assert.False(item.Exists);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("/Areas/MyArea/Views")]
|
||||||
|
[InlineData("/Areas/MyArea/Views/")]
|
||||||
|
public void FindHierarchicalItems_WithNestedBasePath(string basePath)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var path = "/Areas/MyArea/Views/Home/Test.cshtml";
|
||||||
|
var items = new Dictionary<string, RazorProjectItem>
|
||||||
|
{
|
||||||
|
{ "/Areas/MyArea/File.cshtml", CreateProjectItem("/Areas/MyArea/File.cshtml") },
|
||||||
|
{ "/File.cshtml", CreateProjectItem("/File.cshtml") },
|
||||||
|
};
|
||||||
|
var project = new TestRazorProject(items);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = project.FindHierarchicalItems(basePath, path, "File.cshtml");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Collection(
|
||||||
|
result,
|
||||||
|
item =>
|
||||||
|
{
|
||||||
|
Assert.Equal("/Areas/MyArea/Views/Home/File.cshtml", item.Path);
|
||||||
|
Assert.False(item.Exists);
|
||||||
|
},
|
||||||
|
item =>
|
||||||
|
{
|
||||||
|
Assert.Equal("/Areas/MyArea/Views/File.cshtml", item.Path);
|
||||||
|
Assert.False(item.Exists);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("/Areas/MyArea/Views/Home")]
|
||||||
|
[InlineData("/Areas/MyArea/Views/Home/")]
|
||||||
|
public void FindHierarchicalItems_WithFileAtBasePath(string basePath)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var path = "/Areas/MyArea/Views/Home/Test.cshtml";
|
||||||
|
var items = new Dictionary<string, RazorProjectItem>
|
||||||
|
{
|
||||||
|
{ "/Areas/MyArea/File.cshtml", CreateProjectItem("/Areas/MyArea/File.cshtml") },
|
||||||
|
{ "/File.cshtml", CreateProjectItem("/File.cshtml") },
|
||||||
|
};
|
||||||
|
var project = new TestRazorProject(items);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = project.FindHierarchicalItems(basePath, path, "File.cshtml");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Collection(
|
||||||
|
result,
|
||||||
|
item =>
|
||||||
|
{
|
||||||
|
Assert.Equal("/Areas/MyArea/Views/Home/File.cshtml", item.Path);
|
||||||
|
Assert.False(item.Exists);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void FindHierarchicalItems_ReturnsEmptySequenceIfPathIsNotASubPathOfBasePath()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var basePath = "/Pages";
|
||||||
|
var path = "/Areas/MyArea/Views/Home/Test.cshtml";
|
||||||
|
var items = new Dictionary<string, RazorProjectItem>
|
||||||
|
{
|
||||||
|
{ "/Areas/MyArea/File.cshtml", CreateProjectItem("/Areas/MyArea/File.cshtml") },
|
||||||
|
{ "/File.cshtml", CreateProjectItem("/File.cshtml") },
|
||||||
|
};
|
||||||
|
var project = new TestRazorProject(items);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = project.FindHierarchicalItems(basePath, path, "File.cshtml");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Empty(result);
|
||||||
|
}
|
||||||
|
|
||||||
private RazorProjectItem CreateProjectItem(string path)
|
private RazorProjectItem CreateProjectItem(string path)
|
||||||
{
|
{
|
||||||
var projectItem = new Mock<RazorProjectItem>();
|
var projectItem = new Mock<RazorProjectItem>();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue