mirror of https://github.com/abpframework/abp.git
2 changed files with 247 additions and 3 deletions
@ -0,0 +1,213 @@ |
|||
#nullable enable |
|||
using System; |
|||
using System.Reflection; |
|||
using System.Threading.Tasks; |
|||
using System.Xml.Linq; |
|||
using Shouldly; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Xunit; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Mvc.ApiExploring; |
|||
|
|||
public class XmlDocumentationProviderTests |
|||
{ |
|||
// A stub type so we can construct member-name keys that the provider can look up.
|
|||
private class StubType { } |
|||
|
|||
private static XmlDocumentationProvider CreateProvider(string xmlDocBody) |
|||
{ |
|||
var xml = $@"<?xml version=""1.0""?>
|
|||
<doc> |
|||
<members> |
|||
{xmlDocBody} |
|||
</members> |
|||
</doc>";
|
|||
return new FakeXmlDocumentationProvider(xml); |
|||
} |
|||
|
|||
private static string StubTypeMemberName(string elementName, string xmlContent) |
|||
{ |
|||
var typeName = typeof(StubType).FullName!.Replace('+', '.'); |
|||
return $@"<member name=""{elementName}:{typeName}"">
|
|||
{xmlContent} |
|||
</member>";
|
|||
} |
|||
|
|||
// Tests for CleanXmlText via GetSummaryAsync(Type)
|
|||
|
|||
[Fact] |
|||
public async Task GetSummary_Returns_PlainText() |
|||
{ |
|||
var typeName = typeof(StubType).FullName!.Replace('+', '.'); |
|||
var provider = CreateProvider( |
|||
$@"<member name=""T:{typeName}""><summary>A simple summary.</summary></member>"); |
|||
|
|||
var result = await provider.GetSummaryAsync(typeof(StubType)); |
|||
|
|||
result.ShouldBe("A simple summary."); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task GetSummary_Expands_SeeCref_To_ShortTypeName() |
|||
{ |
|||
var typeName = typeof(StubType).FullName!.Replace('+', '.'); |
|||
var provider = CreateProvider( |
|||
$@"<member name=""T:{typeName}""><summary>Returns a <see cref=""T:System.String"" /> value.</summary></member>"); |
|||
|
|||
var result = await provider.GetSummaryAsync(typeof(StubType)); |
|||
|
|||
result.ShouldBe("Returns a String value."); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task GetSummary_Expands_SeeCref_NestedType() |
|||
{ |
|||
var typeName = typeof(StubType).FullName!.Replace('+', '.'); |
|||
var provider = CreateProvider( |
|||
$@"<member name=""T:{typeName}""><summary>See <see cref=""T:System.Collections.Generic.List`1"" /> for details.</summary></member>"); |
|||
|
|||
var result = await provider.GetSummaryAsync(typeof(StubType)); |
|||
|
|||
result.ShouldBe("See List`1 for details."); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task GetSummary_Expands_SeeLangword() |
|||
{ |
|||
var typeName = typeof(StubType).FullName!.Replace('+', '.'); |
|||
var provider = CreateProvider( |
|||
$@"<member name=""T:{typeName}""><summary>Returns <see langword=""null"" /> when not found.</summary></member>"); |
|||
|
|||
var result = await provider.GetSummaryAsync(typeof(StubType)); |
|||
|
|||
result.ShouldBe("Returns null when not found."); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task GetSummary_Strips_CodeTag() |
|||
{ |
|||
var typeName = typeof(StubType).FullName!.Replace('+', '.'); |
|||
var provider = CreateProvider( |
|||
$@"<member name=""T:{typeName}""><summary>Use <c>DoSomething()</c> to start.</summary></member>"); |
|||
|
|||
var result = await provider.GetSummaryAsync(typeof(StubType)); |
|||
|
|||
result.ShouldBe("Use DoSomething() to start."); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task GetSummary_Strips_ParaTag() |
|||
{ |
|||
var typeName = typeof(StubType).FullName!.Replace('+', '.'); |
|||
var provider = CreateProvider( |
|||
$@"<member name=""T:{typeName}""><summary><para>First paragraph.</para></summary></member>"); |
|||
|
|||
var result = await provider.GetSummaryAsync(typeof(StubType)); |
|||
|
|||
result.ShouldBe("First paragraph."); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task GetSummary_Collapses_Whitespace() |
|||
{ |
|||
var typeName = typeof(StubType).FullName!.Replace('+', '.'); |
|||
var provider = CreateProvider( |
|||
$@"<member name=""T:{typeName}""><summary>
|
|||
Multiple |
|||
spaces here. |
|||
</summary></member>");
|
|||
|
|||
var result = await provider.GetSummaryAsync(typeof(StubType)); |
|||
|
|||
result.ShouldBe("Multiple spaces here."); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task GetSummary_Returns_Null_When_Member_Not_Found() |
|||
{ |
|||
var provider = CreateProvider(string.Empty); |
|||
|
|||
var result = await provider.GetSummaryAsync(typeof(StubType)); |
|||
|
|||
result.ShouldBeNull(); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task GetSummary_Returns_Null_When_Summary_Is_Empty() |
|||
{ |
|||
var typeName = typeof(StubType).FullName!.Replace('+', '.'); |
|||
var provider = CreateProvider( |
|||
$@"<member name=""T:{typeName}""><summary> </summary></member>"); |
|||
|
|||
var result = await provider.GetSummaryAsync(typeof(StubType)); |
|||
|
|||
result.ShouldBeNull(); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task GetSummary_Expands_Paramref() |
|||
{ |
|||
var typeName = typeof(StubType).FullName!.Replace('+', '.'); |
|||
var provider = CreateProvider( |
|||
$@"<member name=""T:{typeName}""><summary>Use the <paramref name=""input"" /> parameter.</summary></member>"); |
|||
|
|||
var result = await provider.GetSummaryAsync(typeof(StubType)); |
|||
|
|||
result.ShouldBe("Use the input parameter."); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task GetSummary_Expands_Typeparamref() |
|||
{ |
|||
var typeName = typeof(StubType).FullName!.Replace('+', '.'); |
|||
var provider = CreateProvider( |
|||
$@"<member name=""T:{typeName}""><summary>Returns <typeparamref name=""T"" /> instance.</summary></member>"); |
|||
|
|||
var result = await provider.GetSummaryAsync(typeof(StubType)); |
|||
|
|||
result.ShouldBe("Returns T instance."); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task GetSummary_Expands_Mixed_Tags() |
|||
{ |
|||
var typeName = typeof(StubType).FullName!.Replace('+', '.'); |
|||
var provider = CreateProvider( |
|||
$@"<member name=""T:{typeName}""><summary>Returns <see cref=""T:System.String"" /> or <see langword=""null"" /> if <paramref name=""key"" /> not found.</summary></member>"); |
|||
|
|||
var result = await provider.GetSummaryAsync(typeof(StubType)); |
|||
|
|||
result.ShouldBe("Returns String or null if key not found."); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task GetRemarks_Returns_Null_When_No_Remarks_Element() |
|||
{ |
|||
var typeName = typeof(StubType).FullName!.Replace('+', '.'); |
|||
var provider = CreateProvider( |
|||
$@"<member name=""T:{typeName}""><summary>Only summary.</summary></member>"); |
|||
|
|||
var result = await provider.GetRemarksAsync(typeof(StubType)); |
|||
|
|||
result.ShouldBeNull(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// A fake provider that loads XML from an in-memory string instead of the file system.
|
|||
/// </summary>
|
|||
[DisableConventionalRegistration] |
|||
private sealed class FakeXmlDocumentationProvider : XmlDocumentationProvider |
|||
{ |
|||
private readonly XDocument _document; |
|||
|
|||
public FakeXmlDocumentationProvider(string xml) |
|||
{ |
|||
_document = XDocument.Parse(xml); |
|||
} |
|||
|
|||
protected override Task<XDocument?> LoadXmlDocumentationFromDiskAsync(Assembly assembly) |
|||
{ |
|||
return Task.FromResult<XDocument?>(_document); |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue