Add OutputElementHintAttribute to control design time IntelliSense for TagHelpers.

- Decided to not have the attribute inheritable since TargetElement is not inheritable.
- Added tests to validate serialization, deserialization and construction of TagHelperDescriptors with OutputElementHints.
- Changed TagHelperUsageDescriptor to TagHelperDesignTimeDescriptor and TagHelperAttributeDesignTImeDescriptor.

#382
This commit is contained in:
N. Taylor Mullen 2015-06-23 11:54:31 -07:00
parent eda9edc41d
commit 85be731e2b
23 changed files with 476 additions and 224 deletions

View File

@ -0,0 +1,31 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.Framework.Internal;
namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
{
/// <summary>
/// Provides a hint of the <see cref="ITagHelper"/>'s output element.
/// </summary>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
public sealed class OutputElementHintAttribute : Attribute
{
/// <summary>
/// Instantiates a new instance of the <see cref="OutputElementHintAttribute"/> class.
/// </summary>
/// <param name="outputElement">
/// The HTML element the <see cref="ITagHelper"/> may output.
/// </param>
public OutputElementHintAttribute([NotNull] string outputElement)
{
OutputElement = outputElement;
}
/// <summary>
/// The HTML element the <see cref="ITagHelper"/> may output.
/// </summary>
public string OutputElement { get; }
}
}

View File

@ -82,12 +82,12 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
IEnumerable<TargetElementAttribute> targetElementAttributes,
bool designTime)
{
TagHelperUsageDescriptor typeUsageDescriptor = null;
TagHelperDesignTimeDescriptor typeDesignTimeDescriptor = null;
#if !DNXCORE50
if (designTime)
{
typeUsageDescriptor = TagHelperUsageDescriptorFactory.CreateDescriptor(typeInfo.GetType());
typeDesignTimeDescriptor = TagHelperDesignTimeDescriptorFactory.CreateDescriptor(typeInfo.GetType());
}
#endif
@ -111,7 +111,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
assemblyName,
attributeDescriptors,
requiredAttributes: Enumerable.Empty<string>(),
usageDescriptor: typeUsageDescriptor)
designTimeDescriptor: typeDesignTimeDescriptor)
};
}
@ -122,7 +122,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
assemblyName,
attributeDescriptors,
attribute,
typeUsageDescriptor));
typeDesignTimeDescriptor));
}
private static TagHelperDescriptor BuildTagHelperDescriptor(
@ -130,7 +130,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
string assemblyName,
IEnumerable<TagHelperAttributeDescriptor> attributeDescriptors,
TargetElementAttribute targetElementAttribute,
TagHelperUsageDescriptor usageDescriptor)
TagHelperDesignTimeDescriptor designTimeDescriptor)
{
var requiredAttributes = GetCommaSeparatedValues(targetElementAttribute.Attributes);
@ -140,7 +140,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
assemblyName,
attributeDescriptors,
requiredAttributes,
usageDescriptor);
designTimeDescriptor);
}
private static TagHelperDescriptor BuildTagHelperDescriptor(
@ -149,7 +149,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
string assemblyName,
IEnumerable<TagHelperAttributeDescriptor> attributeDescriptors,
IEnumerable<string> requiredAttributes,
TagHelperUsageDescriptor usageDescriptor)
TagHelperDesignTimeDescriptor designTimeDescriptor)
{
return new TagHelperDescriptor(
prefix: string.Empty,
@ -158,7 +158,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
assemblyName: assemblyName,
attributes: attributeDescriptors,
requiredAttributes: requiredAttributes,
usageDescriptor: usageDescriptor);
designTimeDescriptor: designTimeDescriptor);
}
/// <summary>
@ -462,12 +462,13 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
bool isIndexer,
bool designTime)
{
TagHelperUsageDescriptor propertyUsageDescriptor = null;
TagHelperAttributeDesignTimeDescriptor propertyDesignTimeDescriptor = null;
#if !DNXCORE50
if (designTime)
{
propertyUsageDescriptor = TagHelperUsageDescriptorFactory.CreateDescriptor(property);
propertyDesignTimeDescriptor =
TagHelperDesignTimeDescriptorFactory.CreateAttributeDescriptor(property);
}
#endif
@ -476,7 +477,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
property.Name,
typeName,
isIndexer,
propertyUsageDescriptor);
propertyDesignTimeDescriptor);
}
private static bool IsAccessibleProperty(PropertyInfo property)

View File

@ -154,7 +154,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
descriptor.AssemblyName,
descriptor.Attributes,
descriptor.RequiredAttributes,
descriptor.UsageDescriptor));
descriptor.DesignTimeDescriptor));
}
return descriptors;

View File

@ -14,40 +14,69 @@ using Microsoft.Framework.Internal;
namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
{
/// <summary>
/// Factory for providing <see cref="TagHelperUsageDescriptor"/>s from <see cref="Type"/>s and
/// <see cref="PropertyInfo"/>s.
/// Factory for providing <see cref="TagHelperDesignTimeDescriptor"/>s from <see cref="Type"/>s and
/// <see cref="TagHelperAttributeDesignTimeDescriptor"/>s from <see cref="PropertyInfo"/>s.
/// </summary>
public static class TagHelperUsageDescriptorFactory
public static class TagHelperDesignTimeDescriptorFactory
{
/// <summary>
/// Creates a <see cref="TagHelperUsageDescriptor"/> from the given <paramref name="type"/>.
/// Creates a <see cref="TagHelperDesignTimeDescriptor"/> from the given <paramref name="type"/>.
/// </summary>
/// <param name="type">The <see cref="Type"/> to create a <see cref="TagHelperUsageDescriptor"/> from.</param>
/// <returns>A <see cref="TagHelperUsageDescriptor"/> that describes the summary and remarks XML documentation
/// <param name="type">
/// The <see cref="Type"/> to create a <see cref="TagHelperDesignTimeDescriptor"/> from.
/// </param>
/// <returns>A <see cref="TagHelperDesignTimeDescriptor"/> that describes design time specific information
/// for the given <paramref name="type"/>.</returns>
public static TagHelperUsageDescriptor CreateDescriptor([NotNull] Type type)
public static TagHelperDesignTimeDescriptor CreateDescriptor([NotNull] Type type)
{
var id = XmlDocumentationProvider.GetId(type);
var documentationDescriptor = CreateDocumentationDescriptor(type.Assembly, id);
return CreateDescriptorCore(type.Assembly, id);
// Purposefully not using the TypeInfo.GetCustomAttributes method here to make it easier to mock the Type.
var outputElementHintAttribute = type
.GetCustomAttributes(inherit: false)
?.OfType<OutputElementHintAttribute>()
.FirstOrDefault();
var outputElementHint = outputElementHintAttribute?.OutputElement;
if (documentationDescriptor != null || outputElementHint != null)
{
return new TagHelperDesignTimeDescriptor(
documentationDescriptor?.Summary,
documentationDescriptor?.Remarks,
outputElementHint);
}
return null;
}
/// <summary>
/// Creates a <see cref="TagHelperUsageDescriptor"/> from the given <paramref name="propertyInfo"/>.
/// Creates a <see cref="TagHelperAttributeDesignTimeDescriptor"/> from the given
/// <paramref name="propertyInfo"/>.
/// </summary>
/// <param name="propertyInfo">The <see cref="PropertyInfo"/> to create a
/// <see cref="TagHelperUsageDescriptor"/> from.</param>
/// <returns>A <see cref="TagHelperUsageDescriptor"/> that describes the summary and remarks XML documentation
/// for the given <paramref name="propertyInfo"/>.</returns>
public static TagHelperUsageDescriptor CreateDescriptor([NotNull] PropertyInfo propertyInfo)
/// <param name="propertyInfo">
/// The <see cref="PropertyInfo"/> to create a <see cref="TagHelperAttributeDesignTimeDescriptor"/> from.
/// </param>
/// <returns>A <see cref="TagHelperAttributeDesignTimeDescriptor"/> that describes design time specific
/// information for the given <paramref name="propertyInfo"/>.</returns>
public static TagHelperAttributeDesignTimeDescriptor CreateAttributeDescriptor(
[NotNull] PropertyInfo propertyInfo)
{
var id = XmlDocumentationProvider.GetId(propertyInfo);
var declaringAssembly = propertyInfo.DeclaringType.Assembly;
var documentationDescriptor = CreateDocumentationDescriptor(declaringAssembly, id);
return CreateDescriptorCore(declaringAssembly, id);
if (documentationDescriptor != null)
{
return new TagHelperAttributeDesignTimeDescriptor(
documentationDescriptor.Summary,
documentationDescriptor.Remarks);
}
return null;
}
private static TagHelperUsageDescriptor CreateDescriptorCore(Assembly assembly, string id)
private static DocumentationDescriptor CreateDocumentationDescriptor(Assembly assembly, string id)
{
var assemblyLocation = assembly.Location;
@ -77,7 +106,11 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
if (!string.IsNullOrEmpty(summary) || !string.IsNullOrEmpty(remarks))
{
return new TagHelperUsageDescriptor(summary, remarks);
return new DocumentationDescriptor
{
Summary = summary,
Remarks = remarks
};
}
}
@ -157,6 +190,12 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
return xmlDocumentationFile;
}
private class DocumentationDescriptor
{
public string Summary { get; set; }
public string Remarks { get; set; }
}
}
}
#endif

View File

@ -20,7 +20,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
propertyInfo.PropertyType.FullName,
isIndexer: false,
isStringProperty: propertyInfo.PropertyType == typeof(string),
usageDescriptor: null)
designTimeDescriptor: null)
{
}
@ -40,8 +40,8 @@ namespace Microsoft.AspNet.Razor.TagHelpers
/// If <c>true</c> this <see cref="TagHelperAttributeDescriptor"/> is used for dictionary indexer assignments.
/// Otherwise this <see cref="TagHelperAttributeDescriptor"/> is used for property assignment.
/// </param>
/// <param name="usageDescriptor">The <see cref="TagHelperUsageDescriptor"/> that contains information about
/// use of this attribute.</param>
/// <param name="designTimeDescriptor">The <see cref="TagHelperAttributeDesignTimeDescriptor"/> that contains
/// design time information about this attribute.</param>
/// <remarks>
/// HTML attribute names are matched case-insensitively, regardless of <paramref name="isIndexer"/>.
/// </remarks>
@ -50,14 +50,14 @@ namespace Microsoft.AspNet.Razor.TagHelpers
[NotNull] string propertyName,
[NotNull] string typeName,
bool isIndexer,
TagHelperUsageDescriptor usageDescriptor)
TagHelperAttributeDesignTimeDescriptor designTimeDescriptor)
: this(
name,
propertyName,
typeName,
isIndexer,
isStringProperty: string.Equals(typeName, typeof(string).FullName, StringComparison.Ordinal),
usageDescriptor: usageDescriptor)
designTimeDescriptor: designTimeDescriptor)
{
}
@ -68,14 +68,14 @@ namespace Microsoft.AspNet.Razor.TagHelpers
[NotNull] string typeName,
bool isIndexer,
bool isStringProperty,
TagHelperUsageDescriptor usageDescriptor)
TagHelperAttributeDesignTimeDescriptor designTimeDescriptor)
{
Name = name;
PropertyName = propertyName;
TypeName = typeName;
IsIndexer = isIndexer;
IsStringProperty = isStringProperty;
UsageDescriptor = usageDescriptor;
DesignTimeDescriptor = designTimeDescriptor;
}
/// <summary>
@ -119,9 +119,10 @@ namespace Microsoft.AspNet.Razor.TagHelpers
public string TypeName { get; }
/// <summary>
/// The <see cref="TagHelperUsageDescriptor"/> that contains information about use of this attribute.
/// The <see cref="TagHelperAttributeDesignTimeDescriptor"/> that contains design time information about
/// this attribute.
/// </summary>
public TagHelperUsageDescriptor UsageDescriptor { get; }
public TagHelperAttributeDesignTimeDescriptor DesignTimeDescriptor { get; }
/// <summary>
/// Determines whether HTML attribute <paramref name="name"/> matches this

View File

@ -6,14 +6,14 @@ namespace Microsoft.AspNet.Razor.TagHelpers
/// <summary>
/// A metadata class containing information about tag helper use.
/// </summary>
public class TagHelperUsageDescriptor
public class TagHelperAttributeDesignTimeDescriptor
{
/// <summary>
/// Instantiates a new instance of <see cref="TagHelperUsageDescriptor"/>.
/// Instantiates a new instance of <see cref="TagHelperDesignTimeDescriptor"/>.
/// </summary>
/// <param name="summary">A summary on how to use a tag helper.</param>
/// <param name="remarks">Remarks on how to use a tag helper.</param>
public TagHelperUsageDescriptor(string summary, string remarks)
public TagHelperAttributeDesignTimeDescriptor(string summary, string remarks)
{
Summary = summary;
Remarks = remarks;

View File

@ -60,7 +60,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
assemblyName: assemblyName,
attributes: attributes,
requiredAttributes: requiredAttributes,
usageDescriptor: null)
designTimeDescriptor: null)
{
}
@ -82,8 +82,8 @@ namespace Microsoft.AspNet.Razor.TagHelpers
/// <param name="requiredAttributes">
/// The attribute names required for the tag helper to target the HTML tag.
/// </param>
/// <param name="usageDescriptor">The <see cref="TagHelperUsageDescriptor"/> that contains information about
/// how to use the tag helper at design time.</param>
/// <param name="designTimeDescriptor">The <see cref="TagHelperDesignTimeDescriptor"/> that contains design
/// time information about the tag helper.</param>
public TagHelperDescriptor(
string prefix,
[NotNull] string tagName,
@ -91,7 +91,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
[NotNull] string assemblyName,
[NotNull] IEnumerable<TagHelperAttributeDescriptor> attributes,
[NotNull] IEnumerable<string> requiredAttributes,
TagHelperUsageDescriptor usageDescriptor)
TagHelperDesignTimeDescriptor designTimeDescriptor)
{
Prefix = prefix ?? string.Empty;
TagName = tagName;
@ -100,7 +100,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
AssemblyName = assemblyName;
Attributes = new List<TagHelperAttributeDescriptor>(attributes);
RequiredAttributes = new List<string>(requiredAttributes);
UsageDescriptor = usageDescriptor;
DesignTimeDescriptor = designTimeDescriptor;
}
/// <summary>
@ -144,9 +144,9 @@ namespace Microsoft.AspNet.Razor.TagHelpers
public IReadOnlyList<string> RequiredAttributes { get; }
/// <summary>
/// The <see cref="TagHelperUsageDescriptor"/> that contains information about how to use the tag helper at
/// design time.
/// The <see cref="TagHelperDesignTimeDescriptor"/> that contains design time information about this
/// tag helper.
/// </summary>
public TagHelperUsageDescriptor UsageDescriptor { get; }
public TagHelperDesignTimeDescriptor DesignTimeDescriptor { get; }
}
}

View File

@ -32,7 +32,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
/// Determines equality based on <see cref="TagHelperDescriptor.TypeName"/>,
/// <see cref="TagHelperDescriptor.AssemblyName"/>, <see cref="TagHelperDescriptor.TagName"/>,
/// and <see cref="TagHelperDescriptor.RequiredAttributes"/>. Ignores
/// <see cref="TagHelperDescriptor.UsageDescriptor"/> because it can be inferred directly from
/// <see cref="TagHelperDescriptor.DesignTimeDescriptor"/> because it can be inferred directly from
/// <see cref="TagHelperDescriptor.TypeName"/> and <see cref="TagHelperDescriptor.AssemblyName"/>.
/// </remarks>
public virtual bool Equals(TagHelperDescriptor descriptorX, TagHelperDescriptor descriptorY)

View File

@ -0,0 +1,42 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.AspNet.Razor.TagHelpers
{
/// <summary>
/// A metadata class containing design time information about a tag helper.
/// </summary>
public class TagHelperDesignTimeDescriptor
{
/// <summary>
/// Instantiates a new instance of <see cref="TagHelperDesignTimeDescriptor"/>.
/// </summary>
/// <param name="summary">A summary on how to use a tag helper.</param>
/// <param name="remarks">Remarks on how to use a tag helper.</param>
/// <param name="outputElementHint">The HTML element a tag helper may output.</param>
public TagHelperDesignTimeDescriptor(string summary, string remarks, string outputElementHint)
{
Summary = summary;
Remarks = remarks;
OutputElementHint = outputElementHint;
}
/// <summary>
/// A summary of how to use a tag helper.
/// </summary>
public string Summary { get; }
/// <summary>
/// Remarks about how to use a tag helper.
/// </summary>
public string Remarks { get; }
/// <summary>
/// The HTML element a tag helper may output.
/// </summary>
/// <remarks>
/// In IDEs supporting IntelliSense, may override the HTML information provided at design time.
/// </remarks>
public string OutputElementHint { get; }
}
}

View File

