/// <summary> /// Initializes a new instance of <see cref="T:Microsoft.AspNetCore.Razor.Language.RazorTemplateEngine" />. /// </summary> /// <param name="engine">The <see cref="T:Microsoft.AspNetCore.Razor.Language.RazorEngine" />.</param> /// <param name="project">The <see cref="T:Microsoft.AspNetCore.Razor.Language.RazorProject" />.</param> // Token: 0x0600045F RID: 1119 RVA: 0x00009D6B File Offset: 0x00007F6B public RazorTemplateEngine(Microsoft.AspNetCore.Razor.Language.RazorEngine engine, Microsoft.AspNetCore.Razor.Language.RazorProject project) { if (engine == null) { throw new ArgumentNullException("engine"); } if (project == null) { throw new ArgumentNullException("project"); } this.Engine = engine; this.Project = project; this._options = new RazorTemplateEngineOptions(); }
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); }
public void Execute_CanHandleSingleLengthRemoveTagHelperDirective() { // Arrange var engine = RazorEngine.Create(builder => { builder.AddTagHelpers(new TagHelperDescriptor[0]); }); var phase = new DefaultRazorTagHelperBinderPhase() { Engine = engine, }; var expectedDiagnostics = new[] { RazorDiagnostic.Create( new RazorError( LegacyResources.ParseError_Unterminated_String_Literal, new SourceLocation(17 + Environment.NewLine.Length, 1, 17), length: 1)), RazorDiagnostic.Create( new RazorError( Resources.FormatInvalidTagHelperLookupText("\""), new SourceLocation(17 + Environment.NewLine.Length, 1, 17), length: 1)) }; var content = @" @removeTagHelper """; var sourceDocument = TestRazorSourceDocument.Create(content, fileName: null); var codeDocument = RazorCodeDocument.Create(sourceDocument); var originalTree = RazorSyntaxTree.Parse(sourceDocument); codeDocument.SetSyntaxTree(originalTree); // Act phase.Execute(codeDocument); // Assert var rewrittenTree = codeDocument.GetSyntaxTree(); var directiveValue = rewrittenTree.Root.Children.OfType <Block>().First().Children.Last() as Span; var chunkGenerator = Assert.IsType <RemoveTagHelperChunkGenerator>(directiveValue.ChunkGenerator); Assert.Equal(expectedDiagnostics, chunkGenerator.Diagnostics); }
public void Execute_RewritesTagHelpers() { // Arrange var engine = RazorEngine.Create(builder => { builder.AddTagHelpers(new[] { CreateTagHelperDescriptor( tagName: "form", typeName: "TestFormTagHelper", assemblyName: "TestAssembly"), CreateTagHelperDescriptor( tagName: "input", typeName: "TestInputTagHelper", assemblyName: "TestAssembly"), }); }); var phase = new DefaultRazorTagHelperBinderPhase() { Engine = engine, }; var sourceDocument = CreateTestSourceDocument(); var codeDocument = RazorCodeDocument.Create(sourceDocument); var originalTree = RazorSyntaxTree.Parse(sourceDocument); codeDocument.SetSyntaxTree(originalTree); // Act phase.Execute(codeDocument); // Assert var rewrittenTree = codeDocument.GetSyntaxTree(); Assert.Empty(rewrittenTree.Diagnostics); Assert.Equal(3, rewrittenTree.Root.Children.Count); var formTagHelper = Assert.IsType <TagHelperBlock>(rewrittenTree.Root.Children[2]); Assert.Equal("form", formTagHelper.TagName); Assert.Equal(3, formTagHelper.Children.Count); var inputTagHelper = Assert.IsType <TagHelperBlock>(formTagHelper.Children[1]); Assert.Equal("input", inputTagHelper.TagName); }
public override RazorProjectEngine Build() { RazorEngine engine = null; if (Configuration.DesignTime) { engine = RazorEngine.CreateDesignTimeEmpty(ConfigureRazorEngine); } else { engine = RazorEngine.CreateEmpty(ConfigureRazorEngine); } var projectEngineFeatures = Features.OfType <IRazorProjectEngineFeature>().ToArray(); var projectEngine = new DefaultRazorProjectEngine(engine, FileSystem, projectEngineFeatures); return(projectEngine); }
public void AddDirective_NoFeature_CreatesFeature() { // Arrange var engine = RazorEngine.CreateEmpty(b => { // Act b.AddDirective(DirectiveDescriptor.CreateDirective("test", DirectiveKind.SingleLine)); }); // Assert var actual = Assert.Single(engine.Features.OfType <IRazorDirectiveFeature>()); Assert.IsType <DefaultRazorDirectiveFeature>(actual); var directive = Assert.Single(actual.Directives); Assert.Equal("test", directive.Directive); }
public void AddTargetExtensions_NoFeature_CreatesFeature() { // Arrange var extension = new MyTargetExtension(); var engine = RazorEngine.CreateEmpty(b => { // Act b.AddTargetExtension(extension); }); // Assert var actual = Assert.Single(engine.Features.OfType <IRazorTargetExtensionFeature>()); Assert.IsType <DefaultRazorTargetExtensionFeature>(actual); Assert.Same(extension, Assert.Single(actual.TargetExtensions)); }
public void Execute_AddsSyntaxTree() { // Arrange var phase = new DefaultRazorParsingPhase(); var engine = RazorEngine.CreateEmpty(builder => { builder.Phases.Add(phase); builder.Features.Add(new DefaultRazorParserOptionsFeature(designTime: false, version: RazorLanguageVersion.Latest)); }); var codeDocument = TestRazorCodeDocument.CreateEmpty(); // Act phase.Execute(codeDocument); // Assert Assert.NotNull(codeDocument.GetSyntaxTree()); }
/// <summary> /// Initializes a new instance of <see cref="RazorTemplateEngine"/>. /// </summary> /// <param name="engine">The <see cref="RazorEngine"/>.</param> /// <param name="project">The <see cref="RazorProject"/>.</param> 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(); }
public void Execute_ThrowsForMissingDependency_SyntaxTree() { // Arrange var phase = new DefaultRazorIntermediateNodeLoweringPhase(); var engine = RazorEngine.CreateEmpty(b => { b.Phases.Add(phase); b.Features.Add(new DefaultRazorCodeGenerationOptionsFeature(designTime: false)); }); var codeDocument = TestRazorCodeDocument.CreateEmpty(); // Act & Assert ExceptionAssert.Throws <InvalidOperationException>( () => phase.Execute(codeDocument), $"The '{nameof(DefaultRazorIntermediateNodeLoweringPhase)}' phase requires a '{nameof(RazorSyntaxTree)}' " + $"provided by the '{nameof(RazorCodeDocument)}'."); }
public void Execute_DirectiveWithError_PreservesDiagnosticsAndRemovesDirectiveNodeFromDocument() { // Arrange var content = "@custom \"Hello\""; var expectedDiagnostic = RazorDiagnostic.Create(new RazorDiagnosticDescriptor("RZ9999", () => "Some diagnostic message.", RazorDiagnosticSeverity.Error), SourceSpan.Undefined); var sourceDocument = TestRazorSourceDocument.Create(content); var codeDocument = RazorCodeDocument.Create(sourceDocument); var defaultEngine = RazorEngine.Create(b => { b.AddDirective(DirectiveDescriptor.CreateDirective("custom", DirectiveKind.SingleLine, d => d.AddStringToken())); }); var documentNode = Lower(codeDocument, defaultEngine); // Add the diagnostic to the directive node. var directiveNode = documentNode.FindDescendantNodes <DirectiveIntermediateNode>().Single(); directiveNode.Diagnostics.Add(expectedDiagnostic); var pass = new DirectiveRemovalOptimizationPass() { Engine = defaultEngine, }; // Act pass.Execute(codeDocument, documentNode); // Assert var diagnostic = Assert.Single(documentNode.Diagnostics); Assert.Equal(expectedDiagnostic, diagnostic); Children(documentNode, node => Assert.IsType <NamespaceDeclarationIntermediateNode>(node)); var @namespace = documentNode.Children[0]; Children(@namespace, node => Assert.IsType <ClassDeclarationIntermediateNode>(node)); var @class = @namespace.Children[0]; var method = SingleChild <MethodDeclarationIntermediateNode>(@class); Assert.Empty(method.Children); }
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 <InvalidOperationException>(() => templateEngine.CreateCodeDocument("/DoesNotExist.cshtml")); // Assert Assert.Equal("The item '/DoesNotExist.cshtml' could not be found.", ex.Message); }
public void GetImports_CanQueryInformationOnNonExistentFileWithoutImports() { // Arrange var project = new TestRazorProject(); var razorEngine = RazorEngine.Create(); var templateEngine = new RazorTemplateEngine(razorEngine, project) { Options = { ImportsFileName = "MyImport.cshtml" } }; var projectItemToQuery = project.GetItem("/Views/Home/Index.cshtml"); // Act var imports = templateEngine.GetImports(projectItemToQuery); // Assert Assert.Empty(imports); }
public void Execute_HasDocumentKind_IgnoresDocument() { // Arrange var documentNode = new DocumentIntermediateNode() { DocumentKind = "ignore", Options = RazorCodeGenerationOptions.CreateDefault(), }; var pass = new TestDocumentClassifierPass(); pass.Engine = RazorEngine.CreateEmpty(b => { }); // Act pass.Execute(TestRazorCodeDocument.CreateEmpty(), documentNode); // Assert Assert.Equal("ignore", documentNode.DocumentKind); NoChildren(documentNode); }
public void Execute_ExecutesPhasesInOrder() { // Arrange var codeDocument = TestRazorCodeDocument.CreateEmpty(); // We're going to set up mocks to simulate a sequence of passes. We don't care about // what's in the trees, we're just going to look at the identity via strict mocks. var originalSyntaxTree = RazorSyntaxTree.Parse(codeDocument.Source); var firstPassSyntaxTree = RazorSyntaxTree.Parse(codeDocument.Source); var secondPassSyntaxTree = RazorSyntaxTree.Parse(codeDocument.Source); codeDocument.SetSyntaxTree(originalSyntaxTree); var firstPass = new Mock <IRazorSyntaxTreePass>(MockBehavior.Strict); firstPass.SetupGet(m => m.Order).Returns(0); firstPass.SetupProperty(m => m.Engine); firstPass.Setup(m => m.Execute(codeDocument, originalSyntaxTree)).Returns(firstPassSyntaxTree); var secondPass = new Mock <IRazorSyntaxTreePass>(MockBehavior.Strict); secondPass.SetupGet(m => m.Order).Returns(1); secondPass.SetupProperty(m => m.Engine); secondPass.Setup(m => m.Execute(codeDocument, firstPassSyntaxTree)).Returns(secondPassSyntaxTree); var phase = new DefaultRazorSyntaxTreePhase(); var engine = RazorEngine.CreateEmpty(b => { b.Phases.Add(phase); b.Features.Add(firstPass.Object); b.Features.Add(secondPass.Object); }); // Act phase.Execute(codeDocument); // Assert Assert.Same(secondPassSyntaxTree, codeDocument.GetSyntaxTree()); }
public void Execute_NoMatch_IgnoresDocument() { // Arrange var documentNode = new DocumentIntermediateNode() { Options = RazorCodeGenerationOptions.CreateDefault(), }; var pass = new TestDocumentClassifierPass() { Engine = RazorEngine.CreateEmpty(b => { }), ShouldMatch = false, }; // Act pass.Execute(TestRazorCodeDocument.CreateEmpty(), documentNode); // Assert Assert.Null(documentNode.DocumentKind); NoChildren(documentNode); }
public void AddTargetExtensions_ExistingFeature_UsesFeature() { // Arrange var extension = new MyTargetExtension(); var expected = new DefaultRazorTargetExtensionFeature(); var engine = RazorEngine.CreateEmpty(b => { b.Features.Add(expected); // Act b.AddTargetExtension(extension); }); // Assert var actual = Assert.Single(engine.Features.OfType <IRazorTargetExtensionFeature>()); Assert.Same(expected, actual); Assert.Same(extension, Assert.Single(actual.TargetExtensions)); }
public void AddDirective_ExistingFeature_UsesFeature() { // Arrange var expected = new DefaultRazorDirectiveFeature(); var engine = RazorEngine.CreateEmpty(b => { b.Features.Add(expected); // Act b.AddDirective(DirectiveDescriptor.CreateDirective("test", DirectiveKind.SingleLine)); }); // Assert var actual = Assert.Single(engine.Features.OfType <IRazorDirectiveFeature>()); Assert.Same(expected, actual); var directive = Assert.Single(actual.Directives); Assert.Equal("test", directive.Directive); }
public void CreateCodeDocument_WithFileSystemProject_ReturnsCorrectItems() { // Arrange var testFolder = Path.Combine( TestProject.GetProjectDirectory(typeof(FileSystemRazorProjectTest)), "TestFiles", "FileSystemRazorProject"); var project = new FileSystemRazorProject(testFolder); var razorEngine = RazorEngine.Create(); var templateEngine = new RazorTemplateEngine(razorEngine, project) { Options = { ImportsFileName = "_ViewImports.cshtml" } }; // Act var codeDocument = templateEngine.CreateCodeDocument("/Views/Home/Index.cshtml"); // Assert Assert.Collection( codeDocument.Imports, item => { Assert.Equal(Path.Combine(testFolder, "_ViewImports.cshtml"), item.FilePath); Assert.Equal("_ViewImports.cshtml", item.RelativePath); }, item => { Assert.Equal(Path.Combine(testFolder, "Views", "_ViewImports.cshtml"), item.FilePath); Assert.Equal(Path.Combine("Views", "_ViewImports.cshtml"), item.RelativePath); }, item => { Assert.Equal(Path.Combine(testFolder, "Views", "Home", "_ViewImports.cshtml"), item.FilePath); Assert.Equal(Path.Combine("Views", "Home", "_ViewImports.cshtml"), item.RelativePath); }); }
public void Execute_CanHandleSingleLengthTagHelperPrefix() { // Arrange var engine = RazorEngine.Create(builder => { builder.AddTagHelpers(new TagHelperDescriptor[0]); }); var phase = new DefaultRazorTagHelperBinderPhase() { Engine = engine, }; var expectedDiagnostics = new[] { RazorDiagnosticFactory.CreateParsing_UnterminatedStringLiteral( new SourceSpan(new SourceLocation(17 + Environment.NewLine.Length, 1, 17), contentLength: 1)), RazorDiagnosticFactory.CreateParsing_InvalidTagHelperPrefixValue( new SourceSpan(new SourceLocation(17 + Environment.NewLine.Length, 1, 17), contentLength: 1), "tagHelperPrefix", '\"', "\""), }; var content = @" @tagHelperPrefix """; var sourceDocument = TestRazorSourceDocument.Create(content, filePath: null); var codeDocument = RazorCodeDocument.Create(sourceDocument); var originalTree = RazorSyntaxTree.Parse(sourceDocument); codeDocument.SetSyntaxTree(originalTree); // Act phase.Execute(codeDocument); // Assert var rewrittenTree = codeDocument.GetSyntaxTree(); var directiveValue = rewrittenTree.Root.Children.OfType <Block>().First().Children.Last() as Span; var chunkGenerator = Assert.IsType <TagHelperPrefixDirectiveChunkGenerator>(directiveValue.ChunkGenerator); Assert.Equal(expectedDiagnostics, chunkGenerator.Diagnostics); }
public void OnInitialized_OrdersPassesInAscendingOrder() { // Arrange & Act var phase = new DefaultRazorOptimizationPhase(); var first = Mock.Of <IRazorOptimizationPass>(p => p.Order == 15); var second = Mock.Of <IRazorOptimizationPass>(p => p.Order == 17); var engine = RazorEngine.CreateEmpty(b => { b.Phases.Add(phase); b.Features.Add(second); b.Features.Add(first); }); // Assert Assert.Collection( phase.Passes, p => Assert.Same(first, p), p => Assert.Same(second, p)); }
public void Execute_UsesConfigureParserFeatures() { // Arrange var phase = new DefaultRazorParsingPhase(); var engine = RazorEngine.CreateEmpty((builder) => { builder.Phases.Add(phase); builder.Features.Add(new DefaultRazorParserOptionsFeature(designTime: false, version: RazorLanguageVersion.Latest)); builder.Features.Add(new MyParserOptionsFeature()); }); var codeDocument = TestRazorCodeDocument.CreateEmpty(); // Act phase.Execute(codeDocument); // Assert var syntaxTree = codeDocument.GetSyntaxTree(); var directive = Assert.Single(syntaxTree.Options.Directives); Assert.Equal("test", directive.Directive); }
public void CreateCodeDocument_NullImportFileName_IncludesDefaultImportIfNotNull() { // Arrange var projectItem = new TestRazorProjectItem("/Views/Home/Index.cshtml"); var project = new TestRazorProject(new[] { projectItem }); var razorEngine = RazorEngine.Create(); var defaultImport = RazorSourceDocument.ReadFrom(new MemoryStream(), "Default.cshtml"); var templateEngine = new RazorTemplateEngine(razorEngine, project) { Options = { DefaultImports = defaultImport, } }; // Act var codeDocument = templateEngine.CreateCodeDocument(projectItem); // Assert Assert.Collection(codeDocument.Imports, import => Assert.Same(defaultImport, import)); }
public void GetImportItems_WithPath_ReturnsAllImportsForFile() { // Arrange var expected = new[] { "/Views/Home/MyImport.cshtml", "/Views/MyImport.cshtml", "/MyImport.cshtml" }; var project = new TestRazorProject(); var razorEngine = RazorEngine.Create(); var templateEngine = new RazorTemplateEngine(razorEngine, project) { Options = { ImportsFileName = "MyImport.cshtml" } }; // Act var imports = templateEngine.GetImportItems("/Views/Home/Index.cshtml"); // Assert var paths = imports.Select(i => i.FilePath); Assert.Equal(expected, paths); }
public void Execute_CollatesSyntaxDiagnosticsFromImportDocuments() { // Arrange var phase = new DefaultRazorIntermediateNodeLoweringPhase(); var engine = RazorEngine.CreateEmpty(b => { b.Phases.Add(phase); b.Features.Add(new DefaultRazorCodeGenerationOptionsFeature(designTime: false)); }); var codeDocument = TestRazorCodeDocument.CreateEmpty(); codeDocument.SetSyntaxTree(RazorSyntaxTree.Parse(codeDocument.Source)); codeDocument.SetImportSyntaxTrees(new[] { RazorSyntaxTree.Parse(TestRazorSourceDocument.Create("@ ")), RazorSyntaxTree.Parse(TestRazorSourceDocument.Create("<p @(")), }); var options = RazorCodeGenerationOptions.CreateDefault(); // Act phase.Execute(codeDocument); // Assert var documentNode = codeDocument.GetDocumentIntermediateNode(); Assert.Collection(documentNode.Diagnostics, diagnostic => { Assert.Equal(@"A space or line break was encountered after the ""@"" character. Only valid identifiers, keywords, comments, ""("" and ""{"" are valid at the start of a code block and they must occur immediately following ""@"" with no space in between.", diagnostic.GetMessage()); }, diagnostic => { Assert.Equal(@"The explicit expression block is missing a closing "")"" character. Make sure you have a matching "")"" character for all the ""("" characters within this block, and that none of the "")"" characters are being interpreted as markup.", diagnostic.GetMessage()); }); }
public void Execute_NoopsWhenNoTagHelperFeature() { // Arrange var engine = RazorEngine.Create(); var phase = new DefaultRazorTagHelperBinderPhase() { Engine = engine, }; var sourceDocument = CreateTestSourceDocument(); var codeDocument = RazorCodeDocument.Create(sourceDocument); var originalTree = RazorSyntaxTree.Parse(sourceDocument); codeDocument.SetSyntaxTree(originalTree); // Act phase.Execute(codeDocument); // Assert var outputTree = codeDocument.GetSyntaxTree(); Assert.Empty(outputTree.Diagnostics); Assert.Same(originalTree, outputTree); }
public void Execute_CollatesSyntaxDiagnosticsFromSourceDocument() { // Arrange var phase = new DefaultRazorIntermediateNodeLoweringPhase(); var engine = RazorEngine.CreateEmpty(b => { b.Phases.Add(phase); b.Features.Add(new DefaultRazorCodeGenerationOptionsFeature(designTime: false)); }); var codeDocument = TestRazorCodeDocument.Create("<p class=@("); codeDocument.SetSyntaxTree(RazorSyntaxTree.Parse(codeDocument.Source)); // Act phase.Execute(codeDocument); // Assert var documentNode = codeDocument.GetDocumentIntermediateNode(); var diagnostic = Assert.Single(documentNode.Diagnostics); Assert.Equal(@"The explicit expression block is missing a closing "")"" character. Make sure you have a matching "")"" character for all the ""("" characters within this block, and that none of the "")"" characters are being interpreted as markup.", diagnostic.GetMessage()); }
public void Execute_AddsPrimaryAnnotations() { // Arrange var documentNode = new DocumentIntermediateNode() { Options = RazorCodeGenerationOptions.CreateDefault(), }; var builder = IntermediateNodeBuilder.Create(documentNode); builder.Add(new HtmlContentIntermediateNode()); builder.Add(new CSharpCodeIntermediateNode()); var pass = new TestDocumentClassifierPass() { Engine = RazorEngine.CreateEmpty(b => { }), Namespace = "TestNamespace", Class = "TestClass", Method = "TestMethod", }; // Act pass.Execute(TestRazorCodeDocument.CreateEmpty(), documentNode); // Assert var @namespace = SingleChild <NamespaceDeclarationIntermediateNode>(documentNode); AnnotationEquals(@namespace, CommonAnnotations.PrimaryNamespace); var @class = SingleChild <ClassDeclarationIntermediateNode>(@namespace); AnnotationEquals(@class, CommonAnnotations.PrimaryClass); var method = SingleChild <MethodDeclarationIntermediateNode>(@class); AnnotationEquals(method, CommonAnnotations.PrimaryMethod); }
public void Execute_CanInitializeDefaults() { // Arrange var documentNode = new DocumentIntermediateNode() { Options = RazorCodeGenerationOptions.CreateDefault(), }; var builder = IntermediateNodeBuilder.Create(documentNode); builder.Add(new HtmlContentIntermediateNode()); builder.Add(new CSharpCodeIntermediateNode()); var pass = new TestDocumentClassifierPass() { Engine = RazorEngine.CreateEmpty(b => { }), Namespace = "TestNamespace", Class = "TestClass", Method = "TestMethod", }; // Act pass.Execute(TestRazorCodeDocument.CreateEmpty(), documentNode); // Assert var @namespace = SingleChild <NamespaceDeclarationIntermediateNode>(documentNode); Assert.Equal("TestNamespace", @namespace.Content); var @class = SingleChild <ClassDeclarationIntermediateNode>(@namespace); Assert.Equal("TestClass", @class.ClassName); var method = SingleChild <MethodDeclarationIntermediateNode>(@class); Assert.Equal("TestMethod", method.MethodName); }
public DefaultRazorProjectEngine( RazorConfiguration configuration, RazorEngine engine, RazorProjectFileSystem fileSystem, IReadOnlyList <IRazorProjectEngineFeature> projectFeatures) { if (configuration == null) { throw new ArgumentNullException(nameof(configuration)); } if (engine == null) { throw new ArgumentNullException(nameof(engine)); } if (fileSystem == null) { throw new ArgumentNullException(nameof(fileSystem)); } if (projectFeatures == null) { throw new ArgumentNullException(nameof(projectFeatures)); } Configuration = configuration; Engine = engine; FileSystem = fileSystem; ProjectFeatures = projectFeatures; for (var i = 0; i < projectFeatures.Count; i++) { projectFeatures[i].ProjectEngine = this; } }