1
0
mirror of https://github.com/bitwarden/server.git synced 2025-06-30 07:36:14 -05:00

Run formatting (#2230)

This commit is contained in:
Justin Baur
2022-08-29 16:06:55 -04:00
committed by GitHub
parent 9b7aef0763
commit 7f5f010e1e
1205 changed files with 73813 additions and 75022 deletions

View File

@ -3,26 +3,25 @@ using AutoFixture;
using Bit.Test.Common.Helpers;
using Xunit.Sdk;
namespace Bit.Test.Common.AutoFixture.Attributes
namespace Bit.Test.Common.AutoFixture.Attributes;
[DataDiscoverer("AutoFixture.Xunit2.NoPreDiscoveryDataDiscoverer", "AutoFixture.Xunit2")]
public class BitAutoDataAttribute : DataAttribute
{
[DataDiscoverer("AutoFixture.Xunit2.NoPreDiscoveryDataDiscoverer", "AutoFixture.Xunit2")]
public class BitAutoDataAttribute : DataAttribute
private readonly Func<IFixture> _createFixture;
private readonly object[] _fixedTestParameters;
public BitAutoDataAttribute(params object[] fixedTestParameters) :
this(() => new Fixture(), fixedTestParameters)
{ }
public BitAutoDataAttribute(Func<IFixture> createFixture, params object[] fixedTestParameters) :
base()
{
private readonly Func<IFixture> _createFixture;
private readonly object[] _fixedTestParameters;
public BitAutoDataAttribute(params object[] fixedTestParameters) :
this(() => new Fixture(), fixedTestParameters)
{ }
public BitAutoDataAttribute(Func<IFixture> createFixture, params object[] fixedTestParameters) :
base()
{
_createFixture = createFixture;
_fixedTestParameters = fixedTestParameters;
}
public override IEnumerable<object[]> GetData(MethodInfo testMethod)
=> BitAutoDataAttributeHelpers.GetData(testMethod, _createFixture(), _fixedTestParameters);
_createFixture = createFixture;
_fixedTestParameters = fixedTestParameters;
}
public override IEnumerable<object[]> GetData(MethodInfo testMethod)
=> BitAutoDataAttributeHelpers.GetData(testMethod, _createFixture(), _fixedTestParameters);
}

View File

@ -1,21 +1,20 @@
using AutoFixture;
namespace Bit.Test.Common.AutoFixture.Attributes
namespace Bit.Test.Common.AutoFixture.Attributes;
/// <summary>
/// <para>
/// Base class for customizing parameters in methods decorated with the
/// Bit.Test.Common.AutoFixture.Attributes.MemberAutoDataAttribute.
/// </para>
/// ⚠ Warning ⚠ Will not insert customizations into AutoFixture's AutoDataAttribute build chain
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Parameter, AllowMultiple = true)]
public abstract class BitCustomizeAttribute : Attribute
{
/// <summary>
/// <para>
/// Base class for customizing parameters in methods decorated with the
/// Bit.Test.Common.AutoFixture.Attributes.MemberAutoDataAttribute.
/// </para>
/// ⚠ Warning ⚠ Will not insert customizations into AutoFixture's AutoDataAttribute build chain
/// /// Gets a customization for the method's parameters.
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Parameter, AllowMultiple = true)]
public abstract class BitCustomizeAttribute : Attribute
{
/// <summary>
/// /// Gets a customization for the method's parameters.
/// </summary>
/// <returns>A customization for the method's paramters.</returns>
public abstract ICustomization GetCustomization();
}
/// <returns>A customization for the method's paramters.</returns>
public abstract ICustomization GetCustomization();
}

View File

