Adding support for RenderSection

* Adding unit tests for DefineSection \ RenderSection
* Changes per code review feedback
This commit is contained in:
Pranav K 2014-04-03 15:00:06 -07:00
parent df9d5c4875
commit 9291cbc50b
5 changed files with 133 additions and 19 deletions

View File

@ -123,7 +123,7 @@ namespace Microsoft.AspNet.Mvc.Razor
}
/// <summary>
/// Section '{0}' is not defined
/// Section '{0}' is not defined.
/// </summary>
internal static string SectionNotDefined
{
@ -131,7 +131,7 @@ namespace Microsoft.AspNet.Mvc.Razor
}
/// <summary>
/// Section '{0}' is not defined
/// Section '{0}' is not defined.
/// </summary>
internal static string FormatSectionNotDefined(object p0)
{

View File

@ -11,7 +11,7 @@ namespace Microsoft.AspNet.Mvc.Razor
{
public abstract class RazorView : IView
{
public IViewComponentHelper Component
public IViewComponentHelper Component
{
get { return Context == null ? null : Context.Component; }
}
@ -22,7 +22,7 @@ namespace Microsoft.AspNet.Mvc.Razor
protected TextWriter Output { get; set; }
public IUrlHelper Url
public IUrlHelper Url
{
get { return Context == null ? null : Context.Url; }
}
@ -95,15 +95,6 @@ namespace Microsoft.AspNet.Mvc.Razor
public abstract Task ExecuteAsync();
public void DefineSection(string name, HelperResult action)
{
if (SectionWriters.ContainsKey(name))
{
throw new InvalidOperationException(Resources.FormatSectionAlreadyDefined(name));
}
SectionWriters[name] = action;
}
public virtual void Write(object value)
{
WriteTo(Output, value);
@ -259,15 +250,25 @@ namespace Microsoft.AspNet.Mvc.Razor
return new HtmlString(BodyContent);
}
public HelperResult RenderSection(string name)
public void DefineSection(string name, HelperResult action)
{
return RenderSection(name, required: false);
if (SectionWriters.ContainsKey(name))
{
throw new InvalidOperationException(Resources.FormatSectionAlreadyDefined(name));
}
SectionWriters[name] = action;
}
public HelperResult RenderSection(string name, bool required)
public HelperResult RenderSection([NotNull] string name)
{
return RenderSection(name, required: true);
}
public HelperResult RenderSection([NotNull] string name, bool required)
{
HelperResult action;
if (PreviousSectionWriters.TryGetValue(name, out action))
if (PreviousSectionWriters != null &&
PreviousSectionWriters.TryGetValue(name, out action))
{
return action;
}
@ -283,4 +284,4 @@ namespace Microsoft.AspNet.Mvc.Razor
}
}
}
}
}

View File

@ -139,7 +139,7 @@
<value>Section '{0}' is already defined.</value>
</data>
<data name="SectionNotDefined" xml:space="preserve">
<value>Section '{0}' is not defined</value>
<value>Section '{0}' is not defined.</value>
</data>
<data name="ViewEngine_PartialViewNotFound" xml:space="preserve">
<value>The partial view '{0}' was not found. The following locations were searched:{1}</value>

View File

@ -0,0 +1,111 @@
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNet.Mvc.Rendering;
using Moq;
using Xunit;
namespace Microsoft.AspNet.Mvc.Razor.Test
{
public class RazorViewTest
{
private const string LayoutPath = "~/Shared/_Layout.cshtml";
[Fact]
public async Task DefineSection_ThrowsIfSectionIsAlreadyDefined()
{
// Arrange
Exception ex = null;
var view = CreateView(v =>
{
v.DefineSection("foo", new HelperResult(action: null));
ex = Assert.Throws<InvalidOperationException>(
() => v.DefineSection("foo", new HelperResult(action: null)));
});
var viewContext = CreateViewContext(layoutView: null);
// Act
await view.RenderAsync(viewContext);
// Assert
Assert.Equal("Section 'foo' is already defined.", ex.Message);
}
[Fact]
public async Task RenderSection_RendersSectionFromPreviousPage()
{
// Arrange
var expected = new HelperResult(action: null);
HelperResult actual = null;
var view = CreateView(v =>
{
v.DefineSection("bar", expected);
v.Layout = LayoutPath;
});
var layoutView = CreateView(v =>
{
actual = v.RenderSection("bar");
});
var viewContext = CreateViewContext(layoutView);
// Act
await view.RenderAsync(viewContext);
// Assert
Assert.Same(actual, expected);
}
[Fact]
public async Task RenderSection_ThrowsIfRequiredSectionIsNotFound()
{
// Arrange
var expected = new HelperResult(action: null);
Exception ex = null;
var view = CreateView(v =>
{
v.DefineSection("baz", expected);
v.Layout = LayoutPath;
});
var layoutView = CreateView(v =>
{
ex = Assert.Throws<InvalidOperationException>(
() => v.RenderSection("bar"));
});
var viewContext = CreateViewContext(layoutView);
// Act
await view.RenderAsync(viewContext);
// Assert
Assert.Equal("Section 'bar' is not defined.", ex.Message);
}
public static RazorView CreateView(Action<RazorView> executeAction)
{
var view = new Mock<RazorView> { CallBase = true };
if (executeAction != null)
{
view.Setup(v => v.ExecuteAsync())
.Callback(() => executeAction(view.Object))
.Returns(Task.FromResult(0));
}
return view.Object;
}
private static ViewContext CreateViewContext(IView layoutView)
{
var viewFactory = new Mock<IVirtualPathViewFactory>();
viewFactory.Setup(v => v.CreateInstance(LayoutPath))
.Returns(layoutView);
var serviceProvider = new Mock<IServiceProvider>();
serviceProvider.Setup(f => f.GetService(typeof(IVirtualPathViewFactory)))
.Returns(viewFactory.Object);
return new ViewContext(serviceProvider.Object, httpContext: null, viewEngineContext: null)
{
Writer = new StringWriter()
};
}
}
}

View File

@ -1,9 +1,11 @@
{
"version" : "0.1-alpha-*",
"dependencies": {
"Microsoft.AspNet.Abstractions": "0.1-alpha-*",
"Microsoft.AspNet.FileSystems": "0.1-alpha-*",
"Microsoft.AspNet.Razor": "0.1-alpha-*",
"Microsoft.AspNet.Mvc.Razor" : "",
"Microsoft.AspNet.Mvc.Rendering" : "",
"Microsoft.AspNet.Testing" : "0.1-alpha-*",
"Xunit.KRunner": "0.1-alpha-*",
"xunit.abstractions": "2.0.0-aspnet-*",