Skip to content

Commit

Permalink
add/improve tests
Browse files Browse the repository at this point in the history
  • Loading branch information
saucecontrol committed Nov 9, 2023
1 parent 428d65a commit 391b8a2
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 61 deletions.
25 changes: 15 additions & 10 deletions src/InheritDoc/InheritDocTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,33 +23,38 @@ public class InheritDocTask : Task
public string? NoWarn { get; set; }
public string? TrimLevel { get; set; }

internal ILogger? Logger { get; set; }

public override bool Execute()
{
try
{
var refPaths = RefAssemblyPaths?.Split(';') ?? Array.Empty<string>();
var addPaths = AdditionalDocPaths?.Split(';') ?? Array.Empty<string>();
var logger = new TaskLogger(Log, NoWarn?.Split(';') ?? Array.Empty<string>()) as ILogger;
var refPaths = RefAssemblyPaths?.Split(';') ?? [ ];
var addPaths = AdditionalDocPaths?.Split(';') ?? [ ];
var trim = (ApiLevel)Math.Min((int)(Enum.TryParse<ApiLevel>(TrimLevel, true, out var t) ? t : ApiLevel.Internal), (int)ApiLevel.Internal);

Log.LogCommandLine(MessageImportance.Normal,
typeof(InheritDocTask).Assembly.GetName().FullName +
string cmdargs = typeof(InheritDocTask).Assembly.GetName().FullName +
Environment.NewLine + nameof(AssemblyPath) + ": " + AssemblyPath +
Environment.NewLine + nameof(InDocPath) + ": " + InDocPath +
Environment.NewLine + nameof(OutDocPath) + ": " + OutDocPath +
Environment.NewLine + nameof(RefAssemblyPaths) + ": " + RefAssemblyPaths +
Environment.NewLine + nameof(AdditionalDocPaths) + ": " + AdditionalDocPaths +
Environment.NewLine + nameof(TrimLevel) + ": " + trim
);
Environment.NewLine + nameof(TrimLevel) + ": " + trim;

Logger ??= new TaskLogger(Log, NoWarn?.Split(';') ?? [ ]);
if (BuildEngine is not null)
Log.LogCommandLine(MessageImportance.Normal, cmdargs);

var (replaced, total, trimmed) = InheritDocProcessor.InheritDocs(AssemblyPath, InDocPath, OutDocPath, refPaths, addPaths, trim, logger);
var (replaced, total, trimmed) = InheritDocProcessor.InheritDocs(AssemblyPath, InDocPath, OutDocPath, refPaths, addPaths, trim, Logger);

logger.Write(ILogger.Severity.Message, $"{nameof(InheritDocTask)} replaced {replaced} of {total} inheritdoc tags {(trim > ApiLevel.None ? $"and removed {trimmed} {(trim == ApiLevel.Private ? "private" : "non-public")} member docs " : null)}in {Path.GetFullPath(OutDocPath)}");
Logger.Write(ILogger.Severity.Message, $"{nameof(InheritDocTask)} replaced {replaced} of {total} inheritdoc tags {(trim > ApiLevel.None ? $"and removed {trimmed} {(trim == ApiLevel.Private ? "private" : "non-public")} member docs " : null)}in {Path.GetFullPath(OutDocPath)}");
return true;
}
catch (Exception ex)
{
Log.LogErrorFromException(ex, true);
if (BuildEngine is not null)
Log.LogErrorFromException(ex, true);

return false;
}
}
Expand Down
106 changes: 65 additions & 41 deletions tests/InheritDoc.Test/DocTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// <auto-generated /> (not really, but this disables analyzer warnings)

using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
Expand Down Expand Up @@ -34,7 +35,7 @@ public interface IZ
event EventHandler E;
}

/// <summary>Interface IG</summary>
/// <summary>Interface IG <typeparamref name="TG"/></summary>
/// <typeparam name="TG">TypeParam TG</typeparam>
public interface IG<TG>
{
Expand All @@ -45,15 +46,16 @@ public interface IG<TG>
unsafe U[] M<U>(U* p) where U : unmanaged;

/// <summary>Nested Interface IG&lt;TG&gt;.IN</summary>
/// <typeparam name="TM">TypeParam TM</typeparam>
public interface IN<TM>
{
/// <summary>Method M</summary>
/// <summary>Method M <typeparamref name="TM" /></summary>
/// <param name="p">Param p</param>
public void M(IN<TM> p);
}
}

