|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using Microsoft.AspNetCore.Mvc.ApplicationParts;
using Microsoft.Extensions.Logging.Abstractions;
namespace Microsoft.AspNetCore.Mvc.Razor.Compilation;
public class DefaultViewCompilerTest
{
[Fact]
public async Task CompileAsync_ReturnsResultWithNullAttribute_IfFileIsNotFoundInFileSystem()
{
// Arrange
var path = "/file/does-not-exist";
var viewCompiler = GetViewCompiler();
// Act
var result1 = await viewCompiler.CompileAsync(path);
var result2 = await viewCompiler.CompileAsync(path);
// Assert
Assert.Empty(result1.ExpirationTokens);
}
[Fact]
public async Task CompileAsync_ReturnsCompiledViews()
{
// Arrange
var path = "/Views/Home/Index.cshtml";
var compiledView = new CompiledViewDescriptor
{
RelativePath = path,
};
var viewCompiler = GetViewCompiler(compiledViews: new[] { compiledView });
// Act
var result = await viewCompiler.CompileAsync(path);
// Assert
Assert.Same(compiledView, result);
// This view doesn't have checksums so it can't be recompiled.
Assert.Null(compiledView.ExpirationTokens);
}
[Theory]
[InlineData("/views/home/index.cshtml")]
[InlineData("/VIEWS/HOME/INDEX.CSHTML")]
[InlineData("/viEws/HoME/inDex.cshtml")]
public async Task CompileAsync_PerformsCaseInsensitiveLookupsForCompiledViews(string lookupPath)
{
// Arrange
var path = "/Views/Home/Index.cshtml";
var precompiledView = new CompiledViewDescriptor
{
RelativePath = path,
};
var viewCompiler = GetViewCompiler(compiledViews: new[] { precompiledView });
// Act
var result = await viewCompiler.CompileAsync(lookupPath);
// Assert
Assert.Same(precompiledView, result);
}
[Fact]
public async Task CompileAsync_PerformsCaseInsensitiveLookupsForCompiledViews_WithNonNormalizedPaths()
{
// Arrange
var path = "/Views/Home/Index.cshtml";
var compiledView = new CompiledViewDescriptor
{
RelativePath = path,
};
var viewCompiler = GetViewCompiler(compiledViews: new[] { compiledView });
// Act
var result = await viewCompiler.CompileAsync("Views\\Home\\Index.cshtml");
// Assert
Assert.Same(compiledView, result);
}
[Fact]
public async Task CompileAsync_DiscoversHotReloadedTypes()
{
// Arrange
var path = "/Views/Home/Index.cshtml";
var compiledView = new CompiledViewDescriptor
{
RelativePath = path,
};
var compiledViews = new List<CompiledViewDescriptor>
{
compiledView,
};
var viewCompiler = GetViewCompiler(compiledViews);
// Act - 1
var result = await viewCompiler.CompileAsync(path);
// Assert - 1
Assert.Same(compiledView, result);
// Act - 2
var hotReloaded = new CompiledViewDescriptor { RelativePath = path };
compiledViews[0] = hotReloaded;
viewCompiler.ClearCache();
result = await viewCompiler.CompileAsync(path);
// Assert - 2
Assert.Same(hotReloaded, result);
}
private static TestRazorViewCompiler GetViewCompiler(IList<CompiledViewDescriptor> compiledViews = null)
{
compiledViews = compiledViews ?? Array.Empty<CompiledViewDescriptor>();
var viewCompiler = new TestRazorViewCompiler(compiledViews);
return viewCompiler;
}
private class TestRazorViewCompiler : DefaultViewCompiler
{
public TestRazorViewCompiler(IList<CompiledViewDescriptor> compiledViews) :
base(GetApplicationPartManager(new TestViewsFeatureProvider { CompiledViews = compiledViews }), NullLogger<DefaultViewCompiler>.Instance)
{
}
public TestRazorViewCompiler(TestViewsFeatureProvider featureProvider) :
base(GetApplicationPartManager(featureProvider), NullLogger<DefaultViewCompiler>.Instance)
{
}
private static ApplicationPartManager GetApplicationPartManager(TestViewsFeatureProvider featureProvider)
{
var manager = new ApplicationPartManager();
manager.FeatureProviders.Add(featureProvider);
return manager;
}
}
private class TestViewsFeatureProvider : IApplicationFeatureProvider<ViewsFeature>
{
public IList<CompiledViewDescriptor> CompiledViews { get; init; }
public void PopulateFeature(IEnumerable<ApplicationPart> parts, ViewsFeature feature)
{
foreach (var item in CompiledViews)
{
feature.ViewDescriptors.Add(item);
}
}
}
}
|