From a6d611aecd6ab9d2603dd63009595bc502fe1850 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Tue, 14 Feb 2017 16:47:32 -0800 Subject: [PATCH] Introduce RazorCompilation --- .../DefaultDocumentClassifierPass.cs | 30 +++ .../DefaultDocumentClassifierPassFeature.cs | 23 ++ .../Properties/Resources.Designer.cs | 16 ++ .../RazorCodeDocumentExtensions.cs | 2 +- .../RazorEngine.cs | 25 ++ .../RazorEngineBuilderExtensions.cs | 24 ++ .../RazorSourceDocument.cs | 19 ++ .../RazorTemplateEngine.cs | 216 ++++++++++++++++++ .../RazorTemplateEngineOptions.cs | 21 ++ .../Resources.resx | 3 + .../IntegrationTests/IntegrationTestBase.cs | 7 +- .../RazorTemplateEngineIntegrationTest.cs | 53 +++++ ...oft.AspNetCore.Razor.Evolution.Test.csproj | 2 + .../RazorEngineTest.cs | 4 +- .../RazorProjectItemTest.cs | 43 +--- .../RazorTemplateEngineTest.cs | 195 ++++++++++++++++ .../CustomDirective.ir.txt | 7 +- .../BasicIntegrationTest/Empty.ir.txt | 6 +- .../BasicIntegrationTest/HelloWorld.ir.txt | 6 +- .../HtmlWithConditionalAttribute.ir.txt | 6 +- .../HtmlWithDataDashAttribute.ir.txt | 6 +- .../BasicTest.codegen.cs | 6 +- .../BasicTest.ir.txt | 6 +- .../GenerateCodeWithBaseType.codegen.cs | 16 ++ .../GenerateCodeWithBaseType.cshtml | 1 + .../GenerateCodeWithDefaults.codegen.cs | 16 ++ .../GenerateCodeWithDefaults.cshtml | 1 + .../NestedTagHelpers.ir.txt | 6 +- .../SimpleTagHelpers.ir.txt | 6 +- .../TagHelpersWithBoundAttributes.ir.txt | 6 +- .../TestRazorProject.cs | 34 +++ .../TestRazorProjectItem.cs | 33 +++ 32 files changed, 771 insertions(+), 74 deletions(-) create mode 100644 src/Microsoft.AspNetCore.Razor.Evolution/DefaultDocumentClassifierPassFeature.cs create mode 100644 src/Microsoft.AspNetCore.Razor.Evolution/RazorTemplateEngine.cs create mode 100644 src/Microsoft.AspNetCore.Razor.Evolution/RazorTemplateEngineOptions.cs create mode 100644 test/Microsoft.AspNetCore.Razor.Evolution.Test/IntegrationTests/RazorTemplateEngineIntegrationTest.cs create mode 100644 test/Microsoft.AspNetCore.Razor.Evolution.Test/RazorTemplateEngineTest.cs create mode 100644 test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithBaseType.codegen.cs create mode 100644 test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithBaseType.cshtml create mode 100644 test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithDefaults.codegen.cs create mode 100644 test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithDefaults.cshtml create mode 100644 test/Microsoft.AspNetCore.Razor.Evolution.Test/TestRazorProject.cs create mode 100644 test/Microsoft.AspNetCore.Razor.Evolution.Test/TestRazorProjectItem.cs diff --git a/src/Microsoft.AspNetCore.Razor.Evolution/DefaultDocumentClassifierPass.cs b/src/Microsoft.AspNetCore.Razor.Evolution/DefaultDocumentClassifierPass.cs index 50b6403dae..068a15c011 100644 --- a/src/Microsoft.AspNetCore.Razor.Evolution/DefaultDocumentClassifierPass.cs +++ b/src/Microsoft.AspNetCore.Razor.Evolution/DefaultDocumentClassifierPass.cs @@ -1,6 +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.Linq; using Microsoft.AspNetCore.Razor.Evolution.Intermediate; namespace Microsoft.AspNetCore.Razor.Evolution @@ -15,5 +16,34 @@ namespace Microsoft.AspNetCore.Razor.Evolution { return true; } + + protected override void OnDocumentStructureCreated( + RazorCodeDocument codeDocument, + NamespaceDeclarationIRNode @namespace, + ClassDeclarationIRNode @class, + RazorMethodDeclarationIRNode method) + { + var configuration = Engine.Features.OfType().FirstOrDefault(); + if (configuration != null) + { + for (var i = 0; i < configuration.ConfigureClass.Count; i++) + { + var configureClass = configuration.ConfigureClass[i]; + configureClass(codeDocument, @class); + } + + for (var i = 0; i < configuration.ConfigureNamespace.Count; i++) + { + var configureNamespace = configuration.ConfigureNamespace[i]; + configureNamespace(codeDocument, @namespace); + } + + for (var i = 0; i < configuration.ConfigureMethod.Count; i++) + { + var configureMethod = configuration.ConfigureMethod[i]; + configureMethod(codeDocument, @method); + } + } + } } } diff --git a/src/Microsoft.AspNetCore.Razor.Evolution/DefaultDocumentClassifierPassFeature.cs b/src/Microsoft.AspNetCore.Razor.Evolution/DefaultDocumentClassifierPassFeature.cs new file mode 100644 index 0000000000..f227dce815 --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Evolution/DefaultDocumentClassifierPassFeature.cs @@ -0,0 +1,23 @@ +// 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 Microsoft.AspNetCore.Razor.Evolution.Intermediate; + +namespace Microsoft.AspNetCore.Razor.Evolution +{ + internal class DefaultDocumentClassifierPassFeature : IRazorEngineFeature + { + public RazorEngine Engine { get; set; } + + public IList> ConfigureClass { get; } = + new List>(); + + public IList> ConfigureNamespace { get; } = + new List>(); + + public IList> ConfigureMethod { get; } = + new List>(); + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Evolution/Properties/Resources.Designer.cs b/src/Microsoft.AspNetCore.Razor.Evolution/Properties/Resources.Designer.cs index c262bd6f5d..9ec06f2f43 100644 --- a/src/Microsoft.AspNetCore.Razor.Evolution/Properties/Resources.Designer.cs +++ b/src/Microsoft.AspNetCore.Razor.Evolution/Properties/Resources.Designer.cs @@ -218,6 +218,22 @@ namespace Microsoft.AspNetCore.Razor.Evolution return string.Format(CultureInfo.CurrentCulture, GetString("DocumentMissingTarget"), p0, p1, p2); } + /// + /// The item '{0}' could not be found. + /// + internal static string RazorTemplateEngine_ItemCouldNotBeFound + { + get { return GetString("RazorTemplateEngine_ItemCouldNotBeFound"); } + } + + /// + /// The item '{0}' could not be found. + /// + internal static string FormatRazorTemplateEngine_ItemCouldNotBeFound(object p0) + { + return string.Format(CultureInfo.CurrentCulture, GetString("RazorTemplateEngine_ItemCouldNotBeFound"), p0); + } + private static string GetString(string name, params string[] formatterNames) { var value = _resourceManager.GetString(name); diff --git a/src/Microsoft.AspNetCore.Razor.Evolution/RazorCodeDocumentExtensions.cs b/src/Microsoft.AspNetCore.Razor.Evolution/RazorCodeDocumentExtensions.cs index 079a3162aa..6e6416289c 100644 --- a/src/Microsoft.AspNetCore.Razor.Evolution/RazorCodeDocumentExtensions.cs +++ b/src/Microsoft.AspNetCore.Razor.Evolution/RazorCodeDocumentExtensions.cs @@ -2,8 +2,8 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using Microsoft.AspNetCore.Razor.Evolution.Intermediate; using System.Collections.Generic; +using Microsoft.AspNetCore.Razor.Evolution.Intermediate; namespace Microsoft.AspNetCore.Razor.Evolution { diff --git a/src/Microsoft.AspNetCore.Razor.Evolution/RazorEngine.cs b/src/Microsoft.AspNetCore.Razor.Evolution/RazorEngine.cs index c20352a147..6e30191215 100644 --- a/src/Microsoft.AspNetCore.Razor.Evolution/RazorEngine.cs +++ b/src/Microsoft.AspNetCore.Razor.Evolution/RazorEngine.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Threading.Tasks; using Microsoft.AspNetCore.Razor.Evolution.CodeGeneration; namespace Microsoft.AspNetCore.Razor.Evolution @@ -23,6 +24,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution return builder.Build(); } + public static RazorEngine CreateDesignTime() { return CreateDesignTime(configure: null); @@ -73,6 +75,29 @@ namespace Microsoft.AspNetCore.Razor.Evolution // Default Runtime Targets builder.AddTargetExtension(new TemplateTargetExtension()); + + // Default configuration + var configurationFeature = new DefaultDocumentClassifierPassFeature(); + configurationFeature.ConfigureClass.Add((document, @class) => + { + @class.Name = "Template"; + @class.AccessModifier = "public"; + }); + + configurationFeature.ConfigureNamespace.Add((document, @namespace) => + { + @namespace.Content = "Razor"; + }); + + configurationFeature.ConfigureMethod.Add((document, @method) => + { + @method.Name = "ExecuteAsync"; + @method.ReturnType = $"global::{typeof(Task).FullName}"; + @method.AccessModifier = "public"; + method.Modifiers = new[] { "async", "override" }; + }); + + builder.Features.Add(configurationFeature); } internal static void AddRuntimeDefaults(IRazorEngineBuilder builder) diff --git a/src/Microsoft.AspNetCore.Razor.Evolution/RazorEngineBuilderExtensions.cs b/src/Microsoft.AspNetCore.Razor.Evolution/RazorEngineBuilderExtensions.cs index 6effde8441..9d6904244d 100644 --- a/src/Microsoft.AspNetCore.Razor.Evolution/RazorEngineBuilderExtensions.cs +++ b/src/Microsoft.AspNetCore.Razor.Evolution/RazorEngineBuilderExtensions.cs @@ -45,6 +45,18 @@ namespace Microsoft.AspNetCore.Razor.Evolution return builder; } + public static IRazorEngineBuilder SetBaseType(this IRazorEngineBuilder builder, string baseType) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + var configurationFeature = GetDefaultDocumentClassifierPassFeature(builder); + configurationFeature.ConfigureClass.Add((document, @class) => @class.BaseType = baseType); + return builder; + } + private static IRazorDirectiveFeature GetDirectiveFeature(IRazorEngineBuilder builder) { var directiveFeature = builder.Features.OfType().FirstOrDefault(); @@ -68,5 +80,17 @@ namespace Microsoft.AspNetCore.Razor.Evolution return targetExtensionFeature; } + + private static DefaultDocumentClassifierPassFeature GetDefaultDocumentClassifierPassFeature(IRazorEngineBuilder builder) + { + var configurationFeature = builder.Features.OfType().FirstOrDefault(); + if (configurationFeature == null) + { + configurationFeature = new DefaultDocumentClassifierPassFeature(); + builder.Features.Add(configurationFeature); + } + + return configurationFeature; + } } } diff --git a/src/Microsoft.AspNetCore.Razor.Evolution/RazorSourceDocument.cs b/src/Microsoft.AspNetCore.Razor.Evolution/RazorSourceDocument.cs index 96077f6e18..9d7505b657 100644 --- a/src/Microsoft.AspNetCore.Razor.Evolution/RazorSourceDocument.cs +++ b/src/Microsoft.AspNetCore.Razor.Evolution/RazorSourceDocument.cs @@ -48,6 +48,25 @@ namespace Microsoft.AspNetCore.Razor.Evolution return ReadFromInternal(stream, filename, encoding); } + public static RazorSourceDocument ReadFrom(RazorProjectItem projectItem) + { + if (projectItem == null) + { + throw new ArgumentNullException(nameof(projectItem)); + } + + var path = projectItem.PhysicalPath; + if (string.IsNullOrEmpty(path)) + { + path = projectItem.Path; + } + + using (var inputStream = projectItem.Read()) + { + return ReadFrom(inputStream, path); + } + } + private static RazorSourceDocument ReadFromInternal(Stream stream, string filename, Encoding encoding) { var streamLength = (int)stream.Length; diff --git a/src/Microsoft.AspNetCore.Razor.Evolution/RazorTemplateEngine.cs b/src/Microsoft.AspNetCore.Razor.Evolution/RazorTemplateEngine.cs new file mode 100644 index 0000000000..5f52bb7e77 --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Evolution/RazorTemplateEngine.cs @@ -0,0 +1,216 @@ +// 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.Linq; + +namespace Microsoft.AspNetCore.Razor.Evolution +{ + /// + /// Entry point to parse Razor files and generate code. + /// + public class RazorTemplateEngine + { + private RazorTemplateEngineOptions _options; + + /// + /// Initializes a new instance of . + /// + /// The . + /// The . + public RazorTemplateEngine( + RazorEngine engine, + RazorProject project) + { + if (engine == null) + { + throw new ArgumentNullException(nameof(engine)); + } + + if (project == null) + { + throw new ArgumentNullException(nameof(project)); + } + + Engine = engine; + Project = project; + _options = new RazorTemplateEngineOptions(); + } + + /// + /// Gets the . + /// + public RazorEngine Engine { get; } + + /// + /// Gets the . + /// + public RazorProject Project { get; } + + /// + /// Options to configure . + /// + public RazorTemplateEngineOptions Options + { + get + { + return _options; + } + set + { + _options = value ?? throw new ArgumentNullException(nameof(value)); + } + } + + /// + /// Parses the template specified by the project item . + /// + /// The template path. + /// The . + public RazorCSharpDocument GenerateCode(string path) + { + if (string.IsNullOrEmpty(path)) + { + throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, nameof(path)); + } + + var projectItem = Project.GetItem(path); + return GenerateCode(projectItem); + } + + /// + /// Parses the template specified by . + /// + /// The . + /// The . + public RazorCSharpDocument GenerateCode(RazorProjectItem projectItem) + { + if (projectItem == null) + { + throw new ArgumentNullException(nameof(projectItem)); + } + + if (!projectItem.Exists) + { + throw new InvalidOperationException(Resources.FormatRazorTemplateEngine_ItemCouldNotBeFound(projectItem.Path)); + } + + var codeDocument = CreateCodeDocument(projectItem); + return GenerateCode(codeDocument); + } + + /// + /// Parses the template specified by . + /// + /// The . + /// The . + public virtual RazorCSharpDocument GenerateCode(RazorCodeDocument codeDocument) + { + if (codeDocument == null) + { + throw new ArgumentNullException(nameof(codeDocument)); + } + + Engine.Process(codeDocument); + return codeDocument.GetCSharpDocument(); + } + + /// + /// Generates a for the specified . + /// + /// The template path. + /// The created . + public virtual RazorCodeDocument CreateCodeDocument(string path) + { + if (string.IsNullOrEmpty(path)) + { + throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, nameof(path)); + } + + var projectItem = Project.GetItem(path); + return CreateCodeDocument(projectItem); + } + + /// + /// Generates a for the specified . + /// + /// The . + /// The created . + public virtual RazorCodeDocument CreateCodeDocument(RazorProjectItem projectItem) + { + if (projectItem == null) + { + throw new ArgumentNullException(nameof(projectItem)); + } + + if (!projectItem.Exists) + { + throw new InvalidOperationException(Resources.FormatRazorTemplateEngine_ItemCouldNotBeFound(projectItem.Path)); + } + + var source = RazorSourceDocument.ReadFrom(projectItem); + var imports = GetImports(projectItem); + + return RazorCodeDocument.Create(source, imports); + } + + /// + /// Gets that are applicable to the specified . + /// + /// The template path. + /// The sequence of applicable . + public IEnumerable GetImports(string path) + { + if (string.IsNullOrEmpty(path)) + { + throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, nameof(path)); + } + + var projectItem = Project.GetItem(path); + return GetImports(projectItem); + } + + /// + /// Gets that are applicable to the specified . + /// + /// The . + /// The sequence of applicable . + public virtual IEnumerable GetImports(RazorProjectItem projectItem) + { + if (projectItem == null) + { + throw new ArgumentNullException(nameof(projectItem)); + } + + if (!projectItem.Exists) + { + throw new InvalidOperationException(Resources.FormatRazorTemplateEngine_ItemCouldNotBeFound(projectItem.Path)); + } + + var importsFileName = Options.ImportsFileName; + if (string.IsNullOrEmpty(importsFileName)) + { + return Enumerable.Empty(); + } + + var result = new List(); + var importProjectItems = Project.FindHierarchicalItems(projectItem.Path, importsFileName); + foreach (var importItem in importProjectItems) + { + if (importItem.Exists) + { + // We want items in descending order. FindHierarchicalItems returns items in ascending order. + result.Insert(0, RazorSourceDocument.ReadFrom(importItem)); + } + } + + if (Options.DefaultImports != null) + { + result.Insert(0, Options.DefaultImports); + } + + return result; + } + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Evolution/RazorTemplateEngineOptions.cs b/src/Microsoft.AspNetCore.Razor.Evolution/RazorTemplateEngineOptions.cs new file mode 100644 index 0000000000..80243a2874 --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Evolution/RazorTemplateEngineOptions.cs @@ -0,0 +1,21 @@ +// 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. + +namespace Microsoft.AspNetCore.Razor.Evolution +{ + /// + /// Options for code generation in the . + /// + public class RazorTemplateEngineOptions + { + /// + /// Gets or sets the file name of the imports file (e.g. _ViewImports.cshtml). + /// + public string ImportsFileName { get; set; } + + /// + /// Gets or sets the default set of imports. + /// + public RazorSourceDocument DefaultImports { get; set; } + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Evolution/Resources.resx b/src/Microsoft.AspNetCore.Razor.Evolution/Resources.resx index d19670778f..2701fa6d07 100644 --- a/src/Microsoft.AspNetCore.Razor.Evolution/Resources.resx +++ b/src/Microsoft.AspNetCore.Razor.Evolution/Resources.resx @@ -156,4 +156,7 @@ The document of kind '{0}' does not have a '{1}'. The document classifier must set a value for '{2}'. + + The item '{0}' could not be found. + \ No newline at end of file diff --git a/test/Microsoft.AspNetCore.Razor.Evolution.Test/IntegrationTests/IntegrationTestBase.cs b/test/Microsoft.AspNetCore.Razor.Evolution.Test/IntegrationTests/IntegrationTestBase.cs index 252bb1da84..cbe8d15193 100644 --- a/test/Microsoft.AspNetCore.Razor.Evolution.Test/IntegrationTests/IntegrationTestBase.cs +++ b/test/Microsoft.AspNetCore.Razor.Evolution.Test/IntegrationTests/IntegrationTestBase.cs @@ -11,12 +11,9 @@ using System.Runtime.Remoting.Messaging; #else using System.Threading; #endif -using System.Text; using Microsoft.AspNetCore.Razor.Evolution.Intermediate; -using Microsoft.AspNetCore.Razor.Evolution.Legacy; using Xunit; using Xunit.Sdk; -using System.Runtime.InteropServices; namespace Microsoft.AspNetCore.Razor.Evolution.IntegrationTests { @@ -24,7 +21,6 @@ namespace Microsoft.AspNetCore.Razor.Evolution.IntegrationTests public abstract class IntegrationTestBase { private static readonly string ThisProjectName = typeof(IntializeTestFileAttribute).GetTypeInfo().Assembly.GetName().Name; - private static readonly string TestProjectRoot = FindTestProjectRoot(); private static string FindTestProjectRoot() { @@ -54,6 +50,9 @@ namespace Microsoft.AspNetCore.Razor.Evolution.IntegrationTests private static readonly AsyncLocal _filename = new AsyncLocal(); #endif + protected static string TestProjectRoot { get; } = FindTestProjectRoot(); + + // 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 new file mode 100644 index 0000000000..fae442ad0e --- /dev/null +++ b/test/Microsoft.AspNetCore.Razor.Evolution.Test/IntegrationTests/RazorTemplateEngineIntegrationTest.cs @@ -0,0 +1,53 @@ +// 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.IntegrationTests +{ + public class RazorTemplateEngineIntegrationTest : IntegrationTestBase + { + [Fact] + public void GenerateCodeWithDefaults() + { + // 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(); + var templateEngine = new RazorTemplateEngine(razorEngine, project); + + // Act + var resultcSharpDocument = templateEngine.GenerateCode(projectItem.Path); + + // Assert + AssertCSharpDocumentMatchesBaseline(resultcSharpDocument); + } + + [Fact] + public void GenerateCodeWithBaseType() + { + // 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.SetBaseType("MyBaseType")); + 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/Microsoft.AspNetCore.Razor.Evolution.Test.csproj b/test/Microsoft.AspNetCore.Razor.Evolution.Test/Microsoft.AspNetCore.Razor.Evolution.Test.csproj index ff460eea45..cd94711f4c 100644 --- a/test/Microsoft.AspNetCore.Razor.Evolution.Test/Microsoft.AspNetCore.Razor.Evolution.Test.csproj +++ b/test/Microsoft.AspNetCore.Razor.Evolution.Test/Microsoft.AspNetCore.Razor.Evolution.Test.csproj @@ -3,6 +3,8 @@ netcoreapp1.1;net46 netcoreapp1.1 + + $(DefineConstants);GENERATE_BASELINES $(DefineConstants);__RemoveThisBitTo__GENERATE_BASELINES $(DefaultItemExcludes);TestFiles\**\* diff --git a/test/Microsoft.AspNetCore.Razor.Evolution.Test/RazorEngineTest.cs b/test/Microsoft.AspNetCore.Razor.Evolution.Test/RazorEngineTest.cs index eac1ac9c75..068d2da49f 100644 --- a/test/Microsoft.AspNetCore.Razor.Evolution.Test/RazorEngineTest.cs +++ b/test/Microsoft.AspNetCore.Razor.Evolution.Test/RazorEngineTest.cs @@ -3,9 +3,9 @@ using System.Collections.Generic; using System.Linq; +using Microsoft.AspNetCore.Razor.Evolution.CodeGeneration; using Moq; using Xunit; -using Microsoft.AspNetCore.Razor.Evolution.CodeGeneration; namespace Microsoft.AspNetCore.Razor.Evolution { @@ -155,6 +155,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution feature => Assert.IsType(feature), feature => Assert.IsType(feature), feature => Assert.IsType(feature), + feature => Assert.IsType(feature), feature => Assert.IsType(feature)); } @@ -183,6 +184,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution feature => Assert.IsType(feature), feature => Assert.IsType(feature), feature => Assert.IsType(feature), + feature => Assert.IsType(feature), feature => Assert.IsType(feature), feature => Assert.IsType(feature)); } diff --git a/test/Microsoft.AspNetCore.Razor.Evolution.Test/RazorProjectItemTest.cs b/test/Microsoft.AspNetCore.Razor.Evolution.Test/RazorProjectItemTest.cs index ed45f6ea82..bda7205f53 100644 --- a/test/Microsoft.AspNetCore.Razor.Evolution.Test/RazorProjectItemTest.cs +++ b/test/Microsoft.AspNetCore.Razor.Evolution.Test/RazorProjectItemTest.cs @@ -1,8 +1,6 @@ // 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 Xunit; namespace Microsoft.AspNetCore.Razor.Evolution @@ -15,7 +13,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution // Arrange var emptyBasePath = "/"; var path = "/foo/bar.cshtml"; - var projectItem = new TestRazorProjectItem(emptyBasePath, path); + var projectItem = new TestRazorProjectItem(path, basePath: emptyBasePath); // Act var combinedPath = projectItem.CombinedPath; @@ -31,7 +29,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution { // Arrange var path = "/foo/bar.cshtml"; - var projectItem = new TestRazorProjectItem(basePath, path); + var projectItem = new TestRazorProjectItem(path, basePath: basePath); // Act var combinedPath = projectItem.CombinedPath; @@ -46,7 +44,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution public void Extension_ReturnsNullIfFileDoesNotHaveExtension(string path) { // Arrange - var projectItem = new TestRazorProjectItem("/views", path); + var projectItem = new TestRazorProjectItem(path, basePath: "/views"); // Act var extension = projectItem.Extension; @@ -62,7 +60,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution public void Extension_ReturnsFileExtension(string path, string expected) { // Arrange - var projectItem = new TestRazorProjectItem("/views", path); + var projectItem = new TestRazorProjectItem(path, basePath: "/views"); // Act var extension = projectItem.Extension; @@ -77,7 +75,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution public void FileName_ReturnsFileNameWithExtension(string path, string expected) { // Arrange - var projectItem = new TestRazorProjectItem("/", path); + var projectItem = new TestRazorProjectItem(path, basePath: "/"); // Act var fileName = projectItem.Filename; @@ -94,7 +92,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution public void PathWithoutExtension_ExcludesExtension(string path, string expected) { // Arrange - var projectItem = new TestRazorProjectItem("/", path); + var projectItem = new TestRazorProjectItem(path, basePath: "/"); // Act var fileName = projectItem.PathWithoutExtension; @@ -102,34 +100,5 @@ namespace Microsoft.AspNetCore.Razor.Evolution // Assert Assert.Equal(expected, fileName); } - - - private class TestRazorProjectItem : RazorProjectItem - { - public TestRazorProjectItem(string basePath, string path) - { - BasePath = basePath; - Path = path; - } - - public override string BasePath { get; } - - public override string Path { get; } - - public override string PhysicalPath - { - get - { - throw new NotImplementedException(); - } - } - - public override bool Exists => true; - - public override Stream Read() - { - throw new NotImplementedException(); - } - } } } diff --git a/test/Microsoft.AspNetCore.Razor.Evolution.Test/RazorTemplateEngineTest.cs b/test/Microsoft.AspNetCore.Razor.Evolution.Test/RazorTemplateEngineTest.cs new file mode 100644 index 0000000000..ef68383c22 --- /dev/null +++ b/test/Microsoft.AspNetCore.Razor.Evolution.Test/RazorTemplateEngineTest.cs @@ -0,0 +1,195 @@ +// 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 Microsoft.AspNetCore.Testing; +using Xunit; + +namespace Microsoft.AspNetCore.Razor.Evolution +{ + public class RazorTemplateEngineTest + { + [Fact] + public void GenerateCode_ThrowsIfItemCannotBeFound() + { + // Arrange + var project = new TestRazorProject(new RazorProjectItem[] { }); + var razorEngine = RazorEngine.Create(); + var templateEngine = new RazorTemplateEngine(razorEngine, project); + + // Act & Assert + var ex = Assert.Throws( + () => templateEngine.GenerateCode("/does-not-exist.cstml")); + Assert.Equal("The item '/does-not-exist.cstml' could not be found.", ex.Message); + } + + [Fact] + public void SettingOptions_ThrowsIfValueIsNull() + { + // Arrange + var project = new TestRazorProject(new RazorProjectItem[] { }); + var razorEngine = RazorEngine.Create(); + var templateEngine = new RazorTemplateEngine(razorEngine, project); + + // Act & Assert + ExceptionAssert.ThrowsArgumentNull( + () => templateEngine.Options = null, + "value"); + } + + [Fact] + public void GenerateCode_WithPath() + { + // Arrange + var path = "/Views/Home/Index.cshtml"; + var projectItem = new TestRazorProjectItem(path); + var project = new TestRazorProject(new[] { projectItem }); + var razorEngine = RazorEngine.Create(); + var templateEngine = new RazorTemplateEngine(razorEngine, project); + + // Act + var cSharpDocument = templateEngine.GenerateCode(path); + + // Assert + Assert.NotNull(cSharpDocument); + Assert.NotEmpty(cSharpDocument.GeneratedCode); + Assert.Empty(cSharpDocument.Diagnostics); + } + + [Fact] + public void GenerateCode_ThrowsIfProjectItemCannotBeFound() + { + // Arrange + var path = "/Views/Home/Index.cshtml"; + var project = new TestRazorProject(new RazorProjectItem[] { }); + var razorEngine = RazorEngine.Create(); + var templateEngine = new RazorTemplateEngine(razorEngine, project); + + // Act & Assert + var ex = Assert.Throws(() => templateEngine.GenerateCode(path)); + Assert.Equal($"The item '{path}' could not be found.", ex.Message); + } + + [Fact] + public void GenerateCode_WithProjectItem() + { + // Arrange + var path = "/Views/Home/Index.cshtml"; + var projectItem = new TestRazorProjectItem(path); + var project = new TestRazorProject(new[] { projectItem }); + var razorEngine = RazorEngine.Create(); + var templateEngine = new RazorTemplateEngine(razorEngine, project); + + // Act + var cSharpDocument = templateEngine.GenerateCode(projectItem); + + // Assert + Assert.NotNull(cSharpDocument); + Assert.NotEmpty(cSharpDocument.GeneratedCode); + Assert.Empty(cSharpDocument.Diagnostics); + } + + [Fact] + public void GenerateCode_WithCodeDocument() + { + // Arrange + var path = "/Views/Home/Index.cshtml"; + var projectItem = new TestRazorProjectItem(path); + var project = new TestRazorProject(new[] { projectItem }); + var razorEngine = RazorEngine.Create(); + var templateEngine = new RazorTemplateEngine(razorEngine, project); + + // Act - 1 + var codeDocument = templateEngine.CreateCodeDocument(path); + + // Assert - 1 + Assert.NotNull(codeDocument); + + // Act - 2 + var cSharpDocument = templateEngine.GenerateCode(codeDocument); + + // Assert + Assert.NotNull(cSharpDocument); + Assert.NotEmpty(cSharpDocument.GeneratedCode); + Assert.Empty(cSharpDocument.Diagnostics); + } + + [Fact] + public void CreateCodeDocument_ThrowsIfPathCannotBeFound() + { + // Arrange + var projectItem = new TestRazorProjectItem("/Views/Home/Index.cshtml"); + var project = new TestRazorProject(new[] { projectItem }); + var razorEngine = RazorEngine.Create(); + var templateEngine = new RazorTemplateEngine(razorEngine, project) + { + Options = + { + ImportsFileName = "MyImport.cshtml", + } + }; + + // Act & Assert + var ex = Assert.Throws(() => templateEngine.CreateCodeDocument("/DoesNotExist.cshtml")); + + // Assert + Assert.Equal("The item '/DoesNotExist.cshtml' could not be found.", ex.Message); + } + + [Fact] + public void CreateCodeDocument_IncludesImportsIfFileIsPresent() + { + // Arrange + var projectItem = new TestRazorProjectItem("/Views/Home/Index.cshtml"); + var import1 = new TestRazorProjectItem("/MyImport.cshtml"); + var import2 = new TestRazorProjectItem("/Views/Home/MyImport.cshtml"); + var project = new TestRazorProject(new[] { import1, import2, projectItem }); + var razorEngine = RazorEngine.Create(); + var templateEngine = new RazorTemplateEngine(razorEngine, project) + { + Options = + { + ImportsFileName = "MyImport.cshtml", + } + }; + + // Act + var codeDocument = templateEngine.CreateCodeDocument("/Views/Home/Index.cshtml"); + + // Assert + Assert.Collection(codeDocument.Imports, + import => Assert.Equal("/MyImport.cshtml", import.Filename), + import => Assert.Equal("/Views/Home/MyImport.cshtml", import.Filename)); + } + + [Fact] + public void CreateCodeDocument_IncludesDefaultImportIfNotNull() + { + // Arrange + var projectItem = new TestRazorProjectItem("/Views/Home/Index.cshtml"); + var import1 = new TestRazorProjectItem("/MyImport.cshtml"); + var import2 = new TestRazorProjectItem("/Views/Home/MyImport.cshtml"); + var project = new TestRazorProject(new[] { import1, import2, projectItem }); + var razorEngine = RazorEngine.Create(); + var defaultImport = RazorSourceDocument.ReadFrom(new MemoryStream(), "Default.cshtml"); + var templateEngine = new RazorTemplateEngine(razorEngine, project) + { + Options = + { + ImportsFileName = "MyImport.cshtml", + DefaultImports = defaultImport, + } + }; + + // Act + var codeDocument = templateEngine.CreateCodeDocument(projectItem); + + // Assert + Assert.Collection(codeDocument.Imports, + import => Assert.Same(defaultImport, import), + import => Assert.Equal("/MyImport.cshtml", import.Filename), + import => Assert.Equal("/Views/Home/MyImport.cshtml", import.Filename)); + } + } +} diff --git a/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/BasicIntegrationTest/CustomDirective.ir.txt b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/BasicIntegrationTest/CustomDirective.ir.txt index d11cf3074c..68a01819d7 100644 --- a/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/BasicIntegrationTest/CustomDirective.ir.txt +++ b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/BasicIntegrationTest/CustomDirective.ir.txt @@ -1,8 +1,7 @@ Document - Checksum - - NamespaceDeclaration - - + NamespaceDeclaration - - Razor UsingStatement - - System UsingStatement - - System.Threading.Tasks - ClassDeclaration - - - - - - RazorMethodDeclaration - - - - - - Directive - - test_directive + ClassDeclaration - - public - Template - - + RazorMethodDeclaration - - public - async, override - global::System.Threading.Tasks.Task - ExecuteAsync diff --git a/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/BasicIntegrationTest/Empty.ir.txt b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/BasicIntegrationTest/Empty.ir.txt index 209f3858f3..68a01819d7 100644 --- a/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/BasicIntegrationTest/Empty.ir.txt +++ b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/BasicIntegrationTest/Empty.ir.txt @@ -1,7 +1,7 @@ Document - Checksum - - NamespaceDeclaration - - + NamespaceDeclaration - - Razor UsingStatement - - System UsingStatement - - System.Threading.Tasks - ClassDeclaration - - - - - - RazorMethodDeclaration - - - - - + ClassDeclaration - - public - Template - - + RazorMethodDeclaration - - public - async, override - global::System.Threading.Tasks.Task - ExecuteAsync diff --git a/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/BasicIntegrationTest/HelloWorld.ir.txt b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/BasicIntegrationTest/HelloWorld.ir.txt index d998af149e..45b11d60fa 100644 --- a/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/BasicIntegrationTest/HelloWorld.ir.txt +++ b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/BasicIntegrationTest/HelloWorld.ir.txt @@ -1,8 +1,8 @@ Document - Checksum - - NamespaceDeclaration - - + NamespaceDeclaration - - Razor UsingStatement - - System UsingStatement - - System.Threading.Tasks - ClassDeclaration - - - - - - RazorMethodDeclaration - - - - - + ClassDeclaration - - public - Template - - + RazorMethodDeclaration - - public - async, override - global::System.Threading.Tasks.Task - ExecuteAsync HtmlContent - (0:0,0 [13] HelloWorld.cshtml) - Hello, World! diff --git a/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/HtmlAttributeIntegrationTest/HtmlWithConditionalAttribute.ir.txt b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/HtmlAttributeIntegrationTest/HtmlWithConditionalAttribute.ir.txt index 71b4bede6a..0a34c1e7b2 100644 --- a/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/HtmlAttributeIntegrationTest/HtmlWithConditionalAttribute.ir.txt +++ b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/HtmlAttributeIntegrationTest/HtmlWithConditionalAttribute.ir.txt @@ -1,10 +1,10 @@ Document - Checksum - - NamespaceDeclaration - - + NamespaceDeclaration - - Razor UsingStatement - - System UsingStatement - - System.Threading.Tasks - ClassDeclaration - - - - - - RazorMethodDeclaration - - - - - + ClassDeclaration - - public - Template - - + RazorMethodDeclaration - - public - async, override - global::System.Threading.Tasks.Task - ExecuteAsync HtmlContent - (0:0,0 [25] HtmlWithConditionalAttribute.cshtml) - \n\n \n\n \r\n"); diff --git a/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/InstrumentationPassIntegrationTest/BasicTest.ir.txt b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/InstrumentationPassIntegrationTest/BasicTest.ir.txt index 60c6b21b1a..39cde717f5 100644 --- a/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/InstrumentationPassIntegrationTest/BasicTest.ir.txt +++ b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/InstrumentationPassIntegrationTest/BasicTest.ir.txt @@ -1,14 +1,14 @@ Document - Checksum - - NamespaceDeclaration - - + NamespaceDeclaration - - Razor UsingStatement - - System UsingStatement - - System.Threading.Tasks - ClassDeclaration - - - - - + ClassDeclaration - - public - Template - - DeclarePreallocatedTagHelperAttribute - - __tagHelperAttribute_0 - value - Hello - HtmlAttributeValueStyle.DoubleQuotes DeclarePreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_1 - type - text - HtmlAttributeValueStyle.SingleQuotes DeclarePreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_2 - unbound - foo - HtmlAttributeValueStyle.DoubleQuotes DeclareTagHelperFields - - FormTagHelper - InputTagHelper - RazorMethodDeclaration - - - - - + RazorMethodDeclaration - - public - async, override - global::System.Threading.Tasks.Task - ExecuteAsync CSharpStatement - - BeginContext(31, 28, true); HtmlContent - (31:1,0 [28] BasicTest.cshtml) - Hola\n CSharpStatement - - EndContext(); diff --git a/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithBaseType.codegen.cs b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithBaseType.codegen.cs new file mode 100644 index 0000000000..f042292252 --- /dev/null +++ b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithBaseType.codegen.cs @@ -0,0 +1,16 @@ +#pragma checksum "TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithBaseType.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "247d02621904d87ab805e437f33c5d03b9a0de91" +namespace Razor +{ + #line hidden + using System; + using System.Threading.Tasks; + public class Template : MyBaseType + { + #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/GenerateCodeWithBaseType.cshtml b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithBaseType.cshtml new file mode 100644 index 0000000000..6df88a66a1 --- /dev/null +++ b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithBaseType.cshtml @@ -0,0 +1 @@ +