@ -3,23 +3,22 @@ using AutoFixture;
using Bit.Test.Common.Helpers;
using Xunit;
namespace Bit.Test.Common.AutoFixture.Attributes
namespace Bit.Test.Common.AutoFixture.Attributes;
public class BitMemberAutoDataAttribute : MemberDataAttributeBase
{
public class BitMemberAutoDataAttribute : MemberDataAttributeBase
private readonly Func<IFixture> _createFixture;
public BitMemberAutoDataAttribute(string memberName, params object[] parameters) :
this(() => new Fixture(), memberName, parameters)
{ }
public BitMemberAutoDataAttribute(Func<IFixture> createFixture, string memberName, params object[] parameters) :
base(memberName, parameters)
{
private readonly Func<IFixture> _createFixture;
public BitMemberAutoDataAttribute(string memberName, params object[] parameters) :
this(() => new Fixture(), memberName, parameters)
{ }
public BitMemberAutoDataAttribute(Func<IFixture> createFixture, string memberName, params object[] parameters) :
base(memberName, parameters)
{
_createFixture = createFixture;
}
protected override object[] ConvertDataItem(MethodInfo testMethod, object item) =>
BitAutoDataAttributeHelpers.GetData(testMethod, _createFixture(), item as object[]).First();
_createFixture = createFixture;
}
protected override object[] ConvertDataItem(MethodInfo testMethod, object item) =>
BitAutoDataAttributeHelpers.GetData(testMethod, _createFixture(), item as object[]).First();
}

View File

@ -1,23 +1,22 @@
using AutoFixture;
namespace Bit.Test.Common.AutoFixture.Attributes
namespace Bit.Test.Common.AutoFixture.Attributes;
/// <summary>
/// Disables setting of Auto Properties on the Controller to avoid ASP.net initialization errors from a mock environment. Still sets constructor dependencies.
/// </summary>
public class ControllerCustomizeAttribute : BitCustomizeAttribute
{
private readonly Type _controllerType;
/// <summary>
/// Disables setting of Auto Properties on the Controller to avoid ASP.net initialization errors from a mock environment. Still sets constructor dependencies.
/// Initialize an instance of the ControllerCustomizeAttribute class
/// </summary>
public class ControllerCustomizeAttribute : BitCustomizeAttribute
/// <param name="controllerType">The Type of the controller to allow autofixture to create</param>
public ControllerCustomizeAttribute(Type controllerType)
{
private readonly Type _controllerType;
/// <summary>
/// Initialize an instance of the ControllerCustomizeAttribute class
/// </summary>
/// <param name="controllerType">The Type of the controller to allow autofixture to create</param>
public ControllerCustomizeAttribute(Type controllerType)
{
_controllerType = controllerType;
}
public override ICustomization GetCustomization() => new ControllerCustomization(_controllerType);
_controllerType = controllerType;
}
public override ICustomization GetCustomization() => new ControllerCustomization(_controllerType);
}

View File

@ -1,23 +1,22 @@
using AutoFixture;
using AutoFixture.Xunit2;
namespace Bit.Test.Common.AutoFixture.Attributes
{
public class CustomAutoDataAttribute : AutoDataAttribute
{
public CustomAutoDataAttribute(params Type[] iCustomizationTypes) : this(iCustomizationTypes
.Select(t => (ICustomization)Activator.CreateInstance(t)).ToArray())
{ }
namespace Bit.Test.Common.AutoFixture.Attributes;
public CustomAutoDataAttribute(params ICustomization[] customizations) : base(() =>
public class CustomAutoDataAttribute : AutoDataAttribute
{
public CustomAutoDataAttribute(params Type[] iCustomizationTypes) : this(iCustomizationTypes
.Select(t => (ICustomization)Activator.CreateInstance(t)).ToArray())
{ }
public CustomAutoDataAttribute(params ICustomization[] customizations) : base(() =>
{
var fixture = new Fixture();
foreach (var customization in customizations)
{
var fixture = new Fixture();
foreach (var customization in customizations)
{
fixture.Customize(customization);
}
return fixture;
})
{ }
}
fixture.Customize(customization);
}
return fixture;
})
{ }
}

View File

