[NUI] Rebase develnui (DevelNUI only patches --> master) (#3910)
[platform/core/csapi/tizenfx.git] / test / Tizen.NUI.Devel.Tests.Ubuntu / nunit.framework / Internal / Builders / DefaultSuiteBuilder.cs
1 // ***********************************************************************
2 // Copyright (c) 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 using System.Collections.Generic;
31 using NUnit.Framework.Interfaces;
32
33 namespace NUnit.Framework.Internal.Builders
34 {
35     /// <summary>
36     /// Built-in SuiteBuilder for all types of test classes.
37     /// </summary>
38     public class DefaultSuiteBuilder : ISuiteBuilder
39     {
40         // Builder we use for fixtures without any fixture attribute specified
41         private NUnitTestFixtureBuilder _defaultBuilder = new NUnitTestFixtureBuilder();
42
43         #region ISuiteBuilder Methods
44         /// <summary>
45         /// Checks to see if the provided Type is a fixture.
46         /// To be considered a fixture, it must be a non-abstract
47         /// class with one or more attributes implementing the
48         /// IFixtureBuilder interface or one or more methods
49         /// marked as tests.
50         /// </summary>
51         /// <param name="typeInfo">The fixture type to check</param>
52         /// <returns>True if the fixture can be built, false if not</returns>
53         public bool CanBuildFrom(ITypeInfo typeInfo)
54         {
55             if (typeInfo.IsAbstract && !typeInfo.IsSealed)
56                 return false;
57
58             if (typeInfo.IsDefined<IFixtureBuilder>(true))
59                 return true;
60
61             // Generics must have an attribute in order to provide
62             // them with arguments to determine the specific type.
63             // TODO: What about automatic fixtures? Should there
64             // be some kind of error shown?
65             if (typeInfo.IsGenericTypeDefinition)
66                 return false;
67
68             return typeInfo.HasMethodWithAttribute(typeof(IImplyFixture));
69         }
70
71         /// <summary>
72         /// Build a TestSuite from TypeInfo provided.
73         /// </summary>
74         /// <param name="typeInfo">The fixture type to build</param>
75         /// <returns>A TestSuite built from that type</returns>
76         public TestSuite BuildFrom(ITypeInfo typeInfo)
77         {
78             var fixtures = new List<TestSuite>();
79
80             try
81             {
82                 IFixtureBuilder[] builders = GetFixtureBuilderAttributes(typeInfo);
83
84                 foreach (var builder in builders)
85                     foreach (var fixture in builder.BuildFrom(typeInfo))
86                         fixtures.Add(fixture);
87
88                 if (typeInfo.IsGenericType)
89                     return BuildMultipleFixtures(typeInfo, fixtures);
90
91                 switch (fixtures.Count)
92                 {
93                     case 0:
94                         return _defaultBuilder.BuildFrom(typeInfo);
95                     case 1:
96                         return fixtures[0];
97                     default:
98                         return BuildMultipleFixtures(typeInfo, fixtures);
99                 }
100             }
101             catch (Exception ex)
102             {
103                 var fixture = new TestFixture(typeInfo);
104                 fixture.RunState = RunState.NotRunnable;
105
106                 if (ex is System.Reflection.TargetInvocationException)
107                     ex = ex.InnerException;
108                 var msg = "An exception was thrown while loading the test." + Env.NewLine + ex.ToString();
109                 fixture.Properties.Add(PropertyNames.SkipReason, msg);
110
111                 return fixture;
112             }
113         }
114         #endregion
115
116         #region Helper Methods
117
118         private TestSuite BuildMultipleFixtures(ITypeInfo typeInfo, IEnumerable<TestSuite> fixtures)
119         {
120             TestSuite suite = new ParameterizedFixtureSuite(typeInfo);
121
122             foreach (var fixture in fixtures)
123                 suite.Add(fixture);
124
125             return suite;
126         }
127
128         /// <summary>
129         /// We look for attributes implementing IFixtureBuilder at one level 
130         /// of inheritance at a time. Attributes on base classes are not used 
131         /// unless there are no fixture builder attributes at all on the derived
132         /// class. This is by design.
133         /// </summary>
134         /// <param name="typeInfo">The type being examined for attributes</param>
135         /// <returns>A list of the attributes found.</returns>
136         private IFixtureBuilder[] GetFixtureBuilderAttributes(ITypeInfo typeInfo)
137         {
138             IFixtureBuilder[] attrs = new IFixtureBuilder[0];
139
140             while (typeInfo != null && !typeInfo.IsType(typeof(object)))
141             {
142                 attrs = (IFixtureBuilder[])typeInfo.GetCustomAttributes<IFixtureBuilder>(false);
143
144                 if (attrs.Length > 0)
145                 {
146                     // We want to eliminate duplicates that have no args.
147                     // If there is just one, no duplication is possible.
148                     if (attrs.Length == 1)
149                         return attrs;
150
151                     // Count how many have arguments
152                     int withArgs = 0;
153                     foreach (var attr in attrs)
154                         if (HasArguments(attr))
155                             withArgs++;
156
157                     // If all have args, just return them
158                     if (withArgs == attrs.Length)
159                         return attrs;
160
161                     // If none of them have args, return the first one
162                     if (withArgs == 0)
163                         return new IFixtureBuilder[] { attrs[0] };
164                     
165                     // Some of each - extract those with args
166                     var result = new IFixtureBuilder[withArgs];
167                     int count = 0;
168                     foreach (var attr in attrs)
169                         if (HasArguments(attr))
170                             result[count++] = attr;
171
172                     return result;
173                 }
174
175                 typeInfo = typeInfo.BaseType;
176             }
177
178             return attrs;
179         }
180
181         private bool HasArguments(IFixtureBuilder attr)
182         {
183             // Only TestFixtureAttribute can be used without arguments
184             var temp = attr as TestFixtureAttribute;
185
186             return temp == null || temp.Arguments.Length > 0 || temp.TypeArgs.Length > 0;
187         }
188
189         #endregion
190     }
191 }