diff --git a/test/Microsoft.AspNet.Razor.Runtime.Test/TagHelpers/TagHelperContextTest.cs b/test/Microsoft.AspNet.Razor.Runtime.Test/TagHelpers/TagHelperContextTest.cs new file mode 100644 index 0000000000..7ea62f12c5 --- /dev/null +++ b/test/Microsoft.AspNet.Razor.Runtime.Test/TagHelpers/TagHelperContextTest.cs @@ -0,0 +1,37 @@ +// 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.Threading.Tasks; +using Xunit; + +namespace Microsoft.AspNet.Razor.Runtime.TagHelpers +{ + public class TagHelperContextTest + { + [Fact] + public void Constructor_SetsProperties_AsExpected() + { + // Arrange + var expectedItems = new Dictionary + { + { "test-entry", 1234 } + }; + + // Act + var context = new TagHelperContext( + allAttributes: new Dictionary(), + items: expectedItems, + uniqueId: string.Empty, + getChildContentAsync: () => Task.FromResult(string.Empty)); + + // Assert + Assert.NotNull(context.Items); + Assert.Same(expectedItems, context.Items); + var item = Assert.Single(context.Items); + Assert.Equal("test-entry", (string)item.Key, StringComparer.Ordinal); + Assert.Equal(1234, item.Value); + } + } +} \ No newline at end of file diff --git a/test/Microsoft.AspNet.Razor.Runtime.Test/TagHelpers/TagHelperExecutionContextTest.cs b/test/Microsoft.AspNet.Razor.Runtime.Test/TagHelpers/TagHelperExecutionContextTest.cs index 8a39681239..b3bfd308f4 100644 --- a/test/Microsoft.AspNet.Razor.Runtime.Test/TagHelpers/TagHelperExecutionContextTest.cs +++ b/test/Microsoft.AspNet.Razor.Runtime.Test/TagHelpers/TagHelperExecutionContextTest.cs @@ -25,6 +25,30 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers Assert.Equal(selfClosing, executionContext.SelfClosing); } + [Fact] + public void ParentItems_SetsItemsProperty() + { + // Arrange + var expectedItems = new Dictionary + { + { "test-entry", 1234 } + }; + + // Act + var executionContext = new TagHelperExecutionContext( + "p", + selfClosing: false, + items: expectedItems, + uniqueId: string.Empty, + executeChildContentAsync: async () => await Task.FromResult(result: true), + startWritingScope: () => { }, + endWritingScope: () => new StringWriter()); + + // Assert + Assert.NotNull(executionContext.Items); + Assert.Same(expectedItems, executionContext.Items); + } + [Fact] public async Task GetChildContentAsync_CachesValue() { @@ -34,6 +58,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers var executionContext = new TagHelperExecutionContext( "p", selfClosing: false, + items: null, uniqueId: string.Empty, executeChildContentAsync: () => { @@ -67,6 +92,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers var executionContext = new TagHelperExecutionContext( "p", selfClosing: false, + items: null, uniqueId: string.Empty, executeChildContentAsync: () => { diff --git a/test/Microsoft.AspNet.Razor.Runtime.Test/TagHelpers/TagHelperRunnerTest.cs b/test/Microsoft.AspNet.Razor.Runtime.Test/TagHelpers/TagHelperRunnerTest.cs index d85f0e08f5..499452d490 100644 --- a/test/Microsoft.AspNet.Razor.Runtime.Test/TagHelpers/TagHelperRunnerTest.cs +++ b/test/Microsoft.AspNet.Razor.Runtime.Test/TagHelpers/TagHelperRunnerTest.cs @@ -157,6 +157,23 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers Assert.Equal("True", output.Attributes["foo"]); } + [Fact] + public async Task RunAsync_ConfiguresTagHelperContextWithExecutionContextsItems() + { + // Arrange + var runner = new TagHelperRunner(); + var executionContext = new TagHelperExecutionContext("p", selfClosing: false); + var tagHelper = new ContextInspectingTagHelper(); + executionContext.Add(tagHelper); + + // Act + await runner.RunAsync(executionContext); + + // Assert + Assert.NotNull(tagHelper.ContextProcessedWith); + Assert.Same(tagHelper.ContextProcessedWith.Items, executionContext.Items); + } + private class ExecutableTagHelper : TagHelper { public bool Processed { get; set; } @@ -172,6 +189,16 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers } } + private class ContextInspectingTagHelper : TagHelper + { + public TagHelperContext ContextProcessedWith { get; set; } + + public override void Process(TagHelperContext context, TagHelperOutput output) + { + ContextProcessedWith = context; + } + } + private class TagHelperContextTouchingTagHelper : TagHelper { public override void Process(TagHelperContext context, TagHelperOutput output) diff --git a/test/Microsoft.AspNet.Razor.Runtime.Test/TagHelpers/TagHelperScopeManagerTest.cs b/test/Microsoft.AspNet.Razor.Runtime.Test/TagHelpers/TagHelperScopeManagerTest.cs index a318659d84..ecec105379 100644 --- a/test/Microsoft.AspNet.Razor.Runtime.Test/TagHelpers/TagHelperScopeManagerTest.cs +++ b/test/Microsoft.AspNet.Razor.Runtime.Test/TagHelpers/TagHelperScopeManagerTest.cs @@ -2,6 +2,7 @@ // 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.Threading.Tasks; using Microsoft.AspNet.Razor.Runtime.TagHelpers; @@ -11,10 +12,118 @@ 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_DoesNotRequireParentExecutionContext() + { + // Arrange & Act + var scopeManager = new TagHelperScopeManager(); + + // Act + var executionContext = BeginDefaultScope(scopeManager, tagName: "p"); + executionContext.Items["test-entry"] = 1234; + + // Assert + var executionContextItem = Assert.Single(executionContext.Items); + Assert.Equal("test-entry", (string)executionContextItem.Key, StringComparer.Ordinal); + Assert.Equal(1234, executionContextItem.Value); + } + + [Fact] + public void Begin_ReturnedExecutionContext_ItemsAreRetrievedFromParentExecutionContext() + { + // Arrange + var scopeManager = new TagHelperScopeManager(); + var parentExecutionContext = BeginDefaultScope(scopeManager, tagName: "p"); + parentExecutionContext.Items["test-entry"] = 1234; + + // Act + var executionContext = BeginDefaultScope(scopeManager, tagName: "p"); + + // Assert + var executionContextItem = Assert.Single(executionContext.Items); + Assert.Equal("test-entry", (string)executionContextItem.Key, StringComparer.Ordinal); + Assert.Equal(1234, executionContextItem.Value); + } + + [Fact] + public void Begin_DoesShallowCopyOfParentItems() + { + // Arrange + var scopeManager = new TagHelperScopeManager(); + var parentComplexObject = new Dictionary(StringComparer.Ordinal); + var parentExecutionContext = BeginDefaultScope(scopeManager, tagName: "p"); + parentExecutionContext.Items["test-entry"] = parentComplexObject; + var executionContext = BeginDefaultScope(scopeManager, tagName: "p"); + + // Act + ((Dictionary)executionContext.Items["test-entry"]).Add("from-child", 1234); + + // Assert + var executionContextItem = Assert.Single(executionContext.Items); + Assert.Equal("test-entry", (string)executionContextItem.Key, StringComparer.Ordinal); + Assert.Same(parentComplexObject, executionContextItem.Value); + var parentEntry = Assert.Single(parentComplexObject); + Assert.Equal("from-child", parentEntry.Key, StringComparer.Ordinal); + Assert.Equal(1234, parentEntry.Value); + } + + [Fact] + public void Begin_ReturnedExecutionContext_ItemsModificationDoesNotAffectParent() + { + // Arrange + var scopeManager = new TagHelperScopeManager(); + var parentExecutionContext = BeginDefaultScope(scopeManager, tagName: "p"); + parentExecutionContext.Items["test-entry"] = 1234; + var executionContext = BeginDefaultScope(scopeManager, tagName: "p"); + + // Act + executionContext.Items["test-entry"] = 2222; + + // Assert + var executionContextItem = Assert.Single(executionContext.Items); + Assert.Equal("test-entry", (string)executionContextItem.Key, StringComparer.Ordinal); + Assert.Equal(2222, executionContextItem.Value); + var parentExecutionContextItem = Assert.Single(parentExecutionContext.Items); + Assert.Equal("test-entry", (string)parentExecutionContextItem.Key, StringComparer.Ordinal); + Assert.Equal(1234, parentExecutionContextItem.Value); + } + + [Fact] + public void Begin_ReturnedExecutionContext_ItemsInsertionDoesNotAffectParent() + { + // Arrange + var scopeManager = new TagHelperScopeManager(); + var parentExecutionContext = BeginDefaultScope(scopeManager, tagName: "p"); + var executionContext = BeginDefaultScope(scopeManager, tagName: "p"); + + // Act + executionContext.Items["new-entry"] = 2222; + + // Assert + var executionContextItem = Assert.Single(executionContext.Items); + Assert.Equal("new-entry", (string)executionContextItem.Key, StringComparer.Ordinal); + Assert.Equal(2222, executionContextItem.Value); + Assert.Empty(parentExecutionContext.Items); + } + + [Fact] + public void Begin_ReturnedExecutionContext_ItemsRemovalDoesNotAffectParent() + { + // Arrange + var scopeManager = new TagHelperScopeManager(); + var parentExecutionContext = BeginDefaultScope(scopeManager, tagName: "p"); + parentExecutionContext.Items["test-entry"] = 1234; + var executionContext = BeginDefaultScope(scopeManager, tagName: "p"); + + // Act + executionContext.Items.Remove("test-entry"); + + // Assert + Assert.Empty(executionContext.Items); + var parentExecutionContextItem = Assert.Single(parentExecutionContext.Items); + Assert.Equal("test-entry", (string)parentExecutionContextItem.Key, StringComparer.Ordinal); + Assert.Equal(1234, parentExecutionContextItem.Value); + } [Fact] public void Begin_CreatesContextWithAppropriateTagName() @@ -23,13 +132,7 @@ namespace Microsoft.AspNet.Razor.Runtime.Test.TagHelpers var scopeManager = new TagHelperScopeManager(); // Act - var executionContext = scopeManager.Begin( - "p", - selfClosing: false, - uniqueId: string.Empty, - executeChildContentAsync: DefaultExecuteChildContentAsync, - startWritingScope: DefaultStartWritingScope, - endWritingScope: DefaultEndWritingScope); + var executionContext = BeginDefaultScope(scopeManager, tagName: "p"); // Assert Assert.Equal("p", executionContext.TagName); @@ -42,21 +145,8 @@ namespace Microsoft.AspNet.Razor.Runtime.Test.TagHelpers var scopeManager = new TagHelperScopeManager(); // Act - var executionContext = scopeManager.Begin( - "p", - selfClosing: false, - uniqueId: string.Empty, - executeChildContentAsync: DefaultExecuteChildContentAsync, - startWritingScope: DefaultStartWritingScope, - endWritingScope: DefaultEndWritingScope); - - executionContext = scopeManager.Begin( - "div", - selfClosing: false, - uniqueId: string.Empty, - executeChildContentAsync: DefaultExecuteChildContentAsync, - startWritingScope: DefaultStartWritingScope, - endWritingScope: DefaultEndWritingScope); + var executionContext = BeginDefaultScope(scopeManager, tagName: "p"); + executionContext = BeginDefaultScope(scopeManager, tagName: "div"); // Assert Assert.Equal("div", executionContext.TagName); @@ -71,13 +161,7 @@ namespace Microsoft.AspNet.Razor.Runtime.Test.TagHelpers var scopeManager = new TagHelperScopeManager(); // Act - var executionContext = scopeManager.Begin( - "p", - selfClosing: selfClosing, - uniqueId: string.Empty, - executeChildContentAsync: DefaultExecuteChildContentAsync, - startWritingScope: DefaultStartWritingScope, - endWritingScope: DefaultEndWritingScope); + var executionContext = BeginDefaultScope(scopeManager, "p", selfClosing); // Assert Assert.Equal(selfClosing, executionContext.SelfClosing); @@ -90,22 +174,8 @@ namespace Microsoft.AspNet.Razor.Runtime.Test.TagHelpers var scopeManager = new TagHelperScopeManager(); // Act - var executionContext = scopeManager.Begin( - "p", - selfClosing: false, - uniqueId: string.Empty, - executeChildContentAsync: DefaultExecuteChildContentAsync, - startWritingScope: DefaultStartWritingScope, - endWritingScope: DefaultEndWritingScope); - - executionContext = scopeManager.Begin( - "div", - selfClosing: false, - uniqueId: string.Empty, - executeChildContentAsync: DefaultExecuteChildContentAsync, - startWritingScope: DefaultStartWritingScope, - endWritingScope: DefaultEndWritingScope); - + var executionContext = BeginDefaultScope(scopeManager, tagName: "p"); + executionContext = BeginDefaultScope(scopeManager, tagName: "div"); executionContext = scopeManager.End(); // Assert @@ -119,22 +189,8 @@ namespace Microsoft.AspNet.Razor.Runtime.Test.TagHelpers var scopeManager = new TagHelperScopeManager(); // Act - var executionContext = scopeManager.Begin( - "p", - selfClosing: false, - uniqueId: string.Empty, - executeChildContentAsync: DefaultExecuteChildContentAsync, - startWritingScope: DefaultStartWritingScope, - endWritingScope: DefaultEndWritingScope); - - executionContext = scopeManager.Begin( - "div", - selfClosing: false, - uniqueId: string.Empty, - executeChildContentAsync: DefaultExecuteChildContentAsync, - startWritingScope: DefaultStartWritingScope, - endWritingScope: DefaultEndWritingScope); - + var executionContext = BeginDefaultScope(scopeManager, tagName: "p"); + executionContext = BeginDefaultScope(scopeManager, tagName: "div"); executionContext = scopeManager.End(); executionContext = scopeManager.End(); @@ -161,5 +217,19 @@ namespace Microsoft.AspNet.Razor.Runtime.Test.TagHelpers Assert.Equal(expectedError, ex.Message); } + + private static TagHelperExecutionContext BeginDefaultScope( + TagHelperScopeManager scopeManager, + string tagName, + bool selfClosing = false) + { + return scopeManager.Begin( + tagName, + selfClosing, + uniqueId: string.Empty, + executeChildContentAsync: async () => await Task.FromResult(result: true), + startWritingScope: () => { }, + endWritingScope: () => new StringWriter()); + } } } \ No newline at end of file