Move FileSystemRazorProject into Razor.Evolution
Add tests
This commit is contained in:
parent
c83741f11c
commit
12a502d775
|
|
@ -0,0 +1,69 @@
|
||||||
|
// 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.Evolution
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A <see cref="RazorProject"/> implementation over the physical file system.
|
||||||
|
/// </summary>
|
||||||
|
public class FileSystemRazorProject : RazorProject
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of <see cref="FileSystemRazorProject"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="root">The directory to root the file system at.</param>
|
||||||
|
public FileSystemRazorProject(string root)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(root))
|
||||||
|
{
|
||||||
|
throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, nameof(root));
|
||||||
|
}
|
||||||
|
|
||||||
|
Root = root.TrimEnd('/', '\\');
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The root of the file system.
|
||||||
|
/// </summary>
|
||||||
|
public string Root { get; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override IEnumerable<RazorProjectItem> EnumerateItems(string basePath)
|
||||||
|
{
|
||||||
|
EnsureValidPath(basePath);
|
||||||
|
|
||||||
|
Debug.Assert(basePath.StartsWith("/"));
|
||||||
|
var absoluteBasePath = Path.Combine(Root, basePath.Substring(1));
|
||||||
|
|
||||||
|
var directory = new DirectoryInfo(absoluteBasePath);
|
||||||
|
if (!directory.Exists)
|
||||||
|
{
|
||||||
|
return Enumerable.Empty<RazorProjectItem>();
|
||||||
|
}
|
||||||
|
|
||||||
|
return directory
|
||||||
|
.EnumerateFiles("*.cshtml", SearchOption.AllDirectories)
|
||||||
|
.Select(file =>
|
||||||
|
{
|
||||||
|
var relativePath = file.FullName.Substring(absoluteBasePath.Length).Replace(Path.DirectorySeparatorChar, '/');
|
||||||
|
return new FileSystemRazorProjectItem(basePath, relativePath, file);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override RazorProjectItem GetItem(string path)
|
||||||
|
{
|
||||||
|
EnsureValidPath(path);
|
||||||
|
|
||||||
|
Debug.Assert(path.StartsWith("/"));
|
||||||
|
var absolutePath = Path.Combine(Root, path.Substring(1));
|
||||||
|
return new FileSystemRazorProjectItem("/", path, new FileInfo(absolutePath));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Razor.Evolution
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// An implementation of <see cref="RazorProjectItem"/> using <see cref="FileInfo"/>.
|
||||||
|
/// </summary>
|
||||||
|
public class FileSystemRazorProjectItem : RazorProjectItem
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of <see cref="FileSystemRazorProjectItem"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="basePath">The base path.</param>
|
||||||
|
/// <param name="path">The path.</param>
|
||||||
|
/// <param name="file">The <see cref="FileInfo"/>.</param>
|
||||||
|
public FileSystemRazorProjectItem(string basePath, string path, FileInfo file)
|
||||||
|
{
|
||||||
|
BasePath = basePath;
|
||||||
|
Path = path;
|
||||||
|
File = file;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the <see cref="FileInfo"/>.
|
||||||
|
/// </summary>
|
||||||
|
public FileInfo File { get; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override string BasePath { get; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override string Path { get; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override bool Exists => File.Exists;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override string Filename => File.Name;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override string PhysicalPath => File.FullName;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override Stream Read() => File.OpenRead();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -8,8 +8,17 @@ using Microsoft.AspNetCore.Razor.Evolution.Intermediate;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Razor.Evolution
|
namespace Microsoft.AspNetCore.Razor.Evolution
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Extension methods to <see cref="IRazorEngineBuilder" />.
|
||||||
|
/// </summary>
|
||||||
public static class RazorEngineBuilderExtensions
|
public static class RazorEngineBuilderExtensions
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Adds the specified <see cref="DirectiveDescriptor"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="builder">The <see cref="IRazorEngineBuilder"/>.</param>
|
||||||
|
/// <param name="directive">The <see cref="DirectiveDescriptor"/> to add.</param>
|
||||||
|
/// <returns>The <see cref="IRazorEngineBuilder"/>.</returns>
|
||||||
public static IRazorEngineBuilder AddDirective(this IRazorEngineBuilder builder, DirectiveDescriptor directive)
|
public static IRazorEngineBuilder AddDirective(this IRazorEngineBuilder builder, DirectiveDescriptor directive)
|
||||||
{
|
{
|
||||||
if (builder == null)
|
if (builder == null)
|
||||||
|
|
@ -28,6 +37,12 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds the specified <see cref="IRuntimeTargetExtension"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="builder">The <see cref="IRazorEngineBuilder"/>.</param>
|
||||||
|
/// <param name="extension">The <see cref="IRuntimeTargetExtension"/> to add.</param>
|
||||||
|
/// <returns>The <see cref="IRazorEngineBuilder"/>.</returns>
|
||||||
public static IRazorEngineBuilder AddTargetExtension(this IRazorEngineBuilder builder, IRuntimeTargetExtension extension)
|
public static IRazorEngineBuilder AddTargetExtension(this IRazorEngineBuilder builder, IRuntimeTargetExtension extension)
|
||||||
{
|
{
|
||||||
if (builder == null)
|
if (builder == null)
|
||||||
|
|
@ -46,6 +61,12 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the base type for generated types.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="builder">The <see cref="IRazorEngineBuilder"/>.</param>
|
||||||
|
/// <param name="baseType">The name of the base type.</param>
|
||||||
|
/// <returns>The <see cref="IRazorEngineBuilder"/>.</returns>
|
||||||
public static IRazorEngineBuilder SetBaseType(this IRazorEngineBuilder builder, string baseType)
|
public static IRazorEngineBuilder SetBaseType(this IRazorEngineBuilder builder, string baseType)
|
||||||
{
|
{
|
||||||
if (builder == null)
|
if (builder == null)
|
||||||
|
|
@ -58,17 +79,13 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IRazorEngineBuilder SetClassName(this IRazorEngineBuilder builder, string className)
|
/// <summary>
|
||||||
{
|
/// Registers a class configuration delegate that gets invoked during code generation.
|
||||||
if (builder == null)
|
/// </summary>
|
||||||
{
|
/// <param name="builder">The <see cref="IRazorEngineBuilder"/>.</param>
|
||||||
throw new ArgumentNullException(nameof(builder));
|
/// <param name="configureClass"><see cref="Action"/> invoked to configure
|
||||||
}
|
/// <see cref="ClassDeclarationIRNode"/> during code generation.</param>
|
||||||
|
/// <returns>The <see cref="IRazorEngineBuilder"/>.</returns>
|
||||||
ConfigureClass(builder, (document, @class) => @class.Name = className);
|
|
||||||
return builder;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IRazorEngineBuilder ConfigureClass(
|
public static IRazorEngineBuilder ConfigureClass(
|
||||||
this IRazorEngineBuilder builder,
|
this IRazorEngineBuilder builder,
|
||||||
Action<RazorCodeDocument, ClassDeclarationIRNode> configureClass)
|
Action<RazorCodeDocument, ClassDeclarationIRNode> configureClass)
|
||||||
|
|
@ -88,6 +105,12 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the namespace for generated types.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="builder">The <see cref="IRazorEngineBuilder"/>.</param>
|
||||||
|
/// <param name="namespaceName">The name of the namespace.</param>
|
||||||
|
/// <returns>The <see cref="IRazorEngineBuilder"/>.</returns>
|
||||||
public static IRazorEngineBuilder SetNamespace(this IRazorEngineBuilder builder, string namespaceName)
|
public static IRazorEngineBuilder SetNamespace(this IRazorEngineBuilder builder, string namespaceName)
|
||||||
{
|
{
|
||||||
if (builder == null)
|
if (builder == null)
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
@ -35,22 +34,21 @@ namespace RazorPageGenerator
|
||||||
@class.AccessModifier = "internal";
|
@class.AccessModifier = "internal";
|
||||||
});
|
});
|
||||||
|
|
||||||
builder.Features.Add(new RemovePragamaChecksumFeature());
|
builder.Features.Add(new RemovePragmaChecksumFeature());
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
var viewDirectories = Directory.EnumerateDirectories(targetProjectDirectory, "Views", SearchOption.AllDirectories);
|
var viewDirectories = Directory.EnumerateDirectories(targetProjectDirectory, "Views", SearchOption.AllDirectories);
|
||||||
|
var razorProject = new FileSystemRazorProject(targetProjectDirectory);
|
||||||
|
var templateEngine = new RazorTemplateEngine(razorEngine, razorProject);
|
||||||
|
|
||||||
var fileCount = 0;
|
var fileCount = 0;
|
||||||
foreach (var viewDir in viewDirectories)
|
foreach (var viewDir in viewDirectories)
|
||||||
{
|
{
|
||||||
Console.WriteLine();
|
Console.WriteLine();
|
||||||
Console.WriteLine(" Generating code files for views in {0}", viewDir);
|
Console.WriteLine(" Generating code files for views in {0}", viewDir);
|
||||||
var razorProject = new FileSystemRazorProject(viewDir);
|
var viewDirPath = viewDir.Substring(targetProjectDirectory.Length).Replace('\\', '/');
|
||||||
var templateEngine = new RazorTemplateEngine(razorEngine, razorProject);
|
var cshtmlFiles = razorProject.EnumerateItems(viewDirPath).Cast<FileSystemRazorProjectItem>();
|
||||||
|
|
||||||
|
|
||||||
var cshtmlFiles = razorProject.EnumerateItems("");
|
|
||||||
|
|
||||||
if (!cshtmlFiles.Any())
|
if (!cshtmlFiles.Any())
|
||||||
{
|
{
|
||||||
|
|
@ -72,69 +70,37 @@ namespace RazorPageGenerator
|
||||||
Console.WriteLine();
|
Console.WriteLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void GenerateCodeFile(RazorTemplateEngine templateEngine, RazorProjectItem projectItem)
|
private static void GenerateCodeFile(RazorTemplateEngine templateEngine, FileSystemRazorProjectItem projectItem)
|
||||||
{
|
{
|
||||||
var cSharpDocument = templateEngine.GenerateCode(projectItem);
|
var projectItemWrapper = new FileSystemRazorProjectItemWrapper(projectItem);
|
||||||
|
var cSharpDocument = templateEngine.GenerateCode(projectItemWrapper);
|
||||||
if (cSharpDocument.Diagnostics.Any())
|
if (cSharpDocument.Diagnostics.Any())
|
||||||
{
|
{
|
||||||
var diagnostics = string.Join(Environment.NewLine, cSharpDocument.Diagnostics);
|
var diagnostics = string.Join(Environment.NewLine, cSharpDocument.Diagnostics);
|
||||||
Console.WriteLine($"One or more parse errors encountered. This will not prevent the generator from continuing: {Environment.NewLine}{diagnostics}.");
|
Console.WriteLine($"One or more parse errors encountered. This will not prevent the generator from continuing: {Environment.NewLine}{diagnostics}.");
|
||||||
}
|
}
|
||||||
|
|
||||||
var generatedCodeFilePath = Path.ChangeExtension(
|
var generatedCodeFilePath = Path.ChangeExtension(projectItem.PhysicalPath, ".Designer.cs");
|
||||||
((FileSystemRazorProjectItem)projectItem).FileInfo.FullName,
|
|
||||||
".Designer.cs");
|
|
||||||
File.WriteAllText(generatedCodeFilePath, cSharpDocument.GeneratedCode);
|
File.WriteAllText(generatedCodeFilePath, cSharpDocument.GeneratedCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class FileSystemRazorProject : RazorProject
|
private class FileSystemRazorProjectItemWrapper : RazorProjectItem
|
||||||
{
|
{
|
||||||
private readonly string _basePath;
|
private readonly FileSystemRazorProjectItem _source;
|
||||||
|
|
||||||
public FileSystemRazorProject(string basePath)
|
public FileSystemRazorProjectItemWrapper(FileSystemRazorProjectItem item)
|
||||||
{
|
{
|
||||||
_basePath = basePath;
|
_source = item;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IEnumerable<RazorProjectItem> EnumerateItems(string basePath)
|
public override string BasePath => _source.BasePath;
|
||||||
{
|
|
||||||
return new DirectoryInfo(_basePath)
|
|
||||||
.EnumerateFiles("*.cshtml", SearchOption.TopDirectoryOnly)
|
|
||||||
.Select(file => GetItem(basePath, file));
|
|
||||||
}
|
|
||||||
|
|
||||||
public override RazorProjectItem GetItem(string path) => throw new NotSupportedException();
|
public override string Path => _source.Path;
|
||||||
|
|
||||||
private RazorProjectItem GetItem(string basePath, FileInfo file)
|
|
||||||
{
|
|
||||||
if (!file.Exists)
|
|
||||||
{
|
|
||||||
throw new FileNotFoundException($"{file.FullName} does not exist.");
|
|
||||||
}
|
|
||||||
|
|
||||||
return new FileSystemRazorProjectItem(basePath, file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class FileSystemRazorProjectItem : RazorProjectItem
|
|
||||||
{
|
|
||||||
public FileSystemRazorProjectItem(string basePath, FileInfo fileInfo)
|
|
||||||
{
|
|
||||||
BasePath = basePath;
|
|
||||||
Path = fileInfo.Name;
|
|
||||||
FileInfo = fileInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public FileInfo FileInfo { get; }
|
|
||||||
|
|
||||||
public override string BasePath { get; }
|
|
||||||
|
|
||||||
public override string Path { get; }
|
|
||||||
|
|
||||||
// Mask the full name since we don't want a developer's local file paths to be commited.
|
// Mask the full name since we don't want a developer's local file paths to be commited.
|
||||||
public override string PhysicalPath => FileInfo.Name;
|
public override string PhysicalPath => _source.Filename;
|
||||||
|
|
||||||
public override bool Exists => true;
|
public override bool Exists => _source.Exists;
|
||||||
|
|
||||||
public override Stream Read()
|
public override Stream Read()
|
||||||
{
|
{
|
||||||
|
|
@ -144,8 +110,8 @@ namespace RazorPageGenerator
|
||||||
|
|
||||||
private string ProcessFileIncludes()
|
private string ProcessFileIncludes()
|
||||||
{
|
{
|
||||||
var basePath = FileInfo.DirectoryName;
|
var basePath = _source.File.DirectoryName;
|
||||||
var cshtmlContent = File.ReadAllText(FileInfo.FullName);
|
var cshtmlContent = File.ReadAllText(_source.PhysicalPath);
|
||||||
|
|
||||||
var startMatch = "<%$ include: ";
|
var startMatch = "<%$ include: ";
|
||||||
var endMatch = " %>";
|
var endMatch = " %>";
|
||||||
|
|
@ -160,7 +126,7 @@ namespace RazorPageGenerator
|
||||||
var endIndex = cshtmlContent.IndexOf(endMatch, startIndex);
|
var endIndex = cshtmlContent.IndexOf(endMatch, startIndex);
|
||||||
if (endIndex == -1)
|
if (endIndex == -1)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException($"Invalid include file format in {FileInfo.FullName}. Usage example: <%$ include: ErrorPage.js %>");
|
throw new InvalidOperationException($"Invalid include file format in {_source.PhysicalPath}. Usage example: <%$ include: ErrorPage.js %>");
|
||||||
}
|
}
|
||||||
var includeFileName = cshtmlContent.Substring(startIndex + startMatch.Length, endIndex - (startIndex + startMatch.Length));
|
var includeFileName = cshtmlContent.Substring(startIndex + startMatch.Length, endIndex - (startIndex + startMatch.Length));
|
||||||
Console.WriteLine(" Inlining file {0}", includeFileName);
|
Console.WriteLine(" Inlining file {0}", includeFileName);
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ using Microsoft.AspNetCore.Razor.Evolution.Intermediate;
|
||||||
|
|
||||||
namespace RazorPageGenerator
|
namespace RazorPageGenerator
|
||||||
{
|
{
|
||||||
class RemovePragamaChecksumFeature : RazorIRPassBase, IRazorIROptimizationPass
|
class RemovePragmaChecksumFeature : RazorIRPassBase, IRazorIROptimizationPass
|
||||||
{
|
{
|
||||||
public override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIRNode irDocument)
|
public override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIRNode irDocument)
|
||||||
{
|
{
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
// 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 Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Razor.Evolution
|
||||||
|
{
|
||||||
|
public class FileSystemRazorProjectItemTest
|
||||||
|
{
|
||||||
|
private static string TestFolder { get; } =
|
||||||
|
Path.Combine(TestProject.GetProjectDirectory(), "TestFiles", "FileSystemRazorProject");
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void FileSystemRazorProjectItem_SetsProperties()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var fileInfo = new FileInfo(Path.Combine(TestFolder, "Home.cshtml"));
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var projectItem = new FileSystemRazorProjectItem("/Views", "/Home.cshtml", fileInfo);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal("/Home.cshtml", projectItem.Path);
|
||||||
|
Assert.Equal("/Views", projectItem.BasePath);
|
||||||
|
Assert.True(projectItem.Exists);
|
||||||
|
Assert.Equal("Home.cshtml", projectItem.Filename);
|
||||||
|
Assert.Equal(fileInfo.FullName, projectItem.PhysicalPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Exists_ReturnsFalseWhenFileDoesNotExist()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var fileInfo = new FileInfo(Path.Combine(TestFolder, "Views", "FileDoesNotExist.cshtml"));
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var projectItem = new FileSystemRazorProjectItem("/Views", "/FileDoesNotExist.cshtml", fileInfo);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.False(projectItem.Exists);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Read_ReturnsReadStream()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var fileInfo = new FileInfo(Path.Combine(TestFolder, "Home.cshtml"));
|
||||||
|
var projectItem = new FileSystemRazorProjectItem("/", "/Home.cshtml", fileInfo);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var stream = projectItem.Read();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal("home-content", new StreamReader(stream).ReadToEnd());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,108 @@
|
||||||
|
// 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.Linq;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Razor.Evolution
|
||||||
|
{
|
||||||
|
public class FileSystemRazorProjectTest
|
||||||
|
{
|
||||||
|
private static string TestFolder { get; } =
|
||||||
|
Path.Combine(TestProject.GetProjectDirectory(), "TestFiles", "FileSystemRazorProject");
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void EnumerateItems_DiscoversAllCshtmlFiles()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var fileSystemProject = new FileSystemRazorProject(TestFolder);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var files = fileSystemProject.EnumerateItems("/");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Collection(files.OrderBy(f => f.Path),
|
||||||
|
file =>
|
||||||
|
{
|
||||||
|
Assert.Equal("/Home.cshtml", file.Path);
|
||||||
|
Assert.Equal("/", file.BasePath);
|
||||||
|
},
|
||||||
|
file =>
|
||||||
|
{
|
||||||
|
Assert.Equal("/Views/About/About.cshtml", file.Path);
|
||||||
|
Assert.Equal("/", file.BasePath);
|
||||||
|
},
|
||||||
|
file =>
|
||||||
|
{
|
||||||
|
Assert.Equal("/Views/Home/Index.cshtml", file.Path);
|
||||||
|
Assert.Equal("/", file.BasePath);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void EnumerateItems_DiscoversAllCshtmlFiles_UnderSpecifiedBasePath()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var fileSystemProject = new FileSystemRazorProject(TestFolder);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var files = fileSystemProject.EnumerateItems("/Views");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Collection(files.OrderBy(f => f.Path),
|
||||||
|
file =>
|
||||||
|
{
|
||||||
|
Assert.Equal("/About/About.cshtml", file.Path);
|
||||||
|
Assert.Equal("/Views", file.BasePath);
|
||||||
|
},
|
||||||
|
file =>
|
||||||
|
{
|
||||||
|
Assert.Equal("/Home/Index.cshtml", file.Path);
|
||||||
|
Assert.Equal("/Views", file.BasePath);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void EnumerateItems_ReturnsEmptySequence_WhenBasePathDoesNotExist()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var fileSystemProject = new FileSystemRazorProject(TestFolder);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var files = fileSystemProject.EnumerateItems("/Does-Not-Exist");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Empty(files);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetItem_ReturnsFileFromDisk()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var path = "/Views/About/About.cshtml";
|
||||||
|
var fileSystemProject = new FileSystemRazorProject(TestFolder);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var file = fileSystemProject.GetItem(path);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.True(file.Exists);
|
||||||
|
Assert.Equal(path, file.Path);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetItem_ReturnsNotFoundResult()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var path = "/NotFound.cshtml";
|
||||||
|
var fileSystemProject = new FileSystemRazorProject(TestFolder);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var file = fileSystemProject.GetItem(path);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.False(file.Exists);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -20,26 +20,6 @@ namespace Microsoft.AspNetCore.Razor.Evolution.IntegrationTests
|
||||||
[IntializeTestFile]
|
[IntializeTestFile]
|
||||||
public abstract class IntegrationTestBase
|
public abstract class IntegrationTestBase
|
||||||
{
|
{
|
||||||
private static readonly string ThisProjectName = typeof(IntializeTestFileAttribute).GetTypeInfo().Assembly.GetName().Name;
|
|
||||||
|
|
||||||
private static string FindTestProjectRoot()
|
|
||||||
{
|
|
||||||
#if NET452
|
|
||||||
var currentDirectory = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory);
|
|
||||||
#else
|
|
||||||
var currentDirectory = new DirectoryInfo(AppContext.BaseDirectory);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
while (currentDirectory != null &&
|
|
||||||
!string.Equals(currentDirectory.Name, ThisProjectName, StringComparison.Ordinal))
|
|
||||||
{
|
|
||||||
currentDirectory = currentDirectory.Parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
var normalizedSeparators = currentDirectory.FullName.Replace(Path.DirectorySeparatorChar, '/');
|
|
||||||
return currentDirectory.FullName;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if GENERATE_BASELINES
|
#if GENERATE_BASELINES
|
||||||
private static readonly bool GenerateBaselines = true;
|
private static readonly bool GenerateBaselines = true;
|
||||||
#else
|
#else
|
||||||
|
|
@ -50,8 +30,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution.IntegrationTests
|
||||||
private static readonly AsyncLocal<string> _filename = new AsyncLocal<string>();
|
private static readonly AsyncLocal<string> _filename = new AsyncLocal<string>();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
protected static string TestProjectRoot { get; } = FindTestProjectRoot();
|
protected static string TestProjectRoot { get; } = TestProject.GetProjectDirectory();
|
||||||
|
|
||||||
|
|
||||||
// Used by the test framework to set the 'base' name for test files.
|
// Used by the test framework to set the 'base' name for test files.
|
||||||
public static string Filename
|
public static string Filename
|
||||||
|
|
|
||||||
|
|
@ -49,5 +49,63 @@ namespace Microsoft.AspNetCore.Razor.Evolution.IntegrationTests
|
||||||
// Assert
|
// Assert
|
||||||
AssertCSharpDocumentMatchesBaseline(cSharpDocument);
|
AssertCSharpDocumentMatchesBaseline(cSharpDocument);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GenerateCodeWithConfigureClass()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var filePath = Path.Combine(TestProjectRoot, $"{Filename}.cshtml");
|
||||||
|
var content = File.ReadAllText(filePath);
|
||||||
|
var projectItem = new TestRazorProjectItem($"{Filename}.cshtml", "")
|
||||||
|
{
|
||||||
|
Content = content,
|
||||||
|
};
|
||||||
|
var project = new TestRazorProject(new[] { projectItem });
|
||||||
|
var razorEngine = RazorEngine.Create(engine =>
|
||||||
|
{
|
||||||
|
engine.ConfigureClass((document, @class) =>
|
||||||
|
{
|
||||||
|
@class.Name = "MyClass";
|
||||||
|
@class.AccessModifier = "protected internal";
|
||||||
|
});
|
||||||
|
|
||||||
|
engine.ConfigureClass((document, @class) =>
|
||||||
|
{
|
||||||
|
@class.Interfaces = new[] { "global::System.IDisposable" };
|
||||||
|
@class.BaseType = "CustomBaseType";
|
||||||
|
});
|
||||||
|
});
|
||||||
|
var templateEngine = new RazorTemplateEngine(razorEngine, project);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var cSharpDocument = templateEngine.GenerateCode(projectItem.Path);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
AssertCSharpDocumentMatchesBaseline(cSharpDocument);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GenerateCodeWithSetNamespace()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var filePath = Path.Combine(TestProjectRoot, $"{Filename}.cshtml");
|
||||||
|
var content = File.ReadAllText(filePath);
|
||||||
|
var projectItem = new TestRazorProjectItem($"{Filename}.cshtml", "")
|
||||||
|
{
|
||||||
|
Content = content,
|
||||||
|
};
|
||||||
|
var project = new TestRazorProject(new[] { projectItem });
|
||||||
|
var razorEngine = RazorEngine.Create(engine =>
|
||||||
|
{
|
||||||
|
engine.SetNamespace("MyApp.Razor.Views");
|
||||||
|
});
|
||||||
|
var templateEngine = new RazorTemplateEngine(razorEngine, project);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var cSharpDocument = templateEngine.GenerateCode(projectItem.Path);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
AssertCSharpDocumentMatchesBaseline(cSharpDocument);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
home-content
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
#pragma checksum "TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithConfigureClass.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "247d02621904d87ab805e437f33c5d03b9a0de91"
|
||||||
|
namespace Razor
|
||||||
|
{
|
||||||
|
#line hidden
|
||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
protected internal class MyClass : CustomBaseType, global::System.IDisposable
|
||||||
|
{
|
||||||
|
#pragma warning disable 1998
|
||||||
|
public async override global::System.Threading.Tasks.Task ExecuteAsync()
|
||||||
|
{
|
||||||
|
WriteLiteral("<h1>Hello world!</h1>");
|
||||||
|
}
|
||||||
|
#pragma warning restore 1998
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
<h1>Hello world!</h1>
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
#pragma checksum "TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithSetNamespace.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "247d02621904d87ab805e437f33c5d03b9a0de91"
|
||||||
|
namespace MyApp.Razor.Views
|
||||||
|
{
|
||||||
|
#line hidden
|
||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
public class Template
|
||||||
|
{
|
||||||
|
#pragma warning disable 1998
|
||||||
|
public async override global::System.Threading.Tasks.Task ExecuteAsync()
|
||||||
|
{
|
||||||
|
WriteLiteral("<h1>Hello world!</h1>");
|
||||||
|
}
|
||||||
|
#pragma warning restore 1998
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
<h1>Hello world!</h1>
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
// 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.Reflection;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Razor.Evolution
|
||||||
|
{
|
||||||
|
public static class TestProject
|
||||||
|
{
|
||||||
|
private static readonly string ThisProjectName = typeof(TestProject).GetTypeInfo().Assembly.GetName().Name;
|
||||||
|
|
||||||
|
public static string GetProjectDirectory()
|
||||||
|
{
|
||||||
|
|
||||||
|
#if NET452
|
||||||
|
var currentDirectory = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory);
|
||||||
|
#else
|
||||||
|
var currentDirectory = new DirectoryInfo(AppContext.BaseDirectory);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
while (currentDirectory != null &&
|
||||||
|
!string.Equals(currentDirectory.Name, ThisProjectName, StringComparison.Ordinal))
|
||||||
|
{
|
||||||
|
currentDirectory = currentDirectory.Parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
return currentDirectory.FullName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue