Add test to validate tooling path normalization.
- Tooling passes in rooted paths when asking for a RazorParser for a file. This was problematic when resolving inherited code trees and ultimately this commit tests that. #2213
This commit is contained in:
parent
570b1e583a
commit
9ac346529c
|
|
@ -47,7 +47,7 @@ namespace Microsoft.AspNet.Mvc.Razor.Directives
|
|||
/// <param name="pagePath">The path of the page to locate inherited chunks for.</param>
|
||||
/// <returns>A <see cref="IReadOnlyList{CodeTree}"/> of parsed <c>_GlobalImport</c>
|
||||
/// <see cref="CodeTree"/>s.</returns>
|
||||
public IReadOnlyList<CodeTree> GetInheritedCodeTrees([NotNull] string pagePath)
|
||||
public virtual IReadOnlyList<CodeTree> GetInheritedCodeTrees([NotNull] string pagePath)
|
||||
{
|
||||
var inheritedCodeTrees = new List<CodeTree>();
|
||||
var templateEngine = new RazorTemplateEngine(_razorHost);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
// 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;
|
||||
using System.IO;
|
||||
using Microsoft.Framework.Internal;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.Razor.Internal
|
||||
{
|
||||
public class DesignTimeRazorPathNormalizer : RazorPathNormalizer
|
||||
{
|
||||
private readonly string _applicationRoot;
|
||||
|
||||
public DesignTimeRazorPathNormalizer([NotNull] string applicationRoot)
|
||||
{
|
||||
_applicationRoot = applicationRoot;
|
||||
}
|
||||
|
||||
public override string NormalizePath([NotNull] string path)
|
||||
{
|
||||
// Need to convert path to application relative (rooted paths are passed in during design time).
|
||||
if (Path.IsPathRooted(path) && path.StartsWith(_applicationRoot, StringComparison.Ordinal))
|
||||
{
|
||||
path = path.Substring(_applicationRoot.Length);
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
// 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 Microsoft.Framework.Internal;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.Razor.Internal
|
||||
{
|
||||
public class RazorPathNormalizer
|
||||
{
|
||||
public virtual string NormalizePath([NotNull] string path)
|
||||
{
|
||||
return path;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@ using System.Collections.Generic;
|
|||
using System.IO;
|
||||
using Microsoft.AspNet.FileProviders;
|
||||
using Microsoft.AspNet.Mvc.Razor.Directives;
|
||||
using Microsoft.AspNet.Mvc.Razor.Internal;
|
||||
using Microsoft.AspNet.Razor;
|
||||
using Microsoft.AspNet.Razor.Generator;
|
||||
using Microsoft.AspNet.Razor.Generator.Compiler;
|
||||
|
|
@ -36,31 +37,13 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
// This field holds the type name without the generic decoration (MyBaseType)
|
||||
private readonly string _baseType;
|
||||
private readonly ICodeTreeCache _codeTreeCache;
|
||||
private readonly RazorPathNormalizer _pathNormalizer;
|
||||
private ChunkInheritanceUtility _chunkInheritanceUtility;
|
||||
|
||||
#if NET45
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="MvcRazorHost"/> with the specified
|
||||
/// <param name="root"/>.
|
||||
/// </summary>
|
||||
/// <param name="root">The path to the application base.</param>
|
||||
// Note: This constructor is used by tooling and is created once for each
|
||||
// Razor page that is loaded. Consequently, each loaded page has its own copy of
|
||||
// the CodeTreeCache, but this ok - having a shared CodeTreeCache per application in tooling
|
||||
// is problematic to manage.
|
||||
public MvcRazorHost(string root) :
|
||||
this(new DefaultCodeTreeCache(new PhysicalFileProvider(root)))
|
||||
{
|
||||
ApplicationRoot = root;
|
||||
}
|
||||
#endif
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="MvcRazorHost"/> using the specified <paramref name="fileProvider"/>.
|
||||
/// </summary>
|
||||
/// <param name="fileProvider">A <see cref="IFileProvider"/> rooted at the application base path.</param>
|
||||
public MvcRazorHost(ICodeTreeCache codeTreeCache)
|
||||
internal MvcRazorHost(ICodeTreeCache codeTreeCache, RazorPathNormalizer pathNormalizer)
|
||||
: base(new CSharpRazorCodeLanguage())
|
||||
{
|
||||
_pathNormalizer = pathNormalizer;
|
||||
_baseType = BaseType;
|
||||
_codeTreeCache = codeTreeCache;
|
||||
|
||||
|
|
@ -115,10 +98,26 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
|
||||
#if NET45
|
||||
/// <summary>
|
||||
/// The path to the application root.
|
||||
/// Initializes a new instance of <see cref="MvcRazorHost"/> with the specified <paramref name="root"/>.
|
||||
/// </summary>
|
||||
public string ApplicationRoot { get; }
|
||||
/// <param name="root">The path to the application base.</param>
|
||||
// Note: This constructor is used by tooling and is created once for each
|
||||
// Razor page that is loaded. Consequently, each loaded page has its own copy of
|
||||
// the CodeTreeCache, but this ok - having a shared CodeTreeCache per application in tooling
|
||||
// is problematic to manage.
|
||||
public MvcRazorHost(string root)
|
||||
: this(new DefaultCodeTreeCache(new PhysicalFileProvider(root)), new DesignTimeRazorPathNormalizer(root))
|
||||
{
|
||||
}
|
||||
#endif
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="MvcRazorHost"/> using the specified <paramref name="codeTreeCache"/>.
|
||||
/// </summary>
|
||||
/// <param name="codeTreeCache">An <see cref="ICodeTreeCache"/> rooted at the application base path.</param>
|
||||
public MvcRazorHost(ICodeTreeCache codeTreeCache)
|
||||
: this(codeTreeCache, new RazorPathNormalizer())
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the model type used by default when no model is specified.
|
||||
|
|
@ -168,7 +167,8 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
get { return "CreateModelExpression"; }
|
||||
}
|
||||
|
||||
private ChunkInheritanceUtility ChunkInheritanceUtility
|
||||
// Internal for testing
|
||||
internal ChunkInheritanceUtility ChunkInheritanceUtility
|
||||
{
|
||||
get
|
||||
{
|
||||
|
|
@ -180,6 +180,10 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
|
||||
return _chunkInheritanceUtility;
|
||||
}
|
||||
set
|
||||
{
|
||||
_chunkInheritanceUtility = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
|
@ -194,13 +198,7 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
/// <inheritdoc />
|
||||
public override RazorParser DecorateRazorParser([NotNull] RazorParser razorParser, string sourceFileName)
|
||||
{
|
||||
#if NET45
|
||||
// Need to convert sourceFileName to application relative (rooted paths are passed in by tooling).
|
||||
if (Path.IsPathRooted(sourceFileName))
|
||||
{
|
||||
sourceFileName = sourceFileName.Substring(ApplicationRoot.Length);
|
||||
}
|
||||
#endif
|
||||
sourceFileName = _pathNormalizer.NormalizePath(sourceFileName);
|
||||
|
||||
var inheritedCodeTrees = ChunkInheritanceUtility.GetInheritedCodeTrees(sourceFileName);
|
||||
return new MvcRazorParser(razorParser, inheritedCodeTrees, DefaultInheritedChunks);
|
||||
|
|
|
|||
|
|
@ -1,20 +1,52 @@
|
|||
// 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;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Microsoft.AspNet.Mvc.Razor.Directives;
|
||||
using Microsoft.AspNet.Mvc.Razor.Internal;
|
||||
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;
|
||||
using Microsoft.AspNet.Razor.Text;
|
||||
using Microsoft.Framework.Internal;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.Razor
|
||||
{
|
||||
public class MvcRazorHostTest
|
||||
{
|
||||
[Theory]
|
||||
[InlineData("//")]
|
||||
[InlineData("C:/")]
|
||||
[InlineData(@"\\")]
|
||||
[InlineData(@"C:\")]
|
||||
public void DecorateRazorParser_DesignTimeRazorPathNormalizer_NormalizesChunkInheritanceUtilityPaths(
|
||||
string rootPrefix)
|
||||
{
|
||||
// Arrange
|
||||
var rootedAppPath = $"{rootPrefix}SomeComputer/Location/Project/";
|
||||
var rootedFilePath = $"{rootPrefix}SomeComputer/Location/Project/src/file.cshtml";
|
||||
var host = new MvcRazorHost(
|
||||
codeTreeCache: null,
|
||||
pathNormalizer: new DesignTimeRazorPathNormalizer(rootedAppPath));
|
||||
var parser = new RazorParser(
|
||||
host.CodeLanguage.CreateCodeParser(),
|
||||
host.CreateMarkupParser(),
|
||||
tagHelperDescriptorResolver: null);
|
||||
var chunkInheritanceUtility = new PathValidatingChunkInheritanceUtility(host);
|
||||
host.ChunkInheritanceUtility = chunkInheritanceUtility;
|
||||
|
||||
// Act
|
||||
host.DecorateRazorParser(parser, rootedFilePath);
|
||||
|
||||
// Assert
|
||||
Assert.Equal("src/file.cshtml", chunkInheritanceUtility.InheritedCodeTreePagePath, StringComparer.Ordinal);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MvcRazorHost_EnablesInstrumentationByDefault()
|
||||
{
|
||||
|
|
@ -254,6 +286,23 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
generatedLocation: new MappingLocation(generatedLocation, contentLength));
|
||||
}
|
||||
|
||||
private class PathValidatingChunkInheritanceUtility : ChunkInheritanceUtility
|
||||
{
|
||||
public PathValidatingChunkInheritanceUtility(MvcRazorHost razorHost)
|
||||
: base(razorHost, codeTreeCache: null, defaultInheritedChunks: new Chunk[0])
|
||||
{
|
||||
}
|
||||
|
||||
public string InheritedCodeTreePagePath { get; private set; }
|
||||
|
||||
public override IReadOnlyList<CodeTree> GetInheritedCodeTrees([NotNull] string pagePath)
|
||||
{
|
||||
InheritedCodeTreePagePath = pagePath;
|
||||
|
||||
return new CodeTree[0];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used when testing Tag Helpers, it disables the unique ID generation feature.
|
||||
/// </summary>
|
||||
|
|
|
|||
Loading…
Reference in New Issue