-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathAutoClassDataSourceAttribute.cs
More file actions
93 lines (85 loc) · 3.89 KB
/
AutoClassDataSourceAttribute.cs
File metadata and controls
93 lines (85 loc) · 3.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
using System.Diagnostics.CodeAnalysis;
using AutoFixture.TUnit.Internal;
namespace AutoFixture.TUnit;
/// <summary>
/// Provides a data source for a data theory, with the data coming from a class
/// which must implement IEnumerable<object?[]>,
/// combined with auto-generated data specimens generated by AutoFixture.
/// </summary>
[SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes",
Justification = "This attribute is the root of a potential attribute hierarchy.")]
public class AutoClassDataSourceAttribute : BaseDataSourceAttribute
{
/// <summary>
/// Initializes a new instance of the <see cref="AutoClassDataSourceAttribute"/> class.
/// </summary>
/// <param name="sourceType">The type of the class that provides the data.</param>
/// <param name="parameters">The parameters passed to the data provider class constructor.</param>
public AutoClassDataSourceAttribute(Type sourceType, params object?[] parameters)
: this(() => new Fixture(), sourceType, parameters)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="AutoClassDataSourceAttribute"/> class.
/// </summary>
/// <param name="fixtureFactory">The fixture factory that provides missing data from <paramref name="sourceType"/>.</param>
/// <param name="sourceType">The type of the class that provides the data.</param>
/// <param name="parameters">The parameters passed to the data provider class constructor.</param>
/// <para>
/// This constructor overload exists to enable a derived attribute to
/// supply a custom fixture factory that again may contain custom behavior.
/// </para>
/// <example>
/// In the following example MyTestData is a class that provides test data,
/// that would be complicated or probably impossible to provide using other options.
/// The missing arguments for the test are being supplied from the Fixture instance.
/// <code>
/// [Test]
/// [AutoClassDataSource(typeof(MyTestData))]
/// public void ClassDataSuppliesExtraValues(int sum, int[] numbers, Person client)
/// {
/// var actual = numbers.Sum(x => x);
///
/// Assert.Equal(sum, actual);
/// Assert.NotNull(client);
/// }
///
/// private class MyTestData : IEnumerable<object?[]>
/// {
/// public IEnumerator<object?[]> GetEnumerator()
/// {
/// yield return new object?[] { 0, new int[0] };
/// yield return new object?[] { 4, new int[] { 1, 2, 1} };
/// yield return new object?[] { 23, new int [] { 0, 13, 15, -5 } };
/// }
///
/// IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator();
/// }
/// </code>
/// </example>
protected AutoClassDataSourceAttribute(Func<IFixture> fixtureFactory, Type sourceType, params object?[] parameters)
{
this.FixtureFactory = fixtureFactory ?? throw new ArgumentNullException(nameof(fixtureFactory));
this.SourceType = sourceType ?? throw new ArgumentNullException(nameof(sourceType));
this.Parameters = parameters ?? [null];
}
/// <summary>
/// Gets the fixture factory that provides the missing data from <see cref="SourceType"/>.
/// </summary>
public Func<IFixture> FixtureFactory { get; }
/// <summary>
/// Gets the type of the class that provides the data.
/// </summary>
public Type SourceType { get; }
/// <summary>
/// Gets the constructor parameters for <see cref="SourceType"/>.
/// </summary>
public object?[] Parameters { get; }
/// <inheritdoc />
public override IEnumerable<object?[]> GetData(DataGeneratorMetadata dataGeneratorMetadata)
{
var source = new AutoDataSource(this.FixtureFactory,
new ClassDataSource(this.SourceType, this.Parameters));
return source.GetDataSources(dataGeneratorMetadata).Select(x => x());
}
}