1#!/usr/bin/env python3
2#
3# Copyright (C) 2024 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#      http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
17""" A tool to rewrite source files to turn individual tests that run in main()
18into gtests"""
19
20import argparse
21import os
22from pathlib import Path
23
24def parse_args() -> argparse.Namespace:
25  """Parse commandline arguments."""
26
27  parser = argparse.ArgumentParser()
28  parser.add_argument('--suite', help='specify test suite name')
29  parser.add_argument('--test_name_prefix', help='specify test name prefix')
30  parser.add_argument('--main_no_arguments', action='store_true',
31                      help='standalone test main function is declared with no arguments')
32  parser.add_argument('--predicate', default='NULL',
33                      help='name of function that converts return value of main to boolean pass signal')
34  parser.add_argument('--in', required=True, dest='in_path', type=Path,
35                      help='specify the input file')
36  parser.add_argument('--out', required=True, dest='out_path', type=Path,
37                      help='specify the output file')
38  return parser.parse_args()
39
40
41def rewrite_test_src(in_path: Path, out_path: Path, suite_name: str,
42                     test_name: str, main_no_arguments: bool, predicate: str):
43  with open(out_path, 'w', encoding='utf8') as out_file:
44    with open(in_path, encoding='utf8') as in_file:
45      out_file.write('// Automatically inserted by gtestifier\n')
46      out_file.write('#ifndef GTESTIFIER_TEST\n')
47      if suite_name:
48        out_file.write(f'#define GTESTIFIER_SUITE {suite_name}\n')
49        out_file.write(f'#define GTESTIFIER_TEST {test_name}\n')
50        out_file.write(f'#define GTESTIFIER_MAIN_NO_ARGUMENTS {int(main_no_arguments)}\n')
51        out_file.write(f'#define GTESTIFIER_PREDICATE {predicate}\n')
52        out_file.write('#include <gtestifier.h>\n')
53        out_file.write('#endif\n')
54        out_file.write('// End automatically inserted by gtestifier\n')
55        out_file.write('\n')
56        out_file.write(in_file.read())
57
58
59def path_to_test_name(in_path: Path, test_name_prefix: str):
60  name = ''.join([c for c in in_path.stem if c == '_' or str.isalnum(c)])
61  return test_name_prefix + name
62
63
64def main():
65  """Program entry point."""
66  args = parse_args()
67
68  rewrite_test_src(args.in_path, args.out_path, args.suite,
69                   path_to_test_name(args.in_path, args.test_name_prefix),
70                   args.main_no_arguments, args.predicate)
71
72
73if __name__ == '__main__':
74  main()
75