[NUI] Rebase develnui (DevelNUI only patches --> master) (#3910)
[platform/core/csapi/tizenfx.git] / test / Tizen.NUI.Devel.Tests.Ubuntu / nunit.framework / Internal / Builders / NUnitTestCaseBuilder.cs
1 // ***********************************************************************
2 // Copyright (c) 2008-2014 Charlie Poole
3 //
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:
11 //
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
14 //
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 // ***********************************************************************
23 #define PORTABLE
24 #define TIZEN
25 #define NUNIT_FRAMEWORK
26 #define NUNITLITE
27 #define NET_4_5
28 #define PARALLEL
29 using System;
30 #if NETCF
31 using System.Linq;
32 #endif
33 using NUnit.Framework.Interfaces;
34
35 namespace NUnit.Framework.Internal.Builders
36 {
37     /// <summary>
38     /// NUnitTestCaseBuilder is a utility class used by attributes
39     /// that build test cases.
40     /// </summary>
41     public class NUnitTestCaseBuilder
42     {
43         private readonly Randomizer _randomizer = Randomizer.CreateRandomizer();
44         private readonly TestNameGenerator _nameGenerator;
45
46         /// <summary>
47         /// Constructs an <see cref="NUnitTestCaseBuilder"/>
48         /// </summary>
49         public NUnitTestCaseBuilder()
50         {
51             _nameGenerator = new TestNameGenerator();
52         }
53
54         /// <summary>
55         /// Builds a single NUnitTestMethod, either as a child of the fixture
56         /// or as one of a set of test cases under a ParameterizedTestMethodSuite.
57         /// </summary>
58         /// <param name="method">The MethodInfo from which to construct the TestMethod</param>
59         /// <param name="parentSuite">The suite or fixture to which the new test will be added</param>
60         /// <param name="parms">The ParameterSet to be used, or null</param>
61         /// <returns></returns>
62         public TestMethod BuildTestMethod(IMethodInfo method, Test parentSuite, TestCaseParameters parms)
63         {
64             var testMethod = new TestMethod(method, parentSuite)
65             {
66                 Seed = _randomizer.Next()
67             };
68
69             CheckTestMethodSignature(testMethod, parms);
70
71             if (parms == null || parms.Arguments == null)
72                 testMethod.ApplyAttributesToTest(method.MethodInfo);
73
74             // NOTE: After the call to CheckTestMethodSignature, the Method
75             // property of testMethod may no longer be the same as the
76             // original MethodInfo, so we don't use it here.
77             string prefix = testMethod.Method.TypeInfo.FullName;
78
79             // Needed to give proper fullname to test in a parameterized fixture.
80             // Without this, the arguments to the fixture are not included.
81             if (parentSuite != null)
82                 prefix = parentSuite.FullName;
83
84             if (parms != null)
85             {
86                 parms.ApplyToTest(testMethod);
87
88                 if (parms.TestName != null)
89                 {
90                     // The test is simply for efficiency
91                     testMethod.Name = parms.TestName.Contains("{")
92                         ? new TestNameGenerator(parms.TestName).GetDisplayName(testMethod, parms.OriginalArguments)
93                         : parms.TestName;
94                 }
95                 else
96                 {
97                     testMethod.Name = _nameGenerator.GetDisplayName(testMethod, parms.OriginalArguments);
98                 }
99             }
100             else
101             {
102                 testMethod.Name = _nameGenerator.GetDisplayName(testMethod, null);
103             }
104
105             testMethod.FullName = prefix + "." + testMethod.Name;
106
107             return testMethod;
108         }
109
110         #region Helper Methods
111
112         /// <summary>
113         /// Helper method that checks the signature of a TestMethod and
114         /// any supplied parameters to determine if the test is valid.
115         ///
116         /// Currently, NUnitTestMethods are required to be public,
117         /// non-abstract methods, either static or instance,
118         /// returning void. They may take arguments but the _values must
119         /// be provided or the TestMethod is not considered runnable.
120         ///
121         /// Methods not meeting these criteria will be marked as
122         /// non-runnable and the method will return false in that case.
123         /// </summary>
124         /// <param name="testMethod">The TestMethod to be checked. If it
125         /// is found to be non-runnable, it will be modified.</param>
126         /// <param name="parms">Parameters to be used for this test, or null</param>
127         /// <returns>True if the method signature is valid, false if not</returns>
128         /// <remarks>
129         /// The return value is no longer used internally, but is retained
130         /// for testing purposes.
131         /// </remarks>
132         private static bool CheckTestMethodSignature(TestMethod testMethod, TestCaseParameters parms)
133         {
134             if (testMethod.Method.IsAbstract)
135                 return MarkAsNotRunnable(testMethod, "Method is abstract");
136
137             if (!testMethod.Method.IsPublic)
138                 return MarkAsNotRunnable(testMethod, "Method is not public");
139
140             IParameterInfo[] parameters;
141 #if NETCF
142             if (testMethod.Method.IsGenericMethodDefinition)
143             {
144                 if (parms != null && parms.Arguments != null)
145                 {
146                     var mi = testMethod.Method.MakeGenericMethodEx(parms.Arguments);
147                     if (mi == null)
148                         return MarkAsNotRunnable(testMethod, "Cannot determine generic types by probing");
149                     testMethod.Method = mi;
150                     parameters = testMethod.Method.GetParameters();
151                 }
152                 else
153                     parameters = new IParameterInfo[0];
154             }
155             else
156                 parameters = testMethod.Method.GetParameters();
157
158             int minArgsNeeded = parameters.Length;
159 #else
160             parameters = testMethod.Method.GetParameters();
161             int minArgsNeeded = 0;
162             foreach (var parameter in parameters)
163             {
164                 // IsOptional is supported since .NET 1.1 
165                 if (!parameter.IsOptional)
166                     minArgsNeeded++;
167             }
168 #endif
169             int maxArgsNeeded = parameters.Length;
170
171             object[] arglist = null;
172             int argsProvided = 0;
173
174             if (parms != null)
175             {
176                 testMethod.parms = parms;
177                 testMethod.RunState = parms.RunState;
178
179                 arglist = parms.Arguments;
180
181                 if (arglist != null)
182                     argsProvided = arglist.Length;
183
184                 if (testMethod.RunState != RunState.Runnable)
185                     return false;
186             }
187
188 #if NETCF
189             ITypeInfo returnType = testMethod.Method.IsGenericMethodDefinition && (parms == null || parms.Arguments == null) ? new TypeWrapper(typeof(void)) : testMethod.Method.ReturnType;
190 #else
191             ITypeInfo returnType = testMethod.Method.ReturnType;
192 #endif
193
194 #if NET_4_0 || NET_4_5 || PORTABLE
195             if (AsyncInvocationRegion.IsAsyncOperation(testMethod.Method.MethodInfo))
196             {
197                 if (returnType.IsType(typeof(void)))
198                     return MarkAsNotRunnable(testMethod, "Async test method must have non-void return type");
199
200                 var returnsGenericTask = returnType.IsGenericType &&
201                     returnType.GetGenericTypeDefinition() == typeof(System.Threading.Tasks.Task<>);
202
203                 if (returnsGenericTask && (parms == null || !parms.HasExpectedResult))
204                     return MarkAsNotRunnable(testMethod,
205                         "Async test method must have non-generic Task return type when no result is expected");
206
207                 if (!returnsGenericTask && parms != null && parms.HasExpectedResult)
208                     return MarkAsNotRunnable(testMethod,
209                         "Async test method must have Task<T> return type when a result is expected");
210             }
211             else
212 #endif
213             if (returnType.IsType(typeof(void)))
214             {
215                 if (parms != null && parms.HasExpectedResult)
216                     return MarkAsNotRunnable(testMethod, "Method returning void cannot have an expected result");
217             }
218             else if (parms == null || !parms.HasExpectedResult)
219                 return MarkAsNotRunnable(testMethod, "Method has non-void return value, but no result is expected");
220
221             if (argsProvided > 0 && maxArgsNeeded == 0)
222                 return MarkAsNotRunnable(testMethod, "Arguments provided for method not taking any");
223
224             if (argsProvided == 0 && minArgsNeeded > 0)
225                 return MarkAsNotRunnable(testMethod, "No arguments were provided");
226
227             if (argsProvided < minArgsNeeded)
228                 return MarkAsNotRunnable(testMethod, string.Format("Not enough arguments provided, provide at least {0} arguments.", minArgsNeeded));
229
230             if (argsProvided > maxArgsNeeded)
231                 return MarkAsNotRunnable(testMethod, string.Format("Too many arguments provided, provide at most {0} arguments.", maxArgsNeeded));
232
233             if (testMethod.Method.IsGenericMethodDefinition && arglist != null)
234             {
235                 var typeArguments = new GenericMethodHelper(testMethod.Method.MethodInfo).GetTypeArguments(arglist);
236                 foreach (Type o in typeArguments)
237                     if (o == null || o == TypeHelper.NonmatchingType)
238                         return MarkAsNotRunnable(testMethod, "Unable to determine type arguments for method");
239
240
241                 testMethod.Method = testMethod.Method.MakeGenericMethod(typeArguments);
242                 parameters = testMethod.Method.GetParameters();
243             }
244
245             if (arglist != null && parameters != null)
246                 TypeHelper.ConvertArgumentList(arglist, parameters);
247
248             return true;
249         }
250
251         private static bool MarkAsNotRunnable(TestMethod testMethod, string reason)
252         {
253             testMethod.RunState = RunState.NotRunnable;
254             testMethod.Properties.Set(PropertyNames.SkipReason, reason);
255             return false;
256         }
257
258         #endregion
259     }
260 }