@ -36,7 +36,10 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
StringComparer.Ordinal) &&
descriptorX.Attributes.SequenceEqual(
descriptorY.Attributes,
TagHelperAttributeDescriptorComparer.Default);
TagHelperAttributeDescriptorComparer.Default) &&
TagHelperDesignTimeDescriptorComparer.Default.Equals(
descriptorX.DesignTimeDescriptor,
descriptorY.DesignTimeDescriptor);
}
public override int GetHashCode(TagHelperDescriptor descriptor)
@ -44,7 +47,13 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
var hashCodeCombiner = HashCodeCombiner.Start()
.Add(base.GetHashCode(descriptor))
.Add(descriptor.TagName, StringComparer.Ordinal)
.Add(descriptor.Prefix);
.Add(descriptor.Prefix, StringComparer.Ordinal);
if (descriptor.DesignTimeDescriptor != null)
{
hashCodeCombiner.Add(
TagHelperDesignTimeDescriptorComparer.Default.GetHashCode(descriptor.DesignTimeDescriptor));
}
foreach (var requiredAttribute in descriptor.RequiredAttributes)
{

View File

@ -41,6 +41,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
/// <remarks>
/// Inherits from <see cref="TagHelper"/>.
/// </remarks>
[OutputElementHint("p")]
public class DocumentedTagHelper : TagHelper
{
/// <summary>

View File

@ -30,9 +30,9 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
string.Equals(descriptorX.Name, descriptorY.Name, StringComparison.Ordinal) &&
string.Equals(descriptorX.PropertyName, descriptorY.PropertyName, StringComparison.Ordinal) &&
string.Equals(descriptorX.TypeName, descriptorY.TypeName, StringComparison.Ordinal) &&
TagHelperUsageDescriptorComparer.Default.Equals(
descriptorX.UsageDescriptor,
descriptorY.UsageDescriptor);
TagHelperAttributeDesignTimeDescriptorComparer.Default.Equals(
descriptorX.DesignTimeDescriptor,
descriptorY.DesignTimeDescriptor);
}
public int GetHashCode(TagHelperAttributeDescriptor descriptor)
@ -44,7 +44,8 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
.Add(descriptor.Name, StringComparer.Ordinal)
.Add(descriptor.PropertyName, StringComparer.Ordinal)
.Add(descriptor.TypeName, StringComparer.Ordinal)
.Add(TagHelperUsageDescriptorComparer.Default.GetHashCode(descriptor.UsageDescriptor))
.Add(TagHelperAttributeDesignTimeDescriptorComparer.Default.GetHashCode(
descriptor.DesignTimeDescriptor))
.CombinedHash;
}
}

View File

@ -0,0 +1,45 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using Microsoft.AspNet.Razor.TagHelpers;
using Microsoft.Internal.Web.Utils;
namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
{
public class TagHelperAttributeDesignTimeDescriptorComparer :
IEqualityComparer<TagHelperAttributeDesignTimeDescriptor>
{
public static readonly TagHelperAttributeDesignTimeDescriptorComparer Default =
new TagHelperAttributeDesignTimeDescriptorComparer();
private TagHelperAttributeDesignTimeDescriptorComparer()
{
}
public bool Equals(
TagHelperAttributeDesignTimeDescriptor descriptorX,
TagHelperAttributeDesignTimeDescriptor descriptorY)
{
if (descriptorX == descriptorY)
{
return true;
}
return descriptorX != null &&
descriptorY != null &&
string.Equals(descriptorX.Summary, descriptorY.Summary, StringComparison.Ordinal) &&
string.Equals(descriptorX.Remarks, descriptorY.Remarks, StringComparison.Ordinal);
}
public int GetHashCode(TagHelperAttributeDesignTimeDescriptor descriptor)
{
return HashCodeCombiner
.Start()
.Add(descriptor.Summary, StringComparer.Ordinal)
.Add(descriptor.Remarks, StringComparer.Ordinal)
.CombinedHash;
}
}
}

View File

@ -412,7 +412,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
typeof(int).FullName,
isIndexer: false,
isStringProperty: false,
usageDescriptor: null)
designTimeDescriptor: null)
});
// Act
@ -533,7 +533,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
typeof(object).FullName,
isIndexer: false,
isStringProperty: false,
usageDescriptor: null)
designTimeDescriptor: null)
});
// Act
@ -588,7 +588,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
typeof(string).FullName,
isIndexer: false,
isStringProperty: true,
usageDescriptor: null)
designTimeDescriptor: null)
}),
new TagHelperDescriptor(
"p",
@ -602,7 +602,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
typeof(string).FullName,
isIndexer: false,
isStringProperty: true,
usageDescriptor: null)
designTimeDescriptor: null)
})
};
@ -935,14 +935,14 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
typeName: typeof(IDictionary<string, string>).FullName,
isIndexer: false,
isStringProperty: false,
usageDescriptor: null),
designTimeDescriptor: null),
new TagHelperAttributeDescriptor(
name: "dictionary-property-",
propertyName: nameof(DefaultValidHtmlAttributePrefix.DictionaryProperty),
typeName: typeof(string).FullName,
isIndexer: true,
isStringProperty: true,
usageDescriptor: null),
designTimeDescriptor: null),
},
new string[0]
},
@ -956,14 +956,14 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
typeName: typeof(IDictionary<string, string>).FullName,
isIndexer: false,
isStringProperty: false,
usageDescriptor: null),
designTimeDescriptor: null),
new TagHelperAttributeDescriptor(
name: "valid-prefix",
propertyName: nameof(SingleValidHtmlAttributePrefix.DictionaryProperty),
typeName: typeof(string).FullName,
isIndexer: true,
isStringProperty: true,
usageDescriptor: null),
designTimeDescriptor: null),
},
new string[0]
},
@ -977,77 +977,77 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
typeName: typeof(Dictionary<string, object>).FullName,
isIndexer: false,
isStringProperty: false,
usageDescriptor: null),
designTimeDescriptor: null),
new TagHelperAttributeDescriptor(
name: "valid-name2",
propertyName: nameof(MultipleValidHtmlAttributePrefix.DictionarySubclassProperty),
typeName: typeof(DictionarySubclass).FullName,
isIndexer: false,
isStringProperty: false,
usageDescriptor: null),
designTimeDescriptor: null),
new TagHelperAttributeDescriptor(
name: "valid-name3",
propertyName: nameof(MultipleValidHtmlAttributePrefix.DictionaryWithoutParameterlessConstructorProperty),
typeName: typeof(DictionaryWithoutParameterlessConstructor).FullName,
isIndexer: false,
isStringProperty: false,
usageDescriptor: null),
designTimeDescriptor: null),
new TagHelperAttributeDescriptor(
name: "valid-name4",
propertyName: nameof(MultipleValidHtmlAttributePrefix.GenericDictionarySubclassProperty),
typeName: typeof(GenericDictionarySubclass<object>).FullName,
isIndexer: false,
isStringProperty: false,
usageDescriptor: null),
designTimeDescriptor: null),
new TagHelperAttributeDescriptor(
name: "valid-name5",
propertyName: nameof(MultipleValidHtmlAttributePrefix.SortedDictionaryProperty),
typeName: typeof(SortedDictionary<string, int>).FullName,
isIndexer: false,
isStringProperty: false,
usageDescriptor: null),
designTimeDescriptor: null),
new TagHelperAttributeDescriptor(
name: "valid-name6",
propertyName: nameof(MultipleValidHtmlAttributePrefix.StringProperty),
typeName: typeof(string).FullName,
isIndexer: false,
isStringProperty: true,
usageDescriptor: null),
designTimeDescriptor: null),
new TagHelperAttributeDescriptor(
name: "valid-prefix1-",
propertyName: nameof(MultipleValidHtmlAttributePrefix.DictionaryProperty),
typeName: typeof(object).FullName,
isIndexer: true,
isStringProperty: false,
usageDescriptor: null),
designTimeDescriptor: null),
new TagHelperAttributeDescriptor(
name: "valid-prefix2-",
propertyName: nameof(MultipleValidHtmlAttributePrefix.DictionarySubclassProperty),
typeName: typeof(string).FullName,
isIndexer: true,
isStringProperty: true,
usageDescriptor: null),
designTimeDescriptor: null),
new TagHelperAttributeDescriptor(
name: "valid-prefix3-",
propertyName: nameof(MultipleValidHtmlAttributePrefix.DictionaryWithoutParameterlessConstructorProperty),
typeName: typeof(string).FullName,
isIndexer: true,
isStringProperty: true,
usageDescriptor: null),
designTimeDescriptor: null),
new TagHelperAttributeDescriptor(
name: "valid-prefix4-",
propertyName: nameof(MultipleValidHtmlAttributePrefix.GenericDictionarySubclassProperty),
typeName: typeof(object).FullName,
isIndexer: true,
isStringProperty: false,
usageDescriptor: null),
designTimeDescriptor: null),
new TagHelperAttributeDescriptor(
name: "valid-prefix5-",
propertyName: nameof(MultipleValidHtmlAttributePrefix.SortedDictionaryProperty),
typeName: typeof(int).FullName,
isIndexer: true,
isStringProperty: false,
usageDescriptor: null),
designTimeDescriptor: null),
},
new string[0]
},
@ -1071,7 +1071,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
typeName: typeof(long).FullName,
isIndexer: false,
isStringProperty: false,
usageDescriptor: null),
designTimeDescriptor: null),
},
new[]
{
@ -1156,7 +1156,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
propertyName: "ValidProperty",
typeName: "PropertyType",
isIndexer: false,
usageDescriptor: null);
designTimeDescriptor: null);
var errorSink = new ErrorSink();
// Act
@ -1180,7 +1180,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
propertyName: "ValidProperty",
typeName: "PropertyType",
isIndexer: true,
usageDescriptor: null);
designTimeDescriptor: null);
var errorSink = new ErrorSink();
// Act
@ -1226,7 +1226,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
propertyName: "InvalidProperty",
typeName: "PropertyType",
isIndexer: false,
usageDescriptor: null);
designTimeDescriptor: null);
var errorSink = new ErrorSink();
// Act
@ -1280,7 +1280,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
propertyName: "InvalidProperty",
typeName: "ValuesType",
isIndexer: true,
usageDescriptor: null);
designTimeDescriptor: null);
var errorSink = new ErrorSink();
// Act

View File

