Skip to content
This repository has been archived by the owner on Dec 14, 2018. It is now read-only.

Commit

Permalink
Fix #6479 - remove IFileProvider constructor
Browse files Browse the repository at this point in the history
The RazorProject implementation used by MVC at runtime has a constructor
that takes an IFileProvider (used by tests). This causes ambiguities
when a user registers an IFileProvider in DI.

Cleaning up tests to use a mock instead of the file provider directly
  • Loading branch information
rynowak committed Jul 4, 2017
1 parent a23307e commit 8d9c161
Show file tree
Hide file tree
Showing 9 changed files with 82 additions and 48 deletions.
4 changes: 4 additions & 0 deletions samples/MvcSandbox/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
using Microsoft.AspNetCore.Antiforgery;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Razor.Internal;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;

Expand All @@ -17,6 +20,7 @@ public class Startup
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddSingleton<IFileProvider>(new PhysicalFileProvider(Path.GetFullPath(".")));

services.Insert(0, ServiceDescriptor.Singleton(
typeof(IConfigureOptions<AntiforgeryOptions>),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ public class FileProviderRazorProject : RazorProject
private readonly IFileProvider _provider;

public FileProviderRazorProject(IRazorViewEngineFileProviderAccessor accessor)
: this(accessor.FileProvider)
{
}
if (accessor == null)
{
throw new ArgumentNullException(nameof(accessor));
}

public FileProviderRazorProject(IFileProvider provider)
{
_provider = provider;
_provider = accessor.FileProvider;
}

public override RazorProjectItem GetItem(string path)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Text;
using Moq;
using Xunit;

namespace Microsoft.AspNetCore.Mvc.Razor.Internal
Expand All @@ -19,9 +20,12 @@ public void GetCompilationFailedResult_ReadsRazorErrorsFromPage()
// Arrange
var viewPath = "/Views/Home/Index.cshtml";
var razorEngine = RazorEngine.Create();

var fileProvider = new TestFileProvider();
fileProvider.AddFile(viewPath, "<span name=\"@(User.Id\">");
var razorProject = new FileProviderRazorProject(fileProvider);
var accessor = Mock.Of<IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == fileProvider);

var razorProject = new FileProviderRazorProject(accessor);

var templateEngine = new MvcRazorTemplateEngine(razorEngine, razorProject);
var codeDocument = templateEngine.CreateCodeDocument(viewPath);
Expand All @@ -48,13 +52,16 @@ public void GetCompilationFailedResult_UsesPhysicalPath()
// Arrange
var viewPath = "/Views/Home/Index.cshtml";
var physicalPath = @"x:\myapp\views\home\index.cshtml";
var razorEngine = RazorEngine.Create();

var fileProvider = new TestFileProvider();
var file = fileProvider.AddFile(viewPath, "<span name=\"@(User.Id\">");
file.PhysicalPath = physicalPath;
var razorProject = new FileProviderRazorProject(fileProvider);
var accessor = Mock.Of<IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == fileProvider);

var razorEngine = RazorEngine.Create();
var razorProject = new FileProviderRazorProject(accessor);
var templateEngine = new MvcRazorTemplateEngine(razorEngine, razorProject);

var codeDocument = templateEngine.CreateCodeDocument(viewPath);

// Act
Expand Down Expand Up @@ -82,9 +89,11 @@ public void GetCompilationFailedResult_ReadsContentFromSourceDocuments()
var razorEngine = RazorEngine.Create();
var fileProvider = new TestFileProvider();
fileProvider.AddFile(viewPath, fileContent);
var razorProject = new FileProviderRazorProject(fileProvider);
var accessor = Mock.Of<IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == fileProvider);

var razorProject = new FileProviderRazorProject(accessor);
var templateEngine = new MvcRazorTemplateEngine(razorEngine, razorProject);

var codeDocument = templateEngine.CreateCodeDocument(viewPath);

