Change RazorProjectEngine to operate on RazorProjectItems.

- Removed the `Process(string)` overload to make it extra clear that you must operate on project items. This way we also don't need to worry about the various formats of paths that can flow through the system.
- Updated tests to use the new project item format.
- Did a few formatting fixes on unrealted files.

#2049
This commit is contained in:
N. Taylor Mullen 2018-02-09 16:39:35 -08:00
parent 0c6aadb897
commit 3375fc8b99
12 changed files with 42 additions and 89 deletions

View File

@ -14,18 +14,18 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X
{
private const string ImportsFileName = "_ViewImports.cshtml";
public IReadOnlyList<RazorSourceDocument> GetImports(string sourceFilePath)
public IReadOnlyList<RazorSourceDocument> GetImports(RazorProjectItem projectItem)
{
if (string.IsNullOrEmpty(sourceFilePath))
if (projectItem == null)
{
throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpy, nameof(sourceFilePath));
throw new ArgumentNullException(nameof(projectItem));
}
var imports = new List<RazorSourceDocument>();
AddDefaultDirectivesImport(imports);
// We add hierarchical imports second so any default directive imports can be overridden.
AddHierarchicalImports(sourceFilePath, imports);
AddHierarchicalImports(projectItem, imports);
return imports;
}
@ -58,10 +58,10 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X
}
// Internal for testing
internal void AddHierarchicalImports(string sourceFilePath, List<RazorSourceDocument> imports)
internal void AddHierarchicalImports(RazorProjectItem projectItem, List<RazorSourceDocument> imports)
{
// We want items in descending order. FindHierarchicalItems returns items in ascending order.
var importProjectItems = ProjectEngine.FileSystem.FindHierarchicalItems(sourceFilePath, ImportsFileName).Reverse();
var importProjectItems = ProjectEngine.FileSystem.FindHierarchicalItems(projectItem.FilePath, ImportsFileName).Reverse();
foreach (var importProjectItem in importProjectItems)
{
RazorSourceDocument importSourceDocument;

View File

@ -14,18 +14,18 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
{
private const string ImportsFileName = "_ViewImports.cshtml";
public IReadOnlyList<RazorSourceDocument> GetImports(string sourceFilePath)
public IReadOnlyList<RazorSourceDocument> GetImports(RazorProjectItem projectItem)
{
if (string.IsNullOrEmpty(sourceFilePath))
if (projectItem == null)
{
throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpy, nameof(sourceFilePath));
throw new ArgumentNullException(nameof(projectItem));
}
var imports = new List<RazorSourceDocument>();
AddDefaultDirectivesImport(imports);
// We add hierarchical imports second so any default directive imports can be overridden.
AddHierarchicalImports(sourceFilePath, imports);
AddHierarchicalImports(projectItem, imports);
return imports;
}
@ -60,10 +60,10 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
}
// Internal for testing
internal void AddHierarchicalImports(string sourceFilePath, List<RazorSourceDocument> imports)
internal void AddHierarchicalImports(RazorProjectItem projectItem, List<RazorSourceDocument> imports)
{
// We want items in descending order. FindHierarchicalItems returns items in ascending order.
var importProjectItems = ProjectEngine.FileSystem.FindHierarchicalItems(sourceFilePath, ImportsFileName).Reverse();
var importProjectItems = ProjectEngine.FileSystem.FindHierarchicalItems(projectItem.FilePath, ImportsFileName).Reverse();
foreach (var importProjectItem in importProjectItems)
{
RazorSourceDocument importSourceDocument;

View File

@ -8,6 +8,6 @@ namespace Microsoft.AspNetCore.Razor.Language
{
internal class DefaultRazorImportFeature : RazorProjectEngineFeatureBase, IRazorImportFeature
{
public IReadOnlyList<RazorSourceDocument> GetImports(string sourceFilePath) => Array.Empty<RazorSourceDocument>();
public IReadOnlyList<RazorSourceDocument> GetImports(RazorProjectItem projectItem) => Array.Empty<RazorSourceDocument>();
}
}

View File

@ -45,29 +45,16 @@ namespace Microsoft.AspNetCore.Razor.Language
public override IReadOnlyList<IRazorProjectEngineFeature> Features { get; }
public override RazorCodeDocument Process(string filePath)
public override RazorCodeDocument Process(RazorProjectItem projectItem)
{
if (string.IsNullOrEmpty(filePath))
if (projectItem == null)
{
throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, nameof(filePath));
}
var projectItem = FileSystem.GetItem(filePath);
var sourceDocument = RazorSourceDocument.ReadFrom(projectItem);
var codeDocument = Process(sourceDocument);
return codeDocument;
}
public override RazorCodeDocument Process(RazorSourceDocument sourceDocument)
{
if (sourceDocument == null)
{
throw new ArgumentNullException(nameof(sourceDocument));
throw new ArgumentNullException(nameof(projectItem));
}
var importFeature = GetRequiredFeature<IRazorImportFeature>();
var imports = importFeature.GetImports(sourceDocument.FilePath);
var imports = importFeature.GetImports(projectItem);
var sourceDocument = RazorSourceDocument.ReadFrom(projectItem);
var codeDocument = RazorCodeDocument.Create(sourceDocument, imports);

View File

@ -7,6 +7,6 @@ namespace Microsoft.AspNetCore.Razor.Language
{
public interface IRazorImportFeature : IRazorProjectEngineFeature
{
IReadOnlyList<RazorSourceDocument> GetImports(string sourceFilePath);
IReadOnlyList<RazorSourceDocument> GetImports(RazorProjectItem projectItem);
}
}

View File

@ -14,9 +14,7 @@ namespace Microsoft.AspNetCore.Razor.Language
public abstract IReadOnlyList<IRazorProjectEngineFeature> Features { get; }
public abstract RazorCodeDocument Process(string filePath);
public abstract RazorCodeDocument Process(RazorSourceDocument sourceDocument);
public abstract RazorCodeDocument Process(RazorProjectItem projectItem);
public static RazorProjectEngine Create(RazorProjectFileSystem fileSystem) => Create(fileSystem, configure: null);

View File

@ -9,7 +9,7 @@ namespace Microsoft.AspNetCore.Razor.Language
{
private RazorProjectEngine _projectEngine;
public RazorProjectEngine ProjectEngine
public virtual RazorProjectEngine ProjectEngine
{
get => _projectEngine;
set

View File

@ -10,20 +10,19 @@ namespace Microsoft.AspNetCore.Razor.Language
{
internal class VirtualRazorProjectFileSystem : RazorProjectFileSystem
{
private readonly DirectoryNode Root = new DirectoryNode("/");
private readonly DirectoryNode _root = new DirectoryNode("/");
public override IEnumerable<RazorProjectItem> EnumerateItems(string basePath)
{
basePath = NormalizeAndEnsureValidPath(basePath);
var directory = Root.GetDirectory(basePath);
var directory = _root.GetDirectory(basePath);
return directory?.EnumerateItems() ?? Enumerable.Empty<RazorProjectItem>();
}
public override RazorProjectItem GetItem(string path)
{
path = NormalizeAndEnsureValidPath(path);
return Root.GetItem(path) ?? new NotFoundProjectItem(string.Empty, path);
return _root.GetItem(path) ?? new NotFoundProjectItem(string.Empty, path);
}
public void Add(RazorProjectItem projectItem)
@ -34,7 +33,7 @@ namespace Microsoft.AspNetCore.Razor.Language
}
var filePath = NormalizeAndEnsureValidPath(projectItem.FilePath);
Root.AddFile(new FileNode(filePath, projectItem));
_root.AddFile(new FileNode(filePath, projectItem));
}
// Internal for testing

View File

@ -29,12 +29,13 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
{
// Arrange
var imports = new List<RazorSourceDocument>();
var projectItem = new TestRazorProjectItem("/Contact/Index.cshtml");
var testFileSystem = new TestRazorProjectFileSystem(new[]
{
new TestRazorProjectItem("/Index.cshtml"),
new TestRazorProjectItem("/_ViewImports.cshtml"),
new TestRazorProjectItem("/Contact/_ViewImports.cshtml"),
new TestRazorProjectItem("/Contact/Index.cshtml"),
projectItem,
});
var mvcImportFeature = new DefaultMvcImportFeature()
{
@ -42,7 +43,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
};
// Act
mvcImportFeature.AddHierarchicalImports("/Contact/Index.cshtml", imports);
mvcImportFeature.AddHierarchicalImports(projectItem, imports);
// Assert
Assert.Collection(imports,
@ -55,17 +56,15 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
{
// Arrange
var imports = new List<RazorSourceDocument>();
var testFileSystem = new TestRazorProjectFileSystem(new[]
{
new TestRazorProjectItem("/Pages/Contact/Index.cshtml"),
});
var projectItem = new TestRazorProjectItem("/Pages/Contact/Index.cshtml");
var testFileSystem = new TestRazorProjectFileSystem(new[] { projectItem });
var mvcImportFeature = new DefaultMvcImportFeature()
{
ProjectEngine = Mock.Of<RazorProjectEngine>(projectEngine => projectEngine.FileSystem == testFileSystem)
};
// Act
mvcImportFeature.AddHierarchicalImports("/Pages/Contact/Index.cshtml", imports);
mvcImportFeature.AddHierarchicalImports(projectItem, imports);
// Assert
Assert.Collection(imports,

View File

@ -29,12 +29,13 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X
{
// Arrange
var imports = new List<RazorSourceDocument>();
var projectItem = new TestRazorProjectItem("/Contact/Index.cshtml");
var testFileSystem = new TestRazorProjectFileSystem(new[]
{
new TestRazorProjectItem("/Index.cshtml"),
new TestRazorProjectItem("/_ViewImports.cshtml"),
new TestRazorProjectItem("/Contact/_ViewImports.cshtml"),
new TestRazorProjectItem("/Contact/Index.cshtml"),
projectItem,
});
var mvcImportFeature = new DefaultMvcImportFeature()
{
@ -42,7 +43,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X
};
// Act
mvcImportFeature.AddHierarchicalImports("/Contact/Index.cshtml", imports);
mvcImportFeature.AddHierarchicalImports(projectItem, imports);
// Assert
Assert.Collection(imports,
@ -55,17 +56,15 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X
{
// Arrange
var imports = new List<RazorSourceDocument>();
var testFileSystem = new TestRazorProjectFileSystem(new[]
{
new TestRazorProjectItem("/Pages/Contact/Index.cshtml"),
});
var projectItem = new TestRazorProjectItem("/Pages/Contact/Index.cshtml");
var testFileSystem = new TestRazorProjectFileSystem(new[] { projectItem });
var mvcImportFeature = new DefaultMvcImportFeature()
{
ProjectEngine = Mock.Of<RazorProjectEngine>(projectEngine => projectEngine.FileSystem == testFileSystem)
};
// Act
mvcImportFeature.AddHierarchicalImports("/Pages/Contact/Index.cshtml", imports);
mvcImportFeature.AddHierarchicalImports(projectItem, imports);
// Assert
Assert.Collection(imports,

View File

@ -12,10 +12,10 @@ namespace Microsoft.AspNetCore.Razor.Language
public void Process_GetsImportsFromFeature()
{
// Arrange
var sourceDocument = TestRazorSourceDocument.Create();
var projectItem = new TestRazorProjectItem("Index.cshtml");
var testImport = TestRazorSourceDocument.Create();
var importFeature = new Mock<IRazorImportFeature>();
importFeature.Setup(feature => feature.GetImports(It.IsAny<string>()))
importFeature.Setup(feature => feature.GetImports(It.IsAny<RazorProjectItem>()))
.Returns(new[] { testImport });
var projectEngine = RazorProjectEngine.Create(TestRazorProjectFileSystem.Empty, builder =>
{
@ -23,7 +23,7 @@ namespace Microsoft.AspNetCore.Razor.Language
});
// Act
var codeDocument = projectEngine.Process(sourceDocument);
var codeDocument = projectEngine.Process(projectItem);
// Assert
var import = Assert.Single(codeDocument.Imports);
@ -34,11 +34,11 @@ namespace Microsoft.AspNetCore.Razor.Language
public void Process_GeneratesCodeDocumentWithValidCSharpDocument()
{
// Arrange
var sourceDocument = TestRazorSourceDocument.Create();
var projectItem = new TestRazorProjectItem("Index.cshtml");
var projectEngine = RazorProjectEngine.Create(TestRazorProjectFileSystem.Empty);
// Act
var codeDocument = projectEngine.Process(sourceDocument);
var codeDocument = projectEngine.Process(projectItem);
// Assert
var csharpDocument = codeDocument.GetCSharpDocument();

View File

@ -1,29 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Moq;
using Xunit;
namespace Microsoft.AspNetCore.Razor.Language
{
public class DefaultRazorProjectEngineTest
{
[Fact]
public void Process_AsksFileSystemForItems()
{
// Arrange
var razorProjectItem = new TestRazorProjectItem("/some/path.cshtml");
var testFileSystem = new Mock<RazorProjectFileSystem>();
testFileSystem.Setup(fileSystem => fileSystem.GetItem("/some/path.cshtml"))
.Returns(razorProjectItem)
.Verifiable();
var projectEngine = RazorProjectEngine.Create(testFileSystem.Object);
// Act
projectEngine.Process("/some/path.cshtml");
// Assert
testFileSystem.Verify();
}
}
}