@ -1369,7 +1369,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
assemblyName,
attributes: Enumerable.Empty<TagHelperAttributeDescriptor>(),
requiredAttributes: Enumerable.Empty<string>(),
usageDescriptor: null);
designTimeDescriptor: null);
}
private static TagHelperDescriptor CreatePrefixedValidPlainDescriptor(string prefix)

View File

@ -8,15 +8,16 @@ using Microsoft.Internal.Web.Utils;
namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
{
public class TagHelperUsageDescriptorComparer : IEqualityComparer<TagHelperUsageDescriptor>
public class TagHelperDesignTimeDescriptorComparer : IEqualityComparer<TagHelperDesignTimeDescriptor>
{
public static readonly TagHelperUsageDescriptorComparer Default = new TagHelperUsageDescriptorComparer();
public static readonly TagHelperDesignTimeDescriptorComparer Default =
new TagHelperDesignTimeDescriptorComparer();
private TagHelperUsageDescriptorComparer()
private TagHelperDesignTimeDescriptorComparer()
{
}
public bool Equals(TagHelperUsageDescriptor descriptorX, TagHelperUsageDescriptor descriptorY)
public bool Equals(TagHelperDesignTimeDescriptor descriptorX, TagHelperDesignTimeDescriptor descriptorY)
{
if (descriptorX == descriptorY)
{
@ -29,7 +30,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
string.Equals(descriptorX.Remarks, descriptorY.Remarks, StringComparison.Ordinal);
}
public int GetHashCode(TagHelperUsageDescriptor descriptor)
public int GetHashCode(TagHelperDesignTimeDescriptor descriptor)
{
return HashCodeCombiner
.Start()

View File

@ -12,7 +12,7 @@ using Xunit;
namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
{
public class TagHelperUsageDescriptorFactoryTest
public class TagHelperDesignTimeDescriptorFactoryTest
{
private const string TypeSummary = "The summary for <see cref=\"T:Microsoft.AspNet.Razor.Runtime." +
"TagHelpers.DocumentedTagHelper\" />.";
@ -40,6 +40,45 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
"file:" + new string(Path.DirectorySeparatorChar, 3) +
DocumentedAssemblyLocation.TrimStart(Path.DirectorySeparatorChar);
public static TheoryData OutputElementHintData
{
get
{
// tagHelperType, expectedDescriptor
return new TheoryData<Type, TagHelperDesignTimeDescriptor>
{
{ typeof(InheritedOutputElementHintTagHelper), null },
{
typeof(OutputElementHintTagHelper),
new TagHelperDesignTimeDescriptor(
summary: null,
remarks: null,
outputElementHint: "hinted-value")
},
{
typeof(OverriddenOutputElementHintTagHelper),
new TagHelperDesignTimeDescriptor(
summary: null,
remarks: null,
outputElementHint: "overridden")
},
};
}
}
[Theory]
[MemberData(nameof(OutputElementHintData))]
public void CreateDescriptor_CapturesOutputElementHint(
Type tagHelperType,
TagHelperDesignTimeDescriptor expectedDescriptor)
{
// Act
var descriptors = TagHelperDesignTimeDescriptorFactory.CreateDescriptor(tagHelperType);
// Assert
Assert.Equal(expectedDescriptor, descriptors, TagHelperDesignTimeDescriptorComparer.Default);
}
public static TheoryData CreateDescriptor_TypeDocumentationData
{
get
@ -50,28 +89,35 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
var nonExistentCodeBase = defaultCodeBase.Replace("TestFiles", "TestFile");
var invalidLocation = defaultLocation + '\0';
var invalidCodeBase = defaultCodeBase + '\0';
var onlyHint = new TagHelperDesignTimeDescriptor(
summary: null,
remarks: null,
outputElementHint: "p");
// tagHelperType, expectedUsageDescriptor
return new TheoryData<Type, TagHelperUsageDescriptor>
// tagHelperType, expectedDesignTimeDescriptor
return new TheoryData<Type, TagHelperDesignTimeDescriptor>
{
{ CreateDocumentationTagHelperType(location: null, codeBase: null), null },
{ CreateDocumentationTagHelperType(location: null, codeBase: null), onlyHint },
{
CreateDocumentationTagHelperType(defaultLocation, codeBase: null),
new TagHelperUsageDescriptor(TypeSummary, TypeRemarks)
new TagHelperDesignTimeDescriptor(
TypeSummary,
TypeRemarks,
outputElementHint: "p")
},
{
CreateDocumentationTagHelperType(location: null, codeBase: defaultCodeBase),
new TagHelperUsageDescriptor(TypeSummary, TypeRemarks)
new TagHelperDesignTimeDescriptor(TypeSummary, TypeRemarks, outputElementHint: "p")
},
{
CreateDocumentationTagHelperType(defaultLocation, defaultCodeBase),
new TagHelperUsageDescriptor(TypeSummary, TypeRemarks)
new TagHelperDesignTimeDescriptor(TypeSummary, TypeRemarks, outputElementHint: "p")
},
{ CreateType<SingleAttributeTagHelper>(defaultLocation, defaultCodeBase), null },
{ CreateDocumentationTagHelperType(nonExistentLocation, codeBase: null), null },
{ CreateDocumentationTagHelperType(location: null, codeBase: nonExistentCodeBase), null },
{ CreateDocumentationTagHelperType(nonExistentLocation, codeBase: null), onlyHint },
{ CreateDocumentationTagHelperType(location: null, codeBase: nonExistentCodeBase), onlyHint },
{ CreateType<SingleAttributeTagHelper>(invalidLocation, codeBase: null), null },
{ CreateDocumentationTagHelperType(location: null, codeBase: invalidCodeBase), null },
{ CreateDocumentationTagHelperType(location: null, codeBase: invalidCodeBase), onlyHint },
};
}
}
@ -80,55 +126,60 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
[MemberData(nameof(CreateDescriptor_TypeDocumentationData))]
public void CreateDescriptor_WithType_ReturnsExpectedDescriptors(
Type tagHelperType,
TagHelperUsageDescriptor expectedUsageDescriptor)
TagHelperDesignTimeDescriptor expectedDesignTimeDescriptor)
{
// Act
var usageDescriptor = TagHelperUsageDescriptorFactory.CreateDescriptor(tagHelperType);
var designTimeDescriptor = TagHelperDesignTimeDescriptorFactory.CreateDescriptor(tagHelperType);
// Assert
Assert.Equal(expectedUsageDescriptor, usageDescriptor, TagHelperUsageDescriptorComparer.Default);
Assert.Equal(expectedDesignTimeDescriptor, designTimeDescriptor, TagHelperDesignTimeDescriptorComparer.Default);
}
public static TheoryData CreateDescriptor_LocalizedTypeDocumentationData
{
get
{
// tagHelperType, expectedUsageDescriptor, culture
return new TheoryData<Type, TagHelperUsageDescriptor, string>
// tagHelperType, expectedDesignTimeDescriptor, culture
return new TheoryData<Type, TagHelperDesignTimeDescriptor, string>
{
{
CreateDocumentationTagHelperType(LocalizedDocumentedAssemblyLocation, codeBase: null),
new TagHelperUsageDescriptor(
new TagHelperDesignTimeDescriptor(
summary: "en-GB: " + TypeSummary,
remarks: "en-GB: " + TypeRemarks),
remarks: "en-GB: " + TypeRemarks,
outputElementHint: "p"),
"en-GB"
},
{
CreateDocumentationTagHelperType(LocalizedDocumentedAssemblyLocation, codeBase: null),
new TagHelperUsageDescriptor(
new TagHelperDesignTimeDescriptor(
summary: "en: " + TypeSummary,
remarks: "en: " + TypeRemarks),
remarks: "en: " + TypeRemarks,
outputElementHint: "p"),
"en-US"
},
{
CreateDocumentationTagHelperType(LocalizedDocumentedAssemblyLocation, codeBase: null),
new TagHelperUsageDescriptor(
new TagHelperDesignTimeDescriptor(
summary: "fr-FR: " + TypeSummary,
remarks: "fr-FR: " + TypeRemarks),
remarks: "fr-FR: " + TypeRemarks,
outputElementHint: "p"),
"fr-FR"
},
{
CreateDocumentationTagHelperType(LocalizedDocumentedAssemblyLocation, codeBase: null),
new TagHelperUsageDescriptor(
new TagHelperDesignTimeDescriptor(
summary: "fr: " + TypeSummary,
remarks: "fr: " + TypeRemarks),
remarks: "fr: " + TypeRemarks,
outputElementHint: "p"),
"fr-BE"
},
{
CreateDocumentationTagHelperType(LocalizedDocumentedAssemblyLocation, codeBase: null),
new TagHelperUsageDescriptor(
new TagHelperDesignTimeDescriptor(
summary: "nl-BE: " + TypeSummary,
remarks: "nl-BE: " + TypeRemarks),
remarks: "nl-BE: " + TypeRemarks,
outputElementHint: "p"),
"nl-BE"
}
};
@ -139,23 +190,23 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
[MemberData(nameof(CreateDescriptor_LocalizedTypeDocumentationData))]
public void CreateDescriptor_WithLocalizedType_ReturnsExpectedDescriptors(
Type tagHelperType,
TagHelperUsageDescriptor expectedUsageDescriptor,
TagHelperDesignTimeDescriptor expectedDesignTimeDescriptor,
string culture)
{
// Arrange
TagHelperUsageDescriptor usageDescriptor;
TagHelperDesignTimeDescriptor designTimeDescriptor;
// Act
using (new CultureReplacer(culture))
{
usageDescriptor = TagHelperUsageDescriptorFactory.CreateDescriptor(tagHelperType);
designTimeDescriptor = TagHelperDesignTimeDescriptorFactory.CreateDescriptor(tagHelperType);
}
// Assert
Assert.Equal(expectedUsageDescriptor, usageDescriptor, TagHelperUsageDescriptorComparer.Default);
Assert.Equal(expectedDesignTimeDescriptor, designTimeDescriptor, TagHelperDesignTimeDescriptorComparer.Default);
}
public static TheoryData CreateDescriptor_PropertyDocumentationData
public static TheoryData CreateAttributeDescriptor_PropertyDocumentationData
{
get
{
@ -166,8 +217,8 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
var invalidLocation = defaultLocation + '\0';
var invalidCodeBase = defaultCodeBase + '\0';
// tagHelperType, propertyName, expectedUsageDescriptor
return new TheoryData<Type, string, TagHelperUsageDescriptor>
// tagHelperType, propertyName, expectedDesignTimeDescriptor
return new TheoryData<Type, string, TagHelperAttributeDesignTimeDescriptor>
{
{
CreateDocumentationTagHelperType(location: null, codeBase: null),
@ -192,51 +243,51 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
{
CreateDocumentationTagHelperType(defaultLocation, codeBase: null),
nameof(DocumentedTagHelper.SummaryProperty),
new TagHelperUsageDescriptor(PropertySummary, remarks: null)
new TagHelperAttributeDesignTimeDescriptor(PropertySummary, remarks: null)
},
{
CreateDocumentationTagHelperType(defaultLocation, codeBase: null),
nameof(DocumentedTagHelper.RemarksProperty),
new TagHelperUsageDescriptor(summary: null, remarks: PropertyRemarks)
new TagHelperAttributeDesignTimeDescriptor(summary: null, remarks: PropertyRemarks)
},
{
CreateDocumentationTagHelperType(defaultLocation, codeBase: null),
nameof(DocumentedTagHelper.RemarksAndSummaryProperty),
new TagHelperUsageDescriptor(
new TagHelperAttributeDesignTimeDescriptor(
PropertyWithSummaryAndRemarks_Summary,
PropertyWithSummaryAndRemarks_Remarks)
},
{
CreateDocumentationTagHelperType(location: null, codeBase: defaultCodeBase),
nameof(DocumentedTagHelper.SummaryProperty),
new TagHelperUsageDescriptor(PropertySummary, remarks: null)
new TagHelperAttributeDesignTimeDescriptor(PropertySummary, remarks: null)
},
{
CreateDocumentationTagHelperType(location: null, codeBase: defaultCodeBase),
nameof(DocumentedTagHelper.RemarksProperty),
new TagHelperUsageDescriptor(summary: null, remarks: PropertyRemarks)
new TagHelperAttributeDesignTimeDescriptor(summary: null, remarks: PropertyRemarks)
},
{
CreateDocumentationTagHelperType(location: null, codeBase: defaultCodeBase),
nameof(DocumentedTagHelper.RemarksAndSummaryProperty),
new TagHelperUsageDescriptor(
new TagHelperAttributeDesignTimeDescriptor(
PropertyWithSummaryAndRemarks_Summary,
PropertyWithSummaryAndRemarks_Remarks)
},
{
CreateDocumentationTagHelperType(defaultLocation, defaultCodeBase),
nameof(DocumentedTagHelper.SummaryProperty),
new TagHelperUsageDescriptor(PropertySummary, remarks: null)
new TagHelperAttributeDesignTimeDescriptor(PropertySummary, remarks: null)
},
{
CreateDocumentationTagHelperType(defaultLocation, defaultCodeBase),
nameof(DocumentedTagHelper.RemarksProperty),
new TagHelperUsageDescriptor(summary: null, remarks: PropertyRemarks)
new TagHelperAttributeDesignTimeDescriptor(summary: null, remarks: PropertyRemarks)
},
{
CreateDocumentationTagHelperType(defaultLocation, defaultCodeBase),
nameof(DocumentedTagHelper.RemarksAndSummaryProperty),
new TagHelperUsageDescriptor(
new TagHelperAttributeDesignTimeDescriptor(
PropertyWithSummaryAndRemarks_Summary,
PropertyWithSummaryAndRemarks_Remarks)
},
@ -265,11 +316,11 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
}
[Theory]
[MemberData(nameof(CreateDescriptor_PropertyDocumentationData))]
public void CreateDescriptor_WithProperty_ReturnsExpectedDescriptors(
[MemberData(nameof(CreateAttributeDescriptor_PropertyDocumentationData))]
public void CreateAttributeDescriptor_ReturnsExpectedDescriptors(
Type tagHelperType,
string propertyName,
TagHelperUsageDescriptor expectedUsageDescriptor)
TagHelperAttributeDesignTimeDescriptor expectedDesignTimeDescriptor)
{
// Arrange
var mockPropertyInfo = new Mock<PropertyInfo>();
@ -277,50 +328,54 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
mockPropertyInfo.Setup(propertyInfo => propertyInfo.Name).Returns(propertyName);
// Act
var usageDescriptor = TagHelperUsageDescriptorFactory.CreateDescriptor(mockPropertyInfo.Object);
var designTimeDescriptor = TagHelperDesignTimeDescriptorFactory.CreateAttributeDescriptor(
mockPropertyInfo.Object);
// Assert
Assert.Equal(expectedUsageDescriptor, usageDescriptor, TagHelperUsageDescriptorComparer.Default);
Assert.Equal(
expectedDesignTimeDescriptor,
designTimeDescriptor,
TagHelperAttributeDesignTimeDescriptorComparer.Default);
}
public static TheoryData CreateDescriptor_LocalizedPropertyData
public static TheoryData CreateAttributeDescriptor_LocalizedPropertyData
{
get
{
// tagHelperType, expectedUsageDescriptor, culture
return new TheoryData<Type, TagHelperUsageDescriptor, string>
// tagHelperType, expectedDesignTimeDescriptor, culture
return new TheoryData<Type, TagHelperAttributeDesignTimeDescriptor, string>
{
{
CreateDocumentationTagHelperType(LocalizedDocumentedAssemblyLocation, codeBase: null),
new TagHelperUsageDescriptor(
new TagHelperAttributeDesignTimeDescriptor(
summary: "en-GB: " + PropertyWithSummaryAndRemarks_Summary,
remarks: "en-GB: " + PropertyWithSummaryAndRemarks_Remarks),
"en-GB"
},
{
CreateDocumentationTagHelperType(LocalizedDocumentedAssemblyLocation, codeBase: null),
new TagHelperUsageDescriptor(
new TagHelperAttributeDesignTimeDescriptor(
summary: "en: " + PropertyWithSummaryAndRemarks_Summary,
remarks: "en: " + PropertyWithSummaryAndRemarks_Remarks),
"en-US"
},
{
CreateDocumentationTagHelperType(LocalizedDocumentedAssemblyLocation, codeBase: null),
new TagHelperUsageDescriptor(
new TagHelperAttributeDesignTimeDescriptor(
summary: "fr-FR: " + PropertyWithSummaryAndRemarks_Summary,
remarks: "fr-FR: " + PropertyWithSummaryAndRemarks_Remarks),
"fr-FR"
},
{
CreateDocumentationTagHelperType(LocalizedDocumentedAssemblyLocation, codeBase: null),
new TagHelperUsageDescriptor(
new TagHelperAttributeDesignTimeDescriptor(
summary: "fr: " + PropertyWithSummaryAndRemarks_Summary,
remarks: "fr: " + PropertyWithSummaryAndRemarks_Remarks),
"fr-BE"
},
{
CreateDocumentationTagHelperType(LocalizedDocumentedAssemblyLocation, codeBase: null),
new TagHelperUsageDescriptor(
new TagHelperAttributeDesignTimeDescriptor(
summary: "nl-BE: " + PropertyWithSummaryAndRemarks_Summary,
remarks: "nl-BE: " + PropertyWithSummaryAndRemarks_Remarks),
"nl-BE"
@ -330,10 +385,10 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
}
[Theory]
[MemberData(nameof(CreateDescriptor_LocalizedPropertyData))]
public void CreateDescriptor_WithLocalizedProperty_ReturnsExpectedDescriptors(
[MemberData(nameof(CreateAttributeDescriptor_LocalizedPropertyData))]
public void CreateAttributeDescriptor_WithLocalizedProperty_ReturnsExpectedDescriptors(
Type tagHelperType,
TagHelperUsageDescriptor expectedUsageDescriptor,
TagHelperAttributeDesignTimeDescriptor expectedDesignTimeDescriptor,
string culture)
{
// Arrange
@ -342,16 +397,20 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
mockPropertyInfo
.Setup(propertyInfo => propertyInfo.Name)
.Returns(nameof(DocumentedTagHelper.RemarksAndSummaryProperty));
TagHelperUsageDescriptor usageDescriptor;
TagHelperAttributeDesignTimeDescriptor designTimeDescriptor;
// Act
using (new CultureReplacer(culture))
{
usageDescriptor = TagHelperUsageDescriptorFactory.CreateDescriptor(mockPropertyInfo.Object);
designTimeDescriptor = TagHelperDesignTimeDescriptorFactory.CreateAttributeDescriptor(
mockPropertyInfo.Object);
}
// Assert
Assert.Equal(expectedUsageDescriptor, usageDescriptor, TagHelperUsageDescriptorComparer.Default);
Assert.Equal(
expectedDesignTimeDescriptor,
designTimeDescriptor,
TagHelperAttributeDesignTimeDescriptorComparer.Default);
}
private static Type CreateDocumentationTagHelperType(string location, string codeBase)
@ -367,6 +426,11 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
mockType.Setup(type => type.Assembly).Returns(testAssembly);
mockType.Setup(type => type.FullName).Returns(wrappedType.FullName);
mockType.Setup(type => type.DeclaringType).Returns(wrappedType.DeclaringType);
mockType
.Setup(type => type.GetCustomAttributes(false))
.Returns(wrappedType == typeof(DocumentedTagHelper) ?
new[] { new OutputElementHintAttribute("p") } :
null);
return mockType.Object;
}
@ -383,6 +447,20 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
public override string CodeBase { get; }
}
[OutputElementHint("hinted-value")]
private class OutputElementHintTagHelper : TagHelper
{
}
private class InheritedOutputElementHintTagHelper : OutputElementHintTagHelper
{
}
[OutputElementHint("overridden")]
private class OverriddenOutputElementHintTagHelper : OutputElementHintTagHelper
{
}
}
}
#endif

View File

@ -36,7 +36,7 @@ namespace Microsoft.AspNet.Razor.Test.Generator
"BoundRequiredString",
typeof(string).FullName,
isIndexer: false,
usageDescriptor: null),
designTimeDescriptor: null),
},
requiredAttributes: new[] { "catchall-unbound-required" }),
new TagHelperDescriptor(
@ -50,13 +50,13 @@ namespace Microsoft.AspNet.Razor.Test.Generator
"BoundRequiredString",
typeof(string).FullName,
isIndexer: false,
usageDescriptor: null),
designTimeDescriptor: null),
new TagHelperAttributeDescriptor(
"input-bound-string",
"BoundString",
typeof(string).FullName,
isIndexer: false,
usageDescriptor: null)
designTimeDescriptor: null)
},
requiredAttributes: new[] { "input-bound-required-string", "input-unbound-required" }),
};
@ -175,37 +175,37 @@ namespace Microsoft.AspNet.Razor.Test.Generator
propertyName: "IntProperty",
typeName: typeof(int).FullName,
isIndexer: false,
usageDescriptor: null),
designTimeDescriptor: null),
new TagHelperAttributeDescriptor(
name: "int-dictionary",
propertyName: "IntDictionaryProperty",
typeName: typeof(IDictionary<string, int>).FullName,
isIndexer: false,
usageDescriptor: null),
designTimeDescriptor: null),
new TagHelperAttributeDescriptor(
name: "string-dictionary",
propertyName: "StringDictionaryProperty",
typeName: "Namespace.DictionaryWithoutParameterlessConstructor<string, string>",
isIndexer: false,
usageDescriptor: null),
designTimeDescriptor: null),
new TagHelperAttributeDescriptor(
name: "string-prefix-grabber",
propertyName: "StringProperty",
typeName: typeof(string).FullName,
isIndexer: false,
usageDescriptor: null),
designTimeDescriptor: null),
new TagHelperAttributeDescriptor(
name: "int-prefix-",
propertyName: "IntDictionaryProperty",
typeName: typeof(int).FullName,
isIndexer: true,
usageDescriptor: null),
designTimeDescriptor: null),
new TagHelperAttributeDescriptor(
name: "string-prefix-",
propertyName: "StringDictionaryProperty",
typeName: typeof(string).FullName,
isIndexer: true,
usageDescriptor: null),
designTimeDescriptor: null),
}),
new TagHelperDescriptor(
tagName: "input",
@ -218,25 +218,25 @@ namespace Microsoft.AspNet.Razor.Test.Generator
propertyName: "IntDictionaryProperty",
typeName: typeof(IDictionary<string, int>).FullName,
isIndexer: false,
usageDescriptor: null),
designTimeDescriptor: null),
new TagHelperAttributeDescriptor(
name: "string-dictionary",
propertyName: "StringDictionaryProperty",
typeName: "Namespace.DictionaryWithoutParameterlessConstructor<string, string>",
isIndexer: false,
usageDescriptor: null),
designTimeDescriptor: null),
new TagHelperAttributeDescriptor(
name: "int-prefix-",
propertyName: "IntDictionaryProperty",
typeName: typeof(int).FullName,
isIndexer: true,
usageDescriptor: null),
designTimeDescriptor: null),
new TagHelperAttributeDescriptor(
name: "string-prefix-",
propertyName: "StringDictionaryProperty",
typeName: typeof(string).FullName,
isIndexer: true,
usageDescriptor: null),
designTimeDescriptor: null),
}),
};
}
@ -1065,7 +1065,7 @@ namespace Microsoft.AspNet.Razor.Test.Generator
new TagHelperAttributeDescriptor("age", pAgePropertyInfo)
},
requiredAttributes: Enumerable.Empty<string>(),
usageDescriptor: null),
designTimeDescriptor: null),
new TagHelperDescriptor(
prefix,
tagName: "input",
@ -1076,7 +1076,7 @@ namespace Microsoft.AspNet.Razor.Test.Generator
new TagHelperAttributeDescriptor("type", inputTypePropertyInfo)
},
requiredAttributes: Enumerable.Empty<string>(),
usageDescriptor: null),
designTimeDescriptor: null),
new TagHelperDescriptor(
prefix,
tagName: "input",
@ -1088,7 +1088,7 @@ namespace Microsoft.AspNet.Razor.Test.Generator
new TagHelperAttributeDescriptor("checked", checkedPropertyInfo)
},
requiredAttributes: Enumerable.Empty<string>(),
usageDescriptor: null)
designTimeDescriptor: null)
};
}

