fix(tools): preserve function bodies after line comments
This commit is contained in:
parent
d70b899894
commit
a00559a222
|
|
@ -43,6 +43,8 @@ if(BUILD_TESTING)
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_progress.py)
|
||||
add_test(NAME import_audit COMMAND ${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_import_audit.py)
|
||||
add_test(NAME conventions_function_bodies COMMAND ${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_check_conventions_comments.py)
|
||||
add_test(NAME hardware_oracle COMMAND ${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tools/hw-oracle/test_hw_oracle.py)
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -216,7 +216,7 @@ def allowed_notes(path):
|
|||
|
||||
def function_body(lines, start):
|
||||
text = "\n".join(lines[start:start + 400])
|
||||
text = re.sub(r"//.*|/\*.*?\*/", "", STRINGS.sub('""', text), flags=re.S)
|
||||
text = re.sub(r"//[^\r\n]*|/\*.*?\*/", "", STRINGS.sub('""', text), flags=re.S)
|
||||
brace, semicolon = text.find("{"), text.find(";")
|
||||
if brace < 0 or 0 <= semicolon < brace:
|
||||
return None
|
||||
|
|
|
|||
|
|
@ -0,0 +1,86 @@
|
|||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
|
||||
from check_conventions import STUB_BODY, function_body
|
||||
|
||||
|
||||
class FunctionBodyTests(unittest.TestCase):
|
||||
def test_line_comments_preserve_following_statements(self):
|
||||
sources = (
|
||||
"int APS5_VABI sceExample() {\n// pending implementation\nreturn 0;\n}",
|
||||
"int APS5_VABI sceExample() // pending implementation\n{\nreturn 0;\n}",
|
||||
"int APS5_VABI sceExample() {\n(void)arg; // unused argument\nreturn 0;\n}",
|
||||
"int APS5_VABI sceExample() {\n// ignored } ; { tokens\nreturn 0;\n}",
|
||||
)
|
||||
for source in sources:
|
||||
with self.subTest(source=source):
|
||||
body = function_body(source.splitlines(), 0)
|
||||
self.assertIsNotNone(body)
|
||||
self.assertIsNotNone(STUB_BODY.fullmatch(body))
|
||||
|
||||
def test_line_comment_does_not_turn_an_implementation_into_a_stub(self):
|
||||
source = "int APS5_VABI sceExample() {\n// validate the request\nvalidate();\nreturn 0;\n}"
|
||||
body = function_body(source.splitlines(), 0)
|
||||
self.assertEqual(body, "validate();return0;")
|
||||
self.assertIsNone(STUB_BODY.fullmatch(body))
|
||||
|
||||
def test_block_comments_preserve_following_statements(self):
|
||||
source = "int APS5_VABI sceExample() {\n/* pending\nimplementation */\nreturn 0;\n}"
|
||||
self.assertEqual(function_body(source.splitlines(), 0), "return0;")
|
||||
|
||||
def test_comment_markers_and_braces_in_strings_are_ignored(self):
|
||||
source = 'int APS5_VABI sceExample() {\nuse("// }", "/* { */");\nreturn 0;\n}'
|
||||
self.assertEqual(function_body(source.splitlines(), 0), 'use("","");return0;')
|
||||
|
||||
def test_declaration_has_no_body(self):
|
||||
source = "int APS5_VABI sceExample();\nint APS5_VABI sceOther() { return 0; }"
|
||||
self.assertIsNone(function_body(source.splitlines(), 0))
|
||||
|
||||
def test_unterminated_function_has_no_body(self):
|
||||
source = "int APS5_VABI sceExample() {\n// pending implementation\nreturn 0;"
|
||||
self.assertIsNone(function_body(source.splitlines(), 0))
|
||||
|
||||
|
||||
class SilentStubTests(unittest.TestCase):
|
||||
def test_commented_stub_is_reported_when_debt_change_allows_comments(self):
|
||||
checker = Path(__file__).resolve().parents[1] / "check_conventions.py"
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
root = Path(directory)
|
||||
|
||||
def git(*args):
|
||||
return subprocess.run(
|
||||
["git", "-c", "user.name=Conventions Test", "-c", "user.email=test@example.com",
|
||||
"-c", "commit.gpgsign=false", *args],
|
||||
cwd=root, capture_output=True, text=True, check=True,
|
||||
)
|
||||
|
||||
git("init", "-q")
|
||||
debt = root / "docs/dev/TechnicalDebt.md"
|
||||
debt.parent.mkdir(parents=True)
|
||||
debt.write_text("# Project technical debt\n", encoding="utf-8")
|
||||
git("add", ".")
|
||||
git("commit", "-qm", "docs: record technical debt")
|
||||
source = root / "core/libs/prx/libSceExample/Export.cpp"
|
||||
source.parent.mkdir(parents=True)
|
||||
source.write_text("int APS5_VABI sceExample() {\n// pending implementation\nreturn 0;\n}\n", encoding="utf-8")
|
||||
debt.write_text("# Project technical debt\n\nAn unrelated build limitation.\n", encoding="utf-8")
|
||||
git("add", ".")
|
||||
git("commit", "-qm", "feat: add example export")
|
||||
result = subprocess.run(
|
||||
[sys.executable, str(checker), "--base", "HEAD~1"],
|
||||
cwd=root, capture_output=True, text=True,
|
||||
env={key: value for key, value in os.environ.items()
|
||||
if key not in ("GITHUB_EVENT_PATH", "GITHUB_STEP_SUMMARY", "GITHUB_ACTIONS")},
|
||||
)
|
||||
self.assertEqual(result.returncode, 1, result.stdout + result.stderr)
|
||||
self.assertIn("[silent-stub]", result.stdout)
|
||||
self.assertNotIn("[comment]", result.stdout)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Loading…
Reference in New Issue