Generate pure HTML document as part of Razor code generation (dotnet/aspnetcore-tooling#1624)

* Generate pure HTML document as part of Razor code generation

* feedback
\n\nCommit migrated from 478e2ceda8
This commit is contained in:
Ajay Bhargav B 2020-02-25 13:40:08 -08:00 committed by GitHub
parent 5565519125
commit b84fc9b3b6
84 changed files with 1426 additions and 8 deletions

View File

@ -540,6 +540,7 @@ public class AllTagHelper : {typeof(TagHelper).FullName}
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertHtmlDocumentMatchesBaseline(compiled.CodeDocument.GetHtmlDocument());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertLinePragmas(compiled.CodeDocument, designTime: true);
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
@ -559,6 +560,7 @@ public class AllTagHelper : {typeof(TagHelper).FullName}
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertHtmlDocumentMatchesBaseline(compiled.CodeDocument.GetHtmlDocument());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertLinePragmas(compiled.CodeDocument, designTime: true);
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
@ -584,6 +586,7 @@ public class MyService<TModel>
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertHtmlDocumentMatchesBaseline(compiled.CodeDocument.GetHtmlDocument());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertLinePragmas(compiled.CodeDocument, designTime: true);
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
@ -620,6 +623,7 @@ public class MyModel
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertHtmlDocumentMatchesBaseline(compiled.CodeDocument.GetHtmlDocument());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertLinePragmas(compiled.CodeDocument, designTime: true);
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
@ -655,6 +659,7 @@ public class MyModel
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertHtmlDocumentMatchesBaseline(compiled.CodeDocument.GetHtmlDocument());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertLinePragmas(compiled.CodeDocument, designTime: true);
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
@ -674,6 +679,7 @@ public class MyModel
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertHtmlDocumentMatchesBaseline(compiled.CodeDocument.GetHtmlDocument());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertLinePragmas(compiled.CodeDocument, designTime: true);
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
@ -693,6 +699,7 @@ public class MyModel
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertHtmlDocumentMatchesBaseline(compiled.CodeDocument.GetHtmlDocument());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertLinePragmas(compiled.CodeDocument, designTime: true);
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
@ -712,6 +719,7 @@ public class MyModel
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertHtmlDocumentMatchesBaseline(compiled.CodeDocument.GetHtmlDocument());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertLinePragmas(compiled.CodeDocument, designTime: true);
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
@ -728,6 +736,7 @@ public class MyModel
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertHtmlDocumentMatchesBaseline(compiled.CodeDocument.GetHtmlDocument());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertLinePragmas(compiled.CodeDocument, designTime: true);
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
@ -753,6 +762,7 @@ public class InputTestTagHelper : {typeof(TagHelper).FullName}
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertHtmlDocumentMatchesBaseline(compiled.CodeDocument.GetHtmlDocument());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertLinePragmas(compiled.CodeDocument, designTime: true);
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
@ -769,6 +779,7 @@ public class InputTestTagHelper : {typeof(TagHelper).FullName}
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertHtmlDocumentMatchesBaseline(compiled.CodeDocument.GetHtmlDocument());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertLinePragmas(compiled.CodeDocument, designTime: true);
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
@ -792,6 +803,7 @@ public class MyApp
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertHtmlDocumentMatchesBaseline(compiled.CodeDocument.GetHtmlDocument());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertLinePragmas(compiled.CodeDocument, designTime: true);
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
@ -824,6 +836,7 @@ public class MyApp
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertHtmlDocumentMatchesBaseline(compiled.CodeDocument.GetHtmlDocument());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertLinePragmas(compiled.CodeDocument, designTime: true);
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
@ -857,6 +870,7 @@ public class MyService<TModel>
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertHtmlDocumentMatchesBaseline(compiled.CodeDocument.GetHtmlDocument());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertLinePragmas(compiled.CodeDocument, designTime: true);
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
@ -873,6 +887,7 @@ public class MyService<TModel>
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertHtmlDocumentMatchesBaseline(compiled.CodeDocument.GetHtmlDocument());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertLinePragmas(compiled.CodeDocument, designTime: true);
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
@ -895,6 +910,7 @@ public class ThisShouldBeGenerated
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertHtmlDocumentMatchesBaseline(compiled.CodeDocument.GetHtmlDocument());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertLinePragmas(compiled.CodeDocument, designTime: true);
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
@ -923,6 +939,7 @@ public class InputTestTagHelper : {typeof(TagHelper).FullName}
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertHtmlDocumentMatchesBaseline(compiled.CodeDocument.GetHtmlDocument());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertLinePragmas(compiled.CodeDocument, designTime: true);
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
@ -946,6 +963,7 @@ public class DivTagHelper : {typeof(TagHelper).FullName}
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertHtmlDocumentMatchesBaseline(compiled.CodeDocument.GetHtmlDocument());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertLinePragmas(compiled.CodeDocument, designTime: true);
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
@ -962,6 +980,7 @@ public class DivTagHelper : {typeof(TagHelper).FullName}
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertHtmlDocumentMatchesBaseline(compiled.CodeDocument.GetHtmlDocument());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertLinePragmas(compiled.CodeDocument, designTime: true);
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
@ -985,6 +1004,7 @@ public class DivTagHelper : {typeof(TagHelper).FullName}
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertHtmlDocumentMatchesBaseline(compiled.CodeDocument.GetHtmlDocument());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertLinePragmas(compiled.CodeDocument, designTime: true);
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
@ -1001,6 +1021,7 @@ public class DivTagHelper : {typeof(TagHelper).FullName}
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertHtmlDocumentMatchesBaseline(compiled.CodeDocument.GetHtmlDocument());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertLinePragmas(compiled.CodeDocument, designTime: true);
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
@ -1017,6 +1038,7 @@ public class DivTagHelper : {typeof(TagHelper).FullName}
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertHtmlDocumentMatchesBaseline(compiled.CodeDocument.GetHtmlDocument());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertLinePragmas(compiled.CodeDocument, designTime: true);
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
@ -1049,6 +1071,7 @@ public class AllTagHelper : {typeof(TagHelper).FullName}
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertHtmlDocumentMatchesBaseline(compiled.CodeDocument.GetHtmlDocument());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertLinePragmas(compiled.CodeDocument, designTime: true);
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
@ -1065,6 +1088,7 @@ public class AllTagHelper : {typeof(TagHelper).FullName}
// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentIntermediateNode());
AssertHtmlDocumentMatchesBaseline(compiled.CodeDocument.GetHtmlDocument());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertLinePragmas(compiled.CodeDocument, designTime: true);
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);

