You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
309 lines
11 KiB
309 lines
11 KiB
// Author: Gockner, Simon
|
|
// Created: 2021-12-03
|
|
// Copyright(c) 2021 SimonG. All Rights Reserved.
|
|
|
|
using JetBrains.Annotations;
|
|
using LightweightIocContainer;
|
|
using LightweightIocContainer.Exceptions;
|
|
using LightweightIocContainer.Interfaces.Installers;
|
|
using LightweightIocContainer.Interfaces.Registrations;
|
|
using LightweightIocContainer.Validation;
|
|
using NSubstitute;
|
|
using NUnit.Framework;
|
|
|
|
namespace Test.LightweightIocContainer.Validation;
|
|
|
|
[TestFixture]
|
|
public class IocValidatorTest
|
|
{
|
|
public interface ITest
|
|
{
|
|
|
|
}
|
|
|
|
[UsedImplicitly]
|
|
public interface IParameter
|
|
{
|
|
bool Method();
|
|
}
|
|
|
|
private class Test : ITest
|
|
{
|
|
public Test(IParameter parameter) => parameter.Method();
|
|
}
|
|
|
|
[UsedImplicitly]
|
|
public interface IConstraint
|
|
{
|
|
|
|
}
|
|
|
|
[UsedImplicitly]
|
|
public interface IGenericTest<T> where T : IConstraint, new()
|
|
{
|
|
|
|
}
|
|
|
|
[UsedImplicitly]
|
|
public class GenericTest<T> : IGenericTest<T> where T : IConstraint, new()
|
|
{
|
|
|
|
}
|
|
|
|
[UsedImplicitly]
|
|
public interface IGenericTestFactory
|
|
{
|
|
IGenericTest<T> Create<T>() where T : IConstraint, new();
|
|
}
|
|
|
|
[UsedImplicitly]
|
|
private class TestViewModelDontIgnoreDesignTimeCtor : ITest
|
|
{
|
|
public TestViewModelDontIgnoreDesignTimeCtor(string name, IParameter parameter) => parameter.Method();
|
|
|
|
public TestViewModelDontIgnoreDesignTimeCtor() => throw new Exception();
|
|
}
|
|
|
|
private class Parameter : IParameter
|
|
{
|
|
public bool Method() => throw new NotImplementedException();
|
|
}
|
|
|
|
[UsedImplicitly]
|
|
public interface ITestFactory
|
|
{
|
|
ITest Create(IParameter parameter);
|
|
}
|
|
|
|
[UsedImplicitly]
|
|
public interface ITestMissingParamFactory
|
|
{
|
|
ITest Create(string name);
|
|
}
|
|
|
|
[UsedImplicitly]
|
|
public interface IInvalidTestFactory
|
|
{
|
|
ITest Create();
|
|
}
|
|
|
|
[UsedImplicitly]
|
|
public interface IParameterFactory
|
|
{
|
|
IParameter Create();
|
|
}
|
|
|
|
private class TestInstallerNoFactory : IIocInstaller
|
|
{
|
|
public void Install(IRegistrationCollector registration) => registration.Add<ITest, Test>();
|
|
}
|
|
|
|
private class TestInstallerWithFactory : IIocInstaller
|
|
{
|
|
public void Install(IRegistrationCollector registration) => registration.Add<ITest, Test>().WithFactory<ITestFactory>();
|
|
}
|
|
|
|
private class TestInstallerWithInvalidFactory : IIocInstaller
|
|
{
|
|
public void Install(IRegistrationCollector registration) => registration.Add<ITest, Test>().WithFactory<IInvalidTestFactory>();
|
|
}
|
|
|
|
private class TestInstallerInvalidFactoryParameterRegisteredWithoutFactory : IIocInstaller
|
|
{
|
|
public void Install(IRegistrationCollector registration)
|
|
{
|
|
registration.Add<ITest, Test>().WithFactory<IInvalidTestFactory>();
|
|
registration.Add<IParameter, Parameter>();
|
|
}
|
|
}
|
|
|
|
private class TestInstallerInvalidFactoryParameterRegisteredWithFactory : IIocInstaller
|
|
{
|
|
public void Install(IRegistrationCollector registration)
|
|
{
|
|
registration.Add<ITest, Test>().WithFactory<IInvalidTestFactory>();
|
|
registration.Add<IParameter, Parameter>().WithFactory<IParameterFactory>();
|
|
}
|
|
}
|
|
|
|
private class TestInstallerInvalidFactoryParameterDesignTimeCtorNotIgnoredRegisteredWithFactory : IIocInstaller
|
|
{
|
|
public void Install(IRegistrationCollector registration)
|
|
{
|
|
registration.Add<ITest, Test>().WithFactory<IInvalidTestFactory>();
|
|
registration.Add<IParameter, Parameter>().WithFactory<IParameterFactory>();
|
|
}
|
|
}
|
|
|
|
private class TestInstallerInvalidFactoryViewModel : IIocInstaller
|
|
{
|
|
public void Install(IRegistrationCollector registration)
|
|
{
|
|
registration.Add<ITest, TestViewModelDontIgnoreDesignTimeCtor>().WithFactory<ITestMissingParamFactory>();
|
|
registration.Add<IParameter, Parameter>().WithFactory<IParameterFactory>();
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void TestValidateWithoutFactory()
|
|
{
|
|
IocContainer iocContainer = new();
|
|
iocContainer.Install(new TestInstallerNoFactory());
|
|
|
|
IocValidator validator = new(iocContainer);
|
|
|
|
AggregateException aggregateException = Assert.Throws<AggregateException>(() => validator.Validate());
|
|
|
|
AssertNoMatchingConstructorFoundForType<Test>(aggregateException);
|
|
}
|
|
|
|
[Test]
|
|
public void TestValidateWithFactory()
|
|
{
|
|
IocContainer iocContainer = new();
|
|
iocContainer.Install(new TestInstallerWithFactory());
|
|
|
|
IocValidator validator = new(iocContainer);
|
|
|
|
validator.Validate();
|
|
}
|
|
|
|
[Test]
|
|
public void TestValidateWithParameter()
|
|
{
|
|
IocContainer iocContainer = new();
|
|
iocContainer.Install(new TestInstallerNoFactory());
|
|
|
|
IocValidator validator = new(iocContainer);
|
|
|
|
IParameter parameterMock = Substitute.For<IParameter>();
|
|
parameterMock.Method().Returns(true);
|
|
|
|
validator.AddParameter<ITest, IParameter>(parameterMock);
|
|
|
|
validator.Validate();
|
|
|
|
parameterMock.DidNotReceive().Method();
|
|
}
|
|
|
|
[Test]
|
|
public void TestValidateWithInvalidFactoryParameterWithoutFactory()
|
|
{
|
|
IocContainer iocContainer = new();
|
|
iocContainer.Install(new TestInstallerInvalidFactoryParameterRegisteredWithoutFactory());
|
|
|
|
IocValidator validator = new(iocContainer);
|
|
|
|
validator.Validate();
|
|
}
|
|
|
|
[Test]
|
|
public void TestValidateWithInvalidParameterWithFactory()
|
|
{
|
|
IocContainer iocContainer = new();
|
|
iocContainer.Install(new TestInstallerInvalidFactoryParameterRegisteredWithFactory());
|
|
|
|
IocValidator validator = new(iocContainer);
|
|
|
|
IParameter parameterMock = Substitute.For<IParameter>();
|
|
validator.AddParameter<ITest, IParameter>(parameterMock);
|
|
|
|
AggregateException aggregateException = Assert.Throws<AggregateException>(() => validator.Validate());
|
|
|
|
if (aggregateException?.InnerExceptions[0] is not NoMatchingConstructorFoundException noMatchingConstructorFoundException)
|
|
{
|
|
Assert.Fail($"First element of {nameof(aggregateException.InnerExceptions)} is not of type {nameof(NoMatchingConstructorFoundException)}.");
|
|
return;
|
|
}
|
|
|
|
if (noMatchingConstructorFoundException.InnerExceptions[0] is not ConstructorNotMatchingException iTest2CtorNotMatchingException)
|
|
{
|
|
Assert.Fail($"First element of {nameof(noMatchingConstructorFoundException.InnerExceptions)} is not of type {nameof(ConstructorNotMatchingException)}.");
|
|
return;
|
|
}
|
|
|
|
Assert.IsInstanceOf<DirectResolveWithRegisteredFactoryNotAllowed>(iTest2CtorNotMatchingException.InnerExceptions[0]);
|
|
}
|
|
|
|
[Test]
|
|
public void TestValidateViewModelWithInvalidParameterWithFactory()
|
|
{
|
|
IocContainer iocContainer = new();
|
|
iocContainer.Install(new TestInstallerInvalidFactoryViewModel());
|
|
|
|
IocValidator validator = new(iocContainer);
|
|
|
|
AggregateException aggregateException = Assert.Throws<AggregateException>(() => validator.Validate());
|
|
|
|
if (aggregateException?.InnerExceptions[0] is not NoMatchingConstructorFoundException noMatchingConstructorFoundException)
|
|
{
|
|
Assert.Fail($"First element of {nameof(aggregateException.InnerExceptions)} is not of type {nameof(NoMatchingConstructorFoundException)}.");
|
|
return;
|
|
}
|
|
|
|
if (noMatchingConstructorFoundException.InnerExceptions[0] is not ConstructorNotMatchingException iTest2CtorNotMatchingException)
|
|
{
|
|
Assert.Fail($"First element of {nameof(noMatchingConstructorFoundException.InnerExceptions)} is not of type {nameof(ConstructorNotMatchingException)}.");
|
|
return;
|
|
}
|
|
|
|
Assert.IsInstanceOf<DirectResolveWithRegisteredFactoryNotAllowed>(iTest2CtorNotMatchingException.InnerExceptions[0]);
|
|
}
|
|
|
|
[Test]
|
|
public void TestValidateViewModelWithInvalidParameterDesignTimeCtorNotIgnoredWithFactory()
|
|
{
|
|
IocContainer iocContainer = new();
|
|
iocContainer.Install(new TestInstallerInvalidFactoryParameterDesignTimeCtorNotIgnoredRegisteredWithFactory());
|
|
|
|
IocValidator validator = new(iocContainer);
|
|
|
|
AggregateException aggregateException = Assert.Throws<AggregateException>(() => validator.Validate());
|
|
|
|
if (aggregateException?.InnerExceptions[0] is not NoMatchingConstructorFoundException noMatchingConstructorFoundException)
|
|
{
|
|
Assert.Fail($"First element of {nameof(aggregateException.InnerExceptions)} is not of type {nameof(NoMatchingConstructorFoundException)}.");
|
|
return;
|
|
}
|
|
|
|
if (noMatchingConstructorFoundException.InnerExceptions[0] is not ConstructorNotMatchingException iTest2CtorNotMatchingException)
|
|
{
|
|
Assert.Fail($"First element of {nameof(noMatchingConstructorFoundException.InnerExceptions)} is not of type {nameof(ConstructorNotMatchingException)}.");
|
|
return;
|
|
}
|
|
|
|
Assert.IsInstanceOf<DirectResolveWithRegisteredFactoryNotAllowed>(iTest2CtorNotMatchingException.InnerExceptions[0]);
|
|
}
|
|
|
|
[Test]
|
|
public void TestValidateInvalidFactory()
|
|
{
|
|
IocContainer iocContainer = new();
|
|
iocContainer.Install(new TestInstallerWithInvalidFactory());
|
|
|
|
IocValidator validator = new(iocContainer);
|
|
|
|
AggregateException aggregateException = Assert.Throws<AggregateException>(() => validator.Validate());
|
|
|
|
AssertNoMatchingConstructorFoundForType<Test>(aggregateException);
|
|
}
|
|
|
|
[Test]
|
|
public void TestValidateFactoryOfOpenGenericType()
|
|
{
|
|
IocContainer iocContainer = new();
|
|
iocContainer.Register(r => r.AddOpenGenerics(typeof(IGenericTest<>), typeof(GenericTest<>)).WithFactory<IGenericTestFactory>());
|
|
|
|
IocValidator validator = new(iocContainer);
|
|
validator.Validate();
|
|
}
|
|
|
|
private void AssertNoMatchingConstructorFoundForType<T>(AggregateException aggregateException)
|
|
{
|
|
Exception exception = aggregateException?.InnerExceptions[0];
|
|
if (exception is NoMatchingConstructorFoundException noMatchingConstructorFoundException)
|
|
Assert.AreEqual(typeof(T), noMatchingConstructorFoundException.Type);
|
|
else
|
|
Assert.Fail($"Exception is no {nameof(NoMatchingConstructorFoundException)}, actual type: {exception?.GetType()}");
|
|
}
|
|
} |