View Javadoc

1   package org.apache.maven.surefire.testng.conf;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.lang.reflect.Method;
23  import java.util.ArrayList;
24  import java.util.HashMap;
25  import java.util.Iterator;
26  import java.util.Map;
27  import org.apache.maven.surefire.booter.ProviderParameterNames;
28  import org.apache.maven.surefire.testset.TestSetFailedException;
29  
30  import org.testng.TestNG;
31  
32  /**
33   * TestNG configurator for 5.3+ versions. TestNG exposes a {@link org.testng.TestNG#configure(java.util.Map)} method.
34   * All suppported TestNG options are passed in String format, except
35   * <code>TestNGCommandLineArgs.LISTENER_COMMAND_OPT</code> which is <code>List&gt;Class&lt;</code>,
36   * <code>TestNGCommandLineArgs.JUNIT_DEF_OPT</code> which is a <code>Boolean</code>,
37   * <code>TestNGCommandLineArgs.SKIP_FAILED_INVOCATION_COUNT_OPT</code> which is a <code>Boolean</code>,
38   * <code>TestNGCommandLineArgs.OBJECT_FACTORY_COMMAND_OPT</code> which is a <code>Class</code>,
39   * <code>TestNGCommandLineArgs.REPORTERS_LIST</code> which is a <code>List&gt;ReporterConfig&lt;</code>.
40   * <p/>
41   * Test classes and/or suite files are not passed along as options parameters, but configured separately.
42   *
43   * @author <a href='mailto:the[dot]mindstorm[at]gmail[dot]com'>Alex Popescu</a>
44   */
45  public class TestNGMapConfigurator
46      implements Configurator
47  {
48      public void configure( TestNG testng, Map options )
49          throws TestSetFailedException
50      {
51          Map convertedOptions = getConvertedOptions( options );
52          testng.configure( convertedOptions );
53      }
54  
55      Map getConvertedOptions( Map options )
56          throws TestSetFailedException
57      {
58          Map convertedOptions = new HashMap();
59          convertedOptions.put( "-mixed", Boolean.FALSE );
60          for ( Iterator it = options.entrySet().iterator(); it.hasNext(); )
61          {
62              Map.Entry entry = (Map.Entry) it.next();
63              String key = (String) entry.getKey();
64              Object val = entry.getValue();
65              if ( "listener".equals( key ) )
66              {
67                  val = AbstractDirectConfigurator.loadListenerClasses( (String) val );
68              }
69              if ( "objectfactory".equals( key ) )
70              {
71                  val = AbstractDirectConfigurator.loadClass( (String) val );
72              }
73              if ( "reporter".equals( key ) )
74              {
75                  // TODO support multiple reporters?
76                  val = convertReporterConfig( val );
77                  key = "reporterslist";
78  
79              }
80              if ( "junit".equals( key ) )
81              {
82                  val = convert( val, Boolean.class );
83              }
84              else if ( "skipfailedinvocationcounts".equals( key ) )
85              {
86                  val = convert( val, Boolean.class );
87              }
88              else if ( "mixed".equals( key ) )
89              {
90                  val = convert( val, Boolean.class );
91              }
92              else if ( "configfailurepolicy".equals( key ) )
93              {
94                  val = convert( val, String.class );
95              }
96              else if ( "group-by-instances".equals( key ) )
97              {
98                  val = convert( val, Boolean.class );
99              }
100             else if ( ProviderParameterNames.THREADCOUNT_PROP.equals( key ) )
101             {
102                 val = convert( val, String.class );
103             }
104             // TODO objectfactory... not even documented, does it work?
105             if ( key.startsWith( "-" ) )
106             {
107                 convertedOptions.put( key, val );
108             }
109             else
110             {
111                 convertedOptions.put( "-" + key, val );
112             }
113         }
114         return convertedOptions;
115     }
116 
117     // ReporterConfig only became available in later versions of TestNG
118     private Object convertReporterConfig( Object val )
119     {
120         final String reporterConfigClassName = "org.testng.ReporterConfig";
121         try
122         {
123             Class reporterConfig = Class.forName( reporterConfigClassName );
124             Method deserialize = reporterConfig.getMethod( "deserialize", new Class[]{ String.class } );
125             Object rc = deserialize.invoke( null, new Object[]{ val } );
126             ArrayList reportersList = new ArrayList();
127             reportersList.add( rc );
128             return reportersList;
129         }
130         catch ( Exception e )
131         {
132             return val;
133         }
134     }
135 
136     protected Object convert( Object val, Class type )
137     {
138         if ( val == null )
139         {
140             return null;
141         }
142         if ( type.isAssignableFrom( val.getClass() ) )
143         {
144             return val;
145         }
146 
147         if ( ( Boolean.class.equals( type ) || boolean.class.equals( type ) ) && String.class.equals( val.getClass() ) )
148         {
149             return Boolean.valueOf( (String) val );
150         }
151 
152         if ( String.class.equals( type ) )
153         {
154             return val.toString();
155         }
156 
157         return val;
158     }
159 }