View File

@ -771,19 +771,19 @@ namespace Microsoft.AspNet.Razor.TagHelpers
propertyName: "Age",
typeName: typeof(int).FullName,
isIndexer: false,
usageDescriptor: null),
designTimeDescriptor: null),
new TagHelperAttributeDescriptor(
name: "birthday",
propertyName: "BirthDay",
typeName: typeof(DateTime).FullName,
isIndexer: false,
usageDescriptor: null),
designTimeDescriptor: null),
new TagHelperAttributeDescriptor(
name: "name",
propertyName: "Name",
typeName: typeof(string).FullName,
isIndexer: false,
usageDescriptor: null),
designTimeDescriptor: null),
})
};
var providerContext = new TagHelperDescriptorProvider(descriptors);
@ -1784,13 +1784,13 @@ namespace Microsoft.AspNet.Razor.TagHelpers
propertyName: "Bound",
typeName: typeof(bool).FullName,
isIndexer: false,
usageDescriptor: null),
designTimeDescriptor: null),
new TagHelperAttributeDescriptor(
name: "name",
propertyName: "Name",
typeName: typeof(string).FullName,
isIndexer: false,
usageDescriptor: null)
designTimeDescriptor: null)
})
};
var descriptorProvider = new TagHelperDescriptorProvider(descriptors);
@ -3280,7 +3280,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
"BoundRequiredString",
typeof(string).FullName,
isIndexer: false,
usageDescriptor: null)
designTimeDescriptor: null)
},
requiredAttributes: new[] { "unbound-required" }),
new TagHelperDescriptor(
@ -3294,7 +3294,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
"BoundRequiredString",
typeof(string).FullName,
isIndexer: false,
usageDescriptor: null)
designTimeDescriptor: null)
},
requiredAttributes: new[] { "bound-required-string" }),
new TagHelperDescriptor(
@ -3308,7 +3308,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
"BoundRequiredInt",
typeof(int).FullName,
isIndexer: false,
usageDescriptor: null)
designTimeDescriptor: null)
},
requiredAttributes: new[] { "bound-required-int" }),
new TagHelperDescriptor(
@ -3322,25 +3322,25 @@ namespace Microsoft.AspNet.Razor.TagHelpers
"DictionaryOfIntProperty",
typeof(IDictionary<string, int>).FullName,
isIndexer: false,
usageDescriptor: null),
designTimeDescriptor: null),
new TagHelperAttributeDescriptor(
"string-dictionary",
"DictionaryOfStringProperty",
typeof(IDictionary<string, string>).FullName,
isIndexer: false,
usageDescriptor: null),
designTimeDescriptor: null),
new TagHelperAttributeDescriptor(
"int-prefix-",
"DictionaryOfIntProperty",
typeof(int).FullName,
isIndexer: true,
usageDescriptor: null),
designTimeDescriptor: null),
new TagHelperAttributeDescriptor(
"string-prefix-",
"DictionaryOfStringProperty",
typeof(string).FullName,
isIndexer: true,
usageDescriptor: null),
designTimeDescriptor: null),
},
requiredAttributes: Enumerable.Empty<string>()),
new TagHelperDescriptor(
@ -3354,13 +3354,13 @@ namespace Microsoft.AspNet.Razor.TagHelpers
"BoundRequiredString",
typeof(string).FullName,
isIndexer: false,
usageDescriptor: null),
designTimeDescriptor: null),
new TagHelperAttributeDescriptor(
"bound-int",
"BoundRequiredString",
typeof(int).FullName,
isIndexer: false,
usageDescriptor: null)
designTimeDescriptor: null)
},
requiredAttributes: Enumerable.Empty<string>()),
};

