public void MoveTo_ViewBuffer_TakesPage_IfCurrentPageDoesNotHaveCapacity() { // Arrange var scope = new TestViewBufferScope(); var original = new ViewBuffer(scope, "original", pageSize: 4); var other = new ViewBuffer(scope, "other", pageSize: 4); for (var i = 0; i < 3; i++) { original.AppendHtml($"original-{i}"); } // With two items, we'd try to copy the items, but there's no room in the current page. // So we just take over the page. for (var i = 0; i < 2; i++) { other.AppendHtml($"other-{i}"); } var page = other[0]; // Act other.MoveTo(original); // Assert Assert.Equal(0, other.Count); // Page was taken Assert.Equal(2, original.Count); Assert.Same(page, original[1]); }
public void MoveTo_ViewBuffer_TakesPage_IfCurrentPageInOriginalIsFull() { // Arrange var scope = new TestViewBufferScope(); var original = new ViewBuffer(scope, "original", pageSize: 4); var other = new ViewBuffer(scope, "other", pageSize: 4); for (var i = 0; i < 4; i++) { original.AppendHtml($"original-{i}"); } other.AppendHtml("Hi"); var page = other[0]; // Act other.MoveTo(original); // Assert Assert.Equal(0, other.Count); // Page was taken Assert.Equal(2, original.Count); Assert.Same(page, original[1]); }
public void MoveTo_ViewBuffer_MultiplePages() { // Arrange var scope = new TestViewBufferScope(); var original = new ViewBuffer(scope, "original", pageSize: 4); var other = new ViewBuffer(scope, "other", pageSize: 4); for (var i = 0; i < 2; i++) { original.AppendHtml($"original-{i}"); } for (var i = 0; i < 9; i++) { other.AppendHtml($"other-{i}"); } var pages = new List <ViewBufferPage>(); for (var i = 0; i < other.Count; i++) { pages.Add(other[i]); } // Act other.MoveTo(original); // Assert Assert.Equal(0, other.Count); // Other is cleared Assert.Equal(4, original.Count); Assert.Collection( original[0].Buffer, item => Assert.Equal("original-0", item.Value), item => Assert.Equal("original-1", item.Value), item => Assert.Null(item.Value), item => Assert.Null(item.Value)); Assert.Collection( original[1].Buffer, item => Assert.Equal("other-0", item.Value), item => Assert.Equal("other-1", item.Value), item => Assert.Equal("other-2", item.Value), item => Assert.Equal("other-3", item.Value)); Assert.Collection( original[2].Buffer, item => Assert.Equal("other-4", item.Value), item => Assert.Equal("other-5", item.Value), item => Assert.Equal("other-6", item.Value), item => Assert.Equal("other-7", item.Value)); Assert.Collection( original[3].Buffer, item => Assert.Equal("other-8", item.Value), item => Assert.Null(item.Value), item => Assert.Null(item.Value), item => Assert.Null(item.Value)); }
public async Task ProcessAsync_RendersMainPartial_If_FallbackIsSet_AndMainPartialIsFound() { // Arrange var expected = "Hello from partial!"; var bufferScope = new TestViewBufferScope(); var partialName = "_Partial"; var fallbackName = "_Fallback"; var model = new object(); var viewContext = GetViewContext(); var view = new Mock <IView>(); view.Setup(v => v.RenderAsync(It.IsAny <ViewContext>())) .Callback((ViewContext v) => { v.Writer.Write(expected); }) .Returns(Task.CompletedTask); var fallbackView = new Mock <IView>(); fallbackView.Setup(v => v.RenderAsync(It.IsAny <ViewContext>())) .Callback((ViewContext v) => { v.Writer.Write("Hello from fallback partial!"); }) .Returns(Task.CompletedTask); var viewEngine = new Mock <ICompositeViewEngine>(); viewEngine.Setup(v => v.GetView(It.IsAny <string>(), partialName, false)) .Returns(ViewEngineResult.Found(partialName, view.Object)); viewEngine.Setup(v => v.GetView(It.IsAny <string>(), fallbackName, false)) .Returns(ViewEngineResult.Found(fallbackName, fallbackView.Object)); var tagHelper = new PartialTagHelper(viewEngine.Object, bufferScope) { Name = partialName, ViewContext = viewContext, FallbackName = fallbackName }; var tagHelperContext = GetTagHelperContext(); var output = GetTagHelperOutput(); // Act await tagHelper.ProcessAsync(tagHelperContext, output); // Assert var content = HtmlContentUtilities.HtmlContentToString(output.Content, new HtmlTestEncoder()); Assert.Equal(expected, content); }
public async Task ProcessAsync_IfHasFallback_Throws_When_MainPartialAndFallback_AreNotFound() { // Arrange var bufferScope = new TestViewBufferScope(); var partialName = "_Partial"; var fallbackName = "_Fallback"; var expected = string.Join( Environment.NewLine, $"The partial view '{partialName}' was not found. The following locations were searched:", "PartialNotFound1", "PartialNotFound2", "PartialNotFound3", "PartialNotFound4", $"The fallback partial view '{fallbackName}' was not found. The following locations were searched:", "FallbackNotFound1", "FallbackNotFound2", "FallbackNotFound3", "FallbackNotFound4"); var viewData = new ViewDataDictionary(new TestModelMetadataProvider(), new ModelStateDictionary()); var viewContext = GetViewContext(); var view = Mock.Of <IView>(); var viewEngine = new Mock <ICompositeViewEngine>(); viewEngine.Setup(v => v.GetView(It.IsAny <string>(), partialName, false)) .Returns(ViewEngineResult.NotFound(partialName, new[] { "PartialNotFound1", "PartialNotFound2" })); viewEngine.Setup(v => v.FindView(viewContext, partialName, false)) .Returns(ViewEngineResult.NotFound(partialName, new[] { $"PartialNotFound3", $"PartialNotFound4" })); viewEngine.Setup(v => v.GetView(It.IsAny <string>(), fallbackName, false)) .Returns(ViewEngineResult.NotFound(partialName, new[] { "FallbackNotFound1", "FallbackNotFound2" })); viewEngine.Setup(v => v.FindView(viewContext, fallbackName, false)) .Returns(ViewEngineResult.NotFound(partialName, new[] { $"FallbackNotFound3", $"FallbackNotFound4" })); var tagHelper = new PartialTagHelper(viewEngine.Object, bufferScope) { Name = partialName, ViewContext = viewContext, ViewData = viewData, FallbackName = fallbackName }; var tagHelperContext = GetTagHelperContext(); var output = GetTagHelperOutput(); // Act & Assert var exception = await Assert.ThrowsAsync <InvalidOperationException>( () => tagHelper.ProcessAsync(tagHelperContext, output)); Assert.Equal(expected, exception.Message); }
public async Task ProcessAsync_UsesModelExpression_ToDetermineModel() { // Arrange var expected = new PropertyModel(); var bufferScope = new TestViewBufferScope(); var partialName = "_Partial"; var modelMetadataProvider = new TestModelMetadataProvider(); var containerModel = new TestModel { Property = expected }; var containerModelExplorer = modelMetadataProvider.GetModelExplorerForType( typeof(TestModel), containerModel); var propertyModelExplorer = containerModelExplorer.GetExplorerForProperty(nameof(TestModel.Property)); var modelExpression = new ModelExpression("Property", propertyModelExplorer); var viewContext = GetViewContext(); viewContext.ViewData.Model = new object(); var view = new Mock <IView>(); view.Setup(v => v.RenderAsync(It.IsAny <ViewContext>())) .Callback((ViewContext v) => { var actual = Assert.IsType <PropertyModel>(v.ViewData.Model); Assert.Same(expected, actual); }) .Returns(Task.CompletedTask) .Verifiable(); var viewEngine = new Mock <ICompositeViewEngine>(); viewEngine.Setup(v => v.GetView(It.IsAny <string>(), partialName, false)) .Returns(ViewEngineResult.Found(partialName, view.Object)); var tagHelper = new PartialTagHelper(viewEngine.Object, bufferScope) { Name = partialName, ViewContext = viewContext, For = modelExpression, }; var tagHelperContext = GetTagHelperContext(); var output = GetTagHelperOutput(); // Act await tagHelper.ProcessAsync(tagHelperContext, output); // Assert view.Verify(); }
public async Task ProcessAsync_SetsHtmlFieldPrefix_UsingModelExpression() { // Arrange var expected = "order.items[0].Property"; var bufferScope = new TestViewBufferScope(); var partialName = "_Partial"; var modelMetadataProvider = new TestModelMetadataProvider(); var containerModel = new TestModel { Property = new PropertyModel() }; var containerModelExplorer = modelMetadataProvider.GetModelExplorerForType( typeof(TestModel), containerModel); var propertyModelExplorer = containerModelExplorer.GetExplorerForProperty(nameof(TestModel.Property)); var modelExpression = new ModelExpression("Property", propertyModelExplorer); var viewContext = GetViewContext(); viewContext.ViewData.TemplateInfo.HtmlFieldPrefix = "order.items[0]"; var view = new Mock <IView>(); view.Setup(v => v.RenderAsync(It.IsAny <ViewContext>())) .Callback((ViewContext v) => { Assert.Equal(expected, v.ViewData.TemplateInfo.HtmlFieldPrefix); }) .Returns(Task.CompletedTask) .Verifiable(); var viewEngine = new Mock <ICompositeViewEngine>(); viewEngine.Setup(v => v.GetView(It.IsAny <string>(), partialName, false)) .Returns(ViewEngineResult.Found(partialName, view.Object)); var tagHelper = new PartialTagHelper(viewEngine.Object, bufferScope) { Name = partialName, ViewContext = viewContext, For = modelExpression, }; var tagHelperContext = GetTagHelperContext(); var output = GetTagHelperOutput(); // Act await tagHelper.ProcessAsync(tagHelperContext, output); // Assert view.Verify(); Assert.Equal("order.items[0]", viewContext.ViewData.TemplateInfo.HtmlFieldPrefix); }
public async Task ProcessAsync_UsesPassedInViewData_WhenNotNull() { // Arrange var expected = "Explicit"; var bufferScope = new TestViewBufferScope(); var partialName = "_Partial"; var model = new object(); var viewData = new ViewDataDictionary(new TestModelMetadataProvider(), new ModelStateDictionary()); viewData["key"] = expected; var viewContext = GetViewContext(); viewContext.ViewData["key"] = "ViewContext"; var view = new Mock <IView>(); view.Setup(v => v.RenderAsync(It.IsAny <ViewContext>())) .Callback((ViewContext v) => { v.Writer.Write(v.ViewData["key"]); }) .Returns(Task.CompletedTask); var viewEngine = new Mock <ICompositeViewEngine>(); viewEngine.Setup(v => v.GetView(It.IsAny <string>(), partialName, false)) .Returns(ViewEngineResult.Found(partialName, view.Object)); var tagHelper = new PartialTagHelper(viewEngine.Object, bufferScope) { Name = partialName, ViewContext = viewContext, ViewData = viewData, }; var tagHelperContext = GetTagHelperContext(); var output = GetTagHelperOutput(); // Act await tagHelper.ProcessAsync(tagHelperContext, output); // Assert var content = HtmlContentUtilities.HtmlContentToString(output.Content, new HtmlTestEncoder()); Assert.Equal(expected, content); }
public async Task ProcessAsync_UsesViewDataFromContext() { // Arrange var expected = "Implicit"; var bufferScope = new TestViewBufferScope(); var partialName = "_Partial"; var viewContext = GetViewContext(); viewContext.ViewData["key"] = expected; var view = new Mock <IView>(); view.Setup(v => v.RenderAsync(It.IsAny <ViewContext>())) .Callback((ViewContext v) => { v.Writer.Write(v.ViewData["key"]); }) .Returns(Task.CompletedTask); var viewEngine = new Mock <ICompositeViewEngine>(); viewEngine.Setup(v => v.GetView(It.IsAny <string>(), partialName, false)) .Returns(ViewEngineResult.NotFound(partialName, new[] { partialName })); viewEngine.Setup(v => v.FindView(viewContext, partialName, false)) .Returns(ViewEngineResult.Found(partialName, view.Object)); var tagHelper = new PartialTagHelper(viewEngine.Object, bufferScope) { Name = partialName, ViewContext = viewContext, }; var tagHelperContext = GetTagHelperContext(); var output = GetTagHelperOutput(); // Act await tagHelper.ProcessAsync(tagHelperContext, output); // Assert var content = HtmlContentUtilities.HtmlContentToString(output.Content, new HtmlTestEncoder()); Assert.Equal(expected, content); }
public void MoveTo_ViewBuffer_CanAddToTakenPage() { // Arrange var scope = new TestViewBufferScope(); var original = new ViewBuffer(scope, "original", pageSize: 4); var other = new ViewBuffer(scope, "other", pageSize: 4); for (var i = 0; i < 3; i++) { original.AppendHtml($"original-{i}"); } // More than half full, so we take the page for (var i = 0; i < 3; i++) { other.AppendHtml($"other-{i}"); } var page = other[0]; other.MoveTo(original); // Act original.AppendHtml("after-merge"); // Assert Assert.Equal(0, other.Count); // Other is cleared Assert.Equal(2, original.Count); Assert.Collection( original[0].Buffer, item => Assert.Equal("original-0", item.Value), item => Assert.Equal("original-1", item.Value), item => Assert.Equal("original-2", item.Value), item => Assert.Null(item.Value)); Assert.Collection( original[1].Buffer, item => Assert.Equal("other-0", item.Value), item => Assert.Equal("other-1", item.Value), item => Assert.Equal("other-2", item.Value), item => Assert.Equal("after-merge", item.Value)); }
public async Task ProcessAsync_IfOptional_And_ViewIsNotFound_WillNotRenderAnything() { // Arrange var expected = string.Empty; var bufferScope = new TestViewBufferScope(); var partialName = "_ThisViewDoesNotExists"; var model = new object(); var viewContext = GetViewContext(); var view = new Mock <IView>(); view.Setup(v => v.RenderAsync(It.IsAny <ViewContext>())) .Callback((ViewContext v) => { v.Writer.Write(expected); }) .Returns(Task.CompletedTask); var viewEngine = new Mock <ICompositeViewEngine>(); viewEngine.Setup(v => v.GetView(It.IsAny <string>(), partialName, false)) .Returns(ViewEngineResult.NotFound(partialName, searchedLocations: Array.Empty <string>())); viewEngine.Setup(v => v.FindView(viewContext, partialName, false)) .Returns(ViewEngineResult.NotFound(partialName, searchedLocations: Array.Empty <string>())); var tagHelper = new PartialTagHelper(viewEngine.Object, bufferScope) { Name = partialName, ViewContext = viewContext, Optional = true }; var tagHelperContext = GetTagHelperContext(); var output = GetTagHelperOutput(); // Act await tagHelper.ProcessAsync(tagHelperContext, output); // Assert var content = HtmlContentUtilities.HtmlContentToString(output.Content, new HtmlTestEncoder()); Assert.Empty(content); }
public void MoveTo_ViewBuffer_TakesPage_IfOriginalIsEmpty() { // Arrange var scope = new TestViewBufferScope(); var original = new ViewBuffer(scope, "original", pageSize: 4); var other = new ViewBuffer(scope, "other", pageSize: 4); other.AppendHtml("Hi"); var page = other[0]; // Act other.MoveTo(original); // Assert Assert.Equal(0, other.Count); // Page was taken Assert.Equal(1, original.Count); Assert.Same(page, original[0]); }
public async Task ProcessAsync_DoesNotModifyHtmlFieldPrefix_WhenModelExpressionIsNull() { // Arrange var expected = "original"; var bufferScope = new TestViewBufferScope(); var partialName = "_Partial"; var model = new object(); var viewContext = GetViewContext(); viewContext.ViewData.Model = model; viewContext.ViewData.TemplateInfo.HtmlFieldPrefix = expected; var view = new Mock <IView>(); view.Setup(v => v.RenderAsync(It.IsAny <ViewContext>())) .Callback((ViewContext v) => { Assert.Equal(expected, v.ViewData.TemplateInfo.HtmlFieldPrefix); }) .Returns(Task.CompletedTask) .Verifiable(); var viewEngine = new Mock <ICompositeViewEngine>(); viewEngine.Setup(v => v.GetView(It.IsAny <string>(), partialName, false)) .Returns(ViewEngineResult.Found(partialName, view.Object)); var tagHelper = new PartialTagHelper(viewEngine.Object, bufferScope) { Name = partialName, ViewContext = viewContext, }; var tagHelperContext = GetTagHelperContext(); var output = GetTagHelperOutput(); // Act await tagHelper.ProcessAsync(tagHelperContext, output); // Assert view.Verify(); }
public async Task ProcessAsync_DisposesViewInstance() { // Arrange var bufferScope = new TestViewBufferScope(); var partialName = "_Partial"; var viewContext = GetViewContext(); var disposable = new Mock <IDisposable>(); disposable.Setup(d => d.Dispose()).Verifiable(); var view = disposable.As <IView>(); view.Setup(v => v.RenderAsync(It.IsAny <ViewContext>())) .Returns(Task.CompletedTask) .Verifiable(); var viewEngine = new Mock <ICompositeViewEngine>(); viewEngine.Setup(v => v.GetView(It.IsAny <string>(), partialName, false)) .Returns(ViewEngineResult.Found(partialName, view.Object)); var tagHelper = new PartialTagHelper(viewEngine.Object, bufferScope) { Name = partialName, ViewContext = viewContext, }; var tagHelperContext = GetTagHelperContext(); var output = GetTagHelperOutput(); // Act await tagHelper.ProcessAsync(tagHelperContext, output); // Assert disposable.Verify(); view.Verify(); }
public void MoveTo_ViewBuffer_CopiesItems_IfCurrentPageHasRoom() { // Arrange var scope = new TestViewBufferScope(); var original = new ViewBuffer(scope, "original", pageSize: 4); var other = new ViewBuffer(scope, "other", pageSize: 4); for (var i = 0; i < 2; i++) { original.AppendHtml($"original-{i}"); } // With two items, this is half full so we try to copy the items. for (var i = 0; i < 2; i++) { other.AppendHtml($"other-{i}"); } var page = other[0]; // Act other.MoveTo(original); // Assert Assert.Equal(0, other.Count); // Other is cleared Assert.Contains(page.Buffer, scope.ReturnedBuffers); // Buffer was returned Assert.Equal(1, original.Count); Assert.Collection( original[0].Buffer, item => Assert.Equal("original-0", item.Value), item => Assert.Equal("original-1", item.Value), item => Assert.Equal("other-0", item.Value), item => Assert.Equal("other-1", item.Value)); }
public void MoveTo_ViewBuffer_CopiesItems_IfCurrentPageHasRoom() { // Arrange var scope = new TestViewBufferScope(); var original = new ViewBuffer(scope, "original", pageSize: 4); var other = new ViewBuffer(scope, "other", pageSize: 4); for (var i = 0; i < 2; i++) { original.AppendHtml($"original-{i}"); } // With two items, this is half full so we try to copy the items. for (var i = 0; i < 2; i++) { other.AppendHtml($"other-{i}"); } var page = other.Pages[0]; // Act other.MoveTo(original); // Assert Assert.Empty(other.Pages); // Other is cleared Assert.Contains(page.Buffer, scope.ReturnedBuffers); // Buffer was returned Assert.Collection( Assert.Single(original.Pages).Buffer, item => Assert.Equal("original-0", item.Value), item => Assert.Equal("original-1", item.Value), item => Assert.Equal("other-0", item.Value), item => Assert.Equal("other-1", item.Value)); }
public void MoveTo_ViewBuffer_TakesPage_IfOriginalIsEmpty() { // Arrange var scope = new TestViewBufferScope(); var original = new ViewBuffer(scope, "original", pageSize: 4); var other = new ViewBuffer(scope, "other", pageSize: 4); other.AppendHtml("Hi"); var page = other.Pages[0]; // Act other.MoveTo(original); // Assert Assert.Empty(other.Pages); // Page was taken Assert.Same(page, Assert.Single(original.Pages)); }
public void MoveTo_ViewBuffer_TakesPage_IfCurrentPageInOriginalIsFull() { // Arrange var scope = new TestViewBufferScope(); var original = new ViewBuffer(scope, "original", pageSize: 4); var other = new ViewBuffer(scope, "other", pageSize: 4); for (var i = 0; i < 4; i++) { original.AppendHtml($"original-{i}"); } other.AppendHtml("Hi"); var page = other.Pages[0]; // Act other.MoveTo(original); // Assert Assert.Empty(other.Pages); // Page was taken Assert.Equal(2, original.Pages.Count); Assert.Same(page, original.Pages[1]); }
public void MoveTo_ViewBuffer_TakesPage_IfCurrentPageDoesNotHaveCapacity() { // Arrange var scope = new TestViewBufferScope(); var original = new ViewBuffer(scope, "original", pageSize: 4); var other = new ViewBuffer(scope, "other", pageSize: 4); for (var i = 0; i < 3; i++) { original.AppendHtml($"original-{i}"); } // With two items, we'd try to copy the items, but there's no room in the current page. // So we just take over the page. for (var i = 0; i < 2; i++) { other.AppendHtml($"other-{i}"); } var page = other.Pages[0]; // Act other.MoveTo(original); // Assert Assert.Empty(other.Pages); // Page was taken Assert.Equal(2, original.Pages.Count); Assert.Same(page, original.Pages[1]); }
public void MoveTo_ViewBuffer_MultiplePages() { // Arrange var scope = new TestViewBufferScope(); var original = new ViewBuffer(scope, "original", pageSize: 4); var other = new ViewBuffer(scope, "other", pageSize: 4); for (var i = 0; i < 2; i++) { original.AppendHtml($"original-{i}"); } for (var i = 0; i < 9; i++) { other.AppendHtml($"other-{i}"); } var pages = new List<ViewBufferPage>(other.Pages); // Act other.MoveTo(original); // Assert Assert.Empty(other.Pages); // Other is cleared Assert.Equal(4, original.Pages.Count); Assert.Collection( original.Pages[0].Buffer, item => Assert.Equal("original-0", item.Value), item => Assert.Equal("original-1", item.Value), item => Assert.Null(item.Value), item => Assert.Null(item.Value)); Assert.Collection( original.Pages[1].Buffer, item => Assert.Equal("other-0", item.Value), item => Assert.Equal("other-1", item.Value), item => Assert.Equal("other-2", item.Value), item => Assert.Equal("other-3", item.Value)); Assert.Collection( original.Pages[2].Buffer, item => Assert.Equal("other-4", item.Value), item => Assert.Equal("other-5", item.Value), item => Assert.Equal("other-6", item.Value), item => Assert.Equal("other-7", item.Value)); Assert.Collection( original.Pages[3].Buffer, item => Assert.Equal("other-8", item.Value), item => Assert.Null(item.Value), item => Assert.Null(item.Value), item => Assert.Null(item.Value)); }
public void MoveTo_ViewBuffer_CanAddToTakenPage() { // Arrange var scope = new TestViewBufferScope(); var original = new ViewBuffer(scope, "original", pageSize: 4); var other = new ViewBuffer(scope, "other", pageSize: 4); for (var i = 0; i < 3; i++) { original.AppendHtml($"original-{i}"); } // More than half full, so we take the page for (var i = 0; i < 3; i++) { other.AppendHtml($"other-{i}"); } var page = other.Pages[0]; other.MoveTo(original); // Act original.AppendHtml("after-merge"); // Assert Assert.Empty(other.Pages); // Other is cleared Assert.Equal(2, original.Pages.Count); Assert.Collection( original.Pages[0].Buffer, item => Assert.Equal("original-0", item.Value), item => Assert.Equal("original-1", item.Value), item => Assert.Equal("original-2", item.Value), item => Assert.Null(item.Value)); Assert.Collection( original.Pages[1].Buffer, item => Assert.Equal("other-0", item.Value), item => Assert.Equal("other-1", item.Value), item => Assert.Equal("other-2", item.Value), item => Assert.Equal("after-merge", item.Value)); }
public async Task TagHelperScopes_ViewBuffersCanCombine() { // Arrange var bufferScope = new TestViewBufferScope(); var viewContext = CreateViewContext(bufferScope: bufferScope); var page = CreatePage(async v => { Assert.Equal(0, bufferScope.CreatedBuffers.Count); v.Write("Level:0"); // Creates a 'top-level' buffer. Assert.Equal(1, bufferScope.CreatedBuffers.Count); // Run a TagHelper { v.StartTagHelperWritingScope(encoder: null); Assert.Equal(1, bufferScope.CreatedBuffers.Count); Assert.Equal(0, bufferScope.ReturnedBuffers.Count); v.Write("Level:1-A"); // Creates a new buffer for the taghelper. Assert.Equal(2, bufferScope.CreatedBuffers.Count); Assert.Equal(0, bufferScope.ReturnedBuffers.Count); TagHelperContent innerContentLevel1 = null; var outputLevel1 = new TagHelperOutput("t1", new TagHelperAttributeList(), (_, encoder) => { return Task.FromResult(innerContentLevel1); }); innerContentLevel1 = v.EndTagHelperWritingScope(); outputLevel1.Content = await outputLevel1.GetChildContentAsync(); Assert.Equal(2, bufferScope.CreatedBuffers.Count); Assert.Equal(0, bufferScope.ReturnedBuffers.Count); v.Write(outputLevel1); // Writing the taghelper to output returns a buffer. Assert.Equal(2, bufferScope.CreatedBuffers.Count); Assert.Equal(1, bufferScope.ReturnedBuffers.Count); } Assert.Equal(2, bufferScope.CreatedBuffers.Count); Assert.Equal(1, bufferScope.ReturnedBuffers.Count); v.Write("Level:0"); // Already have a buffer for this scope. Assert.Equal(2, bufferScope.CreatedBuffers.Count); Assert.Equal(1, bufferScope.ReturnedBuffers.Count); // Run another TagHelper { v.StartTagHelperWritingScope(encoder: null); Assert.Equal(2, bufferScope.CreatedBuffers.Count); Assert.Equal(1, bufferScope.ReturnedBuffers.Count); v.Write("Level:1-B"); // Creates a new buffer for the taghelper. Assert.Equal(3, bufferScope.CreatedBuffers.Count); Assert.Equal(1, bufferScope.ReturnedBuffers.Count); TagHelperContent innerContentLevel1 = null; var outputLevel1 = new TagHelperOutput("t2", new TagHelperAttributeList(), (_, encoder) => { return Task.FromResult(innerContentLevel1); }); // Run a nested TagHelper { v.StartTagHelperWritingScope(encoder: null); Assert.Equal(3, bufferScope.CreatedBuffers.Count); Assert.Equal(1, bufferScope.ReturnedBuffers.Count); v.Write("Level:2"); // Creates a new buffer for the taghelper. Assert.Equal(4, bufferScope.CreatedBuffers.Count); Assert.Equal(1, bufferScope.ReturnedBuffers.Count); TagHelperContent innerContentLevel2 = null; var outputLevel2 = new TagHelperOutput("t3", new TagHelperAttributeList(), (_, encoder) => { return Task.FromResult(innerContentLevel2); }); innerContentLevel2 = v.EndTagHelperWritingScope(); outputLevel2.Content = await outputLevel2.GetChildContentAsync(); Assert.Equal(4, bufferScope.CreatedBuffers.Count); Assert.Equal(1, bufferScope.ReturnedBuffers.Count); v.Write(outputLevel2); // Writing the taghelper to output returns a buffer. Assert.Equal(4, bufferScope.CreatedBuffers.Count); Assert.Equal(2, bufferScope.ReturnedBuffers.Count); } Assert.Equal(4, bufferScope.CreatedBuffers.Count); Assert.Equal(2, bufferScope.ReturnedBuffers.Count); v.Write("Level:1-B"); // Already have a buffer for this scope. Assert.Equal(4, bufferScope.CreatedBuffers.Count); Assert.Equal(2, bufferScope.ReturnedBuffers.Count); innerContentLevel1 = v.EndTagHelperWritingScope(); outputLevel1.Content = await outputLevel1.GetChildContentAsync(); Assert.Equal(4, bufferScope.CreatedBuffers.Count); Assert.Equal(2, bufferScope.ReturnedBuffers.Count); v.Write(outputLevel1); // Writing the taghelper to output returns a buffer. Assert.Equal(4, bufferScope.CreatedBuffers.Count); Assert.Equal(3, bufferScope.ReturnedBuffers.Count); } Assert.Equal(4, bufferScope.CreatedBuffers.Count); Assert.Equal(3, bufferScope.ReturnedBuffers.Count); v.Write("Level:0"); // Already have a buffer for this scope. Assert.Equal(4, bufferScope.CreatedBuffers.Count); Assert.Equal(3, bufferScope.ReturnedBuffers.Count); }, viewContext); // Act & Assert await page.ExecuteAsync(); Assert.Equal( "HtmlEncode[[Level:0]]" + "<t1>" + "HtmlEncode[[Level:1-A]]" + "</t1>" + "HtmlEncode[[Level:0]]" + "<t2>" + "HtmlEncode[[Level:1-B]]" + "<t3>" + "HtmlEncode[[Level:2]]" + "</t3>" + "HtmlEncode[[Level:1-B]]" + "</t2>" + "HtmlEncode[[Level:0]]", page.RenderedContent); }