Added the EnvironmentTagHelper:

- #1553
This commit is contained in:
damianedwards 2015-01-14 18:12:21 -08:00
parent 54f88ab190
commit 759fbbd661
8 changed files with 369 additions and 1 deletions

View File

@ -44,6 +44,12 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Mvc.WebApi
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Mvc.TestConfiguration", "test\WebSites\Microsoft.AspNet.Mvc.TestConfiguration\Microsoft.AspNet.Mvc.TestConfiguration.kproj", "{680D75ED-601F-4D86-B01B-1072D0C31B8C}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Mvc.TagHelpers", "src\Microsoft.AspNet.Mvc.TagHelpers\Microsoft.AspNet.Mvc.TagHelpers.kproj", "{B2347320-308E-4D2B-AEC8-005DFA68B0C9}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "TagHelperSample.Web", "samples\TagHelperSample.Web\TagHelperSample.Web.kproj", "{2223120F-D675-40DA-8CD8-11DC14A0B2C7}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Mvc.TagHelpers.Test", "test\Microsoft.AspNet.Mvc.TagHelpers.Test\Microsoft.AspNet.Mvc.TagHelpers.Test.kproj", "{860119ED-3DB1-424D-8D0A-30132A8A7D96}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -206,6 +212,42 @@ Global
{680D75ED-601F-4D86-B01B-1072D0C31B8C}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{680D75ED-601F-4D86-B01B-1072D0C31B8C}.Release|x86.ActiveCfg = Release|Any CPU
{680D75ED-601F-4D86-B01B-1072D0C31B8C}.Release|x86.Build.0 = Release|Any CPU
{B2347320-308E-4D2B-AEC8-005DFA68B0C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B2347320-308E-4D2B-AEC8-005DFA68B0C9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B2347320-308E-4D2B-AEC8-005DFA68B0C9}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{B2347320-308E-4D2B-AEC8-005DFA68B0C9}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{B2347320-308E-4D2B-AEC8-005DFA68B0C9}.Debug|x86.ActiveCfg = Debug|Any CPU
{B2347320-308E-4D2B-AEC8-005DFA68B0C9}.Debug|x86.Build.0 = Debug|Any CPU
{B2347320-308E-4D2B-AEC8-005DFA68B0C9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B2347320-308E-4D2B-AEC8-005DFA68B0C9}.Release|Any CPU.Build.0 = Release|Any CPU
{B2347320-308E-4D2B-AEC8-005DFA68B0C9}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{B2347320-308E-4D2B-AEC8-005DFA68B0C9}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{B2347320-308E-4D2B-AEC8-005DFA68B0C9}.Release|x86.ActiveCfg = Release|Any CPU
{B2347320-308E-4D2B-AEC8-005DFA68B0C9}.Release|x86.Build.0 = Release|Any CPU
{2223120F-D675-40DA-8CD8-11DC14A0B2C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2223120F-D675-40DA-8CD8-11DC14A0B2C7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2223120F-D675-40DA-8CD8-11DC14A0B2C7}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{2223120F-D675-40DA-8CD8-11DC14A0B2C7}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{2223120F-D675-40DA-8CD8-11DC14A0B2C7}.Debug|x86.ActiveCfg = Debug|Any CPU
{2223120F-D675-40DA-8CD8-11DC14A0B2C7}.Debug|x86.Build.0 = Debug|Any CPU
{2223120F-D675-40DA-8CD8-11DC14A0B2C7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2223120F-D675-40DA-8CD8-11DC14A0B2C7}.Release|Any CPU.Build.0 = Release|Any CPU
{2223120F-D675-40DA-8CD8-11DC14A0B2C7}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{2223120F-D675-40DA-8CD8-11DC14A0B2C7}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{2223120F-D675-40DA-8CD8-11DC14A0B2C7}.Release|x86.ActiveCfg = Release|Any CPU
{2223120F-D675-40DA-8CD8-11DC14A0B2C7}.Release|x86.Build.0 = Release|Any CPU
{860119ED-3DB1-424D-8D0A-30132A8A7D96}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{860119ED-3DB1-424D-8D0A-30132A8A7D96}.Debug|Any CPU.Build.0 = Debug|Any CPU
{860119ED-3DB1-424D-8D0A-30132A8A7D96}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{860119ED-3DB1-424D-8D0A-30132A8A7D96}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{860119ED-3DB1-424D-8D0A-30132A8A7D96}.Debug|x86.ActiveCfg = Debug|Any CPU
{860119ED-3DB1-424D-8D0A-30132A8A7D96}.Debug|x86.Build.0 = Debug|Any CPU
{860119ED-3DB1-424D-8D0A-30132A8A7D96}.Release|Any CPU.ActiveCfg = Release|Any CPU
{860119ED-3DB1-424D-8D0A-30132A8A7D96}.Release|Any CPU.Build.0 = Release|Any CPU
{860119ED-3DB1-424D-8D0A-30132A8A7D96}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{860119ED-3DB1-424D-8D0A-30132A8A7D96}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{860119ED-3DB1-424D-8D0A-30132A8A7D96}.Release|x86.ActiveCfg = Release|Any CPU
{860119ED-3DB1-424D-8D0A-30132A8A7D96}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -226,5 +268,8 @@ Global
{23D30B8C-04B1-4577-A604-ED27EA1E4A0E} = {32285FA4-6B46-4D6B-A840-2B13E4C8B58E}
{5DE8E4D9-AACD-4B5F-819F-F091383FB996} = {3BA657BF-28B1-42DA-B5B0-1C4601FCF7B1}
{680D75ED-601F-4D86-B01B-1072D0C31B8C} = {3BA657BF-28B1-42DA-B5B0-1C4601FCF7B1}
{B2347320-308E-4D2B-AEC8-005DFA68B0C9} = {32285FA4-6B46-4D6B-A840-2B13E4C8B58E}
{2223120F-D675-40DA-8CD8-11DC14A0B2C7} = {DAAE4C74-D06F-4874-A166-33305D2643CE}
{860119ED-3DB1-424D-8D0A-30132A8A7D96} = {3BA657BF-28B1-42DA-B5B0-1C4601FCF7B1}
EndGlobalSection
EndGlobal

