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.Collections;
31 using System.Reflection;
32 using NUnit.Compatibility;
33 using NUnit.Framework.Interfaces;
34 using NUnit.Framework.Internal;
36 namespace NUnit.Framework
39 /// ValuesAttribute is used to provide literal arguments for
40 /// an individual parameter of a test.
42 [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
43 public class ValuesAttribute : DataAttribute, IParameterDataSource
46 /// The collection of data to be returned. Must
47 /// be set by any derived attribute classes.
48 /// We use an object[] so that the individual
49 /// elements may have their type changed in GetData
52 // TODO: This causes a lot of boxing so we should eliminate it
53 protected object[] data;
56 /// Constructs for use with an Enum parameter. Will pass every enum
57 /// value in to the test.
59 public ValuesAttribute()
61 data = new object[]{};
65 /// Construct with one argument
67 /// <param name="arg1"></param>
68 public ValuesAttribute(object arg1)
70 data = new object[] { arg1 };
74 /// Construct with two arguments
76 /// <param name="arg1"></param>
77 /// <param name="arg2"></param>
78 public ValuesAttribute(object arg1, object arg2)
80 data = new object[] { arg1, arg2 };
84 /// Construct with three arguments
86 /// <param name="arg1"></param>
87 /// <param name="arg2"></param>
88 /// <param name="arg3"></param>
89 public ValuesAttribute(object arg1, object arg2, object arg3)
91 data = new object[] { arg1, arg2, arg3 };
95 /// Construct with an array of arguments
97 /// <param name="args"></param>
98 public ValuesAttribute(params object[] args)
104 /// Get the collection of _values to be used as arguments
106 public IEnumerable GetData(IParameterInfo parameter)
108 Type targetType = parameter.ParameterType;
110 if (targetType.GetTypeInfo().IsEnum && data.Length == 0)
112 return TypeHelper.GetEnumValues(targetType);
114 if (targetType == typeof(bool) && data.Length == 0)
116 return new object[] {true, false};
118 return GetData(targetType);
121 private IEnumerable GetData(Type targetType)
123 for (int i = 0; i < data.Length; i++)
125 object arg = data[i];
130 if (arg.GetType().FullName == "NUnit.Framework.SpecialValue" &&
131 arg.ToString() == "Null")
137 if (targetType.GetTypeInfo().IsAssignableFrom(arg.GetType().GetTypeInfo()))
148 bool convert = false;
150 if (targetType == typeof(short) || targetType == typeof(byte) || targetType == typeof(sbyte))
151 convert = arg is int;
153 if (targetType == typeof(decimal))
154 convert = arg is double || arg is string || arg is int;
156 if (targetType == typeof(DateTime) || targetType == typeof(TimeSpan))
157 convert = arg is string;
160 data[i] = Convert.ChangeType(arg, targetType, System.Globalization.CultureInfo.InvariantCulture);