use std::collections::BTreeMap;
use camino::Utf8PathBuf;
use crate::elements::{FileResult, Framework, Location, MutantResult, Position, Report, RunInfo, ShardInfo, Thresholds};
use crate::model::{Mutant, Outcome};
use crate::ops::collect::Shape;
pub(crate) const UNRESOLVED_LINK_SOURCE: &str = "unsafe extern \"C\" {\n\
\x20\x20\x20\x20fn gamma_absent_symbol() -> i32;\n\
}\n\n\
pub fn less(a: i32, b: i32) -> bool { a < b }\n\n\
pub fn touch() -> i32 { unsafe { gamma_absent_symbol() } }\n\n\
#[test]\n\
fn calls_it() {\n\
\x20\x20\x20\x20assert!(less(1, 2));\n\
\x20\x20\x20\x20assert_eq!(touch(), 0);\n\
}\n";
pub(crate) fn mutant() -> Mutant {
Mutant {
id: "m1".to_owned().into(),
ordinal: 1,
file: Utf8PathBuf::from("src/lib.rs").into(),
package: "subject".to_owned().into(),
span: 0..1,
line: 1,
end_line: 1,
column: 1,
mutator: "relational.lt_to_le".to_owned().into(),
item_path: "f".to_owned().into(),
trait_impl: None,
occurrence: 0,
replacement_index: 0,
original: "a".to_owned().into(),
replacement: "b".to_owned().into(),
shape: Shape::Expr,
outcome: Outcome::Killed,
suppression: None,
expectation: None,
test_timeout_multiplier: None,
elapsed_ms: 0,
killed_by: None,
note: None,
}
}
pub(crate) fn mutant_at(id: &str, file: &str, line: usize, mutator: &str, outcome: Outcome) -> Mutant {
Mutant {
id: id.to_owned().into(),
file: Utf8PathBuf::from(file).into(),
line,
mutator: mutator.to_owned().into(),
outcome,
..mutant()
}
}
pub(crate) fn mutant_result() -> MutantResult {
MutantResult {
id: "m1".to_owned().into(),
mutator_name: "relational.lt_to_le".into(),
location: Location {
start: Position { line: 1, column: 1 },
end: Position { line: 1, column: 9 },
},
status: "Killed".into(),
replacement: None,
description: None,
status_reason: None,
duration: None,
killed_by: None,
}
}
pub(crate) fn mutant_result_at(id: &str, line: usize, status: &str) -> MutantResult {
MutantResult {
id: id.to_owned().into(),
location: Location {
start: Position { line, column: 1 },
end: Position { line, column: 9 },
},
status: status.into(),
..mutant_result()
}
}
pub(crate) fn report() -> Report {
Report {
schema_version: "2".to_owned(),
thresholds: Thresholds::default(),
project_root: None,
framework: Framework {
name: "cargo-gamma".to_owned(),
version: "0.1.0".to_owned(),
},
files: BTreeMap::new(),
config: None,
}
}
pub(crate) fn report_with(shard: Option<(u32, u32)>, started_at: u64, mutants: Vec<MutantResult>) -> Report {
let mut files = BTreeMap::new();
let _ = files.insert(
"src/lib.rs".to_owned(),
FileResult {
source: "fn f() {}\n".to_owned(),
language: "rust".to_owned(),
mutants,
},
);
Report {
files,
config: Some(RunInfo {
started_at,
merged: false,
shard: shard.map(|(index, count)| ShardInfo { index, count }),
tests: None,
not_built: None,
dropped_test_packages: Vec::new(),
merge_provenance: None,
}),
..report()
}
}
pub(crate) fn crate_dir(name: &str, source: &str) -> (tempfile::TempDir, Utf8PathBuf) {
let dir = crate::testing::workdir(name);
let root = Utf8PathBuf::from_path_buf(dir.path().to_path_buf()).expect("utf8");
std::fs::create_dir(root.join("src")).expect("src");
std::fs::write(
root.join("Cargo.toml"),
"[package]\nname = \"subject\"\nversion = \"0.0.0\"\nedition = \"2024\"\n\n[workspace]\n",
)
.expect("manifest");
std::fs::write(root.join("src/lib.rs"), source).expect("lib");
(dir, root)
}