/// <summary>Class G</summary>
/// <summary>Class G <typeparamref name="T"/></summary>
/// <typeparam name="T">TypeParam T</typeparam>
public abstract class G<T> where T : class
{
Expand Down Expand Up @@ -157,66 +159,51 @@ public struct D : IEquatable<D>
}

/// <inheritdoc />
public class GGI : GG<string>
public class GGI : GG<string[]>
{
new internal const string T_ID = nameof(GGI);
internal const string M_ID = T_ID + "." + nameof(M) + "(" + nameof(System) + "." + nameof(String) + "@)";
internal const string M_ID = T_ID + "." + nameof(M) + "(" + nameof(System) + "." + nameof(String) + "[]@)";
internal const string P_ID = T_ID + ".Item(" + nameof(System) + "." + nameof(Int32) + ")";

/// <inheritdoc />
public GGI() { }

/// <inheritdoc />
public override string M(in string x) => default;
}

/// <inheritdoc />
public class GG<U> : G<U> where U : class
{
internal const string T_ID = nameof(GG<U>) + "`1";
internal const string P_ID_this = T_ID + ".Item(" + nameof(System) + "." + nameof(Int32) + ")";

/// <summary>Constructor GG</summary>
public GG() { }
public override string[] M(in string[] x) => default;

/// <inheritdoc />
public override U this[int i] => default;
public override string[] this[int i] => default;
}

/// <inheritdoc />
public class GI : G<string>
/// <typeparam name="V"><inheritdoc cref="IComparable{T}" path="/typeparam[@name='T']/node()" /></typeparam>
#pragma warning disable 1712
public class GX<V, U> : Lazy<U>, IEquatable<Lazy<U>>, IComparable<V>
#pragma warning restore 1712
{
internal const string T_ID = nameof(GI);
internal const string M_ID = T_ID + "." + nameof(M) + "(" + nameof(System) + "." + nameof(String) + "@)";

/// <inheritdoc />
public override string M(in string s) => default;

/// <inheritdoc />
public override string this[int i] => default;
}

/// <inheritdoc />
public class GX<U> : Lazy<U>, IEquatable<Lazy<U>>
{
internal const string T_ID = nameof(GX<U>) + "`1";
internal const string M_ID_GetHashCode = T_ID + "." + nameof(GetHashCode);
internal const string M_ID_Equals = T_ID + "." + nameof(Equals) + "(" + nameof(System) + "." + nameof(Lazy<U>) + "{`0})";

/// <inheritdoc />
public override int GetHashCode() => default;

/// <inheritdoc />
public bool Equals(Lazy<U> other) => default;

/// <inheritdoc />
/// <param name="other"><typeparamref name="V"/></param>
public int CompareTo(V other) => default;
}

/// <inheritdoc />
public class GXI : Lazy<string>, IEquatable<string>
/// <typeparam name="T">TypeParam T</typeparam>
public class GXI<T> : Lazy<string[]>, IEquatable<string>
{
internal const string T_ID = nameof(GXI);
internal const string M_ID_Equals = T_ID + "." + nameof(Equals) + "(" + nameof(System) + "." + nameof(String) + ")";
internal const string T_ID = nameof(GXI<T>) + "`1";
internal const string M_ID_OpImplicit = T_ID + ".op_Implicit(" + nameof(GXI<T>) + "{`0})~" + nameof(System) + "." + nameof(String);

/// <inheritdoc />
public bool Equals(string other) => default;
public bool Equals(string o) => default;

/// <inheritdoc cref="Equals(string)" />
public static implicit operator string(GXI<T> o) => default;
}

/// <inheritdoc />
Expand Down Expand Up @@ -246,11 +233,26 @@ public class GIS<TT> : GG<TT>, IG<TT> where TT : class
unsafe public virtual MT[] M<MT>(MT* mtp) where MT : unmanaged => default;
}

