Use VirtualRazorProjectSystem for Razor tests
This commit is contained in:
parent
39053a5e22
commit
3db924003e
|
|
@ -28,6 +28,7 @@
|
|||
<MicrosoftAspNetCoreMvcRazorExtensionsPackageVersion>2.1.0-preview3-32110</MicrosoftAspNetCoreMvcRazorExtensionsPackageVersion>
|
||||
<MicrosoftAspNetCoreRangeHelperSourcesPackageVersion>2.1.0-preview3-32110</MicrosoftAspNetCoreRangeHelperSourcesPackageVersion>
|
||||
<MicrosoftAspNetCoreRazorDesignPackageVersion>2.1.0-preview3-32110</MicrosoftAspNetCoreRazorDesignPackageVersion>
|
||||
<MicrosoftAspNetCoreRazorLanguagePackageVersion>2.1.0-preview3-32110</MicrosoftAspNetCoreRazorLanguagePackageVersion>
|
||||
<MicrosoftAspNetCoreRazorRuntimePackageVersion>2.1.0-preview3-32110</MicrosoftAspNetCoreRazorRuntimePackageVersion>
|
||||
<MicrosoftAspNetCoreRazorTagHelpersTestingSourcesPackageVersion>2.1.0-preview3-32110</MicrosoftAspNetCoreRazorTagHelpersTestingSourcesPackageVersion>
|
||||
<MicrosoftAspNetCoreResponseCachingAbstractionsPackageVersion>2.1.0-preview3-32110</MicrosoftAspNetCoreResponseCachingAbstractionsPackageVersion>
|
||||
|
|
|
|||
|
|
@ -1,10 +1,8 @@
|
|||
// 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 Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Razor.Hosting;
|
||||
using Microsoft.AspNetCore.Razor.Language;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
using static Microsoft.AspNetCore.Razor.Hosting.TestRazorCompiledItem;
|
||||
|
||||
|
|
@ -14,15 +12,10 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal
|
|||
{
|
||||
public ChecksumValidatorTest()
|
||||
{
|
||||
FileProvider = new TestFileProvider();
|
||||
FileSystem = new FileProviderRazorProjectFileSystem(
|
||||
Mock.Of<IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == FileProvider),
|
||||
Mock.Of<IHostingEnvironment>(e => e.ContentRootPath == "BasePath"));
|
||||
ProjectFileSystem = new VirtualRazorProjectFileSystem();
|
||||
}
|
||||
|
||||
public RazorProjectFileSystem FileSystem { get; }
|
||||
|
||||
public TestFileProvider FileProvider { get; }
|
||||
public VirtualRazorProjectFileSystem ProjectFileSystem { get; }
|
||||
|
||||
[Fact]
|
||||
public void IsRecompilationSupported_NoChecksums_ReturnsFalse()
|
||||
|
|
@ -77,7 +70,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal
|
|||
var item = new TestRazorCompiledItem(typeof(string), "mvc.1.0.view", "/Views/Home/Index.cstml", new object[] { });
|
||||
|
||||
// Act
|
||||
var result = ChecksumValidator.IsItemValid(FileSystem, item);
|
||||
var result = ChecksumValidator.IsItemValid(ProjectFileSystem, item);
|
||||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
|
|
@ -94,7 +87,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal
|
|||
});
|
||||
|
||||
// Act
|
||||
var result = ChecksumValidator.IsItemValid(FileSystem, item);
|
||||
var result = ChecksumValidator.IsItemValid(ProjectFileSystem, item);
|
||||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
|
|
@ -110,10 +103,10 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal
|
|||
new RazorSourceChecksumAttribute("SHA1", GetChecksum("some content"), "/Views/Home/Index.cstml"),
|
||||
});
|
||||
|
||||
FileProvider.AddFile("/Views/Home/_ViewImports.cstml", "dkdkfkdf"); // This will be ignored
|
||||
ProjectFileSystem.Add(new TestRazorProjectItem("/Views/Home/_ViewImports.cstml", "dkdkfkdf")); // This will be ignored
|
||||
|
||||
// Act
|
||||
var result = ChecksumValidator.IsItemValid(FileSystem, item);
|
||||
var result = ChecksumValidator.IsItemValid(ProjectFileSystem, item);
|
||||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
|
|
@ -129,10 +122,10 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal
|
|||
new RazorSourceChecksumAttribute("SHA1", GetChecksum("some content"), "/Views/Home/Index.cstml"),
|
||||
});
|
||||
|
||||
FileProvider.AddFile("/Views/Home/Index.cstml", "other content");
|
||||
ProjectFileSystem.Add(new TestRazorProjectItem("/Views/Home/Index.cstml", "other content"));
|
||||
|
||||
// Act
|
||||
var result = ChecksumValidator.IsItemValid(FileSystem, item);
|
||||
var result = ChecksumValidator.IsItemValid(ProjectFileSystem, item);
|
||||
|
||||
// Assert
|
||||
Assert.False(result);
|
||||
|
|
@ -148,10 +141,10 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal
|
|||
new RazorSourceChecksumAttribute("SHA1", GetChecksum("some content"), "/Views/Home/Index.cstml"),
|
||||
});
|
||||
|
||||
FileProvider.AddFile("/Views/Home/Index.cstml", "some content");
|
||||
ProjectFileSystem.Add(new TestRazorProjectItem("/Views/Home/Index.cstml", "some content"));
|
||||
|
||||
// Act
|
||||
var result = ChecksumValidator.IsItemValid(FileSystem, item);
|
||||
var result = ChecksumValidator.IsItemValid(ProjectFileSystem, item);
|
||||
|
||||
// Assert
|
||||
Assert.False(result);
|
||||
|
|
@ -167,11 +160,11 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal
|
|||
new RazorSourceChecksumAttribute("SHA1", GetChecksum("some content"), "/Views/Home/Index.cstml"),
|
||||
});
|
||||
|
||||
FileProvider.AddFile("/Views/Home/Index.cstml", "some content");
|
||||
FileProvider.AddFile("/Views/Home/_ViewImports.cstml", "some other import");
|
||||
ProjectFileSystem.Add(new TestRazorProjectItem("/Views/Home/Index.cstml", "some content"));
|
||||
ProjectFileSystem.Add(new TestRazorProjectItem("/Views/Home/_ViewImports.cstml", "some other import"));
|
||||
|
||||
// Act
|
||||
var result = ChecksumValidator.IsItemValid(FileSystem, item);
|
||||
var result = ChecksumValidator.IsItemValid(ProjectFileSystem, item);
|
||||
|
||||
// Assert
|
||||
Assert.False(result);
|
||||
|
|
@ -188,12 +181,12 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal
|
|||
new RazorSourceChecksumAttribute("SHA1", GetChecksum("some content"), "/Views/Home/Index.cstml"),
|
||||
});
|
||||
|
||||
FileProvider.AddFile("/Views/Home/Index.cstml", "some content");
|
||||
FileProvider.AddFile("/Views/Home/_ViewImports.cstml", "some import");
|
||||
FileProvider.AddFile("/Views/_ViewImports.cstml", "some other import");
|
||||
ProjectFileSystem.Add(new TestRazorProjectItem("/Views/Home/Index.cstml", "some content"));
|
||||
ProjectFileSystem.Add(new TestRazorProjectItem("/Views/Home/_ViewImports.cstml", "some import"));
|
||||
ProjectFileSystem.Add(new TestRazorProjectItem("/Views/_ViewImports.cstml", "some other import"));
|
||||
|
||||
// Act
|
||||
var result = ChecksumValidator.IsItemValid(FileSystem, item);
|
||||
var result = ChecksumValidator.IsItemValid(ProjectFileSystem, item);
|
||||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
|
|
|
|||
|
|
@ -3,20 +3,16 @@
|
|||
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Mvc.Razor.Extensions;
|
||||
using Microsoft.AspNetCore.Razor.Language;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.Text;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.Razor.Internal
|
||||
{
|
||||
public class CompilerFailedExceptionFactoryTest
|
||||
{
|
||||
private readonly IHostingEnvironment _hostingEnvironment = Mock.Of<IHostingEnvironment>(e => e.ContentRootPath == "BasePath");
|
||||
|
||||
[Fact]
|
||||
public void GetCompilationFailedResult_ReadsRazorErrorsFromPage()
|
||||
{
|
||||
|
|
@ -24,11 +20,8 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal
|
|||
var viewPath = "/Views/Home/Index.cshtml";
|
||||
var razorEngine = RazorEngine.Create();
|
||||
|
||||
var fileProvider = new TestFileProvider();
|
||||
fileProvider.AddFile(viewPath, "<span name=\"@(User.Id\">");
|
||||
var accessor = Mock.Of<IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == fileProvider);
|
||||
|
||||
var fileSystem = new FileProviderRazorProjectFileSystem(accessor, _hostingEnvironment);
|
||||
var fileSystem = new VirtualRazorProjectFileSystem();
|
||||
fileSystem.Add(new TestRazorProjectItem(viewPath, "<span name=\"@(User.Id\">"));
|
||||
|
||||
var templateEngine = new MvcRazorTemplateEngine(razorEngine, fileSystem);
|
||||
var codeDocument = templateEngine.CreateCodeDocument(viewPath);
|
||||
|
|
@ -39,7 +32,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal
|
|||
|
||||
// Assert
|
||||
var failure = Assert.Single(compilationResult.CompilationFailures);
|
||||
Assert.Equal(Path.Combine("Views", "Home", "Index.cshtml"), failure.SourceFilePath);
|
||||
Assert.Equal(viewPath, failure.SourceFilePath);
|
||||
Assert.Collection(failure.Messages,
|
||||
message => Assert.StartsWith(
|
||||
@"Unterminated string literal.",
|
||||
|
|
@ -56,13 +49,10 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal
|
|||
var viewPath = "/Views/Home/Index.cshtml";
|
||||
var physicalPath = @"x:\myapp\views\home\index.cshtml";
|
||||
|
||||
var fileProvider = new TestFileProvider();
|
||||
var file = fileProvider.AddFile(viewPath, "<span name=\"@(User.Id\">");
|
||||
file.PhysicalPath = physicalPath;
|
||||
var accessor = Mock.Of<IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == fileProvider);
|
||||
var fileSystem = new VirtualRazorProjectFileSystem();
|
||||
fileSystem.Add(new TestRazorProjectItem(viewPath, "<span name=\"@(User.Id\">", physicalPath: physicalPath));
|
||||
|
||||
var razorEngine = RazorEngine.Create();
|
||||
var fileSystem = new FileProviderRazorProjectFileSystem(accessor, _hostingEnvironment);
|
||||
var templateEngine = new MvcRazorTemplateEngine(razorEngine, fileSystem);
|
||||
|
||||
var codeDocument = templateEngine.CreateCodeDocument(viewPath);
|
||||
|
|
@ -90,11 +80,8 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal
|
|||
</span>";
|
||||
|
||||
var razorEngine = RazorEngine.Create();
|
||||
var fileProvider = new TestFileProvider();
|
||||
fileProvider.AddFile(viewPath, fileContent);
|
||||
var accessor = Mock.Of<IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == fileProvider);
|
||||
|
||||
var fileSystem = new FileProviderRazorProjectFileSystem(accessor, _hostingEnvironment);
|
||||
var fileSystem = new VirtualRazorProjectFileSystem();
|
||||
fileSystem.Add(new TestRazorProjectItem(viewPath, fileContent));
|
||||
var templateEngine = new MvcRazorTemplateEngine(razorEngine, fileSystem);
|
||||
|
||||
var codeDocument = templateEngine.CreateCodeDocument(viewPath);
|
||||
|
|
@ -113,18 +100,15 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal
|
|||
{
|
||||
// Arrange
|
||||
var viewPath = "/Views/Home/Index.cshtml";
|
||||
var importsFilePath = @"x:\views\_MyImports.cshtml";
|
||||
var importsPath = "/Views/_MyImports.cshtml";
|
||||
var fileContent = "@ ";
|
||||
var importsContent = "@(abc";
|
||||
|
||||
var fileProvider = new TestFileProvider();
|
||||
fileProvider.AddFile(viewPath, fileContent);
|
||||
var importsFile = fileProvider.AddFile("/Views/_MyImports.cshtml", importsContent);
|
||||
importsFile.PhysicalPath = importsFilePath;
|
||||
var accessor = Mock.Of<IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == fileProvider);
|
||||
var fileSystem = new VirtualRazorProjectFileSystem();
|
||||
fileSystem.Add(new TestRazorProjectItem(viewPath, fileContent));
|
||||
fileSystem.Add(new TestRazorProjectItem("/Views/_MyImports.cshtml", importsContent));
|
||||
|
||||
var razorEngine = RazorEngine.Create();
|
||||
var fileSystem = new FileProviderRazorProjectFileSystem(accessor, _hostingEnvironment);
|
||||
var templateEngine = new MvcRazorTemplateEngine(razorEngine, fileSystem)
|
||||
{
|
||||
Options =
|
||||
|
|
@ -143,7 +127,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal
|
|||
compilationResult.CompilationFailures,
|
||||
failure =>
|
||||
{
|
||||
Assert.Equal(Path.Combine("Views", "Home", "Index.cshtml"), failure.SourceFilePath);
|
||||
Assert.Equal(viewPath, failure.SourceFilePath);
|
||||
Assert.Collection(failure.Messages,
|
||||
message =>
|
||||
{
|
||||
|
|
@ -153,7 +137,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal
|
|||
},
|
||||
failure =>
|
||||
{
|
||||
Assert.Equal(importsFilePath, failure.SourceFilePath);
|
||||
Assert.Equal(importsPath, failure.SourceFilePath);
|
||||
Assert.Collection(failure.Messages,
|
||||
message =>
|
||||
{
|
||||
|
|
@ -179,7 +163,6 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal
|
|||
GetRazorDiagnostic("message-3", SourceLocation.Undefined, length: -1),
|
||||
GetRazorDiagnostic("message-4", new SourceLocation(viewImportsPath, 1, 3, 8), length: 4),
|
||||
};
|
||||
var fileProvider = new TestFileProvider();
|
||||
|
||||
// Act
|
||||
var result = CompilationFailedExceptionFactory.Create(codeDocument, diagnostics);
|
||||
|
|
|
|||
|
|
@ -933,9 +933,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor
|
|||
.Setup(p => p.CreateFactory("/Views/_ViewStart.cshtml"))
|
||||
.Returns(GetPageFactoryResult(() => viewStart));
|
||||
|
||||
var fileProvider = new TestFileProvider();
|
||||
var accessor = Mock.Of<IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == fileProvider);
|
||||
var fileSystem = new FileProviderRazorProjectFileSystem(accessor, Mock.Of<IHostingEnvironment>());
|
||||
var fileSystem = new VirtualRazorProjectFileSystem();
|
||||
var viewEngine = CreateViewEngine(pageFactory.Object, fileSystem: fileSystem);
|
||||
var context = GetActionContext(_controllerTestContext);
|
||||
|
||||
|
|
@ -1385,9 +1383,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor
|
|||
Mock.Of<IRazorPageActivator>(),
|
||||
new HtmlTestEncoder(),
|
||||
GetOptionsAccessor(expanders: null),
|
||||
new FileProviderRazorProjectFileSystem(
|
||||
Mock.Of<IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == new TestFileProvider()),
|
||||
Mock.Of<IHostingEnvironment>()),
|
||||
new VirtualRazorProjectFileSystem(),
|
||||
loggerFactory,
|
||||
new DiagnosticListener("Microsoft.AspNetCore.Mvc.Razor"));
|
||||
|
||||
|
|
@ -1972,11 +1968,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor
|
|||
RazorProjectFileSystem fileSystem = null)
|
||||
{
|
||||
pageFactory = pageFactory ?? Mock.Of<IRazorPageFactoryProvider>();
|
||||
if (fileSystem == null)
|
||||
{
|
||||
var accessor = Mock.Of<IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == new TestFileProvider());
|
||||
fileSystem = new FileProviderRazorProjectFileSystem(accessor, Mock.Of<IHostingEnvironment>());
|
||||
}
|
||||
fileSystem = fileSystem ?? new VirtualRazorProjectFileSystem();
|
||||
return new TestableRazorViewEngine(pageFactory, GetOptionsAccessor(expanders), fileSystem);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,7 @@
|
|||
// 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 System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Microsoft.AspNetCore.Razor.Language;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
|
|
@ -19,7 +16,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
|||
public void TryGetPageDirective_FindsTemplate()
|
||||
{
|
||||
// Arrange
|
||||
var projectItem = new TestRazorProjectItem(@"@page ""Some/Path/{value}""
|
||||
var projectItem = new TestRazorProjectItem("Test.cshtml", @"@page ""Some/Path/{value}""
|
||||
The rest of the thing");
|
||||
var sink = new TestSink();
|
||||
var logger = new TestLogger("logger", sink, enabled: true);
|
||||
|
|
@ -34,7 +31,7 @@ The rest of the thing");
|
|||
public void TryGetPageDirective_NoNewLine()
|
||||
{
|
||||
// Arrange
|
||||
var projectItem = new TestRazorProjectItem(@"@page ""Some/Path/{value}""");
|
||||
var projectItem = new TestRazorProjectItem("Test.cshtml", @"@page ""Some/Path/{value}""");
|
||||
var sink = new TestSink();
|
||||
var logger = new TestLogger("logger", sink, enabled: true);
|
||||
|
||||
|
|
@ -48,7 +45,7 @@ The rest of the thing");
|
|||
public void TryGetPageDirective_JunkBeforeDirective()
|
||||
{
|
||||
// Arrange
|
||||
var projectItem = new TestRazorProjectItem(@"Not a directive @page ""Some/Path/{value}""");
|
||||
var projectItem = new TestRazorProjectItem("Test.cshtml", @"Not a directive @page ""Some/Path/{value}""");
|
||||
var sink = new TestSink();
|
||||
var logger = new TestLogger("logger", sink, enabled: true);
|
||||
|
||||
|
|
@ -67,7 +64,7 @@ The rest of the thing");
|
|||
var expected = "The page directive at 'Test.cshtml' is malformed. Please fix the following issues: The 'page' directive expects a string surrounded by double quotes.";
|
||||
var sink = new TestSink();
|
||||
var logger = new TestLogger("logger", sink, enabled: true);
|
||||
var projectItem = new TestRazorProjectItem($@"@page {inTemplate}");
|
||||
var projectItem = new TestRazorProjectItem("Test.cshtml", $@"@page {inTemplate}");
|
||||
|
||||
// Act & Assert
|
||||
Assert.True(PageDirectiveFeature.TryGetPageDirective(logger, projectItem, out var template));
|
||||
|
|
@ -87,7 +84,7 @@ The rest of the thing");
|
|||
var expected = "The page directive at 'Test.cshtml' is malformed. Please fix the following issues: The 'page' directive expects a string surrounded by double quotes.";
|
||||
var sink = new TestSink();
|
||||
var logger = new TestLogger("logger", sink, enabled: true);
|
||||
var projectItem = new TestRazorProjectItem(@"@page Some/Path/{value}");
|
||||
var projectItem = new TestRazorProjectItem("Test.cshtml", @"@page Some/Path/{value}");
|
||||
|
||||
// Act & Assert
|
||||
Assert.True(PageDirectiveFeature.TryGetPageDirective(logger, projectItem, out var template));
|
||||
|
|
@ -105,7 +102,7 @@ The rest of the thing");
|
|||
public void TryGetPageDirective_NewLineBeforeDirective()
|
||||
{
|
||||
// Arrange
|
||||
var projectItem = new TestRazorProjectItem("\n @page \"Some/Path/{value}\"");
|
||||
var projectItem = new TestRazorProjectItem("Test.cshtml", "\n @page \"Some/Path/{value}\"");
|
||||
var sink = new TestSink();
|
||||
var logger = new TestLogger("logger", sink, enabled: true);
|
||||
|
||||
|
|
@ -119,7 +116,7 @@ The rest of the thing");
|
|||
public void TryGetPageDirective_Directive_WithoutPathOrContent()
|
||||
{
|
||||
// Arrange
|
||||
var projectItem = new TestRazorProjectItem(@"@page");
|
||||
var projectItem = new TestRazorProjectItem("Test.cshtml", @"@page");
|
||||
|
||||
// Act & Assert
|
||||
Assert.True(PageDirectiveFeature.TryGetPageDirective(NullLogger.Instance, projectItem, out var template));
|
||||
|
|
@ -130,7 +127,7 @@ The rest of the thing");
|
|||
public void TryGetPageDirective_DirectiveWithContent_WithoutPath()
|
||||
{
|
||||
// Arrange
|
||||
var projectItem = new TestRazorProjectItem(@"@page
|
||||
var projectItem = new TestRazorProjectItem("Test.cshtml", @"@page
|
||||
Non-path things");
|
||||
var sink = new TestSink();
|
||||
var logger = new TestLogger("logger", sink, enabled: true);
|
||||
|
|
@ -145,7 +142,7 @@ Non-path things");
|
|||
public void TryGetPageDirective_NoDirective()
|
||||
{
|
||||
// Arrange
|
||||
var projectItem = new TestRazorProjectItem(@"This is junk
|
||||
var projectItem = new TestRazorProjectItem("Test.cshtml", @"This is junk
|
||||
Nobody will use it");
|
||||
var sink = new TestSink();
|
||||
var logger = new TestLogger("logger", sink, enabled: true);
|
||||
|
|
@ -156,34 +153,4 @@ Nobody will use it");
|
|||
Assert.Empty(sink.Writes);
|
||||
}
|
||||
}
|
||||
|
||||
public class TestRazorProjectItem : RazorProjectItem
|
||||
{
|
||||
private string _content;
|
||||
|
||||
public TestRazorProjectItem(string content)
|
||||
{
|
||||
_content = content;
|
||||
}
|
||||
|
||||
public override string BasePath => throw new NotImplementedException();
|
||||
|
||||
public override bool Exists => throw new NotImplementedException();
|
||||
|
||||
public override string FilePath => "Test.cshtml";
|
||||
|
||||
public override string PhysicalPath => null;
|
||||
|
||||
public override Stream Read()
|
||||
{
|
||||
if (_content == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new MemoryStream(Encoding.UTF8.GetBytes(_content));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,19 +4,16 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Mvc.ApplicationModels;
|
||||
using Microsoft.AspNetCore.Mvc.ApplicationParts;
|
||||
using Microsoft.AspNetCore.Mvc.Razor;
|
||||
using Microsoft.AspNetCore.Mvc.Razor.Compilation;
|
||||
using Microsoft.AspNetCore.Mvc.Razor.Internal;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure;
|
||||
using Microsoft.AspNetCore.Razor.Hosting;
|
||||
using Microsoft.AspNetCore.Razor.Language;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
using static Microsoft.AspNetCore.Razor.Hosting.TestRazorCompiledItem;
|
||||
|
||||
|
|
@ -141,10 +138,10 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
}),
|
||||
};
|
||||
|
||||
var fileProvider = new TestFileProvider();
|
||||
fileProvider.AddFile("/Pages/About.cshtml", "some other content");
|
||||
var fileSystem = new VirtualRazorProjectFileSystem();
|
||||
fileSystem.Add(new TestRazorProjectItem("/Pages/About.cshtml", "some other content"));
|
||||
|
||||
var provider = CreateProvider(descriptors: descriptors, fileProvider: fileProvider);
|
||||
var provider = CreateProvider(descriptors: descriptors, fileSystem: fileSystem);
|
||||
var context = new PageRouteModelProviderContext();
|
||||
|
||||
// Act
|
||||
|
|
@ -167,11 +164,11 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
}),
|
||||
};
|
||||
|
||||
var fileProvider = new TestFileProvider();
|
||||
fileProvider.AddFile("/Pages/About.cshtml", "some content");
|
||||
fileProvider.AddFile("/Pages/_ViewImports.cshtml", "some import");
|
||||
var fileSystem = new VirtualRazorProjectFileSystem();
|
||||
fileSystem.Add(new TestRazorProjectItem("/Pages/About.cshtml", "some content"));
|
||||
fileSystem.Add(new TestRazorProjectItem("/Pages/_ViewImports.cshtml", "some import"));
|
||||
|
||||
var provider = CreateProvider(descriptors: descriptors, fileProvider: fileProvider);
|
||||
var provider = CreateProvider(descriptors: descriptors, fileSystem: fileSystem);
|
||||
var context = new PageRouteModelProviderContext();
|
||||
|
||||
// Act
|
||||
|
|
@ -196,10 +193,10 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
}),
|
||||
};
|
||||
|
||||
var fileProvider = new TestFileProvider();
|
||||
fileProvider.AddFile("/Pages/_ViewImports.cshtml", "some other import");
|
||||
var fileSystem = new VirtualRazorProjectFileSystem();
|
||||
fileSystem.Add(new TestRazorProjectItem("/Pages/_ViewImports.cshtml", "some other import"));
|
||||
|
||||
var provider = CreateProvider(descriptors: descriptors, fileProvider: fileProvider);
|
||||
var provider = CreateProvider(descriptors: descriptors, fileSystem: fileSystem);
|
||||
var context = new PageRouteModelProviderContext();
|
||||
|
||||
// Act
|
||||
|
|
@ -625,13 +622,10 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
private TestCompiledPageRouteModelProvider CreateProvider(
|
||||
RazorPagesOptions options = null,
|
||||
IList<CompiledViewDescriptor> descriptors = null,
|
||||
TestFileProvider fileProvider = null)
|
||||
VirtualRazorProjectFileSystem fileSystem = null)
|
||||
{
|
||||
options = options ?? new RazorPagesOptions();
|
||||
fileProvider = fileProvider ?? new TestFileProvider();
|
||||
var fileSystem = new FileProviderRazorProjectFileSystem(
|
||||
Mock.Of<IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == fileProvider),
|
||||
Mock.Of<IHostingEnvironment>(e => e.ContentRootPath == "BasePath"));
|
||||
fileSystem = fileSystem ?? new VirtualRazorProjectFileSystem();
|
||||
var projectEngine = RazorProjectEngine.Create(RazorConfiguration.Default, fileSystem);
|
||||
|
||||
var provider = new TestCompiledPageRouteModelProvider(
|
||||
|
|
|
|||
|
|
@ -192,18 +192,15 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
.Setup(f => f.CreateFactory("/_ViewStart.cshtml"))
|
||||
.Returns(new RazorPageFactoryResult(new CompiledViewDescriptor(), factory2));
|
||||
|
||||
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 defaultFileSystem = new FileProviderRazorProjectFileSystem(accessor, _hostingEnvironment);
|
||||
var fileSystem = new VirtualRazorProjectFileSystem();
|
||||
fileSystem.Add(new TestRazorProjectItem("/Home/Path1/_ViewStart.cshtml", "content1"));
|
||||
fileSystem.Add(new TestRazorProjectItem("/_ViewStart.cshtml", "content2"));
|
||||
|
||||
var invokerProvider = CreateInvokerProvider(
|
||||
loader.Object,
|
||||
CreateActionDescriptorCollection(descriptor),
|
||||
razorPageFactoryProvider: razorPageFactoryProvider.Object,
|
||||
fileSystem: defaultFileSystem);
|
||||
fileSystem: fileSystem);
|
||||
|
||||
var context = new ActionInvokerProviderContext(new ActionContext()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,35 +1,24 @@
|
|||
// 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 System;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Mvc.ApplicationModels;
|
||||
using Microsoft.AspNetCore.Mvc.Razor;
|
||||
using Microsoft.Extensions.FileProviders;
|
||||
using Microsoft.AspNetCore.Razor.Language;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||
{
|
||||
public class RazorProjectPageRouteModelProviderTest
|
||||
{
|
||||
private readonly IHostingEnvironment _hostingEnvironment = Mock.Of<IHostingEnvironment>(e => e.ContentRootPath == "BasePath");
|
||||
|
||||
[Fact]
|
||||
public void OnProvidersExecuting_ReturnsPagesWithPageDirective()
|
||||
{
|
||||
// Arrange
|
||||
var fileProvider = new TestFileProvider();
|
||||
var file1 = fileProvider.AddFile("/Pages/Home.cshtml", "@page");
|
||||
var file2 = fileProvider.AddFile("/Pages/Test.cshtml", "Hello world");
|
||||
|
||||
var dir1 = fileProvider.AddDirectoryContent("/Pages", new IFileInfo[] { file1, file2 });
|
||||
fileProvider.AddDirectoryContent("/", new[] { dir1 });
|
||||
|
||||
var fileSystem = new TestRazorProjectFileSystem(fileProvider, _hostingEnvironment);
|
||||
var fileSystem = new VirtualRazorProjectFileSystem();
|
||||
fileSystem.Add(new TestRazorProjectItem("/Pages/Home.cshtml", "@page"));
|
||||
fileSystem.Add(new TestRazorProjectItem("/Pages/Test.cshtml", "Hello world"));
|
||||
|
||||
var optionsManager = Options.Create(new RazorPagesOptions());
|
||||
optionsManager.Value.RootDirectory = "/";
|
||||
|
|
@ -60,18 +49,11 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
public void OnProvidersExecuting_AddsPagesUnderAreas()
|
||||
{
|
||||
// Arrange
|
||||
var fileProvider = new TestFileProvider();
|
||||
var file1 = fileProvider.AddFile("Categories.cshtml", "@page");
|
||||
var file2 = fileProvider.AddFile("Index.cshtml", "@page");
|
||||
var file3 = fileProvider.AddFile("List.cshtml", "@page \"{sortOrder?}\"");
|
||||
var file4 = fileProvider.AddFile("_ViewStart.cshtml", "@page");
|
||||
var manageDir = fileProvider.AddDirectoryContent("/Areas/Products/Pages/Manage", new[] { file1 });
|
||||
var pagesDir = fileProvider.AddDirectoryContent("/Areas/Products/Pages", new IFileInfo[] { manageDir, file2, file3, file4 });
|
||||
var productsDir = fileProvider.AddDirectoryContent("/Areas/Products", new[] { pagesDir });
|
||||
var areasDir = fileProvider.AddDirectoryContent("/Areas", new[] { productsDir });
|
||||
var rootDir = fileProvider.AddDirectoryContent("/", new[] { areasDir });
|
||||
|
||||
var fileSystem = new TestRazorProjectFileSystem(fileProvider, _hostingEnvironment);
|
||||
var fileSystem = new VirtualRazorProjectFileSystem();
|
||||
fileSystem.Add(new TestRazorProjectItem("/Areas/Products/Pages/Manage/Categories.cshtml", "@page"));
|
||||
fileSystem.Add(new TestRazorProjectItem("/Areas/Products/Pages/Index.cshtml", "@page"));
|
||||
fileSystem.Add(new TestRazorProjectItem("/Areas/Products/Pages/List.cshtml", "@page \"{sortOrder?}\""));
|
||||
fileSystem.Add(new TestRazorProjectItem("/Areas/Products/Pages/_ViewStart.cshtml", "@page"));
|
||||
|
||||
var optionsManager = Options.Create(new RazorPagesOptions { AllowAreas = true });
|
||||
var provider = new RazorProjectPageRouteModelProvider(fileSystem, optionsManager, NullLoggerFactory.Instance);
|
||||
|
|
@ -82,24 +64,6 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
|
||||
// Assert
|
||||
Assert.Collection(context.RouteModels,
|
||||
model =>
|
||||
{
|
||||
Assert.Equal("/Areas/Products/Pages/Manage/Categories.cshtml", model.RelativePath);
|
||||
Assert.Equal("/Manage/Categories", model.ViewEnginePath);
|
||||
Assert.Collection(model.Selectors,
|
||||
selector => Assert.Equal("Products/Manage/Categories", selector.AttributeRouteModel.Template));
|
||||
Assert.Collection(model.RouteValues.OrderBy(k => k.Key),
|
||||
kvp =>
|
||||
{
|
||||
Assert.Equal("area", kvp.Key);
|
||||
Assert.Equal("Products", kvp.Value);
|
||||
},
|
||||
kvp =>
|
||||
{
|
||||
Assert.Equal("page", kvp.Key);
|
||||
Assert.Equal("/Manage/Categories", kvp.Value);
|
||||
});
|
||||
},
|
||||
model =>
|
||||
{
|
||||
Assert.Equal("/Areas/Products/Pages/Index.cshtml", model.RelativePath);
|
||||
|
|
@ -136,6 +100,24 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
Assert.Equal("page", kvp.Key);
|
||||
Assert.Equal("/List", kvp.Value);
|
||||
});
|
||||
},
|
||||
model =>
|
||||
{
|
||||
Assert.Equal("/Areas/Products/Pages/Manage/Categories.cshtml", model.RelativePath);
|
||||
Assert.Equal("/Manage/Categories", model.ViewEnginePath);
|
||||
Assert.Collection(model.Selectors,
|
||||
selector => Assert.Equal("Products/Manage/Categories", selector.AttributeRouteModel.Template));
|
||||
Assert.Collection(model.RouteValues.OrderBy(k => k.Key),
|
||||
kvp =>
|
||||
{
|
||||
Assert.Equal("area", kvp.Key);
|
||||
Assert.Equal("Products", kvp.Value);
|
||||
},
|
||||
kvp =>
|
||||
{
|
||||
Assert.Equal("page", kvp.Key);
|
||||
Assert.Equal("/Manage/Categories", kvp.Value);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -143,19 +125,12 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
public void OnProvidersExecuting_DoesNotAddPagesUnderAreas_WhenFeatureIsDisabled()
|
||||
{
|
||||
// Arrange
|
||||
var fileProvider = new TestFileProvider();
|
||||
var file1 = fileProvider.AddFile("Categories.cshtml", "@page");
|
||||
var file2 = fileProvider.AddFile("Index.cshtml", "@page");
|
||||
var file3 = fileProvider.AddFile("List.cshtml", "@page \"{sortOrder?}\"");
|
||||
var file4 = fileProvider.AddFile("About.cshtml", "@page");
|
||||
var manageDir = fileProvider.AddDirectoryContent("/Areas/Products/Pages/Manage", new[] { file1 });
|
||||
var areaPagesDir = fileProvider.AddDirectoryContent("/Areas/Products/Pages", new IFileInfo[] { manageDir, file2, file3, });
|
||||
var productsDir = fileProvider.AddDirectoryContent("/Areas/Products", new[] { areaPagesDir });
|
||||
var areasDir = fileProvider.AddDirectoryContent("/Areas", new[] { productsDir });
|
||||
var pagesDir = fileProvider.AddDirectoryContent("/Pages", new[] { file4 });
|
||||
var rootDir = fileProvider.AddDirectoryContent("/", new[] { areasDir, pagesDir });
|
||||
|
||||
var fileSystem = new TestRazorProjectFileSystem(fileProvider, _hostingEnvironment);
|
||||
var fileSystem = new VirtualRazorProjectFileSystem();
|
||||
fileSystem.Add(new TestRazorProjectItem("/Areas/Products/Pages/Manage/Categories.cshtml", "@page"));
|
||||
fileSystem.Add(new TestRazorProjectItem("/Areas/Products/Pages/Index.cshtml", "@page"));
|
||||
fileSystem.Add(new TestRazorProjectItem("/Areas/Products/Pages/List.cshtml", "@page \"{sortOrder?}\""));
|
||||
fileSystem.Add(new TestRazorProjectItem("/Areas/Products/Pages/_ViewStart.cshtml", "@page"));
|
||||
fileSystem.Add(new TestRazorProjectItem("/Pages/About.cshtml", "@page"));
|
||||
|
||||
var optionsManager = Options.Create(new RazorPagesOptions { AllowAreas = false });
|
||||
var provider = new RazorProjectPageRouteModelProvider(fileSystem, optionsManager, NullLoggerFactory.Instance);
|
||||
|
|
@ -179,17 +154,11 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
public void OnProvidersExecuting_DoesNotAddAreaAndNonAreaRoutesForAPage()
|
||||
{
|
||||
// Arrange
|
||||
var fileProvider = new TestFileProvider();
|
||||
var conformingFileUnderAreasDirectory = fileProvider.AddFile("Categories.cshtml", "@page");
|
||||
var fileSystem = new VirtualRazorProjectFileSystem();
|
||||
fileSystem.Add(new TestRazorProjectItem("/Areas/Products/Categories.cshtml", "@page"));
|
||||
// We shouldn't add a route for this.
|
||||
var nonConformingFileUnderAreasDirectory = fileProvider.AddFile("Home.cshtml", "@page");
|
||||
var rootFile = fileProvider.AddFile("About.cshtml", "@page");
|
||||
|
||||
var productsDir = fileProvider.AddDirectoryContent("/Areas/Products", new[] { conformingFileUnderAreasDirectory });
|
||||
var areasDir = fileProvider.AddDirectoryContent("/Areas", new IFileInfo[] { productsDir, nonConformingFileUnderAreasDirectory });
|
||||
var rootDir = fileProvider.AddDirectoryContent("/", new IFileInfo[] { areasDir, rootFile });
|
||||
|
||||
var fileSystem = new TestRazorProjectFileSystem(fileProvider, _hostingEnvironment);
|
||||
fileSystem.Add(new TestRazorProjectItem("/Areas/Home.cshtml", "@page"));
|
||||
fileSystem.Add(new TestRazorProjectItem("/About.cshtml", "@page"));
|
||||
|
||||
var optionsManager = Options.Create(new RazorPagesOptions
|
||||
{
|
||||
|
|
@ -242,16 +211,10 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
public void OnProvidersExecuting_AddsMultipleSelectorsForIndexPages()
|
||||
{
|
||||
// Arrange
|
||||
var fileProvider = new TestFileProvider();
|
||||
var file1 = fileProvider.AddFile("/Pages/Index.cshtml", "@page");
|
||||
var file2 = fileProvider.AddFile("/Pages/Test.cshtml", "Hello world");
|
||||
var file3 = fileProvider.AddFile("/Pages/Admin/Index.cshtml", "@page \"test\"");
|
||||
|
||||
var dir2 = fileProvider.AddDirectoryContent("/Pages/Admin", new[] { file3 });
|
||||
var dir1 = fileProvider.AddDirectoryContent("/Pages", new IFileInfo[] { dir2, file1, file2 });
|
||||
fileProvider.AddDirectoryContent("/", new[] { dir1 });
|
||||
|
||||
var fileSystem = new TestRazorProjectFileSystem(fileProvider, _hostingEnvironment);
|
||||
var fileSystem = new VirtualRazorProjectFileSystem();
|
||||
fileSystem.Add(new TestRazorProjectItem("/Pages/Index.cshtml", "@page"));
|
||||
fileSystem.Add(new TestRazorProjectItem("/Pages/Test.cshtml", "Hello world"));
|
||||
fileSystem.Add(new TestRazorProjectItem("/Pages/Admin/Index.cshtml", "@page \"test\""));
|
||||
|
||||
var optionsManager = Options.Create(new RazorPagesOptions());
|
||||
optionsManager.Value.RootDirectory = "/";
|
||||
|
|
@ -263,14 +226,6 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
|
||||
// Assert
|
||||
Assert.Collection(context.RouteModels,
|
||||
model =>
|
||||
{
|
||||
Assert.Equal("/Pages/Admin/Index.cshtml", model.RelativePath);
|
||||
Assert.Equal("/Pages/Admin/Index", model.ViewEnginePath);
|
||||
Assert.Collection(model.Selectors,
|
||||
selector => Assert.Equal("Pages/Admin/Index/test", selector.AttributeRouteModel.Template),
|
||||
selector => Assert.Equal("Pages/Admin/test", selector.AttributeRouteModel.Template));
|
||||
},
|
||||
model =>
|
||||
{
|
||||
Assert.Equal("/Pages/Index.cshtml", model.RelativePath);
|
||||
|
|
@ -278,6 +233,14 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
Assert.Collection(model.Selectors,
|
||||
selector => Assert.Equal("Pages/Index", selector.AttributeRouteModel.Template),
|
||||
selector => Assert.Equal("Pages", selector.AttributeRouteModel.Template));
|
||||
},
|
||||
model =>
|
||||
{
|
||||
Assert.Equal("/Pages/Admin/Index.cshtml", model.RelativePath);
|
||||
Assert.Equal("/Pages/Admin/Index", model.ViewEnginePath);
|
||||
Assert.Collection(model.Selectors,
|
||||
selector => Assert.Equal("Pages/Admin/Index/test", selector.AttributeRouteModel.Template),
|
||||
selector => Assert.Equal("Pages/Admin/test", selector.AttributeRouteModel.Template));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -285,11 +248,8 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
public void OnProvidersExecuting_AllowsRouteTemplateWithOverridePattern()
|
||||
{
|
||||
// Arrange
|
||||
var fileProvider = new TestFileProvider();
|
||||
var file = fileProvider.AddFile("/Index.cshtml", "@page \"/custom-route\"");
|
||||
fileProvider.AddDirectoryContent("/", new[] { file });
|
||||
|
||||
var fileSystem = new TestRazorProjectFileSystem(fileProvider, _hostingEnvironment);
|
||||
var fileSystem = new VirtualRazorProjectFileSystem();
|
||||
fileSystem.Add(new TestRazorProjectItem("/Index.cshtml", "@page \"/custom-route\""));
|
||||
|
||||
var optionsManager = Options.Create(new RazorPagesOptions());
|
||||
optionsManager.Value.RootDirectory = "/";
|
||||
|
|
@ -316,16 +276,9 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
public void OnProvidersExecuting_SkipsPagesStartingWithUnderscore()
|
||||
{
|
||||
// Arrange
|
||||
var fileProvider = new TestFileProvider();
|
||||
var dir1 = fileProvider.AddDirectoryContent("/Pages",
|
||||
new[]
|
||||
{
|
||||
fileProvider.AddFile("/Pages/Home.cshtml", "@page"),
|
||||
fileProvider.AddFile("/Pages/_Layout.cshtml", "@page")
|
||||
});
|
||||
fileProvider.AddDirectoryContent("/", new[] { dir1 });
|
||||
|
||||
var fileSystem = new TestRazorProjectFileSystem(fileProvider, _hostingEnvironment);
|
||||
var fileSystem = new VirtualRazorProjectFileSystem();
|
||||
fileSystem.Add(new TestRazorProjectItem("/Pages/Home.cshtml", "@page"));
|
||||
fileSystem.Add(new TestRazorProjectItem("/Pages/_Layout.cshtml", "@page"));
|
||||
|
||||
var optionsManager = Options.Create(new RazorPagesOptions());
|
||||
optionsManager.Value.RootDirectory = "/";
|
||||
|
|
@ -347,23 +300,12 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
public void OnProvidersExecuting_DiscoversFilesUnderBasePath()
|
||||
{
|
||||
// Arrange
|
||||
var fileProvider = new TestFileProvider();
|
||||
var dir1 = fileProvider.AddDirectoryContent("/Pages",
|
||||
new[]
|
||||
{
|
||||
fileProvider.AddFile("/Pages/Index.cshtml", "@page"),
|
||||
fileProvider.AddFile("/Pages/_Layout.cshtml", "@page")
|
||||
});
|
||||
var dir2 = fileProvider.AddDirectoryContent("/NotPages",
|
||||
new[]
|
||||
{
|
||||
fileProvider.AddFile("/NotPages/Index.cshtml", "@page"),
|
||||
fileProvider.AddFile("/NotPages/_Layout.cshtml", "@page")
|
||||
});
|
||||
var rootFile = fileProvider.AddFile("/Index.cshtml", "@page");
|
||||
fileProvider.AddDirectoryContent("/", new IFileInfo[] { rootFile, dir1, dir2 });
|
||||
|
||||
var fileSystem = new TestRazorProjectFileSystem(fileProvider, _hostingEnvironment);
|
||||
var fileSystem = new VirtualRazorProjectFileSystem();
|
||||
fileSystem.Add(new TestRazorProjectItem("/Pages/Index.cshtml", "@page"));
|
||||
fileSystem.Add(new TestRazorProjectItem("/Pages/_Layout.cshtml", "@page"));
|
||||
fileSystem.Add(new TestRazorProjectItem("/NotPages/Index.cshtml", "@page"));
|
||||
fileSystem.Add(new TestRazorProjectItem("/NotPages/_Layout.cshtml", "@page"));
|
||||
fileSystem.Add(new TestRazorProjectItem("/Index.cshtml", "@page"));
|
||||
|
||||
var optionsManager = Options.Create(new RazorPagesOptions());
|
||||
optionsManager.Value.RootDirectory = "/Pages";
|
||||
|
|
@ -385,14 +327,9 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
public void OnProvidersExecuting_DoesNotAddPageDirectivesIfItAlreadyExists()
|
||||
{
|
||||
// Arrange
|
||||
var fileProvider = new TestFileProvider();
|
||||
var file1 = fileProvider.AddFile("/Pages/Home.cshtml", "@page");
|
||||
var file2 = fileProvider.AddFile("/Pages/Test.cshtml", "@page");
|
||||
|
||||
var dir1 = fileProvider.AddDirectoryContent("/Pages", new IFileInfo[] { file1, file2 });
|
||||
fileProvider.AddDirectoryContent("/", new[] { dir1 });
|
||||
|
||||
var fileSystem = new TestRazorProjectFileSystem(fileProvider, _hostingEnvironment);
|
||||
var fileSystem = new VirtualRazorProjectFileSystem();
|
||||
fileSystem.Add(new TestRazorProjectItem("/Pages/Home.cshtml", "@page"));
|
||||
fileSystem.Add(new TestRazorProjectItem("/Pages/Test.cshtml", "@page"));
|
||||
|
||||
var optionsManager = Options.Create(new RazorPagesOptions());
|
||||
optionsManager.Value.RootDirectory = "/";
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Html.Abstractions" Version="$(MicrosoftAspNetCoreHtmlAbstractionsPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Razor.Runtime" Version="$(MicrosoftAspNetCoreRazorRuntimePackageVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Razor.Language" Version="$(MicrosoftAspNetCoreRazorLanguagePackageVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Testing" Version="$(MicrosoftAspNetCoreTestingPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="$(MicrosoftExtensionsDependencyInjectionPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.FileProviders.Abstractions" Version="$(MicrosoftExtensionsFileProvidersAbstractionsPackageVersion)" />
|
||||
|
|
|
|||
|
|
@ -0,0 +1,44 @@
|
|||
// 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 System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language
|
||||
{
|
||||
public class TestRazorProjectItem : RazorProjectItem
|
||||
{
|
||||
public TestRazorProjectItem(
|
||||
string filePath,
|
||||
string content = "Default content",
|
||||
string physicalPath = null,
|
||||
string relativePhysicalPath = null,
|
||||
string basePath = "/")
|
||||
{
|
||||
FilePath = filePath;
|
||||
PhysicalPath = physicalPath;
|
||||
RelativePhysicalPath = relativePhysicalPath;
|
||||
BasePath = basePath;
|
||||
Content = content;
|
||||
}
|
||||
|
||||
public override string BasePath { get; }
|
||||
|
||||
public override string FilePath { get; }
|
||||
|
||||
public override string PhysicalPath { get; }
|
||||
|
||||
public override string RelativePhysicalPath { get; }
|
||||
|
||||
public override bool Exists { get; } = true;
|
||||
|
||||
public string Content { get; set; }
|
||||
|
||||
public override Stream Read()
|
||||
{
|
||||
var stream = new MemoryStream(Encoding.UTF8.GetBytes(Content));
|
||||
|
||||
return stream;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,233 @@
|
|||
// 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 System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language
|
||||
{
|
||||
public class VirtualRazorProjectFileSystem : RazorProjectFileSystem
|
||||
{
|
||||
private readonly DirectoryNode _root = new DirectoryNode("/");
|
||||
|
||||
public override IEnumerable<RazorProjectItem> EnumerateItems(string basePath)
|
||||
{
|
||||
basePath = NormalizeAndEnsureValidPath(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);
|
||||
}
|
||||
|
||||
public void Add(RazorProjectItem projectItem)
|
||||
{
|
||||
if (projectItem == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(projectItem));
|
||||
}
|
||||
|
||||
var filePath = NormalizeAndEnsureValidPath(projectItem.FilePath);
|
||||
_root.AddFile(new FileNode(filePath, projectItem));
|
||||
}
|
||||
|
||||
// Internal for testing
|
||||
[DebuggerDisplay("{Path}")]
|
||||
internal class DirectoryNode
|
||||
{
|
||||
public DirectoryNode(string path)
|
||||
{
|
||||
Path = path;
|
||||
}
|
||||
|
||||
public string Path { get; }
|
||||
|
||||
public List<DirectoryNode> Directories { get; } = new List<DirectoryNode>();
|
||||
|
||||
public List<FileNode> Files { get; } = new List<FileNode>();
|
||||
|
||||
public void AddFile(FileNode fileNode)
|
||||
{
|
||||
var filePath = fileNode.Path;
|
||||
if (!filePath.StartsWith(Path, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
throw new InvalidOperationException($"File {fileNode.Path} does not belong to {Path}.");
|
||||
}
|
||||
|
||||
// Look for the first / that appears in the path after the current directory path.
|
||||
var directoryPath = GetDirectoryPath(filePath);
|
||||
var directory = GetOrAddDirectory(this, directoryPath, createIfNotExists: true);
|
||||
Debug.Assert(directory != null);
|
||||
directory.Files.Add(fileNode);
|
||||
}
|
||||
|
||||
public DirectoryNode GetDirectory(string path)
|
||||
{
|
||||
if (!path.StartsWith(Path, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
throw new InvalidOperationException($"File {path} does not belong to {Path}.");
|
||||
}
|
||||
|
||||
return GetOrAddDirectory(this, path);
|
||||
}
|
||||
|
||||
public IEnumerable<RazorProjectItem> EnumerateItems()
|
||||
{
|
||||
foreach (var file in Files)
|
||||
{
|
||||
yield return file.ProjectItem;
|
||||
}
|
||||
|
||||
foreach (var directory in Directories)
|
||||
{
|
||||
foreach (var file in directory.EnumerateItems())
|
||||
{
|
||||
yield return file;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public RazorProjectItem GetItem(string path)
|
||||
{
|
||||
if (!path.StartsWith(Path, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
throw new InvalidOperationException($"File {path} does not belong to {Path}.");
|
||||
}
|
||||
|
||||
var directoryPath = GetDirectoryPath(path);
|
||||
var directory = GetOrAddDirectory(this, directoryPath);
|
||||
if (directory == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach (var file in directory.Files)
|
||||
{
|
||||
var filePath = file.Path;
|
||||
var directoryLength = directory.Path.Length;
|
||||
|
||||
// path, filePath -> /Views/Home/Index.cshtml
|
||||
// directory.Path -> /Views/Home/
|
||||
// We only need to match the file name portion since we've already matched the directory segment.
|
||||
if (string.Compare(path, directoryLength, filePath, directoryLength, path.Length - directoryLength, StringComparison.OrdinalIgnoreCase) == 0)
|
||||
{
|
||||
return file.ProjectItem;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static string GetDirectoryPath(string path)
|
||||
{
|
||||
// /dir1/dir2/file.cshtml -> /dir1/dir2/
|
||||
var fileNameIndex = path.LastIndexOf('/');
|
||||
if (fileNameIndex == -1)
|
||||
{
|
||||
return path;
|
||||
}
|
||||
|
||||
return path.Substring(0, fileNameIndex + 1);
|
||||
}
|
||||
|
||||
private static DirectoryNode GetOrAddDirectory(
|
||||
DirectoryNode directory,
|
||||
string path,
|
||||
bool createIfNotExists = false)
|
||||
{
|
||||
Debug.Assert(!string.IsNullOrEmpty(path));
|
||||
if (path[path.Length - 1] != '/')
|
||||
{
|
||||
path += '/';
|
||||
}
|
||||
|
||||
int index;
|
||||
while ((index = path.IndexOf('/', directory.Path.Length)) != -1 && index != path.Length)
|
||||
{
|
||||
var subDirectory = FindSubDirectory(directory, path);
|
||||
|
||||
if (subDirectory == null)
|
||||
{
|
||||
if (createIfNotExists)
|
||||
{
|
||||
var directoryPath = path.Substring(0, index + 1); // + 1 to include trailing slash
|
||||
subDirectory = new DirectoryNode(directoryPath);
|
||||
directory.Directories.Add(subDirectory);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
directory = subDirectory;
|
||||
}
|
||||
|
||||
return directory;
|
||||
}
|
||||
|
||||
private static DirectoryNode FindSubDirectory(DirectoryNode parentDirectory, string path)
|
||||
{
|
||||
for (var i = 0; i < parentDirectory.Directories.Count; i++)
|
||||
{
|
||||
// ParentDirectory.Path -> /Views/Home/
|
||||
// CurrentDirectory.Path -> /Views/Home/SubDir/
|
||||
// Path -> /Views/Home/SubDir/MorePath/File.cshtml
|
||||
// Each invocation of FindSubDirectory returns the immediate subdirectory along the path to the file.
|
||||
|
||||
var currentDirectory = parentDirectory.Directories[i];
|
||||
var directoryPath = currentDirectory.Path;
|
||||
var startIndex = parentDirectory.Path.Length;
|
||||
var directoryNameLength = directoryPath.Length - startIndex;
|
||||
|
||||
if (string.Compare(path, startIndex, directoryPath, startIndex, directoryPath.Length - startIndex, StringComparison.OrdinalIgnoreCase) == 0)
|
||||
{
|
||||
return currentDirectory;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Internal for testing
|
||||
[DebuggerDisplay("{Path}")]
|
||||
internal struct FileNode
|
||||
{
|
||||
public FileNode(string path, RazorProjectItem projectItem)
|
||||
{
|
||||
Path = path;
|
||||
ProjectItem = projectItem;
|
||||
}
|
||||
|
||||
public string Path { get; }
|
||||
|
||||
public RazorProjectItem ProjectItem { get; }
|
||||
}
|
||||
|
||||
private class NotFoundProjectItem : RazorProjectItem
|
||||
{
|
||||
public NotFoundProjectItem(string basePath, string path)
|
||||
{
|
||||
BasePath = basePath;
|
||||
FilePath = path;
|
||||
}
|
||||
|
||||
public override string BasePath { get; }
|
||||
|
||||
public override string FilePath { get; }
|
||||
|
||||
public override bool Exists => false;
|
||||
|
||||
public override string PhysicalPath => throw new NotSupportedException();
|
||||
|
||||
public override Stream Read() => throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue