Skip to content

Instantly share code, notes, and snippets.

@bartelink
Created July 17, 2012 13:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bartelink/3129350 to your computer and use it in GitHub Desktop.
Save bartelink/3129350 to your computer and use it in GitHub Desktop.
ClassAutoData spiking
[Theory]
[ClassAutoData( typeof( XProvider ) )]
public static void Scenario( X x, string y )
{
Console.WriteLine( x + "," + y );
}
public class ClassAutoDataAttribute : CompositeDataAttribute
{
public ClassAutoDataAttribute( Type @class )
: base( new DataAttribute[] { new ClassDataAttribute( @class ), new AutoDataAttributeHack() } )
{
}
public override IEnumerable<object[]> GetData( System.Reflection.MethodInfo methodUnderTest, Type[] parameterTypes )
{
return
from result in Attributes.First().GetData( methodUnderTest, parameterTypes ).ToArray()
select result.Concat( Attributes.ElementAt( 1 ).GetData( methodUnderTest, parameterTypes.Skip( result.Length ).ToArray() ).First() ).ToArray();
}
}
public class AutoDataAttributeHack : AutoDataAttribute
{
public override IEnumerable<object[]> GetData( MethodInfo methodUnderTest, Type[] parameterTypes )
{
if ( methodUnderTest == null )
{
throw new ArgumentNullException( "methodUnderTest" );
}
// BEGIN DIFF
var specimens = new List<object>();
var methodParams = methodUnderTest.GetParameters();
foreach ( var p in methodParams.Skip( methodParams.Length - parameterTypes.Length ) )
// END DIFF
{
this.CustomizeFixture( p );
var specimen = this.Resolve( p );
specimens.Add( specimen );
}
return new[] { specimens.ToArray() };
}
private void CustomizeFixture( ParameterInfo p )
{
var dummy = false;
var customizeAttributes = p.GetCustomAttributes( typeof( CustomizeAttribute ), dummy ).OfType<CustomizeAttribute>();
foreach ( var ca in customizeAttributes )
{
var c = ca.GetCustomization( p );
this.Fixture.Customize( c );
}
}
private object Resolve( ParameterInfo p )
{
var context = new SpecimenContext( this.Fixture.Compose() );
return context.Resolve( p );
}
}
class XProvider : TupleTheoryDataProvider<X>
{
protected override IEnumerable<X> Generate()
{
return Enumerable.Repeat( X.Create(), 2 );
}
}
public class X
{
private X() { }
public static X Create()
{
return new X();
}
}
public abstract class TupleTheoryDataProvider<T1> : TheoryDataProvider
{
protected abstract IEnumerable<T1> Generate();
protected override sealed IEnumerable<object[]> DataSource()
{
return Generate().Select( x => new object[] { x } );
}
}
public abstract class TheoryDataProvider : IEnumerable<object[]>
{
public IEnumerator<object[]> GetEnumerator()
{
return DataSource().GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return DataSource().GetEnumerator();
}
protected abstract IEnumerable<object[]> DataSource();
}
@bartelink
Copy link
Author

The following makes the original (https://gist.github.com/3129350/15823b15b55ed803232a85296cbce8cc562ddcba) pass:

                    public override IEnumerable<object[]> GetData( System.Reflection.MethodInfo methodUnderTest, Type[] parameterTypes )
        {
            if ( methodUnderTest == null )
                throw new ArgumentNullException( "methodUnderTest" );

            if ( parameterTypes == null )
                throw new ArgumentNullException( "parameterTypes" );

            return 
                from result in Attributes.First().GetData( methodUnderTest, parameterTypes ).ToArray()
                select result.Concat( Attributes.ElementAt(1).GetData( methodUnderTest, parameterTypes ).First().Skip(result.Length) ).ToArray() ;
        }

but that redundantly creates stuff already covered by the ClassData, which in my case is heavy

@bartelink
Copy link
Author

This gist now passes. Problem: It likely no longer fulfills lots of other goals now!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment