mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-05 14:51:06 +00:00
A Linux job configures without the precompiled header and runs clang-tidy over the C++ lines a pull request changes. The only check for now is misc-include-cleaner for missing includes; .clang-tidy is where further checks get enabled. scripts/run_clang_tidy.sh (Linux, macOS) and scripts/run_clang_tidy.ps1 (Windows) run the same check locally: the same configure, the clang-tidy version pinned in scripts/clang_tidy_requirements.txt, and the same comparison against OrcaSlicer's main. They offer to install what is missing, or print the command to do it by hand.
133 lines
4.7 KiB
Python
133 lines
4.7 KiB
Python
#!/usr/bin/env python3
|
|
"""Tests for the diff handling in scripts/clang_tidy_diff.py (stdlib unittest, no
|
|
external deps).
|
|
|
|
Run from the repo root: python -m unittest discover -s scripts/tests -v
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
import tempfile
|
|
import unittest
|
|
|
|
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
|
|
|
|
import clang_tidy_diff # noqa: E402
|
|
|
|
DIFF = """\
|
|
diff --git a/src/libslic3r/Color.cpp b/src/libslic3r/Color.cpp
|
|
index 1111111..2222222 100644
|
|
--- a/src/libslic3r/Color.cpp
|
|
+++ b/src/libslic3r/Color.cpp
|
|
@@ -3,0 +4 @@
|
|
+#include <cassert>
|
|
@@ -8 +8,0 @@
|
|
-#include "libslic3r/Point.hpp"
|
|
@@ -20,2 +21,3 @@ void f()
|
|
- old();
|
|
- old();
|
|
+ a();
|
|
+ b();
|
|
+ c();
|
|
@@ -40 +42,0 @@ void g()
|
|
- gone();
|
|
diff --git a/src/libslic3r/New.hpp b/src/libslic3r/New.hpp
|
|
new file mode 100644
|
|
--- /dev/null
|
|
+++ b/src/libslic3r/New.hpp
|
|
@@ -0,0 +1,2 @@
|
|
+#pragma once
|
|
+int f();
|
|
diff --git a/src/libslic3r/Old.cpp b/src/libslic3r/Renamed.cpp
|
|
similarity index 100%
|
|
rename from src/libslic3r/Old.cpp
|
|
rename to src/libslic3r/Renamed.cpp
|
|
"""
|
|
|
|
|
|
class TestParseChangedLines(unittest.TestCase):
|
|
def setUp(self):
|
|
self.changed = clang_tidy_diff.parse_diff(DIFF)
|
|
|
|
def test_added_and_replaced_hunks_become_line_ranges(self):
|
|
self.assertEqual(self.changed["src/libslic3r/Color.cpp"].lines, [[4, 4], [21, 23]])
|
|
|
|
def test_deleted_includes_are_collected(self):
|
|
self.assertEqual(self.changed["src/libslic3r/Color.cpp"].removed_includes, {"libslic3r/Point.hpp"})
|
|
self.assertEqual(self.changed["src/libslic3r/New.hpp"].removed_includes, set())
|
|
|
|
def test_new_file_covers_every_line(self):
|
|
self.assertEqual(self.changed["src/libslic3r/New.hpp"].lines, [[1, 2]])
|
|
|
|
def test_pure_rename_has_no_changed_lines(self):
|
|
self.assertNotIn("src/libslic3r/Renamed.cpp", self.changed)
|
|
|
|
|
|
class TestNamesRemovedInclude(unittest.TestCase):
|
|
def test_matches_however_the_include_was_spelled(self):
|
|
removed = {"Point.hpp", "cassert"}
|
|
self.assertTrue(clang_tidy_diff.names_removed_include("<cassert>", removed))
|
|
self.assertTrue(clang_tidy_diff.names_removed_include("<libslic3r/Point.hpp>", removed))
|
|
self.assertTrue(clang_tidy_diff.names_removed_include('"Point.hpp"', {"libslic3r/Point.hpp"}))
|
|
|
|
def test_other_headers_and_no_suggestion_do_not_match(self):
|
|
removed = {"libslic3r/Point.hpp"}
|
|
self.assertFalse(clang_tidy_diff.names_removed_include("<libslic3r/MultiPoint.hpp>", removed))
|
|
self.assertFalse(clang_tidy_diff.names_removed_include("<vector>", removed))
|
|
self.assertFalse(clang_tidy_diff.names_removed_include("", removed))
|
|
|
|
|
|
class TestIsChecked(unittest.TestCase):
|
|
def test_project_sources_and_headers(self):
|
|
for path in ("src/libslic3r/Color.cpp", "src/slic3r/GUI/Tab.hpp", "tests/fff_print/test_flow.cpp",
|
|
"src/libslic3r/Format/bbs_3mf.h"):
|
|
self.assertTrue(clang_tidy_diff.is_checked(path), path)
|
|
|
|
def test_vendored_code_other_languages_and_other_dirs(self):
|
|
for path in ("src/glad/src/gl.c", "src/glad/include/glad/gl.h", "tests/catch2/src/catch.hpp",
|
|
"deps_src/imgui/imgui.cpp", "src/slic3r/Utils/MacUtils.mm", "src/CMakeLists.txt"):
|
|
self.assertFalse(clang_tidy_diff.is_checked(path), path)
|
|
|
|
|
|
FIXES = """\
|
|
---
|
|
MainSourceFile: '/repo/src/libslic3r/Color.cpp'
|
|
Diagnostics:
|
|
- DiagnosticName: misc-include-cleaner
|
|
DiagnosticMessage:
|
|
Message: 'no header providing "assert" is directly included'
|
|
FilePath: '/repo/src/libslic3r/Color.cpp'
|
|
FileOffset: 1974
|
|
Replacements:
|
|
- FilePath: '/repo/src/libslic3r/Color.cpp'
|
|
Offset: 39
|
|
Length: 0
|
|
ReplacementText: "#include <cassert>\\n"
|
|
Level: Error
|
|
- DiagnosticName: misc-include-cleaner
|
|
DiagnosticMessage:
|
|
Message: 'no header providing "Slic3r::comExpert" is directly included'
|
|
FilePath: '/repo/src/libslic3r/Color.cpp'
|
|
FileOffset: 2148
|
|
Replacements: []
|
|
Level: Error
|
|
...
|
|
"""
|
|
|
|
|
|
class TestParseSuggestedIncludes(unittest.TestCase):
|
|
def test_maps_each_message_to_the_include_its_fix_inserts(self):
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
path = os.path.join(tmp, "fixes.yaml")
|
|
with open(path, "w", encoding="utf-8") as f:
|
|
f.write(FIXES)
|
|
self.assertEqual(clang_tidy_diff.parse_suggested_includes(path),
|
|
{'no header providing "assert" is directly included': "<cassert>"})
|
|
|
|
def test_missing_file_means_no_suggestions(self):
|
|
self.assertEqual(clang_tidy_diff.parse_suggested_includes("/nonexistent/fixes.yaml"), {})
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|