1 // ***********************************************************************
2 // Copyright (c) 2008 Charlie Poole
4 // Permission is hereby granted, free of charge, to any person obtaining
5 // a copy of this software and associated documentation files (the
6 // "Software"), to deal in the Software without restriction, including
7 // without limitation the rights to use, copy, modify, merge, publish,
8 // distribute, sublicense, and/or sell copies of the Software, and to
9 // permit persons to whom the Software is furnished to do so, subject to
10 // the following conditions:
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 // ***********************************************************************
25 #define NUNIT_FRAMEWORK
30 using System.Reflection;
31 using System.Collections;
32 using System.Collections.Generic;
33 using NUnit.Compatibility;
34 using NUnit.Framework.Interfaces;
36 namespace NUnit.Framework.Internal.Builders
39 /// Provides data from fields marked with the DatapointAttribute or the
40 /// DatapointsAttribute.
42 public class DatapointProvider : IParameterDataProvider
44 #region IDataPointProvider Members
47 /// Determine whether any data is available for a parameter.
49 /// <param name="parameter">A ParameterInfo representing one
50 /// argument to a parameterized test</param>
52 /// True if any data is available, otherwise false.
54 public bool HasDataFor(IParameterInfo parameter)
56 var method = parameter.Method;
57 if (!method.IsDefined<TheoryAttribute>(true))
60 Type parameterType = parameter.ParameterType;
61 if (parameterType == typeof(bool) || parameterType.GetTypeInfo().IsEnum)
64 Type containingType = method.TypeInfo.Type;
65 foreach (MemberInfo member in containingType.GetMembers(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance | BindingFlags.FlattenHierarchy))
67 if (member.IsDefined(typeof(DatapointAttribute), true) &&
68 GetTypeFromMemberInfo(member) == parameterType)
70 else if (member.IsDefined(typeof(DatapointSourceAttribute), true) &&
71 GetElementTypeFromMemberInfo(member) == parameterType)
79 /// Return an IEnumerable providing data for use with the
80 /// supplied parameter.
82 /// <param name="parameter">A ParameterInfo representing one
83 /// argument to a parameterized test</param>
85 /// An IEnumerable providing the required data
87 public System.Collections.IEnumerable GetDataFor(IParameterInfo parameter)
89 var datapoints = new List<object>();
91 Type parameterType = parameter.ParameterType;
92 Type fixtureType = parameter.Method.TypeInfo.Type;
94 foreach (MemberInfo member in fixtureType.GetMembers(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance | BindingFlags.FlattenHierarchy))
96 if (member.IsDefined(typeof(DatapointAttribute), true))
98 var field = member as FieldInfo;
99 if (GetTypeFromMemberInfo(member) == parameterType && field != null)
102 datapoints.Add(field.GetValue(null));
104 datapoints.Add(field.GetValue(ProviderCache.GetInstanceOf(fixtureType)));
107 else if (member.IsDefined(typeof(DatapointSourceAttribute), true))
109 if (GetElementTypeFromMemberInfo(member) == parameterType)
113 FieldInfo field = member as FieldInfo;
114 PropertyInfo property = member as PropertyInfo;
115 MethodInfo method = member as MethodInfo;
118 instance = field.IsStatic ? null : ProviderCache.GetInstanceOf(fixtureType);
119 foreach (object data in (IEnumerable)field.GetValue(instance))
120 datapoints.Add(data);
122 else if (property != null)
124 MethodInfo getMethod = property.GetGetMethod(true);
125 instance = getMethod.IsStatic ? null : ProviderCache.GetInstanceOf(fixtureType);
126 foreach (object data in (IEnumerable)property.GetValue(instance, null))
127 datapoints.Add(data);
129 else if (method != null)
131 instance = method.IsStatic ? null : ProviderCache.GetInstanceOf(fixtureType);
132 foreach (object data in (IEnumerable)method.Invoke(instance, new Type[0]))
133 datapoints.Add(data);
139 if (datapoints.Count == 0)
141 if (parameterType == typeof(bool))
143 datapoints.Add(true);
144 datapoints.Add(false);
146 else if (parameterType.GetTypeInfo().IsEnum)
148 foreach (object o in TypeHelper.GetEnumValues(parameterType))
156 private Type GetTypeFromMemberInfo(MemberInfo member)
158 var field = member as FieldInfo;
160 return field.FieldType;
162 var property = member as PropertyInfo;
163 if (property != null)
164 return property.PropertyType;
166 var method = member as MethodInfo;
168 return method.ReturnType;
173 private Type GetElementTypeFromMemberInfo(MemberInfo member)
175 Type type = GetTypeFromMemberInfo(member);
181 return type.GetElementType();
183 if (type.GetTypeInfo().IsGenericType && type.Name == "IEnumerable`1")
184 return type.GetGenericArguments()[0];