Added view component tag helper updates. (#823)

Added view component tag helper updates.

aspnet/mvc#1051
This commit is contained in:
Crystal Qian 2016-08-24 16:01:59 -07:00 коммит произвёл GitHub
Родитель 8d7c51bd60
Коммит 489c0d9046
10 изменённых файлов: 308 добавлений и 8 удалений

Просмотреть файл

@ -703,6 +703,7 @@ namespace Microsoft.AspNetCore.Razor.Runtime.TagHelpers
/// Converts from pascal/camel case to lower kebab-case.
/// </summary>
/// <example>
/// <code>
/// SomeThing => some-thing
/// capsONInside => caps-on-inside
/// CAPSOnOUTSIDE => caps-on-outside
@ -710,8 +711,9 @@ namespace Microsoft.AspNetCore.Razor.Runtime.TagHelpers
/// One1Two2Three3 => one1-two2-three3
/// ONE1TWO2THREE3 => one1two2three3
/// First_Second_ThirdHi => first_second_third-hi
/// </code>
/// </example>
private static string ToHtmlCase(string name)
public static string ToHtmlCase(string name)
{
return HtmlCaseRegex.Replace(name, HtmlCaseRegexReplacement).ToLowerInvariant();
}

Просмотреть файл

@ -21,7 +21,7 @@ namespace Microsoft.AspNetCore.Razor.CodeGenerators
{
}
private ChunkTree Tree { get { return Context.ChunkTreeBuilder.Root; } }
protected ChunkTree Tree { get { return Context.ChunkTreeBuilder.Root; } }
public RazorEngineHost Host { get { return Context.Host; } }
/// <summary>
@ -82,12 +82,23 @@ namespace Microsoft.AspNetCore.Razor.CodeGenerators
csharpCodeVisitor.Accept(Tree.Children);
}
}
BuildAfterExecuteContent(writer, Tree.Children);
}
}
return new CodeGeneratorResult(writer.GenerateCode(), writer.LineMappingManager.Mappings);
}
/// <summary>
/// Provides an entry point to append code (after execute content) to a generated Razor class.
/// </summary>
/// <param name="writer">The <see cref="CSharpCodeWriter"/> to receive the additional content.</param>
/// <param name="chunks">The list of <see cref="Chunk"/>s for the generated program.</param>
protected virtual void BuildAfterExecuteContent(CSharpCodeWriter writer, IList<Chunk> chunks)
{
}
protected virtual CSharpCodeVisitor CreateCSharpCodeVisitor(
CSharpCodeWriter writer,
CodeGeneratorContext context)

Просмотреть файл

@ -319,6 +319,17 @@ namespace Microsoft.AspNetCore.Razor.CodeGenerators
.WriteEndMethodInvocation(endLine);
}
public CSharpCodeWriter WriteAutoPropertyDeclaration(string accessibility, string typeName, string name)
{
return Write(accessibility)
.Write(" ")
.Write(typeName)
.Write(" ")
.Write(name)
.Write(" { get; set; }")
.WriteLine();
}
public CSharpDisableWarningScope BuildDisableWarningScope(int warning)
{
return new CSharpDisableWarningScope(this, warning);

Просмотреть файл

@ -2172,6 +2172,35 @@ namespace Microsoft.AspNetCore.Razor.Runtime.TagHelpers
TagHelperAttributeDescriptorComparer.Default);
}
public static TheoryData HtmlConversionData
{
get
{
return new TheoryData<string, string>
{
{ "SomeThing", "some-thing" },
{ "someOtherThing", "some-other-thing" },
{ "capsONInside", "caps-on-inside" },
{ "CAPSOnOUTSIDE", "caps-on-outside" },
{ "ALLCAPS", "allcaps" },
{ "One1Two2Three3", "one1-two2-three3" },
{ "ONE1TWO2THREE3", "one1two2three3" },
{ "First_Second_ThirdHi", "first_second_third-hi" }
};
}
}
[Theory]
[MemberData(nameof(HtmlConversionData))]
public void ToHtmlCase_ReturnsExpectedConversions(string input, string expectedOutput)
{
// Arrange, Act
var output = TagHelperDescriptorFactory.ToHtmlCase(input);
// Assert
Assert.Equal(output, expectedOutput);
}
// TagHelperDesignTimeDescriptors are not created in CoreCLR.
#if !NETCOREAPP1_0
public static TheoryData OutputElementHintData

Просмотреть файл

@ -4,6 +4,10 @@
#if GENERATE_BASELINES
using System;
#endif
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Razor.Chunks;
using Microsoft.AspNetCore.Razor.Chunks.Generators;
using Microsoft.AspNetCore.Razor.Parser.SyntaxTree;
using Microsoft.AspNetCore.Razor.Test.CodeGenerators;
using Microsoft.AspNetCore.Razor.Test.Utils;
@ -14,9 +18,15 @@ namespace Microsoft.AspNetCore.Razor.CodeGenerators
{
public class CSharpCodeGeneratorTest
{
#if GENERATE_BASELINES
private static readonly string _baselinePathStart = "test/Microsoft.AspNetCore.Razor.Test";
#endif
private static readonly string _testOutputDirectory = "TestFiles/CodeGenerator/Output/CSharpCodeGenerator";
[Fact]
public void ChunkTreeWithUsings()
{
// Arrange
var syntaxTreeNode = new Mock<Span>(new SpanBuilder());
var language = new CSharpRazorCodeLanguage();
var host = new CodeGenTestHost(language);
@ -30,7 +40,9 @@ namespace Microsoft.AspNetCore.Razor.CodeGenerators
codeGeneratorContext.ChunkTreeBuilder.AddUsingChunk("FakeNamespace1", syntaxTreeNode.Object);
codeGeneratorContext.ChunkTreeBuilder.AddUsingChunk("FakeNamespace2.SubNamespace", syntaxTreeNode.Object);
var codeGenerator = new CodeGenTestCodeGenerator(codeGeneratorContext);
var testFile = TestFile.Create("TestFiles/CodeGenerator/Output/CSharpCodeGenerator.cs");
var path = $"{_testOutputDirectory}/ChunkTreeWithUsings.cs";
var testFile = TestFile.Create(path);
string expectedOutput;
#if GENERATE_BASELINES
@ -54,14 +66,151 @@ namespace Microsoft.AspNetCore.Razor.CodeGenerators
// Update baseline files if files do not already match.
if (!string.Equals(expectedOutput, result.Code, StringComparison.Ordinal))
{
BaselineWriter.WriteBaseline(
@"test\Microsoft.AspNetCore.Razor.Test\TestFiles\CodeGenerator\Output\CSharpCodeGenerator.cs",
result.Code);
var baselinePath = $"{_baselinePathStart}/{_testOutputDirectory}/ChunkTreeWithUsings.cs";
BaselineWriter.WriteBaseline( baselinePath, result.Code);
}
#else
Assert.Equal(expectedOutput, result.Code);
#endif
}
public static TheoryData ModifyOutputData
{
get
{
var addFileName = "AddGenerateChunkTest.cs";
var addGenerator = new AddGenerateTestCodeGenerator(CreateContext());
var addResult = CreateCodeGeneratorResult(addFileName);
var clearFileName = "ClearGenerateChunkTest.cs";
var clearGenerator = new ClearGenerateTestCodeGenerator(CreateContext());
var clearResult = CreateCodeGeneratorResult(clearFileName);
var defaultFileName = "DefaultGenerateChunkTest.cs";
var defaultGenerator = new CSharpCodeGenerator(CreateContext());
var defaultResult = CreateCodeGeneratorResult(defaultFileName);
var commentFileName = "BuildAfterExecuteContentTest.cs";
var commentGenerator = new BuildAfterExecuteContentTestCodeGenerator(CreateContext());
var commentResult = CreateCodeGeneratorResult(commentFileName);
return new TheoryData<CSharpCodeGenerator, CodeGeneratorResult, string>
{
{addGenerator, addResult, addFileName},
{clearGenerator, clearResult, clearFileName },
{defaultGenerator, defaultResult, defaultFileName },
{commentGenerator, commentResult, commentFileName }
};
}
}
[Theory]
[MemberData(nameof(ModifyOutputData))]
public void BuildAfterExecuteContent_ModifyChunks_ModifyOutput(
CSharpCodeGenerator generator,
CodeGeneratorResult expectedResult,
string fileName)
{
// Arrange, Act
var result = generator.Generate();
// Assert
#if GENERATE_BASELINES
// Update baseline files if files do not already match.
if (!string.Equals(expectedResult.Code, result.Code, StringComparison.Ordinal))
{
var baselinePath = $"{_baselinePathStart}/{_testOutputDirectory}/{fileName}";
BaselineWriter.WriteBaseline( baselinePath, result.Code);
}
#else
Assert.Equal(result.Code, expectedResult.Code);
#endif
}
private static CodeGeneratorResult CreateCodeGeneratorResult(string fileName)
{
var path = $"{_testOutputDirectory}/{fileName}";
var file = TestFile.Create(path);
string code;
#if GENERATE_BASELINES
if (file.Exists())
{
code = file.ReadAllText();
}
else
{
code = null;
}
#else
code = file.ReadAllText();
#endif
var result = new CodeGeneratorResult(code, new List<LineMapping>());
return result;
}
// Returns a context with two literal chunks.
private static CodeGeneratorContext CreateContext()
{
var language = new CSharpRazorCodeLanguage();
var host = new CodeGenTestHost(language);
var codeGeneratorContext = new CodeGeneratorContext(
new ChunkGeneratorContext(
host,
host.DefaultClassName,
host.DefaultNamespace,
"",
shouldGenerateLinePragmas: false),
new ErrorSink());
codeGeneratorContext.ChunkTreeBuilder = new ChunkTreeBuilder();
var syntaxTreeNode = new Mock<Span>(new SpanBuilder());
codeGeneratorContext.ChunkTreeBuilder.AddLiteralChunk("hello", syntaxTreeNode.Object);
codeGeneratorContext.ChunkTreeBuilder.AddStatementChunk("// asdf", syntaxTreeNode.Object);
codeGeneratorContext.ChunkTreeBuilder.AddLiteralChunk("world", syntaxTreeNode.Object);
return codeGeneratorContext;
}
private class BuildAfterExecuteContentTestCodeGenerator : CSharpCodeGenerator
{
public BuildAfterExecuteContentTestCodeGenerator(CodeGeneratorContext context) : base(context)
{
}
protected override void BuildAfterExecuteContent(CSharpCodeWriter writer, IList<Chunk> chunks)
{
writer.WriteLine("// test add content.");
}
}
private class AddGenerateTestCodeGenerator : CSharpCodeGenerator
{
public AddGenerateTestCodeGenerator(CodeGeneratorContext context) : base(context)
{
}
public override CodeGeneratorResult Generate()
{
var firstChunk = Tree.Children.First();
Tree.Children.Add(firstChunk);
return base.Generate();
}
}
private class ClearGenerateTestCodeGenerator : CSharpCodeGenerator
{
public ClearGenerateTestCodeGenerator(CodeGeneratorContext context) : base(context)
{
}
public override CodeGeneratorResult Generate()
{
Tree.Children.Clear();
return base.Generate();
}
}
}
}

Просмотреть файл

@ -0,0 +1,27 @@
namespace Razor
{
using System.Threading.Tasks;
public class __CompiledTemplate
{
#line hidden
public __CompiledTemplate()
{
}
#pragma warning disable 1998
public override async Task ExecuteAsync()
{
WriteLiteral("hello");
#line 1 ""
// asdf
#line default
#line hidden
WriteLiteral("world");
WriteLiteral("hello");
}
#pragma warning restore 1998
}
}

Просмотреть файл

@ -0,0 +1,27 @@
namespace Razor
{
using System.Threading.Tasks;
public class __CompiledTemplate
{
#line hidden
public __CompiledTemplate()
{
}
#pragma warning disable 1998
public override async Task ExecuteAsync()
{
WriteLiteral("hello");
#line 1 ""
// asdf
#line default
#line hidden
WriteLiteral("world");
}
#pragma warning restore 1998
// test add content.
}
}

Просмотреть файл

@ -0,0 +1,18 @@
namespace Razor
{
using System.Threading.Tasks;
public class __CompiledTemplate
{
#line hidden
public __CompiledTemplate()
{
}
#pragma warning disable 1998
public override async Task ExecuteAsync()
{
}
#pragma warning restore 1998
}
}

Просмотреть файл

@ -0,0 +1,26 @@
namespace Razor
{
using System.Threading.Tasks;
public class __CompiledTemplate
{
#line hidden
public __CompiledTemplate()
{
}
#pragma warning disable 1998
public override async Task ExecuteAsync()
{
WriteLiteral("hello");
#line 1 ""
// asdf
#line default
#line hidden
WriteLiteral("world");
}
#pragma warning restore 1998
}
}