Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,18 @@ if(BUILD_TESTING)
${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_performance_csv.py)
set_tests_properties(performance_csv PROPERTIES TIMEOUT 20)
add_test(NAME conventions_wrapped_declarations COMMAND ${Python3_EXECUTABLE}
${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_check_conventions_wrapped_declarations.py)
${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_check_conventions_wrapped_declarations.py WrappedDeclarationTests)
set_tests_properties(conventions_wrapped_declarations PROPERTIES TIMEOUT 30)
set(conventions_wrapped_declarations_source "${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_check_conventions_wrapped_declarations.py")
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${conventions_wrapped_declarations_source}")
file(STRINGS "${conventions_wrapped_declarations_source}" conventions_wrapped_declarations_classes REGEX "^class [A-Za-z0-9_]*Tests\\(")
foreach(test_class IN LISTS conventions_wrapped_declarations_classes)
string(REGEX REPLACE "^class ([A-Za-z0-9_]+).*" "\\1" test_class "${test_class}")
if(NOT test_class STREQUAL "WrappedDeclarationTests")
add_test(NAME conventions_wrapped_declarations_${test_class} COMMAND ${Python3_EXECUTABLE} "${conventions_wrapped_declarations_source}" ${test_class})
set_tests_properties(conventions_wrapped_declarations_${test_class} PROPERTIES TIMEOUT 30)
endif()
endforeach()
add_test(NAME conventions_ci_gate COMMAND ${Python3_EXECUTABLE}
${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_check_conventions_ci_gate.py)
add_test(NAME preview_pad_timeline COMMAND ${Python3_EXECUTABLE}
Expand Down
72 changes: 38 additions & 34 deletions tools/tests/test_check_conventions_wrapped_declarations.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
DEFINITION = "int APS5_VABI sceFooBar(int a, int b) { return a + b; }\n"


class WrappedDeclarationTests(unittest.TestCase):
class WrappedDeclarationFixture(unittest.TestCase):
def check(self, first_file, first_text, second_text=DEFINITION):
with tempfile.TemporaryDirectory() as directory:
root = Path(directory)
Expand Down Expand Up @@ -45,6 +45,8 @@ def git(*args):
cwd=root, capture_output=True, text=True, env=env, timeout=20,
)


class WrappedDeclarationTests(WrappedDeclarationFixture):
def test_wrapped_declaration_is_not_a_duplicate(self):
result = self.check("Export.h", "int APS5_VABI sceFooBar(int a,\n int b);\n")
self.assertNotIn("duplicate-export", result.stdout, result.stdout + result.stderr)
Expand All @@ -66,6 +68,41 @@ def test_wrapped_definition_is_a_duplicate(self):
self.assertEqual(result.returncode, 1, result.stdout + result.stderr)
self.assertIn("[duplicate-export]", result.stdout)

def test_multiline_raw_literal_is_not_a_duplicate(self):
source = 'const char* example = R"example(\n' + DEFINITION + ')example";\n'
result = self.check("Export.cpp", source)
self.assertEqual(result.returncode, 0, result.stdout + result.stderr)
self.assertNotIn("[duplicate-export]", result.stdout)

def test_block_comment_is_not_a_duplicate(self):
result = self.check("Export.cpp", "/*\n" + DEFINITION + "*/\n")
self.assertEqual(result.returncode, 0, result.stdout + result.stderr)
self.assertNotIn("[duplicate-export]", result.stdout)

def test_literal_before_unrelated_export_is_not_a_duplicate(self):
source = 'const char* example = "APS5_VABI sceFooBar()"; int APS5_VABI sceOther() { return 1; }\n'
result = self.check("Export.cpp", source)
self.assertEqual(result.returncode, 0, result.stdout + result.stderr)
self.assertNotIn("[duplicate-export]", result.stdout)

def test_line_comment_before_definition_is_not_a_duplicate(self):
result = self.check("Export.cpp", "// " + DEFINITION + "int unrelated() { return 42; }\n")
self.assertEqual(result.returncode, 0, result.stdout + result.stderr)
self.assertNotIn("[duplicate-export]", result.stdout)

def test_definition_after_unicode_raw_literal_is_a_duplicate(self):
source = 'const char* text = R"text(first\u2028+middle\u2029+last)text";\n' + DEFINITION
result = self.check("Export.cpp", source)
self.assertEqual(result.returncode, 1, result.stdout + result.stderr)
self.assertIn("[duplicate-export]", result.stdout)

def test_definition_after_commented_example_is_a_duplicate(self):
result = self.check("Export.cpp", "/*\n" + DEFINITION + "*/\n" + DEFINITION)
self.assertEqual(result.returncode, 1, result.stdout + result.stderr)
self.assertEqual(result.stdout.count("[duplicate-export]"), 1, result.stdout)


class AbiAliasTests(WrappedDeclarationFixture):
def test_local_abi_alias_cannot_hide_duplicates_in_either_library(self):
aliased = "#define NATIVE_SYSV APS5_VABI\n" + DEFINITION.replace("APS5_VABI", "NATIVE_SYSV")
for first, second in ((aliased, DEFINITION), (DEFINITION, aliased), (aliased, aliased)):
Expand Down Expand Up @@ -117,39 +154,6 @@ def test_unique_aliased_definition_and_unpatched_helpers_remain_valid(self):
result = self.check("Export.cpp", source, source if name.startswith("Support") else DEFINITION)
self.assertEqual(result.returncode, 0, result.stdout + result.stderr)

def test_multiline_raw_literal_is_not_a_duplicate(self):
source = 'const char* example = R"example(\n' + DEFINITION + ')example";\n'
result = self.check("Export.cpp", source)
self.assertEqual(result.returncode, 0, result.stdout + result.stderr)
self.assertNotIn("[duplicate-export]", result.stdout)

def test_block_comment_is_not_a_duplicate(self):
result = self.check("Export.cpp", "/*\n" + DEFINITION + "*/\n")
self.assertEqual(result.returncode, 0, result.stdout + result.stderr)
self.assertNotIn("[duplicate-export]", result.stdout)

def test_literal_before_unrelated_export_is_not_a_duplicate(self):
source = 'const char* example = "APS5_VABI sceFooBar()"; int APS5_VABI sceOther() { return 1; }\n'
result = self.check("Export.cpp", source)
self.assertEqual(result.returncode, 0, result.stdout + result.stderr)
self.assertNotIn("[duplicate-export]", result.stdout)

def test_line_comment_before_definition_is_not_a_duplicate(self):
result = self.check("Export.cpp", "// " + DEFINITION + "int unrelated() { return 42; }\n")
self.assertEqual(result.returncode, 0, result.stdout + result.stderr)
self.assertNotIn("[duplicate-export]", result.stdout)

def test_definition_after_unicode_raw_literal_is_a_duplicate(self):
source = 'const char* text = R"text(first\u2028+middle\u2029+last)text";\n' + DEFINITION
result = self.check("Export.cpp", source)
self.assertEqual(result.returncode, 1, result.stdout + result.stderr)
self.assertIn("[duplicate-export]", result.stdout)

def test_definition_after_commented_example_is_a_duplicate(self):
result = self.check("Export.cpp", "/*\n" + DEFINITION + "*/\n" + DEFINITION)
self.assertEqual(result.returncode, 1, result.stdout + result.stderr)
self.assertEqual(result.stdout.count("[duplicate-export]"), 1, result.stdout)


if __name__ == "__main__":
unittest.main()
Loading