Coverage Report - org.apache.maven.surefire.common.junit48.FilterFactory
 
Classes in this File Line Coverage Branch Coverage Complexity
FilterFactory
0%
0/24
0%
0/16
3,45
FilterFactory$AndFilter
0%
0/6
0%
0/4
3,45
FilterFactory$CombinedCategoryFilter
0%
0/28
0%
0/22
3,45
FilterFactory$GroupMatcherCategoryFilter
0%
0/38
0%
0/38
3,45
FilterFactory$MethodFilter
0%
0/9
0%
0/8
3,45
 
 1  
 package org.apache.maven.surefire.common.junit48;
 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.util.ArrayList;
 23  
 import java.util.Arrays;
 24  
 import java.util.HashMap;
 25  
 import java.util.HashSet;
 26  
 import java.util.List;
 27  
 import java.util.Map;
 28  
 import java.util.Properties;
 29  
 import java.util.Set;
 30  
 import org.apache.maven.shared.utils.io.SelectorUtils;
 31  
 import org.apache.maven.surefire.booter.ProviderParameterNames;
 32  
 import org.apache.maven.surefire.group.match.AndGroupMatcher;
 33  
 import org.apache.maven.surefire.group.match.GroupMatcher;
 34  
 import org.apache.maven.surefire.group.match.InverseGroupMatcher;
 35  
 import org.apache.maven.surefire.group.parse.GroupMatcherParser;
 36  
 import org.apache.maven.surefire.group.parse.ParseException;
 37  
 
 38  
 import org.junit.experimental.categories.Category;
 39  
 import org.junit.runner.Description;
 40  
 import org.junit.runner.manipulation.Filter;
 41  
 
 42  
 /**
 43  
  * @author Todd Lipcon
 44  
  */
 45  
 public class FilterFactory
 46  
 {
 47  
     private final ClassLoader testClassLoader;
 48  
 
 49  
     public FilterFactory( ClassLoader testClassLoader )
 50  0
     {
 51  0
         this.testClassLoader = testClassLoader;
 52  0
     }
 53  
 
 54  
     public Filter createGroupFilter( Properties providerProperties )
 55  
     {
 56  0
         String groups = providerProperties.getProperty( ProviderParameterNames.TESTNG_GROUPS_PROP );
 57  0
         String excludedGroups = providerProperties.getProperty( ProviderParameterNames.TESTNG_EXCLUDEDGROUPS_PROP );
 58  
 
 59  0
         GroupMatcher included = null;
 60  0
         if ( groups != null && groups.trim().length() > 0 )
 61  
         {
 62  
             try
 63  
             {
 64  0
                 included = new GroupMatcherParser( groups ).parse();
 65  
             }
 66  0
             catch ( ParseException e )
 67  
             {
 68  0
                 throw new IllegalArgumentException( "Invalid group expression: '" + groups + "'. Reason: "
 69  
                     + e.getMessage(), e );
 70  0
             }
 71  
         }
 72  
 
 73  0
         GroupMatcher excluded = null;
 74  0
         if ( excludedGroups != null && excludedGroups.trim().length() > 0 )
 75  
         {
 76  
             try
 77  
             {
 78  0
                 excluded = new GroupMatcherParser( excludedGroups ).parse();
 79  
             }
 80  0
             catch ( ParseException e )
 81  
             {
 82  0
                 throw new IllegalArgumentException( "Invalid group expression: '" + excludedGroups + "'. Reason: "
 83  
                     + e.getMessage(), e );
 84  0
             }
 85  
         }
 86  
 
 87  
         // GroupMatcher included = commaSeparatedListToFilters( groups );
 88  
         // GroupMatcher excluded = commaSeparatedListToFilters( excludedGroups
 89  
         // );
 90  
 
 91  0
         if ( included != null && testClassLoader != null )
 92  
         {
 93  0
             included.loadGroupClasses( testClassLoader );
 94  
         }
 95  
 
 96  0
         if ( excluded != null && testClassLoader != null )
 97  
         {
 98  0
             excluded.loadGroupClasses( testClassLoader );
 99  
         }
 100  
 
 101  0
         return new GroupMatcherCategoryFilter( included, excluded );
 102  
     }
 103  
 
 104  
     // private GroupMatcher commaSeparatedListToFilters( String str )
 105  
     // {
 106  
     // List<GroupMatcher> included = new ArrayList<GroupMatcher>();
 107  
     // if ( str != null )
 108  
     // {
 109  
     // for ( String group : str.split( "," ) )
 110  
     // {
 111  
     // group = group.trim();
 112  
     // if ( group == null || group.length() == 0)
 113  
     // {
 114  
     // continue;
 115  
     // }
 116  
     //
 117  
     // try
 118  
     // {
 119  
     // GroupMatcher matcher = new GroupMatcherParser( group ).parse();
 120  
     // included.add( matcher );
 121  
     // }
 122  
     // catch ( ParseException e )
 123  
     // {
 124  
     // throw new IllegalArgumentException( "Invalid group expression: '" + group
 125  
     // + "'. Reason: "
 126  
     // + e.getMessage(), e );
 127  
     // }
 128  
     //
 129  
     // // Class<?> categoryType = classloadCategory( group );
 130  
     // // included.add( Categories.CategoryFilter.include( categoryType ) );
 131  
     // }
 132  
     // }
 133  
     //
 134  
     // return included.isEmpty() ? null : new OrGroupMatcher( included );
 135  
     // }
 136  
 
 137  
     public Filter createMethodFilter( String requestedTestMethod )
 138  
     {
 139  0
         return new MethodFilter( requestedTestMethod );
 140  
     }
 141  
 
 142  
     public Filter and( Filter filter1, Filter filter2 )
 143  
     {
 144  0
         return new AndFilter( filter1, filter2 );
 145  
     }
 146  
 
 147  
     private static class MethodFilter
 148  
         extends Filter
 149  
     {
 150  
         private final String requestedTestMethod;
 151  
 
 152  
         public MethodFilter( String requestedTestMethod )
 153  0
         {
 154  0
             this.requestedTestMethod = requestedTestMethod;
 155  0
         }
 156  
 
 157  
         @Override
 158  
         public boolean shouldRun( Description description )
 159  
         {
 160  0
             for ( Description o : description.getChildren() )
 161  
             {
 162  0
                 if ( isDescriptionMatch( o ) )
 163  
                 {
 164  0
                     return true;
 165  
                 }
 166  
 
 167  
             }
 168  0
             return isDescriptionMatch( description );
 169  
         }
 170  
 
 171  
         private boolean isDescriptionMatch( Description description )
 172  
         {
 173  0
             return description.getMethodName() != null
 174  
                 && SelectorUtils.match( requestedTestMethod, description.getMethodName() );
 175  
         }
 176  
 
 177  
         @Override
 178  
         public String describe()
 179  
         {
 180  0
             return "By method" + requestedTestMethod;
 181  
         }
 182  
     }
 183  
 
 184  
     private static class GroupMatcherCategoryFilter
 185  
         extends Filter
 186  
     {
 187  
 
 188  
         private AndGroupMatcher matcher;
 189  
 
 190  0
         private Map<Description, Boolean> shouldRunAnswers = new HashMap<Description, Boolean>();
 191  
 
 192  
         public GroupMatcherCategoryFilter( GroupMatcher included, GroupMatcher excluded )
 193  0
         {
 194  0
             GroupMatcher invertedExclude = excluded == null ? null : new InverseGroupMatcher( excluded );
 195  0
             if ( included != null || invertedExclude != null )
 196  
             {
 197  0
                 matcher = new AndGroupMatcher();
 198  0
                 if ( included != null )
 199  
                 {
 200  0
                     matcher.addMatcher( included );
 201  
                 }
 202  
 
 203  0
                 if ( invertedExclude != null )
 204  
                 {
 205  0
                     matcher.addMatcher( invertedExclude );
 206  
                 }
 207  
             }
 208  0
         }
 209  
 
 210  
         @Override
 211  
         public boolean shouldRun( Description description )
 212  
         {
 213  0
             return shouldRun( description,
 214  
                               ( description.getMethodName() == null ? null
 215  
                                               : Description.createSuiteDescription( description.getTestClass() ) ) );
 216  
         }
 217  
 
 218  
         private boolean shouldRun( Description description, Description parent )
 219  
         {
 220  0
             Boolean result = shouldRunAnswers.get( description );
 221  0
             if ( result != null )
 222  
             {
 223  0
                 return result;
 224  
             }
 225  
 
 226  0
             if ( matcher == null )
 227  
             {
 228  0
                 return true;
 229  
             }
 230  
 
 231  
             // System.out.println( "\n\nMatcher: " + matcher );
 232  
             // System.out.println( "Checking: " + description.getClassName()
 233  
             // + ( parent == null ? "" : "#" + description.getMethodName() ) );
 234  
 
 235  0
             Set<Class<?>> cats = new HashSet<Class<?>>();
 236  0
             Category cat = description.getAnnotation( Category.class );
 237  0
             if ( cat != null )
 238  
             {
 239  
                 // System.out.println( "Adding categories: " + Arrays.toString(
 240  
                 // cat.value() ) );
 241  0
                 cats.addAll( Arrays.asList( cat.value() ) );
 242  
             }
 243  
 
 244  0
             if ( parent != null )
 245  
             {
 246  0
                 cat = parent.getAnnotation( Category.class );
 247  0
                 if ( cat != null )
 248  
                 {
 249  
                     // System.out.println( "Adding class-level categories: " +
 250  
                     // Arrays.toString( cat.value() ) );
 251  0
                     cats.addAll( Arrays.asList( cat.value() ) );
 252  
                 }
 253  
             }
 254  
 
 255  
             // System.out.println( "Checking " + cats.size() + " categories..."
 256  
             // );
 257  
             //
 258  
             // System.out.println( "Enabled? " + ( matcher.enabled(
 259  
             // cats.toArray( new Class<?>[] {} ) ) ) + "\n\n" );
 260  0
             result = matcher.enabled( cats.toArray( new Class<?>[] {} ) );
 261  
 
 262  0
             if ( parent == null )
 263  
             {
 264  0
                 if ( cats.size() == 0 )
 265  
                 {
 266  
                     // System.out.println(
 267  
                     // "Allow method-level filtering by PASSing class-level shouldRun() test..."
 268  
                     // );
 269  0
                     result = true;
 270  
                 }
 271  0
                 else if ( !result )
 272  
                 {
 273  0
                     ArrayList<Description> children = description.getChildren();
 274  0
                     if ( children != null )
 275  
                     {
 276  0
                         for ( Description child : children )
 277  
                         {
 278  0
                             if ( shouldRun( child, description ) )
 279  
                             {
 280  0
                                 result = true;
 281  0
                                 break;
 282  
                             }
 283  
                         }
 284  
                     }
 285  
                 }
 286  
             }
 287  
 
 288  0
             shouldRunAnswers.put( description, result );
 289  0
             return result == null ? false : result;
 290  
         }
 291  
 
 292  
         @Override
 293  
         public String describe()
 294  
         {
 295  0
             return matcher == null ? "ANY" : matcher.toString();
 296  
         }
 297  
 
 298  
     }
 299  
 
 300  
     private static class AndFilter
 301  
         extends Filter
 302  
     {
 303  
         private final Filter filter1;
 304  
 
 305  
         private final Filter filter2;
 306  
 
 307  
         public AndFilter( Filter filter1, Filter filter2 )
 308  0
         {
 309  0
             this.filter1 = filter1;
 310  0
             this.filter2 = filter2;
 311  0
         }
 312  
 
 313  
         @Override
 314  
         public boolean shouldRun( Description description )
 315  
         {
 316  0
             return filter1.shouldRun( description ) && filter2.shouldRun( description );
 317  
         }
 318  
 
 319  
         @Override
 320  
         public String describe()
 321  
         {
 322  0
             return filter1.describe() + " AND " + filter2.describe();
 323  
         }
 324  
     }
 325  
 
 326  
     @SuppressWarnings( "unused" )
 327  
     private static class CombinedCategoryFilter
 328  
         extends Filter
 329  
     {
 330  
         private final List<Filter> includedFilters;
 331  
 
 332  
         private final List<Filter> excludedFilters;
 333  
 
 334  
         public CombinedCategoryFilter( List<Filter> includedFilters, List<Filter> excludedFilters )
 335  0
         {
 336  0
             this.includedFilters = includedFilters;
 337  0
             this.excludedFilters = excludedFilters;
 338  0
         }
 339  
 
 340  
         @Override
 341  
         public boolean shouldRun( Description description )
 342  
         {
 343  0
             return ( includedFilters.isEmpty() || inOneOfFilters( includedFilters, description ) )
 344  
                 && ( excludedFilters.isEmpty() || !inOneOfFilters( excludedFilters, description ) );
 345  
         }
 346  
 
 347  
         private boolean inOneOfFilters( List<Filter> filters, Description description )
 348  
         {
 349  0
             for ( Filter f : filters )
 350  
             {
 351  0
                 if ( f.shouldRun( description ) )
 352  
                 {
 353  0
                     return true;
 354  
                 }
 355  
             }
 356  0
             return false;
 357  
         }
 358  
 
 359  
         @Override
 360  
         public String describe()
 361  
         {
 362  0
             StringBuilder sb = new StringBuilder();
 363  0
             if ( !includedFilters.isEmpty() )
 364  
             {
 365  0
                 sb.append( "(" );
 366  0
                 sb.append( joinFilters( includedFilters, " OR " ) );
 367  0
                 sb.append( ")" );
 368  0
                 if ( !excludedFilters.isEmpty() )
 369  
                 {
 370  0
                     sb.append( " AND " );
 371  
                 }
 372  
             }
 373  0
             if ( !excludedFilters.isEmpty() )
 374  
             {
 375  0
                 sb.append( "NOT (" );
 376  0
                 sb.append( joinFilters( includedFilters, " OR " ) );
 377  0
                 sb.append( ")" );
 378  
             }
 379  
 
 380  0
             return sb.toString();
 381  
         }
 382  
 
 383  
         private String joinFilters( List<Filter> filters, String sep )
 384  
         {
 385  0
             int i = 0;
 386  0
             StringBuilder sb = new StringBuilder();
 387  0
             for ( Filter f : filters )
 388  
             {
 389  0
                 if ( i++ > 0 )
 390  
                 {
 391  0
                     sb.append( sep );
 392  
                 }
 393  0
                 sb.append( f.describe() );
 394  
             }
 395  0
             return sb.toString();
 396  
         }
 397  
     }
 398  
 
 399  
 }