Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ protected override MethodProvider[] BuildMethods()
{
var getCachedClientMethod = getCachedClientMethods[mockableResource.ArmCoreType];
redirectedMethods.AddRange(
mockableResource.Methods.Select(m => BuildRedirectMethod(mockableResource.ArmCoreType, m, getCachedClientMethod))
mockableResource.Methods.Select(m => BuildRedirectMethod(mockableResource, m, getCachedClientMethod))
);
}

Expand Down Expand Up @@ -83,10 +83,10 @@ private MethodProvider BuildGetCachedClientMethod(MockableResourceProvider mocka
return new MethodProvider(methodSignature, statements, this);
}

private MethodProvider BuildRedirectMethod(CSharpType coreType, MethodProvider targetMethod, MethodProvider getCachedClientMethod)
private MethodProvider BuildRedirectMethod(MockableResourceProvider mockableResource, MethodProvider targetMethod, MethodProvider getCachedClientMethod)
{
var coreType = mockableResource.ArmCoreType;
var target = targetMethod.Signature;
// TODO -- add mocking information in method description
var extensionParameter = new ParameterProvider(
GetArmCoreTypeVariableName(coreType),
$"The {coreType:C} the method will execute against.",
Expand Down Expand Up @@ -121,7 +121,12 @@ private MethodProvider BuildRedirectMethod(CSharpType coreType, MethodProvider t
}
}

return new MethodProvider(methodSignature, body, this);
var method = new MethodProvider(methodSignature, body, this);

// Add mocking documentation
AddMockingDocumentation(method, mockableResource, targetMethod);

return method;

static ParameterProvider DuplicateParameter(ParameterProvider original)
{
Expand All @@ -140,6 +145,42 @@ static ParameterProvider DuplicateParameter(ParameterProvider original)
}
}

private void AddMockingDocumentation(MethodProvider method, MockableResourceProvider mockableResource, MethodProvider targetMethod)
{
if (method.XmlDocs == null)
{
return;
}

// Build the mocking documentation item
// Format: To mock this method, please mock <see cref="MockableType.MethodName(params)"/> instead.
var mockingDescription = BuildMockingDescription(mockableResource.Type, targetMethod.Signature);
var mockingItem = new XmlDocStatement("item", [],
new XmlDocStatement("term", [$"Mocking"]),
new XmlDocStatement("description", [mockingDescription]));

// Create a new summary with the existing description and the mocking item
// The targetMethod already has the description we want to keep
var descriptionText = targetMethod.Signature.Description ?? $"";
var updatedSummary = new XmlDocSummaryStatement([descriptionText], mockingItem);
method.XmlDocs.Update(summary: updatedSummary);
}

private FormattableString BuildMockingDescription(CSharpType mockableType, MethodSignature targetSignature)
{
// Build description: "To mock this method, please mock <see cref="MockableType.MethodName(params)"/> instead."
// We need to construct a method reference that includes parameter types
// In C# XML docs, method references look like: MethodName(TypeName1, TypeName2)

// Build parameter type list as a simple string since XML doc cref attributes use simple type names
var parameterTypeNames = string.Join(", ", targetSignature.Parameters.Select(p => p.Type.Name));
var methodRef = $"{mockableType.Name}.{targetSignature.Name}({parameterTypeNames})";

// Return a FormattableString that will be converted to: To mock this method, please mock <see cref="..."/> instead.
// The :C formatter on mockableType will create the <see cref> tag
return $"To mock this method, please mock <see cref=\"{methodRef}\"/> instead.";
}

private string GetArmCoreTypeVariableName(CSharpType armCoreType)
{
if (armCoreType.Equals(typeof(ArmClient)))
Expand Down
Loading
Loading