diff --git a/clang-tools-manager/src/downloader/pypi.rs b/clang-tools-manager/src/downloader/pypi.rs index 064af45f..5f67310e 100644 --- a/clang-tools-manager/src/downloader/pypi.rs +++ b/clang-tools-manager/src/downloader/pypi.rs @@ -613,7 +613,7 @@ const EXTRACTED_CHUNK_SIZE: u64 = 1024; mod test { use std::str::FromStr; - use super::{PlatformTag, PyPiReleaseInfo, WheelTags}; + use super::{LinuxLibC, PlatformOs, PlatformTag, PyPiReleaseInfo, WheelTags}; #[test] fn bad_json_digest() { @@ -655,4 +655,77 @@ mod test { let err = WheelTags::from_str(bad_wheel_name).unwrap_err(); println!("{}", err); } + + #[test] + fn win32_tag() { + let tag = PlatformTag::from_str("win32").unwrap(); + assert!(matches!(tag.os, PlatformOs::Windows)); + assert_eq!(tag.arch.as_str(), "x86"); + } + + #[test] + fn win_amd64_tag() { + let tag = PlatformTag::from_str("win_amd64").unwrap(); + assert!(matches!(tag.os, PlatformOs::Windows)); + assert_eq!(tag.arch.as_str(), "amd64"); + } + + #[test] + fn win_missing_arch_tag() { + // "win" prefix without an "_" suffix is malformed. + let err = PlatformTag::from_str("win").unwrap_err(); + println!("{}", err); + } + + #[test] + fn macosx_tag() { + let tag = PlatformTag::from_str("macosx_11_0_arm64").unwrap(); + assert!(matches!(tag.os, PlatformOs::MacOS)); + assert_eq!(tag.arch.as_str(), "arm64"); + } + + #[test] + fn musllinux_tag() { + let tag = PlatformTag::from_str("musllinux_1_2_x86_64").unwrap(); + assert!(matches!( + tag.os, + PlatformOs::Linux { + lib_c: LinuxLibC::Musl { .. } + } + )); + assert_eq!(tag.arch.as_str(), "x86_64"); + } + + #[test] + fn manylinux2_tag() { + let tag = PlatformTag::from_str("manylinux_2_17_x86_64").unwrap(); + assert!(matches!( + tag.os, + PlatformOs::Linux { + lib_c: LinuxLibC::Glibc { .. } + } + )); + assert_eq!(tag.arch.as_str(), "x86_64"); + } + + #[test] + fn manylinux_dotted_tag() { + // A combined tag like "manylinux_2_17_x86_64.manylinux2014_x86_64" should + // select the "manylinux_" variant from the dotted alternatives. + let tag = PlatformTag::from_str("manylinux_2_17_x86_64.manylinux2014_x86_64").unwrap(); + assert!(matches!( + tag.os, + PlatformOs::Linux { + lib_c: LinuxLibC::Glibc { .. } + } + )); + assert_eq!(tag.arch.as_str(), "x86_64"); + } + + #[test] + fn valid_wheel_tags() { + let wheel_name = "clang_format-17.0.0-py3-none-manylinux_2_17_x86_64.whl"; + let tags = WheelTags::from_str(wheel_name).unwrap(); + assert_eq!(tags.platform.arch.as_str(), "x86_64"); + } } diff --git a/cpp-linter/src/clang_tools/clang_format.rs b/cpp-linter/src/clang_tools/clang_format.rs index 0215e540..d4435129 100644 --- a/cpp-linter/src/clang_tools/clang_format.rs +++ b/cpp-linter/src/clang_tools/clang_format.rs @@ -338,6 +338,34 @@ mod tests { formalize_style("file", "Custom"); } + #[test] + fn tally_counts_only_nonempty_advice() { + use std::sync::{Arc, Mutex}; + + use super::{FormatAdvice, tally_format_advice}; + use crate::common_fs::FileObj; + + let mut with_advice = FileObj::new(std::path::PathBuf::from("demo.cpp")); + #[allow(clippy::single_range_in_vec_init)] + { + with_advice.format_advice = Some(FormatAdvice { + replacements: vec![1..=2], + }); + } + let mut empty_advice = FileObj::new(std::path::PathBuf::from("empty.cpp")); + empty_advice.format_advice = Some(FormatAdvice { + replacements: vec![], + }); + // a third file with no advice at all is also ignored + let no_advice = FileObj::new(std::path::PathBuf::from("none.cpp")); + let files = vec![ + Arc::new(Mutex::new(with_advice)), + Arc::new(Mutex::new(empty_advice)), + Arc::new(Mutex::new(no_advice)), + ]; + assert_eq!(tally_format_advice(&files).unwrap(), 1); + } + #[test] fn three_way_diff_mixed() { const OG_SRC: &str = diff --git a/cpp-linter/src/clang_tools/clang_tidy.rs b/cpp-linter/src/clang_tools/clang_tidy.rs index b5475c52..7a719680 100644 --- a/cpp-linter/src/clang_tools/clang_tidy.rs +++ b/cpp-linter/src/clang_tools/clang_tidy.rs @@ -603,6 +603,52 @@ TrenchBroom/TrenchBroom/common/test/src/mdl/tst_ReadFreeImageTexture.cpp:44:48: } } + fn dummy_note(filename: &str, fixed_lines: Vec) -> TidyNotification { + TidyNotification { + filename: filename.to_string(), + line: 5, + cols: 1, + severity: String::from("warning"), + rationale: String::from("a dummy rationale"), + diagnostic: String::from("modernize-use-auto"), + suggestion: vec![], + fixed_lines, + } + } + + #[test] + fn tally_counts_matching_notes() { + use super::{TidyAdvice, tally_tidy_advice}; + + let mut file = FileObj::new(PathBuf::from("demo.cpp")); + file.tidy_advice = Some(TidyAdvice { + notes: vec![ + // matches the file name -> counted + dummy_note("demo.cpp", vec![]), + // does not match the file name -> not counted + dummy_note("other.cpp", vec![]), + ], + }); + let files = vec![Arc::new(Mutex::new(file))]; + assert_eq!(tally_tidy_advice(&files).unwrap(), 1); + } + + #[test] + fn suggestion_help_with_and_without_fixes() { + use super::TidyAdvice; + + let advice = TidyAdvice { + notes: vec![dummy_note("demo.cpp", vec![5])], + }; + // A fixed line within the range yields a "diagnostic(s)" header plus the rationale. + let help = advice.get_suggestion_help(1, 10); + assert!(help.contains("clang-tidy diagnostic(s)")); + assert!(help.contains("a dummy rationale")); + // No fixed line within the range falls back to a plain "suggestion" header. + let help = advice.get_suggestion_help(20, 30); + assert!(help.contains("clang-tidy suggestion")); + } + #[test] fn restore_on_drop_fires() { let tmp = tempfile::tempdir().unwrap();