1package org.testng;
2
3import org.testng.collections.Lists;
4import org.testng.collections.Objects;
5import org.testng.internal.ConfigurationMethod;
6import org.testng.internal.NoOpTestClass;
7import org.testng.internal.RunInfo;
8import org.testng.internal.TestNGMethod;
9import org.testng.internal.Utils;
10import org.testng.internal.annotations.IAnnotationFinder;
11import org.testng.xml.XmlClass;
12import org.testng.xml.XmlTest;
13
14import java.lang.reflect.Method;
15import java.util.List;
16
17/**
18 * This class represents a test class:
19 * - The test methods
20 * - The configuration methods (test and method)
21 * - The class file
22 *
23 * @author <a href="mailto:cedric@beust.com">Cedric Beust</a>
24 * @author <a href='mailto:the_mindstorm@evolva.ro'>Alexandru Popescu</a>
25 */
26class TestClass extends NoOpTestClass implements ITestClass {
27	/* generated */
28	private static final long serialVersionUID = -8077917128278361294L;
29  transient private IAnnotationFinder m_annotationFinder = null;
30  // The Strategy used to locate test methods (TestNG, JUnit, etc...)
31  transient private ITestMethodFinder m_testMethodFinder = null;
32
33  private IClass m_iClass = null;
34  private RunInfo m_runInfo = null;
35  private String m_testName;
36  private XmlTest m_xmlTest;
37  private XmlClass m_xmlClass;
38
39  protected TestClass(IClass cls,
40                   ITestMethodFinder testMethodFinder,
41                   IAnnotationFinder annotationFinder,
42                   RunInfo runInfo,
43                   XmlTest xmlTest,
44                   XmlClass xmlClass) {
45    init(cls, testMethodFinder, annotationFinder, runInfo, xmlTest, xmlClass);
46  }
47
48  /**
49   * @return the name of this test if the class implements org.testng.ITest, null otherwise.
50   */
51  @Override
52  public String getTestName() {
53    return m_testName;
54  }
55
56  @Override
57  public XmlTest getXmlTest() {
58    return m_xmlTest;
59  }
60
61  @Override
62  public XmlClass getXmlClass() {
63    return m_xmlClass;
64  }
65
66  public IAnnotationFinder getAnnotationFinder() {
67    return m_annotationFinder;
68  }
69
70  private void init(IClass cls,
71                    ITestMethodFinder testMethodFinder,
72                    IAnnotationFinder annotationFinder,
73                    RunInfo runInfo,
74                    XmlTest xmlTest,
75                    XmlClass xmlClass)
76  {
77    log(3, "Creating TestClass for " + cls);
78    m_iClass = cls;
79    m_testClass = cls.getRealClass();
80    m_xmlTest = xmlTest;
81    m_xmlClass = xmlClass;
82    m_runInfo = runInfo;
83    m_testMethodFinder = testMethodFinder;
84    m_annotationFinder = annotationFinder;
85    initTestClassesAndInstances();
86    initMethods();
87  }
88
89  private void initTestClassesAndInstances() {
90    //
91    // TestClasses and instances
92    //
93    Object[] instances = getInstances(false);
94    for (Object instance : instances) {
95      if (instance instanceof ITest) {
96        m_testName = ((ITest) instance).getTestName();
97        break;
98      }
99    }
100    if (m_testName == null) {
101      m_testName = m_iClass.getTestName();
102    }
103  }
104
105  @Override
106  public Object[] getInstances(boolean create) {
107    return m_iClass.getInstances(create);
108  }
109
110  @Override
111  public long[] getInstanceHashCodes() {
112    return m_iClass.getInstanceHashCodes();
113  }
114
115  @Override
116  public int getInstanceCount() {
117    return m_iClass.getInstanceCount();
118  }
119
120  @Override
121  public void addInstance(Object instance) {
122    m_iClass.addInstance(instance);
123  }
124
125  private void initMethods() {
126    ITestNGMethod[] methods = m_testMethodFinder.getTestMethods(m_testClass, m_xmlTest);
127    m_testMethods = createTestMethods(methods);
128
129    for (Object instance : m_iClass.getInstances(false)) {
130      m_beforeSuiteMethods = ConfigurationMethod
131          .createSuiteConfigurationMethods(m_testMethodFinder.getBeforeSuiteMethods(m_testClass),
132                                           m_annotationFinder,
133                                           true,
134                                           instance);
135      m_afterSuiteMethods = ConfigurationMethod
136          .createSuiteConfigurationMethods(m_testMethodFinder.getAfterSuiteMethods(m_testClass),
137                                           m_annotationFinder,
138                                           false,
139                                           instance);
140      m_beforeTestConfMethods = ConfigurationMethod
141          .createTestConfigurationMethods(m_testMethodFinder.getBeforeTestConfigurationMethods(m_testClass),
142                                          m_annotationFinder,
143                                          true,
144                                          instance);
145      m_afterTestConfMethods = ConfigurationMethod
146          .createTestConfigurationMethods(m_testMethodFinder.getAfterTestConfigurationMethods(m_testClass),
147                                          m_annotationFinder,
148                                          false,
149                                          instance);
150      m_beforeClassMethods = ConfigurationMethod
151          .createClassConfigurationMethods(m_testMethodFinder.getBeforeClassMethods(m_testClass),
152                                           m_annotationFinder,
153                                           true,
154                                           instance);
155      m_afterClassMethods = ConfigurationMethod
156          .createClassConfigurationMethods(m_testMethodFinder.getAfterClassMethods(m_testClass),
157                                           m_annotationFinder,
158                                           false,
159                                           instance);
160      m_beforeGroupsMethods = ConfigurationMethod
161          .createBeforeConfigurationMethods(m_testMethodFinder.getBeforeGroupsConfigurationMethods(m_testClass),
162                                            m_annotationFinder,
163                                            true,
164                                            instance);
165      m_afterGroupsMethods = ConfigurationMethod
166          .createAfterConfigurationMethods(m_testMethodFinder.getAfterGroupsConfigurationMethods(m_testClass),
167                                           m_annotationFinder,
168                                           false,
169                                           instance);
170      m_beforeTestMethods = ConfigurationMethod
171          .createTestMethodConfigurationMethods(m_testMethodFinder.getBeforeTestMethods(m_testClass),
172                                                m_annotationFinder,
173                                                true,
174                                                instance);
175      m_afterTestMethods = ConfigurationMethod
176          .createTestMethodConfigurationMethods(m_testMethodFinder.getAfterTestMethods(m_testClass),
177                                                m_annotationFinder,
178                                                false,
179                                                instance);
180    }
181  }
182
183  /**
184   * Create the test methods that belong to this class (rejects
185   * all those that belong to a different class).
186   */
187  private ITestNGMethod[] createTestMethods(ITestNGMethod[] methods) {
188    List<ITestNGMethod> vResult = Lists.newArrayList();
189    for (ITestNGMethod tm : methods) {
190      Method m = tm.getMethod();
191      if (m.getDeclaringClass().isAssignableFrom(m_testClass)) {
192        for (Object o : m_iClass.getInstances(false)) {
193          log(4, "Adding method " + tm + " on TestClass " + m_testClass);
194          vResult.add(new TestNGMethod(/* tm.getRealClass(), */ m, m_annotationFinder, m_xmlTest,
195              o));
196        }
197      }
198      else {
199        log(4, "Rejecting method " + tm + " for TestClass " + m_testClass);
200      }
201    }
202
203    ITestNGMethod[] result = vResult.toArray(new ITestNGMethod[vResult.size()]);
204    return result;
205  }
206
207  private RunInfo getRunInfo() {
208    return m_runInfo;
209  }
210
211  public ITestMethodFinder getTestMethodFinder() {
212    return m_testMethodFinder;
213  }
214
215  private void log(int level, String s) {
216    Utils.log("TestClass", level, s);
217  }
218
219  private static void ppp(String s) {
220    System.out.println("[TestClass] " + s);
221  }
222
223  protected void dump() {
224    System.out.println("===== Test class\n" + m_testClass.getName());
225    for (ITestNGMethod m : m_beforeClassMethods) {
226      System.out.println("  @BeforeClass " + m);
227    }
228    for (ITestNGMethod m : m_beforeTestMethods) {
229      System.out.println("  @BeforeMethod " + m);
230    }
231    for (ITestNGMethod m : m_testMethods) {
232      System.out.println("    @Test " + m);
233    }
234    for (ITestNGMethod m : m_afterTestMethods) {
235      System.out.println("  @AfterMethod " + m);
236    }
237    for (ITestNGMethod m : m_afterClassMethods) {
238      System.out.println("  @AfterClass " + m);
239    }
240    System.out.println("======");
241  }
242
243  @Override
244  public String toString() {
245    return Objects.toStringHelper(getClass())
246        .add("name", m_testClass)
247        .toString();
248  }
249
250  public IClass getIClass() {
251    return m_iClass;
252  }
253}