use crate::edit::series::{self, SeriesFile};
use rowan::ast::AstNode;
#[test]
fn test_parse_empty_file() {
let parsed = series::parse("");
assert!(parsed.errors().is_empty());
let series = parsed.quilt_tree();
assert_eq!(series.entries().count(), 0);
}
#[test]
fn test_parse_whitespace_only() {
let parsed = series::parse(" \n\t\n \n");
assert!(parsed.errors().is_empty());
let series = parsed.quilt_tree();
assert_eq!(series.patch_entries().count(), 0);
}
#[test]
fn test_parse_comments_only() {
let text = "# First comment\n# Second comment\n";
let parsed = series::parse(text);
assert!(parsed.errors().is_empty());
let series = parsed.quilt_tree();
let comments: Vec<_> = series.comment_lines().collect();
assert_eq!(comments.len(), 2);
assert_eq!(comments[0].text(), "First comment");
assert_eq!(comments[1].text(), "Second comment");
}
#[test]
fn test_parse_patches_with_various_options() {
let text = "patch1.patch\npatch2.patch -p1\npatch3.patch -p2 --reverse --fuzz=3\n";
let parsed = series::parse(text);
assert!(parsed.errors().is_empty());
let series = parsed.quilt_tree();
let patches: Vec<_> = series.patch_entries().collect();
assert_eq!(patches.len(), 3);
assert_eq!(patches[0].name(), Some("patch1.patch".to_string()));
assert_eq!(patches[0].option_strings(), Vec::<String>::new());
assert_eq!(patches[1].name(), Some("patch2.patch".to_string()));
assert_eq!(patches[1].option_strings(), vec!["-p1"]);
assert_eq!(patches[2].name(), Some("patch3.patch".to_string()));
assert_eq!(
patches[2].option_strings(),
vec!["-p2", "--reverse", "--fuzz=3"]
);
}
#[test]
fn test_parse_mixed_content() {
let text = r#"# Debian patch series
# First set of patches
001-fix-build.patch -p1
002-add-feature.patch
# Security fixes
CVE-2023-1234.patch --reverse
CVE-2023-5678.patch -p2 --fuzz=2
# Backports
backport-upstream-fix.patch
"#;
let parsed = series::parse(text);
assert!(parsed.errors().is_empty());
let series = parsed.quilt_tree();
let patches: Vec<_> = series.patch_entries().collect();
assert_eq!(patches.len(), 5);
let comments: Vec<_> = series.comment_lines().collect();
assert_eq!(comments.len(), 4);
}
#[test]
fn test_preserve_formatting() {
let text = "patch1.patch \t-p1 \t--reverse\n# Comment with spaces\npatch2.patch\n";
let parsed = series::parse(text);
let series = parsed.quilt_tree();
assert_eq!(series.syntax().to_string(), text);
}
#[test]
fn test_thread_safety() {
let text = "patch1.patch\n";
let parsed = series::parse(text);
let green1 = parsed.green().clone();
let green2 = parsed.green().clone();
let root1 = SeriesFile::new_root(green1);
let root2 = SeriesFile::new_root(green2);
assert_eq!(root1.syntax().to_string(), root2.syntax().to_string());
}
#[test]
fn test_edit_insert_first() {
let text = "patch2.patch\n";
let parsed = series::parse(text);
let mut series = parsed.quilt_tree_mut();
series.insert(0, "patch1.patch", Vec::<&str>::new());
let patches: Vec<_> = series.patch_entries().collect();
assert_eq!(patches.len(), 2);
assert_eq!(patches[0].name(), Some("patch1.patch".to_string()));
assert_eq!(patches[1].name(), Some("patch2.patch".to_string()));
}
#[test]
fn test_edit_insert_last() {
let text = "patch1.patch\n";
let parsed = series::parse(text);
let mut series = parsed.quilt_tree_mut();
series.insert(1, "patch2.patch", vec!["-p1".to_string()]);
let patches: Vec<_> = series.patch_entries().collect();
assert_eq!(patches.len(), 2);
assert_eq!(patches[0].name(), Some("patch1.patch".to_string()));
assert_eq!(patches[1].name(), Some("patch2.patch".to_string()));
assert_eq!(patches[1].option_strings(), vec!["-p1"]);
}
#[test]
fn test_edit_remove_preserves_comments() {
let text = "# Header\npatch1.patch\n# Middle\npatch2.patch\n# Footer\n";
let parsed = series::parse(text);
let mut series = parsed.quilt_tree_mut();
assert!(series.remove("patch1.patch"));
let patches: Vec<_> = series.patch_entries().collect();
assert_eq!(patches.len(), 1);
assert_eq!(patches[0].name(), Some("patch2.patch".to_string()));
let comments: Vec<_> = series.comment_lines().collect();
assert_eq!(comments.len(), 3);
}
#[test]
fn test_edit_update_options() {
let text = "patch1.patch -p1\n";
let parsed = series::parse(text);
let mut series = parsed.quilt_tree_mut();
assert!(series.set_options(
"patch1.patch",
vec!["-p2".to_string(), "--fuzz=3".to_string()],
));
let patches: Vec<_> = series.patch_entries().collect();
assert_eq!(patches[0].option_strings(), vec!["-p2", "--fuzz=3"]);
}
#[test]
fn test_edit_chain_operations() {
let text = "patch1.patch\n";
let parsed = series::parse(text);
let mut series = parsed.quilt_tree_mut();
series.insert(1, "patch2.patch", vec!["-p1".to_string()]);
series.add_comment("Added patch2");
series.insert(0, "patch0.patch", Vec::<&str>::new());
let patches: Vec<_> = series.patch_entries().collect();
assert_eq!(patches.len(), 3);
assert_eq!(patches[0].name(), Some("patch0.patch".to_string()));
assert_eq!(patches[1].name(), Some("patch1.patch".to_string()));
assert_eq!(patches[2].name(), Some("patch2.patch".to_string()));
let comments: Vec<_> = series.comment_lines().collect();
assert_eq!(comments.len(), 1);
assert_eq!(comments[0].text(), "Added patch2");
}
#[test]
fn test_error_recovery() {
let text = "patch1.patch\n\n \npatch2.patch -p1\n";
let parsed = series::parse(text);
let series = parsed.quilt_tree();
let patches: Vec<_> = series.patch_entries().collect();
assert_eq!(patches.len(), 2);
}
#[test]
fn test_special_patch_names() {
let text = "debian/patches/fix-build.patch -p1\n../other/patch.diff\nCVE-2023-1234.patch\n";
let parsed = series::parse(text);
assert!(parsed.errors().is_empty());
let series = parsed.quilt_tree();
let patches: Vec<_> = series.patch_entries().collect();
assert_eq!(patches.len(), 3);
assert_eq!(
patches[0].name(),
Some("debian/patches/fix-build.patch".to_string())
);
assert_eq!(patches[1].name(), Some("../other/patch.diff".to_string()));
assert_eq!(patches[2].name(), Some("CVE-2023-1234.patch".to_string()));
}
#[test]
fn test_builder_comprehensive() {
let series = series::SeriesBuilder::new()
.add_comment("Debian patch series for package foo")
.add_comment("")
.add_patch("debian/patches/01-fix-build.patch", vec!["-p1".to_string()])
.add_patch("debian/patches/02-add-feature.patch", vec![])
.add_comment("Security fixes")
.add_patch(
"debian/patches/CVE-2023-1234.patch",
vec!["-p2".to_string(), "--fuzz=3".to_string()],
)
.build();
let patches: Vec<_> = series.patch_entries().collect();
assert_eq!(patches.len(), 3);
let comments: Vec<_> = series.comment_lines().collect();
assert_eq!(comments.len(), 3);
}