View File

@ -321,7 +321,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
assemblyName: "SomeAssembly",
attributes: Enumerable.Empty<TagHelperAttributeDescriptor>(),
requiredAttributes: Enumerable.Empty<string>(),
usageDescriptor: null);
designTimeDescriptor: null);
}
}
}

View File

@ -21,7 +21,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
assemblyName: "assembly name",
attributes: Enumerable.Empty<TagHelperAttributeDescriptor>(),
requiredAttributes: new[] { "required attribute one", "required attribute two" },
usageDescriptor: new TagHelperUsageDescriptor("usage summary", "usage remarks"));
designTimeDescriptor: new TagHelperDesignTimeDescriptor("usage summary", "usage remarks", "some-tag"));
var expectedSerializedDescriptor =
$"{{\"{ nameof(TagHelperDescriptor.Prefix) }\":\"prefix:\"," +
@ -32,9 +32,10 @@ namespace Microsoft.AspNet.Razor.TagHelpers
$"\"{ nameof(TagHelperDescriptor.Attributes) }\":[]," +
$"\"{ nameof(TagHelperDescriptor.RequiredAttributes) }\":" +
"[\"required attribute one\",\"required attribute two\"]," +
$"\"{ nameof(TagHelperDescriptor.UsageDescriptor) }\":{{"+
$"\"{ nameof(TagHelperUsageDescriptor.Summary) }\":\"usage summary\"," +
$"\"{ nameof(TagHelperUsageDescriptor.Remarks) }\":\"usage remarks\"}}}}";
$"\"{ nameof(TagHelperDescriptor.DesignTimeDescriptor) }\":{{"+
$"\"{ nameof(TagHelperDesignTimeDescriptor.Summary) }\":\"usage summary\"," +
$"\"{ nameof(TagHelperDesignTimeDescriptor.Remarks) }\":\"usage remarks\"," +
$"\"{ nameof(TagHelperDesignTimeDescriptor.OutputElementHint) }\":\"some-tag\"}}}}";
// Act
var serializedDescriptor = JsonConvert.SerializeObject(descriptor);
@ -59,16 +60,16 @@ namespace Microsoft.AspNet.Razor.TagHelpers
propertyName: "property name",
typeName: "property type name",
isIndexer: false,
usageDescriptor: null),
designTimeDescriptor: null),
new TagHelperAttributeDescriptor(
name: "attribute two",
propertyName: "property name",
typeName: typeof(string).FullName,
isIndexer: false,
usageDescriptor: null),
designTimeDescriptor: null),
},
requiredAttributes: Enumerable.Empty<string>(),
usageDescriptor: null);
designTimeDescriptor: null);
var expectedSerializedDescriptor =
$"{{\"{ nameof(TagHelperDescriptor.Prefix) }\":\"prefix:\"," +
$"\"{ nameof(TagHelperDescriptor.TagName) }\":\"tag name\"," +
@ -81,15 +82,15 @@ namespace Microsoft.AspNet.Razor.TagHelpers
$"\"{ nameof(TagHelperAttributeDescriptor.Name) }\":\"attribute one\"," +
$"\"{ nameof(TagHelperAttributeDescriptor.PropertyName) }\":\"property name\"," +
$"\"{ nameof(TagHelperAttributeDescriptor.TypeName) }\":\"property type name\"," +
$"\"{ nameof(TagHelperAttributeDescriptor.UsageDescriptor) }\":null}}," +
$"\"{ nameof(TagHelperAttributeDescriptor.DesignTimeDescriptor) }\":null}}," +
$"{{\"{ nameof(TagHelperAttributeDescriptor.IsIndexer) }\":false," +
$"\"{ nameof(TagHelperAttributeDescriptor.IsStringProperty) }\":true," +
$"\"{ nameof(TagHelperAttributeDescriptor.Name) }\":\"attribute two\"," +
$"\"{ nameof(TagHelperAttributeDescriptor.PropertyName) }\":\"property name\"," +
$"\"{ nameof(TagHelperAttributeDescriptor.TypeName) }\":\"{ typeof(string).FullName }\"," +
$"\"{ nameof(TagHelperAttributeDescriptor.UsageDescriptor) }\":null}}]," +
$"\"{ nameof(TagHelperAttributeDescriptor.DesignTimeDescriptor) }\":null}}]," +
$"\"{ nameof(TagHelperDescriptor.RequiredAttributes) }\":[]," +
$"\"{ nameof(TagHelperDescriptor.UsageDescriptor) }\":null}}";
$"\"{ nameof(TagHelperDescriptor.DesignTimeDescriptor) }\":null}}";
// Act
var serializedDescriptor = JsonConvert.SerializeObject(descriptor);
@ -114,16 +115,16 @@ namespace Microsoft.AspNet.Razor.TagHelpers
propertyName: "property name",
typeName: "property type name",
isIndexer: true,
usageDescriptor: null),
designTimeDescriptor: null),
new TagHelperAttributeDescriptor(
name: "attribute two",
propertyName: "property name",
typeName: typeof(string).FullName,
isIndexer: true,
usageDescriptor: null),
designTimeDescriptor: null),
},
requiredAttributes: Enumerable.Empty<string>(),
usageDescriptor: null);
designTimeDescriptor: null);
var expectedSerializedDescriptor =
$"{{\"{ nameof(TagHelperDescriptor.Prefix) }\":\"prefix:\"," +
$"\"{ nameof(TagHelperDescriptor.TagName) }\":\"tag name\"," +
@ -136,15 +137,15 @@ namespace Microsoft.AspNet.Razor.TagHelpers
$"\"{ nameof(TagHelperAttributeDescriptor.Name) }\":\"attribute one\"," +
$"\"{ nameof(TagHelperAttributeDescriptor.PropertyName) }\":\"property name\"," +
$"\"{ nameof(TagHelperAttributeDescriptor.TypeName) }\":\"property type name\"," +
$"\"{ nameof(TagHelperAttributeDescriptor.UsageDescriptor) }\":null}}," +
$"\"{ nameof(TagHelperAttributeDescriptor.DesignTimeDescriptor) }\":null}}," +
$"{{\"{ nameof(TagHelperAttributeDescriptor.IsIndexer) }\":true," +
$"\"{ nameof(TagHelperAttributeDescriptor.IsStringProperty) }\":true," +
$"\"{ nameof(TagHelperAttributeDescriptor.Name) }\":\"attribute two\"," +
$"\"{ nameof(TagHelperAttributeDescriptor.PropertyName) }\":\"property name\"," +
$"\"{ nameof(TagHelperAttributeDescriptor.TypeName) }\":\"{ typeof(string).FullName }\"," +
$"\"{ nameof(TagHelperAttributeDescriptor.UsageDescriptor) }\":null}}]," +
$"\"{ nameof(TagHelperAttributeDescriptor.DesignTimeDescriptor) }\":null}}]," +
$"\"{ nameof(TagHelperDescriptor.RequiredAttributes) }\":[]," +
$"\"{ nameof(TagHelperDescriptor.UsageDescriptor) }\":null}}";
$"\"{ nameof(TagHelperDescriptor.DesignTimeDescriptor) }\":null}}";
// Act
var serializedDescriptor = JsonConvert.SerializeObject(descriptor);
@ -166,9 +167,10 @@ namespace Microsoft.AspNet.Razor.TagHelpers
$"\"{nameof(TagHelperDescriptor.Attributes)}\":[]," +
$"\"{nameof(TagHelperDescriptor.RequiredAttributes)}\":" +
"[\"required attribute one\",\"required attribute two\"]," +
$"\"{ nameof(TagHelperDescriptor.UsageDescriptor) }\":{{" +
$"\"{ nameof(TagHelperUsageDescriptor.Summary) }\":\"usage summary\"," +
$"\"{ nameof(TagHelperUsageDescriptor.Remarks) }\":\"usage remarks\"}}}}";
$"\"{ nameof(TagHelperDescriptor.DesignTimeDescriptor) }\":{{" +
$"\"{ nameof(TagHelperDesignTimeDescriptor.Summary) }\":\"usage summary\"," +
$"\"{ nameof(TagHelperDesignTimeDescriptor.Remarks) }\":\"usage remarks\"," +
$"\"{ nameof(TagHelperDesignTimeDescriptor.OutputElementHint) }\":\"some-tag\"}}}}";
var expectedDescriptor = new TagHelperDescriptor(
prefix: "prefix:",
tagName: "tag name",
@ -176,7 +178,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
assemblyName: "assembly name",
attributes: Enumerable.Empty<TagHelperAttributeDescriptor>(),
requiredAttributes: new[] { "required attribute one", "required attribute two" },
usageDescriptor: new TagHelperUsageDescriptor("usage summary", "usage remarks"));
designTimeDescriptor: new TagHelperDesignTimeDescriptor("usage summary", "usage remarks", "some-tag"));
// Act
var descriptor = JsonConvert.DeserializeObject<TagHelperDescriptor>(serializedDescriptor);
@ -191,9 +193,9 @@ namespace Microsoft.AspNet.Razor.TagHelpers
Assert.Empty(descriptor.Attributes);
Assert.Equal(expectedDescriptor.RequiredAttributes, descriptor.RequiredAttributes, StringComparer.Ordinal);
Assert.Equal(
expectedDescriptor.UsageDescriptor,
descriptor.UsageDescriptor,
TagHelperUsageDescriptorComparer.Default);
expectedDescriptor.DesignTimeDescriptor,
descriptor.DesignTimeDescriptor,
TagHelperDesignTimeDescriptorComparer.Default);
}
[Fact]
@ -212,15 +214,15 @@ namespace Microsoft.AspNet.Razor.TagHelpers
$"\"{ nameof(TagHelperAttributeDescriptor.Name) }\":\"attribute one\"," +
$"\"{ nameof(TagHelperAttributeDescriptor.PropertyName) }\":\"property name\"," +
$"\"{ nameof(TagHelperAttributeDescriptor.TypeName) }\":\"property type name\"," +
$"\"{ nameof(TagHelperAttributeDescriptor.UsageDescriptor) }\":null}}," +
$"\"{ nameof(TagHelperAttributeDescriptor.DesignTimeDescriptor) }\":null}}," +
$"{{\"{ nameof(TagHelperAttributeDescriptor.IsIndexer) }\":false," +
$"\"{ nameof(TagHelperAttributeDescriptor.IsStringProperty) }\":true," +
$"\"{ nameof(TagHelperAttributeDescriptor.Name) }\":\"attribute two\"," +
$"\"{ nameof(TagHelperAttributeDescriptor.PropertyName) }\":\"property name\"," +
$"\"{ nameof(TagHelperAttributeDescriptor.TypeName) }\":\"{ typeof(string).FullName }\"," +
$"\"{ nameof(TagHelperAttributeDescriptor.UsageDescriptor) }\":null}}]," +
$"\"{ nameof(TagHelperAttributeDescriptor.DesignTimeDescriptor) }\":null}}]," +
$"\"{ nameof(TagHelperDescriptor.RequiredAttributes) }\":[]," +
$"\"{ nameof(TagHelperDescriptor.UsageDescriptor) }\":null}}";
$"\"{ nameof(TagHelperDescriptor.DesignTimeDescriptor) }\":null}}";
var expectedDescriptor = new TagHelperDescriptor(
prefix: "prefix:",
tagName: "tag name",
@ -233,16 +235,16 @@ namespace Microsoft.AspNet.Razor.TagHelpers
propertyName: "property name",
typeName: "property type name",
isIndexer: false,
usageDescriptor: null),
designTimeDescriptor: null),
new TagHelperAttributeDescriptor(
name: "attribute two",
propertyName: "property name",
typeName: typeof(string).FullName,
isIndexer: false,
usageDescriptor: null),
designTimeDescriptor: null),
},
requiredAttributes: Enumerable.Empty<string>(),
usageDescriptor: null);
designTimeDescriptor: null);
// Act
var descriptor = JsonConvert.DeserializeObject<TagHelperDescriptor>(serializedDescriptor);
@ -299,15 +301,15 @@ namespace Microsoft.AspNet.Razor.TagHelpers
$"\"{ nameof(TagHelperAttributeDescriptor.Name) }\":\"attribute one\"," +
$"\"{ nameof(TagHelperAttributeDescriptor.PropertyName) }\":\"property name\"," +
$"\"{ nameof(TagHelperAttributeDescriptor.TypeName) }\":\"property type name\"," +
$"\"{ nameof(TagHelperAttributeDescriptor.UsageDescriptor) }\":null}}," +
$"\"{ nameof(TagHelperAttributeDescriptor.DesignTimeDescriptor) }\":null}}," +
$"{{\"{ nameof(TagHelperAttributeDescriptor.IsIndexer) }\":true," +
$"\"{ nameof(TagHelperAttributeDescriptor.IsStringProperty) }\":true," +
$"\"{ nameof(TagHelperAttributeDescriptor.Name) }\":\"attribute two\"," +
$"\"{ nameof(TagHelperAttributeDescriptor.PropertyName) }\":\"property name\"," +
$"\"{ nameof(TagHelperAttributeDescriptor.TypeName) }\":\"{ typeof(string).FullName }\"," +
$"\"{ nameof(TagHelperAttributeDescriptor.UsageDescriptor) }\":null}}]," +
$"\"{ nameof(TagHelperAttributeDescriptor.DesignTimeDescriptor) }\":null}}]," +
$"\"{ nameof(TagHelperDescriptor.RequiredAttributes) }\":[]," +
$"\"{ nameof(TagHelperDescriptor.UsageDescriptor) }\":null}}";
$"\"{ nameof(TagHelperDescriptor.DesignTimeDescriptor) }\":null}}";
var expectedDescriptor = new TagHelperDescriptor(
prefix: "prefix:",
tagName: "tag name",
@ -320,16 +322,16 @@ namespace Microsoft.AspNet.Razor.TagHelpers
propertyName: "property name",
typeName: "property type name",
isIndexer: true,
usageDescriptor: null),
designTimeDescriptor: null),
new TagHelperAttributeDescriptor(
name: "attribute two",
propertyName: "property name",
typeName: typeof(string).FullName,
isIndexer: true,
usageDescriptor: null),
designTimeDescriptor: null),
},
requiredAttributes: Enumerable.Empty<string>(),
usageDescriptor: null);
designTimeDescriptor: null);
// Act
var descriptor = JsonConvert.DeserializeObject<TagHelperDescriptor>(serializedDescriptor);