// Act
Expand All @@ -105,13 +114,14 @@ public void GetCompilationFailedResult_ReadsContentFromImports()
var fileContent = "@ ";
var importsContent = "@(abc";

var razorEngine = RazorEngine.Create();
var fileProvider = new TestFileProvider();
fileProvider.AddFile(viewPath, fileContent);
var importsFile = fileProvider.AddFile("/Views/_MyImports.cshtml", importsContent);
importsFile.PhysicalPath = importsFilePath;
var razorProject = new FileProviderRazorProject(fileProvider);
var accessor = Mock.Of<IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == fileProvider);

var razorEngine = RazorEngine.Create();
var razorProject = new FileProviderRazorProject(accessor);
var templateEngine = new MvcRazorTemplateEngine(razorEngine, razorProject)
{
Options =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System.Linq;
using Microsoft.Extensions.FileProviders;
using Moq;
using Xunit;

namespace Microsoft.AspNetCore.Mvc.Razor.Internal
Expand All @@ -18,7 +19,9 @@ public void EnumerateFiles_ReturnsEmptySequenceIfNoCshtmlFilesArePresent()
var file2 = fileProvider.AddFile("File2.js", "content");
fileProvider.AddDirectoryContent("/", new IFileInfo[] { file1, file2 });

var razorProject = new FileProviderRazorProject(fileProvider);
var accessor = Mock.Of<IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == fileProvider);

var razorProject = new FileProviderRazorProject(accessor);

// Act
var razorFiles = razorProject.EnumerateItems("/");
Expand All @@ -37,7 +40,9 @@ public void EnumerateFiles_ReturnsCshtmlFiles()
var file3 = fileProvider.AddFile("File3.cshtml", "content");
fileProvider.AddDirectoryContent("/", new IFileInfo[] { file1, file2, file3 });

var razorProject = new FileProviderRazorProject(fileProvider);
var accessor = Mock.Of<IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == fileProvider);

var razorProject = new FileProviderRazorProject(accessor);

// Act
var razorFiles = razorProject.EnumerateItems("/");
Expand Down Expand Up @@ -76,7 +81,9 @@ public void EnumerateFiles_IteratesOverAllCshtmlUnderRoot()
fileProvider.AddDirectoryContent("/Level1-Dir2", new IFileInfo[] { file5 });
fileProvider.AddDirectoryContent("/Level1/Level2", new IFileInfo[0]);

var razorProject = new FileProviderRazorProject(fileProvider);
var accessor = Mock.Of<IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == fileProvider);

var razorProject = new FileProviderRazorProject(accessor);

// Act
var razorFiles = razorProject.EnumerateItems("/");
Expand Down Expand Up @@ -117,7 +124,9 @@ public void EnumerateFiles_IteratesOverAllCshtmlUnderPath()
fileProvider.AddDirectoryContent("/Level1-Dir2", new IFileInfo[] { file5 });
fileProvider.AddDirectoryContent("/Level1/Level2", new IFileInfo[0]);

var razorProject = new FileProviderRazorProject(fileProvider);
var accessor = Mock.Of<IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == fileProvider);

var razorProject = new FileProviderRazorProject(accessor);

// Act
var razorFiles = razorProject.EnumerateItems("/Level1-Dir1");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,19 @@ public void GetCompiler_ThrowsIfNullFileProvider()
$"not be empty. At least one '{typeof(IFileProvider).FullName}' is required to locate a view for " +
"rendering.";
var fileProvider = new NullFileProvider();
var accessor = new Mock<IRazorViewEngineFileProviderAccessor>();
var applicationManager = new ApplicationPartManager();
var accessor = Mock.Of<IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == fileProvider);

var partManager = new ApplicationPartManager();
var options = new TestOptionsManager<RazorViewEngineOptions>();
var referenceManager = new DefaultRazorReferenceManager(applicationManager, options);
accessor.Setup(a => a.FileProvider).Returns(fileProvider);

