//! The core builds from the standard library alone. A foreign crate could //! bring floating point, hash maps or threads in through the back door. // Tests may read files. The rules of core/clippy.toml apply to core/src. #![allow(clippy::disallowed_methods)] use std::fs; use std::path::Path; /// Every manifest section that may add a dependency, with the lines it /// declares. Development dependencies are allowed, because they never reach /// the game. fn dependency_sections(manifest: &str) -> Vec<(String, Vec)> { let mut sections: Vec<(String, Vec)> = Vec::new(); let mut inside = false; for line in manifest.lines() { let line = line.trim(); if line.starts_with('[') { inside = line.contains("dependencies") && !line.contains("dev-dependencies"); if inside { sections.push((line.to_owned(), Vec::new())); } continue; } if inside && !line.is_empty() && !line.starts_with('#') { if let Some((_, entries)) = sections.last_mut() { entries.push(line.to_owned()); } } } sections } #[test] fn the_core_has_no_dependencies() { let path = Path::new(env!("CARGO_MANIFEST_DIR")).join("Cargo.toml"); let manifest = fs::read_to_string(&path).expect("the manifest is readable"); for (header, entries) in dependency_sections(&manifest) { assert!( !header.contains("dependencies."), "the core declares a dependency table: {header}" ); assert!( entries.is_empty(), "{header} of the core must stay empty, found: {entries:?}" ); } } #[test] fn dependency_sections_are_found_with_their_entries() { let manifest = "[package]\nname = \"x\"\n\n[dependencies]\n# a comment\nserde = \"1\"\n\n\ [dev-dependencies]\nproptest = \"1\"\n\n[dependencies.rand]\nversion = \"0.8\"\n"; assert_eq!( dependency_sections(manifest), vec![ ( "[dependencies]".to_owned(), vec!["serde = \"1\"".to_owned()] ), ( "[dependencies.rand]".to_owned(), vec!["version = \"0.8\"".to_owned()] ), ] ); }