/// <inheritdoc />
public class GG<U> : G<U> where U : class
{
internal const string T_ID = nameof(GG<U>) + "`1";
internal const string P_ID_this = T_ID + ".Item(" + nameof(System) + "." + nameof(Int32) + ")";

/// <summary>Constructor GG</summary>
public GG() { }

/// <inheritdoc />
public override U this[int i] => default;
}

/// <inheritdoc />
public class GII : IG<string>
{
internal const string T_ID = nameof(GII);
internal const string M_ID = T_ID + "." + nameof(M) + "``1(``0*)";

/// <inheritdoc />
private GII() { }

/// <inheritdoc />
unsafe public T[] M<T>(T* tp) where T : unmanaged => default;
Expand All @@ -266,11 +268,32 @@ public class W
/// <summary>Internal Field T_ID</summary>
internal const string T_ID = nameof(W);
internal const string F_ID = T_ID + "." + nameof(T_ID);
internal const string M_ID_NotInherited = T_ID + "." + nameof(MNotInherited);
internal const string P_ID_NotInherited = T_ID + "." + nameof(PNotInherited);

/// <inheritdoc />
public void MNotInherited() { }

/// <inheritdoc />
[GeneratedCode("SG", "1")]
public int PNotInherited { get; set; }

/// <summary>M managed</summary>
/// <param name="ptr">fnptr</param>
public unsafe void M(delegate*<void> ptr) { }

/// <inheritdoc />
public void NotInherited() { }
public override string ToString() => default;
}

/// <inheritdoc cref="GIG{TT}" />
/// <typeparam name="U">U</typeparam>
public class GB<U> : B { }

/// <inheritdoc />
[CompilerGenerated]
public interface IG { }

//
// Tricky Generic Case
//
Expand Down Expand Up @@ -305,6 +328,7 @@ void ICollection<KeyValuePair<string, string>>.CopyTo(KeyValuePair<string, strin
// Internal Type
//

/// <inheritdoc />
internal class ImplementsICollection : ICollection<string>
{
internal const string T_ID = nameof(ImplementsICollection);
Expand Down
62 changes: 52 additions & 10 deletions tests/InheritDoc.Test/InheritDocTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using System.Xml.Linq;
using System.Xml.XPath;
using System.Diagnostics;
using System.Collections.Generic;

using Microsoft.VisualStudio.TestTools.UnitTesting;

Expand All @@ -23,6 +24,7 @@ public class InheritDocTests
static readonly string assemblyPath = typeof(InheritDocTests).Assembly.Location;
static readonly string documentPath = Path.Combine(Path.GetDirectoryName(assemblyPath), Path.GetFileNameWithoutExtension(assemblyPath) + ".xml");
static readonly string[] referencePaths = new[] { Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), corlibPath.Replace('\\', Path.DirectorySeparatorChar)), typeof(InheritDocProcessor).Assembly.Location };
static readonly DebugLogger logger = new();

static XElement processedDocs;
static XElement processedDocsPrivateTrim;
Expand All @@ -33,15 +35,14 @@ public static void InheritDocProcess(TestContext _)
string outPath = documentPath + ".after";
string outPathPrivateTrim = documentPath + ".privateTrim.after";

var log = new DebugLogger() as ILogger;
var (replaced, total, trimmed) = InheritDocProcessor.InheritDocs(assemblyPath, documentPath, outPath, referencePaths, [ ], ApiLevel.Internal, log);
log.Write(ILogger.Severity.Message, $"replaced {replaced} of {total} and removed {trimmed}");
var (replaced, total, trimmed) = InheritDocProcessor.InheritDocs(assemblyPath, documentPath, outPath, referencePaths, [ ], ApiLevel.Internal, logger);
logger.Write(ILogger.Severity.Message, $"replaced {replaced} of {total} and removed {trimmed}");

using var stmdoc = File.Open(outPath, FileMode.Open);
processedDocs = XDocument.Load(stmdoc, LoadOptions.PreserveWhitespace).Root.Element("members");

