#![warn(clippy::nursery)]
#![deny(
unused,
nonstandard_style,
future_incompatible,
missing_copy_implementations,
missing_debug_implementations,
missing_docs,
clippy::pedantic,
clippy::cargo,
clippy::complexity,
clippy::correctness,
clippy::perf,
clippy::style,
clippy::suspicious,
non_fmt_panics
)]
#![allow(clippy::multiple_crate_versions)]
pub use cmd::{diff, diff_with_algorithm};
pub use diff_algorithm::Algorithm;
pub use draw_diff::DrawDiff;
#[cfg(feature = "arrows_color")]
pub use themes::ArrowsColorTheme;
#[cfg(feature = "arrows")]
pub use themes::ArrowsTheme;
#[cfg(feature = "signs_color")]
pub use themes::SignsColorTheme;
#[cfg(feature = "signs")]
pub use themes::SignsTheme;
pub use themes::Theme;
mod cmd;
mod diff_algorithm;
mod draw_diff;
mod themes;
#[cfg(doctest)]
mod test_readme {
macro_rules! external_doc_test {
($x:expr) => {
#[doc = $x]
extern "C" {}
};
}
external_doc_test!(include_str!("../README.md"));
}
#[cfg(test)]
mod integration_tests {
use crate::{diff, ArrowsTheme, DrawDiff, SignsTheme, Theme};
use std::io::Cursor;
#[test]
fn test_diff_with_arrows_theme() {
let old = "The quick brown fox";
let new = "The quick red fox";
let mut buffer = Cursor::new(Vec::new());
let theme = ArrowsTheme::default();
diff(&mut buffer, old, new, &theme).unwrap();
let output = String::from_utf8(buffer.into_inner()).expect("Not valid UTF-8");
assert!(output.contains("<The quick brown fox"));
assert!(output.contains(">The quick red fox"));
assert!(output.contains(">The quick red fox"));
assert!(output.contains(">The quick red fox"));
assert!(output.contains("< left / > right"));
}
#[test]
fn test_diff_with_signs_theme() {
let old = "The quick brown fox";
let new = "The quick red fox";
let mut buffer = Cursor::new(Vec::new());
let theme = SignsTheme::default();
diff(&mut buffer, old, new, &theme).unwrap();
let output = String::from_utf8(buffer.into_inner()).expect("Not valid UTF-8");
assert!(output.contains("-The quick brown fox"));
assert!(output.contains("+The quick red fox"));
assert!(output.contains("--- remove | insert +++"));
}
#[test]
fn test_draw_diff_with_arrows_theme() {
let old = "The quick brown fox";
let new = "The quick red fox";
let theme = ArrowsTheme::default();
let output = format!("{}", DrawDiff::new(old, new, &theme));
assert!(
output.contains("<The quick brown fox"),
"Expected deleted line marker without space, got:\n{}",
output
);
assert!(
output.contains(">The quick red fox"),
"Expected inserted line marker with space, got:\n{}",
output
);
assert!(
output.contains("< left / > right"),
"Expected header with proper spacing, got:\n{}",
output
);
}
#[test]
fn test_draw_diff_with_signs_theme() {
let old = "The quick brown fox";
let new = "The quick red fox";
let theme = SignsTheme::default();
let output = format!("{}", DrawDiff::new(old, new, &theme));
assert!(output.contains("-The quick brown fox"));
assert!(output.contains("+The quick red fox"));
assert!(output.contains("--- remove | insert +++"));
}
#[test]
fn test_empty_strings() {
let old = "";
let new = "";
let theme = ArrowsTheme::default();
let output = format!("{}", DrawDiff::new(old, new, &theme));
assert_eq!(output, "< left / > right\n");
}
#[test]
fn test_newline_differences() {
let old = "line\n";
let new = "line";
let theme = ArrowsTheme::default();
let output = format!("{}", DrawDiff::new(old, new, &theme));
assert!(output.contains("line␊"));
}
#[test]
fn test_custom_theme() {
use std::borrow::Cow;
#[derive(Debug)]
struct CustomTheme;
impl Theme for CustomTheme {
fn equal_prefix<'this>(&self) -> Cow<'this, str> {
"=".into()
}
fn delete_prefix<'this>(&self) -> Cow<'this, str> {
"DEL>".into()
}
fn insert_prefix<'this>(&self) -> Cow<'this, str> {
"INS>".into()
}
fn header<'this>(&self) -> Cow<'this, str> {
"CUSTOM DIFF\n".into()
}
}
let old = "The quick brown fox";
let new = "The quick red fox";
let theme = CustomTheme;
let output = format!("{}", DrawDiff::new(old, new, &theme));
assert!(output.contains("DEL>The quick brown fox"));
assert!(output.contains("INS>The quick red fox"));
assert!(output.contains("CUSTOM DIFF"));
}
#[test]
fn test_multiline_with_unchanged_lines() {
let old = "Line 1\nLine 2\nLine 3\nLine 4";
let new = "Line 1\nModified Line 2\nLine 3\nModified Line 4";
let theme = SignsTheme::default();
let output = format!("{}", DrawDiff::new(old, new, &theme));
assert!(output.contains(" Line 1"));
assert!(output.contains(" Line 3"));
assert!(output.contains("-Line 2"));
assert!(output.contains("+Modified Line 2"));
assert!(output.contains("-Line 4"));
assert!(output.contains("+Modified Line 4"));
}
#[test]
fn test_draw_diff_to_string() {
let old = "The quick brown fox";
let new = "The quick red fox";
let theme = ArrowsTheme::default();
let diff = DrawDiff::new(old, new, &theme);
let output: String = diff.into();
assert!(output.contains("<The quick brown fox"));
assert!(output.contains(">The quick red fox"));
assert!(output.contains(">The quick red fox"));
}
}