1
0
mirror of https://github.com/bitwarden/server.git synced 2024-11-29 13:25:17 +01:00

Add Attribute to use the Bit Autodata dependency chain

BitAutoDataAttribute is used to mark a Theory as autopopulating
parameters.

Extract common attribute methods to to a helper class. Cannot
inherit a common base, since both require inheriting from different
Xunit base classes to work.
This commit is contained in:
Matt Gibson 2021-10-30 13:32:15 -04:00 committed by Justin Baur
parent fcbf0f094e
commit f9fd83d809
3 changed files with 90 additions and 48 deletions

View File

@ -0,0 +1,29 @@
using System;
using Xunit.Sdk;
using AutoFixture;
using System.Reflection;
using System.Collections.Generic;
using Bit.Test.Common.Helpers;
namespace Bit.Test.Common.AutoFixture.Attributes
{
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()
{
_createFixture = createFixture;
_fixedTestParameters = fixedTestParameters;
}
public override IEnumerable<object[]> GetData(MethodInfo testMethod)
=> BitAutoDataAttributeHelpers.GetData(testMethod, _createFixture(), _fixedTestParameters);
}
}

View File

@ -1,69 +1,27 @@
using System; using System;
using Xunit.Sdk;
using Xunit; using Xunit;
using AutoFixture; using AutoFixture;
using System.Reflection; using System.Reflection;
using System.Collections.Generic;
using AutoFixture.Xunit2;
using System.Linq; using System.Linq;
using AutoFixture.Kernel; using Bit.Test.Common.Helpers;
using System.Collections;
namespace Bit.Test.Common.AutoFixture.Attributes namespace Bit.Test.Common.AutoFixture.Attributes
{ {
public class MemberAutoDataAttribute : MemberDataAttributeBase public class BitMemberAutoDataAttribute : MemberDataAttributeBase
{ {
private readonly Func<IFixture> _createFixture; private readonly Func<IFixture> _createFixture;
public MemberAutoDataAttribute(string memberName, params object[] parameters) : public BitMemberAutoDataAttribute(string memberName, params object[] parameters) :
this(() => new Fixture(), memberName, parameters) this(() => new Fixture(), memberName, parameters)
{ } { }
public MemberAutoDataAttribute(Func<IFixture> createFixture, string memberName, params object[] parameters) : public BitMemberAutoDataAttribute(Func<IFixture> createFixture, string memberName, params object[] parameters) :
base(memberName, parameters) base(memberName, parameters)
{ {
_createFixture = createFixture; _createFixture = createFixture;
} }
protected override object[] ConvertDataItem(MethodInfo testMethod, object item) protected override object[] ConvertDataItem(MethodInfo testMethod, object item) =>
{ BitAutoDataAttributeHelpers.GetData(testMethod, _createFixture(), item as object[]).First();
var methodParameters = testMethod.GetParameters();
var classCustomizations = testMethod.DeclaringType.GetCustomAttributes<BitCustomizeAttribute>().Select(attr => attr.GetCustomization());
var methodCustomizations = testMethod.GetCustomAttributes<BitCustomizeAttribute>().Select(attr => attr.GetCustomization());
var array = item as object[] ?? Array.Empty<object>();
var fixture = ApplyCustomizations(ApplyCustomizations(_createFixture(), classCustomizations), methodCustomizations);
var missingParameters = methodParameters.Skip(array.Length).Select(p => CustomizeAndCreate(p, fixture));
return array.Concat(missingParameters).ToArray();
}
private static object CustomizeAndCreate(ParameterInfo p, IFixture fixture)
{
var customizations = p.GetCustomAttributes(typeof(CustomizeAttribute), false)
.OfType<CustomizeAttribute>()
.Select(attr => attr.GetCustomization(p));
var context = new SpecimenContext(ApplyCustomizations(fixture, customizations));
return context.Resolve(p);
}
private static IFixture ApplyCustomizations(IFixture fixture, IEnumerable<ICustomization> customizations)
{
var newFixture = new Fixture();
foreach (var customization in fixture.Customizations.Reverse().Select(b => b.ToCustomization()))
{
newFixture.Customize(customization);
}
foreach (var customization in customizations)
{
newFixture.Customize(customization);
}
return newFixture;
}
} }
} }

View File

@ -0,0 +1,55 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using AutoFixture;
using AutoFixture.Kernel;
using AutoFixture.Xunit2;
using Bit.Test.Common.AutoFixture.Attributes;
namespace Bit.Test.Common.Helpers
{
public static class BitAutoDataAttributeHelpers
{
public static IEnumerable<object[]> GetData(MethodInfo testMethod, IFixture fixture, object[] fixedTestParamters)
{
var methodParameters = testMethod.GetParameters();
var classCustomizations = testMethod.DeclaringType.GetCustomAttributes<BitCustomizeAttribute>().Select(attr => attr.GetCustomization());
var methodCustomizations = testMethod.GetCustomAttributes<BitCustomizeAttribute>().Select(attr => attr.GetCustomization());
fixedTestParamters = fixedTestParamters ?? Array.Empty<object>();
fixture = ApplyCustomizations(ApplyCustomizations(fixture, classCustomizations), methodCustomizations);
var missingParameters = methodParameters.Skip(fixedTestParamters.Length).Select(p => CustomizeAndCreate(p, fixture));
return new object[1][] { fixedTestParamters.Concat(missingParameters).ToArray() };
}
public static object CustomizeAndCreate(ParameterInfo p, IFixture fixture)
{
var customizations = p.GetCustomAttributes(typeof(CustomizeAttribute), false)
.OfType<CustomizeAttribute>()
.Select(attr => attr.GetCustomization(p));
var context = new SpecimenContext(ApplyCustomizations(fixture, customizations));
return context.Resolve(p);
}
public static IFixture ApplyCustomizations(IFixture fixture, IEnumerable<ICustomization> customizations)
{
var newFixture = new Fixture();
foreach (var customization in fixture.Customizations.Reverse().Select(b => b.ToCustomization()))
{
newFixture.Customize(customization);
}
foreach (var customization in customizations)
{
newFixture.Customize(customization);
}
return newFixture;
}
}
}