Repository: google/googletest
File: googletest/src/gtest.cc (C++)

Code before:
          // match one more character than the last attempt.
          pattern_next = pattern;
          name_next = name + 1;
          ++pattern;
          continue;
      }
    }
    // Failed to match a character. Restart if possible.
    if (name_begin < name_next && name_next <= name_end) {
      pattern = pattern_next;
      name = name_next;
      continue;
    }
    return false;
  }
  return true;
}

namespace {
class UnitTestFilter {
 public:
  UnitTestFilter() = default;

  // Constructs a filter form a string of patterns separated by `:`.
  explicit UnitTestFilter(const std::string& filter) {
    if (filter.empty()) return;

    SplitString(filter, ':', &patterns_);
  }

  // Returns true if and only if name matches at least one of the patterns in
  // the filter.
  bool MatchesName(const std::string& name) const {
    const auto pattern_matches_name = [&name](const std::string& pattern) {
      return PatternMatchesString(name, pattern.c_str(),
                                  pattern.c_str() + pattern.size());
    };
    return std::any_of(patterns_.begin(), patterns_.end(),
                       pattern_matches_name);
  }

 private:
  std::vector<std::string> patterns_;
};

class PositiveAndNegativeUnitTestFilter {
 public:
  // Constructs a positive and a negative filter from a string. The string
  // contains a positive filter optionally followed by a '-' character and a
  // negative filter. In case only a negative filter is provided the positive
  // filter will be assumed "*".

Review comment (suggestion):
The original implementation had the filter `""` match string `""`. Even though this was not explicitly documented, changing this behavior may cause regressions.

Removing the corner case here should fix it.

Code after:
          // match one more character than the last attempt.
          pattern_next = pattern;
          name_next = name + 1;
          ++pattern;
          continue;
      }
    }
    // Failed to match a character. Restart if possible.
    if (name_begin < name_next && name_next <= name_end) {
      pattern = pattern_next;
      name = name_next;
      continue;
    }
    return false;
  }
  return true;
}

namespace {

class UnitTestFilter {
 public:
  UnitTestFilter() = default;

  // Constructs a filter from a string of patterns separated by `:`.
  explicit UnitTestFilter(const std::string& filter) {
    // By design "" filter matches "" string.
    SplitString(filter, ':', &patterns_);
  }

  // Returns true if and only if name matches at least one of the patterns in
  // the filter.
  bool MatchesName(const std::string& name) const {
    return std::any_of(patterns_.begin(), patterns_.end(),
                       [&name](const std::string& pattern) {
                         return PatternMatchesString(
                             name, pattern.c_str(),
                             pattern.c_str() + pattern.size());
                       });
  }

 private:
  std::vector<std::string> patterns_;
};

class PositiveAndNegativeUnitTestFilter {
 public:
  // Constructs a positive and a negative filter from a string. The string
  // contains a positive filter optionally followed by a '-' character and a
  // negative filter. In case only a negative filter is provided the positive
  // filter will be assumed "*".