Update `TagHelperDesignTimeDescriptorFactory` to work in CoreCLR.

- After discussion offline to maintain consistency we decided to also remove `CodeBase` fallback in the net451 scenario. This will keep CoreCLR and net451 scenarios more consistent.
- Removed `CodeBase` validation tests.
- Added `GetAssemblyLocation` extensibility point to enable proper testing of the `TagHelperDesignTimeDescriptorFactory`.

#709
This commit is contained in:
N. Taylor Mullen 2016-03-16 14:53:26 -07:00
parent dd9c92a990
commit 3d0bf621f3
6 changed files with 103 additions and 177 deletions

View File

@ -34,9 +34,7 @@ namespace Microsoft.AspNetCore.Razor.Runtime.TagHelpers
RegexOptions.None,
Constants.RegexMatchTimeout);
#if !NETSTANDARD1_3
private readonly TagHelperDesignTimeDescriptorFactory _designTimeDescriptorFactory;
#endif
private readonly bool _designTime;
// TODO: Investigate if we should cache TagHelperDescriptors for types:
@ -53,12 +51,10 @@ namespace Microsoft.AspNetCore.Razor.Runtime.TagHelpers
/// </param>
public TagHelperDescriptorFactory(bool designTime)
{
#if !NETSTANDARD1_3
if (designTime)
{
_designTimeDescriptorFactory = new TagHelperDesignTimeDescriptorFactory();
}
#endif
_designTime = designTime;
}
@ -129,12 +125,10 @@ namespace Microsoft.AspNetCore.Razor.Runtime.TagHelpers
{
TagHelperDesignTimeDescriptor typeDesignTimeDescriptor = null;
#if !NETSTANDARD1_3
if (_designTime)
{
typeDesignTimeDescriptor = _designTimeDescriptorFactory.CreateDescriptor(type);
}
#endif
var typeName = type.FullName;
@ -689,12 +683,10 @@ namespace Microsoft.AspNetCore.Razor.Runtime.TagHelpers
{
TagHelperAttributeDesignTimeDescriptor propertyDesignTimeDescriptor = null;
#if !NETSTANDARD1_3
if (_designTime)
{
propertyDesignTimeDescriptor = _designTimeDescriptorFactory.CreateAttributeDescriptor(property);
}
#endif
return new TagHelperAttributeDescriptor
{

View File

@ -1,7 +1,6 @@
// 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.
#if !NETSTANDARD1_3 // Cannot accurately resolve the location of the documentation XML file in coreclr.
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
@ -40,10 +39,10 @@ namespace Microsoft.AspNetCore.Razor.Runtime.TagHelpers
}
var id = XmlDocumentationProvider.GetId(type);
var documentationDescriptor = CreateDocumentationDescriptor(type.Assembly, id);
var documentationDescriptor = CreateDocumentationDescriptor(type.GetTypeInfo().Assembly, id);
// Purposefully not using the TypeInfo.GetCustomAttributes method here to make it easier to mock the Type.
var outputElementHintAttribute = type
.GetTypeInfo()
.GetCustomAttributes(inherit: false)
?.OfType<OutputElementHintAttribute>()
.FirstOrDefault();
@ -79,7 +78,7 @@ namespace Microsoft.AspNetCore.Razor.Runtime.TagHelpers
}
var id = XmlDocumentationProvider.GetId(propertyInfo);
var declaringAssembly = propertyInfo.DeclaringType.Assembly;
var declaringAssembly = propertyInfo.DeclaringType.GetTypeInfo().Assembly;
var documentationDescriptor = CreateDocumentationDescriptor(declaringAssembly, id);
if (documentationDescriptor != null)
{
@ -93,6 +92,18 @@ namespace Microsoft.AspNetCore.Razor.Runtime.TagHelpers
return null;
}
/// <summary>
/// Retrieves <paramref name="assembly"/>'s location on disk.
/// </summary>
/// <param name="assembly">The assembly.</param>
/// <returns>The path to the given <paramref name="assembly"/>.</returns>
public virtual string GetAssemblyLocation(Assembly assembly)
{
var assemblyLocation = assembly.Location;
return assemblyLocation;
}
private XmlDocumentationProvider GetXmlDocumentationProvider(Assembly assembly)
{
var hashCodeCombiner = HashCodeCombiner.Start();
@ -102,15 +113,7 @@ namespace Microsoft.AspNetCore.Razor.Runtime.TagHelpers
var documentationProvider = _documentationProviderCache.GetOrAdd(cacheKey, valueFactory: _ =>
{
var assemblyLocation = assembly.Location;
if (string.IsNullOrEmpty(assemblyLocation) && !string.IsNullOrEmpty(assembly.CodeBase))
{
var uri = new UriBuilder(assembly.CodeBase);
// Normalize the path to UNC path. This will remove things like file:// from start of uri.Path.
assemblyLocation = Uri.UnescapeDataString(uri.Path);
}
var assemblyLocation = GetAssemblyLocation(assembly);
// Couldn't resolve a valid assemblyLocation.
if (string.IsNullOrEmpty(assemblyLocation))
@ -234,5 +237,4 @@ namespace Microsoft.AspNetCore.Razor.Runtime.TagHelpers
public string Remarks { get; set; }
}
}
}
#endif
}

