Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[http-client-csharp] Fix: remove duplicate 'Client' suffix in subclients #4791

Merged
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 @@ -2,13 +2,11 @@
// Licensed under the MIT License.

using System;
using System.ClientModel.Primitives;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using Microsoft.Generator.CSharp.ClientModel.Primitives;
using Microsoft.Generator.CSharp.ClientModel.Snippets;
using Microsoft.Generator.CSharp.Expressions;
using Microsoft.Generator.CSharp.Input;
using Microsoft.Generator.CSharp.Primitives;
Expand All @@ -25,6 +23,7 @@ public class ClientProvider : TypeProvider
private const string AuthorizationApiKeyPrefixConstName = "AuthorizationApiKeyPrefix";
private const string ApiKeyCredentialFieldName = "_keyCredential";
private const string EndpointFieldName = "_endpoint";
private const string ClientSuffix = "Client";
private readonly FormattableString _publicCtorDescription;
private readonly InputClient _inputClient;
private readonly InputAuth? _inputAuth;
Expand Down Expand Up @@ -429,10 +428,13 @@ protected override MethodProvider[] BuildMethods()
var interlockedCompareExchange = Static(typeof(Interlocked)).Invoke(
nameof(Interlocked.CompareExchange),
[cachedClientFieldVar, New.Instance(subClientInstance.Type, subClientConstructorArgs), Null]);
var factoryMethodName = subClient.Value.Name.EndsWith(ClientSuffix, StringComparison.OrdinalIgnoreCase)
? $"Get{subClient.Value.Name}"
: $"Get{subClient.Value.Name}{ClientSuffix}";

var factoryMethod = new MethodProvider(
new(
$"Get{subClient.Value.Name}Client",
factoryMethodName,
$"Initializes a new instance of {subClientInstance.Type.Name}",
MethodSignatureModifiers.Public | MethodSignatureModifiers.Virtual,
subClientInstance.Type,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -266,5 +266,31 @@ public async Task CanChangeClientOptionsAccessibility()
Assert.IsNull(method.XmlDocs);
}
}

[Test]
public async Task CanRenameSubClient()
{
var inputOperation = InputFactory.Operation("HelloAgain", parameters:
[
InputFactory.Parameter("p1", InputFactory.Array(InputPrimitiveType.String))
]);
var inputClient = InputFactory.Client("TestClient", operations: [inputOperation]);
InputClient subClient = InputFactory.Client("custom", [], [], inputClient.Name);
var plugin = await MockHelpers.LoadMockPluginAsync(
clients: () => [inputClient, subClient],
compilation: async () => await Helpers.GetCompilationFromDirectoryAsync());

// Find the sub-client provider
var subClientProvider = plugin.Object.OutputLibrary.TypeProviders.SingleOrDefault(t => t is ClientProvider && t.Name == "CustomClient");
Assert.IsNotNull(subClientProvider);

// find the parent client provider
var parentClientProvider = plugin.Object.OutputLibrary.TypeProviders.SingleOrDefault(t => t is ClientProvider && t.Name == "TestClient");
Assert.IsNotNull(parentClientProvider);

// find the sub-client factory method
var subClientFactoryMethod = parentClientProvider!.Methods.SingleOrDefault(m => m.Signature.Name == "GetCustomClient");
Assert.IsNotNull(subClientFactoryMethod);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,15 @@ public class ClientProviderSubClientTests
private static readonly InputClient _animalClient = new("animal", "AnimalClient description", [], [], TestClientName);
private static readonly InputClient _dogClient = new("dog", "DogClient description", [], [], _animalClient.Name);
private static readonly InputClient _catClient = new("cat", "CatClient description", [], [], _animalClient.Name);
private static readonly InputClient _hawkClient = new("hawkClient", "HawkClient description", [], [], _animalClient.Name);
private static readonly InputClient _huskyClient = new("husky", "HuskyClient description", [], [], _dogClient.Name);

[SetUp]
public void SetUp()
{
MockHelpers.LoadMockPlugin(
apiKeyAuth: () => new InputApiKeyAuth("mock", null),
clients: () => [_animalClient, _dogClient, _catClient, _huskyClient]);
clients: () => [_animalClient, _dogClient, _catClient, _huskyClient, _hawkClient]);
}

// This test validates that the generated code is correct when the client has one direct subclient.
Expand Down Expand Up @@ -57,7 +58,8 @@ public void SubClientWithMultipleSubClients()
string[] expectedSubClientFactoryMethodNames =
[
$"Get{_dogClient.Name.ToCleanName()}Client",
$"Get{_catClient.Name.ToCleanName()}Client"
$"Get{_catClient.Name.ToCleanName()}Client",
$"Get{_hawkClient.Name.ToCleanName()}"
];
var clientProvider = new MockClientProvider(_animalClient, expectedSubClientFactoryMethodNames);
var writer = new TypeProviderWriter(clientProvider);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using Microsoft.Generator.CSharp.Customization;

namespace Sample
{
[CodeGenClient("Custom")]
internal partial class CustomClient
{
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,11 @@ public partial class Animal
{
return (global::System.Threading.Volatile.Read(ref _cachedCat) ?? (global::System.Threading.Interlocked.CompareExchange(ref _cachedCat, new global::Sample.Cat(), null) ?? _cachedCat));
}

/// <summary> Initializes a new instance of HawkClient. </summary>
public virtual global::Sample.HawkClient GetHawkClient()
{
return (global::System.Threading.Volatile.Read(ref _cachedHawkClient) ?? (global::System.Threading.Interlocked.CompareExchange(ref _cachedHawkClient, new global::Sample.HawkClient(), null) ?? _cachedHawkClient));
}
}
}
Loading