diff --git a/.github/workflows/dist.yml b/.github/workflows/dist.yml index 9db0a53..218ce61 100644 --- a/.github/workflows/dist.yml +++ b/.github/workflows/dist.yml @@ -81,7 +81,7 @@ jobs: run: python setup.py bdist_wheel - name: Install test dependencies - run: python -m pip --disable-pip-version-check install pytest + run: python -m pip --disable-pip-version-check install pytest pcpp - name: Test wheel shell: bash diff --git a/cxxheaderparser/gentest.py b/cxxheaderparser/gentest.py index b192cea..ace24d7 100644 --- a/cxxheaderparser/gentest.py +++ b/cxxheaderparser/gentest.py @@ -6,6 +6,7 @@ import subprocess import typing from .errors import CxxParseError +from .preprocessor import make_pcpp_preprocessor from .options import ParserOptions from .simple import parse_string, ParsedData @@ -49,14 +50,23 @@ def nondefault_repr(data: ParsedData) -> str: return _inner_repr(data) -def gentest(infile: str, name: str, outfile: str, verbose: bool, fail: bool) -> None: +def gentest( + infile: str, name: str, outfile: str, verbose: bool, fail: bool, pcpp: bool +) -> None: # Goal is to allow making a unit test as easy as running this dumper # on a file and copy/pasting this into a test with open(infile, "r") as fp: content = fp.read() + maybe_options = "" + popt = "" + options = ParserOptions(verbose=verbose) + if options: + options.preprocessor = make_pcpp_preprocessor() + maybe_options = "options = ParserOptions(preprocessor=make_pcpp_preprocessor())" + popt = ", options=options" try: data = parse_string(content, options=options) @@ -74,15 +84,17 @@ def gentest(infile: str, name: str, outfile: str, verbose: bool, fail: bool) -> if not fail: stmt = nondefault_repr(data) stmt = f""" - data = parse_string(content, cleandoc=True) + {maybe_options} + data = parse_string(content, cleandoc=True{popt}) assert data == {stmt} """ else: stmt = f""" + {maybe_options} err = {repr(err)} with pytest.raises(CxxParseError, match=re.escape(err)): - parse_string(content, cleandoc=True) + parse_string(content, cleandoc=True{popt}) """ content = ("\n" + content.strip()).replace("\n", "\n ") @@ -113,6 +125,7 @@ if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("header") parser.add_argument("name", nargs="?", default="TODO") + parser.add_argument("--pcpp", default=False, action="store_true") parser.add_argument("-v", "--verbose", default=False, action="store_true") parser.add_argument("-o", "--output", default="-") parser.add_argument( @@ -120,4 +133,4 @@ if __name__ == "__main__": ) args = parser.parse_args() - gentest(args.header, args.name, args.output, args.verbose, args.fail) + gentest(args.header, args.name, args.output, args.verbose, args.fail, args.pcpp) diff --git a/tests/test_preprocessor.py b/tests/test_preprocessor.py new file mode 100644 index 0000000..35ed0ab --- /dev/null +++ b/tests/test_preprocessor.py @@ -0,0 +1,27 @@ +from cxxheaderparser.options import ParserOptions +from cxxheaderparser.preprocessor import make_pcpp_preprocessor +from cxxheaderparser.simple import NamespaceScope, ParsedData, parse_string +from cxxheaderparser.types import FundamentalSpecifier, NameSpecifier, PQName, Token, Type, Value, Variable + + +def test_basic_preprocessor() -> None: + content = """ + #define X 1 + int x = X; + """ + options = ParserOptions(preprocessor=make_pcpp_preprocessor()) + data = parse_string(content, cleandoc=True, options=options) + + assert data == ParsedData( + namespace=NamespaceScope( + variables=[ + Variable( + name=PQName(segments=[NameSpecifier(name="x")]), + type=Type( + typename=PQName(segments=[FundamentalSpecifier(name="int")]) + ), + value=Value(tokens=[Token(value="1")]), + ) + ] + ) + ) \ No newline at end of file