blob: 4a6b320670bbc3043445d55ca06bf86864804311 [file] [log] [blame]
Dan Harrington238d3392018-10-19 20:14:531#!/usr/bin/env python
2# Copyright (c) 2018 The Chromium Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5"""Reads lines from files or stdin and identifies C++ tests.
6
7Outputs a filter that can be used with --gtest_filter to run only the tests
8identified.
9
10Usage:
11
12Outputs filter for all test fixtures in a directory. --class-only avoids an
13overly long filter string.
14> cat components/mycomp/**test.cc | make-gtest-filter.py --class-only
15
16Outputs filter for all tests in a file.
17> make-gtest-filter.py ./myfile_unittest.cc
18
19Outputs filter for only test at line 123
20> make-gtest-filter.py --line=123 ./myfile_unittest.cc
21"""
22
Raul Tambre26d7db42019-09-25 11:06:3523from __future__ import print_function
24
Dan Harrington238d3392018-10-19 20:14:5325import argparse
26import fileinput
27import re
28import sys
29
30parser = argparse.ArgumentParser()
31parser.add_argument('--line', type=int)
32parser.add_argument('--class-only', action='store_true')
33args, left = parser.parse_known_args()
34file_input = fileinput.input(left)
35
36if args.line:
37 # If --line is used, restrict text to a few lines around the requested
38 # line.
39 requested_line = args.line
40 selected_lines = []
41 for line in file_input:
42 if (fileinput.lineno() >= requested_line and
43 fileinput.lineno() <= requested_line + 1):
44 selected_lines.append(line)
45 txt = ''.join(selected_lines)
46else:
47 txt = ''.join(list(file_input))
48
49# This regex is not exhaustive, and should be updated as needed.
50rx = re.compile(
51 r'^(?:TYPED_)?(?:IN_PROC_BROWSER_)?TEST(_F|_P)?\(\s*(\w+)\s*,\s*(\w+)\s*\)',
52 flags=re.DOTALL | re.M)
53tests = []
54for m in rx.finditer(txt):
55 tests.append(m.group(2) + '.' + m.group(3))
56
57# Note: Test names have the following structures:
58# * FixtureName.TestName
59# * InstantiationName/FixtureName.TestName/##
60# Since this script doesn't parse instantiations, we generate filters to match
61# either regular tests or instantiated tests.
62if args.class_only:
63 fixtures = set([t.split('.')[0] for t in tests])
64 test_filters = [c + '.*' for c in fixtures]
65 instantiation_filters = ['*/' + c + '.*/*' for c in fixtures]
Raul Tambre26d7db42019-09-25 11:06:3566 print(':'.join(test_filters + instantiation_filters))
Dan Harrington238d3392018-10-19 20:14:5367else:
68 instantiations = ['*/' + c + '/*' for c in tests]
Raul Tambre26d7db42019-09-25 11:06:3569 print(':'.join(tests + instantiations))