var referenceManager = new DefaultRazorReferenceManager(partManager, options);

var provider = new RazorViewCompilerProvider(
applicationManager,
new RazorTemplateEngine(RazorEngine.Create(), new FileProviderRazorProject(fileProvider)),
accessor.Object,
partManager,
new RazorTemplateEngine(
RazorEngine.Create(),
new FileProviderRazorProject(accessor)),
accessor,
new CSharpCompiler(referenceManager, options),
options,
NullLoggerFactory.Instance);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.CodeAnalysis;
using Microsoft.Extensions.Logging.Abstractions;
using Moq;
using Xunit;

namespace Microsoft.AspNetCore.Mvc.Razor.Internal
Expand Down Expand Up @@ -526,6 +527,8 @@ public void Compile_SucceedsIfReferencesAreAddedInCallback()
IList<CompiledViewDescriptor> precompiledViews = null)
{
fileProvider = fileProvider ?? new TestFileProvider();
var accessor = Mock.Of<IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == fileProvider);

compilationCallback = compilationCallback ?? (_ => { });
var options = new TestOptionsManager<RazorViewEngineOptions>();
if (referenceManager == null)
Expand All @@ -540,7 +543,7 @@ public void Compile_SucceedsIfReferencesAreAddedInCallback()

precompiledViews = precompiledViews ?? Array.Empty<CompiledViewDescriptor>();

var projectSystem = new FileProviderRazorProject(fileProvider);
var projectSystem = new FileProviderRazorProject(accessor);
var templateEngine = new RazorTemplateEngine(RazorEngine.Create(), projectSystem)
{
Options =
Expand Down
19 changes: 13 additions & 6 deletions test/Microsoft.AspNetCore.Mvc.Razor.Test/RazorViewEngineTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -934,7 +934,8 @@ public void FindView_InvokesPageFactoryIfViewStartExpirationTokensHaveExpired()
.Returns(GetPageFactoryResult(() => viewStart));

var fileProvider = new TestFileProvider();
var razorProject = new FileProviderRazorProject(fileProvider);
var accessor = Mock.Of<IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == fileProvider);
var razorProject = new FileProviderRazorProject(accessor);
var viewEngine = CreateViewEngine(pageFactory.Object, razorProject: razorProject);
var context = GetActionContext(_controllerTestContext);

Expand Down Expand Up @@ -1384,7 +1385,8 @@ public void CreateCacheResult_LogsPrecompiledViewFound()
Mock.Of<IRazorPageActivator>(),
new HtmlTestEncoder(),
GetOptionsAccessor(expanders: null),
new FileProviderRazorProject(new TestFileProvider()),
new FileProviderRazorProject(
Mock.Of<IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == new TestFileProvider())),
loggerFactory,
new DiagnosticListener("Microsoft.AspNetCore.Mvc.Razor"));

Expand Down Expand Up @@ -1822,7 +1824,8 @@ private RazorViewEngine CreateSuccessfulViewEngine()
pageFactory = pageFactory ?? Mock.Of<IRazorPageFactoryProvider>();
if (razorProject == null)
{
razorProject = new FileProviderRazorProject(new TestFileProvider());
var accessor = Mock.Of<IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == new TestFileProvider());
razorProject = new FileProviderRazorProject(accessor);
}
return new TestableRazorViewEngine(pageFactory, GetOptionsAccessor(expanders), razorProject);
}
Expand Down Expand Up @@ -1923,9 +1926,13 @@ private class TestableRazorViewEngine : RazorViewEngine
public TestableRazorViewEngine(
IRazorPageFactoryProvider pageFactory,
IOptions<RazorViewEngineOptions> optionsAccessor)
: this(pageFactory, optionsAccessor, new FileProviderRazorProject(new TestFileProvider()))
{
}
: this(
pageFactory,
optionsAccessor,
new FileProviderRazorProject(
Mock.Of<IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == new TestFileProvider())))
{
}

