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,571
FilterFactory$AndFilter
0%
0/6
0%
0/4
3,571
FilterFactory$CombinedCategoryFilter
0%
0/28
0%
0/22
3,571
FilterFactory$GroupMatcherCategoryFilter
0%
0/43
0%
0/44
3,571
FilterFactory$MethodFilter
0%
0/9
0%
0/8
3,571
 
 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.Collection;
 25  
 import java.util.Collections;
 26  
 import java.util.HashSet;
 27  
 import java.util.List;
 28  
 import java.util.Properties;
 29  
 import java.util.Set;
 30  
 
 31  
 import org.apache.maven.shared.utils.io.SelectorUtils;
 32  
 import org.apache.maven.surefire.booter.ProviderParameterNames;
 33  
 import org.apache.maven.surefire.group.match.AndGroupMatcher;
 34  
 import org.apache.maven.surefire.group.match.GroupMatcher;
 35  
 import org.apache.maven.surefire.group.match.InverseGroupMatcher;
 36  
 import org.apache.maven.surefire.group.parse.GroupMatcherParser;
 37  
 import org.apache.maven.surefire.group.parse.ParseException;
 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  0
         if ( included != null && testClassLoader != null )
 88  
         {
 89  0
             included.loadGroupClasses( testClassLoader );
 90  
         }
 91  
 
 92  0
         if ( excluded != null && testClassLoader != null )
 93  
         {
 94  0
             excluded.loadGroupClasses( testClassLoader );
 95  
         }
 96  
 
 97  0
         return new GroupMatcherCategoryFilter( included, excluded );
 98  
     }
 99  
 
 100  
     public Filter createMethodFilter( String requestedTestMethod )
 101  
     {
 102  0
         return new MethodFilter( requestedTestMethod );
 103  
     }
 104  
 
 105  
     public Filter and( Filter filter1, Filter filter2 )
 106  
     {
 107  0
         return new AndFilter( filter1, filter2 );
 108  
     }
 109  
 
 110  
     private static class MethodFilter
 111  
         extends Filter
 112  
     {
 113  
         private final String requestedTestMethod;
 114  
 
 115  
         public MethodFilter( String requestedTestMethod )
 116  0
         {
 117  0
             this.requestedTestMethod = requestedTestMethod;
 118  0
         }
 119  
 
 120  
         @Override
 121  
         public boolean shouldRun( Description description )
 122  
         {
 123  0
             for ( Description o : description.getChildren() )
 124  
             {
 125  0
                 if ( isDescriptionMatch( o ) )
 126  
                 {
 127  0
                     return true;
 128  
                 }
 129  
 
 130  
             }
 131  0
             return isDescriptionMatch( description );
 132  
         }
 133  
 
 134  
         private boolean isDescriptionMatch( Description description )
 135  
         {
 136  0
             return description.getMethodName() != null
 137  
                 && SelectorUtils.match( requestedTestMethod, description.getMethodName() );
 138  
         }
 139  
 
 140  
         @Override
 141  
         public String describe()
 142  
         {
 143  0
             return "By method" + requestedTestMethod;
 144  
         }
 145  
     }
 146  
 
 147  
     private static class GroupMatcherCategoryFilter
 148  
         extends Filter
 149  
     {
 150  
 
 151  
         private AndGroupMatcher matcher;
 152  
 
 153  
         public GroupMatcherCategoryFilter( GroupMatcher included, GroupMatcher excluded )
 154  0
         {
 155  0
             GroupMatcher invertedExclude = excluded == null ? null : new InverseGroupMatcher( excluded );
 156  0
             if ( included != null || invertedExclude != null )
 157  
             {
 158  0
                 matcher = new AndGroupMatcher();
 159  0
                 if ( included != null )
 160  
                 {
 161  0
                     matcher.addMatcher( included );
 162  
                 }
 163  
 
 164  0
                 if ( invertedExclude != null )
 165  
                 {
 166  0
                     matcher.addMatcher( invertedExclude );
 167  
                 }
 168  
             }
 169  0
         }
 170  
 
 171  
         @Override
 172  
         public boolean shouldRun( Description description )
 173  
         {
 174  0
             if ( description.getMethodName() == null || description.getTestClass() == null )
 175  
             {
 176  0
                 return shouldRun( description, null, null );
 177  
             }
 178  
             else
 179  
             {
 180  0
                 return shouldRun( description, Description.createSuiteDescription( description.getTestClass() ),
 181  
                                   description.getTestClass() );
 182  
             }
 183  
         }
 184  
 
 185  
         private Collection<Class<?>> findSuperclassCategories( Class<?> clazz )
 186  
         {
 187  0
             if ( clazz != null && clazz.getSuperclass() != null )
 188  
             {
 189  0
                 Category cat = clazz.getSuperclass().getAnnotation( Category.class );
 190  0
                 if ( cat != null )
 191  
                 {
 192  0
                     return new HashSet<Class<?>>( Arrays.asList( cat.value() ) );
 193  
                 }
 194  
                 else
 195  
                 {
 196  0
                     return findSuperclassCategories( clazz.getSuperclass() );
 197  
                 }
 198  
             }
 199  
 
 200  0
             return Collections.emptySet();
 201  
         }
 202  
 
 203  
         private boolean shouldRun( Description description, Description parent, Class<?> parentClass )
 204  
         {
 205  0
             if ( matcher == null )
 206  
             {
 207  0
                 return true;
 208  
             }
 209  
 
 210  0
             Set<Class<?>> cats = new HashSet<Class<?>>();
 211  0
             Category cat = description.getAnnotation( Category.class );
 212  0
             if ( cat != null )
 213  
             {
 214  0
                 cats.addAll( Arrays.asList( cat.value() ) );
 215  
             }
 216  
 
 217  0
             if ( parent != null )
 218  
             {
 219  0
                 cat = parent.getAnnotation( Category.class );
 220  0
                 if ( cat != null )
 221  
                 {
 222  0
                     cats.addAll( Arrays.asList( cat.value() ) );
 223  
                 }
 224  
             }
 225  
 
 226  0
             if ( parentClass != null )
 227  
             {
 228  0
                 cats.addAll( findSuperclassCategories( parentClass ) );
 229  
             }
 230  
 
 231  0
             boolean result = matcher.enabled( cats.toArray( new Class<?>[] {} ) );
 232  
 
 233  0
             if ( parent == null )
 234  
             {
 235  0
                 if ( cats.size() == 0 )
 236  
                 {
 237  0
                     result = true;
 238  
                 }
 239  0
                 else if ( !result )
 240  
                 {
 241  0
                     ArrayList<Description> children = description.getChildren();
 242  0
                     if ( children != null )
 243  
                     {
 244  0
                         for ( Description child : children )
 245  
                         {
 246  0
                             if ( shouldRun( child, description, null ) )
 247  
                             {
 248  0
                                 result = true;
 249  0
                                 break;
 250  
                             }
 251  
                         }
 252  
                     }
 253  
                 }
 254  
             }
 255  
 
 256  0
             return result;
 257  
         }
 258  
 
 259  
         @Override
 260  
         public String describe()
 261  
         {
 262  0
             return matcher == null ? "ANY" : matcher.toString();
 263  
         }
 264  
 
 265  
     }
 266  
 
 267  
     private static class AndFilter
 268  
         extends Filter
 269  
     {
 270  
         private final Filter filter1;
 271  
 
 272  
         private final Filter filter2;
 273  
 
 274  
         public AndFilter( Filter filter1, Filter filter2 )
 275  0
         {
 276  0
             this.filter1 = filter1;
 277  0
             this.filter2 = filter2;
 278  0
         }
 279  
 
 280  
         @Override
 281  
         public boolean shouldRun( Description description )
 282  
         {
 283  0
             return filter1.shouldRun( description ) && filter2.shouldRun( description );
 284  
         }
 285  
 
 286  
         @Override
 287  
         public String describe()
 288  
         {
 289  0
             return filter1.describe() + " AND " + filter2.describe();
 290  
         }
 291  
     }
 292  
 
 293  
     @SuppressWarnings( "unused" )
 294  
     private static class CombinedCategoryFilter
 295  
         extends Filter
 296  
     {
 297  
         private final List<Filter> includedFilters;
 298  
 
 299  
         private final List<Filter> excludedFilters;
 300  
 
 301  
         public CombinedCategoryFilter( List<Filter> includedFilters, List<Filter> excludedFilters )
 302  0
         {
 303  0
             this.includedFilters = includedFilters;
 304  0
             this.excludedFilters = excludedFilters;
 305  0
         }
 306  
 
 307  
         @Override
 308  
         public boolean shouldRun( Description description )
 309  
         {
 310  0
             return ( includedFilters.isEmpty() || inOneOfFilters( includedFilters, description ) )
 311  
                 && ( excludedFilters.isEmpty() || !inOneOfFilters( excludedFilters, description ) );
 312  
         }
 313  
 
 314  
         private boolean inOneOfFilters( List<Filter> filters, Description description )
 315  
         {
 316  0
             for ( Filter f : filters )
 317  
             {
 318  0
                 if ( f.shouldRun( description ) )
 319  
                 {
 320  0
                     return true;
 321  
                 }
 322  
             }
 323  0
             return false;
 324  
         }
 325  
 
 326  
         @Override
 327  
         public String describe()
 328  
         {
 329  0
             StringBuilder sb = new StringBuilder();
 330  0
             if ( !includedFilters.isEmpty() )
 331  
             {
 332  0
                 sb.append( "(" );
 333  0
                 sb.append( joinFilters( includedFilters, " OR " ) );
 334  0
                 sb.append( ")" );
 335  0
                 if ( !excludedFilters.isEmpty() )
 336  
                 {
 337  0
                     sb.append( " AND " );
 338  
                 }
 339  
             }
 340  0
             if ( !excludedFilters.isEmpty() )
 341  
             {
 342  0
                 sb.append( "NOT (" );
 343  0
                 sb.append( joinFilters( includedFilters, " OR " ) );
 344  0
                 sb.append( ")" );
 345  
             }
 346  
 
 347  0
             return sb.toString();
 348  
         }
 349  
 
 350  
         private String joinFilters( List<Filter> filters, String sep )
 351  
         {
 352  0
             int i = 0;
 353  0
             StringBuilder sb = new StringBuilder();
 354  0
             for ( Filter f : filters )
 355  
             {
 356  0
                 if ( i++ > 0 )
 357  
                 {
 358  0
                     sb.append( sep );
 359  
                 }
 360  0
                 sb.append( f.describe() );
 361  
             }
 362  0
             return sb.toString();
 363  
         }
 364  
     }
 365  
 
 366  
 }