View File

@ -7,15 +7,16 @@ using Microsoft.Internal.Web.Utils;
namespace Microsoft.AspNet.Razor.TagHelpers
{
public class TagHelperUsageDescriptorComparer : IEqualityComparer<TagHelperUsageDescriptor>
public class TagHelperDesignTimeDescriptorComparer : IEqualityComparer<TagHelperDesignTimeDescriptor>
{
public static readonly TagHelperUsageDescriptorComparer Default = new TagHelperUsageDescriptorComparer();
public static readonly TagHelperDesignTimeDescriptorComparer Default =
new TagHelperDesignTimeDescriptorComparer();
private TagHelperUsageDescriptorComparer()
private TagHelperDesignTimeDescriptorComparer()
{
}
public bool Equals(TagHelperUsageDescriptor descriptorX, TagHelperUsageDescriptor descriptorY)
public bool Equals(TagHelperDesignTimeDescriptor descriptorX, TagHelperDesignTimeDescriptor descriptorY)
{
if (descriptorX == descriptorY)
{
@ -28,7 +29,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
string.Equals(descriptorX.Remarks, descriptorY.Remarks, StringComparison.Ordinal);
}
public int GetHashCode(TagHelperUsageDescriptor descriptor)
public int GetHashCode(TagHelperDesignTimeDescriptor descriptor)
{
return HashCodeCombiner
.Start()

View File

@ -911,7 +911,7 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
assemblyName: "SomeAssembly",
attributes: Enumerable.Empty<TagHelperAttributeDescriptor>(),
requiredAttributes: Enumerable.Empty<string>(),
usageDescriptor: null),
designTimeDescriptor: null),
new TagHelperDescriptor(
prefix: "th:",
tagName: "myth2",
@ -924,10 +924,10 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
propertyName: "Bound",
typeName: typeof(bool).FullName,
isIndexer: false,
usageDescriptor: null),
designTimeDescriptor: null),
},
requiredAttributes: Enumerable.Empty<string>(),
usageDescriptor: null)
designTimeDescriptor: null)
};
var availableDescriptorsText = new TagHelperDescriptor[]
{
@ -938,7 +938,7 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
assemblyName: "SomeAssembly",
attributes: Enumerable.Empty<TagHelperAttributeDescriptor>(),
requiredAttributes: Enumerable.Empty<string>(),
usageDescriptor: null),
designTimeDescriptor: null),
new TagHelperDescriptor(
prefix: "PREFIX",
tagName: "myth2",
@ -951,10 +951,10 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
propertyName: "Bound",
typeName: typeof(bool).FullName,
isIndexer: false,
usageDescriptor: null),
designTimeDescriptor: null),
},
requiredAttributes: Enumerable.Empty<string>(),
usageDescriptor: null)
designTimeDescriptor: null)
};
var availableDescriptorsCatchAll = new TagHelperDescriptor[]
{
@ -965,7 +965,7 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
assemblyName: "SomeAssembly",
attributes: Enumerable.Empty<TagHelperAttributeDescriptor>(),
requiredAttributes: Enumerable.Empty<string>(),
usageDescriptor: null),
designTimeDescriptor: null),
};
// documentContent, expectedOutput, availableDescriptors