View File

@ -0,0 +1,36 @@
<h1>New Customer</h1>
<form method="post" class="form-horizontal">
<div class="text-danger"></div>
<div class="form-group">
<label class="col-md-2 control-label"> </label>
<div class="col-md-10">
<input class="form-control" />
<span class="text-danger"></span>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<button type="submit" class="btn btn-primary">Save</button>
</div>
</div>
</form>

View File

@ -0,0 +1,40 @@
<h1>New Customer</h1>
<form method="post" class="form-horizontal" >
<div class="text-danger"></div>
<div class="form-group">
<label class="col-md-2 control-label"> </label>
<div class="col-md-10">
<input class="form-control" />
<span class="text-danger"></span>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<button type="submit" class="btn btn-primary">Save</button>
</div>
</div>
</form>

View File

@ -0,0 +1,14 @@
<div>Some body</div>
<div>This is in Section 1</div>
<input-test for=" " />

View File

@ -2,7 +2,6 @@
// 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 Microsoft.AspNetCore.Razor.Language.CodeGeneration;
using Microsoft.AspNetCore.Razor.Language.Intermediate;

View File

@ -0,0 +1,35 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
namespace Microsoft.AspNetCore.Razor.Language
{
internal class DefaultRazorHtmlDocument : RazorHtmlDocument
{
private readonly string _generatedHtml;
private readonly RazorCodeGenerationOptions _options;
public DefaultRazorHtmlDocument(
string generatedHtml,
RazorCodeGenerationOptions options)
{
if (generatedHtml == null)
{
throw new ArgumentNullException(nameof(generatedHtml));
}
if (options == null)
{
throw new ArgumentNullException(nameof(options));
}
_generatedHtml = generatedHtml;
_options = options;
}
public override string GeneratedHtml => _generatedHtml;
public override RazorCodeGenerationOptions Options => _options;
}
}

View File

