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
@@ -0,0 +1,82 @@
using System.Reflection;
using FluentAssertions;
using Microsoft.Extensions.DependencyInjection;
using Trax.Effect.Attributes;
using Trax.Effect.Extensions;

namespace Trax.Effect.Tests.Integration.UnitTests.Attributes;

[TestFixture]
public class InjectAttributeTests
{
[Test]
public void InjectAttribute_CanBeAppliedToProperty()
{
// Arrange & Act
var property = typeof(TestInjectable).GetProperty(nameof(TestInjectable.InjectedService));
var attribute = property?.GetCustomAttribute<InjectAttribute>();

// Assert
attribute.Should().NotBeNull();
}

[Test]
public void InjectAttribute_TargetsPropertyOnly()
{
// Arrange & Act
var attributeUsage = typeof(InjectAttribute).GetCustomAttribute<AttributeUsageAttribute>();

// Assert
attributeUsage.Should().NotBeNull();
attributeUsage!.ValidOn.Should().Be(AttributeTargets.Property);
}

[Test]
public void InjectProperties_SetsMarkedProperties()
{
// Arrange
var services = new ServiceCollection();
services.AddSingleton<ITestService>(new TestService());
using var provider = services.BuildServiceProvider();
var instance = new TestInjectable();

// Act
provider.InjectProperties(instance);

// Assert
instance.InjectedService.Should().NotBeNull();
instance.InjectedService.Should().BeOfType<TestService>();
}

[Test]
public void InjectProperties_SkipsNonMarkedProperties()
{
// Arrange
var services = new ServiceCollection();
services.AddSingleton<ITestService>(new TestService());
using var provider = services.BuildServiceProvider();
var instance = new TestInjectable();

// Act
provider.InjectProperties(instance);

// Assert
instance.NonInjectedService.Should().BeNull();
}

#region Test helpers

private interface ITestService { }

private class TestService : ITestService { }

private class TestInjectable
{
[Inject]
public ITestService? InjectedService { get; set; }

public ITestService? NonInjectedService { get; set; }
}

#endregion
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
using FluentAssertions;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Trax.Effect.Configuration.TraxEffectBuilder;

namespace Trax.Effect.Tests.Integration.UnitTests.Configuration;

[TestFixture]
public class TraxEffectConfigurationBuilderTests
{
[Test]
public void Constructor_DefaultValues_AreCorrect()
{
// Arrange & Act
var builder = new TraxEffectConfigurationBuilder(new ServiceCollection());

// Assert
builder.DataContextLoggingEffectEnabled.Should().BeFalse();
builder.SerializeStepData.Should().BeFalse();
builder.LogLevel.Should().Be(LogLevel.Debug);
}

[Test]
public void ServiceCollection_ExposedFromConstructor()
{
// Arrange
var services = new ServiceCollection();

// Act
var builder = new TraxEffectConfigurationBuilder(services);

// Assert
builder.ServiceCollection.Should().BeSameAs(services);
}

[Test]
public void SetEffectLogLevel_UpdatesLogLevel()
{
// Arrange
var builder = new TraxEffectConfigurationBuilder(new ServiceCollection());

// Act
builder.LogLevel = LogLevel.Trace;

// Assert
builder.LogLevel.Should().Be(LogLevel.Trace);
}

[Test]
public void SerializeStepData_SetTrue_IsReflected()
{
// Arrange
var builder = new TraxEffectConfigurationBuilder(new ServiceCollection());

// Act
builder.SerializeStepData = true;

// Assert
builder.SerializeStepData.Should().BeTrue();
}

[Test]
public void TrainParameterJsonSerializerOptions_DefaultIsNotNull()
{
// Arrange & Act
var builder = new TraxEffectConfigurationBuilder(new ServiceCollection());

// Assert
builder.TrainParameterJsonSerializerOptions.Should().NotBeNull();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
using FluentAssertions;
using LanguageExt;
using Microsoft.Extensions.DependencyInjection;
using Trax.Core.Route;
using Trax.Core.Step;
using Trax.Effect.Extensions;

namespace Trax.Effect.Tests.Integration.UnitTests.Extensions;

[TestFixture]
public class ServiceExtensionsRegistrationTests
{
[Test]
public void AddScopedTraxStep_Resolves_ViaInterface()
{
// Arrange
var services = new ServiceCollection();
services.AddScopedTraxStep<IFakeStep, FakeStep>();
using var provider = services.BuildServiceProvider();

// Act
var step = provider.GetService<IFakeStep>();

// Assert
step.Should().NotBeNull();
step.Should().BeOfType<FakeStep>();
}

[Test]
public void AddTransientTraxStep_Resolves_ViaInterface()
{
// Arrange
var services = new ServiceCollection();
services.AddTransientTraxStep<IFakeStep, FakeStep>();
using var provider = services.BuildServiceProvider();

// Act
var step = provider.GetService<IFakeStep>();

// Assert
step.Should().NotBeNull();
step.Should().BeOfType<FakeStep>();
}

[Test]
public void AddSingletonTraxStep_Resolves_ViaInterface()
{
// Arrange
var services = new ServiceCollection();
services.AddSingletonTraxStep<IFakeStep, FakeStep>();
using var provider = services.BuildServiceProvider();

// Act
var step = provider.GetService<IFakeStep>();

// Assert
step.Should().NotBeNull();
step.Should().BeOfType<FakeStep>();
}

[Test]
public void AddScopedTraxRoute_Resolves_ViaInterface()
{
// Arrange
var services = new ServiceCollection();
services.AddScopedTraxRoute<IFakeRoute, FakeRoute>();
using var provider = services.BuildServiceProvider();

// Act
var route = provider.GetService<IFakeRoute>();

// Assert
route.Should().NotBeNull();
route.Should().BeOfType<FakeRoute>();
}

[Test]
public void AddTransientTraxRoute_Resolves_ViaInterface()
{
// Arrange
var services = new ServiceCollection();
services.AddTransientTraxRoute<IFakeRoute, FakeRoute>();
using var provider = services.BuildServiceProvider();

// Act
var route = provider.GetService<IFakeRoute>();

// Assert
route.Should().NotBeNull();
route.Should().BeOfType<FakeRoute>();
}

[Test]
public void AddSingletonTraxRoute_Resolves_ViaInterface()
{
// Arrange
var services = new ServiceCollection();
services.AddSingletonTraxRoute<IFakeRoute, FakeRoute>();
using var provider = services.BuildServiceProvider();

// Act
var route = provider.GetService<IFakeRoute>();

// Assert
route.Should().NotBeNull();
route.Should().BeOfType<FakeRoute>();
}

#region Test helpers

public interface IFakeStep : IStep<string, int> { }

public class FakeStep : Step<string, int>, IFakeStep
{
public override Task<int> Run(string input) => Task.FromResult(input.Length);
}

public interface IFakeRoute : IRoute<string, int> { }

public class FakeRoute : IFakeRoute
{
public Task<int> Run(string input, CancellationToken cancellationToken = default) =>
Task.FromResult(input.Length);
}

#endregion
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using System.Text.Json;
using FluentAssertions;
using Trax.Effect.Utils;

namespace Trax.Effect.Tests.Integration.UnitTests.Utils;

[TestFixture]
public class DisposableConverterTests
{
[Test]
public void CanConvert_DisposableType_ReturnsTrue()
{
// Arrange
var converter = new DisposableConverter();

// Act
var result = converter.CanConvert(typeof(MemoryStream));

// Assert
result.Should().BeTrue();
}

[Test]
public void CanConvert_NonDisposableType_ReturnsFalse()
{
// Arrange
var converter = new DisposableConverter();

// Act
var result = converter.CanConvert(typeof(string));

// Assert
result.Should().BeFalse();
}

[Test]
public void Write_DisposableObject_WritesPlaceholder()
{
// Arrange
var options = new JsonSerializerOptions();
options.Converters.Add(new DisposableConverter());
using var stream = new MemoryStream();

// Act
var json = JsonSerializer.Serialize<object>(stream, options);

// Assert
json.Should().Contain("IDisposable");
}
}
Loading
Loading