using GitConverter.Lib.Factories;
using GitConverter.Lib.Converters;
using GitConverter.TestsApp.TestSupport;
namespace GitConverter.TestsApp.Factories
{
///
/// Lightweight unit tests verifying specific logging behaviors of .
///
///
///
/// Purpose
/// - Validate that emits diagnostic and error logs at the
/// expected levels during construction, lookup misses, successful instantiation and failure
/// to instantiate converter delegates.
///
///
/// Test approach
/// - Use a that captures emitted log messages. Assert on presence of
/// tokens at the appropriate (Debug/Info/Warn/Error) rather than
/// comparing complete strings to keep assertions resilient to wording changes.
/// - Exercise both default built-in registrations (via the parameterless constructor) and
/// custom registrations that simulate error conditions (factory delegate throwing).
///
///
/// Important messages asserted in tests
/// - Lookup miss: Debug message indicating a lookup miss when asking for an unknown key.
/// - Suggestion warn: Warn-level message when Create() throws and suggests a close match.
/// - Duplicate registration: Error-level message emitted when duplicate normalized keys are registered.
/// - Instantiation success: Debug-level message emitted when a factory delegate returns a converter instance.
/// - Instantiation failure: Warn-level message emitted when a factory delegate throws during TryCreate.
/// - Registration summary: Info-level message emitted at factory initialization listing supported options.
///
///
public class ConverterFactoryLoggingTests
{
[Fact]
public void TryCreate_UnknownKey_LogsLookupMiss()
{
var logger = new TestLogger();
var factory = new ConverterFactory(null, logger);
var ok = factory.TryCreate("this-does-not-exist", out var conv);
Assert.False(ok);
Assert.Null(conv);
LogAssert.ContainsMessage(logger, LogLevel.Debug, "lookup miss");
}
[Fact]
public void Create_Typo_LogsSuggestionWarn()
{
var logger = new TestLogger();
var factory = new ConverterFactory(null, logger);
var ex = Assert.Throws(() => factory.Create("esrijsn"));
Assert.Contains("Did you mean", ex.Message, StringComparison.OrdinalIgnoreCase);
LogAssert.ContainsMessage(logger, LogLevel.Warn, "suggest");
}
[Fact]
public void DuplicateRegistration_LogsError()
{
var registrations = new Dictionary>(StringComparer.Ordinal)
{
{ "A", () => new UniversalGisConverter() },
{ "a", () => new UniversalGisConverter() } // duplicates normalized key
};
var logger = new TestLogger();
var ex = Record.Exception(() => new ConverterFactory(registrations, logger));
Assert.NotNull(ex);
LogAssert.ContainsMessage(logger, LogLevel.Error, "duplicate registration");
}
[Fact]
public void TryCreate_Success_LogsInstantiation()
{
var logger = new TestLogger();
var factory = new ConverterFactory(null, logger);
var ok = factory.TryCreate("GeoJson", out var conv);
Assert.True(ok);
Assert.NotNull(conv);
// The factory logs a debug message indicating instantiation success
LogAssert.ContainsMessage(logger, LogLevel.Debug, "instantiated converter");
}
[Fact]
public void Constructor_LogsRegistrationSummary_Info()
{
var logger = new TestLogger();
// Constructing the factory should log an info-level registration summary
var factory = new ConverterFactory(null, logger);
LogAssert.ContainsMessage(logger, LogLevel.Info, "initialized with options");
}
[Fact]
public void TryCreate_FactoryDelegateThrows_LogsWarn()
{
var registrations = new Dictionary>(StringComparer.OrdinalIgnoreCase)
{
{ "Explode", () => throw new InvalidOperationException("boom") }
};
var logger = new TestLogger();
var factory = new ConverterFactory(registrations, logger);
var ok = factory.TryCreate("Explode", out var conv);
Assert.False(ok);
Assert.Null(conv);
LogAssert.ContainsMessage(logger, LogLevel.Warn, "failed to instantiate converter");
}
}
}