@ -1,43 +1,42 @@
using System.Reflection;
using Xunit.Sdk;
namespace Bit.Test.Common.AutoFixture.Attributes
namespace Bit.Test.Common.AutoFixture.Attributes;
/// <summary>
/// Used for collecting data from environment useful for when we want to test an integration with another service and
/// it might require an api key or other piece of sensitive data that we don't want slipping into the wrong hands.
/// </summary>
/// <remarks>
/// It probably should be refactored to support fixtures and other customization so it can more easily be used in conjunction
/// with more parameters. Currently it attempt to match environment variable names to values of the parameter type in that positions.
/// It will start from the first parameter and go for each supplied name.
/// </remarks>
public class EnvironmentDataAttribute : DataAttribute
{
/// <summary>
/// Used for collecting data from environment useful for when we want to test an integration with another service and
/// it might require an api key or other piece of sensitive data that we don't want slipping into the wrong hands.
/// </summary>
/// <remarks>
/// It probably should be refactored to support fixtures and other customization so it can more easily be used in conjunction
/// with more parameters. Currently it attempt to match environment variable names to values of the parameter type in that positions.
/// It will start from the first parameter and go for each supplied name.
/// </remarks>
public class EnvironmentDataAttribute : DataAttribute
private readonly string[] _environmentVariableNames;
public EnvironmentDataAttribute(params string[] environmentVariableNames)
{
private readonly string[] _environmentVariableNames;
_environmentVariableNames = environmentVariableNames;
}
public EnvironmentDataAttribute(params string[] environmentVariableNames)
public override IEnumerable<object[]> GetData(MethodInfo testMethod)
{
var methodParameters = testMethod.GetParameters();
if (methodParameters.Length < _environmentVariableNames.Length)
{
_environmentVariableNames = environmentVariableNames;
throw new ArgumentException($"The target test method only has {methodParameters.Length} arguments but you supplied {_environmentVariableNames.Length}");
}
public override IEnumerable<object[]> GetData(MethodInfo testMethod)
var values = new object[_environmentVariableNames.Length];
for (var i = 0; i < _environmentVariableNames.Length; i++)
{
var methodParameters = testMethod.GetParameters();
if (methodParameters.Length < _environmentVariableNames.Length)
{
throw new ArgumentException($"The target test method only has {methodParameters.Length} arguments but you supplied {_environmentVariableNames.Length}");
}
var values = new object[_environmentVariableNames.Length];
for (var i = 0; i < _environmentVariableNames.Length; i++)
{
values[i] = Convert.ChangeType(Environment.GetEnvironmentVariable(_environmentVariableNames[i]), methodParameters[i].ParameterType);
}
return new[] { values };
values[i] = Convert.ChangeType(Environment.GetEnvironmentVariable(_environmentVariableNames[i]), methodParameters[i].ParameterType);
}
return new[] { values };
}
}

View File

