From 12a502d775ff43e228db8bf22cc22e627e121feb Mon Sep 17 00:00:00 2001 From: Pranav K Date: Fri, 24 Feb 2017 09:25:12 -0800 Subject: [PATCH] Move FileSystemRazorProject into Razor.Evolution Add tests --- .../FileSystemRazorProject.cs | 69 +++++++++++ .../FileSystemRazorProjectItem.cs | 49 ++++++++ .../RazorEngineBuilderExtensions.cs | 45 ++++++-- src/RazorPageGenerator/Program.cs | 74 ++++-------- ...ture.cs => RemovePragmaChecksumFeature.cs} | 2 +- .../FileSystemRazorProjectItemTest.cs | 58 ++++++++++ .../FileSystemRazorProjectTest.cs | 108 ++++++++++++++++++ .../IntegrationTests/IntegrationTestBase.cs | 23 +--- .../RazorTemplateEngineIntegrationTest.cs | 58 ++++++++++ .../FileSystemRazorProject/Home.cshtml | 1 + .../Views/About/About.cshtml | 1 + .../Views/Home/Index.cshtml | 1 + .../Views/Home/Index.txt | 1 + .../GenerateCodeWithConfigureClass.codegen.cs | 16 +++ .../GenerateCodeWithConfigureClass.cshtml | 1 + .../GenerateCodeWithSetNamespace.codegen.cs | 16 +++ .../GenerateCodeWithSetNamespace.cshtml | 1 + .../TestProject.cs | 32 ++++++ 18 files changed, 468 insertions(+), 88 deletions(-) create mode 100644 src/Microsoft.AspNetCore.Razor.Evolution/FileSystemRazorProject.cs create mode 100644 src/Microsoft.AspNetCore.Razor.Evolution/FileSystemRazorProjectItem.cs rename src/RazorPageGenerator/{RemovePragamaChecksumFeature.cs => RemovePragmaChecksumFeature.cs} (89%) create mode 100644 test/Microsoft.AspNetCore.Razor.Evolution.Test/FileSystemRazorProjectItemTest.cs create mode 100644 test/Microsoft.AspNetCore.Razor.Evolution.Test/FileSystemRazorProjectTest.cs create mode 100644 test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/FileSystemRazorProject/Home.cshtml create mode 100644 test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/FileSystemRazorProject/Views/About/About.cshtml create mode 100644 test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/FileSystemRazorProject/Views/Home/Index.cshtml create mode 100644 test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/FileSystemRazorProject/Views/Home/Index.txt create mode 100644 test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithConfigureClass.codegen.cs create mode 100644 test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithConfigureClass.cshtml create mode 100644 test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithSetNamespace.codegen.cs create mode 100644 test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithSetNamespace.cshtml create mode 100644 test/Microsoft.AspNetCore.Razor.Evolution.Test/TestProject.cs diff --git a/src/Microsoft.AspNetCore.Razor.Evolution/FileSystemRazorProject.cs b/src/Microsoft.AspNetCore.Razor.Evolution/FileSystemRazorProject.cs new file mode 100644 index 0000000000..1d794919b0 --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Evolution/FileSystemRazorProject.cs @@ -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 +{ + /// + /// A implementation over the physical file system. + /// + public class FileSystemRazorProject : RazorProject + { + /// + /// Initializes a new instance of . + /// + /// The directory to root the file system at. + public FileSystemRazorProject(string root) + { + if (string.IsNullOrEmpty(root)) + { + throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, nameof(root)); + } + + Root = root.TrimEnd('/', '\\'); + } + + /// + /// The root of the file system. + /// + public string Root { get; } + + /// + public override IEnumerable 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(); + } + + return directory + .EnumerateFiles("*.cshtml", SearchOption.AllDirectories) + .Select(file => + { + var relativePath = file.FullName.Substring(absoluteBasePath.Length).Replace(Path.DirectorySeparatorChar, '/'); + return new FileSystemRazorProjectItem(basePath, relativePath, file); + }); + } + + /// + 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)); + } + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Evolution/FileSystemRazorProjectItem.cs b/src/Microsoft.AspNetCore.Razor.Evolution/FileSystemRazorProjectItem.cs new file mode 100644 index 0000000000..9ce8bef44b --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Evolution/FileSystemRazorProjectItem.cs @@ -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 +{ + /// + /// An implementation of using . + /// + public class FileSystemRazorProjectItem : RazorProjectItem + { + /// + /// Initializes a new instance of . + /// + /// The base path. + /// The path. + /// The . + public FileSystemRazorProjectItem(string basePath, string path, FileInfo file) + { + BasePath = basePath; + Path = path; + File = file; + } + + /// + /// Gets the . + /// + public FileInfo File { get; } + + /// + public override string BasePath { get; } + + /// + public override string Path { get; } + + /// + public override bool Exists => File.Exists; + + /// + public override string Filename => File.Name; + + /// + public override string PhysicalPath => File.FullName; + + /// + public override Stream Read() => File.OpenRead(); + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.Razor.Evolution/RazorEngineBuilderExtensions.cs b/src/Microsoft.AspNetCore.Razor.Evolution/RazorEngineBuilderExtensions.cs index c7d811488c..f01b5d9f61 100644 --- a/src/Microsoft.AspNetCore.Razor.Evolution/RazorEngineBuilderExtensions.cs +++ b/src/Microsoft.AspNetCore.Razor.Evolution/RazorEngineBuilderExtensions.cs @@ -8,8 +8,17 @@ using Microsoft.AspNetCore.Razor.Evolution.Intermediate; namespace Microsoft.AspNetCore.Razor.Evolution { + /// + /// Extension methods to . + /// public static class RazorEngineBuilderExtensions { + /// + /// Adds the specified . + /// + /// The . + /// The to add. + /// The . public static IRazorEngineBuilder AddDirective(this IRazorEngineBuilder builder, DirectiveDescriptor directive) { if (builder == null) @@ -28,6 +37,12 @@ namespace Microsoft.AspNetCore.Razor.Evolution return builder; } + /// + /// Adds the specified . + /// + /// The . + /// The to add. + /// The . public static IRazorEngineBuilder AddTargetExtension(this IRazorEngineBuilder builder, IRuntimeTargetExtension extension) { if (builder == null) @@ -46,6 +61,12 @@ namespace Microsoft.AspNetCore.Razor.Evolution return builder; } + /// + /// Sets the base type for generated types. + /// + /// The . + /// The name of the base type. + /// The . public static IRazorEngineBuilder SetBaseType(this IRazorEngineBuilder builder, string baseType) { if (builder == null) @@ -58,17 +79,13 @@ namespace Microsoft.AspNetCore.Razor.Evolution return builder; } - public static IRazorEngineBuilder SetClassName(this IRazorEngineBuilder builder, string className) - { - if (builder == null) - { - throw new ArgumentNullException(nameof(builder)); - } - - ConfigureClass(builder, (document, @class) => @class.Name = className); - return builder; - } - + /// + /// Registers a class configuration delegate that gets invoked during code generation. + /// + /// The . + /// invoked to configure + /// during code generation. + /// The . public static IRazorEngineBuilder ConfigureClass( this IRazorEngineBuilder builder, Action configureClass) @@ -88,6 +105,12 @@ namespace Microsoft.AspNetCore.Razor.Evolution return builder; } + /// + /// Sets the namespace for generated types. + /// + /// The . + /// The name of the namespace. + /// The . public static IRazorEngineBuilder SetNamespace(this IRazorEngineBuilder builder, string namespaceName) { if (builder == null) diff --git a/src/RazorPageGenerator/Program.cs b/src/RazorPageGenerator/Program.cs index dbb44c30a2..9680ff590e 100644 --- a/src/RazorPageGenerator/Program.cs +++ b/src/RazorPageGenerator/Program.cs @@ -2,7 +2,6 @@ // 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.IO; using System.Linq; using System.Text; @@ -35,22 +34,21 @@ namespace RazorPageGenerator @class.AccessModifier = "internal"; }); - builder.Features.Add(new RemovePragamaChecksumFeature()); + builder.Features.Add(new RemovePragmaChecksumFeature()); }); var viewDirectories = Directory.EnumerateDirectories(targetProjectDirectory, "Views", SearchOption.AllDirectories); + var razorProject = new FileSystemRazorProject(targetProjectDirectory); + var templateEngine = new RazorTemplateEngine(razorEngine, razorProject); var fileCount = 0; foreach (var viewDir in viewDirectories) { Console.WriteLine(); Console.WriteLine(" Generating code files for views in {0}", viewDir); - var razorProject = new FileSystemRazorProject(viewDir); - var templateEngine = new RazorTemplateEngine(razorEngine, razorProject); - - - var cshtmlFiles = razorProject.EnumerateItems(""); + var viewDirPath = viewDir.Substring(targetProjectDirectory.Length).Replace('\\', '/'); + var cshtmlFiles = razorProject.EnumerateItems(viewDirPath).Cast(); if (!cshtmlFiles.Any()) { @@ -72,69 +70,37 @@ namespace RazorPageGenerator 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()) { 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}."); } - var generatedCodeFilePath = Path.ChangeExtension( - ((FileSystemRazorProjectItem)projectItem).FileInfo.FullName, - ".Designer.cs"); + var generatedCodeFilePath = Path.ChangeExtension(projectItem.PhysicalPath, ".Designer.cs"); 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 EnumerateItems(string basePath) - { - return new DirectoryInfo(_basePath) - .EnumerateFiles("*.cshtml", SearchOption.TopDirectoryOnly) - .Select(file => GetItem(basePath, file)); - } + public override string BasePath => _source.BasePath; - public override RazorProjectItem GetItem(string path) => throw new NotSupportedException(); - - 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; } + public override string Path => _source.Path; // 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() { @@ -144,8 +110,8 @@ namespace RazorPageGenerator private string ProcessFileIncludes() { - var basePath = FileInfo.DirectoryName; - var cshtmlContent = File.ReadAllText(FileInfo.FullName); + var basePath = _source.File.DirectoryName; + var cshtmlContent = File.ReadAllText(_source.PhysicalPath); var startMatch = "<%$ include: "; var endMatch = " %>"; @@ -160,7 +126,7 @@ namespace RazorPageGenerator var endIndex = cshtmlContent.IndexOf(endMatch, startIndex); 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)); Console.WriteLine(" Inlining file {0}", includeFileName); diff --git a/src/RazorPageGenerator/RemovePragamaChecksumFeature.cs b/src/RazorPageGenerator/RemovePragmaChecksumFeature.cs similarity index 89% rename from src/RazorPageGenerator/RemovePragamaChecksumFeature.cs rename to src/RazorPageGenerator/RemovePragmaChecksumFeature.cs index 6ed229693b..bc6386ce25 100644 --- a/src/RazorPageGenerator/RemovePragamaChecksumFeature.cs +++ b/src/RazorPageGenerator/RemovePragmaChecksumFeature.cs @@ -4,7 +4,7 @@ using Microsoft.AspNetCore.Razor.Evolution.Intermediate; namespace RazorPageGenerator { - class RemovePragamaChecksumFeature : RazorIRPassBase, IRazorIROptimizationPass + class RemovePragmaChecksumFeature : RazorIRPassBase, IRazorIROptimizationPass { public override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIRNode irDocument) { diff --git a/test/Microsoft.AspNetCore.Razor.Evolution.Test/FileSystemRazorProjectItemTest.cs b/test/Microsoft.AspNetCore.Razor.Evolution.Test/FileSystemRazorProjectItemTest.cs new file mode 100644 index 0000000000..7bb8006fa5 --- /dev/null +++ b/test/Microsoft.AspNetCore.Razor.Evolution.Test/FileSystemRazorProjectItemTest.cs @@ -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()); + } + } +} diff --git a/test/Microsoft.AspNetCore.Razor.Evolution.Test/FileSystemRazorProjectTest.cs b/test/Microsoft.AspNetCore.Razor.Evolution.Test/FileSystemRazorProjectTest.cs new file mode 100644 index 0000000000..d9d21dc1f6 --- /dev/null +++ b/test/Microsoft.AspNetCore.Razor.Evolution.Test/FileSystemRazorProjectTest.cs @@ -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); + } + } +} diff --git a/test/Microsoft.AspNetCore.Razor.Evolution.Test/IntegrationTests/IntegrationTestBase.cs b/test/Microsoft.AspNetCore.Razor.Evolution.Test/IntegrationTests/IntegrationTestBase.cs index cbe8d15193..3b130ae3b3 100644 --- a/test/Microsoft.AspNetCore.Razor.Evolution.Test/IntegrationTests/IntegrationTestBase.cs +++ b/test/Microsoft.AspNetCore.Razor.Evolution.Test/IntegrationTests/IntegrationTestBase.cs @@ -20,26 +20,6 @@ namespace Microsoft.AspNetCore.Razor.Evolution.IntegrationTests [IntializeTestFile] 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 private static readonly bool GenerateBaselines = true; #else @@ -50,8 +30,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution.IntegrationTests private static readonly AsyncLocal _filename = new AsyncLocal(); #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. public static string Filename diff --git a/test/Microsoft.AspNetCore.Razor.Evolution.Test/IntegrationTests/RazorTemplateEngineIntegrationTest.cs b/test/Microsoft.AspNetCore.Razor.Evolution.Test/IntegrationTests/RazorTemplateEngineIntegrationTest.cs index fae442ad0e..511506f2a9 100644 --- a/test/Microsoft.AspNetCore.Razor.Evolution.Test/IntegrationTests/RazorTemplateEngineIntegrationTest.cs +++ b/test/Microsoft.AspNetCore.Razor.Evolution.Test/IntegrationTests/RazorTemplateEngineIntegrationTest.cs @@ -49,5 +49,63 @@ namespace Microsoft.AspNetCore.Razor.Evolution.IntegrationTests // Assert 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); + } } } diff --git a/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/FileSystemRazorProject/Home.cshtml b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/FileSystemRazorProject/Home.cshtml new file mode 100644 index 0000000000..7c5b3ca2e3 --- /dev/null +++ b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/FileSystemRazorProject/Home.cshtml @@ -0,0 +1 @@ +home-content \ No newline at end of file diff --git a/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/FileSystemRazorProject/Views/About/About.cshtml b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/FileSystemRazorProject/Views/About/About.cshtml new file mode 100644 index 0000000000..5f282702bb --- /dev/null +++ b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/FileSystemRazorProject/Views/About/About.cshtml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/FileSystemRazorProject/Views/Home/Index.cshtml b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/FileSystemRazorProject/Views/Home/Index.cshtml new file mode 100644 index 0000000000..5f282702bb --- /dev/null +++ b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/FileSystemRazorProject/Views/Home/Index.cshtml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/FileSystemRazorProject/Views/Home/Index.txt b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/FileSystemRazorProject/Views/Home/Index.txt new file mode 100644 index 0000000000..5f282702bb --- /dev/null +++ b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/FileSystemRazorProject/Views/Home/Index.txt @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithConfigureClass.codegen.cs b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithConfigureClass.codegen.cs new file mode 100644 index 0000000000..a55823e23f --- /dev/null +++ b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithConfigureClass.codegen.cs @@ -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("

Hello world!

"); + } + #pragma warning restore 1998 + } +} diff --git a/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithConfigureClass.cshtml b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithConfigureClass.cshtml new file mode 100644 index 0000000000..6df88a66a1 --- /dev/null +++ b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithConfigureClass.cshtml @@ -0,0 +1 @@ +

Hello world!

\ No newline at end of file diff --git a/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithSetNamespace.codegen.cs b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithSetNamespace.codegen.cs new file mode 100644 index 0000000000..70362197e0 --- /dev/null +++ b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithSetNamespace.codegen.cs @@ -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("

Hello world!

"); + } + #pragma warning restore 1998 + } +} diff --git a/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithSetNamespace.cshtml b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithSetNamespace.cshtml new file mode 100644 index 0000000000..6df88a66a1 --- /dev/null +++ b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithSetNamespace.cshtml @@ -0,0 +1 @@ +

Hello world!

\ No newline at end of file diff --git a/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestProject.cs b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestProject.cs new file mode 100644 index 0000000000..001996a2a8 --- /dev/null +++ b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestProject.cs @@ -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; + } + } +}