Skip to content
Open
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
19 changes: 10 additions & 9 deletions src/LightInject.Tests/AssemblyScannerTests.cs
Original file line number Diff line number Diff line change
@@ -1,33 +1,32 @@
using System.Management.Instrumentation;
using System.Reflection;

namespace LightInject.Tests
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;

using LightInject;
using LightInject.SampleLibrary;

using LightMock;

using Xunit;



public class AssemblyScannerTests
{
private MockContext<IServiceContainer> GetContainerMock(Func<ILifetime> lifetimeFactory, Func<Type, Type, bool> shouldRegister)
{
var containerMock = new ContainerMock();
var compositionRootMock = new CompositionRootMock();
var asyncCompositionRootMock = new AsyncCompositionRootMock();

var compositionRootTypeExtractorMock = new TypeExtractorMock();
compositionRootTypeExtractorMock.Arrange(c => c.Execute(The<Assembly>.IsAnyValue)).Returns(Type.EmptyTypes);

var assemblyScanner = new AssemblyScanner(new ConcreteTypeExtractor(), compositionRootTypeExtractorMock, new CompositionRootExecutor(containerMock,t => compositionRootMock));
var assemblyScanner = new AssemblyScanner(new ConcreteTypeExtractor(), compositionRootTypeExtractorMock, new CompositionRootExecutor(containerMock,t => compositionRootMock,t => asyncCompositionRootMock));
assemblyScanner.Scan(typeof(IFoo).Assembly, containerMock, lifetimeFactory, shouldRegister);
return containerMock;
}
Expand Down Expand Up @@ -101,12 +100,13 @@ public void Scan_SampleAssembly_ConfiguresAllServicesByDefault()
public void Scan_SampleAssemblyWithCompositionRoot_CallsComposeMethodOnce()
{
var compositionRootMock = new CompositionRootMock();
var asyncCompositionRootMock = new AsyncCompositionRootMock();
var containerMock = new ContainerMock();
var compositionRootExtractorMock = new TypeExtractorMock();
compositionRootExtractorMock.Arrange(c => c.Execute(The<Assembly>.IsAnyValue)).Returns(new []{typeof(CompositionRootMock)});
var assemblyScanner = new AssemblyScanner(new ConcreteTypeExtractor(),
compositionRootExtractorMock,
new CompositionRootExecutor(containerMock, t => compositionRootMock));
new CompositionRootExecutor(containerMock, t => compositionRootMock, t => asyncCompositionRootMock));

assemblyScanner.Scan(typeof(AssemblyScannerTests).Assembly, containerMock);

Expand All @@ -117,10 +117,11 @@ public void Scan_SampleAssemblyWithCompositionRoot_CallsComposeMethodOnce()
public void ScanUsingPredicate_SampleAssemblyWithCompositionRoot_DoesNotCallCompositionRoot()
{
var compositionRootMock = new CompositionRootMock();
var asyncCompositionRootMock = new AsyncCompositionRootMock();
var containerMock = new ContainerMock();
var assemblyScanner = new AssemblyScanner(new ConcreteTypeExtractor(),
new CompositionRootTypeExtractor(new CompositionRootAttributeExtractor()),
new CompositionRootExecutor(containerMock, t => compositionRootMock));
new CompositionRootExecutor(containerMock, t => compositionRootMock, t => asyncCompositionRootMock));

assemblyScanner.Scan(typeof(AssemblyScannerTests).Assembly, containerMock, () => null, (s, t) => true);

Expand Down
8 changes: 8 additions & 0 deletions src/LightInject.Tests/CompositionRootExecutorMock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,19 @@

namespace LightInject.Tests
{
using System.Threading.Tasks;

internal class CompositionRootExecutorMock : MockContext<ICompositionRootExecutor>, ICompositionRootExecutor
{
public void Execute(Type compositionRootType)
{
((IInvocationContext<ICompositionRootExecutor>) this).Invoke(c => c.Execute(compositionRootType));
}

public Task ExecuteAsync(Type compositionRootType)
{
((IInvocationContext<ICompositionRootExecutor>) this).Invoke(c => c.ExecuteAsync(compositionRootType));
return Task.CompletedTask;
}
}
}
52 changes: 47 additions & 5 deletions src/LightInject.Tests/CompositionRootExecutorTests.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
namespace LightInject.Tests
{
{
using System.Threading.Tasks;
using LightMock;
using Xunit;
using Xunit;

public class CompositionRootExecutorTests
{
[Fact]
public void Execute_CompositionRootType_IsCreatedAndExecuted()
{
CompositionRootMock compositionRootMock = new CompositionRootMock();
AsyncCompositionRootMock asyncCompositionRootMock = new AsyncCompositionRootMock();
var serviceContainerMock = new ContainerMock();
var executor = new CompositionRootExecutor(serviceContainerMock, (t) => compositionRootMock);
var executor = new CompositionRootExecutor(serviceContainerMock, (t) => compositionRootMock, (t) => asyncCompositionRootMock);
executor.Execute(typeof(CompositionRootMock));
compositionRootMock.Assert(c => c.Compose(The<IServiceContainer>.IsAnyValue), Invoked.Once);
}
Expand All @@ -19,11 +21,51 @@ public void Execute_CompositionRootType_IsCreatedAndExecuted()
public void Execute_CompositionRootType_IsCreatedAndExecutedOnlyOnce()
{
CompositionRootMock compositionRootMock = new CompositionRootMock();
AsyncCompositionRootMock asyncCompositionRootMock = new AsyncCompositionRootMock();
var serviceContainerMock = new ContainerMock();
var executor = new CompositionRootExecutor(serviceContainerMock, (t) => compositionRootMock);
var executor = new CompositionRootExecutor(serviceContainerMock, (t) => compositionRootMock, (t) => asyncCompositionRootMock);
executor.Execute(typeof(CompositionRootMock));
executor.Execute(typeof(CompositionRootMock));
compositionRootMock.Assert(c => c.Compose(The<IServiceContainer>.IsAnyValue), Invoked.Once);
}

[Fact]
public async Task ExecuteAsync_CompositionRootType_IsCreatedAndExecuted()
{
CompositionRootMock compositionRootMock = new CompositionRootMock();
AsyncCompositionRootMock asyncCompositionRootMock = new AsyncCompositionRootMock();
var serviceContainerMock = new ContainerMock();
var executor = new CompositionRootExecutor(serviceContainerMock, (t) => compositionRootMock, (t) => asyncCompositionRootMock);
await executor.ExecuteAsync(typeof(AsyncCompositionRootMock));
asyncCompositionRootMock.Assert(c => c.ComposeAsync(The<IServiceContainer>.IsAnyValue), Invoked.Once);
}

[Fact]
public async Task ExecuteAsync_CompositionRootType_IsCreatedAndExecutedOnlyOnce()
{
CompositionRootMock compositionRootMock = new CompositionRootMock();
AsyncCompositionRootMock asyncCompositionRootMock = new AsyncCompositionRootMock();
var serviceContainerMock = new ContainerMock();
var executor = new CompositionRootExecutor(serviceContainerMock, (t) => compositionRootMock, (t) => asyncCompositionRootMock);
await executor.ExecuteAsync(typeof(AsyncCompositionRootMock));
await executor.ExecuteAsync(typeof(AsyncCompositionRootMock));
asyncCompositionRootMock.Assert(c => c.ComposeAsync(The<IServiceContainer>.IsAnyValue), Invoked.Once);
}

[Fact]
public async Task ExecuteAsync_CompositionRootType_IsCreatedAndExecutedOnlyOnceWithParallel()
{
CompositionRootMock compositionRootMock = new CompositionRootMock();
AsyncCompositionRootMock asyncCompositionRootMock = new AsyncCompositionRootMock();
var serviceContainerMock = new ContainerMock();
var executor = new CompositionRootExecutor(serviceContainerMock, (t) => compositionRootMock, (t) => asyncCompositionRootMock);

var first = executor.ExecuteAsync(typeof(AsyncCompositionRootMock));
var second = executor.ExecuteAsync(typeof(AsyncCompositionRootMock));

await Task.WhenAll(first, second);

asyncCompositionRootMock.Assert(c => c.ComposeAsync(The<IServiceContainer>.IsAnyValue), Invoked.Once);
}
}
}
15 changes: 10 additions & 5 deletions src/LightInject.Tests/CompositionRootMock.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using LightMock;

namespace LightInject.Tests
{


internal class CompositionRootMock : MockContext<ICompositionRoot>, ICompositionRoot
{
Expand All @@ -24,4 +20,13 @@ public void Compose(IServiceRegistry serviceRegistry)
((IInvocationContext<ICompositionRoot>)this).Invoke(c => c.Compose(serviceRegistry));
}
}

internal class AsyncCompositionRootMock : MockContext<IAsyncCompositionRoot>, IAsyncCompositionRoot
{
public Task ComposeAsync(IServiceRegistry serviceRegistry)
{
((IInvocationContext<IAsyncCompositionRoot>)this).Invoke(c => c.ComposeAsync(serviceRegistry));
return Task.CompletedTask;
}
}
}
7 changes: 6 additions & 1 deletion src/LightInject.Tests/ContainerMock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ namespace LightInject.Tests
{
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;
using System.Threading.Tasks;
using LightMock;

internal class ContainerMock : MockContext<IServiceContainer>, IServiceContainer
Expand Down Expand Up @@ -192,6 +192,11 @@ public void RegisterAssembly(Assembly assembly, Func<ILifetime> lifetimeFactory,
throw new NotImplementedException();
}

public Task RegisterFromAsync<TAsyncCompositionRoot>() where TAsyncCompositionRoot : IAsyncCompositionRoot, new()
{
throw new NotImplementedException();
}

public void RegisterConstructorDependency<TDependency>(Func<IServiceFactory, ParameterInfo, TDependency> factory)
{
throw new NotImplementedException();
Expand Down
3 changes: 2 additions & 1 deletion src/LightInject.Tests/LazyCompositionRootTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,14 @@ public void GetInstance_UnknownService_ExecutesCompositionRootInSourceAssembly()
{
var container = new ServiceContainer();
var compositionRootMock = new CompositionRootMock();
var asyncCompositionRootMock = new AsyncCompositionRootMock();
compositionRootMock.Arrange(c => c.Compose(container)).Callback<IServiceContainer>(c => c.Register<IFoo, Foo>());

var compositionRootTypeExtractorMock = new TypeExtractorMock();
compositionRootTypeExtractorMock.Arrange(c => c.Execute(The<Assembly>.IsAnyValue)).Returns(new[] {typeof(CompositionRootMock)});

var assemblyScanner = new AssemblyScanner(new ConcreteTypeExtractor(), compositionRootTypeExtractorMock,
new CompositionRootExecutor(container, t => compositionRootMock));
new CompositionRootExecutor(container, t => compositionRootMock, t => asyncCompositionRootMock));

container.AssemblyScanner = assemblyScanner;

Expand Down
27 changes: 18 additions & 9 deletions src/LightInject.Tests/ServiceContainerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,17 @@ namespace LightInject.Tests
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security;

using System.Linq;
using System.Text;
using System.Threading.Tasks;

using LightInject;
using LightInject.SampleLibrary;
using Xunit;
using Xunit.Sdk;
using Bar = LightInject.SampleLibrary.Bar;
using Foo = LightInject.SampleLibrary.Foo;
using IFoo = LightInject.SampleLibrary.IFoo;
using IBar = LightInject.SampleLibrary.IBar;
using Bar = LightInject.SampleLibrary.Bar;
using IFoo = LightInject.SampleLibrary.IFoo;

public class ServiceContainerTests : TestBase
{
#region InputValidation
Expand Down Expand Up @@ -1600,7 +1596,20 @@ public void RegisterFrom_CompositionRoot_CallsCompositionRootExecutor()

compositionRootExecutorMock.Assert(c => c.Execute(typeof(CompositionRootMock)), Invoked.Once);
}
#endif
#endif

[Fact]
public async Task RegisterFromAsync_CompositionRoot_CallsCompositionRootExecutor()
{
var container = (ServiceContainer)CreateContainer();
var compositionRootExecutorMock = new CompositionRootExecutorMock();
container.CompositionRootExecutor = compositionRootExecutorMock;

await container.RegisterFromAsync<AsyncCompositionRootMock>();

compositionRootExecutorMock.Assert(c => c.ExecuteAsync(typeof(AsyncCompositionRootMock)), Invoked.Once);
}

[Fact]
public void GetInstance_SingletonInstance_EmitterIsProperlyPoppedOnConstructorException()
{
Expand Down
Loading