@ -3,20 +3,19 @@ using AutoFixture.Xunit2;
using Xunit;
using Xunit.Sdk;
namespace Bit.Test.Common.AutoFixture.Attributes
{
public class InlineCustomAutoDataAttribute : CompositeDataAttribute
{
public InlineCustomAutoDataAttribute(Type[] iCustomizationTypes, params object[] values) : base(new DataAttribute[] {
new InlineDataAttribute(values),
new CustomAutoDataAttribute(iCustomizationTypes)
})
{ }
namespace Bit.Test.Common.AutoFixture.Attributes;
public InlineCustomAutoDataAttribute(ICustomization[] customizations, params object[] values) : base(new DataAttribute[] {
new InlineDataAttribute(values),
new CustomAutoDataAttribute(customizations)
})
{ }
}
public class InlineCustomAutoDataAttribute : CompositeDataAttribute
{
public InlineCustomAutoDataAttribute(Type[] iCustomizationTypes, params object[] values) : base(new DataAttribute[] {
new InlineDataAttribute(values),
new CustomAutoDataAttribute(iCustomizationTypes)
})
{ }
public InlineCustomAutoDataAttribute(ICustomization[] customizations, params object[] values) : base(new DataAttribute[] {
new InlineDataAttribute(values),
new CustomAutoDataAttribute(customizations)
})
{ }
}

View File

@ -1,18 +1,17 @@
using AutoFixture;
namespace Bit.Test.Common.AutoFixture.Attributes
{
public class InlineSutAutoDataAttribute : InlineCustomAutoDataAttribute
{
public InlineSutAutoDataAttribute(params object[] values) : base(
new Type[] { typeof(SutProviderCustomization) }, values)
{ }
public InlineSutAutoDataAttribute(Type[] iCustomizationTypes, params object[] values) : base(
iCustomizationTypes.Append(typeof(SutProviderCustomization)).ToArray(), values)
{ }
namespace Bit.Test.Common.AutoFixture.Attributes;
public InlineSutAutoDataAttribute(ICustomization[] customizations, params object[] values) : base(
customizations.Append(new SutProviderCustomization()).ToArray(), values)
{ }
}
public class InlineSutAutoDataAttribute : InlineCustomAutoDataAttribute
{
public InlineSutAutoDataAttribute(params object[] values) : base(
new Type[] { typeof(SutProviderCustomization) }, values)
{ }
public InlineSutAutoDataAttribute(Type[] iCustomizationTypes, params object[] values) : base(
iCustomizationTypes.Append(typeof(SutProviderCustomization)).ToArray(), values)
{ }
public InlineSutAutoDataAttribute(ICustomization[] customizations, params object[] values) : base(
customizations.Append(new SutProviderCustomization()).ToArray(), values)
{ }
}

View File

@ -1,11 +1,10 @@
using AutoFixture;
using Bit.Test.Common.AutoFixture.JsonDocumentFixtures;
namespace Bit.Test.Common.AutoFixture.Attributes
namespace Bit.Test.Common.AutoFixture.Attributes;
public class JsonDocumentCustomizeAttribute : BitCustomizeAttribute
{
public class JsonDocumentCustomizeAttribute : BitCustomizeAttribute
{
public string Json { get; set; }
public override ICustomization GetCustomization() => new JsonDocumentCustomization() { Json = Json };
}
public string Json { get; set; }
public override ICustomization GetCustomization() => new JsonDocumentCustomization() { Json = Json };
}

View File

@ -1,38 +1,37 @@
using Xunit;
namespace Bit.Test.Common.AutoFixture.Attributes
namespace Bit.Test.Common.AutoFixture.Attributes;
/// <summary>
/// Used for requiring certain environment variables exist at the time. Mostly used for more edge unit tests that shouldn't
/// be run during CI builds or should only be ran in CI builds when pieces of information are available.
/// </summary>
public class RequiredEnvironmentTheoryAttribute : TheoryAttribute
{
/// <summary>
/// Used for requiring certain environment variables exist at the time. Mostly used for more edge unit tests that shouldn't
/// be run during CI builds or should only be ran in CI builds when pieces of information are available.
/// </summary>
public class RequiredEnvironmentTheoryAttribute : TheoryAttribute
private readonly string[] _environmentVariableNames;
public RequiredEnvironmentTheoryAttribute(params string[] environmentVariableNames)
{
private readonly string[] _environmentVariableNames;
_environmentVariableNames = environmentVariableNames;
public RequiredEnvironmentTheoryAttribute(params string[] environmentVariableNames)
if (!HasRequiredEnvironmentVariables())
{
_environmentVariableNames = environmentVariableNames;
if (!HasRequiredEnvironmentVariables())
{
Skip = $"Missing one or more required environment variables. ({string.Join(", ", _environmentVariableNames)})";
}
}
private bool HasRequiredEnvironmentVariables()
{
foreach (var env in _environmentVariableNames)
{
var value = Environment.GetEnvironmentVariable(env);
if (value == null)
{
return false;
}
}
return true;
Skip = $"Missing one or more required environment variables. ({string.Join(", ", _environmentVariableNames)})";
}
}
private bool HasRequiredEnvironmentVariables()
{
foreach (var env in _environmentVariableNames)
{
var value = Environment.GetEnvironmentVariable(env);
if (value == null)
{
return false;
}
}
return true;
}
}

View File

@ -1,16 +1,15 @@
using AutoFixture;
namespace Bit.Test.Common.AutoFixture.Attributes
{
public class SutProviderCustomizeAttribute : BitCustomizeAttribute
{
public override ICustomization GetCustomization() => new SutProviderCustomization();
}
namespace Bit.Test.Common.AutoFixture.Attributes;
public class SutAutoDataAttribute : CustomAutoDataAttribute
{
public SutAutoDataAttribute(params Type[] iCustomizationTypes) : base(
iCustomizationTypes.Append(typeof(SutProviderCustomization)).ToArray())
{ }
}
public class SutProviderCustomizeAttribute : BitCustomizeAttribute
{
public override ICustomization GetCustomization() => new SutProviderCustomization();
}
public class SutAutoDataAttribute : CustomAutoDataAttribute
{
public SutAutoDataAttribute(params Type[] iCustomizationTypes) : base(
iCustomizationTypes.Append(typeof(SutProviderCustomization)).ToArray())
{ }
}

View File

@ -1,39 +1,38 @@
using AutoFixture;
using AutoFixture.Kernel;
namespace Bit.Test.Common.AutoFixture
namespace Bit.Test.Common.AutoFixture;
public class BuilderWithoutAutoProperties : ISpecimenBuilder
{
public class BuilderWithoutAutoProperties : ISpecimenBuilder
private readonly Type _type;
public BuilderWithoutAutoProperties(Type type)
{
private readonly Type _type;
public BuilderWithoutAutoProperties(Type type)
{
_type = type;
}
public object Create(object request, ISpecimenContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
var type = request as Type;
if (type == null || type != _type)
{
return new NoSpecimen();
}
var fixture = new Fixture();
// This is the equivalent of _fixture.Build<_type>().OmitAutoProperties().Create(request, context), but no overload for
// Build(Type type) exists.
dynamic reflectedComposer = typeof(Fixture).GetMethod("Build").MakeGenericMethod(_type).Invoke(fixture, null);
return reflectedComposer.OmitAutoProperties().Create(request, context);
}
_type = type;
}
public class BuilderWithoutAutoProperties<T> : ISpecimenBuilder
public object Create(object request, ISpecimenContext context)
{
public object Create(object request, ISpecimenContext context) =>
new BuilderWithoutAutoProperties(typeof(T)).Create(request, context);
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
var type = request as Type;
if (type == null || type != _type)
{
return new NoSpecimen();
}
var fixture = new Fixture();
// This is the equivalent of _fixture.Build<_type>().OmitAutoProperties().Create(request, context), but no overload for
// Build(Type type) exists.
dynamic reflectedComposer = typeof(Fixture).GetMethod("Build").MakeGenericMethod(_type).Invoke(fixture, null);
return reflectedComposer.OmitAutoProperties().Create(request, context);
}
}
public class BuilderWithoutAutoProperties<T> : ISpecimenBuilder
{
public object Create(object request, ISpecimenContext context) =>
new BuilderWithoutAutoProperties(typeof(T)).Create(request, context);
}

View File

@ -2,32 +2,31 @@
using Microsoft.AspNetCore.Mvc;
using Org.BouncyCastle.Security;
namespace Bit.Test.Common.AutoFixture
namespace Bit.Test.Common.AutoFixture;
/// <summary>
/// Disables setting of Auto Properties on the Controller to avoid ASP.net initialization errors. Still sets constructor dependencies.
/// </summary>
/// <param name="fixture"></param>
public class ControllerCustomization : ICustomization
{
/// <summary>
/// Disables setting of Auto Properties on the Controller to avoid ASP.net initialization errors. Still sets constructor dependencies.
/// </summary>
/// <param name="fixture"></param>
public class ControllerCustomization : ICustomization
private readonly Type _controllerType;
public ControllerCustomization(Type controllerType)
{
private readonly Type _controllerType;
public ControllerCustomization(Type controllerType)
if (!controllerType.IsAssignableTo(typeof(Controller)))
{
if (!controllerType.IsAssignableTo(typeof(Controller)))
{
throw new InvalidParameterException($"{nameof(controllerType)} must derive from {typeof(Controller).Name}");
}
_controllerType = controllerType;
throw new InvalidParameterException($"{nameof(controllerType)} must derive from {typeof(Controller).Name}");
}
public void Customize(IFixture fixture)
{
fixture.Customizations.Add(new BuilderWithoutAutoProperties(_controllerType));
}
_controllerType = controllerType;
}
public class ControllerCustomization<T> : ICustomization where T : Controller
public void Customize(IFixture fixture)
{
public void Customize(IFixture fixture) => new ControllerCustomization(typeof(T)).Customize(fixture);
fixture.Customizations.Add(new BuilderWithoutAutoProperties(_controllerType));
}
}
public class ControllerCustomization<T> : ICustomization where T : Controller
{
public void Customize(IFixture fixture) => new ControllerCustomization(typeof(T)).Customize(fixture);
}

View File

@ -1,14 +1,13 @@
using AutoFixture;
using AutoFixture.AutoNSubstitute;
namespace Bit.Test.Common.AutoFixture
{
public static class FixtureExtensions
{
public static IFixture WithAutoNSubstitutions(this IFixture fixture)
=> fixture.Customize(new AutoNSubstituteCustomization());
namespace Bit.Test.Common.AutoFixture;
public static IFixture WithAutoNSubstitutionsAutoPopulatedProperties(this IFixture fixture)
=> fixture.Customize(new AutoNSubstituteCustomization { ConfigureMembers = true });
}
public static class FixtureExtensions
{
public static IFixture WithAutoNSubstitutions(this IFixture fixture)
=> fixture.Customize(new AutoNSubstituteCustomization());
public static IFixture WithAutoNSubstitutionsAutoPopulatedProperties(this IFixture fixture)
=> fixture.Customize(new AutoNSubstituteCustomization { ConfigureMembers = true });
}

View File

@ -1,16 +1,15 @@
using AutoFixture;
namespace Bit.Test.Common.AutoFixture
namespace Bit.Test.Common.AutoFixture;
public class GlobalSettings : ICustomization
{
public class GlobalSettings : ICustomization
public void Customize(IFixture fixture)
{
public void Customize(IFixture fixture)
{
fixture.Customize<Bit.Core.Settings.GlobalSettings>(composer => composer
.Without(s => s.BaseServiceUri)
.Without(s => s.Attachment)
.Without(s => s.Send)
.Without(s => s.DataProtection));
}
fixture.Customize<Bit.Core.Settings.GlobalSettings>(composer => composer
.Without(s => s.BaseServiceUri)
.Without(s => s.Attachment)
.Without(s => s.Send)
.Without(s => s.DataProtection));
}
}

View File

@ -1,8 +1,7 @@
namespace Bit.Test.Common.AutoFixture
namespace Bit.Test.Common.AutoFixture;
public interface ISutProvider
{
public interface ISutProvider
{
Type SutType { get; }
ISutProvider Create();
}
Type SutType { get; }
ISutProvider Create();
}

View File

@ -2,31 +2,30 @@
using AutoFixture;
using AutoFixture.Kernel;
namespace Bit.Test.Common.AutoFixture.JsonDocumentFixtures
namespace Bit.Test.Common.AutoFixture.JsonDocumentFixtures;
public class JsonDocumentCustomization : ICustomization, ISpecimenBuilder
{
public class JsonDocumentCustomization : ICustomization, ISpecimenBuilder
public string Json { get; set; }
public void Customize(IFixture fixture)
{
fixture.Customizations.Add(this);
}
public string Json { get; set; }
public void Customize(IFixture fixture)
public object Create(object request, ISpecimenContext context)
{
if (context == null)
{
fixture.Customizations.Add(this);
throw new ArgumentNullException(nameof(context));
}
var type = request as Type;
if (type == null || (type != typeof(JsonDocument)))
{
return new NoSpecimen();
}
public object Create(object request, ISpecimenContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
var type = request as Type;
if (type == null || (type != typeof(JsonDocument)))
{
return new NoSpecimen();
}
return JsonDocument.Parse(Json ?? "{}");
}
return JsonDocument.Parse(Json ?? "{}");
}
}

View File

@ -2,133 +2,132 @@
using AutoFixture;
using AutoFixture.Kernel;
namespace Bit.Test.Common.AutoFixture
namespace Bit.Test.Common.AutoFixture;
public class SutProvider<TSut> : ISutProvider
{
public class SutProvider<TSut> : ISutProvider
private Dictionary<Type, Dictionary<string, object>> _dependencies;
private readonly IFixture _fixture;
private readonly ConstructorParameterRelay<TSut> _constructorParameterRelay;
public TSut Sut { get; private set; }
public Type SutType => typeof(TSut);
public SutProvider() : this(new Fixture()) { }
public SutProvider(IFixture fixture)
{
private Dictionary<Type, Dictionary<string, object>> _dependencies;
_dependencies = new Dictionary<Type, Dictionary<string, object>>();
_fixture = (fixture ?? new Fixture()).WithAutoNSubstitutions().Customize(new GlobalSettings());
_constructorParameterRelay = new ConstructorParameterRelay<TSut>(this, _fixture);
_fixture.Customizations.Add(_constructorParameterRelay);
}
public SutProvider<TSut> SetDependency<T>(T dependency, string parameterName = "")
=> SetDependency(typeof(T), dependency, parameterName);
public SutProvider<TSut> SetDependency(Type dependencyType, object dependency, string parameterName = "")
{
if (_dependencies.ContainsKey(dependencyType))
{
_dependencies[dependencyType][parameterName] = dependency;
}
else
{
_dependencies[dependencyType] = new Dictionary<string, object> { { parameterName, dependency } };
}
return this;
}
public T GetDependency<T>(string parameterName = "") => (T)GetDependency(typeof(T), parameterName);
public object GetDependency(Type dependencyType, string parameterName = "")
{
if (DependencyIsSet(dependencyType, parameterName))
{
return _dependencies[dependencyType][parameterName];
}
else if (_dependencies.ContainsKey(dependencyType))
{
var knownDependencies = _dependencies[dependencyType];
if (knownDependencies.Values.Count == 1)
{
return _dependencies[dependencyType].Values.Single();
}
else
{
throw new ArgumentException(string.Concat($"Dependency of type {dependencyType.Name} and name ",
$"{parameterName} does not exist. Available dependency names are: ",
string.Join(", ", knownDependencies.Keys)));
}
}
else
{
throw new ArgumentException($"Dependency of type {dependencyType.Name} and name {parameterName} has not been set.");
}
}
public void Reset()
{
_dependencies = new Dictionary<Type, Dictionary<string, object>>();
Sut = default;
}
ISutProvider ISutProvider.Create() => Create();
public SutProvider<TSut> Create()
{
Sut = _fixture.Create<TSut>();
return this;
}
private bool DependencyIsSet(Type dependencyType, string parameterName = "")
=> _dependencies.ContainsKey(dependencyType) && _dependencies[dependencyType].ContainsKey(parameterName);
private object GetDefault(Type type) => type.IsValueType ? Activator.CreateInstance(type) : null;
private class ConstructorParameterRelay<T> : ISpecimenBuilder
{
private readonly SutProvider<T> _sutProvider;
private readonly IFixture _fixture;
private readonly ConstructorParameterRelay<TSut> _constructorParameterRelay;
public TSut Sut { get; private set; }
public Type SutType => typeof(TSut);
public SutProvider() : this(new Fixture()) { }
public SutProvider(IFixture fixture)
public ConstructorParameterRelay(SutProvider<T> sutProvider, IFixture fixture)
{
_dependencies = new Dictionary<Type, Dictionary<string, object>>();
_fixture = (fixture ?? new Fixture()).WithAutoNSubstitutions().Customize(new GlobalSettings());
_constructorParameterRelay = new ConstructorParameterRelay<TSut>(this, _fixture);
_fixture.Customizations.Add(_constructorParameterRelay);
_sutProvider = sutProvider;
_fixture = fixture;
}
public SutProvider<TSut> SetDependency<T>(T dependency, string parameterName = "")
=> SetDependency(typeof(T), dependency, parameterName);
public SutProvider<TSut> SetDependency(Type dependencyType, object dependency, string parameterName = "")
public object Create(object request, ISpecimenContext context)
{
if (_dependencies.ContainsKey(dependencyType))
if (context == null)
{
_dependencies[dependencyType][parameterName] = dependency;
throw new ArgumentNullException(nameof(context));
}
else
if (!(request is ParameterInfo parameterInfo))
{
_dependencies[dependencyType] = new Dictionary<string, object> { { parameterName, dependency } };
return new NoSpecimen();
}
if (parameterInfo.Member.DeclaringType != typeof(T) ||
parameterInfo.Member.MemberType != MemberTypes.Constructor)
{
return new NoSpecimen();
}
return this;
}
public T GetDependency<T>(string parameterName = "") => (T)GetDependency(typeof(T), parameterName);
public object GetDependency(Type dependencyType, string parameterName = "")
{
if (DependencyIsSet(dependencyType, parameterName))
if (_sutProvider.DependencyIsSet(parameterInfo.ParameterType, parameterInfo.Name))
{
return _dependencies[dependencyType][parameterName];
return _sutProvider.GetDependency(parameterInfo.ParameterType, parameterInfo.Name);
}
else if (_dependencies.ContainsKey(dependencyType))
// Return default type if set
else if (_sutProvider.DependencyIsSet(parameterInfo.ParameterType, ""))
{
var knownDependencies = _dependencies[dependencyType];
if (knownDependencies.Values.Count == 1)
{
return _dependencies[dependencyType].Values.Single();
}
else
{
throw new ArgumentException(string.Concat($"Dependency of type {dependencyType.Name} and name ",
$"{parameterName} does not exist. Available dependency names are: ",
string.Join(", ", knownDependencies.Keys)));
}
}
else
{
throw new ArgumentException($"Dependency of type {dependencyType.Name} and name {parameterName} has not been set.");
}
}
public void Reset()
{
_dependencies = new Dictionary<Type, Dictionary<string, object>>();
Sut = default;
}
ISutProvider ISutProvider.Create() => Create();
public SutProvider<TSut> Create()
{
Sut = _fixture.Create<TSut>();
return this;
}
private bool DependencyIsSet(Type dependencyType, string parameterName = "")
=> _dependencies.ContainsKey(dependencyType) && _dependencies[dependencyType].ContainsKey(parameterName);
private object GetDefault(Type type) => type.IsValueType ? Activator.CreateInstance(type) : null;
private class ConstructorParameterRelay<T> : ISpecimenBuilder
{
private readonly SutProvider<T> _sutProvider;
private readonly IFixture _fixture;
public ConstructorParameterRelay(SutProvider<T> sutProvider, IFixture fixture)
{
_sutProvider = sutProvider;
_fixture = fixture;
return _sutProvider.GetDependency(parameterInfo.ParameterType, "");
}
public object Create(object request, ISpecimenContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
if (!(request is ParameterInfo parameterInfo))
{
return new NoSpecimen();
}
if (parameterInfo.Member.DeclaringType != typeof(T) ||
parameterInfo.Member.MemberType != MemberTypes.Constructor)
{
return new NoSpecimen();
}
if (_sutProvider.DependencyIsSet(parameterInfo.ParameterType, parameterInfo.Name))
{
return _sutProvider.GetDependency(parameterInfo.ParameterType, parameterInfo.Name);
}
// Return default type if set
else if (_sutProvider.DependencyIsSet(parameterInfo.ParameterType, ""))
{
return _sutProvider.GetDependency(parameterInfo.ParameterType, "");
}
// This is the equivalent of _fixture.Create<parameterInfo.ParameterType>, but no overload for
// Create(Type type) exists.
var dependency = new SpecimenContext(_fixture).Resolve(new SeededRequest(parameterInfo.ParameterType,
_sutProvider.GetDefault(parameterInfo.ParameterType)));
_sutProvider.SetDependency(parameterInfo.ParameterType, dependency, parameterInfo.Name);
return dependency;
}
// This is the equivalent of _fixture.Create<parameterInfo.ParameterType>, but no overload for
// Create(Type type) exists.
var dependency = new SpecimenContext(_fixture).Resolve(new SeededRequest(parameterInfo.ParameterType,
_sutProvider.GetDefault(parameterInfo.ParameterType)));
_sutProvider.SetDependency(parameterInfo.ParameterType, dependency, parameterInfo.Name);
return dependency;
}
}
}

View File

@ -1,34 +1,33 @@
using AutoFixture;
using AutoFixture.Kernel;
namespace Bit.Test.Common.AutoFixture.Attributes
namespace Bit.Test.Common.AutoFixture.Attributes;
public class SutProviderCustomization : ICustomization, ISpecimenBuilder
{
public class SutProviderCustomization : ICustomization, ISpecimenBuilder
private IFixture _fixture = null;
public object Create(object request, ISpecimenContext context)
{
private IFixture _fixture = null;
public object Create(object request, ISpecimenContext context)
if (context == null)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
if (!(request is Type typeRequest))
{
return new NoSpecimen();
}
if (!typeof(ISutProvider).IsAssignableFrom(typeRequest))
{
return new NoSpecimen();
}
return ((ISutProvider)Activator.CreateInstance(typeRequest, _fixture)).Create();
throw new ArgumentNullException(nameof(context));
}
if (!(request is Type typeRequest))
{
return new NoSpecimen();
}
if (!typeof(ISutProvider).IsAssignableFrom(typeRequest))
{
return new NoSpecimen();
}
public void Customize(IFixture fixture)
{
_fixture = fixture;
fixture.Customizations.Add(this);
}
return ((ISutProvider)Activator.CreateInstance(typeRequest, _fixture)).Create();
}
public void Customize(IFixture fixture)
{
_fixture = fixture;
fixture.Customizations.Add(this);
}
}