(replaced, total, trimmed) = InheritDocProcessor.InheritDocs(assemblyPath, documentPath, outPathPrivateTrim, referencePaths, [ ], ApiLevel.Private, log);
log.Write(ILogger.Severity.Message, $"replaced {replaced} of {total} and removed {trimmed}");
var task = new InheritDocTask { AssemblyPath = assemblyPath, InDocPath = documentPath, OutDocPath = outPathPrivateTrim, RefAssemblyPaths = string.Join(";", referencePaths), TrimLevel = ApiLevel.Private.ToString(), Logger = logger };
task.Execute();

using var stmdocPrivateTrim = File.Open(outPathPrivateTrim, FileMode.Open);
processedDocsPrivateTrim = XDocument.Load(stmdocPrivateTrim, LoadOptions.PreserveWhitespace).Root.Element("members");
Expand Down Expand Up @@ -100,7 +101,7 @@ public void ConstructorInherits()
public void NestedGenericParamsAssigned()
{
var ele = getDocElement("M:" + GIG<string>.M_ID_MImplicit, "summary");
Assert.AreEqual("Method M", ele?.Value);
Assert.AreEqual("Method M ", ele?.Value);
}

[TestMethod]
Expand All @@ -125,12 +126,33 @@ public void CrefOverridesDefaultBase()
}

[TestMethod]
public void TypeParamRefRemapped()
public void MethodTypeParamRefRemapped()
{
var ele = getDocElement("M:" + GIG<string>.M_ID_MExplicit, "returns/typeparamref[@name='MT']");
Assert.IsNotNull(ele);
}

[TestMethod]
public void MethodTypeParamRefRemappedFromClass()
{
var ele = getDocElement("M:" + GIG<string>.M_ID_MImplicit, "summary/typeparamref[@name='TT']");
Assert.IsNotNull(ele);
}

[TestMethod]
public void ClosedTypeParamRefReplaced()
{
var ele = getDocElement("P:" + GGI.P_ID, "value/see[@cref='T:System.String[]']");
Assert.IsNotNull(ele);
}

[TestMethod]
public void UnusedTypeParamsTrimmed()
{
var ele = getDocElement("T:" + D.T_ID, ".");
Assert.AreEqual(0, ele?.Elements("typeparam").Count() ?? 0);
}

[TestMethod]
public void UnusedParamsTrimmed()
{
Expand Down Expand Up @@ -183,7 +205,7 @@ public void StructInheritsFromRefDocs()
[TestMethod]
public void ClassInheritsFromRefDocs()
{
var ele = getDocElement("T:" + GXI.T_ID, "summary");
var ele = getDocElement("T:" + GXI<string>.T_ID, "summary");
Assert.AreEqual("Provides support for lazy initialization.", ele?.Value);
}

Expand Down Expand Up @@ -297,6 +319,20 @@ public void InternalClassImplementsInterfaceImplicitPrivateTrim()
Assert.IsNotNull(ele);
}

[TestMethod]
public void NoBaseWarning()
{
bool warn = logger.Warnings.Any(w => w.code == ErrorCodes.NoBase && w.msg.Contains("M:" + W.M_ID_NotInherited));
Assert.IsTrue(warn);
}

[TestMethod]
public void NoBaseWarningIgnoredForGenerated()
{
bool warn = logger.Warnings.Any(w => w.code == ErrorCodes.NoBase && w.msg.Contains("P:" + W.P_ID_NotInherited));
Assert.IsFalse(warn);
}

private static XElement? getDocElement(string docID, string xpath) =>
processedDocs.Elements("member").FirstOrDefault(m => (string)m.Attribute("name") == docID)?.XPathSelectElement(xpath);

Expand All @@ -305,12 +341,18 @@ public void InternalClassImplementsInterfaceImplicitPrivateTrim()

private class DebugLogger : ILogger
{
void ILogger.Write(ILogger.Severity severity, string msg)
public readonly List<(string code, string msg)> Warnings = [ ];

public void Write(ILogger.Severity severity, string msg)
{
if (severity >= ILogger.Severity.Info)
Debug.WriteLine(msg);
}

void ILogger.Warn(string code, string file, int line, int column, string msg) => Debug.WriteLine(code + ": " + msg);
public void Warn(string code, string file, int line, int column, string msg)
{
Warnings.Add((code, msg));
Debug.WriteLine(code + ": " + msg);
}
}
}

0 comments on commit 391b8a2

Please sign in to comment.