Hello world!

\ No newline at end of file diff --git a/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithDefaults.codegen.cs b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithDefaults.codegen.cs new file mode 100644 index 0000000000..c0f8f2eb5d --- /dev/null +++ b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithDefaults.codegen.cs @@ -0,0 +1,16 @@ +#pragma checksum "TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithDefaults.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "247d02621904d87ab805e437f33c5d03b9a0de91" +namespace Razor +{ + #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/GenerateCodeWithDefaults.cshtml b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithDefaults.cshtml new file mode 100644 index 0000000000..6df88a66a1 --- /dev/null +++ b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithDefaults.cshtml @@ -0,0 +1 @@ +

Hello world!

\ No newline at end of file diff --git a/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/TagHelpersIntegrationTest/NestedTagHelpers.ir.txt b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/TagHelpersIntegrationTest/NestedTagHelpers.ir.txt index ab226937f1..261f4b6e47 100644 --- a/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/TagHelpersIntegrationTest/NestedTagHelpers.ir.txt +++ b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/TagHelpersIntegrationTest/NestedTagHelpers.ir.txt @@ -1,14 +1,14 @@ Document - Checksum - - NamespaceDeclaration - - + NamespaceDeclaration - - Razor UsingStatement - - System UsingStatement - - System.Threading.Tasks - ClassDeclaration - - - - - + ClassDeclaration - - public - Template - - DeclarePreallocatedTagHelperAttribute - - __tagHelperAttribute_0 - value - Hello - HtmlAttributeValueStyle.DoubleQuotes DeclarePreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_1 - type - text - HtmlAttributeValueStyle.SingleQuotes DeclarePreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_2 - unbound - foo - HtmlAttributeValueStyle.DoubleQuotes DeclareTagHelperFields - - PTagHelper - FormTagHelper - InputTagHelper - RazorMethodDeclaration - - - - - + RazorMethodDeclaration - - public - async, override - global::System.Threading.Tasks.Task - ExecuteAsync TagHelper - (31:1,0 [20] NestedTagHelpers.cshtml) InitializeTagHelperStructure - - p - TagMode.StartTagAndEndTag HtmlContent - (43:1,12 [4] NestedTagHelpers.cshtml) - Hola diff --git a/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/TagHelpersIntegrationTest/SimpleTagHelpers.ir.txt b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/TagHelpersIntegrationTest/SimpleTagHelpers.ir.txt index 0dac40e506..b91c8b98bf 100644 --- a/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/TagHelpersIntegrationTest/SimpleTagHelpers.ir.txt +++ b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/TagHelpersIntegrationTest/SimpleTagHelpers.ir.txt @@ -1,13 +1,13 @@ Document - Checksum - - NamespaceDeclaration - - + NamespaceDeclaration - - Razor UsingStatement - - System UsingStatement - - System.Threading.Tasks - ClassDeclaration - - - - - + ClassDeclaration - - public - Template - - DeclarePreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_0 - value - Hello - HtmlAttributeValueStyle.SingleQuotes DeclarePreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_1 - type - text - HtmlAttributeValueStyle.SingleQuotes DeclareTagHelperFields - - InputTagHelper - RazorMethodDeclaration - - - - - + RazorMethodDeclaration - - public - async, override - global::System.Threading.Tasks.Task - ExecuteAsync HtmlContent - (31:1,0 [25] SimpleTagHelpers.cshtml) -

