1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
|
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.
import os
import os.path
import libcst.codegen.gen_matcher_classes as matcher_codegen
import libcst.codegen.gen_type_mapping as type_codegen
import libcst.codegen.gen_visitor_functions as visitor_codegen
from libcst.codegen.generate import clean_generated_code, format_file
from libcst.testing.utils import UnitTest
class TestCodegenClean(UnitTest):
def assert_code_matches(
self,
old_code: str,
new_code: str,
module_name: str,
) -> None:
self.assertTrue(
old_code == new_code,
f"{module_name} needs new codegen, see "
+ "`python -m libcst.codegen.generate --help` "
+ "for instructions, or run `python -m libcst.codegen.generate all`",
)
def test_codegen_clean_visitor_functions(self) -> None:
"""
Verifies that codegen of visitor functions would not result in a
changed file. If this test fails, please run 'python -m libcst.codegen.generate all'
to generate new files.
"""
new_code = clean_generated_code("\n".join(visitor_codegen.generated_code))
new_file = os.path.join(
os.path.dirname(os.path.abspath(__file__)), "visitor_codegen.deleteme.py"
)
with open(new_file, "w") as fp:
fp.write(new_code)
try:
format_file(new_file)
except Exception:
# We failed to format, but this is probably due to invalid code that
# black doesn't like. This test will still fail and report to run codegen.
pass
with open(new_file, "r") as fp:
new_code = fp.read()
os.remove(new_file)
with open(
os.path.join(
os.path.dirname(os.path.abspath(__file__)), "../../_typed_visitor.py"
),
"r",
) as fp:
old_code = fp.read()
# Now that we've done simple codegen, verify that it matches.
self.assert_code_matches(old_code, new_code, "libcst._typed_visitor")
def test_codegen_clean_matcher_classes(self) -> None:
"""
Verifies that codegen of matcher classes would not result in a
changed file. If this test fails, please run 'python -m libcst.codegen.generate all'
to generate new files.
"""
new_code = clean_generated_code("\n".join(matcher_codegen.generated_code))
new_file = os.path.join(
os.path.dirname(os.path.abspath(__file__)), "matcher_codegen.deleteme.py"
)
with open(new_file, "w") as fp:
fp.write(new_code)
try:
format_file(new_file)
except Exception:
# We failed to format, but this is probably due to invalid code that
# black doesn't like. This test will still fail and report to run codegen.
pass
with open(new_file, "r") as fp:
new_code = fp.read()
os.remove(new_file)
with open(
os.path.join(
os.path.dirname(os.path.abspath(__file__)), "../../matchers/__init__.py"
),
"r",
) as fp:
old_code = fp.read()
# Now that we've done simple codegen, verify that it matches.
self.assert_code_matches(old_code, new_code, "libcst.matchers.__init__")
def test_codegen_clean_return_types(self) -> None:
"""
Verifies that codegen of return types would not result in a
changed file. If this test fails, please run 'python -m libcst.codegen.generate all'
to generate new files.
"""
new_code = clean_generated_code("\n".join(type_codegen.generated_code))
new_file = os.path.join(
os.path.dirname(os.path.abspath(__file__)), "type_codegen.deleteme.py"
)
with open(new_file, "w") as fp:
fp.write(new_code)
try:
format_file(new_file)
except Exception:
# We failed to format, but this is probably due to invalid code that
# black doesn't like. This test will still fail and report to run codegen.
pass
with open(new_file, "r") as fp:
new_code = fp.read()
os.remove(new_file)
with open(
os.path.join(
os.path.dirname(os.path.abspath(__file__)),
"../../matchers/_return_types.py",
),
"r",
) as fp:
old_code = fp.read()
# Now that we've done simple codegen, verify that it matches.
self.assert_code_matches(old_code, new_code, "libcst.matchers._return_types")
|