Add tests to validate TagHelper attribute targeting.
- Added tests to validate TargetElementAttribute, TagHelperDescriptorFactory, CSharpTagHelperCodeRenderer and TagHelperParseTreeRewriterTests. - Renamed HtmlElementNameAttributeTest to TargetElementAttributeTest. #311
This commit is contained in:
parent
d22246f636
commit
4345b06e88
|
|
@ -0,0 +1,89 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNet.Razor.TagHelpers;
|
||||
using Microsoft.Internal.Web.Utils;
|
||||
|
||||
namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||
{
|
||||
public class CaseSensitiveTagHelperDescriptorComparer : TagHelperDescriptorComparer, IEqualityComparer<TagHelperDescriptor>
|
||||
{
|
||||
public new static readonly CaseSensitiveTagHelperDescriptorComparer Default =
|
||||
new CaseSensitiveTagHelperDescriptorComparer();
|
||||
|
||||
private CaseSensitiveTagHelperDescriptorComparer()
|
||||
{
|
||||
}
|
||||
|
||||
bool IEqualityComparer<TagHelperDescriptor>.Equals(
|
||||
TagHelperDescriptor descriptorX,
|
||||
TagHelperDescriptor descriptorY)
|
||||
{
|
||||
return base.Equals(descriptorX, descriptorY) &&
|
||||
// Normal comparer doesn't care about the case, required attribute order, attributes or prefixes.
|
||||
// In tests we do.
|
||||
string.Equals(descriptorX.TagName, descriptorY.TagName, StringComparison.Ordinal) &&
|
||||
string.Equals(descriptorX.Prefix, descriptorY.Prefix, StringComparison.Ordinal) &&
|
||||
Enumerable.SequenceEqual(
|
||||
descriptorX.RequiredAttributes,
|
||||
descriptorY.RequiredAttributes,
|
||||
StringComparer.Ordinal) &&
|
||||
descriptorX.Attributes.SequenceEqual(
|
||||
descriptorY.Attributes,
|
||||
CaseSensitiveAttributeDescriptorComparer.Default);
|
||||
}
|
||||
|
||||
int IEqualityComparer<TagHelperDescriptor>.GetHashCode(TagHelperDescriptor descriptor)
|
||||
{
|
||||
var hashCodeCombiner = HashCodeCombiner
|
||||
.Start()
|
||||
.Add(base.GetHashCode())
|
||||
.Add(descriptor.TagName, StringComparer.Ordinal)
|
||||
.Add(descriptor.Prefix);
|
||||
|
||||
foreach (var requiredAttribute in descriptor.RequiredAttributes)
|
||||
{
|
||||
hashCodeCombiner.Add(requiredAttribute, StringComparer.Ordinal);
|
||||
}
|
||||
|
||||
foreach (var attribute in descriptor.Attributes)
|
||||
{
|
||||
hashCodeCombiner.Add(CaseSensitiveAttributeDescriptorComparer.Default.GetHashCode(attribute));
|
||||
}
|
||||
|
||||
return hashCodeCombiner.CombinedHash;
|
||||
}
|
||||
|
||||
private class CaseSensitiveAttributeDescriptorComparer : IEqualityComparer<TagHelperAttributeDescriptor>
|
||||
{
|
||||
public static readonly CaseSensitiveAttributeDescriptorComparer Default =
|
||||
new CaseSensitiveAttributeDescriptorComparer();
|
||||
|
||||
private CaseSensitiveAttributeDescriptorComparer()
|
||||
{
|
||||
}
|
||||
|
||||
public bool Equals(TagHelperAttributeDescriptor descriptorX, TagHelperAttributeDescriptor descriptorY)
|
||||
{
|
||||
return
|
||||
// Normal comparer doesn't care about case, in tests we do.
|
||||
string.Equals(descriptorX.Name, descriptorY.Name, StringComparison.Ordinal) &&
|
||||
string.Equals(descriptorX.PropertyName, descriptorY.PropertyName, StringComparison.Ordinal) &&
|
||||
string.Equals(descriptorX.TypeName, descriptorY.TypeName, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
public int GetHashCode(TagHelperAttributeDescriptor descriptor)
|
||||
{
|
||||
return HashCodeCombiner
|
||||
.Start()
|
||||
.Add(descriptor.Name, StringComparer.Ordinal)
|
||||
.Add(descriptor.PropertyName, StringComparer.Ordinal)
|
||||
.Add(descriptor.TypeName, StringComparer.Ordinal)
|
||||
.CombinedHash;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNet.Razor.TagHelpers;
|
||||
using Microsoft.Internal.Web.Utils;
|
||||
|
||||
namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||
{
|
||||
public class CompleteTagHelperDescriptorComparer : TagHelperDescriptorComparer, IEqualityComparer<TagHelperDescriptor>
|
||||
{
|
||||
public new static readonly CompleteTagHelperDescriptorComparer Default =
|
||||
new CompleteTagHelperDescriptorComparer();
|
||||
|
||||
private CompleteTagHelperDescriptorComparer()
|
||||
{
|
||||
}
|
||||
|
||||
bool IEqualityComparer<TagHelperDescriptor>.Equals(TagHelperDescriptor descriptorX, TagHelperDescriptor descriptorY)
|
||||
{
|
||||
return base.Equals(descriptorX, descriptorY) &&
|
||||
// Tests should be exact casing
|
||||
string.Equals(descriptorX.TagName, descriptorY.TagName, StringComparison.Ordinal) &&
|
||||
descriptorX.Attributes.SequenceEqual(descriptorY.Attributes,
|
||||
CompleteTagHelperAttributeDescriptorComparer.Default);
|
||||
}
|
||||
|
||||
int IEqualityComparer<TagHelperDescriptor>.GetHashCode(TagHelperDescriptor descriptor)
|
||||
{
|
||||
return HashCodeCombiner.Start()
|
||||
.Add(base.GetHashCode())
|
||||
.Add(descriptor.Attributes)
|
||||
.CombinedHash;
|
||||
}
|
||||
|
||||
private class CompleteTagHelperAttributeDescriptorComparer : IEqualityComparer<TagHelperAttributeDescriptor>
|
||||
{
|
||||
public static readonly CompleteTagHelperAttributeDescriptorComparer Default =
|
||||
new CompleteTagHelperAttributeDescriptorComparer();
|
||||
|
||||
private CompleteTagHelperAttributeDescriptorComparer()
|
||||
{
|
||||
}
|
||||
|
||||
public bool Equals(TagHelperAttributeDescriptor descriptorX, TagHelperAttributeDescriptor descriptorY)
|
||||
{
|
||||
return string.Equals(descriptorX.Name, descriptorY.Name, StringComparison.Ordinal) &&
|
||||
string.Equals(descriptorX.PropertyName, descriptorY.PropertyName, StringComparison.Ordinal) &&
|
||||
string.Equals(descriptorX.TypeName, descriptorY.TypeName, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
public int GetHashCode(TagHelperAttributeDescriptor descriptor)
|
||||
{
|
||||
return HashCodeCombiner.Start()
|
||||
.Add(descriptor.Name, StringComparer.Ordinal)
|
||||
.Add(descriptor.PropertyName, StringComparer.Ordinal)
|
||||
.Add(descriptor.TypeName, StringComparer.Ordinal)
|
||||
.CombinedHash;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||
{
|
||||
public class HtmlElementNameAttributeTest
|
||||
{
|
||||
public static TheoryData InvalidTagNameData
|
||||
{
|
||||
get
|
||||
{
|
||||
var invalidTagNameError =
|
||||
"Tag helpers cannot target element name '{0}' because it contains a '{1}' character.";
|
||||
var nullOrWhitespaceTagNameError =
|
||||
"Tag name cannot be null or whitespace.";
|
||||
|
||||
// tagName, expectedExceptionMessage
|
||||
return new TheoryData<string, string>
|
||||
{
|
||||
{ "!", string.Format(invalidTagNameError, "!", "!") },
|
||||
{ "hello!", string.Format(invalidTagNameError, "hello!", "!") },
|
||||
{ "!hello", string.Format(invalidTagNameError, "!hello", "!") },
|
||||
{ "he!lo", string.Format(invalidTagNameError, "he!lo", "!") },
|
||||
{ "!he!lo!", string.Format(invalidTagNameError, "!he!lo!", "!") },
|
||||
{ string.Empty, nullOrWhitespaceTagNameError },
|
||||
{ Environment.NewLine, nullOrWhitespaceTagNameError },
|
||||
{ "\t", nullOrWhitespaceTagNameError },
|
||||
{ " \t ", nullOrWhitespaceTagNameError },
|
||||
{ " ", nullOrWhitespaceTagNameError },
|
||||
{ Environment.NewLine + " ", nullOrWhitespaceTagNameError },
|
||||
{ null, nullOrWhitespaceTagNameError },
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(InvalidTagNameData))]
|
||||
public void SingleArgumentConstructor_ThrowsOnInvalidTagNames(
|
||||
string tagName,
|
||||
string expectedExceptionMessage)
|
||||
{
|
||||
// Arrange
|
||||
expectedExceptionMessage += Environment.NewLine + "Parameter name: tag";
|
||||
|
||||
// Act & Assert
|
||||
var exception = Assert.Throws<ArgumentException>(
|
||||
"tag",
|
||||
() => new HtmlElementNameAttribute(tagName));
|
||||
Assert.Equal(exception.Message, expectedExceptionMessage);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(InvalidTagNameData))]
|
||||
public void MultipleArgumentConstructor_ThrowsOnInvalidTagNames(
|
||||
string tagName,
|
||||
string expectedExceptionMessage)
|
||||
{
|
||||
// Arrange
|
||||
expectedExceptionMessage += Environment.NewLine + "Parameter name: additionalTags";
|
||||
|
||||
// Act & Assert
|
||||
var exception = Assert.Throws<ArgumentException>(
|
||||
"additionalTags",
|
||||
() => new HtmlElementNameAttribute("p", "div", "span", tagName));
|
||||
Assert.Equal(exception.Message, expectedExceptionMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,8 +2,12 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Microsoft.AspNet.Razor.Parser;
|
||||
using Microsoft.AspNet.Razor.TagHelpers;
|
||||
using Microsoft.AspNet.Razor.Text;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||
|
|
@ -13,6 +17,183 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
private static readonly string AssemblyName =
|
||||
typeof(TagHelperDescriptorFactoryTest).GetTypeInfo().Assembly.GetName().Name;
|
||||
|
||||
public static TheoryData AttributeTargetData
|
||||
{
|
||||
get
|
||||
{
|
||||
var attributes = Enumerable.Empty<TagHelperAttributeDescriptor>();
|
||||
|
||||
// tagHelperType, expectedDescriptors
|
||||
return new TheoryData<Type, IEnumerable<TagHelperDescriptor>>
|
||||
{
|
||||
{
|
||||
typeof(AttributeTargetingTagHelper),
|
||||
new[]
|
||||
{
|
||||
new TagHelperDescriptor(
|
||||
TagHelperDescriptorProvider.CatchAllDescriptorTarget,
|
||||
typeof(AttributeTargetingTagHelper).FullName,
|
||||
AssemblyName,
|
||||
attributes,
|
||||
requiredAttributes: new[] { "class" })
|
||||
}
|
||||
},
|
||||
{
|
||||
typeof(MultiAttributeTargetingTagHelper),
|
||||
new[]
|
||||
{
|
||||
new TagHelperDescriptor(
|
||||
TagHelperDescriptorProvider.CatchAllDescriptorTarget,
|
||||
typeof(MultiAttributeTargetingTagHelper).FullName,
|
||||
AssemblyName,
|
||||
attributes,
|
||||
requiredAttributes: new[] { "class", "style" })
|
||||
}
|
||||
},
|
||||
{
|
||||
typeof(MultiAttributeAttributeTargetingTagHelper),
|
||||
new[]
|
||||
{
|
||||
new TagHelperDescriptor(
|
||||
TagHelperDescriptorProvider.CatchAllDescriptorTarget,
|
||||
typeof(MultiAttributeAttributeTargetingTagHelper).FullName,
|
||||
AssemblyName,
|
||||
attributes,
|
||||
requiredAttributes: new[] { "custom" }),
|
||||
new TagHelperDescriptor(
|
||||
TagHelperDescriptorProvider.CatchAllDescriptorTarget,
|
||||
typeof(MultiAttributeAttributeTargetingTagHelper).FullName,
|
||||
AssemblyName,
|
||||
attributes,
|
||||
requiredAttributes: new[] { "class", "style" })
|
||||
}
|
||||
},
|
||||
{
|
||||
typeof(InheritedAttributeTargetingTagHelper),
|
||||
new[]
|
||||
{
|
||||
new TagHelperDescriptor(
|
||||
TagHelperDescriptorProvider.CatchAllDescriptorTarget,
|
||||
typeof(InheritedAttributeTargetingTagHelper).FullName,
|
||||
AssemblyName,
|
||||
attributes,
|
||||
requiredAttributes: new[] { "style" })
|
||||
}
|
||||
},
|
||||
{
|
||||
typeof(RequiredAttributeTagHelper),
|
||||
new[]
|
||||
{
|
||||
new TagHelperDescriptor(
|
||||
"input",
|
||||
typeof(RequiredAttributeTagHelper).FullName,
|
||||
AssemblyName,
|
||||
attributes,
|
||||
requiredAttributes: new[] { "class" })
|
||||
}
|
||||
},
|
||||
{
|
||||
typeof(InheritedRequiredAttributeTagHelper),
|
||||
new[]
|
||||
{
|
||||
new TagHelperDescriptor(
|
||||
"div",
|
||||
typeof(InheritedRequiredAttributeTagHelper).FullName,
|
||||
AssemblyName,
|
||||
attributes,
|
||||
requiredAttributes: new[] { "class" })
|
||||
}
|
||||
},
|
||||
{
|
||||
typeof(MultiAttributeRequiredAttributeTagHelper),
|
||||
new[]
|
||||
{
|
||||
new TagHelperDescriptor(
|
||||
"div",
|
||||
typeof(MultiAttributeRequiredAttributeTagHelper).FullName,
|
||||
AssemblyName,
|
||||
attributes,
|
||||
requiredAttributes: new[] { "class" }),
|
||||
new TagHelperDescriptor(
|
||||
"input",
|
||||
typeof(MultiAttributeRequiredAttributeTagHelper).FullName,
|
||||
AssemblyName,
|
||||
attributes,
|
||||
requiredAttributes: new[] { "class" })
|
||||
}
|
||||
},
|
||||
{
|
||||
typeof(MultiAttributeSameTagRequiredAttributeTagHelper),
|
||||
new[]
|
||||
{
|
||||
new TagHelperDescriptor(
|
||||
"input",
|
||||
typeof(MultiAttributeSameTagRequiredAttributeTagHelper).FullName,
|
||||
AssemblyName,
|
||||
attributes,
|
||||
requiredAttributes: new[] { "style" }),
|
||||
new TagHelperDescriptor(
|
||||
"input",
|
||||
typeof(MultiAttributeSameTagRequiredAttributeTagHelper).FullName,
|
||||
AssemblyName,
|
||||
attributes,
|
||||
requiredAttributes: new[] { "class" })
|
||||
}
|
||||
},
|
||||
{
|
||||
typeof(MultiRequiredAttributeTagHelper),
|
||||
new[]
|
||||
{
|
||||
new TagHelperDescriptor(
|
||||
"input",
|
||||
typeof(MultiRequiredAttributeTagHelper).FullName,
|
||||
AssemblyName,
|
||||
attributes,
|
||||
requiredAttributes: new[] { "class", "style" })
|
||||
}
|
||||
},
|
||||
{
|
||||
typeof(MultiTagMultiRequiredAttributeTagHelper),
|
||||
new[]
|
||||
{
|
||||
new TagHelperDescriptor(
|
||||
"div",
|
||||
typeof(MultiTagMultiRequiredAttributeTagHelper).FullName,
|
||||
AssemblyName,
|
||||
attributes,
|
||||
requiredAttributes: new[] { "class", "style" }),
|
||||
new TagHelperDescriptor(
|
||||
"input",
|
||||
typeof(MultiTagMultiRequiredAttributeTagHelper).FullName,
|
||||
AssemblyName,
|
||||
attributes,
|
||||
requiredAttributes: new[] { "class", "style" }),
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(AttributeTargetData))]
|
||||
public void CreateDescriptors_ReturnsExpectedDescriptors(
|
||||
Type tagHelperType,
|
||||
IEnumerable<TagHelperDescriptor> expectedDescriptors)
|
||||
{
|
||||
// Arrange
|
||||
var errorSink = new ParserErrorSink();
|
||||
|
||||
// Act
|
||||
var descriptors = TagHelperDescriptorFactory.CreateDescriptors(
|
||||
AssemblyName,
|
||||
tagHelperType,
|
||||
errorSink);
|
||||
|
||||
// Assert
|
||||
Assert.Empty(errorSink.Errors);
|
||||
Assert.Equal(expectedDescriptors, descriptors, CaseSensitiveTagHelperDescriptorComparer.Default);
|
||||
}
|
||||
|
||||
public static TheoryData HtmlCaseData
|
||||
{
|
||||
get
|
||||
|
|
@ -39,10 +220,17 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
string expectedTagName,
|
||||
string expectedAttributeName)
|
||||
{
|
||||
// Arrange & Act
|
||||
var descriptors = TagHelperDescriptorFactory.CreateDescriptors(AssemblyName, tagHelperType);
|
||||
// Arrange
|
||||
var errorSink = new ParserErrorSink();
|
||||
|
||||
// Act
|
||||
var descriptors = TagHelperDescriptorFactory.CreateDescriptors(
|
||||
AssemblyName,
|
||||
tagHelperType,
|
||||
errorSink);
|
||||
|
||||
// Assert
|
||||
Assert.Empty(errorSink.Errors);
|
||||
var descriptor = Assert.Single(descriptors);
|
||||
Assert.Equal(expectedTagName, descriptor.TagName, StringComparer.Ordinal);
|
||||
var attributeDescriptor = Assert.Single(descriptor.Attributes);
|
||||
|
|
@ -53,6 +241,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
public void CreateDescriptor_OverridesAttributeNameFromAttribute()
|
||||
{
|
||||
// Arrange
|
||||
var errorSink = new ParserErrorSink();
|
||||
var validProperty1 = typeof(OverriddenAttributeTagHelper).GetProperty(
|
||||
nameof(OverriddenAttributeTagHelper.ValidAttribute1));
|
||||
var validProperty2 = typeof(OverriddenAttributeTagHelper).GetProperty(
|
||||
|
|
@ -69,17 +258,21 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
};
|
||||
|
||||
// Act
|
||||
var descriptors = TagHelperDescriptorFactory.CreateDescriptors(AssemblyName,
|
||||
typeof(OverriddenAttributeTagHelper));
|
||||
var descriptors = TagHelperDescriptorFactory.CreateDescriptors(
|
||||
AssemblyName,
|
||||
typeof(OverriddenAttributeTagHelper),
|
||||
errorSink);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expectedDescriptors, descriptors, CompleteTagHelperDescriptorComparer.Default);
|
||||
Assert.Empty(errorSink.Errors);
|
||||
Assert.Equal(expectedDescriptors, descriptors, CaseSensitiveTagHelperDescriptorComparer.Default);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreateDescriptor_DoesNotInheritOverridenAttributeName()
|
||||
{
|
||||
// Arrange
|
||||
var errorSink = new ParserErrorSink();
|
||||
var validProperty1 = typeof(InheritedOverriddenAttributeTagHelper).GetProperty(
|
||||
nameof(InheritedOverriddenAttributeTagHelper.ValidAttribute1));
|
||||
var validProperty2 = typeof(InheritedOverriddenAttributeTagHelper).GetProperty(
|
||||
|
|
@ -97,17 +290,21 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
};
|
||||
|
||||
// Act
|
||||
var descriptors = TagHelperDescriptorFactory.CreateDescriptors(AssemblyName,
|
||||
typeof(InheritedOverriddenAttributeTagHelper));
|
||||
var descriptors = TagHelperDescriptorFactory.CreateDescriptors(
|
||||
AssemblyName,
|
||||
typeof(InheritedOverriddenAttributeTagHelper),
|
||||
errorSink);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expectedDescriptors, descriptors, CompleteTagHelperDescriptorComparer.Default);
|
||||
Assert.Empty(errorSink.Errors);
|
||||
Assert.Equal(expectedDescriptors, descriptors, CaseSensitiveTagHelperDescriptorComparer.Default);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreateDescriptor_AllowsOverridenAttributeNameOnUnimplementedVirtual()
|
||||
{
|
||||
// Arrange
|
||||
var errorSink = new ParserErrorSink();
|
||||
var validProperty1 = typeof(InheritedNotOverriddenAttributeTagHelper).GetProperty(
|
||||
nameof(InheritedNotOverriddenAttributeTagHelper.ValidAttribute1));
|
||||
var validProperty2 = typeof(InheritedNotOverriddenAttributeTagHelper).GetProperty(
|
||||
|
|
@ -124,33 +321,42 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
};
|
||||
|
||||
// Act
|
||||
var descriptors = TagHelperDescriptorFactory.CreateDescriptors(AssemblyName,
|
||||
typeof(InheritedNotOverriddenAttributeTagHelper));
|
||||
var descriptors = TagHelperDescriptorFactory.CreateDescriptors(
|
||||
AssemblyName,
|
||||
typeof(InheritedNotOverriddenAttributeTagHelper),
|
||||
errorSink);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expectedDescriptors, descriptors, CompleteTagHelperDescriptorComparer.Default);
|
||||
Assert.Empty(errorSink.Errors);
|
||||
Assert.Equal(expectedDescriptors, descriptors, CaseSensitiveTagHelperDescriptorComparer.Default);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreateDescriptor_BuildsDescriptorsFromSimpleTypes()
|
||||
{
|
||||
// Arrange
|
||||
var errorSink = new ParserErrorSink();
|
||||
var objectAssemblyName = typeof(object).GetTypeInfo().Assembly.GetName().Name;
|
||||
var expectedDescriptor =
|
||||
new TagHelperDescriptor("object", "System.Object", objectAssemblyName);
|
||||
|
||||
// Act
|
||||
var descriptors = TagHelperDescriptorFactory.CreateDescriptors(objectAssemblyName, typeof(object));
|
||||
var descriptors = TagHelperDescriptorFactory.CreateDescriptors(
|
||||
objectAssemblyName,
|
||||
typeof(object),
|
||||
errorSink);
|
||||
|
||||
// Assert
|
||||
Assert.Empty(errorSink.Errors);
|
||||
var descriptor = Assert.Single(descriptors);
|
||||
Assert.Equal(expectedDescriptor, descriptor, CompleteTagHelperDescriptorComparer.Default);
|
||||
Assert.Equal(expectedDescriptor, descriptor, CaseSensitiveTagHelperDescriptorComparer.Default);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreateDescriptor_BuildsDescriptorsWithInheritedProperties()
|
||||
{
|
||||
// Arrange
|
||||
var errorSink = new ParserErrorSink();
|
||||
var intProperty = typeof(InheritedSingleAttributeTagHelper).GetProperty(
|
||||
nameof(InheritedSingleAttributeTagHelper.IntAttribute));
|
||||
var expectedDescriptor = new TagHelperDescriptor(
|
||||
|
|
@ -162,18 +368,22 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
});
|
||||
|
||||
// Act
|
||||
var descriptors = TagHelperDescriptorFactory.CreateDescriptors(AssemblyName,
|
||||
typeof(InheritedSingleAttributeTagHelper));
|
||||
var descriptors = TagHelperDescriptorFactory.CreateDescriptors(
|
||||
AssemblyName,
|
||||
typeof(InheritedSingleAttributeTagHelper),
|
||||
errorSink);
|
||||
|
||||
// Assert
|
||||
Assert.Empty(errorSink.Errors);
|
||||
var descriptor = Assert.Single(descriptors);
|
||||
Assert.Equal(expectedDescriptor, descriptor, CompleteTagHelperDescriptorComparer.Default);
|
||||
Assert.Equal(expectedDescriptor, descriptor, CaseSensitiveTagHelperDescriptorComparer.Default);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreateDescriptor_BuildsDescriptorsWithConventionNames()
|
||||
{
|
||||
// Arrange
|
||||
var errorSink = new ParserErrorSink();
|
||||
var intProperty = typeof(SingleAttributeTagHelper).GetProperty(nameof(SingleAttributeTagHelper.IntAttribute));
|
||||
var expectedDescriptor = new TagHelperDescriptor(
|
||||
"single-attribute",
|
||||
|
|
@ -184,18 +394,22 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
});
|
||||
|
||||
// Act
|
||||
var descriptors = TagHelperDescriptorFactory.CreateDescriptors(AssemblyName,
|
||||
typeof(SingleAttributeTagHelper));
|
||||
var descriptors = TagHelperDescriptorFactory.CreateDescriptors(
|
||||
AssemblyName,
|
||||
typeof(SingleAttributeTagHelper),
|
||||
new ParserErrorSink());
|
||||
|
||||
// Assert
|
||||
Assert.Empty(errorSink.Errors);
|
||||
var descriptor = Assert.Single(descriptors);
|
||||
Assert.Equal(expectedDescriptor, descriptor, CompleteTagHelperDescriptorComparer.Default);
|
||||
Assert.Equal(expectedDescriptor, descriptor, CaseSensitiveTagHelperDescriptorComparer.Default);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreateDescriptor_OnlyAcceptsPropertiesWithGetAndSet()
|
||||
{
|
||||
// Arrange
|
||||
var errorSink = new ParserErrorSink();
|
||||
var validProperty = typeof(MissingAccessorTagHelper).GetProperty(
|
||||
nameof(MissingAccessorTagHelper.ValidAttribute));
|
||||
var expectedDescriptor = new TagHelperDescriptor(
|
||||
|
|
@ -207,18 +421,22 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
});
|
||||
|
||||
// Act
|
||||
var descriptors = TagHelperDescriptorFactory.CreateDescriptors(AssemblyName,
|
||||
typeof(MissingAccessorTagHelper));
|
||||
var descriptors = TagHelperDescriptorFactory.CreateDescriptors(
|
||||
AssemblyName,
|
||||
typeof(MissingAccessorTagHelper),
|
||||
errorSink);
|
||||
|
||||
// Assert
|
||||
Assert.Empty(errorSink.Errors);
|
||||
var descriptor = Assert.Single(descriptors);
|
||||
Assert.Equal(expectedDescriptor, descriptor, CompleteTagHelperDescriptorComparer.Default);
|
||||
Assert.Equal(expectedDescriptor, descriptor, CaseSensitiveTagHelperDescriptorComparer.Default);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreateDescriptor_OnlyAcceptsPropertiesWithPublicGetAndSet()
|
||||
{
|
||||
// Arrange
|
||||
var errorSink = new ParserErrorSink();
|
||||
var validProperty = typeof(PrivateAccessorTagHelper).GetProperty(
|
||||
nameof(PrivateAccessorTagHelper.ValidAttribute));
|
||||
var expectedDescriptor = new TagHelperDescriptor(
|
||||
|
|
@ -231,29 +449,33 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
});
|
||||
|
||||
// Act
|
||||
var descriptors = TagHelperDescriptorFactory.CreateDescriptors(AssemblyName,
|
||||
typeof(PrivateAccessorTagHelper));
|
||||
var descriptors = TagHelperDescriptorFactory.CreateDescriptors(
|
||||
AssemblyName,
|
||||
typeof(PrivateAccessorTagHelper),
|
||||
errorSink);
|
||||
|
||||
// Assert
|
||||
Assert.Empty(errorSink.Errors);
|
||||
var descriptor = Assert.Single(descriptors);
|
||||
Assert.Equal(expectedDescriptor, descriptor, CompleteTagHelperDescriptorComparer.Default);
|
||||
Assert.Equal(expectedDescriptor, descriptor, CaseSensitiveTagHelperDescriptorComparer.Default);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreateDescriptor_ResolvesMultipleTagHelperDescriptorsFromSingleType()
|
||||
{
|
||||
// Arrange
|
||||
var errorSink = new ParserErrorSink();
|
||||
var validProp = typeof(MultiTagTagHelper).GetProperty(nameof(MultiTagTagHelper.ValidAttribute));
|
||||
var expectedDescriptors = new[] {
|
||||
new TagHelperDescriptor(
|
||||
"div",
|
||||
"p",
|
||||
typeof(MultiTagTagHelper).FullName,
|
||||
AssemblyName,
|
||||
new[] {
|
||||
new TagHelperAttributeDescriptor("valid-attribute", validProp)
|
||||
}),
|
||||
new TagHelperDescriptor(
|
||||
"p",
|
||||
"div",
|
||||
typeof(MultiTagTagHelper).FullName,
|
||||
AssemblyName,
|
||||
new[] {
|
||||
|
|
@ -262,16 +484,21 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
};
|
||||
|
||||
// Act
|
||||
var descriptors = TagHelperDescriptorFactory.CreateDescriptors(AssemblyName, typeof(MultiTagTagHelper));
|
||||
var descriptors = TagHelperDescriptorFactory.CreateDescriptors(
|
||||
AssemblyName,
|
||||
typeof(MultiTagTagHelper),
|
||||
errorSink);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expectedDescriptors, descriptors, CompleteTagHelperDescriptorComparer.Default);
|
||||
Assert.Empty(errorSink.Errors);
|
||||
Assert.Equal(expectedDescriptors, descriptors, CaseSensitiveTagHelperDescriptorComparer.Default);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreateDescriptor_DoesntResolveInheritedTagNames()
|
||||
{
|
||||
// Arrange
|
||||
var errorSink = new ParserErrorSink();
|
||||
var validProp = typeof(InheritedMultiTagTagHelper).GetProperty(nameof(InheritedMultiTagTagHelper.ValidAttribute));
|
||||
var expectedDescriptor = new TagHelperDescriptor(
|
||||
"inherited-multi-tag",
|
||||
|
|
@ -282,18 +509,22 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
});
|
||||
|
||||
// Act
|
||||
var descriptors = TagHelperDescriptorFactory.CreateDescriptors(AssemblyName,
|
||||
typeof(InheritedMultiTagTagHelper));
|
||||
var descriptors = TagHelperDescriptorFactory.CreateDescriptors(
|
||||
AssemblyName,
|
||||
typeof(InheritedMultiTagTagHelper),
|
||||
errorSink);
|
||||
|
||||
// Assert
|
||||
Assert.Empty(errorSink.Errors);
|
||||
var descriptor = Assert.Single(descriptors);
|
||||
Assert.Equal(expectedDescriptor, descriptor, CompleteTagHelperDescriptorComparer.Default);
|
||||
Assert.Equal(expectedDescriptor, descriptor, CaseSensitiveTagHelperDescriptorComparer.Default);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreateDescriptor_IgnoresDuplicateTagNamesFromAttribute()
|
||||
{
|
||||
// Arrange
|
||||
var errorSink = new ParserErrorSink();
|
||||
var expectedDescriptors = new[] {
|
||||
new TagHelperDescriptor(
|
||||
"p",
|
||||
|
|
@ -306,17 +537,21 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
};
|
||||
|
||||
// Act
|
||||
var descriptors = TagHelperDescriptorFactory.CreateDescriptors(AssemblyName,
|
||||
typeof(DuplicateTagNameTagHelper));
|
||||
var descriptors = TagHelperDescriptorFactory.CreateDescriptors(
|
||||
AssemblyName,
|
||||
typeof(DuplicateTagNameTagHelper),
|
||||
errorSink);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expectedDescriptors, descriptors, CompleteTagHelperDescriptorComparer.Default);
|
||||
Assert.Empty(errorSink.Errors);
|
||||
Assert.Equal(expectedDescriptors, descriptors, CaseSensitiveTagHelperDescriptorComparer.Default);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreateDescriptor_OverridesTagNameFromAttribute()
|
||||
{
|
||||
// Arrange
|
||||
var errorSink = new ParserErrorSink();
|
||||
var expectedDescriptors = new[] {
|
||||
new TagHelperDescriptor("data-condition",
|
||||
typeof(OverrideNameTagHelper).FullName,
|
||||
|
|
@ -324,41 +559,353 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
};
|
||||
|
||||
// Act
|
||||
var descriptors = TagHelperDescriptorFactory.CreateDescriptors(AssemblyName,
|
||||
typeof(OverrideNameTagHelper));
|
||||
var descriptors = TagHelperDescriptorFactory.CreateDescriptors(
|
||||
AssemblyName,
|
||||
typeof(OverrideNameTagHelper),
|
||||
errorSink);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expectedDescriptors, descriptors, CompleteTagHelperDescriptorComparer.Default);
|
||||
Assert.Empty(errorSink.Errors);
|
||||
Assert.Equal(expectedDescriptors, descriptors, CaseSensitiveTagHelperDescriptorComparer.Default);
|
||||
}
|
||||
|
||||
public static TheoryData InvalidNameData
|
||||
{
|
||||
get
|
||||
{
|
||||
var invalidNameError =
|
||||
"Tag helpers cannot target {0} name '{1}' because it contains a '{2}' character.";
|
||||
var nullOrWhitespaceNameError =
|
||||
"{0} name cannot be null or whitespace.";
|
||||
Func<string, string, string> onNameError = (invalidText, invalidCharacter) =>
|
||||
string.Format(invalidNameError, "tag", invalidText, invalidCharacter);
|
||||
|
||||
// name, expectedErrorMessages
|
||||
return new TheoryData<string, string[]>
|
||||
{
|
||||
{ "!", new[] { onNameError("!", "!") } },
|
||||
{ "hello!", new[] { onNameError("hello!", "!") } },
|
||||
{ "!hello", new[] { onNameError("!hello", "!") } },
|
||||
{ "he!lo", new[] { onNameError("he!lo", "!") } },
|
||||
{
|
||||
"!he!lo!",
|
||||
new[]
|
||||
{
|
||||
onNameError("!he!lo!", "!"),
|
||||
onNameError("!he!lo!", "!"),
|
||||
onNameError("!he!lo!", "!")
|
||||
}
|
||||
},
|
||||
{ "@", new[] { onNameError("@", "@") } },
|
||||
{ "hello@", new[] { onNameError("hello@", "@") } },
|
||||
{ "@hello", new[] { onNameError("@hello", "@") } },
|
||||
{ "he@lo", new[] { onNameError("he@lo", "@") } },
|
||||
{
|
||||
"@he@lo@",
|
||||
new[]
|
||||
{
|
||||
onNameError("@he@lo@", "@"),
|
||||
onNameError("@he@lo@", "@"),
|
||||
onNameError("@he@lo@", "@")
|
||||
}
|
||||
},
|
||||
{ "/", new[] { onNameError("/", "/") } },
|
||||
{ "hello/", new[] { onNameError("hello/", "/") } },
|
||||
{ "/hello", new[] { onNameError("/hello", "/") } },
|
||||
{ "he/lo", new[] { onNameError("he/lo", "/") } },
|
||||
{
|
||||
"/he/lo/",
|
||||
new[] {
|
||||
onNameError("/he/lo/", "/"),
|
||||
onNameError("/he/lo/", "/"),
|
||||
onNameError("/he/lo/", "/")
|
||||
}
|
||||
},
|
||||
{ "<", new[] { onNameError("<", "<") } },
|
||||
{ "hello<", new[] { onNameError("hello<", "<") } },
|
||||
{ "<hello", new[] { onNameError("<hello", "<") } },
|
||||
{ "he<lo", new[] { onNameError("he<lo", "<") } },
|
||||
{
|
||||
"<he<lo<",
|
||||
new[]
|
||||
{
|
||||
onNameError("<he<lo<", "<"),
|
||||
onNameError("<he<lo<", "<"),
|
||||
onNameError("<he<lo<", "<")
|
||||
}
|
||||
},
|
||||
{ "?", new[] { onNameError("?", "?") } },
|
||||
{ "hello?", new[] { onNameError("hello?", "?") } },
|
||||
{ "?hello", new[] { onNameError("?hello", "?") } },
|
||||
{ "he?lo", new[] { onNameError("he?lo", "?") } },
|
||||
{
|
||||
"?he?lo?",
|
||||
new[]
|
||||
{
|
||||
onNameError("?he?lo?", "?"),
|
||||
onNameError("?he?lo?", "?"),
|
||||
onNameError("?he?lo?", "?")
|
||||
}
|
||||
},
|
||||
{ "[", new[] { onNameError("[", "[") } },
|
||||
{ "hello[", new[] { onNameError("hello[", "[") } },
|
||||
{ "[hello", new[] { onNameError("[hello", "[") } },
|
||||
{ "he[lo", new[] { onNameError("he[lo", "[") } },
|
||||
{
|
||||
"[he[lo[",
|
||||
new[]
|
||||
{
|
||||
onNameError("[he[lo[", "["),
|
||||
onNameError("[he[lo[", "["),
|
||||
onNameError("[he[lo[", "[")
|
||||
}
|
||||
},
|
||||
{ ">", new[] { onNameError(">", ">") } },
|
||||
{ "hello>", new[] { onNameError("hello>", ">") } },
|
||||
{ ">hello", new[] { onNameError(">hello", ">") } },
|
||||
{ "he>lo", new[] { onNameError("he>lo", ">") } },
|
||||
{
|
||||
">he>lo>",
|
||||
new[]
|
||||
{
|
||||
onNameError(">he>lo>", ">"),
|
||||
onNameError(">he>lo>", ">"),
|
||||
onNameError(">he>lo>", ">")
|
||||
}
|
||||
},
|
||||
{ "]", new[] { onNameError("]", "]") } },
|
||||
{ "hello]", new[] { onNameError("hello]", "]") } },
|
||||
{ "]hello", new[] { onNameError("]hello", "]") } },
|
||||
{ "he]lo", new[] { onNameError("he]lo", "]") } },
|
||||
{
|
||||
"]he]lo]",
|
||||
new[]
|
||||
{
|
||||
onNameError("]he]lo]", "]"),
|
||||
onNameError("]he]lo]", "]"),
|
||||
onNameError("]he]lo]", "]")
|
||||
}
|
||||
},
|
||||
{ "=", new[] { onNameError("=", "=") } },
|
||||
{ "hello=", new[] { onNameError("hello=", "=") } },
|
||||
{ "=hello", new[] { onNameError("=hello", "=") } },
|
||||
{ "he=lo", new[] { onNameError("he=lo", "=") } },
|
||||
{
|
||||
"=he=lo=",
|
||||
new[]
|
||||
{
|
||||
onNameError("=he=lo=", "="),
|
||||
onNameError("=he=lo=", "="),
|
||||
onNameError("=he=lo=", "=")
|
||||
}
|
||||
},
|
||||
{ "\"", new[] { onNameError("\"", "\"") } },
|
||||
{ "hello\"", new[] { onNameError("hello\"", "\"") } },
|
||||
{ "\"hello", new[] { onNameError("\"hello", "\"") } },
|
||||
{ "he\"lo", new[] { onNameError("he\"lo", "\"") } },
|
||||
{
|
||||
"\"he\"lo\"",
|
||||
new[]
|
||||
{
|
||||
onNameError("\"he\"lo\"", "\""),
|
||||
onNameError("\"he\"lo\"", "\""),
|
||||
onNameError("\"he\"lo\"", "\"")
|
||||
}
|
||||
},
|
||||
{ "'", new[] { onNameError("'", "'") } },
|
||||
{ "hello'", new[] { onNameError("hello'", "'") } },
|
||||
{ "'hello", new[] { onNameError("'hello", "'") } },
|
||||
{ "he'lo", new[] { onNameError("he'lo", "'") } },
|
||||
{
|
||||
"'he'lo'",
|
||||
new[]
|
||||
{
|
||||
onNameError("'he'lo'", "'"),
|
||||
onNameError("'he'lo'", "'"),
|
||||
onNameError("'he'lo'", "'")
|
||||
}
|
||||
},
|
||||
{ string.Empty, new[] { string.Format(nullOrWhitespaceNameError, "Tag") } },
|
||||
{ Environment.NewLine, new[] { string.Format(nullOrWhitespaceNameError, "Tag") } },
|
||||
{ "\t", new[] { string.Format(nullOrWhitespaceNameError, "Tag") } },
|
||||
{ " \t ", new[] { string.Format(nullOrWhitespaceNameError, "Tag") } },
|
||||
{ " ", new[] { string.Format(nullOrWhitespaceNameError, "Tag") } },
|
||||
{ Environment.NewLine + " ", new[] { string.Format(nullOrWhitespaceNameError, "Tag") } },
|
||||
{
|
||||
"! \t\r\n@/<>?[]=\"'",
|
||||
new[]
|
||||
{
|
||||
onNameError("! \t\r\n@/<>?[]=\"'", "!"),
|
||||
onNameError("! \t\r\n@/<>?[]=\"'", " "),
|
||||
onNameError("! \t\r\n@/<>?[]=\"'", "\t"),
|
||||
onNameError("! \t\r\n@/<>?[]=\"'", "\r"),
|
||||
onNameError("! \t\r\n@/<>?[]=\"'", "\n"),
|
||||
onNameError("! \t\r\n@/<>?[]=\"'", "@"),
|
||||
onNameError("! \t\r\n@/<>?[]=\"'", "/"),
|
||||
onNameError("! \t\r\n@/<>?[]=\"'", "<"),
|
||||
onNameError("! \t\r\n@/<>?[]=\"'", ">"),
|
||||
onNameError("! \t\r\n@/<>?[]=\"'", "?"),
|
||||
onNameError("! \t\r\n@/<>?[]=\"'", "["),
|
||||
onNameError("! \t\r\n@/<>?[]=\"'", "]"),
|
||||
onNameError("! \t\r\n@/<>?[]=\"'", "="),
|
||||
onNameError("! \t\r\n@/<>?[]=\"'", "\""),
|
||||
onNameError("! \t\r\n@/<>?[]=\"'", "'"),
|
||||
}
|
||||
},
|
||||
{
|
||||
"! \tv\ra\nl@i/d<>?[]=\"'",
|
||||
new[]
|
||||
{
|
||||
onNameError("! \tv\ra\nl@i/d<>?[]=\"'", "!"),
|
||||
onNameError("! \tv\ra\nl@i/d<>?[]=\"'", " "),
|
||||
onNameError("! \tv\ra\nl@i/d<>?[]=\"'", "\t"),
|
||||
onNameError("! \tv\ra\nl@i/d<>?[]=\"'", "\r"),
|
||||
onNameError("! \tv\ra\nl@i/d<>?[]=\"'", "\n"),
|
||||
onNameError("! \tv\ra\nl@i/d<>?[]=\"'", "@"),
|
||||
onNameError("! \tv\ra\nl@i/d<>?[]=\"'", "/"),
|
||||
onNameError("! \tv\ra\nl@i/d<>?[]=\"'", "<"),
|
||||
onNameError("! \tv\ra\nl@i/d<>?[]=\"'", ">"),
|
||||
onNameError("! \tv\ra\nl@i/d<>?[]=\"'", "?"),
|
||||
onNameError("! \tv\ra\nl@i/d<>?[]=\"'", "["),
|
||||
onNameError("! \tv\ra\nl@i/d<>?[]=\"'", "]"),
|
||||
onNameError("! \tv\ra\nl@i/d<>?[]=\"'", "="),
|
||||
onNameError("! \tv\ra\nl@i/d<>?[]=\"'", "\""),
|
||||
onNameError("! \tv\ra\nl@i/d<>?[]=\"'", "'"),
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(InvalidNameData))]
|
||||
public void ValidTargetElementAttributeNames_CreatesErrorOnInvalidNames(
|
||||
string name, string[] expectedErrorMessages)
|
||||
{
|
||||
// Arrange
|
||||
var errorSink = new ParserErrorSink();
|
||||
var attribute = new TargetElementAttribute(name);
|
||||
|
||||
// Act
|
||||
TagHelperDescriptorFactory.ValidTargetElementAttributeNames(attribute, errorSink);
|
||||
|
||||
// Assert
|
||||
var errors = errorSink.Errors.ToArray();
|
||||
for (var i = 0; i < errors.Length; i++)
|
||||
{
|
||||
Assert.Equal(expectedErrorMessages[i], errors[i].Message);
|
||||
Assert.Equal(SourceLocation.Zero, errors[i].Location);
|
||||
}
|
||||
}
|
||||
|
||||
public static TheoryData ValidNameData
|
||||
{
|
||||
get
|
||||
{
|
||||
// name, expectedNames
|
||||
return new TheoryData<string, IEnumerable<string>>
|
||||
{
|
||||
{ "p", new[] { "p" } },
|
||||
{ " p", new[] { "p" } },
|
||||
{ "p ", new[] { "p" } },
|
||||
{ " p ", new[] { "p" } },
|
||||
{ "p,div", new[] { "p", "div" } },
|
||||
{ " p,div", new[] { "p", "div" } },
|
||||
{ "p ,div", new[] { "p", "div" } },
|
||||
{ " p ,div", new[] { "p", "div" } },
|
||||
{ "p, div", new[] { "p", "div" } },
|
||||
{ "p,div ", new[] { "p", "div" } },
|
||||
{ "p, div ", new[] { "p", "div" } },
|
||||
{ " p, div ", new[] { "p", "div" } },
|
||||
{ " p , div ", new[] { "p", "div" } },
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(ValidNameData))]
|
||||
public void GetCommaSeparatedValues_OutputsCommaSeparatedListOfNames(
|
||||
string name,
|
||||
IEnumerable<string> expectedNames)
|
||||
{
|
||||
// Act
|
||||
var result = TagHelperDescriptorFactory.GetCommaSeparatedValues(name);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expectedNames, result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreateDescriptor_GetsTagNamesFromMultipleAttributes()
|
||||
public void GetCommaSeparatedValues_OutputsEmptyArrayForNullValue()
|
||||
{
|
||||
// Arrange
|
||||
var expectedDescriptors = new[] {
|
||||
new TagHelperDescriptor(
|
||||
"span",
|
||||
typeof(MultipleAttributeTagHelper).FullName,
|
||||
AssemblyName),
|
||||
new TagHelperDescriptor(
|
||||
"p",
|
||||
typeof(MultipleAttributeTagHelper).FullName,
|
||||
AssemblyName),
|
||||
new TagHelperDescriptor(
|
||||
"div",
|
||||
typeof(MultipleAttributeTagHelper).FullName,
|
||||
AssemblyName)
|
||||
};
|
||||
|
||||
// Act
|
||||
var descriptors = TagHelperDescriptorFactory.CreateDescriptors(AssemblyName,
|
||||
typeof(MultipleAttributeTagHelper));
|
||||
var result = TagHelperDescriptorFactory.GetCommaSeparatedValues(text: null);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expectedDescriptors, descriptors, CompleteTagHelperDescriptorComparer.Default);
|
||||
Assert.Empty(result);
|
||||
}
|
||||
|
||||
[HtmlElementName("p", "div")]
|
||||
[TargetElement(Attributes = "class")]
|
||||
private class AttributeTargetingTagHelper : TagHelper
|
||||
{
|
||||
}
|
||||
|
||||
[TargetElement(Attributes = "class,style")]
|
||||
private class MultiAttributeTargetingTagHelper : TagHelper
|
||||
{
|
||||
}
|
||||
|
||||
[TargetElement(Attributes = "custom")]
|
||||
[TargetElement(Attributes = "class,style")]
|
||||
private class MultiAttributeAttributeTargetingTagHelper : TagHelper
|
||||
{
|
||||
}
|
||||
|
||||
[TargetElement(Attributes = "style")]
|
||||
private class InheritedAttributeTargetingTagHelper : AttributeTargetingTagHelper
|
||||
{
|
||||
}
|
||||
|
||||
[TargetElement("input", Attributes = "class")]
|
||||
private class RequiredAttributeTagHelper : TagHelper
|
||||
{
|
||||
}
|
||||
|
||||
[TargetElement("div", Attributes = "class")]
|
||||
private class InheritedRequiredAttributeTagHelper : RequiredAttributeTagHelper
|
||||
{
|
||||
}
|
||||
|
||||
[TargetElement("div", Attributes = "class")]
|
||||
[TargetElement("input", Attributes = "class")]
|
||||
private class MultiAttributeRequiredAttributeTagHelper : TagHelper
|
||||
{
|
||||
}
|
||||
|
||||
[TargetElement("input", Attributes = "style")]
|
||||
[TargetElement("input", Attributes = "class")]
|
||||
private class MultiAttributeSameTagRequiredAttributeTagHelper : TagHelper
|
||||
{
|
||||
}
|
||||
|
||||
[TargetElement("input", Attributes = "class,style")]
|
||||
private class MultiRequiredAttributeTagHelper : TagHelper
|
||||
{
|
||||
}
|
||||
|
||||
[TargetElement("div", Attributes = "style")]
|
||||
private class InheritedMultiRequiredAttributeTagHelper : MultiRequiredAttributeTagHelper
|
||||
{
|
||||
}
|
||||
|
||||
[TargetElement("div", Attributes = "class,style")]
|
||||
[TargetElement("input", Attributes = "class,style")]
|
||||
private class MultiTagMultiRequiredAttributeTagHelper : TagHelper
|
||||
{
|
||||
}
|
||||
|
||||
[TargetElement("p")]
|
||||
[TargetElement("div")]
|
||||
private class MultiTagTagHelper
|
||||
{
|
||||
public string ValidAttribute { get; set; }
|
||||
|
|
@ -368,22 +915,19 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
{
|
||||
}
|
||||
|
||||
[HtmlElementName("p", "p", "div", "div")]
|
||||
[TargetElement("p")]
|
||||
[TargetElement("p")]
|
||||
[TargetElement("div")]
|
||||
[TargetElement("div")]
|
||||
private class DuplicateTagNameTagHelper
|
||||
{
|
||||
}
|
||||
|
||||
[HtmlElementName("data-condition")]
|
||||
[TargetElement("data-condition")]
|
||||
private class OverrideNameTagHelper
|
||||
{
|
||||
}
|
||||
|
||||
[HtmlElementName("span")]
|
||||
[HtmlElementName("div", "p")]
|
||||
private class MultipleAttributeTagHelper
|
||||
{
|
||||
}
|
||||
|
||||
private class InheritedSingleAttributeTagHelper : SingleAttributeTagHelper
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1241,7 +1241,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
|
||||
// Assert
|
||||
var descriptor = Assert.Single(descriptors);
|
||||
Assert.Equal(Valid_PlainTagHelperDescriptor, descriptor, CompleteTagHelperDescriptorComparer.Default);
|
||||
Assert.Equal(Valid_PlainTagHelperDescriptor, descriptor, CaseSensitiveTagHelperDescriptorComparer.Default);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -1265,7 +1265,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
|
||||
// Assert
|
||||
Assert.Equal(descriptors.Length, 2);
|
||||
Assert.Equal(expectedDescriptors, descriptors, CompleteTagHelperDescriptorComparer.Default);
|
||||
Assert.Equal(expectedDescriptors, descriptors, CaseSensitiveTagHelperDescriptorComparer.Default);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -1369,7 +1369,8 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
tagName,
|
||||
typeName,
|
||||
assemblyName,
|
||||
attributes: Enumerable.Empty<TagHelperAttributeDescriptor>());
|
||||
attributes: Enumerable.Empty<TagHelperAttributeDescriptor>(),
|
||||
requiredAttributes: Enumerable.Empty<string>());
|
||||
}
|
||||
|
||||
private static TagHelperDescriptor CreatePrefixedValidPlainDescriptor(string prefix)
|
||||
|
|
|
|||
|
|
@ -19,6 +19,49 @@ namespace Microsoft.AspNet.Razor.Test.Generator
|
|||
private static IEnumerable<TagHelperDescriptor> PrefixedPAndInputTagHelperDescriptors
|
||||
=> BuildPAndInputTagHelperDescriptors("THS");
|
||||
|
||||
private static IEnumerable<TagHelperDescriptor> AttributeTargetingTagHelperDescriptors
|
||||
{
|
||||
get
|
||||
{
|
||||
var inputTypePropertyInfo = typeof(TestType).GetProperty("Type");
|
||||
var inputCheckedPropertyInfo = typeof(TestType).GetProperty("Checked");
|
||||
return new[]
|
||||
{
|
||||
new TagHelperDescriptor(
|
||||
tagName: "p",
|
||||
typeName: "PTagHelper",
|
||||
assemblyName: "SomeAssembly",
|
||||
attributes: new TagHelperAttributeDescriptor[0],
|
||||
requiredAttributes: new[] { "class" }),
|
||||
new TagHelperDescriptor(
|
||||
tagName: "input",
|
||||
typeName: "InputTagHelper",
|
||||
assemblyName: "SomeAssembly",
|
||||
attributes: new TagHelperAttributeDescriptor[]
|
||||
{
|
||||
new TagHelperAttributeDescriptor("type", inputTypePropertyInfo)
|
||||
},
|
||||
requiredAttributes: new[] { "type" }),
|
||||
new TagHelperDescriptor(
|
||||
tagName: "input",
|
||||
typeName: "InputTagHelper2",
|
||||
assemblyName: "SomeAssembly",
|
||||
attributes: new TagHelperAttributeDescriptor[]
|
||||
{
|
||||
new TagHelperAttributeDescriptor("type", inputTypePropertyInfo),
|
||||
new TagHelperAttributeDescriptor("checked", inputCheckedPropertyInfo)
|
||||
},
|
||||
requiredAttributes: new[] { "type", "checked" }),
|
||||
new TagHelperDescriptor(
|
||||
tagName: "*",
|
||||
typeName: "CatchAllTagHelper",
|
||||
assemblyName: "SomeAssembly",
|
||||
attributes: new TagHelperAttributeDescriptor[0],
|
||||
requiredAttributes: new[] { "catchAll" })
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public static TheoryData TagHelperDescriptorFlowTestData
|
||||
{
|
||||
get
|
||||
|
|
@ -91,6 +134,20 @@ namespace Microsoft.AspNet.Razor.Test.Generator
|
|||
DefaultPAndInputTagHelperDescriptors,
|
||||
DefaultPAndInputTagHelperDescriptors,
|
||||
true
|
||||
},
|
||||
{
|
||||
"AttributeTargetingTagHelpers",
|
||||
"AttributeTargetingTagHelpers",
|
||||
AttributeTargetingTagHelperDescriptors,
|
||||
AttributeTargetingTagHelperDescriptors,
|
||||
false
|
||||
},
|
||||
{
|
||||
"AttributeTargetingTagHelpers",
|
||||
"AttributeTargetingTagHelpers.DesignTime",
|
||||
AttributeTargetingTagHelperDescriptors,
|
||||
AttributeTargetingTagHelperDescriptors,
|
||||
true
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
@ -294,6 +351,33 @@ namespace Microsoft.AspNet.Razor.Test.Generator
|
|||
contentLength: 4)
|
||||
}
|
||||
},
|
||||
{
|
||||
"AttributeTargetingTagHelpers",
|
||||
"AttributeTargetingTagHelpers.DesignTime",
|
||||
AttributeTargetingTagHelperDescriptors,
|
||||
new List<LineMapping>
|
||||
{
|
||||
BuildLineMapping(documentAbsoluteIndex: 14,
|
||||
documentLineIndex: 0,
|
||||
generatedAbsoluteIndex: 501,
|
||||
generatedLineIndex: 15,
|
||||
characterOffsetIndex: 14,
|
||||
contentLength: 14),
|
||||
BuildLineMapping(documentAbsoluteIndex: 186,
|
||||
documentLineIndex: 5,
|
||||
generatedAbsoluteIndex: 1460,
|
||||
generatedLineIndex: 41,
|
||||
characterOffsetIndex: 36,
|
||||
contentLength: 4),
|
||||
BuildLineMapping(documentAbsoluteIndex: 232,
|
||||
documentLineIndex: 6,
|
||||
documentCharacterOffsetIndex: 36,
|
||||
generatedAbsoluteIndex: 1827,
|
||||
generatedLineIndex: 50,
|
||||
generatedCharacterOffsetIndex: 36,
|
||||
contentLength: 4)
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -328,6 +412,7 @@ namespace Microsoft.AspNet.Razor.Test.Generator
|
|||
{ "ComplexTagHelpers", DefaultPAndInputTagHelperDescriptors },
|
||||
{ "EmptyAttributeTagHelpers", DefaultPAndInputTagHelperDescriptors },
|
||||
{ "EscapedTagHelpers", DefaultPAndInputTagHelperDescriptors },
|
||||
{ "AttributeTargetingTagHelpers", AttributeTargetingTagHelperDescriptors },
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -421,7 +506,8 @@ namespace Microsoft.AspNet.Razor.Test.Generator
|
|||
assemblyName: "SomeAssembly",
|
||||
attributes: new [] {
|
||||
new TagHelperAttributeDescriptor("age", pAgePropertyInfo)
|
||||
}),
|
||||
},
|
||||
requiredAttributes: Enumerable.Empty<string>()),
|
||||
new TagHelperDescriptor(
|
||||
prefix,
|
||||
tagName: "input",
|
||||
|
|
@ -429,7 +515,8 @@ namespace Microsoft.AspNet.Razor.Test.Generator
|
|||
assemblyName: "SomeAssembly",
|
||||
attributes: new TagHelperAttributeDescriptor[] {
|
||||
new TagHelperAttributeDescriptor("type", inputTypePropertyInfo)
|
||||
}),
|
||||
},
|
||||
requiredAttributes: Enumerable.Empty<string>()),
|
||||
new TagHelperDescriptor(
|
||||
prefix,
|
||||
tagName: "input",
|
||||
|
|
@ -438,7 +525,8 @@ namespace Microsoft.AspNet.Razor.Test.Generator
|
|||
attributes: new TagHelperAttributeDescriptor[] {
|
||||
new TagHelperAttributeDescriptor("type", inputTypePropertyInfo),
|
||||
new TagHelperAttributeDescriptor("checked", checkedPropertyInfo)
|
||||
})
|
||||
},
|
||||
requiredAttributes: Enumerable.Empty<string>())
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,31 +1,143 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNet.Razor.TagHelpers;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Razor.Test.TagHelpers
|
||||
namespace Microsoft.AspNet.Razor.TagHelpers
|
||||
{
|
||||
public class TagHelperDescriptorProviderTest
|
||||
{
|
||||
[Fact]
|
||||
public void GetTagHelpers_ReturnsEmptyDescriptorsWithPrefixAsTagName()
|
||||
public static TheoryData RequiredAttributeData
|
||||
{
|
||||
get
|
||||
{
|
||||
var divDescriptor = new TagHelperDescriptor(
|
||||
tagName: "div",
|
||||
typeName: "DivTagHelper",
|
||||
assemblyName: "SomeAssembly",
|
||||
attributes: Enumerable.Empty<TagHelperAttributeDescriptor>(),
|
||||
requiredAttributes: new[] { "style" });
|
||||
var inputDescriptor = new TagHelperDescriptor(
|
||||
tagName: "input",
|
||||
typeName: "InputTagHelper",
|
||||
assemblyName: "SomeAssembly",
|
||||
attributes: Enumerable.Empty<TagHelperAttributeDescriptor>(),
|
||||
requiredAttributes: new[] { "class", "style" });
|
||||
var catchAllDescriptor = new TagHelperDescriptor(
|
||||
tagName: TagHelperDescriptorProvider.CatchAllDescriptorTarget,
|
||||
typeName: "CatchAllTagHelper",
|
||||
assemblyName: "SomeAssembly",
|
||||
attributes: Enumerable.Empty<TagHelperAttributeDescriptor>(),
|
||||
requiredAttributes: new[] { "class" });
|
||||
var catchAllDescriptor2 = new TagHelperDescriptor(
|
||||
tagName: TagHelperDescriptorProvider.CatchAllDescriptorTarget,
|
||||
typeName: "CatchAllTagHelper",
|
||||
assemblyName: "SomeAssembly",
|
||||
attributes: Enumerable.Empty<TagHelperAttributeDescriptor>(),
|
||||
requiredAttributes: new[] { "custom", "class" });
|
||||
var defaultAvailableDescriptors =
|
||||
new[] { divDescriptor, inputDescriptor, catchAllDescriptor, catchAllDescriptor2 };
|
||||
|
||||
return new TheoryData<
|
||||
string, // tagName
|
||||
IEnumerable<string>, // providedAttributes
|
||||
IEnumerable<TagHelperDescriptor>, // availableDescriptors
|
||||
IEnumerable<TagHelperDescriptor>> // expectedDescriptors
|
||||
{
|
||||
{
|
||||
"div",
|
||||
new[] { "custom" },
|
||||
defaultAvailableDescriptors,
|
||||
Enumerable.Empty<TagHelperDescriptor>()
|
||||
},
|
||||
{ "div", new[] { "style" }, defaultAvailableDescriptors, new[] { divDescriptor } },
|
||||
{ "div", new[] { "class" }, defaultAvailableDescriptors, new[] { catchAllDescriptor } },
|
||||
{
|
||||
"div",
|
||||
new[] { "class", "style" },
|
||||
defaultAvailableDescriptors,
|
||||
new[] { divDescriptor, catchAllDescriptor }
|
||||
},
|
||||
{
|
||||
"div",
|
||||
new[] { "class", "style", "custom" },
|
||||
defaultAvailableDescriptors,
|
||||
new[] { divDescriptor, catchAllDescriptor, catchAllDescriptor2 }
|
||||
},
|
||||
{
|
||||
"input",
|
||||
new[] { "class", "style" },
|
||||
defaultAvailableDescriptors,
|
||||
new[] { inputDescriptor, catchAllDescriptor }
|
||||
},
|
||||
{
|
||||
TagHelperDescriptorProvider.CatchAllDescriptorTarget,
|
||||
new[] { "custom" },
|
||||
defaultAvailableDescriptors,
|
||||
Enumerable.Empty<TagHelperDescriptor>()
|
||||
},
|
||||
{
|
||||
TagHelperDescriptorProvider.CatchAllDescriptorTarget,
|
||||
new[] { "class" },
|
||||
defaultAvailableDescriptors,
|
||||
new[] { catchAllDescriptor }
|
||||
},
|
||||
{
|
||||
TagHelperDescriptorProvider.CatchAllDescriptorTarget,
|
||||
new[] { "class", "style" },
|
||||
defaultAvailableDescriptors,
|
||||
new[] { catchAllDescriptor }
|
||||
},
|
||||
{
|
||||
TagHelperDescriptorProvider.CatchAllDescriptorTarget,
|
||||
new[] { "class", "custom" },
|
||||
defaultAvailableDescriptors,
|
||||
new[] { catchAllDescriptor, catchAllDescriptor2 }
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RequiredAttributeData))]
|
||||
public void GetDescriptors_ReturnsDescriptorsWithRequiredAttributes(
|
||||
string tagName,
|
||||
IEnumerable<string> providedAttributes,
|
||||
IEnumerable<TagHelperDescriptor> availableDescriptors,
|
||||
IEnumerable<TagHelperDescriptor> expectedDescriptors)
|
||||
{
|
||||
// Arrange
|
||||
var catchAllDescriptor = CreatePrefixedDescriptor("th", "*", "foo1");
|
||||
var provider = new TagHelperDescriptorProvider(availableDescriptors);
|
||||
|
||||
// Act
|
||||
var resolvedDescriptors = provider.GetDescriptors(tagName, providedAttributes);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expectedDescriptors, resolvedDescriptors, TagHelperDescriptorComparer.Default);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetDescriptors_ReturnsEmptyDescriptorsWithPrefixAsTagName()
|
||||
{
|
||||
// Arrange
|
||||
var catchAllDescriptor = CreatePrefixedDescriptor(
|
||||
"th",
|
||||
TagHelperDescriptorProvider.CatchAllDescriptorTarget,
|
||||
"foo1");
|
||||
var descriptors = new[] { catchAllDescriptor };
|
||||
var provider = new TagHelperDescriptorProvider(descriptors);
|
||||
|
||||
// Act
|
||||
var resolvedDescriptors = provider.GetTagHelpers("th");
|
||||
var resolvedDescriptors = provider.GetDescriptors("th", attributeNames: Enumerable.Empty<string>());
|
||||
|
||||
// Assert
|
||||
Assert.Empty(resolvedDescriptors);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetTagHelpers_OnlyUnderstandsSinglePrefix()
|
||||
public void GetDescriptors_OnlyUnderstandsSinglePrefix()
|
||||
{
|
||||
// Arrange
|
||||
var divDescriptor = CreatePrefixedDescriptor("th:", "div", "foo1");
|
||||
|
|
@ -34,8 +146,8 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
|
|||
var provider = new TagHelperDescriptorProvider(descriptors);
|
||||
|
||||
// Act
|
||||
var retrievedDescriptorsDiv = provider.GetTagHelpers("th:div");
|
||||
var retrievedDescriptorsSpan = provider.GetTagHelpers("th2:span");
|
||||
var retrievedDescriptorsDiv = provider.GetDescriptors("th:div", attributeNames: Enumerable.Empty<string>());
|
||||
var retrievedDescriptorsSpan = provider.GetDescriptors("th2:span", attributeNames: Enumerable.Empty<string>());
|
||||
|
||||
// Assert
|
||||
var descriptor = Assert.Single(retrievedDescriptorsDiv);
|
||||
|
|
@ -44,16 +156,16 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public void GetTagHelpers_ReturnsCatchAllDescriptorsForPrefixedTags()
|
||||
public void GetDescriptors_ReturnsCatchAllDescriptorsForPrefixedTags()
|
||||
{
|
||||
// Arrange
|
||||
var catchAllDescriptor = CreatePrefixedDescriptor("th:", "*", "foo1");
|
||||
var catchAllDescriptor = CreatePrefixedDescriptor("th:", TagHelperDescriptorProvider.CatchAllDescriptorTarget, "foo1");
|
||||
var descriptors = new[] { catchAllDescriptor };
|
||||
var provider = new TagHelperDescriptorProvider(descriptors);
|
||||
|
||||
// Act
|
||||
var retrievedDescriptorsDiv = provider.GetTagHelpers("th:div");
|
||||
var retrievedDescriptorsSpan = provider.GetTagHelpers("th:span");
|
||||
var retrievedDescriptorsDiv = provider.GetDescriptors("th:div", attributeNames: Enumerable.Empty<string>());
|
||||
var retrievedDescriptorsSpan = provider.GetDescriptors("th:span", attributeNames: Enumerable.Empty<string>());
|
||||
|
||||
// Assert
|
||||
var descriptor = Assert.Single(retrievedDescriptorsDiv);
|
||||
|
|
@ -63,7 +175,7 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public void GetTagHelpers_ReturnsDescriptorsForPrefixedTags()
|
||||
public void GetDescriptors_ReturnsDescriptorsForPrefixedTags()
|
||||
{
|
||||
// Arrange
|
||||
var divDescriptor = CreatePrefixedDescriptor("th:", "div", "foo1");
|
||||
|
|
@ -71,7 +183,7 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
|
|||
var provider = new TagHelperDescriptorProvider(descriptors);
|
||||
|
||||
// Act
|
||||
var retrievedDescriptors = provider.GetTagHelpers("th:div");
|
||||
var retrievedDescriptors = provider.GetDescriptors("th:div", attributeNames: Enumerable.Empty<string>());
|
||||
|
||||
// Assert
|
||||
var descriptor = Assert.Single(retrievedDescriptors);
|
||||
|
|
@ -81,7 +193,7 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
|
|||
[Theory]
|
||||
[InlineData("*")]
|
||||
[InlineData("div")]
|
||||
public void GetTagHelpers_ReturnsNothingForUnprefixedTags(string tagName)
|
||||
public void GetDescriptors_ReturnsNothingForUnprefixedTags(string tagName)
|
||||
{
|
||||
// Arrange
|
||||
var divDescriptor = CreatePrefixedDescriptor("th:", tagName, "foo1");
|
||||
|
|
@ -89,14 +201,14 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
|
|||
var provider = new TagHelperDescriptorProvider(descriptors);
|
||||
|
||||
// Act
|
||||
var retrievedDescriptorsDiv = provider.GetTagHelpers("div");
|
||||
var retrievedDescriptorsDiv = provider.GetDescriptors("div", attributeNames: Enumerable.Empty<string>());
|
||||
|
||||
// Assert
|
||||
Assert.Empty(retrievedDescriptorsDiv);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetTagHelpers_ReturnsNothingForUnregisteredTags()
|
||||
public void GetDescriptors_ReturnsNothingForUnregisteredTags()
|
||||
{
|
||||
// Arrange
|
||||
var divDescriptor = new TagHelperDescriptor("div", "foo1", "SomeAssembly");
|
||||
|
|
@ -105,24 +217,27 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
|
|||
var provider = new TagHelperDescriptorProvider(descriptors);
|
||||
|
||||
// Act
|
||||
var retrievedDescriptors = provider.GetTagHelpers("foo");
|
||||
var retrievedDescriptors = provider.GetDescriptors("foo", attributeNames: Enumerable.Empty<string>());
|
||||
|
||||
// Assert
|
||||
Assert.Empty(retrievedDescriptors);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetTagHelpers_DoesNotReturnNonCatchAllTagsForCatchAll()
|
||||
public void GetDescriptors_DoesNotReturnNonCatchAllTagsForCatchAll()
|
||||
{
|
||||
// Arrange
|
||||
var divDescriptor = new TagHelperDescriptor("div", "foo1", "SomeAssembly");
|
||||
var spanDescriptor = new TagHelperDescriptor("span", "foo2", "SomeAssembly");
|
||||
var catchAllDescriptor = new TagHelperDescriptor("*", "foo3", "SomeAssembly");
|
||||
var catchAllDescriptor = new TagHelperDescriptor(
|
||||
TagHelperDescriptorProvider.CatchAllDescriptorTarget,
|
||||
"foo3",
|
||||
"SomeAssembly");
|
||||
var descriptors = new TagHelperDescriptor[] { divDescriptor, spanDescriptor, catchAllDescriptor };
|
||||
var provider = new TagHelperDescriptorProvider(descriptors);
|
||||
|
||||
// Act
|
||||
var retrievedDescriptors = provider.GetTagHelpers("*");
|
||||
var retrievedDescriptors = provider.GetDescriptors(TagHelperDescriptorProvider.CatchAllDescriptorTarget, attributeNames: Enumerable.Empty<string>());
|
||||
|
||||
// Assert
|
||||
var descriptor = Assert.Single(retrievedDescriptors);
|
||||
|
|
@ -130,18 +245,21 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public void GetTagHelpers_ReturnsCatchAllsWithEveryTagName()
|
||||
public void GetDescriptors_ReturnsCatchAllsWithEveryTagName()
|
||||
{
|
||||
// Arrange
|
||||
var divDescriptor = new TagHelperDescriptor("div", "foo1", "SomeAssembly");
|
||||
var spanDescriptor = new TagHelperDescriptor("span", "foo2", "SomeAssembly");
|
||||
var catchAllDescriptor = new TagHelperDescriptor("*", "foo3", "SomeAssembly");
|
||||
var catchAllDescriptor = new TagHelperDescriptor(
|
||||
TagHelperDescriptorProvider.CatchAllDescriptorTarget,
|
||||
"foo3",
|
||||
"SomeAssembly");
|
||||
var descriptors = new TagHelperDescriptor[] { divDescriptor, spanDescriptor, catchAllDescriptor };
|
||||
var provider = new TagHelperDescriptorProvider(descriptors);
|
||||
|
||||
// Act
|
||||
var divDescriptors = provider.GetTagHelpers("div");
|
||||
var spanDescriptors = provider.GetTagHelpers("span");
|
||||
var divDescriptors = provider.GetDescriptors("div", attributeNames: Enumerable.Empty<string>());
|
||||
var spanDescriptors = provider.GetDescriptors("span", attributeNames: Enumerable.Empty<string>());
|
||||
|
||||
// Assert
|
||||
// For divs
|
||||
|
|
@ -156,7 +274,7 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public void GetTagHelpers_DuplicateDescriptorsAreNotPartOfTagHelperDescriptorPool()
|
||||
public void GetDescriptors_DuplicateDescriptorsAreNotPartOfTagHelperDescriptorPool()
|
||||
{
|
||||
// Arrange
|
||||
var divDescriptor = new TagHelperDescriptor("div", "foo1", "SomeAssembly");
|
||||
|
|
@ -164,7 +282,7 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
|
|||
var provider = new TagHelperDescriptorProvider(descriptors);
|
||||
|
||||
// Act
|
||||
var retrievedDescriptors = provider.GetTagHelpers("div");
|
||||
var retrievedDescriptors = provider.GetDescriptors("div", attributeNames: Enumerable.Empty<string>());
|
||||
|
||||
// Assert
|
||||
var descriptor = Assert.Single(retrievedDescriptors);
|
||||
|
|
@ -174,11 +292,12 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
|
|||
private static TagHelperDescriptor CreatePrefixedDescriptor(string prefix, string tagName, string typeName)
|
||||
{
|
||||
return new TagHelperDescriptor(
|
||||
prefix,
|
||||
tagName,
|
||||
typeName,
|
||||
assemblyName: "SomeAssembly",
|
||||
attributes: Enumerable.Empty<TagHelperAttributeDescriptor>());
|
||||
prefix,
|
||||
tagName,
|
||||
typeName,
|
||||
assemblyName: "SomeAssembly",
|
||||
attributes: Enumerable.Empty<TagHelperAttributeDescriptor>(),
|
||||
requiredAttributes: Enumerable.Empty<string>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -19,6 +19,867 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
|
|||
{
|
||||
public class TagHelperParseTreeRewriterTest : CsHtmlMarkupParserTestBase
|
||||
{
|
||||
public static TheoryData RequiredAttributeData
|
||||
{
|
||||
get
|
||||
{
|
||||
var factory = CreateDefaultSpanFactory();
|
||||
var blockFactory = new BlockFactory(factory);
|
||||
var dateTimeNow = new MarkupBlock(
|
||||
new MarkupBlock(
|
||||
new ExpressionBlock(
|
||||
factory.CodeTransition(),
|
||||
factory.Code("DateTime.Now")
|
||||
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
|
||||
.Accepts(AcceptedCharacters.NonWhiteSpace))));
|
||||
|
||||
// documentContent, expectedOutput
|
||||
return new TheoryData<string, MarkupBlock>
|
||||
{
|
||||
{
|
||||
"<p />",
|
||||
new MarkupBlock(blockFactory.MarkupTagBlock("<p />"))
|
||||
},
|
||||
{
|
||||
"<p></p>",
|
||||
new MarkupBlock(
|
||||
blockFactory.MarkupTagBlock("<p>"),
|
||||
blockFactory.MarkupTagBlock("</p>"))
|
||||
},
|
||||
{
|
||||
"<div />",
|
||||
new MarkupBlock(blockFactory.MarkupTagBlock("<div />"))
|
||||
},
|
||||
{
|
||||
"<div></div>",
|
||||
new MarkupBlock(
|
||||
blockFactory.MarkupTagBlock("<div>"),
|
||||
blockFactory.MarkupTagBlock("</div>"))
|
||||
},
|
||||
{
|
||||
"<p class=\"btn\" />",
|
||||
new MarkupBlock(
|
||||
new MarkupTagHelperBlock(
|
||||
"p",
|
||||
selfClosing: true,
|
||||
attributes: new Dictionary<string, SyntaxTreeNode>
|
||||
{
|
||||
["class"] = factory.Markup("btn")
|
||||
}))
|
||||
},
|
||||
{
|
||||
"<p class=\"@DateTime.Now\" />",
|
||||
new MarkupBlock(
|
||||
new MarkupTagHelperBlock(
|
||||
"p",
|
||||
selfClosing: true,
|
||||
attributes: new Dictionary<string, SyntaxTreeNode>
|
||||
{
|
||||
["class"] = dateTimeNow
|
||||
}))
|
||||
},
|
||||
{
|
||||
"<p class=\"btn\">words and spaces</p>",
|
||||
new MarkupBlock(
|
||||
new MarkupTagHelperBlock(
|
||||
"p",
|
||||
attributes: new Dictionary<string, SyntaxTreeNode>
|
||||
{
|
||||
["class"] = factory.Markup("btn")
|
||||
},
|
||||
children: factory.Markup("words and spaces")))
|
||||
},
|
||||
{
|
||||
"<p class=\"@DateTime.Now\">words and spaces</p>",
|
||||
new MarkupBlock(
|
||||
new MarkupTagHelperBlock(
|
||||
"p",
|
||||
attributes: new Dictionary<string, SyntaxTreeNode>
|
||||
{
|
||||
["class"] = dateTimeNow
|
||||
},
|
||||
children: factory.Markup("words and spaces")))
|
||||
},
|
||||
{
|
||||
"<p class=\"btn\">words<strong>and</strong>spaces</p>",
|
||||
new MarkupBlock(
|
||||
new MarkupTagHelperBlock(
|
||||
"p",
|
||||
attributes: new Dictionary<string, SyntaxTreeNode>
|
||||
{
|
||||
["class"] = factory.Markup("btn")
|
||||
},
|
||||
children: new SyntaxTreeNode[]
|
||||
{
|
||||
factory.Markup("words"),
|
||||
blockFactory.MarkupTagBlock("<strong>"),
|
||||
factory.Markup("and"),
|
||||
blockFactory.MarkupTagBlock("</strong>"),
|
||||
factory.Markup("spaces")
|
||||
}))
|
||||
},
|
||||
{
|
||||
"<strong catchAll=\"hi\" />",
|
||||
new MarkupBlock(
|
||||
new MarkupTagHelperBlock(
|
||||
"strong",
|
||||
selfClosing: true,
|
||||
attributes: new Dictionary<string, SyntaxTreeNode>
|
||||
{
|
||||
["catchAll"] = factory.Markup("hi")
|
||||
}))
|
||||
},
|
||||
{
|
||||
"<strong catchAll=\"@DateTime.Now\" />",
|
||||
new MarkupBlock(
|
||||
new MarkupTagHelperBlock(
|
||||
"strong",
|
||||
selfClosing: true,
|
||||
attributes: new Dictionary<string, SyntaxTreeNode>
|
||||
{
|
||||
["catchAll"] = dateTimeNow
|
||||
}))
|
||||
},
|
||||
{
|
||||
"<strong catchAll=\"hi\">words and spaces</strong>",
|
||||
new MarkupBlock(
|
||||
new MarkupTagHelperBlock(
|
||||
"strong",
|
||||
attributes: new Dictionary<string, SyntaxTreeNode>
|
||||
{
|
||||
["catchAll"] = factory.Markup("hi")
|
||||
},
|
||||
children: factory.Markup("words and spaces")))
|
||||
},
|
||||
{
|
||||
"<strong catchAll=\"@DateTime.Now\">words and spaces</strong>",
|
||||
new MarkupBlock(
|
||||
new MarkupTagHelperBlock(
|
||||
"strong",
|
||||
attributes: new Dictionary<string, SyntaxTreeNode>
|
||||
{
|
||||
["catchAll"] = dateTimeNow
|
||||
},
|
||||
children: factory.Markup("words and spaces")))
|
||||
},
|
||||
{
|
||||
"<div class=\"btn\" />",
|
||||
new MarkupBlock(
|
||||
new MarkupTagBlock(
|
||||
factory.Markup("<div"),
|
||||
new MarkupBlock(
|
||||
new AttributeBlockCodeGenerator(
|
||||
name: "class",
|
||||
prefix: new LocationTagged<string>(" class=\"", 4, 0, 4),
|
||||
suffix: new LocationTagged<string>("\"", 15, 0, 15)),
|
||||
factory.Markup(" class=\"").With(SpanCodeGenerator.Null),
|
||||
factory.Markup("btn").With(
|
||||
new LiteralAttributeCodeGenerator(
|
||||
prefix: new LocationTagged<string>(string.Empty, 12, 0, 12),
|
||||
value: new LocationTagged<string>("btn", 12, 0, 12))),
|
||||
factory.Markup("\"").With(SpanCodeGenerator.Null)),
|
||||
factory.Markup(" />")))
|
||||
},
|
||||
{
|
||||
"<div class=\"btn\"></div>",
|
||||
new MarkupBlock(
|
||||
new MarkupTagBlock(
|
||||
factory.Markup("<div"),
|
||||
new MarkupBlock(
|
||||
new AttributeBlockCodeGenerator(
|
||||
name: "class",
|
||||
prefix: new LocationTagged<string>(" class=\"", 4, 0, 4),
|
||||
suffix: new LocationTagged<string>("\"", 15, 0, 15)),
|
||||
factory.Markup(" class=\"").With(SpanCodeGenerator.Null),
|
||||
factory.Markup("btn").With(
|
||||
new LiteralAttributeCodeGenerator(
|
||||
prefix: new LocationTagged<string>(string.Empty, 12, 0, 12),
|
||||
value: new LocationTagged<string>("btn", 12, 0, 12))),
|
||||
factory.Markup("\"").With(SpanCodeGenerator.Null)),
|
||||
factory.Markup(">")),
|
||||
blockFactory.MarkupTagBlock("</div>"))
|
||||
},
|
||||
{
|
||||
"<p notRequired=\"a\" class=\"btn\" />",
|
||||
new MarkupBlock(
|
||||
new MarkupTagHelperBlock(
|
||||
"p",
|
||||
selfClosing: true,
|
||||
attributes: new Dictionary<string, SyntaxTreeNode>
|
||||
{
|
||||
["notRequired"] = factory.Markup("a"),
|
||||
["class"] = factory.Markup("btn")
|
||||
}))
|
||||
},
|
||||
{
|
||||
"<p notRequired=\"@DateTime.Now\" class=\"btn\" />",
|
||||
new MarkupBlock(
|
||||
new MarkupTagHelperBlock(
|
||||
"p",
|
||||
selfClosing: true,
|
||||
attributes: new Dictionary<string, SyntaxTreeNode>
|
||||
{
|
||||
["notRequired"] = dateTimeNow,
|
||||
["class"] = factory.Markup("btn")
|
||||
}))
|
||||
},
|
||||
{
|
||||
"<p notRequired=\"a\" class=\"btn\">words and spaces</p>",
|
||||
new MarkupBlock(
|
||||
new MarkupTagHelperBlock(
|
||||
"p",
|
||||
attributes: new Dictionary<string, SyntaxTreeNode>
|
||||
{
|
||||
["notRequired"] = factory.Markup("a"),
|
||||
["class"] = factory.Markup("btn")
|
||||
},
|
||||
children: factory.Markup("words and spaces")))
|
||||
},
|
||||
{
|
||||
"<div style=\"\" class=\"btn\" />",
|
||||
new MarkupBlock(
|
||||
new MarkupTagHelperBlock(
|
||||
"div",
|
||||
selfClosing: true,
|
||||
attributes: new Dictionary<string, SyntaxTreeNode>
|
||||
{
|
||||
["style"] = new MarkupBlock(),
|
||||
["class"] = factory.Markup("btn")
|
||||
}))
|
||||
},
|
||||
{
|
||||
"<div style=\"@DateTime.Now\" class=\"btn\" />",
|
||||
new MarkupBlock(
|
||||
new MarkupTagHelperBlock(
|
||||
"div",
|
||||
selfClosing: true,
|
||||
attributes: new Dictionary<string, SyntaxTreeNode>
|
||||
{
|
||||
["style"] = dateTimeNow,
|
||||
["class"] = factory.Markup("btn")
|
||||
}))
|
||||
},
|
||||
{
|
||||
"<div style=\"\" class=\"btn\">words and spaces</div>",
|
||||
new MarkupBlock(
|
||||
new MarkupTagHelperBlock(
|
||||
"div",
|
||||
attributes: new Dictionary<string, SyntaxTreeNode>
|
||||
{
|
||||
["style"] = new MarkupBlock(),
|
||||
["class"] = factory.Markup("btn")
|
||||
},
|
||||
children: factory.Markup("words and spaces")))
|
||||
},
|
||||
{
|
||||
"<div style=\"@DateTime.Now\" class=\"@DateTime.Now\">words and spaces</div>",
|
||||
new MarkupBlock(
|
||||
new MarkupTagHelperBlock(
|
||||
"div",
|
||||
attributes: new Dictionary<string, SyntaxTreeNode>
|
||||
{
|
||||
["style"] = dateTimeNow,
|
||||
["class"] = dateTimeNow
|
||||
},
|
||||
children: factory.Markup("words and spaces")))
|
||||
},
|
||||
{
|
||||
"<div style=\"\" class=\"btn\">words<strong>and</strong>spaces</div>",
|
||||
new MarkupBlock(
|
||||
new MarkupTagHelperBlock(
|
||||
"div",
|
||||
attributes: new Dictionary<string, SyntaxTreeNode>
|
||||
{
|
||||
["style"] = new MarkupBlock(),
|
||||
["class"] = factory.Markup("btn")
|
||||
},
|
||||
children: new SyntaxTreeNode[]
|
||||
{
|
||||
factory.Markup("words"),
|
||||
blockFactory.MarkupTagBlock("<strong>"),
|
||||
factory.Markup("and"),
|
||||
blockFactory.MarkupTagBlock("</strong>"),
|
||||
factory.Markup("spaces")
|
||||
}))
|
||||
},
|
||||
{
|
||||
"<p class=\"btn\" catchAll=\"hi\" />",
|
||||
new MarkupBlock(
|
||||
new MarkupTagHelperBlock(
|
||||
"p",
|
||||
selfClosing: true,
|
||||
attributes: new Dictionary<string, SyntaxTreeNode>
|
||||
{
|
||||
["class"] = factory.Markup("btn"),
|
||||
["catchAll"] = factory.Markup("hi")
|
||||
}))
|
||||
},
|
||||
{
|
||||
"<p class=\"btn\" catchAll=\"hi\">words and spaces</p>",
|
||||
new MarkupBlock(
|
||||
new MarkupTagHelperBlock(
|
||||
"p",
|
||||
attributes: new Dictionary<string, SyntaxTreeNode>
|
||||
{
|
||||
["class"] = factory.Markup("btn"),
|
||||
["catchAll"] = factory.Markup("hi")
|
||||
},
|
||||
children: factory.Markup("words and spaces")))
|
||||
},
|
||||
{
|
||||
"<div style=\"\" class=\"btn\" catchAll=\"hi\" />",
|
||||
new MarkupBlock(
|
||||
new MarkupTagHelperBlock(
|
||||
"div",
|
||||
selfClosing: true,
|
||||
attributes: new Dictionary<string, SyntaxTreeNode>
|
||||
{
|
||||
["style"] = new MarkupBlock(),
|
||||
["class"] = factory.Markup("btn"),
|
||||
["catchAll"] = factory.Markup("hi")
|
||||
}))
|
||||
},
|
||||
{
|
||||
"<div style=\"\" class=\"btn\" catchAll=\"hi\" >words and spaces</div>",
|
||||
new MarkupBlock(
|
||||
new MarkupTagHelperBlock(
|
||||
"div",
|
||||
attributes: new Dictionary<string, SyntaxTreeNode>
|
||||
{
|
||||
["style"] = new MarkupBlock(),
|
||||
["class"] = factory.Markup("btn"),
|
||||
["catchAll"] = factory.Markup("hi")
|
||||
},
|
||||
children: factory.Markup("words and spaces")))
|
||||
},
|
||||
{
|
||||
"<div style=\"@DateTime.Now\" class=\"@DateTime.Now\" catchAll=\"@DateTime.Now\" >words and " +
|
||||
"spaces</div>",
|
||||
new MarkupBlock(
|
||||
new MarkupTagHelperBlock(
|
||||
"div",
|
||||
attributes: new Dictionary<string, SyntaxTreeNode>
|
||||
{
|
||||
["style"] = dateTimeNow,
|
||||
["class"] = dateTimeNow,
|
||||
["catchAll"] = dateTimeNow
|
||||
},
|
||||
children: factory.Markup("words and spaces")))
|
||||
},
|
||||
{
|
||||
"<div style=\"\" class=\"btn\" catchAll=\"hi\" >words<strong>and</strong>spaces</div>",
|
||||
new MarkupBlock(
|
||||
new MarkupTagHelperBlock(
|
||||
"div",
|
||||
attributes: new Dictionary<string, SyntaxTreeNode>
|
||||
{
|
||||
["style"] = new MarkupBlock(),
|
||||
["class"] = factory.Markup("btn"),
|
||||
["catchAll"] = factory.Markup("hi")
|
||||
},
|
||||
children: new SyntaxTreeNode[]
|
||||
{
|
||||
factory.Markup("words"),
|
||||
blockFactory.MarkupTagBlock("<strong>"),
|
||||
factory.Markup("and"),
|
||||
blockFactory.MarkupTagBlock("</strong>"),
|
||||
factory.Markup("spaces")
|
||||
}))
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RequiredAttributeData))]
|
||||
public void Rewrite_RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly(
|
||||
string documentContent,
|
||||
MarkupBlock expectedOutput)
|
||||
{
|
||||
// Arrange
|
||||
var descriptors = new TagHelperDescriptor[]
|
||||
{
|
||||
new TagHelperDescriptor(
|
||||
tagName: "p",
|
||||
typeName: "pTagHelper",
|
||||
assemblyName: "SomeAssembly",
|
||||
attributes: new TagHelperAttributeDescriptor[0],
|
||||
requiredAttributes: new[] { "class" }),
|
||||
new TagHelperDescriptor(
|
||||
tagName: "div",
|
||||
typeName: "divTagHelper",
|
||||
assemblyName: "SomeAssembly",
|
||||
attributes: new TagHelperAttributeDescriptor[0],
|
||||
requiredAttributes: new[] { "class", "style" }),
|
||||
new TagHelperDescriptor(
|
||||
tagName: "*",
|
||||
typeName: "catchAllTagHelper",
|
||||
assemblyName: "SomeAssembly",
|
||||
attributes: new TagHelperAttributeDescriptor[0],
|
||||
requiredAttributes: new[] { "catchAll" })
|
||||
};
|
||||
var descriptorProvider = new TagHelperDescriptorProvider(descriptors);
|
||||
|
||||
// Act & Assert
|
||||
EvaluateData(descriptorProvider, documentContent, expectedOutput, expectedErrors: new RazorError[0]);
|
||||
}
|
||||
|
||||
public static TheoryData NestedRequiredAttributeData
|
||||
{
|
||||
get
|
||||
{
|
||||
var factory = CreateDefaultSpanFactory();
|
||||
var blockFactory = new BlockFactory(factory);
|
||||
var dateTimeNow = new MarkupBlock(
|
||||
new MarkupBlock(
|
||||
new ExpressionBlock(
|
||||
factory.CodeTransition(),
|
||||
factory.Code("DateTime.Now")
|
||||
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
|
||||
.Accepts(AcceptedCharacters.NonWhiteSpace))));
|
||||
|
||||
// documentContent, expectedOutput
|
||||
return new TheoryData<string, MarkupBlock>
|
||||
{
|
||||
{
|
||||
"<p class=\"btn\"><p></p></p>",
|
||||
new MarkupBlock(
|
||||
new MarkupTagHelperBlock(
|
||||
"p",
|
||||
attributes: new Dictionary<string, SyntaxTreeNode>
|
||||
{
|
||||
["class"] = factory.Markup("btn")
|
||||
},
|
||||
children: new[]
|
||||
{
|
||||
blockFactory.MarkupTagBlock("<p>"),
|
||||
blockFactory.MarkupTagBlock("</p>")
|
||||
}))
|
||||
},
|
||||
{
|
||||
"<strong catchAll=\"hi\"><strong></strong></strong>",
|
||||
new MarkupBlock(
|
||||
new MarkupTagHelperBlock(
|
||||
"strong",
|
||||
attributes: new Dictionary<string, SyntaxTreeNode>
|
||||
{
|
||||
["catchAll"] = factory.Markup("hi")
|
||||
},
|
||||
children: new SyntaxTreeNode[]
|
||||
{
|
||||
blockFactory.MarkupTagBlock("<strong>"),
|
||||
blockFactory.MarkupTagBlock("</strong>"),
|
||||
}))
|
||||
},
|
||||
{
|
||||
"<p class=\"btn\"><strong><p></p></strong></p>",
|
||||
new MarkupBlock(
|
||||
new MarkupTagHelperBlock(
|
||||
"p",
|
||||
attributes: new Dictionary<string, SyntaxTreeNode>
|
||||
{
|
||||
["class"] = factory.Markup("btn")
|
||||
},
|
||||
children: new[]
|
||||
{
|
||||
blockFactory.MarkupTagBlock("<strong>"),
|
||||
blockFactory.MarkupTagBlock("<p>"),
|
||||
blockFactory.MarkupTagBlock("</p>"),
|
||||
blockFactory.MarkupTagBlock("</strong>"),
|
||||
}))
|
||||
},
|
||||
{
|
||||
"<strong catchAll=\"hi\"><p><strong></strong></p></strong>",
|
||||
new MarkupBlock(
|
||||
new MarkupTagHelperBlock(
|
||||
"strong",
|
||||
attributes: new Dictionary<string, SyntaxTreeNode>
|
||||
{
|
||||
["catchAll"] = factory.Markup("hi")
|
||||
},
|
||||
children: new SyntaxTreeNode[]
|
||||
{
|
||||
blockFactory.MarkupTagBlock("<p>"),
|
||||
blockFactory.MarkupTagBlock("<strong>"),
|
||||
blockFactory.MarkupTagBlock("</strong>"),
|
||||
blockFactory.MarkupTagBlock("</p>"),
|
||||
}))
|
||||
},
|
||||
{
|
||||
"<p class=\"btn\"><strong catchAll=\"hi\"><p></p></strong></p>",
|
||||
new MarkupBlock(
|
||||
new MarkupTagHelperBlock(
|
||||
"p",
|
||||
attributes: new Dictionary<string, SyntaxTreeNode>
|
||||
{
|
||||
["class"] = factory.Markup("btn")
|
||||
},
|
||||
children: new MarkupTagHelperBlock(
|
||||
"strong",
|
||||
attributes: new Dictionary<string, SyntaxTreeNode>
|
||||
{
|
||||
["catchAll"] = factory.Markup("hi")
|
||||
},
|
||||
children: new[]
|
||||
{
|
||||
blockFactory.MarkupTagBlock("<p>"),
|
||||
blockFactory.MarkupTagBlock("</p>")
|
||||
})))
|
||||
},
|
||||
{
|
||||
"<strong catchAll=\"hi\"><p class=\"btn\"><strong></strong></p></strong>",
|
||||
new MarkupBlock(
|
||||
new MarkupTagHelperBlock(
|
||||
"strong",
|
||||
attributes: new Dictionary<string, SyntaxTreeNode>
|
||||
{
|
||||
["catchAll"] = factory.Markup("hi")
|
||||
},
|
||||
children: new MarkupTagHelperBlock(
|
||||
"p",
|
||||
attributes: new Dictionary<string, SyntaxTreeNode>
|
||||
{
|
||||
["class"] = factory.Markup("btn")
|
||||
},
|
||||
children: new[]
|
||||
{
|
||||
blockFactory.MarkupTagBlock("<strong>"),
|
||||
blockFactory.MarkupTagBlock("</strong>"),
|
||||
})))
|
||||
},
|
||||
{
|
||||
"<p class=\"btn\"><p class=\"btn\"><p></p></p></p>",
|
||||
new MarkupBlock(
|
||||
new MarkupTagHelperBlock(
|
||||
"p",
|
||||
attributes: new Dictionary<string, SyntaxTreeNode>
|
||||
{
|
||||
["class"] = factory.Markup("btn")
|
||||
},
|
||||
children: new MarkupTagHelperBlock(
|
||||
"p",
|
||||
attributes: new Dictionary<string, SyntaxTreeNode>
|
||||
{
|
||||
["class"] = factory.Markup("btn")
|
||||
},
|
||||
children: new[]
|
||||
{
|
||||
blockFactory.MarkupTagBlock("<p>"),
|
||||
blockFactory.MarkupTagBlock("</p>")
|
||||
})))
|
||||
},
|
||||
{
|
||||
"<strong catchAll=\"hi\"><strong catchAll=\"hi\"><strong></strong></strong></strong>",
|
||||
new MarkupBlock(
|
||||
new MarkupTagHelperBlock(
|
||||
"strong",
|
||||
attributes: new Dictionary<string, SyntaxTreeNode>
|
||||
{
|
||||
["catchAll"] = factory.Markup("hi")
|
||||
},
|
||||
children: new MarkupTagHelperBlock(
|
||||
"strong",
|
||||
attributes: new Dictionary<string, SyntaxTreeNode>
|
||||
{
|
||||
["catchAll"] = factory.Markup("hi")
|
||||
},
|
||||
children: new[]
|
||||
{
|
||||
blockFactory.MarkupTagBlock("<strong>"),
|
||||
blockFactory.MarkupTagBlock("</strong>"),
|
||||
})))
|
||||
},
|
||||
{
|
||||
"<p class=\"btn\"><p><p><p class=\"btn\"><p></p></p></p></p></p>",
|
||||
new MarkupBlock(
|
||||
new MarkupTagHelperBlock(
|
||||
"p",
|
||||
attributes: new Dictionary<string, SyntaxTreeNode>
|
||||
{
|
||||
["class"] = factory.Markup("btn")
|
||||
},
|
||||
children: new[]
|
||||
{
|
||||
blockFactory.MarkupTagBlock("<p>"),
|
||||
blockFactory.MarkupTagBlock("<p>"),
|
||||
new MarkupTagHelperBlock(
|
||||
"p",
|
||||
attributes: new Dictionary<string, SyntaxTreeNode>
|
||||
{
|
||||
["class"] = factory.Markup("btn")
|
||||
},
|
||||
children: new[]
|
||||
{
|
||||
blockFactory.MarkupTagBlock("<p>"),
|
||||
blockFactory.MarkupTagBlock("</p>")
|
||||
}),
|
||||
blockFactory.MarkupTagBlock("</p>"),
|
||||
blockFactory.MarkupTagBlock("</p>"),
|
||||
}))
|
||||
},
|
||||
{
|
||||
"<strong catchAll=\"hi\"><strong><strong><strong catchAll=\"hi\"><strong></strong></strong>" +
|
||||
"</strong></strong></strong>",
|
||||
new MarkupBlock(
|
||||
new MarkupTagHelperBlock(
|
||||
"strong",
|
||||
attributes: new Dictionary<string, SyntaxTreeNode>
|
||||
{
|
||||
["catchAll"] = factory.Markup("hi")
|
||||
},
|
||||
children: new[]
|
||||
{
|
||||
blockFactory.MarkupTagBlock("<strong>"),
|
||||
blockFactory.MarkupTagBlock("<strong>"),
|
||||
new MarkupTagHelperBlock(
|
||||
"strong",
|
||||
attributes: new Dictionary<string, SyntaxTreeNode>
|
||||
{
|
||||
["catchAll"] = factory.Markup("hi")
|
||||
},
|
||||
children: new[]
|
||||
{
|
||||
blockFactory.MarkupTagBlock("<strong>"),
|
||||
blockFactory.MarkupTagBlock("</strong>"),
|
||||
}),
|
||||
blockFactory.MarkupTagBlock("</strong>"),
|
||||
blockFactory.MarkupTagBlock("</strong>"),
|
||||
}))
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(NestedRequiredAttributeData))]
|
||||
public void Rewrite_NestedRequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly(
|
||||
string documentContent,
|
||||
MarkupBlock expectedOutput)
|
||||
{
|
||||
// Arrange
|
||||
var descriptors = new TagHelperDescriptor[]
|
||||
{
|
||||
new TagHelperDescriptor(
|
||||
tagName: "p",
|
||||
typeName: "pTagHelper",
|
||||
assemblyName: "SomeAssembly",
|
||||
attributes: new TagHelperAttributeDescriptor[0],
|
||||
requiredAttributes: new[] { "class" }),
|
||||
new TagHelperDescriptor(
|
||||
tagName: "*",
|
||||
typeName: "catchAllTagHelper",
|
||||
assemblyName: "SomeAssembly",
|
||||
attributes: new TagHelperAttributeDescriptor[0],
|
||||
requiredAttributes: new[] { "catchAll" })
|
||||
};
|
||||
var descriptorProvider = new TagHelperDescriptorProvider(descriptors);
|
||||
|
||||
// Act & Assert
|
||||
EvaluateData(descriptorProvider, documentContent, expectedOutput, expectedErrors: new RazorError[0]);
|
||||
}
|
||||
|
||||
public static TheoryData<string, MarkupBlock, RazorError[]> MalformedRequiredAttributeData
|
||||
{
|
||||
get
|
||||
{
|
||||
var factory = CreateDefaultSpanFactory();
|
||||
var blockFactory = new BlockFactory(factory);
|
||||
var errorFormatUnclosed = "Found a malformed '{0}' tag helper. Tag helpers must have a start and " +
|
||||
"end tag or be self closing.";
|
||||
var errorFormatNoCloseAngle = "Missing close angle for tag helper '{0}'.";
|
||||
|
||||
// documentContent, expectedOutput, expectedErrors
|
||||
return new TheoryData<string, MarkupBlock, RazorError[]>
|
||||
{
|
||||
{
|
||||
"<p",
|
||||
new MarkupBlock(blockFactory.MarkupTagBlock("<p")),
|
||||
new RazorError[0]
|
||||
},
|
||||
{
|
||||
"<p class=\"btn\"",
|
||||
new MarkupBlock(
|
||||
new MarkupTagHelperBlock(
|
||||
"p",
|
||||
attributes: new Dictionary<string, SyntaxTreeNode>
|
||||
{
|
||||
["class"] = factory.Markup("btn")
|
||||
})),
|
||||
new[]
|
||||
{
|
||||
new RazorError(
|
||||
string.Format(CultureInfo.InvariantCulture, errorFormatNoCloseAngle, "p"),
|
||||
SourceLocation.Zero),
|
||||
new RazorError(
|
||||
string.Format(CultureInfo.InvariantCulture, errorFormatUnclosed, "p"),
|
||||
SourceLocation.Zero)
|
||||
}
|
||||
},
|
||||
{
|
||||
"<p notRequired=\"hi\" class=\"btn\"",
|
||||
new MarkupBlock(
|
||||
new MarkupTagHelperBlock(
|
||||
"p",
|
||||
attributes: new Dictionary<string, SyntaxTreeNode>
|
||||
{
|
||||
["notRequired"] = factory.Markup("hi"),
|
||||
["class"] = factory.Markup("btn")
|
||||
})),
|
||||
new[]
|
||||
{
|
||||
new RazorError(
|
||||
string.Format(CultureInfo.InvariantCulture, errorFormatNoCloseAngle, "p"),
|
||||
SourceLocation.Zero),
|
||||
new RazorError(
|
||||
string.Format(CultureInfo.InvariantCulture, errorFormatUnclosed, "p"),
|
||||
SourceLocation.Zero)
|
||||
}
|
||||
},
|
||||
{
|
||||
"<p></p",
|
||||
new MarkupBlock(
|
||||
blockFactory.MarkupTagBlock("<p>"),
|
||||
blockFactory.MarkupTagBlock("</p")),
|
||||
new RazorError[0]
|
||||
},
|
||||
{
|
||||
"<p class=\"btn\"></p",
|
||||
new MarkupBlock(
|
||||
new MarkupTagHelperBlock(
|
||||
"p",
|
||||
attributes: new Dictionary<string, SyntaxTreeNode>
|
||||
{
|
||||
["class"] = factory.Markup("btn")
|
||||
})),
|
||||
new[]
|
||||
{
|
||||
new RazorError(
|
||||
string.Format(CultureInfo.InvariantCulture, errorFormatNoCloseAngle, "p"),
|
||||
absoluteIndex: 15, lineIndex: 0, columnIndex: 15)
|
||||
}
|
||||
},
|
||||
{
|
||||
"<p notRequired=\"hi\" class=\"btn\"></p",
|
||||
new MarkupBlock(
|
||||
new MarkupTagHelperBlock(
|
||||
"p",
|
||||
attributes: new Dictionary<string, SyntaxTreeNode>
|
||||
{
|
||||
["notRequired"] = factory.Markup("hi"),
|
||||
["class"] = factory.Markup("btn")
|
||||
})),
|
||||
new[]
|
||||
{
|
||||
new RazorError(
|
||||
string.Format(CultureInfo.InvariantCulture, errorFormatNoCloseAngle, "p"),
|
||||
absoluteIndex: 32, lineIndex: 0, columnIndex: 32)
|
||||
}
|
||||
},
|
||||
{
|
||||
"<p class=\"btn\" <p>",
|
||||
new MarkupBlock(
|
||||
new MarkupTagHelperBlock("p",
|
||||
attributes: new Dictionary<string, SyntaxTreeNode>
|
||||
{
|
||||
["class"] = factory.Markup("btn")
|
||||
},
|
||||
children: blockFactory.MarkupTagBlock("<p>"))),
|
||||
new[]
|
||||
{
|
||||
new RazorError(
|
||||
string.Format(CultureInfo.InvariantCulture, errorFormatNoCloseAngle, "p"),
|
||||
SourceLocation.Zero),
|
||||
new RazorError(
|
||||
string.Format(CultureInfo.InvariantCulture, errorFormatUnclosed, "p"),
|
||||
SourceLocation.Zero),
|
||||
}
|
||||
},
|
||||
{
|
||||
"<p notRequired=\"hi\" class=\"btn\" <p>",
|
||||
new MarkupBlock(
|
||||
new MarkupTagHelperBlock("p",
|
||||
attributes: new Dictionary<string, SyntaxTreeNode>
|
||||
{
|
||||
["notRequired"] = factory.Markup("hi"),
|
||||
["class"] = factory.Markup("btn")
|
||||
},
|
||||
children: blockFactory.MarkupTagBlock("<p>"))),
|
||||
new[]
|
||||
{
|
||||
new RazorError(
|
||||
string.Format(CultureInfo.InvariantCulture, errorFormatNoCloseAngle, "p"),
|
||||
SourceLocation.Zero),
|
||||
new RazorError(
|
||||
string.Format(CultureInfo.InvariantCulture, errorFormatUnclosed, "p"),
|
||||
SourceLocation.Zero),
|
||||
}
|
||||
},
|
||||
{
|
||||
"<p class=\"btn\" </p",
|
||||
new MarkupBlock(
|
||||
new MarkupTagHelperBlock(
|
||||
"p",
|
||||
attributes: new Dictionary<string, SyntaxTreeNode>
|
||||
{
|
||||
["class"] = factory.Markup("btn")
|
||||
})),
|
||||
new[]
|
||||
{
|
||||
new RazorError(
|
||||
string.Format(CultureInfo.InvariantCulture, errorFormatNoCloseAngle, "p"),
|
||||
SourceLocation.Zero),
|
||||
new RazorError(
|
||||
string.Format(CultureInfo.InvariantCulture, errorFormatNoCloseAngle, "p"),
|
||||
absoluteIndex: 15, lineIndex: 0, columnIndex: 15)
|
||||
}
|
||||
},
|
||||
{
|
||||
"<p notRequired=\"hi\" class=\"btn\" </p",
|
||||
new MarkupBlock(
|
||||
new MarkupTagHelperBlock(
|
||||
"p",
|
||||
attributes: new Dictionary<string, SyntaxTreeNode>
|
||||
{
|
||||
["notRequired"] = factory.Markup("hi"),
|
||||
["class"] = factory.Markup("btn")
|
||||
})),
|
||||
new[]
|
||||
{
|
||||
new RazorError(
|
||||
string.Format(CultureInfo.InvariantCulture, errorFormatNoCloseAngle, "p"),
|
||||
SourceLocation.Zero),
|
||||
new RazorError(
|
||||
string.Format(CultureInfo.InvariantCulture, errorFormatNoCloseAngle, "p"),
|
||||
absoluteIndex: 32, lineIndex: 0, columnIndex: 32)
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(MalformedRequiredAttributeData))]
|
||||
public void Rewrite_RequiredAttributeDescriptorsCreateMalformedTagHelperBlocksCorrectly(
|
||||
string documentContent,
|
||||
MarkupBlock expectedOutput,
|
||||
RazorError[] expectedErrors)
|
||||
{
|
||||
// Arrange
|
||||
var descriptors = new TagHelperDescriptor[]
|
||||
{
|
||||
new TagHelperDescriptor(
|
||||
tagName: "p",
|
||||
typeName: "pTagHelper",
|
||||
assemblyName: "SomeAssembly",
|
||||
attributes: new TagHelperAttributeDescriptor[0],
|
||||
requiredAttributes: new[] { "class" })
|
||||
};
|
||||
var descriptorProvider = new TagHelperDescriptorProvider(descriptors);
|
||||
|
||||
// Act & Assert
|
||||
EvaluateData(descriptorProvider, documentContent, expectedOutput, expectedErrors);
|
||||
}
|
||||
|
||||
public static TheoryData PrefixedTagHelperBoundData
|
||||
{
|
||||
get
|
||||
|
|
@ -32,7 +893,8 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
|
|||
tagName: "myth",
|
||||
typeName: "mythTagHelper",
|
||||
assemblyName: "SomeAssembly",
|
||||
attributes: Enumerable.Empty<TagHelperAttributeDescriptor>()),
|
||||
attributes: Enumerable.Empty<TagHelperAttributeDescriptor>(),
|
||||
requiredAttributes: Enumerable.Empty<string>()),
|
||||
new TagHelperDescriptor(
|
||||
prefix: "th:",
|
||||
tagName: "myth2",
|
||||
|
|
@ -44,7 +906,8 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
|
|||
name: "bound",
|
||||
propertyName: "Bound",
|
||||
typeName: typeof(bool).FullName),
|
||||
})
|
||||
},
|
||||
requiredAttributes: Enumerable.Empty<string>())
|
||||
};
|
||||
var availableDescriptorsText = new TagHelperDescriptor[]
|
||||
{
|
||||
|
|
@ -53,7 +916,8 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
|
|||
tagName: "myth",
|
||||
typeName: "mythTagHelper",
|
||||
assemblyName: "SomeAssembly",
|
||||
attributes: Enumerable.Empty<TagHelperAttributeDescriptor>()),
|
||||
attributes: Enumerable.Empty<TagHelperAttributeDescriptor>(),
|
||||
requiredAttributes: Enumerable.Empty<string>()),
|
||||
new TagHelperDescriptor(
|
||||
prefix: "PREFIX",
|
||||
tagName: "myth2",
|
||||
|
|
@ -65,7 +929,8 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
|
|||
name: "bound",
|
||||
propertyName: "Bound",
|
||||
typeName: typeof(bool).FullName),
|
||||
})
|
||||
},
|
||||
requiredAttributes: Enumerable.Empty<string>())
|
||||
};
|
||||
var availableDescriptorsCatchAll = new TagHelperDescriptor[]
|
||||
{
|
||||
|
|
@ -74,7 +939,8 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
|
|||
tagName: "*",
|
||||
typeName: "mythTagHelper",
|
||||
assemblyName: "SomeAssembly",
|
||||
attributes: Enumerable.Empty<TagHelperAttributeDescriptor>()),
|
||||
attributes: Enumerable.Empty<TagHelperAttributeDescriptor>(),
|
||||
requiredAttributes: Enumerable.Empty<string>()),
|
||||
};
|
||||
|
||||
// documentContent, expectedOutput, availableDescriptors
|
||||
|
|
@ -280,8 +1146,8 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
|
|||
[Theory]
|
||||
[MemberData(nameof(PrefixedTagHelperBoundData))]
|
||||
public void Rewrite_AllowsPrefixedTagHelpers(
|
||||
string documentContent,
|
||||
MarkupBlock expectedOutput,
|
||||
string documentContent,
|
||||
MarkupBlock expectedOutput,
|
||||
IEnumerable<TagHelperDescriptor> availableDescriptors)
|
||||
{
|
||||
// Arrange
|
||||
|
|
@ -289,9 +1155,9 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
|
|||
|
||||
// Act & Assert
|
||||
EvaluateData(
|
||||
descriptorProvider,
|
||||
documentContent,
|
||||
expectedOutput,
|
||||
descriptorProvider,
|
||||
documentContent,
|
||||
expectedOutput,
|
||||
expectedErrors: Enumerable.Empty<RazorError>());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,60 @@
|
|||
namespace TestOutput
|
||||
{
|
||||
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
public class AttributeTargetingTagHelpers
|
||||
{
|
||||
private static object @__o;
|
||||
private void @__RazorDesignTimeHelpers__()
|
||||
{
|
||||
#pragma warning disable 219
|
||||
string __tagHelperDirectiveSyntaxHelper = null;
|
||||
__tagHelperDirectiveSyntaxHelper =
|
||||
#line 1 "AttributeTargetingTagHelpers.cshtml"
|
||||
"*, something"
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
;
|
||||
#pragma warning restore 219
|
||||
}
|
||||
#line hidden
|
||||
private PTagHelper __PTagHelper = null;
|
||||
private CatchAllTagHelper __CatchAllTagHelper = null;
|
||||
private InputTagHelper __InputTagHelper = null;
|
||||
private InputTagHelper2 __InputTagHelper2 = null;
|
||||
#line hidden
|
||||
public AttributeTargetingTagHelpers()
|
||||
{
|
||||
}
|
||||
|
||||
#pragma warning disable 1998
|
||||
public override async Task ExecuteAsync()
|
||||
{
|
||||
__CatchAllTagHelper = CreateTagHelper<CatchAllTagHelper>();
|
||||
__InputTagHelper = CreateTagHelper<InputTagHelper>();
|
||||
__InputTagHelper.Type = "checkbox";
|
||||
__InputTagHelper2 = CreateTagHelper<InputTagHelper2>();
|
||||
__InputTagHelper2.Type = __InputTagHelper.Type;
|
||||
#line 6 "AttributeTargetingTagHelpers.cshtml"
|
||||
__InputTagHelper2.Checked = true;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
__InputTagHelper = CreateTagHelper<InputTagHelper>();
|
||||
__InputTagHelper.Type = "checkbox";
|
||||
__InputTagHelper2 = CreateTagHelper<InputTagHelper2>();
|
||||
__InputTagHelper2.Type = __InputTagHelper.Type;
|
||||
#line 7 "AttributeTargetingTagHelpers.cshtml"
|
||||
__InputTagHelper2.Checked = true;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
__CatchAllTagHelper = CreateTagHelper<CatchAllTagHelper>();
|
||||
__PTagHelper = CreateTagHelper<PTagHelper>();
|
||||
}
|
||||
#pragma warning restore 1998
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
#pragma checksum "AttributeTargetingTagHelpers.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "e5aa16869aaf5543b30289e98ee5733b08bfe423"
|
||||
namespace TestOutput
|
||||
{
|
||||
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
public class AttributeTargetingTagHelpers
|
||||
{
|
||||
#line hidden
|
||||
#pragma warning disable 0414
|
||||
private TagHelperContent __tagHelperStringValueBuffer = null;
|
||||
#pragma warning restore 0414
|
||||
private TagHelperExecutionContext __tagHelperExecutionContext = null;
|
||||
private TagHelperRunner __tagHelperRunner = null;
|
||||
private TagHelperScopeManager __tagHelperScopeManager = new TagHelperScopeManager();
|
||||
private PTagHelper __PTagHelper = null;
|
||||
private CatchAllTagHelper __CatchAllTagHelper = null;
|
||||
private InputTagHelper __InputTagHelper = null;
|
||||
private InputTagHelper2 __InputTagHelper2 = null;
|
||||
#line hidden
|
||||
public AttributeTargetingTagHelpers()
|
||||
{
|
||||
}
|
||||
|
||||
#pragma warning disable 1998
|
||||
public override async Task ExecuteAsync()
|
||||
{
|
||||
__tagHelperRunner = __tagHelperRunner ?? new TagHelperRunner();
|
||||
Instrumentation.BeginContext(30, 2, true);
|
||||
WriteLiteral("\r\n");
|
||||
Instrumentation.EndContext();
|
||||
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", false, "test", async() => {
|
||||
WriteLiteral("\r\n <p>");
|
||||
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("strong", false, "test", async() => {
|
||||
WriteLiteral("Hello");
|
||||
}
|
||||
, StartTagHelperWritingScope, EndTagHelperWritingScope);
|
||||
__CatchAllTagHelper = CreateTagHelper<CatchAllTagHelper>();
|
||||
__tagHelperExecutionContext.Add(__CatchAllTagHelper);
|
||||
__tagHelperExecutionContext.AddHtmlAttribute("catchAll", "hi");
|
||||
__tagHelperExecutionContext.Output = __tagHelperRunner.RunAsync(__tagHelperExecutionContext).Result;
|
||||
WriteTagHelperAsync(__tagHelperExecutionContext).Wait();
|
||||
__tagHelperExecutionContext = __tagHelperScopeManager.End();
|
||||
WriteLiteral("<strong>World</strong></p>\r\n <input checked=\"true\" />\r\n ");
|
||||
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
|
||||
}
|
||||
, StartTagHelperWritingScope, EndTagHelperWritingScope);
|
||||
__InputTagHelper = CreateTagHelper<InputTagHelper>();
|
||||
__tagHelperExecutionContext.Add(__InputTagHelper);
|
||||
__InputTagHelper.Type = "checkbox";
|
||||
__tagHelperExecutionContext.AddTagHelperAttribute("type", __InputTagHelper.Type);
|
||||
__InputTagHelper2 = CreateTagHelper<InputTagHelper2>();
|
||||
__tagHelperExecutionContext.Add(__InputTagHelper2);
|
||||
__InputTagHelper2.Type = __InputTagHelper.Type;
|
||||
#line 6 "AttributeTargetingTagHelpers.cshtml"
|
||||
__InputTagHelper2.Checked = true;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
__tagHelperExecutionContext.AddTagHelperAttribute("checked", __InputTagHelper2.Checked);
|
||||
__tagHelperExecutionContext.Output = __tagHelperRunner.RunAsync(__tagHelperExecutionContext).Result;
|
||||
WriteTagHelperAsync(__tagHelperExecutionContext).Wait();
|
||||
__tagHelperExecutionContext = __tagHelperScopeManager.End();
|
||||
WriteLiteral("\r\n ");
|
||||
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
|
||||
}
|
||||
, StartTagHelperWritingScope, EndTagHelperWritingScope);
|
||||
__InputTagHelper = CreateTagHelper<InputTagHelper>();
|
||||
__tagHelperExecutionContext.Add(__InputTagHelper);
|
||||
__InputTagHelper.Type = "checkbox";
|
||||
__tagHelperExecutionContext.AddTagHelperAttribute("type", __InputTagHelper.Type);
|
||||
__InputTagHelper2 = CreateTagHelper<InputTagHelper2>();
|
||||
__tagHelperExecutionContext.Add(__InputTagHelper2);
|
||||
__InputTagHelper2.Type = __InputTagHelper.Type;
|
||||
#line 7 "AttributeTargetingTagHelpers.cshtml"
|
||||
__InputTagHelper2.Checked = true;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
__tagHelperExecutionContext.AddTagHelperAttribute("checked", __InputTagHelper2.Checked);
|
||||
__CatchAllTagHelper = CreateTagHelper<CatchAllTagHelper>();
|
||||
__tagHelperExecutionContext.Add(__CatchAllTagHelper);
|
||||
__tagHelperExecutionContext.AddHtmlAttribute("catchAll", "hi");
|
||||
__tagHelperExecutionContext.Output = __tagHelperRunner.RunAsync(__tagHelperExecutionContext).Result;
|
||||
WriteTagHelperAsync(__tagHelperExecutionContext).Wait();
|
||||
__tagHelperExecutionContext = __tagHelperScopeManager.End();
|
||||
WriteLiteral("\r\n");
|
||||
}
|
||||
, StartTagHelperWritingScope, EndTagHelperWritingScope);
|
||||
__PTagHelper = CreateTagHelper<PTagHelper>();
|
||||
__tagHelperExecutionContext.Add(__PTagHelper);
|
||||
__tagHelperExecutionContext.AddHtmlAttribute("class", "btn");
|
||||
__tagHelperExecutionContext.Output = __tagHelperRunner.RunAsync(__tagHelperExecutionContext).Result;
|
||||
WriteTagHelperAsync(__tagHelperExecutionContext).Wait();
|
||||
__tagHelperExecutionContext = __tagHelperScopeManager.End();
|
||||
}
|
||||
#pragma warning restore 1998
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
@addTagHelper "*, something"
|
||||
|
||||
<p class="btn">
|
||||
<p><strong catchAll="hi">Hello</strong><strong>World</strong></p>
|
||||
<input checked="true" />
|
||||
<input type="checkbox" checked="true" />
|
||||
<input type="checkbox" checked="true" catchAll="hi" />
|
||||
</p>
|
||||
Loading…
Reference in New Issue