From 192df467cee84d6e7b2734b1e155c11b1c41ada5 Mon Sep 17 00:00:00 2001 From: Matt Gibson Date: Fri, 29 Oct 2021 18:40:50 -0400 Subject: [PATCH] Workaround for broken MemberAutoDataAttribute https://github.com/AutoFixture/AutoFixture/pull/1164 shows that only the first test case is pulled for this attribute. This is a workaround that populates the provided parameters, left to right, using AutoFixture to populate any remaining. --- .../Attributes/MemberAutoDataAttribute.cs | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 test/Common/AutoFixture/Attributes/MemberAutoDataAttribute.cs diff --git a/test/Common/AutoFixture/Attributes/MemberAutoDataAttribute.cs b/test/Common/AutoFixture/Attributes/MemberAutoDataAttribute.cs new file mode 100644 index 000000000..cded9a26c --- /dev/null +++ b/test/Common/AutoFixture/Attributes/MemberAutoDataAttribute.cs @@ -0,0 +1,69 @@ +using System; +using Xunit.Sdk; +using Xunit; +using AutoFixture; +using System.Reflection; +using System.Collections.Generic; +using AutoFixture.Xunit2; +using System.Linq; +using AutoFixture.Kernel; +using System.Collections; + +namespace Bit.Test.Common.AutoFixture.Attributes +{ + public class MemberAutoDataAttribute : MemberDataAttributeBase + { + private readonly Func _createFixture; + + public MemberAutoDataAttribute(string memberName, params object[] parameters) : + this(() => new Fixture(), memberName, parameters) + { } + + public MemberAutoDataAttribute(Func createFixture, string memberName, params object[] parameters) : + base(memberName, parameters) + { + _createFixture = createFixture; + } + + protected override object[] ConvertDataItem(MethodInfo testMethod, object item) + { + var methodParameters = testMethod.GetParameters(); + var classCustomizations = testMethod.DeclaringType.GetCustomAttributes().Select(attr => attr.GetCustomization()); + var methodCustomizations = testMethod.GetCustomAttributes().Select(attr => attr.GetCustomization()); + + var array = item as object[] ?? Array.Empty(); + + 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() + .Select(attr => attr.GetCustomization(p)); + + var context = new SpecimenContext(ApplyCustomizations(fixture, customizations)); + return context.Resolve(p); + } + + private static IFixture ApplyCustomizations(IFixture fixture, IEnumerable 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; + } + } +}