View File

@ -2,6 +2,10 @@
@using TagHelperSample.Web.Models
@model IList<User>
<environment names="development">
Hello, you're in Development
</environment>
<h2>Index</h2>
@if (Model != null && Model.Count() != 0)
{

View File

@ -0,0 +1,72 @@
// 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.Linq;
using Microsoft.AspNet.Hosting;
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
namespace Microsoft.AspNet.Mvc.TagHelpers
{
/// <summary>
/// <see cref="ITagHelper"/> implementation targeting &lt;environment&gt; elements that conditionally renders
/// content based on the current value of <see cref="IHostingEnvironment.EnvironmentName"/>.
/// </summary>
public class EnvironmentTagHelper : TagHelper
{
private static readonly char[] NameSeparator = new[] { ',' };
/// <summary>
/// A comma separated list of environment names in which the content should be rendered.
/// </summary>
/// <remarks>
/// The specified environment names are compared case insensitively to the current value of
/// <see cref="IHostingEnvironment.EnvironmentName"/>.
/// </remarks>
public string Names { get; set; }
// Protected to ensure subclasses are correctly activated. Internal for ease of use when testing.
[Activate]
protected internal IHostingEnvironment HostingEnvironment { get; set; }
/// <inheritdoc />
public override void Process(TagHelperContext context, TagHelperOutput output)
{
// Always strip the outer tag name as we never want <environment> to render
output.TagName = null;
if (string.IsNullOrWhiteSpace(Names))
{
// No names specified, do nothing
return;
}
var environments = Names.Split(NameSeparator, StringSplitOptions.RemoveEmptyEntries)
.Where(name => !string.IsNullOrWhiteSpace(name));
if (!environments.Any())
{
// Names contains only commas or empty entries, do nothing
return;
}
var currentEnvironmentName = HostingEnvironment.EnvironmentName?.Trim();
if (string.IsNullOrWhiteSpace(currentEnvironmentName))
{
// No current environment name, do nothing
return;
}
if (environments.Any(name =>
string.Equals(name.Trim(), currentEnvironmentName, StringComparison.OrdinalIgnoreCase)))
{
// Matching environment name found, do nothing
return;
}
// No matching environment name found, suppress all output
output.SuppressOutput();
}
}
}

View File

@ -0,0 +1,44 @@

<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>Environment</title>
</head>
<body>
<h2>Environment Tag Helper Test</h2>
<ul>
<li>This will show</li>
<li>This will show</li>
<li>This will show</li>
<li>This will show</li>
<li>This will show</li>
<li>This will show</li>
<li>This will show</li>
<li>This will show</li>
<li>This will show</li>
</ul>
</body>
</html>

View File

@ -33,7 +33,9 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
// Testing SelectTagHelper with Html.BeginForm
[InlineData("CreateWarehouse", null)]
// Testing the HTML helpers with FormTagHelper
[InlineData("EditWarehouse", null)]
[InlineData("EditWarehouse", null)]
// Testing the EnvironmentTagHelper
[InlineData("Environment", null)]
public async Task MvcTagHelpers_GeneratesExpectedResults(string action, string antiForgeryPath)
{
// Arrange

View File

@ -0,0 +1,147 @@
// 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 Microsoft.AspNet.Hosting;
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
using Moq;
using Xunit;
namespace Microsoft.AspNet.Mvc.TagHelpers.Test
{
public class EnvironmentTagHelperTest
{
[Theory]
[InlineData("Development", "Development")]
[InlineData("development", "Development")]
[InlineData("DEVELOPMENT", "Development")]
[InlineData(" development", "Development")]
[InlineData("development ", "Development")]
[InlineData(" development ", "Development")]
[InlineData("Development,Production", "Development")]
[InlineData("Production,Development", "Development")]
[InlineData("Development , Production", "Development")]
[InlineData(" Development,Production ", "Development")]
[InlineData("Development , Production", "Development")]
[InlineData("Development\t,Production", "Development")]
[InlineData("Development,\tProduction", "Development")]
[InlineData(" Development,Production ", "Development")]
[InlineData("Development,Staging,Production", "Development")]
[InlineData("Staging,Development,Production", "Development")]
[InlineData("Staging,Production,Development", "Development")]
[InlineData("Test", "Test")]
[InlineData("Test,Staging", "Test")]
public void ShowsContentWhenCurrentEnvironmentIsSpecified(string namesAttribute, string environmentName)
{
ShouldShowContent(namesAttribute, environmentName);
}
[Theory]
[InlineData("", "Development")]
[InlineData(null, "Development")]
[InlineData(" ", "Development")]
[InlineData(", ", "Development")]
[InlineData(" , ", "Development")]
[InlineData("\t,\t", "Development")]
[InlineData(",", "Development")]
[InlineData(",,", "Development")]
[InlineData(",,,", "Development")]
[InlineData(",,, ", "Development")]
public void ShowsContentWhenNoEnvironmentIsSpecified(string namesAttribute, string environmentName)
{
ShouldShowContent(namesAttribute, environmentName);
}
[Theory]
[InlineData("Development", null)]
[InlineData("Development", "")]
[InlineData("Development", " ")]
[InlineData("Development", " ")]
[InlineData("Development", "\t")]
[InlineData("Test", null)]
public void ShowsContentWhenCurrentEnvironmentIsNotSet(string namesAttribute, string environmentName)
{
ShouldShowContent(namesAttribute, environmentName);
}
[Theory]
[InlineData("NotDevelopment", "Development")]
[InlineData("NOTDEVELOPMENT", "Development")]
[InlineData("NotDevelopment,AlsoNotDevelopment", "Development")]
[InlineData("Doesn'tMatchAtAll", "Development")]
[InlineData("Development and a space", "Development")]
[InlineData("Development and a space,SomethingElse", "Development")]
public void DoesNotShowContentWhenCurrentEnvironmentIsNotSpecified(
string namesAttribute,
string environmentName)
{
// Arrange
var content = "content";
var context = MakeTagHelperContext(
attributes: new Dictionary<string, object> { { "names", namesAttribute } },
content: content);
var output = MakeTagHelperOutput("environment");
var hostingEnvironment = new Mock<IHostingEnvironment>();
hostingEnvironment.SetupProperty(h => h.EnvironmentName);
hostingEnvironment.Object.EnvironmentName = environmentName;
// Act
var helper = new EnvironmentTagHelper
{
HostingEnvironment = hostingEnvironment.Object,
Names = namesAttribute
};
helper.Process(context, output);
// Assert
Assert.Null(output.TagName);
Assert.Null(output.PreContent);
Assert.Null(output.Content);
Assert.Null(output.PostContent);
Assert.True(output.ContentSet);
}
private void ShouldShowContent(string namesAttribute, string environmentName)
{
// Arrange
var content = "content";
var context = MakeTagHelperContext(
attributes: new Dictionary<string, object> { { "names", namesAttribute } },
content: content);
var output = MakeTagHelperOutput("environment");
var hostingEnvironment = new Mock<IHostingEnvironment>();
hostingEnvironment.SetupProperty(h => h.EnvironmentName);
hostingEnvironment.Object.EnvironmentName = environmentName;
// Act
var helper = new EnvironmentTagHelper
{
HostingEnvironment = hostingEnvironment.Object,
Names = namesAttribute
};
helper.Process(context, output);
// Assert
Assert.Null(output.TagName);
Assert.False(output.ContentSet);
}
private TagHelperContext MakeTagHelperContext(
IDictionary<string, object> attributes = null,
string content = null)
{
attributes = attributes ?? new Dictionary<string, object>();
return new TagHelperContext(attributes, Guid.NewGuid().ToString("N"), () => Task.FromResult(content));
}
private TagHelperOutput MakeTagHelperOutput(string tagName, IDictionary<string, string> attributes = null)
{
attributes = attributes ?? new Dictionary<string, string>();
return new TagHelperOutput(tagName, attributes);
}
}
}

View File

@ -136,5 +136,10 @@ namespace MvcTagHelpersWebSite.Controllers
};
return View(warehouse);
}
public IActionResult Environment()
{
return View();
}
}
}

View File

@ -0,0 +1,49 @@
@addtaghelper "Microsoft.AspNet.Mvc.TagHelpers"
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>Environment</title>
</head>
<body>
<h2>Environment Tag Helper Test</h2>
<ul>
<environment names="Development">
<li>This will show</li>
</environment>
<environment names="development">
<li>This will show</li>
</environment>
<environment names="Development, Production">
<li>This will show</li>
</environment>
<environment names="Production, Development">
<li>This will show</li>
</environment>
<environment names="Local,Development, Production">
<li>This will show</li>
</environment>
<environment names="Development,">
<li>This will show</li>
</environment>
<environment>
<li>This will show</li>
</environment>
<environment names="">
<li>This will show</li>
</environment>
<environment names=" ">
<li>This will show</li>
</environment>
<environment names="Production">
<li>FAIL: This should NOT show</li>
</environment>
<environment names="Staging,Production">
<li>FAIL: This should NOT show</li>
</environment>
</ul>
</body>
</html>