diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/test/Providers/ClientProviders/ClientProviderCustomizationTests.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/test/Providers/ClientProviders/ClientProviderCustomizationTests.cs new file mode 100644 index 0000000000..b4fae5cbc3 --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/test/Providers/ClientProviders/ClientProviderCustomizationTests.cs @@ -0,0 +1,118 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.ClientModel; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.Generator.CSharp.ClientModel.Providers; +using Microsoft.Generator.CSharp.Input; +using Microsoft.Generator.CSharp.Tests.Common; +using NUnit.Framework; + +namespace Microsoft.Generator.CSharp.ClientModel.Tests.Providers.ClientProviders +{ + public class ClientProviderCustomizationTests + { + [Test] + public async Task CanAddMethod() + { + var inputOperation = InputFactory.Operation("HelloAgain", parameters: + [ + InputFactory.Parameter("p1", InputFactory.Array(InputPrimitiveType.String)) + ]); + var inputClient = InputFactory.Client("TestClient", operations: [inputOperation]); + var plugin = await MockHelpers.LoadMockPluginAsync( + clients: () => [inputClient], + compilation: async () => await Helpers.GetCompilationFromDirectoryAsync()); + + // Find the client provider + var clientProvider = plugin.Object.OutputLibrary.TypeProviders.SingleOrDefault(t => t is ClientProvider); + Assert.IsNotNull(clientProvider); + + var clientProviderMethods = clientProvider!.Methods; + Assert.AreEqual(4, clientProviderMethods.Count); + Assert.IsFalse(clientProviderMethods.Any(m => m.Signature.Name == "NewMethod")); + + // The custom code view should contain the method + var customCodeView = clientProvider.CustomCodeView; + Assert.IsNotNull(customCodeView); + var customMethods = customCodeView!.Methods; + Assert.AreEqual(1, customMethods.Count); + Assert.AreEqual("NewMethod", customMethods[0].Signature.Name); + Assert.AreEqual(customMethods[0].Signature.Parameters.Count, 2); + Assert.IsNull(customMethods[0].BodyExpression); + Assert.AreEqual(string.Empty, customMethods[0].BodyStatements!.ToDisplayString()); + } + + [Test] + public async Task CanAddMultipleMethods() + { + var inputOperation = InputFactory.Operation("HelloAgain", parameters: + [ + InputFactory.Parameter("p1", InputFactory.Array(InputPrimitiveType.String)) + ]); + var inputClient = InputFactory.Client("TestClient", operations: [inputOperation]); + var plugin = await MockHelpers.LoadMockPluginAsync( + clients: () => [inputClient], + compilation: async () => await Helpers.GetCompilationFromDirectoryAsync()); + + // Find the client provider + var clientProvider = plugin.Object.OutputLibrary.TypeProviders.SingleOrDefault(t => t is ClientProvider); + Assert.IsNotNull(clientProvider); + + var clientProviderMethods = clientProvider!.Methods; + Assert.AreEqual(4, clientProviderMethods.Count); + + // The custom code view should contain the method + var customCodeView = clientProvider.CustomCodeView; + Assert.IsNotNull(customCodeView); + var customMethods = customCodeView!.Methods; + Assert.AreEqual(4, customMethods.Count); + Assert.AreEqual("NewMethodOne", customMethods[0].Signature.Name); + Assert.AreEqual(customMethods[0].Signature.Parameters.Count, 2); + Assert.AreEqual("NewMethodTwo", customMethods[1].Signature.Name); + Assert.AreEqual(customMethods[1].Signature.Parameters.Count, 0); + Assert.AreEqual("NewMethodThree", customMethods[2].Signature.Name); + Assert.AreEqual(customMethods[2].Signature.Parameters.Count, 1); + Assert.AreEqual("NewMethodFour", customMethods[3].Signature.Name); + Assert.AreEqual(customMethods[3].Signature.Parameters.Count, 1); + } + + // Validates that the custom method is added when the method has the same name as an existing method but different parameters + [Test] + public async Task CanAddMethodSameName() + { + var inputOperation = InputFactory.Operation("HelloAgain", parameters: + [ + InputFactory.Parameter("p1", InputFactory.Array(InputPrimitiveType.String)) + ]); + var inputClient = InputFactory.Client("TestClient", operations: [inputOperation]); + var plugin = await MockHelpers.LoadMockPluginAsync( + clients: () => [inputClient], + compilation: async () => await Helpers.GetCompilationFromDirectoryAsync()); + + // Find the client provider + var clientProvider = plugin.Object.OutputLibrary.TypeProviders.SingleOrDefault(t => t is ClientProvider); + Assert.IsNotNull(clientProvider); + + var clientProviderMethods = clientProvider!.Methods; + Assert.AreEqual(4, clientProviderMethods.Count); + + var helloAgainMethod = clientProviderMethods.FirstOrDefault(m + => m.Signature.Name == "HelloAgain" && m.Signature.Parameters.Count > 0 && m.Signature.Parameters[0].Name == "p1"); + Assert.IsNotNull(helloAgainMethod); + Assert.AreEqual(1, helloAgainMethod!.Signature.Parameters.Count); + + // The custom code view should contain the method + var customCodeView = clientProvider.CustomCodeView; + Assert.IsNotNull(customCodeView); + var customMethods = customCodeView!.Methods; + Assert.AreEqual(1, customMethods.Count); + Assert.AreEqual("HelloAgain", customMethods[0].Signature.Name); + Assert.AreEqual(customMethods[0].Signature.Parameters.Count, 2); + Assert.IsNull(customMethods[0].BodyExpression); + Assert.AreEqual(string.Empty, customMethods[0].BodyStatements!.ToDisplayString()); + } + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/test/Providers/ClientProviders/TestData/ClientProviderCustomizationTests/CanAddMethod/CanAddMethod.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/test/Providers/ClientProviders/TestData/ClientProviderCustomizationTests/CanAddMethod/CanAddMethod.cs new file mode 100644 index 0000000000..4bb20ab75f --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/test/Providers/ClientProviders/TestData/ClientProviderCustomizationTests/CanAddMethod/CanAddMethod.cs @@ -0,0 +1,25 @@ +// + +#nullable disable + +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Sample +{ + /// + public partial class TestClient + { + public virtual ClientResult NewMethod(BinaryContent content, RequestOptions options) + { + Argument.AssertNotNull(content, nameof(content)); + + using PipelineMessage message = CreateRequest(content, options); + return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options)); + } + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/test/Providers/ClientProviders/TestData/ClientProviderCustomizationTests/CanAddMethodSameName/CanAddMethodSameName.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/test/Providers/ClientProviders/TestData/ClientProviderCustomizationTests/CanAddMethodSameName/CanAddMethodSameName.cs new file mode 100644 index 0000000000..750bbb18f1 --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/test/Providers/ClientProviders/TestData/ClientProviderCustomizationTests/CanAddMethodSameName/CanAddMethodSameName.cs @@ -0,0 +1,22 @@ +// + +#nullable disable + +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Sample +{ + /// + public partial class TestClient + { + public virtual ClientResult HelloAgain(string[] p1, RequestOptions options) + { + + } + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/test/Providers/ClientProviders/TestData/ClientProviderCustomizationTests/CanAddMultipleMethods/CanAddMultipleMethods.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/test/Providers/ClientProviders/TestData/ClientProviderCustomizationTests/CanAddMultipleMethods/CanAddMultipleMethods.cs new file mode 100644 index 0000000000..17e0e7e9ff --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/test/Providers/ClientProviders/TestData/ClientProviderCustomizationTests/CanAddMultipleMethods/CanAddMultipleMethods.cs @@ -0,0 +1,32 @@ +// + +#nullable disable + +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Sample +{ + /// + public partial class TestClient + { + public virtual ClientResult NewMethodOne(BinaryContent content, RequestOptions options) + { + Argument.AssertNotNull(content, nameof(content)); + + using PipelineMessage message = CreateRequest(content, options); + return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options)); + } + + public void NewMethodTwo() { } + + public void NewMethodThree(CustomModel p1) { } + public bool NewMethodFour(CustomModel? p1) { return false; } + } + + public class CustomModel { } +} diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/test/TestHelpers/MockHelpers.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/test/TestHelpers/MockHelpers.cs index a16c7c47e0..0c9c14cd5a 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/test/TestHelpers/MockHelpers.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/test/TestHelpers/MockHelpers.cs @@ -25,9 +25,13 @@ internal static class MockHelpers public static async Task> LoadMockPluginAsync( Func>? inputEnums = null, Func>? inputModels = null, + Func>? clients = null, Func>? compilation = null) { - var mockPlugin = LoadMockPlugin(inputEnums: inputEnums, inputModels: inputModels); + var mockPlugin = LoadMockPlugin( + inputEnums: inputEnums, + inputModels: inputModels, + clients: clients); var compilationResult = compilation == null ? null : await compilation(); diff --git a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/TypeProvider.cs b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/TypeProvider.cs index 00f4b78510..d70019b3d3 100644 --- a/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/TypeProvider.cs +++ b/packages/http-client-csharp/generator/Microsoft.Generator.CSharp/src/Providers/TypeProvider.cs @@ -424,7 +424,7 @@ private static bool IsMatch(TypeProvider enclosingType, MethodSignatureBase sign private static bool IsMatch(MethodSignatureBase customMethod, MethodSignatureBase method) { - if (customMethod.Parameters.Count != method.Parameters.Count) + if (customMethod.Parameters.Count != method.Parameters.Count || customMethod.Name != method.Name) { return false; }