|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Text;
using Aspire.Cli.Backchannel;
using Aspire.Cli.Certificates;
using Aspire.Cli.Commands;
using Aspire.Cli.Interaction;
using Aspire.Cli.Projects;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Spectre.Console;
using Xunit;
namespace Aspire.Cli.Tests.Utils;
internal static class CliTestHelper
{
public static IServiceCollection CreateServiceCollection(ITestOutputHelper outputHelper, Action<CliServiceCollectionTestOptions>? configure = null)
{
var options = new CliServiceCollectionTestOptions(outputHelper);
configure?.Invoke(options);
var services = new ServiceCollection();
services.AddLogging();
services.AddSingleton(options.AnsiConsoleFactory);
services.AddSingleton(options.ProjectLocatorFactory);
services.AddSingleton(options.InteractionServiceFactory);
services.AddSingleton(options.CertificateServiceFactory);
services.AddSingleton(options.NewCommandPrompterFactory);
services.AddSingleton(options.AddCommandPrompterFactory);
services.AddSingleton(options.PublishCommandPrompterFactory);
services.AddTransient(options.DotNetCliRunnerFactory);
services.AddTransient(options.NuGetPackageCacheFactory);
services.AddTransient<RootCommand>();
services.AddTransient<NewCommand>();
services.AddTransient<RunCommand>();
services.AddTransient<AddCommand>();
services.AddTransient<PublishCommand>();
services.AddTransient(options.AppHostBackchannelFactory);
return services;
}
}
internal sealed class CliServiceCollectionTestOptions(ITestOutputHelper outputHelper)
{
public Func<IServiceProvider, IAnsiConsole> AnsiConsoleFactory { get; set; } = (IServiceProvider serviceProvider) =>
{
AnsiConsoleSettings settings = new AnsiConsoleSettings()
{
Ansi = AnsiSupport.Yes,
Interactive = InteractionSupport.Yes,
ColorSystem = ColorSystemSupport.Standard,
Out = new AnsiConsoleOutput(new TestOutputTextWriter(outputHelper))
};
var ansiConsole = AnsiConsole.Create(settings);
return ansiConsole;
};
public Func<IServiceProvider, INewCommandPrompter> NewCommandPrompterFactory { get; set; } = (IServiceProvider serviceProvider) =>
{
var interactionService = serviceProvider.GetRequiredService<IInteractionService>();
return new NewCommandPrompter(interactionService);
};
public Func<IServiceProvider, IAddCommandPrompter> AddCommandPrompterFactory { get; set; } = (IServiceProvider serviceProvider) =>
{
var interactionService = serviceProvider.GetRequiredService<IInteractionService>();
return new AddCommandPrompter(interactionService);
};
public Func<IServiceProvider, IPublishCommandPrompter> PublishCommandPrompterFactory { get; set; } = (IServiceProvider serviceProvider) =>
{
var interactionService = serviceProvider.GetRequiredService<IInteractionService>();
return new PublishCommandPrompter(interactionService);
};
public Func<IServiceProvider, IProjectLocator> ProjectLocatorFactory { get; set; } = (IServiceProvider serviceProvider) => {
var logger = serviceProvider.GetRequiredService<ILogger<ProjectLocator>>();
return new ProjectLocator(logger, Directory.GetCurrentDirectory());
};
public Func<IServiceProvider, IInteractionService> InteractionServiceFactory { get; set; } = (IServiceProvider serviceProvider) => {
var ansiConsole = serviceProvider.GetRequiredService<IAnsiConsole>();
return new InteractionService(ansiConsole);
};
public Func<IServiceProvider, ICertificateService> CertificateServiceFactory { get; set; } = (IServiceProvider serviceProvider) => {
var interactiveService = serviceProvider.GetRequiredService<IInteractionService>();
return new CertificateService(interactiveService);
};
public Func<IServiceProvider, IDotNetCliRunner> DotNetCliRunnerFactory { get; set; } = (IServiceProvider serviceProvider) => {
var logger = serviceProvider.GetRequiredService<ILogger<DotNetCliRunner>>();
return new DotNetCliRunner(logger, serviceProvider);
};
public Func<IServiceProvider, INuGetPackageCache> NuGetPackageCacheFactory { get; set; } = (IServiceProvider serviceProvider) => {
var logger = serviceProvider.GetRequiredService<ILogger<NuGetPackageCache>>();
var runner = serviceProvider.GetRequiredService<IDotNetCliRunner>();
return new NuGetPackageCache(logger, runner);
};
public Func<IServiceProvider, IAppHostBackchannel> AppHostBackchannelFactory { get; set; } = (IServiceProvider serviceProvider) =>
{
var logger = serviceProvider.GetRequiredService<ILogger<AppHostBackchannel>>();
var rpcTarget = serviceProvider.GetService<CliRpcTarget>() ?? throw new InvalidOperationException("CliRpcTarget not registered");
return new AppHostBackchannel(logger, rpcTarget);
};
}
internal sealed class TestOutputTextWriter(ITestOutputHelper outputHelper) : TextWriter
{
public override Encoding Encoding => Encoding.UTF8;
public override void WriteLine(string? message)
{
outputHelper.WriteLine(message!);
}
public override void Write(string? message)
{
outputHelper.Write(message!);
}
}
|