Hola

\n
\n TagHelper - (56:3,4 [35] SimpleTagHelpers.cshtml) InitializeTagHelperStructure - - input - TagMode.SelfClosing diff --git a/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/TagHelpersIntegrationTest/TagHelpersWithBoundAttributes.ir.txt b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/TagHelpersIntegrationTest/TagHelpersWithBoundAttributes.ir.txt index bbf60ae89f..64b3ce299c 100644 --- a/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/TagHelpersIntegrationTest/TagHelpersWithBoundAttributes.ir.txt +++ b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestFiles/IntegrationTests/TagHelpersIntegrationTest/TagHelpersWithBoundAttributes.ir.txt @@ -1,12 +1,12 @@ Document - Checksum - - NamespaceDeclaration - - + NamespaceDeclaration - - Razor UsingStatement - - System UsingStatement - - System.Threading.Tasks - ClassDeclaration - - - - - + ClassDeclaration - - public - Template - - DeclarePreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_0 - type - text - HtmlAttributeValueStyle.SingleQuotes DeclareTagHelperFields - - InputTagHelper - RazorMethodDeclaration - - - - - + RazorMethodDeclaration - - public - async, override - global::System.Threading.Tasks.Task - ExecuteAsync HtmlContent - (31:1,0 [12] TagHelpersWithBoundAttributes.cshtml) - \n TagHelper - (43:2,4 [34] TagHelpersWithBoundAttributes.cshtml) InitializeTagHelperStructure - - input - TagMode.SelfClosing diff --git a/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestRazorProject.cs b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestRazorProject.cs new file mode 100644 index 0000000000..c06c2ac667 --- /dev/null +++ b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestRazorProject.cs @@ -0,0 +1,34 @@ +// 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.Linq; + +namespace Microsoft.AspNetCore.Razor.Evolution +{ + public class TestRazorProject : RazorProject + { + private readonly Dictionary _lookup; + + public TestRazorProject(IList items) + { + _lookup = items.ToDictionary(item => item.Path); + } + + public override IEnumerable EnumerateItems(string basePath) + { + throw new NotImplementedException(); + } + + public override RazorProjectItem GetItem(string path) + { + if (!_lookup.TryGetValue(path, out var value)) + { + value = new NotFoundProjectItem("", path); + } + + return value; + } + } +} diff --git a/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestRazorProjectItem.cs b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestRazorProjectItem.cs new file mode 100644 index 0000000000..9ea4784a13 --- /dev/null +++ b/test/Microsoft.AspNetCore.Razor.Evolution.Test/TestRazorProjectItem.cs @@ -0,0 +1,33 @@ +// 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.Evolution +{ + public class TestRazorProjectItem : RazorProjectItem + { + public TestRazorProjectItem( + string path, + string physicalPath = null, + string basePath = "/") + { + Path = path; + PhysicalPath = physicalPath; + BasePath = basePath; + } + + public override string BasePath { get; } + + public override string Path { get; } + + public override string PhysicalPath { get; } + + public override bool Exists => true; + + public string Content { get; set; } = "Default content"; + + public override Stream Read() => new MemoryStream(Encoding.UTF8.GetBytes(Content)); + } +}