Home | History | Annotate | Download | only in local
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 package org.chromium.testing.local;
      6 
      7 import org.junit.runner.Description;
      8 import org.junit.runner.manipulation.Filter;
      9 
     10 import java.util.HashSet;
     11 import java.util.Set;
     12 import java.util.regex.Pattern;
     13 
     14 /**
     15  *  Filters tests based on a googletest-style filter string.
     16  */
     17 class GtestFilter extends Filter {
     18 
     19     private final String mFilterString;
     20 
     21     private final Set<Pattern> mPositiveRegexes;
     22     private final Set<Pattern> mNegativeRegexes;
     23 
     24     private static final Pattern ASTERISK = Pattern.compile("\\*");
     25     private static final Pattern COLON = Pattern.compile(":");
     26     private static final Pattern DASH = Pattern.compile("-");
     27     private static final Pattern PERIOD = Pattern.compile("\\.");
     28 
     29     /**
     30      *  Creates the filter and converts the provided googletest-style filter
     31      *  string into positive and negative regexes.
     32      */
     33     public GtestFilter(String filterString) {
     34         mFilterString = filterString;
     35         mPositiveRegexes = new HashSet<Pattern>();
     36         mNegativeRegexes = new HashSet<Pattern>();
     37 
     38         String[] filterStrings = COLON.split(filterString);
     39         for (String f : filterStrings) {
     40             if (f.isEmpty()) continue;
     41 
     42             String sanitized = PERIOD.matcher(f).replaceAll("\\\\.");
     43             sanitized = ASTERISK.matcher(sanitized).replaceAll(".*");
     44             int negIndex = sanitized.indexOf('-');
     45             if (negIndex == 0) {
     46                 mNegativeRegexes.add(Pattern.compile(sanitized.substring(1)));
     47             } else if (negIndex != -1) {
     48                 String[] c = DASH.split(sanitized, 2);
     49                 mPositiveRegexes.add(Pattern.compile(c[0]));
     50                 mNegativeRegexes.add(Pattern.compile(c[1]));
     51             } else {
     52                 mPositiveRegexes.add(Pattern.compile(sanitized));
     53             }
     54         }
     55     }
     56 
     57     /**
     58      *  Determines whether or not a test with the provided description should
     59      *  run based on the configured positive and negative regexes.
     60      *
     61      *  A test should run if:
     62      *    - it's just a class, OR
     63      *    - it doesn't match any of the negative regexes, AND
     64      *    - either:
     65      *      - there are no configured positive regexes, OR
     66      *      - it matches at least one of the positive regexes.
     67      */
     68     @Override
     69     public boolean shouldRun(Description description) {
     70         if (description.getMethodName() == null) return true;
     71 
     72         String gtestName = description.getClassName() + "." + description.getMethodName();
     73         for (Pattern p : mNegativeRegexes) {
     74             if (p.matcher(gtestName).matches()) return false;
     75         }
     76 
     77         if (mPositiveRegexes.isEmpty()) return true;
     78 
     79         for (Pattern p : mPositiveRegexes) {
     80             if (p.matcher(gtestName).matches()) return true;
     81         }
     82 
     83         return false;
     84     }
     85 
     86     /**
     87      *  Returns a description of this filter.
     88      */
     89     @Override
     90     public String describe() {
     91         return "gtest-filter: " + mFilterString;
     92     }
     93 
     94 }
     95 
     96