// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information. using System.IO; using System.Threading; using System.Web.Razor.Generator; using System.Web.Razor.Parser; using System.Web.Razor.Text; using System.Web.WebPages.TestUtils; using Moq; using Xunit; using Assert = Microsoft.TestCommon.AssertEx; namespace System.Web.Razor.Test { public class RazorTemplateEngineTest { [Fact] public void ConstructorRequiresNonNullHost() { Assert.ThrowsArgumentNull(() => new RazorTemplateEngine(null), "host"); } [Fact] public void ConstructorInitializesHost() { // Arrange RazorEngineHost host = new RazorEngineHost(new CSharpRazorCodeLanguage()); // Act RazorTemplateEngine engine = new RazorTemplateEngine(host); // Assert Assert.Same(host, engine.Host); } [Fact] public void CreateParserMethodIsConstructedFromHost() { // Arrange RazorEngineHost host = CreateHost(); RazorTemplateEngine engine = new RazorTemplateEngine(host); // Act RazorParser parser = engine.CreateParser(); // Assert Assert.IsType(parser.CodeParser); Assert.IsType(parser.MarkupParser); } [Fact] public void CreateParserMethodSetsParserContextToDesignTimeModeIfHostSetToDesignTimeMode() { // Arrange RazorEngineHost host = CreateHost(); RazorTemplateEngine engine = new RazorTemplateEngine(host); host.DesignTimeMode = true; // Act RazorParser parser = engine.CreateParser(); // Assert Assert.True(parser.DesignTimeMode); } [Fact] public void CreateParserMethodPassesParsersThroughDecoratorMethodsOnHost() { // Arrange ParserBase expectedCode = new Mock().Object; ParserBase expectedMarkup = new Mock().Object; var mockHost = new Mock(new CSharpRazorCodeLanguage()) { CallBase = true }; mockHost.Setup(h => h.DecorateCodeParser(It.IsAny())) .Returns(expectedCode); mockHost.Setup(h => h.DecorateMarkupParser(It.IsAny())) .Returns(expectedMarkup); RazorTemplateEngine engine = new RazorTemplateEngine(mockHost.Object); // Act RazorParser actual = engine.CreateParser(); // Assert Assert.Equal(expectedCode, actual.CodeParser); Assert.Equal(expectedMarkup, actual.MarkupParser); } [Fact] public void CreateCodeGeneratorMethodPassesCodeGeneratorThroughDecorateMethodOnHost() { // Arrange var mockHost = new Mock(new CSharpRazorCodeLanguage()) { CallBase = true }; RazorCodeGenerator expected = new Mock("Foo", "Bar", "Baz", mockHost.Object).Object; mockHost.Setup(h => h.DecorateCodeGenerator(It.IsAny())) .Returns(expected); RazorTemplateEngine engine = new RazorTemplateEngine(mockHost.Object); // Act RazorCodeGenerator actual = engine.CreateCodeGenerator("Foo", "Bar", "Baz"); // Assert Assert.Equal(expected, actual); } [Fact] public void ParseTemplateCopiesTextReaderContentToSeekableTextReaderAndPassesToParseTemplateCore() { // Arrange Mock mockEngine = new Mock(CreateHost()); TextReader reader = new StringReader("foo"); CancellationTokenSource source = new CancellationTokenSource(); // Act mockEngine.Object.ParseTemplate(reader, cancelToken: source.Token); // Assert mockEngine.Verify(e => e.ParseTemplateCore(It.Is(l => l.ReadToEnd() == "foo"), source.Token)); } [Fact] public void GenerateCodeCopiesTextReaderContentToSeekableTextReaderAndPassesToGenerateCodeCore() { // Arrange Mock mockEngine = new Mock(CreateHost()); TextReader reader = new StringReader("foo"); CancellationTokenSource source = new CancellationTokenSource(); string className = "Foo"; string ns = "Bar"; string src = "Baz"; // Act mockEngine.Object.GenerateCode(reader, className: className, rootNamespace: ns, sourceFileName: src, cancelToken: source.Token); // Assert mockEngine.Verify(e => e.GenerateCodeCore(It.Is(l => l.ReadToEnd() == "foo"), className, ns, src, source.Token)); } [Fact] public void ParseTemplateOutputsResultsOfParsingProvidedTemplateSource() { // Arrange RazorTemplateEngine engine = new RazorTemplateEngine(CreateHost()); // Act ParserResults results = engine.ParseTemplate(new StringTextBuffer("foo @bar(")); // Assert Assert.False(results.Success); Assert.Single(results.ParserErrors); Assert.NotNull(results.Document); } [Fact] public void GenerateOutputsResultsOfParsingAndGeneration() { // Arrange RazorTemplateEngine engine = new RazorTemplateEngine(CreateHost()); // Act GeneratorResults results = engine.GenerateCode(new StringTextBuffer("foo @bar(")); // Assert Assert.False(results.Success); Assert.Single(results.ParserErrors); Assert.NotNull(results.Document); Assert.NotNull(results.GeneratedCode); Assert.Null(results.DesignTimeLineMappings); } [Fact] public void GenerateOutputsDesignTimeMappingsIfDesignTimeSetOnHost() { // Arrange RazorTemplateEngine engine = new RazorTemplateEngine(CreateHost(designTime: true)); // Act GeneratorResults results = engine.GenerateCode(new StringTextBuffer("foo @bar()"), className: null, rootNamespace: null, sourceFileName: "foo.cshtml"); // Assert Assert.True(results.Success); Assert.Empty(results.ParserErrors); Assert.NotNull(results.Document); Assert.NotNull(results.GeneratedCode); Assert.NotNull(results.DesignTimeLineMappings); } private static RazorEngineHost CreateHost(bool designTime = false) { return new RazorEngineHost(new CSharpRazorCodeLanguage()) { DesignTimeMode = designTime }; } } }