|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Collections.Generic;
using System.Globalization;
using Microsoft.AspNetCore.Razor.Language.Components;
using Xunit;
namespace Microsoft.AspNetCore.Razor.Language.Legacy;
public class TagHelperBlockRewriterTest : TagHelperRewritingTestBase
{
public static readonly TagHelperCollection SymbolBoundAttributes_TagHelpers =
[
TagHelperDescriptorBuilder.CreateTagHelper("CatchAllTagHelper", "SomeAssembly")
.TagMatchingRuleDescriptor(rule => rule
.RequireTagName("*")
.RequireAttributeDescriptor(attribute => attribute.Name("bound")))
.BoundAttributeDescriptor(attribute => attribute
.Name("[item]")
.PropertyName("ListItems")
.TypeName(typeof(List<string>).Namespace + "List<System.String>"))
.BoundAttributeDescriptor(attribute => attribute
.Name("[(item)]")
.PropertyName("ArrayItems")
.TypeName(typeof(string[]).Namespace + "System.String[]"))
.BoundAttributeDescriptor(attribute => attribute
.Name("(click)")
.PropertyName("Event1")
.TypeName(typeof(Action).FullName))
.BoundAttributeDescriptor(attribute => attribute
.Name("(^click)")
.PropertyName("Event2")
.TypeName(typeof(Action).FullName))
.BoundAttributeDescriptor(attribute => attribute
.Name("*something")
.PropertyName("StringProperty1")
.TypeName(typeof(string).FullName))
.BoundAttributeDescriptor(attribute => attribute
.Name("#local")
.PropertyName("StringProperty2")
.TypeName(typeof(string).FullName))
.Build()
];
[Fact]
public void CanHandleSymbolBoundAttributes1()
{
EvaluateData(SymbolBoundAttributes_TagHelpers, "<ul bound [item]='items'></ul>");
}
[Fact]
public void CanHandleSymbolBoundAttributes2()
{
EvaluateData(SymbolBoundAttributes_TagHelpers, "<ul bound [(item)]='items'></ul>");
}
[Fact]
public void CanHandleSymbolBoundAttributes3()
{
EvaluateData(SymbolBoundAttributes_TagHelpers, "<button bound (click)='doSomething()'>Click Me</button>");
}
[Fact]
public void CanHandleSymbolBoundAttributes4()
{
EvaluateData(SymbolBoundAttributes_TagHelpers, "<button bound (^click)='doSomething()'>Click Me</button>");
}
[Fact]
public void CanHandleSymbolBoundAttributes5()
{
EvaluateData(SymbolBoundAttributes_TagHelpers, "<template bound *something='value'></template>");
}
[Fact]
public void CanHandleSymbolBoundAttributes6()
{
EvaluateData(SymbolBoundAttributes_TagHelpers, "<div bound #localminimized></div>");
}
[Fact]
public void CanHandleSymbolBoundAttributes7()
{
EvaluateData(SymbolBoundAttributes_TagHelpers, "<div bound #local='value'></div>");
}
public static readonly TagHelperCollection WithoutEndTag_TagHelpers =
[
TagHelperDescriptorBuilder.CreateTagHelper("InputTagHelper", "SomeAssembly")
.TagMatchingRuleDescriptor(rule => rule
.RequireTagName("input")
.RequireTagStructure(TagStructure.WithoutEndTag))
.Build()
];
[Fact]
public void CanHandleWithoutEndTagTagStructure1()
{
EvaluateData(WithoutEndTag_TagHelpers, "<input>");
}
[Fact]
public void CanHandleWithoutEndTagTagStructure2()
{
EvaluateData(WithoutEndTag_TagHelpers, "<input type='text'>");
}
[Fact]
public void CanHandleWithoutEndTagTagStructure3()
{
EvaluateData(WithoutEndTag_TagHelpers, "<input><input>");
}
[Fact]
public void CanHandleWithoutEndTagTagStructure4()
{
EvaluateData(WithoutEndTag_TagHelpers, "<input type='text'><input>");
}
[Fact]
public void CanHandleWithoutEndTagTagStructure5()
{
EvaluateData(WithoutEndTag_TagHelpers, "<div><input><input></div>");
}
public static TagHelperCollection GetTagStructureCompatibilityTagHelpers(TagStructure structure1, TagStructure structure2)
{
return
[
TagHelperDescriptorBuilder.CreateTagHelper("InputTagHelper1", "SomeAssembly")
.TagMatchingRuleDescriptor(rule => rule
.RequireTagName("input")
.RequireTagStructure(structure1))
.Build(),
TagHelperDescriptorBuilder.CreateTagHelper("InputTagHelper2", "SomeAssembly")
.TagMatchingRuleDescriptor(rule => rule
.RequireTagName("input")
.RequireTagStructure(structure2))
.Build()
];
}
[Fact]
public void AllowsCompatibleTagStructures1()
{
// Arrange
var tagHelpers = GetTagStructureCompatibilityTagHelpers(TagStructure.Unspecified, TagStructure.Unspecified);
// Act & Assert
EvaluateData(tagHelpers, "<input></input>");
}
[Fact]
public void AllowsCompatibleTagStructures2()
{
// Arrange
var tagHelpers = GetTagStructureCompatibilityTagHelpers(TagStructure.Unspecified, TagStructure.Unspecified);
// Act & Assert
EvaluateData(tagHelpers, "<input />");
}
[Fact]
public void AllowsCompatibleTagStructures3()
{
// Arrange
var tagHelpers = GetTagStructureCompatibilityTagHelpers(TagStructure.Unspecified, TagStructure.WithoutEndTag);
// Act & Assert
EvaluateData(tagHelpers, "<input type='text'>");
}
[Fact]
public void AllowsCompatibleTagStructures4()
{
// Arrange
var tagHelpers = GetTagStructureCompatibilityTagHelpers(TagStructure.WithoutEndTag, TagStructure.WithoutEndTag);
// Act & Assert
EvaluateData(tagHelpers, "<input><input>");
}
[Fact]
public void AllowsCompatibleTagStructures5()
{
// Arrange
var tagHelpers = GetTagStructureCompatibilityTagHelpers(TagStructure.Unspecified, TagStructure.NormalOrSelfClosing);
// Act & Assert
EvaluateData(tagHelpers, "<input type='text'></input>");
}
[Fact]
public void AllowsCompatibleTagStructures6()
{
// Arrange
var tagHelpers = GetTagStructureCompatibilityTagHelpers(TagStructure.Unspecified, TagStructure.WithoutEndTag);
// Act & Assert
EvaluateData(tagHelpers, "<input />");
}
[Fact]
public void AllowsCompatibleTagStructures7()
{
// Arrange
var tagHelpers = GetTagStructureCompatibilityTagHelpers(TagStructure.NormalOrSelfClosing, TagStructure.Unspecified);
// Act & Assert
EvaluateData(tagHelpers, "<input />");
}
[Fact]
public void AllowsCompatibleTagStructures8()
{
// Arrange
var tagHelpers = GetTagStructureCompatibilityTagHelpers(TagStructure.WithoutEndTag, TagStructure.Unspecified);
// Act & Assert
EvaluateData(tagHelpers, "<input></input>");
}
[Fact]
public void AllowsCompatibleTagStructures_DirectiveAttribute_SelfClosing()
{
// Arrange
TagHelperCollection tagHelpers =
[
TagHelperDescriptorBuilder.CreateEventHandler("InputTagHelper1", "SomeAssembly")
.TagMatchingRuleDescriptor(rule => rule
.RequireTagName("*")
.RequireAttributeDescriptor(attribute => attribute
.Name("@onclick")
.IsDirectiveAttribute()))
.Build(),
];
// Act & Assert
EvaluateData(tagHelpers, "<input @onclick=\"@test\"/>");
}
[Fact]
public void AllowsCompatibleTagStructures_DirectiveAttribute_Void()
{
// Arrange
TagHelperCollection tagHelpers =
[
TagHelperDescriptorBuilder.CreateEventHandler("InputTagHelper1", "SomeAssembly")
.TagMatchingRuleDescriptor(rule => rule
.RequireTagName("*")
.RequireAttributeDescriptor(attribute => attribute
.Name("@onclick")
.IsDirectiveAttribute()))
.Build(),
];
// Act & Assert
EvaluateData(tagHelpers, "<input @onclick=\"@test\">");
}
[Fact]
public void CreatesErrorForMalformedTagHelpersWithAttributes1()
{
RunParseTreeRewriterTest("<p class='", "strong", "p");
}
[Fact]
public void CreatesErrorForMalformedTagHelpersWithAttributes2()
{
RunParseTreeRewriterTest("<p bar=\"false\"\" <strong>", "strong", "p");
}
[Fact]
public void CreatesErrorForMalformedTagHelpersWithAttributes3()
{
RunParseTreeRewriterTest("<p bar='false <strong>", "strong", "p");
}
[Fact]
public void CreatesErrorForMalformedTagHelpersWithAttributes4()
{
RunParseTreeRewriterTest("<p bar='false <strong'", "strong", "p");
}
[Fact]
public void CreatesErrorForMalformedTagHelpersWithAttributes5()
{
RunParseTreeRewriterTest("<p bar=false'", "strong", "p");
}
[Fact]
public void CreatesErrorForMalformedTagHelpersWithAttributes6()
{
RunParseTreeRewriterTest("<p bar=\"false'", "strong", "p");
}
[Fact]
public void CreatesErrorForMalformedTagHelpersWithAttributes7()
{
RunParseTreeRewriterTest("<p bar=\"false' ></p>", "strong", "p");
}
[Fact]
public void CreatesErrorForMalformedTagHelpersWithAttributes8()
{
RunParseTreeRewriterTest("<p foo bar<strong>", "strong", "p");
}
[Fact]
public void CreatesErrorForMalformedTagHelpersWithAttributes9()
{
RunParseTreeRewriterTest("<p class=btn\" bar<strong>", "strong", "p");
}
[Fact]
public void CreatesErrorForMalformedTagHelpersWithAttributes10()
{
RunParseTreeRewriterTest("<p class=btn\" bar=\"foo\"<strong>", "strong", "p");
}
[Fact]
public void CreatesErrorForMalformedTagHelpersWithAttributes11()
{
RunParseTreeRewriterTest("<p class=\"btn bar=\"foo\"<strong>", "strong", "p");
}
[Fact]
public void CreatesErrorForMalformedTagHelpersWithAttributes12()
{
RunParseTreeRewriterTest("<p class=\"btn bar=\"foo\"></p>", "strong", "p");
}
[Fact]
public void CreatesErrorForMalformedTagHelpersWithAttributes13()
{
RunParseTreeRewriterTest("<p @DateTime.Now class=\"btn\"></p>", "strong", "p");
}
[Fact]
public void CreatesErrorForMalformedTagHelpersWithAttributes14()
{
RunParseTreeRewriterTest("<p @DateTime.Now=\"btn\"></p>", "strong", "p");
}
[Fact]
public void CreatesErrorForMalformedTagHelpersWithAttributes15()
{
RunParseTreeRewriterTest("<p class=@DateTime.Now\"></p>", "strong", "p");
}
[Fact]
public void CreatesErrorForMalformedTagHelpersWithAttributes16()
{
RunParseTreeRewriterTest("<p class=\"@do {", "strong", "p");
}
[Fact]
public void CreatesErrorForMalformedTagHelpersWithAttributes17()
{
RunParseTreeRewriterTest("<p class=\"@do {\"></p>", "strong", "p");
}
[Fact]
public void CreatesErrorForMalformedTagHelpersWithAttributes18()
{
RunParseTreeRewriterTest("<p @do { someattribute=\"btn\"></p>", "strong", "p");
}
[Fact]
public void CreatesErrorForMalformedTagHelpersWithAttributes19()
{
RunParseTreeRewriterTest("<p class=some=thing attr=\"@value\"></p>", "strong", "p");
}
[Fact]
public void CreatesErrorForMalformedTagHelpersWithAttributes20()
{
RunParseTreeRewriterTest("<p attr=\"@if (true) <p attr='@foo'> }\"></p>", "strong", "p");
}
[Fact]
public void CreatesErrorForMalformedTagHelper1()
{
RunParseTreeRewriterTest("<p", "strong", "p");
}
[Fact]
public void CreatesErrorForMalformedTagHelper2()
{
RunParseTreeRewriterTest("<p></p", "strong", "p");
}
[Fact]
public void CreatesErrorForMalformedTagHelper3()
{
RunParseTreeRewriterTest("<p><strong", "strong", "p");
}
[Fact]
public void CreatesErrorForMalformedTagHelper4()
{
RunParseTreeRewriterTest("<strong <p>", "strong", "p");
}
[Fact]
public void CreatesErrorForMalformedTagHelper5()
{
RunParseTreeRewriterTest("<strong </strong", "strong", "p");
}
[Fact]
public void CreatesErrorForMalformedTagHelper6()
{
RunParseTreeRewriterTest("<<</strong> <<p>", "strong", "p");
}
[Fact]
public void CreatesErrorForMalformedTagHelper7()
{
RunParseTreeRewriterTest("<<<strong>> <<>>", "strong", "p");
}
[Fact]
public void CreatesErrorForMalformedTagHelper8()
{
RunParseTreeRewriterTest("<str<strong></p></strong>", "strong", "p");
}
public static readonly TagHelperCollection CodeTagHelperAttributes_TagHelpers =
[
TagHelperDescriptorBuilder.CreateTagHelper("PersonTagHelper", "personAssembly")
.TagMatchingRuleDescriptor(rule => rule.RequireTagName("person"))
.BoundAttributeDescriptor(attribute => attribute
.Name("age")
.PropertyName("Age")
.TypeName(typeof(int).FullName))
.BoundAttributeDescriptor(attribute => attribute
.Name("birthday")
.PropertyName("BirthDay")
.TypeName(typeof(DateTime).FullName))
.BoundAttributeDescriptor(attribute => attribute
.Name("name")
.PropertyName("Name")
.TypeName(typeof(string).FullName))
.Build()
];
[Fact]
public void UnderstandsMultipartNonStringTagHelperAttributes()
{
EvaluateData(CodeTagHelperAttributes_TagHelpers, "<person age=\"(() => 123)()\" />");
}
[Fact]
public void CreatesMarkupCodeSpansForNonStringTagHelperAttributes1()
{
EvaluateData(CodeTagHelperAttributes_TagHelpers, "<person age=\"12\" />");
}
[Fact]
public void CreatesMarkupCodeSpansForNonStringTagHelperAttributes2()
{
EvaluateData(CodeTagHelperAttributes_TagHelpers, "<person birthday=\"DateTime.Now\" />");
}
[Fact]
public void CreatesMarkupCodeSpansForNonStringTagHelperAttributes3()
{
EvaluateData(CodeTagHelperAttributes_TagHelpers, "<person age=\"@DateTime.Now.Year\" />");
}
[Fact]
public void CreatesMarkupCodeSpansForNonStringTagHelperAttributes4()
{
EvaluateData(CodeTagHelperAttributes_TagHelpers, "<person age=\" @DateTime.Now.Year\" />");
}
[Fact]
public void CreatesMarkupCodeSpansForNonStringTagHelperAttributes5()
{
EvaluateData(CodeTagHelperAttributes_TagHelpers, "<person name=\"John\" />");
}
[Fact]
public void CreatesMarkupCodeSpansForNonStringTagHelperAttributes6()
{
EvaluateData(CodeTagHelperAttributes_TagHelpers, "<person name=\"Time: @DateTime.Now\" />");
}
[Fact]
public void CreatesMarkupCodeSpansForNonStringTagHelperAttributes7()
{
EvaluateData(CodeTagHelperAttributes_TagHelpers, "<person age=\"1 + @value + 2\" birthday='(bool)@Bag[\"val\"] ? @@DateTime : @DateTime.Now'/>");
}
[Fact]
public void CreatesMarkupCodeSpansForNonStringTagHelperAttributes8()
{
EvaluateData(CodeTagHelperAttributes_TagHelpers, "<person age=\"12\" birthday=\"DateTime.Now\" name=\"Time: @DateTime.Now\" />");
}
[Fact]
public void CreatesMarkupCodeSpansForNonStringTagHelperAttributes9()
{
EvaluateData(CodeTagHelperAttributes_TagHelpers, "<person age=\"12\" birthday=\"DateTime.Now\" name=\"Time: @@ @DateTime.Now\" />");
}
[Fact]
public void CreatesMarkupCodeSpansForNonStringTagHelperAttributes10()
{
EvaluateData(CodeTagHelperAttributes_TagHelpers, "<person age=\"12\" birthday=\"DateTime.Now\" name=\"@@BoundStringAttribute\" />");
}
[Fact]
public void CreatesMarkupCodeSpansForNonStringTagHelperAttributes11()
{
EvaluateData(CodeTagHelperAttributes_TagHelpers, "<person age=\"@@@(11+1)\" birthday=\"DateTime.Now\" name=\"Time: @DateTime.Now\" />");
}
[Fact]
public void CreatesMarkupCodeSpansForNonStringTagHelperAttributes12()
{
EvaluateData(CodeTagHelperAttributes_TagHelpers, "<person age=\"@{flag == 0 ? 11 : 12}\" />");
}
[Fact]
public void TagHelperParseTreeRewriter_CreatesErrorForIncompleteTagHelper1()
{
RunParseTreeRewriterTest("<p class=foo dynamic=@DateTime.Now style=color:red;><strong></p></strong>", "strong", "p");
}
[Fact]
public void TagHelperParseTreeRewriter_CreatesErrorForIncompleteTagHelper2()
{
RunParseTreeRewriterTest("<div><p>Hello <strong>World</strong></div>", "strong", "p");
}
[Fact]
public void TagHelperParseTreeRewriter_CreatesErrorForIncompleteTagHelper3()
{
RunParseTreeRewriterTest("<div><p>Hello <strong>World</div>", "strong", "p");
}
[Fact]
public void TagHelperParseTreeRewriter_CreatesErrorForIncompleteTagHelper4()
{
RunParseTreeRewriterTest("<p class=\"foo\">Hello <p style=\"color:red;\">World</p>", "strong", "p");
}
[Fact]
public void TagHelperParseTreeRewriter_RewritesOddlySpacedTagHelperTagBlocks1()
{
RunParseTreeRewriterTest("<p class=\" foo\" style=\" color : red ; \" ></p>", "p");
}
[Fact]
public void TagHelperParseTreeRewriter_RewritesOddlySpacedTagHelperTagBlocks2()
{
RunParseTreeRewriterTest("<p class=\" foo\" style=\" color : red ; \" >Hello World</p>", "p");
}
[Fact]
public void TagHelperParseTreeRewriter_RewritesOddlySpacedTagHelperTagBlocks3()
{
RunParseTreeRewriterTest("<p class=\" foo \" >Hello</p> <p style=\" color:red; \" >World</p>", "p");
}
[Fact]
public void TagHelperParseTreeRewriter_RewritesComplexAttributeTagHelperTagBlocks1()
{
// Arrange
var dateTimeNowString = "@DateTime.Now";
var currentFormattedString = "<p class=\"{0}\" style='{0}'></p>";
var document = string.Format(CultureInfo.InvariantCulture, currentFormattedString, dateTimeNowString);
// Act & Assert
RunParseTreeRewriterTest(document, "p");
}
[Fact]
public void TagHelperParseTreeRewriter_RewritesComplexAttributeTagHelperTagBlocks2()
{
// Arrange
var doWhileString = "@do { var foo = bar; <text>Foo</text> foo++; } while (foo<bar>);";
var currentFormattedString = "<p class=\"{0}\" style='{0}'></p>";
var document = string.Format(CultureInfo.InvariantCulture, currentFormattedString, doWhileString);
// Act & Assert
RunParseTreeRewriterTest(document, "p");
}
[Fact]
public void TagHelperParseTreeRewriter_RewritesComplexAttributeTagHelperTagBlocks3()
{
// Arrange
var dateTimeNowString = "@DateTime.Now";
var currentFormattedString = "<p class=\"{0}\" style='{0}'>Hello World</p>";
var document = string.Format(CultureInfo.InvariantCulture, currentFormattedString, dateTimeNowString);
// Act & Assert
RunParseTreeRewriterTest(document, "p");
}
[Fact]
public void TagHelperParseTreeRewriter_RewritesComplexAttributeTagHelperTagBlocks4()
{
// Arrange
var doWhileString = "@do { var foo = bar; <text>Foo</text> foo++; } while (foo<bar>);";
var currentFormattedString = "<p class=\"{0}\" style='{0}'>Hello World</p>";
var document = string.Format(CultureInfo.InvariantCulture, currentFormattedString, doWhileString);
// Act & Assert
RunParseTreeRewriterTest(document, "p");
}
[Fact]
public void TagHelperParseTreeRewriter_RewritesComplexAttributeTagHelperTagBlocks5()
{
// Arrange
var dateTimeNowString = "@DateTime.Now";
var currentFormattedString = "<p class=\"{0}\">Hello</p> <p style='{0}'>World</p>";
var document = string.Format(CultureInfo.InvariantCulture, currentFormattedString, dateTimeNowString);
// Act & Assert
RunParseTreeRewriterTest(document, "p");
}
[Fact]
public void TagHelperParseTreeRewriter_RewritesComplexAttributeTagHelperTagBlocks6()
{
// Arrange
var doWhileString = "@do { var foo = bar; <text>Foo</text> foo++; } while (foo<bar>);";
var currentFormattedString = "<p class=\"{0}\">Hello</p> <p style='{0}'>World</p>";
var document = string.Format(CultureInfo.InvariantCulture, currentFormattedString, doWhileString);
// Act & Assert
RunParseTreeRewriterTest(document, "p");
}
[Fact]
public void TagHelperParseTreeRewriter_RewritesComplexAttributeTagHelperTagBlocks7()
{
// Arrange
var dateTimeNowString = "@DateTime.Now";
var currentFormattedString = "<p class=\"{0}\" style='{0}'>Hello World <strong class=\"{0}\">inside of strong tag</strong></p>";
var document = string.Format(CultureInfo.InvariantCulture, currentFormattedString, dateTimeNowString);
// Act & Assert
RunParseTreeRewriterTest(document, "p");
}
[Fact]
public void TagHelperParseTreeRewriter_RewritesComplexTagHelperTagBlocks1()
{
// Arrange
var dateTimeNowString = "@DateTime.Now";
var currentFormattedString = "<p>{0}</p>";
var document = string.Format(CultureInfo.InvariantCulture, currentFormattedString, dateTimeNowString);
// Act & Assert
RunParseTreeRewriterTest(document, "p");
}
[Fact]
public void TagHelperParseTreeRewriter_RewritesComplexTagHelperTagBlocks2()
{
// Arrange
var doWhileString = "@do { var foo = bar; <p>Foo</p> foo++; } while (foo<bar>);";
var currentFormattedString = "<p>{0}</p>";
var document = string.Format(CultureInfo.InvariantCulture, currentFormattedString, doWhileString);
// Act & Assert
RunParseTreeRewriterTest(document, "p");
}
[Fact]
public void TagHelperParseTreeRewriter_RewritesComplexTagHelperTagBlocks3()
{
// Arrange
var dateTimeNowString = "@DateTime.Now";
var currentFormattedString = "<p>Hello World {0}</p>";
var document = string.Format(CultureInfo.InvariantCulture, currentFormattedString, dateTimeNowString);
// Act & Assert
RunParseTreeRewriterTest(document, "p");
}
[Fact]
public void TagHelperParseTreeRewriter_RewritesComplexTagHelperTagBlocks4()
{
// Arrange
var doWhileString = "@do { var foo = bar; <p>Foo</p> foo++; } while (foo<bar>);";
var currentFormattedString = "<p>Hello World {0}</p>";
var document = string.Format(CultureInfo.InvariantCulture, currentFormattedString, doWhileString);
// Act & Assert
RunParseTreeRewriterTest(document, "p");
}
[Fact]
public void TagHelperParseTreeRewriter_RewritesComplexTagHelperTagBlocks5()
{
// Arrange
var dateTimeNowString = "@DateTime.Now";
var currentFormattedString = "<p>{0}</p> <p>{0}</p>";
var document = string.Format(CultureInfo.InvariantCulture, currentFormattedString, dateTimeNowString);
// Act & Assert
RunParseTreeRewriterTest(document, "p");
}
[Fact]
public void TagHelperParseTreeRewriter_RewritesComplexTagHelperTagBlocks6()
{
// Arrange
var doWhileString = "@do { var foo = bar; <p>Foo</p> foo++; } while (foo<bar>);";
var currentFormattedString = "<p>{0}</p> <p>{0}</p>";
var document = string.Format(CultureInfo.InvariantCulture, currentFormattedString, doWhileString);
// Act & Assert
RunParseTreeRewriterTest(document, "p");
}
[Fact]
public void TagHelperParseTreeRewriter_RewritesComplexTagHelperTagBlocks7()
{
// Arrange
var dateTimeNowString = "@DateTime.Now";
var currentFormattedString = "<p>Hello {0}<strong>inside of {0} strong tag</strong></p>";
var document = string.Format(CultureInfo.InvariantCulture, currentFormattedString, dateTimeNowString);
// Act & Assert
RunParseTreeRewriterTest(document, "p");
}
[Fact]
public void TagHelperParseTreeRewriter_RewritesComplexTagHelperTagBlocks8()
{
// Arrange
var doWhileString = "@do { var foo = bar; <p>Foo</p> foo++; } while (foo<bar>);";
var currentFormattedString = "<p>Hello {0}<strong>inside of {0} strong tag</strong></p>";
var document = string.Format(CultureInfo.InvariantCulture, currentFormattedString, doWhileString);
// Act & Assert
RunParseTreeRewriterTest(document, "p");
}
[Fact]
public void TagHelperParseTreeRewriter_AllowsInvalidHtml1()
{
RunParseTreeRewriterTest("<<<p>>></p>", "p");
}
[Fact]
public void TagHelperParseTreeRewriter_AllowsInvalidHtml2()
{
RunParseTreeRewriterTest("<<p />", "p");
}
[Fact]
public void TagHelperParseTreeRewriter_AllowsInvalidHtml3()
{
RunParseTreeRewriterTest("< p />", "p");
}
[Fact]
public void TagHelperParseTreeRewriter_AllowsInvalidHtml4()
{
RunParseTreeRewriterTest("<input <p />", "p");
}
[Fact]
public void TagHelperParseTreeRewriter_AllowsInvalidHtml5()
{
RunParseTreeRewriterTest("< class=\"foo\" <p />", "p");
}
[Fact]
public void TagHelperParseTreeRewriter_AllowsInvalidHtml6()
{
RunParseTreeRewriterTest("</<<p>/></p>>", "p");
}
[Fact]
public void TagHelperParseTreeRewriter_AllowsInvalidHtml7()
{
RunParseTreeRewriterTest("</<<p>/><strong></p>>", "p");
}
[Fact]
public void TagHelperParseTreeRewriter_AllowsInvalidHtml8()
{
RunParseTreeRewriterTest("</<<p>@DateTime.Now/><strong></p>>", "p");
}
[Fact]
public void TagHelperParseTreeRewriter_AllowsInvalidHtml9()
{
RunParseTreeRewriterTest("</ /< ><p>@DateTime.Now / ><strong></p></ >", "p");
}
[Fact]
public void TagHelperParseTreeRewriter_AllowsInvalidHtml10()
{
RunParseTreeRewriterTest("<p>< @DateTime.Now ></ @DateTime.Now ></p>", "p");
}
[Fact]
public void UnderstandsEmptyAttributeTagHelpers1()
{
RunParseTreeRewriterTest("<p class=\"\"></p>", "p");
}
[Fact]
public void UnderstandsEmptyAttributeTagHelpers2()
{
RunParseTreeRewriterTest("<p class=''></p>", "p");
}
[Fact]
public void UnderstandsEmptyAttributeTagHelpers3()
{
RunParseTreeRewriterTest("<p class=></p>", "p");
}
[Fact]
public void UnderstandsEmptyAttributeTagHelpers4()
{
RunParseTreeRewriterTest("<p class1='' class2= class3=\"\" />", "p");
}
[Fact]
public void UnderstandsEmptyAttributeTagHelpers5()
{
RunParseTreeRewriterTest("<p class1=''class2=\"\"class3= />", "p");
}
public static readonly TagHelperCollection EmptyTagHelperBoundAttribute_TagHelpers =
[
TagHelperDescriptorBuilder.CreateTagHelper("mythTagHelper", "SomeAssembly")
.TagMatchingRuleDescriptor(rule => rule.RequireTagName("myth"))
.BoundAttributeDescriptor(attribute => attribute
.Name("bound")
.PropertyName("Bound")
.TypeName(typeof(bool).FullName))
.BoundAttributeDescriptor(attribute => attribute
.Name("name")
.PropertyName("Name")
.TypeName(typeof(string).FullName))
.Build()
];
[Fact]
public void CreatesErrorForEmptyTagHelperBoundAttributes1()
{
EvaluateData(EmptyTagHelperBoundAttribute_TagHelpers, "<myth bound='' />");
}
[Fact]
public void CreatesErrorForEmptyTagHelperBoundAttributes2()
{
EvaluateData(EmptyTagHelperBoundAttribute_TagHelpers, "<myth bound=' true' />");
}
[Fact]
public void CreatesErrorForEmptyTagHelperBoundAttributes3()
{
EvaluateData(EmptyTagHelperBoundAttribute_TagHelpers, "<myth bound=' ' />");
}
[Fact]
public void CreatesErrorForEmptyTagHelperBoundAttributes4()
{
EvaluateData(EmptyTagHelperBoundAttribute_TagHelpers, "<myth bound='' bound=\"\" />");
}
[Fact]
public void CreatesErrorForEmptyTagHelperBoundAttributes5()
{
EvaluateData(EmptyTagHelperBoundAttribute_TagHelpers, "<myth bound=' ' bound=\" \" />");
}
[Fact]
public void CreatesErrorForEmptyTagHelperBoundAttributes6()
{
EvaluateData(EmptyTagHelperBoundAttribute_TagHelpers, "<myth bound='true' bound= />");
}
[Fact]
public void CreatesErrorForEmptyTagHelperBoundAttributes7()
{
EvaluateData(EmptyTagHelperBoundAttribute_TagHelpers, "<myth bound= name='' />");
}
[Fact]
public void CreatesErrorForEmptyTagHelperBoundAttributes8()
{
EvaluateData(EmptyTagHelperBoundAttribute_TagHelpers, "<myth bound= name=' ' />");
}
[Fact]
public void CreatesErrorForEmptyTagHelperBoundAttributes9()
{
EvaluateData(EmptyTagHelperBoundAttribute_TagHelpers, "<myth bound='true' name='john' bound= name= />");
}
[Fact]
public void CreatesErrorForEmptyTagHelperBoundAttributes10()
{
EvaluateData(EmptyTagHelperBoundAttribute_TagHelpers, "<myth BouND='' />");
}
[Fact]
public void CreatesErrorForEmptyTagHelperBoundAttributes11()
{
EvaluateData(EmptyTagHelperBoundAttribute_TagHelpers, "<myth BOUND='' bOUnd=\"\" />");
}
[Fact]
public void CreatesErrorForEmptyTagHelperBoundAttributes12()
{
EvaluateData(EmptyTagHelperBoundAttribute_TagHelpers, "<myth BOUND= nAMe='john'></myth>");
}
[Fact]
public void CreatesErrorForEmptyTagHelperBoundAttributes13()
{
EvaluateData(EmptyTagHelperBoundAttribute_TagHelpers, "<myth bound=' @true ' />");
}
[Fact]
public void CreatesErrorForEmptyTagHelperBoundAttributes14()
{
EvaluateData(EmptyTagHelperBoundAttribute_TagHelpers, "<myth bound=' @(true) ' />");
}
[Fact]
public void TagHelperParseTreeRewriter_RewritesScriptTagHelpers1()
{
RunParseTreeRewriterTest("<script><script></foo></script>", "p", "div", "script");
}
[Fact]
public void TagHelperParseTreeRewriter_RewritesScriptTagHelpers2()
{
RunParseTreeRewriterTest("<script>Hello World <div></div></script>", "p", "div", "script");
}
[Fact]
public void TagHelperParseTreeRewriter_RewritesScriptTagHelpers3()
{
RunParseTreeRewriterTest("<script>Hel<p>lo</p></script> <p><div>World</div></p>", "p", "div", "script");
}
[Fact]
public void TagHelperParseTreeRewriter_RewritesScriptTagHelpers4()
{
RunParseTreeRewriterTest("<script>Hel<strong>lo</strong></script> <script><span>World</span></script>", "p", "div", "script");
}
[Fact]
public void TagHelperParseTreeRewriter_RewritesScriptTagHelpers5()
{
RunParseTreeRewriterTest("<script class=\"foo\" style=\"color:red;\" />", "p", "div", "script");
}
[Fact]
public void TagHelperParseTreeRewriter_RewritesScriptTagHelpers6()
{
RunParseTreeRewriterTest("<p>Hello <script class=\"foo\" style=\"color:red;\"></script> World</p>", "p", "div", "script");
}
[Fact]
public void TagHelperParseTreeRewriter_RewritesScriptTagHelpers7()
{
RunParseTreeRewriterTest("<p>Hello <script class=\"@@foo@bar.com\" style=\"color:red;\"></script> World</p>", "p", "div", "script");
}
[Fact]
public void TagHelperParseTreeRewriter_RewritesSelfClosingTagHelpers1()
{
RunParseTreeRewriterTest("<p class=\"foo\" style=\"color:red;\" />", "p");
}
[Fact]
public void TagHelperParseTreeRewriter_RewritesSelfClosingTagHelpers2()
{
RunParseTreeRewriterTest("<p>Hello <p class=\"foo\" style=\"color:red;\" /> World</p>", "p");
}
[Fact]
public void TagHelperParseTreeRewriter_RewritesSelfClosingTagHelpers3()
{
RunParseTreeRewriterTest("Hello<p class=\"foo\" /> <p style=\"color:red;\" />World", "p");
}
[Fact]
public void TagHelperParseTreeRewriter_RewritesTagHelpersWithQuotelessAttributes1()
{
RunParseTreeRewriterTest("<p class=foo dynamic=@DateTime.Now style=color:red;></p>", "p");
}
[Fact]
public void TagHelperParseTreeRewriter_RewritesTagHelpersWithQuotelessAttributes2()
{
RunParseTreeRewriterTest("<p class=foo dynamic=@DateTime.Now style=color:red;>Hello World</p>", "p");
}
[Fact]
public void TagHelperParseTreeRewriter_RewritesTagHelpersWithQuotelessAttributes3()
{
RunParseTreeRewriterTest("<p class=foo dynamic=@DateTime.Now style=color@@:red;>Hello World</p>", "p");
}
[Fact]
public void TagHelperParseTreeRewriter_RewritesTagHelpersWithQuotelessAttributes4()
{
RunParseTreeRewriterTest("<p class=foo dynamic=@DateTime.Now>Hello</p> <p style=color:red; dynamic=@DateTime.Now>World</p>", "p");
}
[Fact]
public void TagHelperParseTreeRewriter_RewritesTagHelpersWithQuotelessAttributes5()
{
RunParseTreeRewriterTest("<p class=foo dynamic=@DateTime.Now style=color:red;>Hello World <strong class=\"foo\">inside of strong tag</strong></p>", "p");
}
[Fact]
public void TagHelperParseTreeRewriter_RewritesTagHelpersWithPlainAttributes1()
{
RunParseTreeRewriterTest("<p class=\"foo\" style=\"color:red;\"></p>", "p");
}
[Fact]
public void TagHelperParseTreeRewriter_RewritesTagHelpersWithPlainAttributes2()
{
RunParseTreeRewriterTest("<p class=\"foo\" style=\"color:red;\">Hello World</p>", "p");
}
[Fact]
public void TagHelperParseTreeRewriter_RewritesTagHelpersWithPlainAttributes3()
{
RunParseTreeRewriterTest("<p class=\"foo\">Hello</p> <p style=\"color:red;\">World</p>", "p");
}
[Fact]
public void TagHelperParseTreeRewriter_RewritesTagHelpersWithPlainAttributes4()
{
RunParseTreeRewriterTest("<p class=\"foo\" style=\"color:red;\">Hello World <strong class=\"foo\">inside of strong tag</strong></p>", "p");
}
[Fact]
public void TagHelperParseTreeRewriter_RewritesPlainTagHelperTagBlocks1()
{
RunParseTreeRewriterTest("<p></p>", "p");
}
[Fact]
public void TagHelperParseTreeRewriter_RewritesPlainTagHelperTagBlocks2()
{
RunParseTreeRewriterTest("<p>Hello World</p>", "p");
}
[Fact]
public void TagHelperParseTreeRewriter_RewritesPlainTagHelperTagBlocks3()
{
RunParseTreeRewriterTest("<p>Hello</p> <p>World</p>", "p");
}
[Fact]
public void TagHelperParseTreeRewriter_RewritesPlainTagHelperTagBlocks4()
{
RunParseTreeRewriterTest("<p>Hello World <strong>inside of strong tag</strong></p>", "p");
}
[Fact]
public void GeneratesExpectedOutputForUnboundDataDashAttributes_Document1()
{
// Arrange
var dateTimeNowString = "@DateTime.Now";
var document = $"<input data-required='{dateTimeNowString}' />";
// Act & Assert
RunParseTreeRewriterTest(document, "input");
}
[Fact]
public void GeneratesExpectedOutputForUnboundDataDashAttributes_Document2()
{
// Arrange
var document = "<input data-required='value' />";
// Act & Assert
RunParseTreeRewriterTest(document, "input");
}
[Fact]
public void GeneratesExpectedOutputForUnboundDataDashAttributes_Document3()
{
// Arrange
var dateTimeNowString = "@DateTime.Now";
var document = $"<input data-required='prefix {dateTimeNowString}' />";
// Act & Assert
RunParseTreeRewriterTest(document, "input");
}
[Fact]
public void GeneratesExpectedOutputForUnboundDataDashAttributes_Document4()
{
// Arrange
var dateTimeNowString = "@DateTime.Now";
var document = $"<input data-required='{dateTimeNowString} suffix' />";
// Act & Assert
RunParseTreeRewriterTest(document, "input");
}
[Fact]
public void GeneratesExpectedOutputForUnboundDataDashAttributes_Document5()
{
// Arrange
var dateTimeNowString = "@DateTime.Now";
var document = $"<input data-required='prefix {dateTimeNowString} suffix' />";
// Act & Assert
RunParseTreeRewriterTest(document, "input");
}
[Fact]
public void GeneratesExpectedOutputForUnboundDataDashAttributes_Document6()
{
// Arrange
var dateTimeNowString = "@DateTime.Now";
var document = $"<input pre-attribute data-required='prefix {dateTimeNowString} suffix' post-attribute />";
// Act & Assert
RunParseTreeRewriterTest(document, "input");
}
[Fact]
public void GeneratesExpectedOutputForUnboundDataDashAttributes_Document7()
{
// Arrange
var dateTimeNowString = "@DateTime.Now";
var document = $"<input data-required='{dateTimeNowString} middle {dateTimeNowString}' />";
// Act & Assert
RunParseTreeRewriterTest(document, "input");
}
[Fact]
public void GeneratesExpectedOutputForUnboundDataDashAttributes_Block1()
{
// Arrange
var dateTimeNowString = "@DateTime.Now";
var document = $"<input data-required='{dateTimeNowString}' />";
// Wrap in a CSharp block
document = $$"""@{{{document}}}""";
// Act & Assert
RunParseTreeRewriterTest(document, "input");
}
[Fact]
public void GeneratesExpectedOutputForUnboundDataDashAttributes_Block2()
{
// Arrange
var document = "<input data-required='value' />";
// Wrap in a CSharp block
document = $$"""@{{{document}}}""";
// Act & Assert
RunParseTreeRewriterTest(document, "input");
}
[Fact]
public void GeneratesExpectedOutputForUnboundDataDashAttributes_Block3()
{
// Arrange
var dateTimeNowString = "@DateTime.Now";
var document = $"<input data-required='prefix {dateTimeNowString}' />";
// Wrap in a CSharp block
document = $$"""@{{{document}}}""";
// Act & Assert
RunParseTreeRewriterTest(document, "input");
}
[Fact]
public void GeneratesExpectedOutputForUnboundDataDashAttributes_Block4()
{
// Arrange
var dateTimeNowString = "@DateTime.Now";
var document = $"<input data-required='{dateTimeNowString} suffix' />";
// Wrap in a CSharp block
document = $$"""@{{{document}}}""";
// Act & Assert
RunParseTreeRewriterTest(document, "input");
}
[Fact]
public void GeneratesExpectedOutputForUnboundDataDashAttributes_Block5()
{
// Arrange
var dateTimeNowString = "@DateTime.Now";
var document = $"<input data-required='prefix {dateTimeNowString} suffix' />";
// Wrap in a CSharp block
document = $$"""@{{{document}}}""";
// Act & Assert
RunParseTreeRewriterTest(document, "input");
}
[Fact]
public void GeneratesExpectedOutputForUnboundDataDashAttributes_Block6()
{
// Arrange
var dateTimeNowString = "@DateTime.Now";
var document = $"<input pre-attribute data-required='prefix {dateTimeNowString} suffix' post-attribute />";
// Wrap in a CSharp block
document = $$"""@{{{document}}}""";
// Act & Assert
RunParseTreeRewriterTest(document, "input");
}
[Fact]
public void GeneratesExpectedOutputForUnboundDataDashAttributes_Block7()
{
// Arrange
var dateTimeNowString = "@DateTime.Now";
var document = $"<input data-required='{dateTimeNowString} middle {dateTimeNowString}' />";
// Wrap in a CSharp block
document = $$"""@{{{document}}}""";
// Act & Assert
RunParseTreeRewriterTest(document, "input");
}
public static readonly TagHelperCollection MinimizedAttribute_TagHelpers =
[
TagHelperDescriptorBuilder.CreateTagHelper("InputTagHelper1", "SomeAssembly")
.TagMatchingRuleDescriptor(rule => rule
.RequireTagName("input")
.RequireAttributeDescriptor(attribute => attribute.Name("unbound-required")))
.TagMatchingRuleDescriptor(rule => rule
.RequireTagName("input")
.RequireAttributeDescriptor(attribute => attribute.Name("bound-required-string")))
.BoundAttributeDescriptor(attribute => attribute
.Name("bound-required-string")
.PropertyName("BoundRequiredString")
.TypeName(typeof(string).FullName))
.Build(),
TagHelperDescriptorBuilder.CreateTagHelper("InputTagHelper2", "SomeAssembly")
.TagMatchingRuleDescriptor(rule => rule
.RequireTagName("input")
.RequireAttributeDescriptor(attribute => attribute.Name("bound-required-int")))
.BoundAttributeDescriptor(attribute => attribute
.Name("bound-required-int")
.PropertyName("BoundRequiredInt")
.TypeName(typeof(int).FullName))
.Build(),
TagHelperDescriptorBuilder.CreateTagHelper("InputTagHelper3", "SomeAssembly")
.TagMatchingRuleDescriptor(rule => rule.RequireTagName("input"))
.BoundAttributeDescriptor(attribute => attribute
.Name("int-dictionary")
.PropertyName("DictionaryOfIntProperty")
.TypeName(typeof(IDictionary<string, int>).Namespace + ".IDictionary<System.String, System.Int32>")
.AsDictionaryAttribute("int-prefix-", typeof(int).FullName))
.BoundAttributeDescriptor(attribute => attribute
.Name("string-dictionary")
.PropertyName("DictionaryOfStringProperty")
.TypeName(typeof(IDictionary<string, string>).Namespace + ".IDictionary<System.String, System.String>")
.AsDictionaryAttribute("string-prefix-", typeof(string).FullName))
.Build(),
TagHelperDescriptorBuilder.CreateTagHelper("PTagHelper", "SomeAssembly")
.TagMatchingRuleDescriptor(rule => rule.RequireTagName("p"))
.BoundAttributeDescriptor(attribute => attribute
.Name("bound-string")
.PropertyName("BoundRequiredString")
.TypeName(typeof(string).FullName))
.BoundAttributeDescriptor(attribute => attribute
.Name("bound-int")
.PropertyName("BoundRequiredString")
.TypeName(typeof(int).FullName))
.Build(),
];
[Fact]
public void UnderstandsMinimizedAttributes_Document1()
{
// Arrange
var document = "<input unbound-required />";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Document2()
{
// Arrange
var document = "<p bound-string></p>";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Document3()
{
// Arrange
var document = "<input bound-required-string />";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Document4()
{
// Arrange
var document = "<input bound-required-int />";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Document5()
{
// Arrange
var document = "<p bound-int></p>";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Document6()
{
// Arrange
var document = "<input int-dictionary/>";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Document7()
{
// Arrange
var document = "<input string-dictionary />";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Document8()
{
// Arrange
var document = "<input int-prefix- />";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Document9()
{
// Arrange
var document = "<input string-prefix-/>";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Document10()
{
// Arrange
var document = "<input int-prefix-value/>";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Document11()
{
// Arrange
var document = "<input string-prefix-value />";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Document12()
{
// Arrange
var document = "<input int-prefix-value='' />";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Document13()
{
// Arrange
var document = "<input string-prefix-value=''/>";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Document14()
{
// Arrange
var document = "<input int-prefix-value='3'/>";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Document15()
{
// Arrange
var document = "<input string-prefix-value='some string' />";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Document16()
{
// Arrange
var document = "<input unbound-required bound-required-string />";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Document17()
{
// Arrange
var document = "<p bound-int bound-string></p>";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Document18()
{
// Arrange
var document = "<input bound-required-int unbound-required bound-required-string />";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Document19()
{
// Arrange
var document = "<p bound-int bound-string bound-string></p>";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Document20()
{
// Arrange
var document = "<input unbound-required class='btn' />";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Document21()
{
// Arrange
var document = "<p bound-string class='btn'></p>";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Document22()
{
// Arrange
var document = "<input class='btn' unbound-required />";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Document23()
{
// Arrange
var document = "<p class='btn' bound-string></p>";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Document24()
{
// Arrange
var document = "<input bound-required-string class='btn' />";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Document25()
{
// Arrange
var document = "<input class='btn' bound-required-string />";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Document26()
{
// Arrange
var document = "<input bound-required-int class='btn' />";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Document27()
{
// Arrange
var document = "<p bound-int class='btn'></p>";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Document28()
{
// Arrange
var document = "<input class='btn' bound-required-int />";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Document29()
{
// Arrange
var document = "<p class='btn' bound-int></p>";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Document30()
{
// Arrange
var expressionString = "@DateTime.Now + 1";
var document = $"<input class='{expressionString}' bound-required-int />";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Document31()
{
// Arrange
var expressionString = "@DateTime.Now + 1";
var document = $"<p class='{expressionString}' bound-int></p>";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Document32()
{
// Arrange
var expressionString = "@DateTime.Now + 1";
var document = $"<input bound-required-int class='{expressionString}' bound-required-string class='{expressionString}' unbound-required />";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Document33()
{
// Arrange
var expressionString = "@DateTime.Now + 1";
var document = $"<p bound-int class='{expressionString}' bound-string class='{expressionString}' bound-string></p>";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Block1()
{
// Arrange
var document = "<input unbound-required />";
// Wrap in a CSharp block
document = $$"""@{{{document}}}""";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Block2()
{
// Arrange
var document = "<p bound-string></p>";
// Wrap in a CSharp block
document = $$"""@{{{document}}}""";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Block3()
{
// Arrange
var document = "<input bound-required-string />";
// Wrap in a CSharp block
document = $$"""@{{{document}}}""";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Block4()
{
// Arrange
var document = "<input bound-required-int />";
// Wrap in a CSharp block
document = $$"""@{{{document}}}""";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Block5()
{
// Arrange
var document = "<p bound-int></p>";
// Wrap in a CSharp block
document = $$"""@{{{document}}}""";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Block6()
{
// Arrange
var document = "<input int-dictionary/>";
// Wrap in a CSharp block
document = $$"""@{{{document}}}""";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Block7()
{
// Arrange
var document = "<input string-dictionary />";
// Wrap in a CSharp block
document = $$"""@{{{document}}}""";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Block8()
{
// Arrange
var document = "<input int-prefix- />";
// Wrap in a CSharp block
document = $$"""@{{{document}}}""";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Block9()
{
// Arrange
var document = "<input string-prefix-/>";
// Wrap in a CSharp block
document = $$"""@{{{document}}}""";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Block10()
{
// Arrange
var document = "<input int-prefix-value/>";
// Wrap in a CSharp block
document = $$"""@{{{document}}}""";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Block11()
{
// Arrange
var document = "<input string-prefix-value />";
// Wrap in a CSharp block
document = $$"""@{{{document}}}""";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Block12()
{
// Arrange
var document = "<input int-prefix-value='' />";
// Wrap in a CSharp block
document = $$"""@{{{document}}}""";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Block13()
{
// Arrange
var document = "<input string-prefix-value=''/>";
// Wrap in a CSharp block
document = $$"""@{{{document}}}""";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Block14()
{
// Arrange
var document = "<input int-prefix-value='3'/>";
// Wrap in a CSharp block
document = $$"""@{{{document}}}""";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Block15()
{
// Arrange
var document = "<input string-prefix-value='some string' />";
// Wrap in a CSharp block
document = $$"""@{{{document}}}""";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Block16()
{
// Arrange
var document = "<input unbound-required bound-required-string />";
// Wrap in a CSharp block
document = $$"""@{{{document}}}""";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Block17()
{
// Arrange
var document = "<p bound-int bound-string></p>";
// Wrap in a CSharp block
document = $$"""@{{{document}}}""";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Block18()
{
// Arrange
var document = "<input bound-required-int unbound-required bound-required-string />";
// Wrap in a CSharp block
document = $$"""@{{{document}}}""";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Block19()
{
// Arrange
var document = "<p bound-int bound-string bound-string></p>";
// Wrap in a CSharp block
document = $$"""@{{{document}}}""";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Block20()
{
// Arrange
var document = "<input unbound-required class='btn' />";
// Wrap in a CSharp block
document = $$"""@{{{document}}}""";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Block21()
{
// Arrange
var document = "<p bound-string class='btn'></p>";
// Wrap in a CSharp block
document = $$"""@{{{document}}}""";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Block22()
{
// Arrange
var document = "<input class='btn' unbound-required />";
// Wrap in a CSharp block
document = $$"""@{{{document}}}""";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Block23()
{
// Arrange
var document = "<p class='btn' bound-string></p>";
// Wrap in a CSharp block
document = $$"""@{{{document}}}""";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Block24()
{
// Arrange
var document = "<input bound-required-string class='btn' />";
// Wrap in a CSharp block
document = $$"""@{{{document}}}""";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Block25()
{
// Arrange
var document = "<input class='btn' bound-required-string />";
// Wrap in a CSharp block
document = $$"""@{{{document}}}""";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Block26()
{
// Arrange
var document = "<input bound-required-int class='btn' />";
// Wrap in a CSharp block
document = $$"""@{{{document}}}""";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Block27()
{
// Arrange
var document = "<p bound-int class='btn'></p>";
// Wrap in a CSharp block
document = $$"""@{{{document}}}""";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Block28()
{
// Arrange
var document = "<input class='btn' bound-required-int />";
// Wrap in a CSharp block
document = $$"""@{{{document}}}""";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Block29()
{
// Arrange
var document = "<p class='btn' bound-int></p>";
// Wrap in a CSharp block
document = $$"""@{{{document}}}""";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Block30()
{
// Arrange
var expressionString = "@DateTime.Now + 1";
var document = $"<input class='{expressionString}' bound-required-int />";
// Wrap in a CSharp block
document = $$"""@{{{document}}}""";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Block31()
{
// Arrange
var expressionString = "@DateTime.Now + 1";
var document = $"<p class='{expressionString}' bound-int></p>";
// Wrap in a CSharp block
document = $$"""@{{{document}}}""";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Block32()
{
// Arrange
var expressionString = "@DateTime.Now + 1";
var document = $"<input bound-required-int class='{expressionString}' bound-required-string class='{expressionString}' unbound-required />";
// Wrap in a CSharp block
document = $$"""@{{{document}}}""";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_Block33()
{
// Arrange
var expressionString = "@DateTime.Now + 1";
var document = $"<p bound-int class='{expressionString}' bound-string class='{expressionString}' bound-string></p>";
// Wrap in a CSharp block
document = $$"""@{{{document}}}""";
// Act & Assert
EvaluateData(MinimizedAttribute_TagHelpers, document);
}
[Fact]
public void UnderstandsMinimizedAttributes_PartialTags1()
{
EvaluateData(MinimizedAttribute_TagHelpers, "<input unbound-required");
}
[Fact]
public void UnderstandsMinimizedAttributes_PartialTags2()
{
EvaluateData(MinimizedAttribute_TagHelpers, "<input bound-required-string");
}
[Fact]
public void UnderstandsMinimizedAttributes_PartialTags3()
{
EvaluateData(MinimizedAttribute_TagHelpers, "<input bound-required-int");
}
[Fact]
public void UnderstandsMinimizedAttributes_PartialTags4()
{
EvaluateData(MinimizedAttribute_TagHelpers, "<input bound-required-int unbound-required bound-required-string");
}
[Fact]
public void UnderstandsMinimizedAttributes_PartialTags5()
{
EvaluateData(MinimizedAttribute_TagHelpers, "<p bound-string");
}
[Fact]
public void UnderstandsMinimizedAttributes_PartialTags6()
{
EvaluateData(MinimizedAttribute_TagHelpers, "<p bound-int");
}
[Fact]
public void UnderstandsMinimizedAttributes_PartialTags7()
{
EvaluateData(MinimizedAttribute_TagHelpers, "<p bound-int bound-string");
}
[Fact]
public void UnderstandsMinimizedAttributes_PartialTags8()
{
EvaluateData(MinimizedAttribute_TagHelpers, "<input bound-required-int unbound-required bound-required-string<p bound-int bound-string");
}
[Fact]
public void UnderstandsMinimizedBooleanBoundAttributes()
{
// Arrange
var document = "<input boundbool boundbooldict-key />";
TagHelperCollection tagHelpers =
[
TagHelperDescriptorBuilder.CreateTagHelper("InputTagHelper", "SomeAssembly")
.TagMatchingRuleDescriptor(rule => rule
.RequireTagName("input"))
.BoundAttributeDescriptor(attribute => attribute
.Name("boundbool")
.PropertyName("BoundBoolProp")
.TypeName(typeof(bool).FullName))
.BoundAttributeDescriptor(attribute => attribute
.Name("boundbooldict")
.PropertyName("BoundBoolDictProp")
.TypeName("System.Collections.Generic.IDictionary<string, bool>")
.AsDictionary("boundbooldict-", typeof(bool).FullName))
.Build(),
];
// Act & Assert
EvaluateData(tagHelpers, document);
}
[Fact]
public void FeatureDisabled_AddsErrorForMinimizedBooleanBoundAttributes()
{
// Arrange
var document = "<input boundbool boundbooldict-key />";
TagHelperCollection tagHelpers =
[
TagHelperDescriptorBuilder.CreateTagHelper("InputTagHelper", "SomeAssembly")
.TagMatchingRuleDescriptor(rule => rule
.RequireTagName("input"))
.BoundAttributeDescriptor(attribute => attribute
.Name("boundbool")
.PropertyName("BoundBoolProp")
.TypeName(typeof(bool).FullName))
.BoundAttributeDescriptor(attribute => attribute
.Name("boundbooldict")
.PropertyName("BoundBoolDictProp")
.TypeName("System.Collections.Generic.IDictionary<string, bool>")
.AsDictionary("boundbooldict-", typeof(bool).FullName))
.Build(),
];
// Act & Assert
EvaluateData(tagHelpers, document, languageVersion: RazorLanguageVersion.Version_2_0, fileKind: RazorFileKind.Legacy);
}
[Fact]
public void Rewrites_ComponentDirectiveAttributes()
{
// Arrange
var document = @"<input @bind-value=""Message"" @bind-value:event=""onchange"" />";
TagHelperCollection tagHelpers =
[
TagHelperDescriptorBuilder.Create(TagHelperKind.Bind, "Bind", ComponentsApi.AssemblyName)
.TypeName(
fullName: "Microsoft.AspNetCore.Components.Bind",
typeNamespace: "Microsoft.AspNetCore.Components",
typeNameIdentifier: "Bind")
.ClassifyAttributesOnly(true)
.Metadata(new BindMetadata()
{
IsFallback = true
})
.TagMatchingRuleDescriptor(rule => rule
.RequireTagName("*")
.RequireAttributeDescriptor(attribute => attribute
.Name("@bind-", RequiredAttributeNameComparison.PrefixMatch)
.IsDirectiveAttribute()))
.BoundAttributeDescriptor(attribute => attribute
.Name("@bind-...")
.PropertyName("Bind")
.AsDictionaryAttribute("@bind-", typeof(object).FullName)
.TypeName("System.Collections.Generic.Dictionary<string, object>")
.IsDirectiveAttribute()
.BindAttributeParameter(p =>
{
p.Name = "event";
p.PropertyName = "Event";
p.TypeName = typeof(string).FullName;
}))
.Build(),
];
// Act & Assert
EvaluateData(tagHelpers, document, configureParserOptions: builder =>
{
builder.AllowCSharpInMarkupAttributeArea = false;
});
}
[Fact]
public void Rewrites_MinimizedComponentDirectiveAttributes()
{
// Arrange
var document = @"<input @bind-foo @bind-foo:param />";
TagHelperCollection tagHelpers =
[
TagHelperDescriptorBuilder.Create(TagHelperKind.Bind, "Bind", ComponentsApi.AssemblyName)
.TypeName(
fullName: "Microsoft.AspNetCore.Components.Bind",
typeNamespace: "Microsoft.AspNetCore.Components",
typeNameIdentifier: "Bind")
.ClassifyAttributesOnly(true)
.Metadata(new BindMetadata()
{
IsFallback = true
})
.TagMatchingRuleDescriptor(rule => rule
.RequireTagName("*")
.RequireAttributeDescriptor(attribute => attribute
.Name("@bind-", RequiredAttributeNameComparison.PrefixMatch)
.IsDirectiveAttribute()))
.BoundAttributeDescriptor(attribute => attribute
.Name("@bind-...")
.PropertyName("Bind")
.AsDictionaryAttribute("@bind-", typeof(object).FullName)
.TypeName("System.Collections.Generic.Dictionary<string, object>")
.IsDirectiveAttribute()
.BindAttributeParameter(p =>
{
p.Name = "param";
p.PropertyName = "Param";
p.TypeName = typeof(string).FullName;
}))
.Build(),
];
// Act & Assert
EvaluateData(tagHelpers, document, configureParserOptions: builder =>
{
builder.AllowCSharpInMarkupAttributeArea = false;
});
}
}
|