blob: 22c0e1d7660ada917fd61fd2aa51f81475d11728 [file] [log] [blame]
#!/usr/bin/env python
# Copyright (c) 2018 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Reads lines from files or stdin and identifies C++ tests.
Outputs a filter that can be used with --gtest_filter to run only the tests
Outputs filter for all test fixtures in a directory. --class-only avoids an
overly long filter string.
> cat components/mycomp/** | --class-only
Outputs filter for all tests in a file.
> ./
Outputs filter for only test at line 123
> --line=123 ./
import argparse
import fileinput
import re
import sys
parser = argparse.ArgumentParser()
parser.add_argument('--line', type=int)
parser.add_argument('--class-only', action='store_true')
args, left = parser.parse_known_args()
file_input = fileinput.input(left)
if args.line:
# If --line is used, restrict text to a few lines around the requested
# line.
requested_line = args.line
selected_lines = []
for line in file_input:
if (fileinput.lineno() >= requested_line and
fileinput.lineno() <= requested_line + 1):
txt = ''.join(selected_lines)
txt = ''.join(list(file_input))
# This regex is not exhaustive, and should be updated as needed.
rx = re.compile(
flags=re.DOTALL | re.M)
tests = []
for m in rx.finditer(txt):
tests.append( + '.' +
# Note: Test names have the following structures:
# * FixtureName.TestName
# * InstantiationName/FixtureName.TestName/##
# Since this script doesn't parse instantiations, we generate filters to match
# either regular tests or instantiated tests.
if args.class_only:
fixtures = set([t.split('.')[0] for t in tests])
test_filters = [c + '.*' for c in fixtures]
instantiation_filters = ['*/' + c + '.*/*' for c in fixtures]
print ':'.join(test_filters + instantiation_filters)
instantiations = ['*/' + c + '/*' for c in tests]
print ':'.join(tests + instantiations)