View File

@ -1,7 +1,6 @@
// 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.
#if !NETSTANDARD1_3
using System;
using System.Collections.Generic;
using System.Linq;
@ -125,5 +124,4 @@ namespace Microsoft.AspNetCore.Razor.Runtime.TagHelpers
return stringBuilder.ToString().Trim();
}
}
}
#endif
}

View File

@ -56,9 +56,12 @@
},
"netstandard1.3": {
"dependencies": {
"System.Collections.Concurrent": "4.0.12-*",
"System.Reflection": "4.1.0-*",
"System.Reflection.Extensions": "4.0.1-*",
"System.Reflection.TypeExtensions": "4.1.0-*",
"System.Text.RegularExpressions": "4.0.12-*"
"System.Text.RegularExpressions": "4.0.12-*",
"System.Xml.XDocument": "4.0.11-*"
},
"imports": [
"dotnet5.4"

View File

@ -1,7 +1,6 @@
// 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.
#if !NETSTANDARDAPP1_5
using System;
using System.IO;
using System.Reflection;
@ -36,7 +35,7 @@ namespace Microsoft.AspNetCore.Razor.Runtime.TagHelpers
#if NET451
Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory(), "..", "..", "..", ".."));
#else
Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory(), "..", ".."));
Directory.GetCurrentDirectory();
#endif
public static readonly string DocumentedAssemblyLocation =
Path.Combine(TestRoot, "TestFiles", "NotLocalized", "TagHelperDocumentation.dll");
@ -104,12 +103,13 @@ namespace Microsoft.AspNetCore.Razor.Runtime.TagHelpers
OutputElementHint = "p"
};
// tagHelperType, expectedDesignTimeDescriptor
return new TheoryData<Type, TagHelperDesignTimeDescriptor>
// tagHelperType, assemblyLocation, expectedDesignTimeDescriptor
return new TheoryData<Type, string, TagHelperDesignTimeDescriptor>
{
{ CreateDocumentationTagHelperType(location: null, codeBase: null), onlyHint },
{ typeof(DocumentedTagHelper), null, onlyHint },
{
CreateDocumentationTagHelperType(defaultLocation, codeBase: null),
typeof(DocumentedTagHelper),
defaultLocation,
new TagHelperDesignTimeDescriptor
{
Summary = TypeSummary,
@ -117,29 +117,9 @@ namespace Microsoft.AspNetCore.Razor.Runtime.TagHelpers
OutputElementHint = "p"
}
},
{
CreateDocumentationTagHelperType(location: null, codeBase: defaultCodeBase),
new TagHelperDesignTimeDescriptor
{
Summary = TypeSummary,
Remarks = TypeRemarks,
OutputElementHint = "p"
}
},
{
CreateDocumentationTagHelperType(defaultLocation, defaultCodeBase),
new TagHelperDesignTimeDescriptor
{
Summary = TypeSummary,
Remarks = TypeRemarks,
OutputElementHint = "p"
}
},
{ CreateType<SingleAttributeTagHelper>(defaultLocation, defaultCodeBase), null },
{ CreateDocumentationTagHelperType(nonExistentLocation, codeBase: null), onlyHint },
{ CreateDocumentationTagHelperType(location: null, codeBase: nonExistentCodeBase), onlyHint },
{ CreateType<SingleAttributeTagHelper>(invalidLocation, codeBase: null), null },
{ CreateDocumentationTagHelperType(location: null, codeBase: invalidCodeBase), onlyHint },
{ typeof(SingleAttributeTagHelper), defaultLocation, null },
{ typeof(DocumentedTagHelper), nonExistentLocation, onlyHint },
{ typeof(SingleAttributeTagHelper), invalidLocation, null },
};
}
}
@ -148,10 +128,11 @@ namespace Microsoft.AspNetCore.Razor.Runtime.TagHelpers
[MemberData(nameof(CreateDescriptor_TypeDocumentationData))]
public void CreateDescriptor_WithType_ReturnsExpectedDescriptors(
Type tagHelperType,
string assemblyLocation,
TagHelperDesignTimeDescriptor expectedDesignTimeDescriptor)
{
// Arrange
var factory = new TagHelperDesignTimeDescriptorFactory();
var factory = new TestTagHelperDesignTimeDescriptorFactory(assemblyLocation);
// Act
var designTimeDescriptor = factory.CreateDescriptor(tagHelperType);
@ -164,11 +145,12 @@ namespace Microsoft.AspNetCore.Razor.Runtime.TagHelpers
{
get
{
// tagHelperType, expectedDesignTimeDescriptor, culture
return new TheoryData<Type, TagHelperDesignTimeDescriptor, string>
// tagHelperType, assemblyLocation, expectedDesignTimeDescriptor, culture
return new TheoryData<Type, string, TagHelperDesignTimeDescriptor, string>
{
{
CreateDocumentationTagHelperType(LocalizedDocumentedAssemblyLocation, codeBase: null),
typeof(DocumentedTagHelper),
LocalizedDocumentedAssemblyLocation,
new TagHelperDesignTimeDescriptor
{
Summary = "en-GB: " + TypeSummary,
@ -178,7 +160,8 @@ namespace Microsoft.AspNetCore.Razor.Runtime.TagHelpers
"en-GB"
},
{
CreateDocumentationTagHelperType(LocalizedDocumentedAssemblyLocation, codeBase: null),
typeof(DocumentedTagHelper),
LocalizedDocumentedAssemblyLocation,
new TagHelperDesignTimeDescriptor
{
Summary = "en: " + TypeSummary,
@ -188,7 +171,8 @@ namespace Microsoft.AspNetCore.Razor.Runtime.TagHelpers
"en-US"
},
{
CreateDocumentationTagHelperType(LocalizedDocumentedAssemblyLocation, codeBase: null),
typeof(DocumentedTagHelper),
LocalizedDocumentedAssemblyLocation,
new TagHelperDesignTimeDescriptor
{
Summary = "fr-FR: " + TypeSummary,
@ -198,7 +182,8 @@ namespace Microsoft.AspNetCore.Razor.Runtime.TagHelpers
"fr-FR"
},
{
CreateDocumentationTagHelperType(LocalizedDocumentedAssemblyLocation, codeBase: null),
typeof(DocumentedTagHelper),
LocalizedDocumentedAssemblyLocation,
new TagHelperDesignTimeDescriptor
{
Summary = "fr: " + TypeSummary,
@ -208,7 +193,8 @@ namespace Microsoft.AspNetCore.Razor.Runtime.TagHelpers
"fr-BE"
},
{
CreateDocumentationTagHelperType(LocalizedDocumentedAssemblyLocation, codeBase: null),
typeof(DocumentedTagHelper),
LocalizedDocumentedAssemblyLocation,
new TagHelperDesignTimeDescriptor
{
Summary = "nl-BE: " + TypeSummary,
@ -225,12 +211,13 @@ namespace Microsoft.AspNetCore.Razor.Runtime.TagHelpers
[MemberData(nameof(CreateDescriptor_LocalizedTypeDocumentationData))]
public void CreateDescriptor_WithLocalizedType_ReturnsExpectedDescriptors(
Type tagHelperType,
string assemblyLocation,
TagHelperDesignTimeDescriptor expectedDesignTimeDescriptor,
string culture)
{
// Arrange
TagHelperDesignTimeDescriptor designTimeDescriptor;
var factory = new TagHelperDesignTimeDescriptorFactory();
var factory = new TestTagHelperDesignTimeDescriptorFactory(assemblyLocation);
// Act
using (new CultureReplacer(culture))
@ -246,7 +233,7 @@ namespace Microsoft.AspNetCore.Razor.Runtime.TagHelpers
public void CreateDescriptor_WithLocalizedType_CachesBasedOnCulture()
{
// Arrange
var factory = new TagHelperDesignTimeDescriptorFactory();
var factory = new TestTagHelperDesignTimeDescriptorFactory(LocalizedDocumentedAssemblyLocation);
var expectedFRDesignTimeDescriptor = new TagHelperDesignTimeDescriptor
{
Summary = "fr-FR: " + TypeSummary,
@ -259,7 +246,7 @@ namespace Microsoft.AspNetCore.Razor.Runtime.TagHelpers
Remarks = "nl-BE: " + TypeRemarks,
OutputElementHint = "p",
};
var tagHelperType = CreateDocumentationTagHelperType(LocalizedDocumentedAssemblyLocation, codeBase: null);
var tagHelperType = typeof(DocumentedTagHelper);
TagHelperDesignTimeDescriptor frDesignTimeDescriptor, nlBEDesignTimeDescriptor;
// Act
@ -294,48 +281,55 @@ namespace Microsoft.AspNetCore.Razor.Runtime.TagHelpers
var invalidLocation = defaultLocation + '\0';
var invalidCodeBase = defaultCodeBase + '\0';
// tagHelperType, propertyName, expectedDesignTimeDescriptor
return new TheoryData<Type, string, TagHelperAttributeDesignTimeDescriptor>
// tagHelperType, propertyName, assemblyLocation, expectedDesignTimeDescriptor
return new TheoryData<Type, string, string, TagHelperAttributeDesignTimeDescriptor>
{
{
CreateDocumentationTagHelperType(location: null, codeBase: null),
typeof(DocumentedTagHelper),
nameof(DocumentedTagHelper.SummaryProperty),
null,
null
},
{
CreateDocumentationTagHelperType(location: null, codeBase: null),
typeof(DocumentedTagHelper),
nameof(DocumentedTagHelper.RemarksProperty),
null,
null
},
{
CreateDocumentationTagHelperType(location: null, codeBase: null),
typeof(DocumentedTagHelper),
nameof(DocumentedTagHelper.RemarksAndSummaryProperty),
null,
null
},
{
CreateDocumentationTagHelperType(defaultLocation, defaultCodeBase),
typeof(DocumentedTagHelper),
nameof(DocumentedTagHelper.UndocumentedProperty),
defaultLocation,
null
},
{
CreateDocumentationTagHelperType(defaultLocation, codeBase: null),
typeof(DocumentedTagHelper),
nameof(DocumentedTagHelper.SummaryProperty),
defaultLocation,
new TagHelperAttributeDesignTimeDescriptor
{
Summary = PropertySummary
}
},
{
CreateDocumentationTagHelperType(defaultLocation, codeBase: null),
typeof(DocumentedTagHelper),
nameof(DocumentedTagHelper.RemarksProperty),
defaultLocation,
new TagHelperAttributeDesignTimeDescriptor
{
Remarks = PropertyRemarks
}
},
{
CreateDocumentationTagHelperType(defaultLocation, codeBase: null),
typeof(DocumentedTagHelper),
nameof(DocumentedTagHelper.RemarksAndSummaryProperty),
defaultLocation,
new TagHelperAttributeDesignTimeDescriptor
{
Summary = PropertyWithSummaryAndRemarks_Summary,
@ -343,75 +337,35 @@ namespace Microsoft.AspNetCore.Razor.Runtime.TagHelpers
}
},
{
CreateDocumentationTagHelperType(location: null, codeBase: defaultCodeBase),
typeof(DocumentedTagHelper),
nameof(DocumentedTagHelper.SummaryProperty),
defaultLocation,
new TagHelperAttributeDesignTimeDescriptor
{
Summary = PropertySummary
}
},
{
CreateDocumentationTagHelperType(location: null, codeBase: defaultCodeBase),
typeof(DocumentedTagHelper),
nameof(DocumentedTagHelper.RemarksProperty),
defaultLocation,
new TagHelperAttributeDesignTimeDescriptor
{
Remarks = PropertyRemarks
}
},
{
CreateDocumentationTagHelperType(location: null, codeBase: defaultCodeBase),
nameof(DocumentedTagHelper.RemarksAndSummaryProperty),
new TagHelperAttributeDesignTimeDescriptor
{
Summary = PropertyWithSummaryAndRemarks_Summary,
Remarks = PropertyWithSummaryAndRemarks_Remarks
}
},
{
CreateDocumentationTagHelperType(defaultLocation, defaultCodeBase),
nameof(DocumentedTagHelper.SummaryProperty),
new TagHelperAttributeDesignTimeDescriptor
{
Summary = PropertySummary
}
},
{
CreateDocumentationTagHelperType(defaultLocation, defaultCodeBase),
nameof(DocumentedTagHelper.RemarksProperty),
new TagHelperAttributeDesignTimeDescriptor
{
Remarks = PropertyRemarks
}
},
{
CreateDocumentationTagHelperType(defaultLocation, defaultCodeBase),
nameof(DocumentedTagHelper.RemarksAndSummaryProperty),
new TagHelperAttributeDesignTimeDescriptor
{
Summary = PropertyWithSummaryAndRemarks_Summary,
Remarks = PropertyWithSummaryAndRemarks_Remarks
}
},
{
CreateDocumentationTagHelperType(nonExistentLocation, codeBase: null),
typeof(DocumentedTagHelper),
nameof(DocumentedTagHelper.RemarksAndSummaryProperty),
nonExistentLocation,
null
},
{
CreateDocumentationTagHelperType(location: null, codeBase: nonExistentCodeBase),
typeof(DocumentedTagHelper),
nameof(DocumentedTagHelper.RemarksAndSummaryProperty),
invalidLocation,
null
},
{
CreateDocumentationTagHelperType(invalidLocation, codeBase: null),
nameof(DocumentedTagHelper.RemarksAndSummaryProperty),
null
},
{
CreateDocumentationTagHelperType(location: null, codeBase: invalidCodeBase),
nameof(DocumentedTagHelper.RemarksAndSummaryProperty),
null
}
};
}
}
@ -421,13 +375,14 @@ namespace Microsoft.AspNetCore.Razor.Runtime.TagHelpers
public void CreateAttributeDescriptor_ReturnsExpectedDescriptors(
Type tagHelperType,
string propertyName,
string assemblyLocation,
TagHelperAttributeDesignTimeDescriptor expectedDesignTimeDescriptor)
{
// Arrange
var mockPropertyInfo = new Mock<PropertyInfo>();
mockPropertyInfo.Setup(propertyInfo => propertyInfo.DeclaringType).Returns(tagHelperType);
mockPropertyInfo.Setup(propertyInfo => propertyInfo.Name).Returns(propertyName);
var factory = new TagHelperDesignTimeDescriptorFactory();
var factory = new TestTagHelperDesignTimeDescriptorFactory(assemblyLocation);
// Act
var designTimeDescriptor = factory.CreateAttributeDescriptor(
@ -444,11 +399,12 @@ namespace Microsoft.AspNetCore.Razor.Runtime.TagHelpers
{
get
{
// tagHelperType, expectedDesignTimeDescriptor, culture
return new TheoryData<Type, TagHelperAttributeDesignTimeDescriptor, string>
// tagHelperType, assemblyLocation, expectedDesignTimeDescriptor, culture
return new TheoryData<Type, string, TagHelperAttributeDesignTimeDescriptor, string>
{
{
CreateDocumentationTagHelperType(LocalizedDocumentedAssemblyLocation, codeBase: null),
typeof(DocumentedTagHelper),
LocalizedDocumentedAssemblyLocation,
new TagHelperAttributeDesignTimeDescriptor
{
Summary = "en-GB: " + PropertyWithSummaryAndRemarks_Summary,
@ -457,7 +413,8 @@ namespace Microsoft.AspNetCore.Razor.Runtime.TagHelpers
"en-GB"
},
{
CreateDocumentationTagHelperType(LocalizedDocumentedAssemblyLocation, codeBase: null),
typeof(DocumentedTagHelper),
LocalizedDocumentedAssemblyLocation,
new TagHelperAttributeDesignTimeDescriptor
{
Summary = "en: " + PropertyWithSummaryAndRemarks_Summary,
@ -466,7 +423,8 @@ namespace Microsoft.AspNetCore.Razor.Runtime.TagHelpers
"en-US"
},
{
CreateDocumentationTagHelperType(LocalizedDocumentedAssemblyLocation, codeBase: null),
typeof(DocumentedTagHelper),
LocalizedDocumentedAssemblyLocation,
new TagHelperAttributeDesignTimeDescriptor
{
Summary = "fr-FR: " + PropertyWithSummaryAndRemarks_Summary,
@ -475,7 +433,8 @@ namespace Microsoft.AspNetCore.Razor.Runtime.TagHelpers
"fr-FR"
},
{
CreateDocumentationTagHelperType(LocalizedDocumentedAssemblyLocation, codeBase: null),
typeof(DocumentedTagHelper),
LocalizedDocumentedAssemblyLocation,
new TagHelperAttributeDesignTimeDescriptor
{
Summary = "fr: " + PropertyWithSummaryAndRemarks_Summary,
@ -484,7 +443,8 @@ namespace Microsoft.AspNetCore.Razor.Runtime.TagHelpers
"fr-BE"
},
{
CreateDocumentationTagHelperType(LocalizedDocumentedAssemblyLocation, codeBase: null),
typeof(DocumentedTagHelper),
LocalizedDocumentedAssemblyLocation,
new TagHelperAttributeDesignTimeDescriptor
{
Summary = "nl-BE: " + PropertyWithSummaryAndRemarks_Summary,
@ -500,6 +460,7 @@ namespace Microsoft.AspNetCore.Razor.Runtime.TagHelpers
[MemberData(nameof(CreateAttributeDescriptor_LocalizedPropertyData))]
public void CreateAttributeDescriptor_WithLocalizedProperty_ReturnsExpectedDescriptors(
Type tagHelperType,
string assemblyLocation,
TagHelperAttributeDesignTimeDescriptor expectedDesignTimeDescriptor,
string culture)
{
@ -510,7 +471,7 @@ namespace Microsoft.AspNetCore.Razor.Runtime.TagHelpers
.Setup(propertyInfo => propertyInfo.Name)
.Returns(nameof(DocumentedTagHelper.RemarksAndSummaryProperty));
TagHelperAttributeDesignTimeDescriptor designTimeDescriptor;
var factory = new TagHelperDesignTimeDescriptorFactory();
var factory = new TestTagHelperDesignTimeDescriptorFactory(assemblyLocation);
// Act
using (new CultureReplacer(culture))
@ -530,13 +491,13 @@ namespace Microsoft.AspNetCore.Razor.Runtime.TagHelpers
public void CreateDescriptor_WithLocalizedProperty_CachesBasedOnCulture()
{
// Arrange
var tagHelperType = CreateDocumentationTagHelperType(LocalizedDocumentedAssemblyLocation, codeBase: null);
var tagHelperType = typeof(DocumentedTagHelper);
var mockPropertyInfo = new Mock<PropertyInfo>();
mockPropertyInfo.Setup(propertyInfo => propertyInfo.DeclaringType).Returns(tagHelperType);
mockPropertyInfo
.Setup(propertyInfo => propertyInfo.Name)
.Returns(nameof(DocumentedTagHelper.RemarksAndSummaryProperty));
var factory = new TagHelperDesignTimeDescriptorFactory();
var factory = new TestTagHelperDesignTimeDescriptorFactory(LocalizedDocumentedAssemblyLocation);
var expectedFRDesignTimeDescriptor = new TagHelperAttributeDesignTimeDescriptor
{
Summary = "fr-FR: " + PropertyWithSummaryAndRemarks_Summary,
@ -570,50 +531,20 @@ namespace Microsoft.AspNetCore.Razor.Runtime.TagHelpers
TagHelperAttributeDesignTimeDescriptorComparer.Default);
}
private static Type CreateDocumentationTagHelperType(string location, string codeBase)
private class TestTagHelperDesignTimeDescriptorFactory : TagHelperDesignTimeDescriptorFactory
{
return CreateType<DocumentedTagHelper>(location, codeBase);
}
private readonly string _assemblyLocation;
private static Type CreateType<TWrappedType>(string location, string codeBase)
{
var testAssembly = new TestAssembly(location, codeBase);
var wrappedType = typeof(TWrappedType);
var mockType = new Mock<Type>();
var mockReflectedType = mockType.As<IReflectableType>();
// TypeDelegator inherits from abstract TypeInfo class and has a constructor Moq can use.
var mockTypeInfo = new Mock<TypeDelegator>(mockType.Object);
mockReflectedType.Setup(type => type.GetTypeInfo()).Returns(mockTypeInfo.Object);
mockTypeInfo.Setup(typeInfo => typeInfo.Assembly).Returns(testAssembly);
mockTypeInfo.Setup(typeInfo => typeInfo.FullName).Returns(wrappedType.FullName);
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;
}
private class TestAssembly : Assembly
{
public TestAssembly(string location, string codeBase)
public TestTagHelperDesignTimeDescriptorFactory(string assemblyLocation)
: base()
{
Location = location;
CodeBase = codeBase;
_assemblyLocation = assemblyLocation;
}
public override string Location { get; }
public override string CodeBase { get; }
public override AssemblyName GetName() { return new AssemblyName("TestAssembly"); }
public override string GetAssemblyLocation(Assembly assembly)
{
return _assemblyLocation;
}
}
[OutputElementHint("hinted-value")]
@ -630,5 +561,4 @@ namespace Microsoft.AspNetCore.Razor.Runtime.TagHelpers
{
}
}
}
#endif
}

View File

@ -23,7 +23,8 @@
"portable-net451+win8"
],
"dependencies": {
"dotnet-test-xunit": "1.0.0-dev-*"
"dotnet-test-xunit": "1.0.0-dev-*",
"moq.netcore": "4.4.0-beta8"
}
},
"net451": {