use diffo::*;
use serde::Serialize;
#[test]
fn test_index_based_default() {
let old = vec![1, 2, 3];
let new = vec![1, 2, 4];
let diff = diff(&old, &new).unwrap();
assert!(!diff.is_empty());
assert!(diff.get("[2]").is_some());
}
#[test]
fn test_myers_insertion() {
let old = vec![1, 2, 3];
let new = vec![1, 5, 2, 3];
let config = DiffConfig::new().default_sequence_algorithm(SequenceDiffAlgorithm::Myers);
let diff = diff_with(&old, &new, &config).unwrap();
assert!(!diff.is_empty());
assert!(diff.get("[1]").is_some()); }
#[test]
fn test_myers_deletion() {
let old = vec![1, 2, 3, 4];
let new = vec![1, 3, 4];
let config = DiffConfig::new().default_sequence_algorithm(SequenceDiffAlgorithm::Myers);
let diff = diff_with(&old, &new, &config).unwrap();
assert!(!diff.is_empty());
}
#[test]
fn test_patience_reordering() {
#[derive(Serialize, PartialEq, Eq, Hash)]
struct Item {
id: u64,
name: String,
}
let old = vec![
Item {
id: 1,
name: "alpha".into(),
},
Item {
id: 2,
name: "beta".into(),
},
Item {
id: 3,
name: "gamma".into(),
},
];
let new = vec![
Item {
id: 2,
name: "beta".into(),
},
Item {
id: 3,
name: "gamma".into(),
},
Item {
id: 4,
name: "delta".into(),
},
Item {
id: 1,
name: "alpha".into(),
},
];
let config = DiffConfig::new().default_sequence_algorithm(SequenceDiffAlgorithm::Patience);
let diff = diff_with(&old, &new, &config).unwrap();
assert!(!diff.is_empty());
}
#[test]
fn test_per_path_algorithm() {
#[derive(Serialize)]
struct Data {
users: Vec<String>,
logs: Vec<String>,
}
let old = Data {
users: vec!["alice".into(), "bob".into()],
logs: vec!["log1".into(), "log2".into(), "log3".into()],
};
let new = Data {
users: vec!["alice".into(), "charlie".into(), "bob".into()],
logs: vec!["log1".into(), "log2".into(), "log4".into()],
};
let config = DiffConfig::new()
.sequence_algorithm("users", SequenceDiffAlgorithm::Patience)
.sequence_algorithm("logs", SequenceDiffAlgorithm::IndexBased);
let diff = diff_with(&old, &new, &config).unwrap();
assert!(!diff.is_empty());
}
#[test]
fn test_all_algorithms_produce_valid_diff() {
let old = vec![1, 2, 3, 4, 5];
let new = vec![1, 6, 2, 3, 5];
for algo in [
SequenceDiffAlgorithm::IndexBased,
SequenceDiffAlgorithm::Myers,
SequenceDiffAlgorithm::Patience,
] {
let config = DiffConfig::new().default_sequence_algorithm(algo);
let diff = diff_with(&old, &new, &config).unwrap();
assert!(!diff.is_empty(), "Algorithm {:?} failed", algo);
}
}
#[test]
fn test_identical_sequences() {
let old = vec![1, 2, 3];
let new = vec![1, 2, 3];
for algo in [
SequenceDiffAlgorithm::IndexBased,
SequenceDiffAlgorithm::Myers,
SequenceDiffAlgorithm::Patience,
] {
let config = DiffConfig::new().default_sequence_algorithm(algo);
let diff = diff_with(&old, &new, &config).unwrap();
assert!(diff.is_empty(), "Algorithm {:?} should show no diff", algo);
}
}
#[test]
fn test_completely_different_sequences() {
let old = vec![1, 2, 3];
let new = vec![4, 5, 6];
for algo in [
SequenceDiffAlgorithm::IndexBased,
SequenceDiffAlgorithm::Myers,
SequenceDiffAlgorithm::Patience,
] {
let config = DiffConfig::new().default_sequence_algorithm(algo);
let diff = diff_with(&old, &new, &config).unwrap();
assert!(
!diff.is_empty(),
"Algorithm {:?} should detect changes",
algo
);
assert_eq!(diff.len(), 3, "Algorithm {:?} should show 3 changes", algo);
}
}
#[test]
fn test_empty_sequences() {
let old: Vec<i32> = vec![];
let new: Vec<i32> = vec![];
for algo in [
SequenceDiffAlgorithm::IndexBased,
SequenceDiffAlgorithm::Myers,
SequenceDiffAlgorithm::Patience,
] {
let config = DiffConfig::new().default_sequence_algorithm(algo);
let diff = diff_with(&old, &new, &config).unwrap();
assert!(
diff.is_empty(),
"Algorithm {:?} should handle empty sequences",
algo
);
}
}
#[test]
fn test_one_empty_sequence() {
let old = vec![1, 2, 3];
let new: Vec<i32> = vec![];
for algo in [
SequenceDiffAlgorithm::IndexBased,
SequenceDiffAlgorithm::Myers,
SequenceDiffAlgorithm::Patience,
] {
let config = DiffConfig::new().default_sequence_algorithm(algo);
let diff = diff_with(&old, &new, &config).unwrap();
assert!(
!diff.is_empty(),
"Algorithm {:?} should detect removals",
algo
);
}
}
#[test]
fn test_collection_size_limit_with_algorithms() {
let old: Vec<i32> = (0..2000).collect();
let new: Vec<i32> = (0..2000).collect();
for algo in [
SequenceDiffAlgorithm::IndexBased,
SequenceDiffAlgorithm::Myers,
SequenceDiffAlgorithm::Patience,
] {
let config = DiffConfig::new()
.default_sequence_algorithm(algo)
.collection_limit(100);
let diff = diff_with(&old, &new, &config).unwrap();
assert!(
!diff.is_empty(),
"Algorithm {:?} should respect size limits",
algo
);
let change = diff.changes().values().next().unwrap();
assert!(
change.is_elided(),
"Algorithm {:?} should elide large collections",
algo
);
}
}