Updating ViewStartUtility to use IFileSystem.TryGetParentPath
This commit is contained in:
parent
103693b61c
commit
df0b33a378
|
|
@ -52,18 +52,16 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
|
|||
/// </summary>
|
||||
/// <param name="razorHost">The <see cref="MvcRazorHost"/> used to parse _ViewStart pages.</param>
|
||||
/// <param name="fileSystem">The filesystem that represents the application.</param>
|
||||
/// <param name="appRoot">The root of the application.</param>
|
||||
/// <param name="pagePath">The path of the page to locate inherited chunks for.</param>
|
||||
/// <returns>A list of chunks that are applicable to the given page.</returns>
|
||||
public List<Chunk> GetInheritedChunks([NotNull] MvcRazorHost razorHost,
|
||||
[NotNull] IFileSystem fileSystem,
|
||||
[NotNull] string appRoot,
|
||||
[NotNull] string pagePath)
|
||||
{
|
||||
var inheritedChunks = new List<Chunk>();
|
||||
|
||||
var templateEngine = new RazorTemplateEngine(razorHost);
|
||||
foreach (var viewStart in ViewStartUtility.GetViewStartLocations(appRoot, pagePath))
|
||||
foreach (var viewStart in ViewStartUtility.GetViewStartLocations(fileSystem, pagePath))
|
||||
{
|
||||
IFileInfo fileInfo;
|
||||
if (fileSystem.TryGetFileInfo(viewStart, out fileInfo))
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
new InjectChunk("Microsoft.AspNet.Mvc.IUrlHelper", "Url"),
|
||||
};
|
||||
|
||||
private readonly string _appRoot;
|
||||
private readonly IFileSystem _fileSystem;
|
||||
// CodeGenerationContext.DefaultBaseClass is set to MyBaseType<dynamic>.
|
||||
// This field holds the type name without the generic decoration (MyBaseType)
|
||||
|
|
@ -43,24 +42,17 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
/// </summary>
|
||||
/// <param name="appEnvironment">Contains information about the executing application.</param>
|
||||
public MvcRazorHost(IApplicationEnvironment appEnvironment)
|
||||
: this(appEnvironment.ApplicationBasePath,
|
||||
new PhysicalFileSystem(appEnvironment.ApplicationBasePath))
|
||||
: this(new PhysicalFileSystem(appEnvironment.ApplicationBasePath))
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="MvcRazorHost"/> at the specified application root
|
||||
/// and <paramref name="fileSystem"/>.
|
||||
/// Initializes a new instance of <see cref="MvcRazorHost"/> using the specified <paramref name="fileSystem"/>.
|
||||
/// </summary>
|
||||
/// <param name="applicationBasePath">The base path of the application.</param>
|
||||
/// <param name="fileSystem">
|
||||
/// A <see cref="IFileSystem"/> rooted at the <paramref name="applicationBasePath"/>.
|
||||
/// </param>
|
||||
protected internal MvcRazorHost(string applicationBasePath,
|
||||
IFileSystem fileSystem)
|
||||
/// <param name="fileSystem">A <see cref="IFileSystem"/> rooted at the application base path.</param>
|
||||
protected internal MvcRazorHost([NotNull] IFileSystem fileSystem)
|
||||
: base(new CSharpRazorCodeLanguage())
|
||||
{
|
||||
_appRoot = applicationBasePath;
|
||||
_fileSystem = fileSystem;
|
||||
_baseType = BaseType;
|
||||
|
||||
|
|
@ -140,7 +132,7 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
var chunkUtility = new ChunkInheritanceUtility(context.CodeTreeBuilder.CodeTree,
|
||||
DefaultInheritedChunks,
|
||||
DefaultModel);
|
||||
var inheritedChunks = chunkUtility.GetInheritedChunks(this, _fileSystem, _appRoot, context.SourceFile);
|
||||
var inheritedChunks = chunkUtility.GetInheritedChunks(this, _fileSystem, context.SourceFile);
|
||||
chunkUtility.MergeInheritedChunks(inheritedChunks);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNet.FileSystems;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.Razor
|
||||
{
|
||||
|
|
@ -35,55 +36,26 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
/// e.g.
|
||||
/// /Views/Home/View.cshtml -> [ /Views/Home/_ViewStart.cshtml, /Views/_ViewStart.cshtml, /_ViewStart.cshtml ]
|
||||
/// </remarks>
|
||||
public static IEnumerable<string> GetViewStartLocations(string applicationBase, string path)
|
||||
public static IEnumerable<string> GetViewStartLocations(IFileSystem fileSystem, string path)
|
||||
{
|
||||
if (string.IsNullOrEmpty(path))
|
||||
{
|
||||
return Enumerable.Empty<string>();
|
||||
}
|
||||
|
||||
applicationBase = TrimTrailingSlash(applicationBase);
|
||||
var viewStartLocations = new List<string>();
|
||||
var currentDir = GetViewDirectory(applicationBase, path);
|
||||
while (IsSubDirectory(applicationBase, currentDir))
|
||||
if (path.StartsWith("~/", StringComparison.Ordinal))
|
||||
{
|
||||
viewStartLocations.Add(Path.Combine(currentDir, ViewStartFileName));
|
||||
currentDir = Path.GetDirectoryName(currentDir);
|
||||
path = path.Substring(1);
|
||||
}
|
||||
|
||||
var viewStartLocations = new List<string>();
|
||||
|
||||
while (fileSystem.TryGetParentPath(path, out path))
|
||||
{
|
||||
var viewStartPath = Path.Combine(path, ViewStartFileName);
|
||||
viewStartLocations.Add(viewStartPath);
|
||||
}
|
||||
|
||||
return viewStartLocations;
|
||||
}
|
||||
|
||||
private static bool IsSubDirectory(string appRoot, string currentDir)
|
||||
{
|
||||
return currentDir.StartsWith(appRoot, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
private static string GetViewDirectory(string appRoot, string viewPath)
|
||||
{
|
||||
if (viewPath.StartsWith("~/"))
|
||||
{
|
||||
viewPath = viewPath.Substring(2);
|
||||
}
|
||||
else if (viewPath[0] == Path.DirectorySeparatorChar ||
|
||||
viewPath[0] == Path.AltDirectorySeparatorChar)
|
||||
{
|
||||
viewPath = viewPath.Substring(1);
|
||||
}
|
||||
|
||||
var viewDir = Path.GetDirectoryName(viewPath);
|
||||
return Path.GetFullPath(Path.Combine(appRoot, viewDir));
|
||||
}
|
||||
|
||||
private static string TrimTrailingSlash(string path)
|
||||
{
|
||||
if (path.Length > 0 &&
|
||||
path[path.Length - 1] == Path.DirectorySeparatorChar)
|
||||
{
|
||||
return path.Substring(0, path.Length - 1);
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNet.FileSystems;
|
||||
using Microsoft.Framework.Runtime;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.Razor
|
||||
|
|
@ -11,20 +12,21 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
/// <inheritdoc />
|
||||
public class ViewStartProvider : IViewStartProvider
|
||||
{
|
||||
private readonly string _appRoot;
|
||||
private readonly IFileSystem _fileSystem;
|
||||
private readonly IRazorPageFactory _pageFactory;
|
||||
|
||||
public ViewStartProvider(IApplicationEnvironment appEnv,
|
||||
IRazorPageFactory pageFactory)
|
||||
{
|
||||
_appRoot = appEnv.ApplicationBasePath;
|
||||
_fileSystem = new PhysicalFileSystem(appEnv.ApplicationBasePath);
|
||||
_pageFactory = pageFactory;
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<IRazorPage> GetViewStartPages([NotNull] string path)
|
||||
{
|
||||
var viewStartLocations = ViewStartUtility.GetViewStartLocations(_appRoot, path);
|
||||
var viewStartLocations = ViewStartUtility.GetViewStartLocations(_fileSystem, path);
|
||||
var viewStarts = viewStartLocations.Select(_pageFactory.CreateInstance)
|
||||
.Where(p => p != null)
|
||||
.ToArray();
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
|
|||
public void GetInheritedChunks_ReadsChunksFromViewStartsInPath()
|
||||
{
|
||||
// Arrange
|
||||
var appRoot = @"x:\myapproot";
|
||||
var fileSystem = new TestFileSystem();
|
||||
fileSystem.AddFile(@"x:\myapproot\views\accounts\_viewstart.cshtml", "@using AccountModels");
|
||||
fileSystem.AddFile(@"x:\myapproot\views\Shared\_viewstart.cshtml", "@inject SharedHelper Shared");
|
||||
|
|
@ -29,13 +28,12 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
|
|||
}
|
||||
|
||||
");
|
||||
var host = new MvcRazorHost(appRoot, fileSystem);
|
||||
var host = new MvcRazorHost(fileSystem);
|
||||
var utility = new ChunkInheritanceUtility(new CodeTree(), new Chunk[0], "dynamic");
|
||||
|
||||
// Act
|
||||
var chunks = utility.GetInheritedChunks(host,
|
||||
fileSystem,
|
||||
appRoot,
|
||||
@"x:\myapproot\views\home\Index.cshtml");
|
||||
|
||||
// Assert
|
||||
|
|
@ -55,18 +53,16 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
|
|||
public void GetInheritedChunks_ReturnsEmptySequenceIfNoViewStartsArePresent()
|
||||
{
|
||||
// Arrange
|
||||
var appRoot = @"x:\myapproot";
|
||||
var fileSystem = new TestFileSystem();
|
||||
fileSystem.AddFile(@"x:\myapproot\_viewstart.cs", string.Empty);
|
||||
fileSystem.AddFile(@"x:\myapproot\views\_Layout.cshtml", string.Empty);
|
||||
fileSystem.AddFile(@"x:\myapproot\views\home\_not-viewstart.cshtml", string.Empty);
|
||||
var host = new MvcRazorHost(appRoot, fileSystem);
|
||||
var host = new MvcRazorHost(fileSystem);
|
||||
var utility = new ChunkInheritanceUtility(new CodeTree(), new Chunk[0], "dynamic");
|
||||
|
||||
// Act
|
||||
var chunks = utility.GetInheritedChunks(host,
|
||||
fileSystem,
|
||||
appRoot,
|
||||
@"x:\myapproot\views\home\Index.cshtml");
|
||||
|
||||
// Assert
|
||||
|
|
@ -77,7 +73,6 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
|
|||
public void GetInheritedChunks_ReturnsDefaultInheritedChunks()
|
||||
{
|
||||
// Arrange
|
||||
var appRoot = @"x:\myapproot";
|
||||
var fileSystem = new TestFileSystem();
|
||||
fileSystem.AddFile(@"x:\myapproot\views\_viewstart.cshtml",
|
||||
@"@inject DifferentHelper<TModel> Html
|
||||
|
|
@ -87,7 +82,7 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
|
|||
}
|
||||
|
||||
");
|
||||
var host = new MvcRazorHost(appRoot, fileSystem);
|
||||
var host = new MvcRazorHost(fileSystem);
|
||||
var defaultChunks = new Chunk[]
|
||||
{
|
||||
new InjectChunk("MyTestHtmlHelper", "Html"),
|
||||
|
|
@ -98,7 +93,6 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
|
|||
// Act
|
||||
var chunks = utility.GetInheritedChunks(host,
|
||||
fileSystem,
|
||||
appRoot,
|
||||
@"x:\myapproot\views\home\Index.cshtml");
|
||||
|
||||
// Assert
|
||||
|
|
|
|||
|
|
@ -3,14 +3,12 @@
|
|||
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Microsoft.AspNet.FileSystems;
|
||||
using Microsoft.AspNet.Razor;
|
||||
using Microsoft.AspNet.Razor.Generator;
|
||||
using Microsoft.AspNet.Razor.Generator.Compiler;
|
||||
using Microsoft.AspNet.Razor.Generator.Compiler.CSharp;
|
||||
using Microsoft.AspNet.Razor.Parser.SyntaxTree;
|
||||
using Microsoft.AspNet.Razor.Text;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.Razor
|
||||
|
|
@ -116,7 +114,7 @@ MyType2 @MyPropertyName2
|
|||
public void InjectVisitor_GeneratesCorrectLineMappings()
|
||||
{
|
||||
// Arrange
|
||||
var host = new MvcRazorHost("appRoot", Mock.Of<IFileSystem>())
|
||||
var host = new MvcRazorHost(new TestFileSystem())
|
||||
{
|
||||
DesignTimeMode = true
|
||||
};
|
||||
|
|
@ -148,7 +146,7 @@ MyType2 @MyPropertyName2
|
|||
public void InjectVisitorWithModel_GeneratesCorrectLineMappings()
|
||||
{
|
||||
// Arrange
|
||||
var host = new MvcRazorHost("appRoot", Mock.Of<IFileSystem>())
|
||||
var host = new MvcRazorHost(new TestFileSystem())
|
||||
{
|
||||
DesignTimeMode = true
|
||||
};
|
||||
|
|
@ -190,7 +188,7 @@ MyType2 @MyPropertyName2
|
|||
|
||||
private static CodeGeneratorContext CreateContext()
|
||||
{
|
||||
return CodeGeneratorContext.Create(new MvcRazorHost("appRoot", Mock.Of<IFileSystem>()),
|
||||
return CodeGeneratorContext.Create(new MvcRazorHost(new TestFileSystem()),
|
||||
"MyClass",
|
||||
"MyNamespace",
|
||||
string.Empty,
|
||||
|
|
|
|||
|
|
@ -4,14 +4,12 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Microsoft.AspNet.FileSystems;
|
||||
using Microsoft.AspNet.Razor;
|
||||
using Microsoft.AspNet.Razor.Generator;
|
||||
using Microsoft.AspNet.Razor.Generator.Compiler;
|
||||
using Microsoft.AspNet.Razor.Generator.Compiler.CSharp;
|
||||
using Microsoft.AspNet.Razor.Parser.SyntaxTree;
|
||||
using Microsoft.AspNet.Razor.Text;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.Razor
|
||||
|
|
@ -108,7 +106,7 @@ Environment.NewLine +
|
|||
public void ModelVisitor_GeneratesCorrectLineMappings()
|
||||
{
|
||||
// Arrange
|
||||
var host = new MvcRazorHost("appRoot", Mock.Of<IFileSystem>())
|
||||
var host = new MvcRazorHost(new TestFileSystem())
|
||||
{
|
||||
DesignTimeMode = true
|
||||
};
|
||||
|
|
@ -148,7 +146,7 @@ Environment.NewLine +
|
|||
|
||||
private static CodeGeneratorContext CreateContext()
|
||||
{
|
||||
return CodeGeneratorContext.Create(new MvcRazorHost("appRoot", Mock.Of<IFileSystem>()),
|
||||
return CodeGeneratorContext.Create(new MvcRazorHost(new TestFileSystem()),
|
||||
"MyClass",
|
||||
"MyNamespace",
|
||||
string.Empty,
|
||||
|
|
|
|||
|
|
@ -44,7 +44,8 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
|
||||
public bool TryGetParentPath(string subpath, out string parentPath)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
parentPath = Path.GetDirectoryName(subpath);
|
||||
return !string.IsNullOrEmpty(parentPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
|
||||
|
|
@ -0,0 +1 @@
|
|||
|
||||
|
|
@ -1,7 +1,10 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Microsoft.AspNet.FileSystems;
|
||||
using Microsoft.Framework.Runtime;
|
||||
using Microsoft.Framework.Runtime.Infrastructure;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.Razor
|
||||
|
|
@ -13,69 +16,64 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
[InlineData("")]
|
||||
public void GetViewStartLocations_ReturnsEmptySequenceIfViewPathIsEmpty(string viewPath)
|
||||
{
|
||||
// Arrange
|
||||
var appPath = @"x:\test";
|
||||
|
||||
// Act
|
||||
var result = ViewStartUtility.GetViewStartLocations(appPath, viewPath);
|
||||
var result = ViewStartUtility.GetViewStartLocations(new TestFileSystem(), viewPath);
|
||||
|
||||
// Assert
|
||||
Assert.Empty(result);
|
||||
}
|
||||
|
||||
public static IEnumerable<object[]> GetViewStartLocations_ReturnsPotentialViewStartLocationsData
|
||||
{
|
||||
get
|
||||
{
|
||||
yield return new object[]
|
||||
{
|
||||
@"x:\test\myapp",
|
||||
"/Views/Home/View.cshtml",
|
||||
new[]
|
||||
{
|
||||
@"x:\test\myapp\Views\Home\_viewstart.cshtml",
|
||||
@"x:\test\myapp\Views\_viewstart.cshtml",
|
||||
@"x:\test\myapp\_viewstart.cshtml",
|
||||
}
|
||||
};
|
||||
|
||||
yield return new object[]
|
||||
{
|
||||
@"x:\test\myapp",
|
||||
"Views/Home/View.cshtml",
|
||||
new[]
|
||||
{
|
||||
@"x:\test\myapp\Views\Home\_viewstart.cshtml",
|
||||
@"x:\test\myapp\Views\_viewstart.cshtml",
|
||||
@"x:\test\myapp\_viewstart.cshtml",
|
||||
}
|
||||
};
|
||||
|
||||
yield return new object[]
|
||||
{
|
||||
@"x:\test\myapp\",
|
||||
"Views/Home/View.cshtml",
|
||||
new[]
|
||||
{
|
||||
@"x:\test\myapp\Views\Home\_viewstart.cshtml",
|
||||
@"x:\test\myapp\Views\_viewstart.cshtml",
|
||||
@"x:\test\myapp\_viewstart.cshtml",
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(GetViewStartLocations_ReturnsPotentialViewStartLocationsData))]
|
||||
public void GetViewStartLocations_ReturnsPotentialViewStartLocations(string appPath,
|
||||
string viewPath,
|
||||
IEnumerable<string> expected)
|
||||
[InlineData("/views/Home/MyView.cshtml")]
|
||||
[InlineData("~/views/Home/MyView.cshtml")]
|
||||
[InlineData("views/Home/MyView.cshtml")]
|
||||
public void GetViewStartLocations_ReturnsPotentialViewStartLocations(string inputPath)
|
||||
{
|
||||
// Arrange
|
||||
var expected = new[]
|
||||
{
|
||||
@"views\Home\_viewstart.cshtml",
|
||||
@"views\_viewstart.cshtml",
|
||||
@"_viewstart.cshtml"
|
||||
};
|
||||
var fileSystem = new PhysicalFileSystem(GetTestFileSystemBase());
|
||||
|
||||
// Act
|
||||
var result = ViewStartUtility.GetViewStartLocations(appPath, viewPath);
|
||||
var result = ViewStartUtility.GetViewStartLocations(fileSystem, inputPath);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetViewStartLocations_ReturnsPotentialViewStartLocations_IfPathIsAbsolute()
|
||||
{
|
||||
// Arrange
|
||||
var expected = new[]
|
||||
{
|
||||
@"Areas\MyArea\Sub\Views\Admin\_viewstart.cshtml",
|
||||
@"Areas\MyArea\Sub\Views\_viewstart.cshtml",
|
||||
@"Areas\MyArea\Sub\_viewstart.cshtml",
|
||||
@"Areas\MyArea\_viewstart.cshtml",
|
||||
@"Areas\_viewstart.cshtml",
|
||||
@"_viewstart.cshtml",
|
||||
};
|
||||
var appBase = GetTestFileSystemBase();
|
||||
var viewPath = Path.Combine(appBase, "Areas", "MyArea", "Sub", "Views", "Admin", "Test.cshtml");
|
||||
var fileSystem = new PhysicalFileSystem(appBase);
|
||||
|
||||
// Act
|
||||
var result = ViewStartUtility.GetViewStartLocations(fileSystem, viewPath);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, result);
|
||||
}
|
||||
|
||||
private static string GetTestFileSystemBase()
|
||||
{
|
||||
var serviceProvider = CallContextServiceLocator.Locator.ServiceProvider;
|
||||
var appEnv = (IApplicationEnvironment)serviceProvider.GetService(typeof(IApplicationEnvironment));
|
||||
return Path.Combine(appEnv.ApplicationBasePath, "TestFiles", "ViewStartUtilityFiles");
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue