зеркало из https://github.com/dotnet/razor.git
Added view component tag helper updates. (#823)
Added view component tag helper updates. aspnet/mvc#1051
This commit is contained in:
Родитель
8d7c51bd60
Коммит
489c0d9046
|
@ -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
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче