From 0eb614b0272417bade4dc8182d5db66923e23cb3 Mon Sep 17 00:00:00 2001 From: "N. Taylor Mullen" Date: Thu, 18 Dec 2014 15:47:51 -0800 Subject: [PATCH] Modify tests to allow new content mode design for runtime components. - Added a new internal ctor for TagHelperExecutionContext since it's used in multiple tests to allow for less friction testing. #221 --- .../TagHelpers/TagHelperExecutionContext.cs | 12 ++ .../TagHelpers/TagHelperOutput.cs | 6 - .../TagHelperExecutionContextTest.cs | 62 ++++++ .../TagHelpers/TagHelperOutputTest.cs | 198 +++++++++++++++--- .../TagHelpers/TagHelperRunnerTest.cs | 17 -- .../TagHelpers/TagHelperScopeManagerTest.cs | 50 ++++- 6 files changed, 286 insertions(+), 59 deletions(-) diff --git a/src/Microsoft.AspNet.Razor.Runtime/TagHelpers/TagHelperExecutionContext.cs b/src/Microsoft.AspNet.Razor.Runtime/TagHelpers/TagHelperExecutionContext.cs index 930359cc04..03593d80fa 100644 --- a/src/Microsoft.AspNet.Razor.Runtime/TagHelpers/TagHelperExecutionContext.cs +++ b/src/Microsoft.AspNet.Razor.Runtime/TagHelpers/TagHelperExecutionContext.cs @@ -19,6 +19,18 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers private readonly Func _endWritingScope; private string _childContent; + /// + /// Internal for testing purposes only. + /// + internal TagHelperExecutionContext(string tagName) + : this(tagName, + uniqueId: string.Empty, + executeChildContentAsync: async () => await Task.FromResult(result: true), + startWritingScope: () => { }, + endWritingScope: () => new StringWriter()) + { + } + /// /// Instantiates a new . /// diff --git a/src/Microsoft.AspNet.Razor.Runtime/TagHelpers/TagHelperOutput.cs b/src/Microsoft.AspNet.Razor.Runtime/TagHelpers/TagHelperOutput.cs index 9c82848f8b..54e54e9f9c 100644 --- a/src/Microsoft.AspNet.Razor.Runtime/TagHelpers/TagHelperOutput.cs +++ b/src/Microsoft.AspNet.Razor.Runtime/TagHelpers/TagHelperOutput.cs @@ -24,12 +24,6 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers Attributes = new Dictionary(StringComparer.OrdinalIgnoreCase); } - // Internal for testing - internal TagHelperOutput(string tagName, [NotNull] IDictionary attributes) - : this(tagName, attributes, string.Empty) - { - } - /// /// Instantiates a new instance of . /// diff --git a/test/Microsoft.AspNet.Razor.Runtime.Test/TagHelpers/TagHelperExecutionContextTest.cs b/test/Microsoft.AspNet.Razor.Runtime.Test/TagHelpers/TagHelperExecutionContextTest.cs index 1b51c9ba85..909eae7a5e 100644 --- a/test/Microsoft.AspNet.Razor.Runtime.Test/TagHelpers/TagHelperExecutionContextTest.cs +++ b/test/Microsoft.AspNet.Razor.Runtime.Test/TagHelpers/TagHelperExecutionContextTest.cs @@ -1,14 +1,76 @@ // Copyright (c) Microsoft Open Technologies, Inc. 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.IO; using System.Linq; +using System.Threading.Tasks; using Xunit; namespace Microsoft.AspNet.Razor.Runtime.TagHelpers { public class TagHelperExecutionContextTest { + [Fact] + public async Task GetChildContentAsync_CachesValue() + { + // Arrange + var writer = new StringWriter(); + var expectedContent = string.Empty; + var executionContext = new TagHelperExecutionContext( + "p", + uniqueId: string.Empty, + executeChildContentAsync: () => + { + if (string.IsNullOrEmpty(expectedContent)) + { + expectedContent = "Hello from child content: " + Guid.NewGuid().ToString(); + } + + writer.Write(expectedContent); + + return Task.FromResult(result: true); + }, + startWritingScope: () => { }, + endWritingScope: () => writer); + + // Act + var content1 = await executionContext.GetChildContentAsync(); + var content2 = await executionContext.GetChildContentAsync(); + + // Assert + Assert.Same(content1, content2); + Assert.Equal(expectedContent, content1); + Assert.Equal(expectedContent, content2); + } + + [Fact] + public async Task ExecuteChildContentAsync_IsNotMemoized() + { + // Arrange + var childContentExecutionCount = 0; + var executionContext = new TagHelperExecutionContext( + "p", + uniqueId: string.Empty, + executeChildContentAsync: () => + { + childContentExecutionCount++; + + return Task.FromResult(result: true); + }, + startWritingScope: () => { }, + endWritingScope: () => new StringWriter()); + + // Act + await executionContext.ExecuteChildContentAsync(); + await executionContext.ExecuteChildContentAsync(); + await executionContext.ExecuteChildContentAsync(); + + // Assert + Assert.Equal(3, childContentExecutionCount); + } + public static TheoryData DictionaryCaseTestingData { get diff --git a/test/Microsoft.AspNet.Razor.Runtime.Test/TagHelpers/TagHelperOutputTest.cs b/test/Microsoft.AspNet.Razor.Runtime.Test/TagHelpers/TagHelperOutputTest.cs index 34a34a3659..343853447e 100644 --- a/test/Microsoft.AspNet.Razor.Runtime.Test/TagHelpers/TagHelperOutputTest.cs +++ b/test/Microsoft.AspNet.Razor.Runtime.Test/TagHelpers/TagHelperOutputTest.cs @@ -9,39 +9,65 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers public class TagHelperOutputTest { [Fact] - public void TagName_CannotSetToNullInCtor() + public void TagName_CanSetToNullInCtor() { // Arrange & Act var tagHelperOutput = new TagHelperOutput(null); // Assert - Assert.Empty(tagHelperOutput.TagName); + Assert.Null(tagHelperOutput.TagName); } [Fact] - public void TagName_CannotSetToNull() + public void TagName_CanSetToNull() { - // Arrange - var tagHelperOutput = new TagHelperOutput("p"); - - // Act - tagHelperOutput.TagName = null; + // Arrange & Act + var tagHelperOutput = new TagHelperOutput("p") + { + TagName = null + }; // Assert - Assert.Empty(tagHelperOutput.TagName); + Assert.Null(tagHelperOutput.TagName); } [Fact] - public void Content_CannotSetToNull() + public void Content_CanSetToNull() { - // Arrange - var tagHelperOutput = new TagHelperOutput("p"); - - // Act - tagHelperOutput.Content = null; + // Arrange & Act + var tagHelperOutput = new TagHelperOutput("p") + { + Content = null + }; // Assert - Assert.Empty(tagHelperOutput.Content); + Assert.Null(tagHelperOutput.Content); + } + + [Fact] + public void PreContent_CanSetToNull() + { + // Arrange & Act + var tagHelperOutput = new TagHelperOutput("p") + { + PreContent = null + }; + + // Assert + Assert.Null(tagHelperOutput.PreContent); + } + + [Fact] + public void PostContent_CanSetToNull() + { + // Arrange & Act + var tagHelperOutput = new TagHelperOutput("p") + { + PostContent = null + }; + + // Assert + Assert.Null(tagHelperOutput.PostContent); } [Fact] @@ -119,9 +145,10 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers { { "class", "btn" }, { "something", " spaced " } - }); - - tagHelperOutput.SelfClosing = true; + }) + { + SelfClosing = true + }; // Act var output = tagHelperOutput.GenerateStartTag(); @@ -135,9 +162,10 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers public void GenerateEndTag_ReturnsNothingIfWhitespaceTagName() { // Arrange - var tagHelperOutput = new TagHelperOutput(" "); ; - - tagHelperOutput.Content = "Hello World"; + var tagHelperOutput = new TagHelperOutput(" ") + { + Content = "Hello World" + }; // Act var output = tagHelperOutput.GenerateEndTag(); @@ -146,13 +174,47 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers Assert.Empty(output); } + [Fact] + public void GeneratePreContent_ReturnsPreContent() + { + // Arrange + var tagHelperOutput = new TagHelperOutput("p") + { + PreContent = "Hello World" + }; + + // Act + var output = tagHelperOutput.GeneratePreContent(); + + // Assert + Assert.Equal("Hello World", output); + } + + [Fact] + public void GeneratePreContent_ReturnsNothingIfSelfClosing() + { + // Arrange + var tagHelperOutput = new TagHelperOutput("p") + { + SelfClosing = true, + PreContent = "Hello World" + }; + + // Act + var output = tagHelperOutput.GeneratePreContent(); + + // Assert + Assert.Empty(output); + } + [Fact] public void GenerateContent_ReturnsContent() { // Arrange - var tagHelperOutput = new TagHelperOutput("p"); - - tagHelperOutput.Content = "Hello World"; + var tagHelperOutput = new TagHelperOutput("p") + { + Content = "Hello World" + }; // Act var output = tagHelperOutput.GenerateContent(); @@ -168,11 +230,10 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers // Arrange var tagHelperOutput = new TagHelperOutput("p") { - SelfClosing = true + SelfClosing = true, + Content = "Hello World" }; - tagHelperOutput.Content = "Hello World"; - // Act var output = tagHelperOutput.GenerateContent(); @@ -180,6 +241,39 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers Assert.Empty(output); } + [Fact] + public void GeneratePostContent_ReturnsPostContent() + { + // Arrange + var tagHelperOutput = new TagHelperOutput("p") + { + PostContent = "Hello World" + }; + + // Act + var output = tagHelperOutput.GeneratePostContent(); + + // Assert + Assert.Equal("Hello World", output); + } + + [Fact] + public void GeneratePostContent_ReturnsNothingIfSelfClosing() + { + // Arrange + var tagHelperOutput = new TagHelperOutput("p") + { + SelfClosing = true, + PostContent = "Hello World" + }; + + // Act + var output = tagHelperOutput.GeneratePostContent(); + + // Assert + Assert.Empty(output); + } + [Fact] public void GenerateEndTag_ReturnsEndTag() { @@ -209,6 +303,54 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers Assert.Empty(output); } + [Fact] + public void SuppressOutput_Sets_TagName_Content_PreContent_PostContent_ToNull() + { + // Arrange + var tagHelperOutput = new TagHelperOutput("p") + { + PreContent = "Pre Content", + Content = "Content", + PostContent = "Post Content" + }; + + // Act + tagHelperOutput.SuppressOutput(); + + // Assert + Assert.Null(tagHelperOutput.TagName); + Assert.Null(tagHelperOutput.PreContent); + Assert.Null(tagHelperOutput.Content); + Assert.Null(tagHelperOutput.PostContent); + } + + [Fact] + public void SuppressOutput_PreventsTagOutput() + { + // Arrange + var tagHelperOutput = new TagHelperOutput("p", + attributes: new Dictionary + { + { "class", "btn" }, + { "something", " spaced " } + }) + { + PreContent = "Pre Content", + Content = "Content", + PostContent = "Post Content" + }; + + // Act + tagHelperOutput.SuppressOutput(); + + // Assert + Assert.Empty(tagHelperOutput.GenerateStartTag()); + Assert.Null(tagHelperOutput.GeneratePreContent()); + Assert.Null(tagHelperOutput.GenerateContent()); + Assert.Null(tagHelperOutput.GeneratePostContent()); + Assert.Empty(tagHelperOutput.GenerateEndTag()); + } + [Theory] [InlineData("class", "ClASs")] [InlineData("CLaSs", "class")] diff --git a/test/Microsoft.AspNet.Razor.Runtime.Test/TagHelpers/TagHelperRunnerTest.cs b/test/Microsoft.AspNet.Razor.Runtime.Test/TagHelpers/TagHelperRunnerTest.cs index 7e09f88404..d8e7d829a9 100644 --- a/test/Microsoft.AspNet.Razor.Runtime.Test/TagHelpers/TagHelperRunnerTest.cs +++ b/test/Microsoft.AspNet.Razor.Runtime.Test/TagHelpers/TagHelperRunnerTest.cs @@ -66,23 +66,6 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers Assert.Equal("True", output.Attributes["foo"]); } - [Fact] - public async Task RunAsync_WithContentSetsOutputsContent() - { - // Arrange - var runner = new TagHelperRunner(); - var executionContext = new TagHelperExecutionContext("p"); - var tagHelper = new ExecutableTagHelper(); - var contentWriter = new StringWriter(new StringBuilder("Hello World")); - - // Act - executionContext.Add(tagHelper); - var output = await runner.RunAsync(executionContext, contentWriter); - - // Assert - Assert.Equal(output.Content, "Hello World"); - } - private class ExecutableTagHelper : TagHelper { public bool Processed { get; set; } diff --git a/test/Microsoft.AspNet.Razor.Runtime.Test/TagHelpers/TagHelperScopeManagerTest.cs b/test/Microsoft.AspNet.Razor.Runtime.Test/TagHelpers/TagHelperScopeManagerTest.cs index 64a6f38861..3fc94323c4 100644 --- a/test/Microsoft.AspNet.Razor.Runtime.Test/TagHelpers/TagHelperScopeManagerTest.cs +++ b/test/Microsoft.AspNet.Razor.Runtime.Test/TagHelpers/TagHelperScopeManagerTest.cs @@ -2,6 +2,8 @@ // 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.Threading.Tasks; using Microsoft.AspNet.Razor.Runtime.TagHelpers; using Xunit; @@ -9,6 +11,11 @@ namespace Microsoft.AspNet.Razor.Runtime.Test.TagHelpers { public class TagHelperScopeManagerTest { + private static readonly Action DefaultStartWritingScope = () => { }; + private static readonly Func DefaultEndWritingScope = () => new StringWriter(); + private static readonly Func DefaultExecuteChildContentAsync = + async () => await Task.FromResult(result: true); + [Fact] public void Begin_CreatesContextWithAppropriateTagName() { @@ -16,7 +23,11 @@ namespace Microsoft.AspNet.Razor.Runtime.Test.TagHelpers var scopeManager = new TagHelperScopeManager(); // Act - var executionContext = scopeManager.Begin("p", string.Empty); + var executionContext = scopeManager.Begin("p", + string.Empty, + DefaultExecuteChildContentAsync, + DefaultStartWritingScope, + DefaultEndWritingScope); // Assert Assert.Equal("p", executionContext.TagName); @@ -29,8 +40,16 @@ namespace Microsoft.AspNet.Razor.Runtime.Test.TagHelpers var scopeManager = new TagHelperScopeManager(); // Act - var executionContext = scopeManager.Begin("p", string.Empty); - executionContext = scopeManager.Begin("div", string.Empty); + var executionContext = scopeManager.Begin("p", + string.Empty, + DefaultExecuteChildContentAsync, + DefaultStartWritingScope, + DefaultEndWritingScope); + executionContext = scopeManager.Begin("div", + string.Empty, + DefaultExecuteChildContentAsync, + DefaultStartWritingScope, + DefaultEndWritingScope); // Assert Assert.Equal("div", executionContext.TagName); @@ -43,8 +62,16 @@ namespace Microsoft.AspNet.Razor.Runtime.Test.TagHelpers var scopeManager = new TagHelperScopeManager(); // Act - var executionContext = scopeManager.Begin("p", string.Empty); - executionContext = scopeManager.Begin("div", string.Empty); + var executionContext = scopeManager.Begin("p", + string.Empty, + DefaultExecuteChildContentAsync, + DefaultStartWritingScope, + DefaultEndWritingScope); + executionContext = scopeManager.Begin("div", + string.Empty, + DefaultExecuteChildContentAsync, + DefaultStartWritingScope, + DefaultEndWritingScope); executionContext = scopeManager.End(); // Assert @@ -58,8 +85,16 @@ namespace Microsoft.AspNet.Razor.Runtime.Test.TagHelpers var scopeManager = new TagHelperScopeManager(); // Act - var executionContext = scopeManager.Begin("p", string.Empty); - executionContext = scopeManager.Begin("div", string.Empty); + var executionContext = scopeManager.Begin("p", + string.Empty, + DefaultExecuteChildContentAsync, + DefaultStartWritingScope, + DefaultEndWritingScope); + executionContext = scopeManager.Begin("div", + string.Empty, + DefaultExecuteChildContentAsync, + DefaultStartWritingScope, + DefaultEndWritingScope); executionContext = scopeManager.End(); executionContext = scopeManager.End(); @@ -85,7 +120,6 @@ namespace Microsoft.AspNet.Razor.Runtime.Test.TagHelpers }); Assert.Equal(expectedError, ex.Message); - } } } \ No newline at end of file