public TestableRazorViewEngine(
IRazorPageFactoryProvider pageFactory,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,13 @@ public void GetChangeToken_WatchesAllCshtmlFilesUnderFileSystemRoot()
{
// Arrange
var fileProvider = new Mock<IFileProvider>();
var accessor = Mock.Of<IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == fileProvider.Object);

var templateEngine = new RazorTemplateEngine(
RazorEngine.Create(),
new FileProviderRazorProject(fileProvider.Object));
new FileProviderRazorProject(accessor));
var options = new TestOptionsManager<RazorPagesOptions>();
var fileProviderAccessor = new Mock<IRazorViewEngineFileProviderAccessor>();
fileProviderAccessor
.Setup(f => f.FileProvider)
.Returns(fileProvider.Object);
var changeProvider = new PageActionDescriptorChangeProvider(templateEngine, fileProviderAccessor.Object, options);
var changeProvider = new PageActionDescriptorChangeProvider(templateEngine, accessor, options);

// Act
var changeToken = changeProvider.GetChangeToken();
Expand All @@ -42,16 +40,15 @@ public void GetChangeToken_WatchesAllCshtmlFilesUnderSpecifiedRootDirectory(stri
{
// Arrange
var fileProvider = new Mock<IFileProvider>();
var accessor = Mock.Of<IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == fileProvider.Object);

var templateEngine = new RazorTemplateEngine(
RazorEngine.Create(),
new FileProviderRazorProject(fileProvider.Object));
new FileProviderRazorProject(accessor));
var options = new TestOptionsManager<RazorPagesOptions>();
options.Value.RootDirectory = rootDirectory;
var fileProviderAccessor = new Mock<IRazorViewEngineFileProviderAccessor>();
fileProviderAccessor
.Setup(f => f.FileProvider)
.Returns(fileProvider.Object);
var changeProvider = new PageActionDescriptorChangeProvider(templateEngine, fileProviderAccessor.Object, options);

var changeProvider = new PageActionDescriptorChangeProvider(templateEngine, accessor, options);

// Act
var changeToken = changeProvider.GetChangeToken();
Expand All @@ -65,17 +62,16 @@ public void GetChangeToken_WatchesViewImportsOutsidePagesRoot()
{
// Arrange
var fileProvider = new TestFileProvider();
var accessor = Mock.Of<IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == fileProvider);

var templateEngine = new RazorTemplateEngine(
RazorEngine.Create(),
new FileProviderRazorProject(fileProvider));
new FileProviderRazorProject(accessor));
templateEngine.Options.ImportsFileName = "_ViewImports.cshtml";
var options = new TestOptionsManager<RazorPagesOptions>();
options.Value.RootDirectory = "/dir1/dir2";
var fileProviderAccessor = new Mock<IRazorViewEngineFileProviderAccessor>();
fileProviderAccessor
.Setup(f => f.FileProvider)
.Returns(fileProvider);
var changeProvider = new PageActionDescriptorChangeProvider(templateEngine, fileProviderAccessor.Object, options);

var changeProvider = new PageActionDescriptorChangeProvider(templateEngine, accessor, options);

// Act & Assert
var compositeChangeToken = Assert.IsType<CompositeChangeToken>(changeProvider.GetChangeToken());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,9 @@ public void OnProvidersExecuting_CachesViewStartFactories()
var fileProvider = new TestFileProvider();
fileProvider.AddFile("/Home/Path1/_ViewStart.cshtml", "content1");
fileProvider.AddFile("/_ViewStart.cshtml", "content2");
var accessor = Mock.Of<IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == fileProvider);

var defaultRazorProject = new FileProviderRazorProject(fileProvider);
var defaultRazorProject = new FileProviderRazorProject(accessor);

var invokerProvider = CreateInvokerProvider(
loader.Object,
Expand Down

0 comments on commit 8d9c161

Please sign in to comment.