@ -102,8 +102,6 @@ namespace Microsoft.AspNetCore.Razor.Language
return string.Equals(descriptor.Name, typePattern, StringComparison.Ordinal);
}
internal abstract class DirectiveVisitor : SyntaxWalker
{
public abstract HashSet<TagHelperDescriptor> Matches { get; }

View File

@ -3,9 +3,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using Microsoft.AspNetCore.Razor.Language.Extensions;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
@ -118,6 +115,25 @@ namespace Microsoft.AspNetCore.Razor.Language
document.Items[typeof(DocumentIntermediateNode)] = documentNode;
}
internal static RazorHtmlDocument GetHtmlDocument(this RazorCodeDocument document)
{
if (document == null)
{
throw new ArgumentNullException(nameof(document));
}
var razorHtmlObj = document.Items[typeof(RazorHtmlDocument)];
if (razorHtmlObj == null)
{
var razorHtmlDocument = RazorHtmlWriter.GetHtmlDocument(document);
document.Items[typeof(RazorHtmlDocument)] = razorHtmlDocument;
return razorHtmlDocument;
}
return (RazorHtmlDocument)razorHtmlObj;
}
public static RazorCSharpDocument GetCSharpDocument(this RazorCodeDocument document)
{
if (document == null)

View File

@ -14,7 +14,7 @@ namespace Microsoft.AspNetCore.Razor.Language
{
#pragma warning disable CS0618 // Type or member is obsolete
private static RazorEngine CreateCore(RazorConfiguration configuration, bool designTime, Action<IRazorEngineBuilder> configure)
#pragma warning disable CS0618 // Type or member is obsolete
#pragma warning restore CS0618 // Type or member is obsolete
{
if (configuration == null)
{

View File

@ -0,0 +1,29 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
namespace Microsoft.AspNetCore.Razor.Language
{
internal abstract class RazorHtmlDocument
{
public abstract string GeneratedHtml { get; }
public abstract RazorCodeGenerationOptions Options { get; }
public static RazorHtmlDocument Create(string generatedHtml, RazorCodeGenerationOptions options)
{
if (generatedHtml == null)
{
throw new ArgumentNullException(nameof(generatedHtml));
}
if (options == null)
{
throw new ArgumentNullException(nameof(options));
}
return new DefaultRazorHtmlDocument(generatedHtml, options);
}
}
}

View File

@ -0,0 +1,166 @@
// Copyright (c) .NET Foundation. 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.Diagnostics;
using System.Text;
using Microsoft.AspNetCore.Razor.Language.Syntax;
namespace Microsoft.AspNetCore.Razor.Language
{
// We want to generate a HTML document that contains only pure HTML.
// So we want replace all non-HTML content with whitespace.
// Ideally we should just use ClassifiedSpans to generate this document but
// not all characters in the document are included in the ClassifiedSpans.
internal class RazorHtmlWriter : SyntaxWalker
{
private bool _isHtml;
private RazorHtmlWriter(RazorSourceDocument source)
{
if (source is null)
{
throw new ArgumentNullException(nameof(source));
}
Source = source;
Builder = new StringBuilder(Source.Length);
_isHtml = true;
}
public RazorSourceDocument Source { get; }
public StringBuilder Builder { get; }
public static RazorHtmlDocument GetHtmlDocument(RazorCodeDocument codeDocument)
{
var options = codeDocument.GetCodeGenerationOptions();
if (options == null || !options.DesignTime)
{
// Not needed in run time. This pass generates the backing HTML document that is used to provide HTML intellisense.
return null;
}
var writer = new RazorHtmlWriter(codeDocument.Source);
var syntaxTree = codeDocument.GetSyntaxTree();
writer.Visit(syntaxTree.Root);
var generatedHtml = writer.Builder.ToString();
Debug.Assert(
writer.Source.Length == writer.Builder.Length,
$"The backing HTML document should be the same length as the original document. Expected: {writer.Source.Length} Actual: {writer.Builder.Length}");
var razorHtmlDocument = new DefaultRazorHtmlDocument(generatedHtml, options);
return razorHtmlDocument;
}
public override void VisitRazorCommentBlock(RazorCommentBlockSyntax node)
{
WriteNode(node, isHtml: false, base.VisitRazorCommentBlock);
}
public override void VisitRazorMetaCode(RazorMetaCodeSyntax node)
{
WriteNode(node, isHtml: false, base.VisitRazorMetaCode);
}
public override void VisitMarkupTransition(MarkupTransitionSyntax node)
{
WriteNode(node, isHtml: false, base.VisitMarkupTransition);
}
public override void VisitCSharpTransition(CSharpTransitionSyntax node)
{
WriteNode(node, isHtml: false, base.VisitCSharpTransition);
}
public override void VisitCSharpEphemeralTextLiteral(CSharpEphemeralTextLiteralSyntax node)
{
WriteNode(node, isHtml: false, base.VisitCSharpEphemeralTextLiteral);
}
public override void VisitCSharpExpressionLiteral(CSharpExpressionLiteralSyntax node)
{
WriteNode(node, isHtml: false, base.VisitCSharpExpressionLiteral);
}
public override void VisitCSharpStatementLiteral(CSharpStatementLiteralSyntax node)
{
WriteNode(node, isHtml: false, base.VisitCSharpStatementLiteral);
}
public override void VisitMarkupStartTag(MarkupStartTagSyntax node)
{
WriteNode(node, isHtml: true, base.VisitMarkupStartTag);
}
public override void VisitMarkupEndTag(MarkupEndTagSyntax node)
{
WriteNode(node, isHtml: true, base.VisitMarkupEndTag);
}
public override void VisitMarkupTagHelperStartTag(MarkupTagHelperStartTagSyntax node)
{
WriteNode(node, isHtml: true, base.VisitMarkupTagHelperStartTag);
}
public override void VisitMarkupTagHelperEndTag(MarkupTagHelperEndTagSyntax node)
{
WriteNode(node, isHtml: true, base.VisitMarkupTagHelperEndTag);
}
public override void VisitMarkupEphemeralTextLiteral(MarkupEphemeralTextLiteralSyntax node)
{
WriteNode(node, isHtml: true, base.VisitMarkupEphemeralTextLiteral);
}
public override void VisitMarkupTextLiteral(MarkupTextLiteralSyntax node)
{
WriteNode(node, isHtml: true, base.VisitMarkupTextLiteral);
}
public override void VisitUnclassifiedTextLiteral(UnclassifiedTextLiteralSyntax node)
{
WriteNode(node, isHtml: true, base.VisitUnclassifiedTextLiteral);
}
public override void VisitToken(SyntaxToken token)
{
base.VisitToken(token);
WriteToken(token);
}
private void WriteToken(SyntaxToken token)
{
var content = token.Content;
if (_isHtml)
{
// If we're in HTML context, append the content directly.
Builder.Append(content);
return;
}
// We're in non-HTML context. Let's replace all non-whitespace chars with a space.
foreach (var c in content)
{
if (char.IsWhiteSpace(c))
{
Builder.Append(c);
}
else
{
Builder.Append(' ');
}
}
}
private void WriteNode<TNode>(TNode node, bool isHtml, Action<TNode> handler) where TNode : SyntaxNode
{
var old = _isHtml;
_isHtml = isHtml;
handler(node);
_isHtml = old;
}
}
}

View File

@ -1001,6 +1001,7 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
// Assert
AssertDocumentNodeMatchesBaseline(codeDocument.GetDocumentIntermediateNode());
AssertHtmlDocumentMatchesBaseline(codeDocument.GetHtmlDocument());
AssertCSharpDocumentMatchesBaseline(codeDocument.GetCSharpDocument());
AssertSourceMappingsMatchBaseline(codeDocument);
AssertLinePragmas(codeDocument, designTime: true);

View File

@ -81,7 +81,7 @@ namespace Microsoft.AspNetCore.Razor.Language
feature => Assert.IsType<HtmlNodeOptimizationPass>(feature),
feature => Assert.IsType<ImplementsDirectivePass>(feature),
feature => Assert.IsType<InheritsDirectivePass>(feature),
feature => Assert.IsType<MetadataAttributePass>(feature),
feature => Assert.IsType<MetadataAttributePass>(feature),
feature => Assert.IsType<PreallocatedTagHelperAttributeOptimizationPass>(feature));
}

View File

@ -0,0 +1,26 @@
<section>
<h1>Basic Asynchronous Expression Test</h1>
<p>Basic Asynchronous Expression: </p>
<p>Basic Asynchronous Template: </p>
<p>Basic Asynchronous Statement: </p>
<p>Basic Asynchronous Statement Nested: <b> </b> </p>
<p>Basic Incomplete Asynchronous Statement: </p>
</section>
<section>
<h1>Advanced Asynchronous Expression Test</h1>
<p>Advanced Asynchronous Expression: </p>
<p>Advanced Asynchronous Expression Extended: </p>
<p>Advanced Asynchronous Template: </p>
<p>Advanced Asynchronous Statement: </p>
<p>Advanced Asynchronous Statement Extended: </p>
<p>Advanced Asynchronous Statement Nested: <b> </b> </p>
<p>Advanced Incomplete Asynchronous Statement: </p>
</section>

View File

@ -0,0 +1,37 @@
<p>Hello from C#, # </p>
<p>We wrote 10 lines!</p>
<p>No really, we wrote 10 lines!</p>
<p>Actually, we didn't...</p>
<p>Hello again from C#, # </p>
<p>That time, we wrote 5 lines!</p>
<p>Oh no! An error occurred: </p>
<p>i is now </p>
<p>This block is locked, for your security!</p>

View File

@ -0,0 +1,43 @@
<body>
<p>
Here's a very unique number:
</p>
<div>
</div>
</body>

View File

@ -0,0 +1,15 @@
<a href="Foo" />
<p class=" " />
<p class="foo " />
<p class=" foo" />
<input type="checkbox" checked=" " />
<input type="checkbox" checked="foo " />
<p class=" " />
<a href="~/Foo" />
<script src=" " type="text/javascript"></script>
<script src=" " type="text/javascript"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jquery.ui/1.8.16/jquery-ui.min.js" type="text/javascript"></script>

View File

@ -0,0 +1,15 @@
<div>
<p>This is item # </p>
</div>
<p>
<p>Bar Biz</p>
</p>
<p>Foo</p>

View File

@ -0,0 +1,38 @@
<p>Bar</p>
Hello, World
<p>Hello, World</p>
<p>Hello from C#, # </p>
<p>We wrote 10 lines!</p>
<p>No really, we wrote 10 lines!</p>
<p>Actually, we didn't...</p>
<p>Hello again from C#, # </p>
<p>That time, we wrote 5 lines!</p>
<p>Oh no! An error occurred: </p>
<p>This block is locked, for your security!</p>

View File

@ -0,0 +1,45 @@
<div> </div>
<div>
<h3>Happy birthday !</h3>
</div>
<ul>
<li> Happy birthday!</li>
</ul>
<h4>Secret message</h4>

View File

@ -0,0 +1,38 @@
<p>Hello from C#, # </p>
<p>We wrote 10 lines!</p>
<p>No really, we wrote 10 lines!</p>
<p>Actually, we didn't...</p>
<p>Hello again from C#, # </p>
<p>That time, we wrote 5 lines!</p>
<p>Oh no! An error occurred: </p>
<p>i is now </p>
<p>This block is locked, for your security!</p>

View File

@ -0,0 +1,18 @@
<p>This should be shown</p>
<p>But this should show the comment syntax: </p>
<input value="@*this razor comment is the actual value*@" type="text" />
<input type="text" />

View File

@ -0,0 +1,17 @@
<div>This is in the Body>
<div class="some ">This is in Section 2</div>
<div>This is in Section 1</div>
<span> </span>

View File

@ -0,0 +1,102 @@
<p>Before Text</p>
<p>Hello!</p>
<p>The time is </p>
<p>After Text</p>

View File

@ -0,0 +1,237 @@
<p>This is line 1</p>
<p>This is line 2</p>
<p>This is line 3</p>
<p>This is line 4</p>
<p>This is line 5</p>
<p>This is line 6</p>
<p>This is line 7</p>
<p>This is line 8</p>
<p>This is line 9</p>
<p>This is line 10</p>
<p>This is line 11</p>
<p>This is line 12</p>
<p>This is line 13</p>
<p>This is line 14</p>
<p>This is line 15</p>
<p>This is line 16</p>
<p>This is line 17</p>
<p>This is line 18</p>
<p>This is line 19</p>
<p>This is line 20</p>
<p>This is line 21</p>
<p>This is line 22</p>
<p>This is line 23</p>
<p>This is line 24</p>
<p>This is line 25</p>
<p>This is line 26</p>
<p>This is line 27</p>
<p>This is line 28</p>
<p>This is line 29</p>
<p>This is line 30</p>
<p>This is line 31</p>
<p>This is line 32</p>
<p>This is line 33</p>
<p>This is line 34</p>
<p>This is line 35</p>
<p>This is line 36</p>
<p>This is line 37</p>
<p>This is line 38</p>
<p>This is line 39</p>
<p>This is line 40</p>
<p>This is line 41</p>
<p>This is line 42</p>
<p>This is line 43</p>
<p>This is line 44</p>
<p>This is line 45</p>
<p>This is line 46</p>
<p>This is line 47</p>
<p>This is line 48</p>
<p>This is line 49</p>
<p>This is line 50</p>
<p>This is line 51</p>
<p>This is line 52</p>
<p>This is line 53</p>
<p>This is line 54</p>
<p>This is line 55</p>
<p>This is line 56</p>
<p>This is line 57</p>
<p>This is line 58</p>
<p>This is line 59</p>
<p>This is line 60</p>
<p>This is line 61</p>
<p>This is line 62</p>
<p>This is line 63</p>
<p>This is line 64</p>
<p>This is line 65</p>
<p>This is line 66</p>
<p>This is line 67</p>
<p>This is line 68</p>
<p>This is line 69</p>
<p>This is line 70</p>
<p>This is line 71</p>
<p>This is line 72</p>
<p>This is line 73</p>
<p>This is line 74</p>
<p>This is line 75</p>
<p>This is line 76</p>
<p>This is line 77</p>
<p>This is line 78</p>
<p>This is line 79</p>
<p>This is line 80</p>
<p>This is line 81</p>
<p>This is line 82</p>
<p>This is line 83</p>
<p>This is line 84</p><br>
<p>This is line 1 nested</p>
<p>This is line 2 nested</p>
<p>This is line 3 nested</p>
<p>This is line 4 nested</p>
<p>This is line 5 nested</p>
<p>This is line 6 nested</p>
<p>This is line 7 nested</p>
<p>This is line 8 nested</p>
<p>This is line 9 nested</p>
<p>This is line 10 nested</p>
<p>This is line 11 nested</p>
<p>This is line 12 nested</p>
<p>This is line 13 nested</p>
<p>This is line 14 nested</p>
<p>This is line 15 nested</p>
<p>This is line 16 nested</p>
<p>This is line 17 nested</p>
<p>This is line 18 nested</p>
<p>This is line 19 nested</p>
<p>This is line 20 nested</p>
<p>This is line 21 nested</p>
<p>This is line 22 nested</p>
<p>This is line 23 nested</p>
<p>This is line 24 nested</p>
<p>This is line 25 nested</p>
<p>This is line 26 nested</p>
<p>This is line 27 nested</p>
<p>This is line 28 nested</p>
<p>This is line 29 nested</p>
<p>This is line 30 nested</p>
<p>This is line 31 nested</p>
<p>This is line 32 nested</p>
<p>This is line 33 nested</p>
<p>This is line 34 nested</p>
<p>This is line 35 nested</p>
<p>This is line 36 nested</p>
<p>This is line 37 nested</p>
<p>This is line 38 nested</p>
<p>This is line 39 nested</p>
<p>This is line 40 nested</p>
<p>This is line 41 nested</p>
<p>This is line 42 nested</p>
<p>This is line 43 nested</p>
<p>This is line 44 nested</p>
<p>This is line 45 nested</p>
<p>This is line 46 nested</p>
<p>This is line 47 nested</p>
<p>This is line 48 nested</p>
<p>This is line 49 nested</p>
<p>This is line 50 nested</p>
<p>This is line 51 nested</p>
<p>This is line 52 nested</p>
<p>This is line 53 nested</p>
<p>This is line 54 nested</p>
<p>This is line 55 nested</p>
<p>This is line 56 nested</p>
<p>This is line 57 nested</p>
<p>This is line 58 nested</p>
<p>This is line 59 nested</p>
<p>This is line 60 nested</p>
<p>This is line 61 nested</p>
<p>This is line 62 nested</p>
<p>This is line 63 nested</p>
<p>This is line 64 nested</p>
<p>This is line 65 nested</p>
<p>This is line 66 nested</p>
<p>This is line 67 nested</p>
<p>This is line 68 nested</p>
<p>This is line 69 nested</p>
<p>This is line 70 nested</p>
<p>This is line 71 nested</p>
<p>This is line 72 nested</p>
<p>This is line 73 nested</p>
<p>This is line 74 nested</p>
<p>This is line 75 nested</p>
<p>This is line 1</p>
<p>This is line 2</p>
<p>This is line 3</p>
<p>This is line 4</p>
<p>This is line 5</p>
<p>This is line 6</p>
<p>This is line 7</p>
<p>This is line 8</p>
<p>This is line 9</p>
<p>This is line 10</p>
<p>This is line 11</p>
<p>This is line 12</p>
<p>This is line 13</p>
<p>This is line 14</p>
<p>This is line 15</p>
<p>This is line 16</p>
<p>This is line 17</p>
<p>This is line 18</p>
<p>This is line 19</p>
<p>This is line 20</p>
<p>This is line 21</p>
<p>This is line 22</p>
<p>This is line 23</p>
<p>This is line 24</p>
<p>This is line 25</p>
<p>This is line 26</p>
<p>This is line 27</p>
<p>This is line 28</p>
<p>This is line 29</p>
<p>This is line 30</p>
<p>This is line 31</p>
<p>This is line 32</p>
<p>This is line 33</p>
<p>This is line 34</p>
<p>This is line 35</p>
<p>This is line 36</p>
<p>This is line 37</p>
<p>This is line 38</p>
<p>This is line 39</p>
<p>This is line 40</p>
<p>This is line 41</p>
<p>This is line 42</p>
<p>This is line 43</p>hi!
<p>This is line 1 nested</p>
<p>This is line 2 nested</p>
<p>This is line 3 nested</p>
<p>This is line 4 nested</p>
<p>This is line 5 nested</p>
<p>This is line 6 nested</p>
<p>This is line 7 nested</p>
<p>This is line 8 nested</p>
<p>This is line 9 nested</p>
<p>This is line 10 nested</p>
<p>This is line 11 nested</p>
<p>This is line 12 nested</p>
<p>This is line 13 nested</p>
<p>This is line 14 nested</p>
<p>This is line 15 nested</p>
<p>This is line 16 nested</p>
<p>This is line 17 nested</p>
<p>This is line 18 nested</p>
<p>This is line 19 nested</p>
<p>This is line 20 nested</p>
<p>This is line 21 nested</p>
<p>This is line 22 nested</p>
<p>This is line 23 nested</p>
<p>This is line 24 nested</p>
<p>This is line 25 nested</p>
<p>This is line 26 nested</p>
<p>This is line 27 nested</p>
<p>This is line 28 nested</p>
<p>This is line 29 nested</p>
<p>30</p>
!

View File

@ -0,0 +1,9 @@
<script type="text/javascript" ></script @foo >
<script type="text/html">
<%var x = window == null%>
</script>
<script></script @

View File

@ -0,0 +1,53 @@
<text>This works !</text>
<p class=" ">Hello</p>
<ul>
<li>Item # </li>
</ul>
<p>
This is line# of markup<br/>
</p>
<p>
: This is line# of markup<br />
</p>
<p>
:: This is line# of markup<br />
</p>
<ul>
<li>
Item #
<ul>
<li>Child Items... ?</li>
</ul>
</li>
</ul>

View File

@ -0,0 +1,15 @@
<p>Path's full type name is </p>
<p>Foo's actual full type name is </p>

View File

@ -361,6 +361,36 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
IntermediateNodeVerifier.Verify(document, baseline);
}
internal void AssertHtmlDocumentMatchesBaseline(RazorHtmlDocument htmlDocument)
{
if (FileName == null)
{
var message = $"{nameof(AssertHtmlDocumentMatchesBaseline)} should only be called from an integration test ({nameof(FileName)} is null).";
throw new InvalidOperationException(message);
}
var baselineFileName = Path.ChangeExtension(FileName, ".codegen.html");
if (GenerateBaselines)
{
var baselineFullPath = Path.Combine(TestProjectRoot, baselineFileName);
File.WriteAllText(baselineFullPath, htmlDocument.GeneratedHtml);
return;
}
var htmlFile = TestFile.Create(baselineFileName, GetType().GetTypeInfo().Assembly);
if (!htmlFile.Exists())
{
throw new XunitException($"The resource {baselineFileName} was not found.");
}
var baseline = htmlFile.ReadAllText();
// Normalize newlines to match those in the baseline.
var actual = htmlDocument.GeneratedHtml.Replace("\r", "").Replace("\n", "\r\n");
Assert.Equal(baseline, actual);
}
protected void AssertCSharpDocumentMatchesBaseline(RazorCSharpDocument cSharpDocument)
{
if (FileName == null)