use super::*;
fn content(text: &str) -> RegisterContent {
RegisterContent::characterwise(text.to_string())
}
fn linewise_content(text: &str) -> RegisterContent {
RegisterContent::linewise(text.to_string())
}
#[test]
fn test_new_empty() {
let ring = HistoryRing::new();
assert!(ring.is_empty());
assert_eq!(ring.len(), 0);
assert_eq!(ring.capacity(), DEFAULT_HISTORY_CAPACITY);
}
#[test]
fn test_with_capacity() {
let ring = HistoryRing::with_capacity(5);
assert!(ring.is_empty());
assert_eq!(ring.capacity(), 5);
}
#[test]
fn test_default() {
let ring = HistoryRing::default();
assert!(ring.is_empty());
assert_eq!(ring.capacity(), DEFAULT_HISTORY_CAPACITY);
}
#[test]
fn test_push_single() {
let mut ring = HistoryRing::new();
ring.push(content("hello"));
assert_eq!(ring.len(), 1);
assert!(!ring.is_empty());
assert_eq!(ring.get(0).map(|r| r.text.as_str()), Some("hello"));
}
#[test]
fn test_push_multiple_lifo_order() {
let mut ring = HistoryRing::new();
ring.push(content("first"));
ring.push(content("second"));
ring.push(content("third"));
assert_eq!(ring.len(), 3);
assert_eq!(ring.get(0).map(|r| r.text.as_str()), Some("third"));
assert_eq!(ring.get(1).map(|r| r.text.as_str()), Some("second"));
assert_eq!(ring.get(2).map(|r| r.text.as_str()), Some("first"));
}
#[test]
fn test_push_evicts_oldest_at_capacity() {
let mut ring = HistoryRing::with_capacity(3);
ring.push(content("a"));
ring.push(content("b"));
ring.push(content("c"));
assert_eq!(ring.len(), 3);
ring.push(content("d"));
assert_eq!(ring.len(), 3);
assert_eq!(ring.get(0).map(|r| r.text.as_str()), Some("d"));
assert_eq!(ring.get(1).map(|r| r.text.as_str()), Some("c"));
assert_eq!(ring.get(2).map(|r| r.text.as_str()), Some("b"));
}
#[test]
fn test_push_preserves_yank_type() {
let mut ring = HistoryRing::new();
ring.push(linewise_content("line\n"));
let entry = ring.get(0).unwrap();
assert!(entry.is_linewise());
assert_eq!(entry.text, "line\n");
}
#[test]
fn test_get_numbered_valid() {
let mut ring = HistoryRing::new();
ring.push(content("zero"));
ring.push(content("one"));
ring.push(content("two"));
assert_eq!(ring.get_numbered('0').map(|r| r.text), Some("two".to_string()));
assert_eq!(ring.get_numbered('1').map(|r| r.text), Some("one".to_string()));
assert_eq!(ring.get_numbered('2').map(|r| r.text), Some("zero".to_string()));
}
#[test]
fn test_get_numbered_out_of_range() {
let mut ring = HistoryRing::new();
ring.push(content("only"));
assert!(ring.get_numbered('0').is_some());
assert!(ring.get_numbered('1').is_none());
assert!(ring.get_numbered('9').is_none());
}
#[test]
fn test_get_numbered_invalid_char() {
let ring = HistoryRing::new();
assert!(ring.get_numbered('a').is_none());
assert!(ring.get_numbered('+').is_none());
assert!(ring.get_numbered('*').is_none());
}
#[test]
fn test_get_numbered_empty() {
let ring = HistoryRing::new();
assert!(ring.get_numbered('0').is_none());
}
#[test]
fn test_get_numbered_all_digits() {
let mut ring = HistoryRing::new();
for i in 0..10 {
ring.push(content(&format!("entry-{i}")));
}
for digit in '0'..='9' {
let index = (digit as u8 - b'0') as usize;
let expected = format!("entry-{}", 9 - index);
assert_eq!(
ring.get_numbered(digit).map(|r| r.text),
Some(expected),
"register '{digit}' mismatch"
);
}
}
#[test]
fn test_get_out_of_bounds() {
let ring = HistoryRing::new();
assert!(ring.get(0).is_none());
assert!(ring.get(100).is_none());
}
#[test]
fn test_iter_order() {
let mut ring = HistoryRing::new();
ring.push(content("a"));
ring.push(content("b"));
ring.push(content("c"));
let texts: Vec<&str> = ring.iter().map(|r| r.text.as_str()).collect();
assert_eq!(texts, vec!["c", "b", "a"]);
}
#[test]
fn test_iter_empty() {
let ring = HistoryRing::new();
assert_eq!(ring.iter().count(), 0);
}
#[test]
fn test_clear() {
let mut ring = HistoryRing::new();
ring.push(content("a"));
ring.push(content("b"));
assert_eq!(ring.len(), 2);
ring.clear();
assert!(ring.is_empty());
assert_eq!(ring.len(), 0);
}
#[test]
fn test_clone() {
let mut ring = HistoryRing::new();
ring.push(content("hello"));
let cloned = ring.clone();
assert_eq!(cloned.len(), 1);
assert_eq!(cloned.get(0).map(|r| r.text.as_str()), Some("hello"));
assert_eq!(cloned.capacity(), ring.capacity());
}
#[test]
fn test_full_rotation() {
let mut ring = HistoryRing::with_capacity(3);
ring.push(content("a"));
ring.push(content("b"));
ring.push(content("c"));
ring.push(content("d"));
ring.push(content("e"));
ring.push(content("f"));
assert_eq!(ring.len(), 3);
assert_eq!(ring.get(0).map(|r| r.text.as_str()), Some("f"));
assert_eq!(ring.get(1).map(|r| r.text.as_str()), Some("e"));
assert_eq!(ring.get(2).map(|r| r.text.as_str()), Some("d"));
}
#[test]
#[cfg_attr(coverage_nightly, coverage(off))]
fn test_debug() {
let ring = HistoryRing::new();
let debug_str = format!("{ring:?}");
assert!(debug_str.contains("HistoryRing"));
}
#[test]
fn test_get_by_index_empty() {
let ring = HistoryRing::new();
assert!(ring.get_by_index(0).is_none());
assert!(ring.get_by_index(255).is_none());
}
#[test]
fn test_get_by_index_single() {
let mut ring = HistoryRing::new();
ring.push(content("entry"));
assert_eq!(ring.get_by_index(0).map(|r| r.text.as_str()), Some("entry"));
assert!(ring.get_by_index(1).is_none());
}
#[test]
fn test_get_by_index_multiple() {
let mut ring = HistoryRing::new();
ring.push(content("first"));
ring.push(content("second"));
ring.push(content("third"));
assert_eq!(ring.get_by_index(0).map(|r| r.text.as_str()), Some("third"));
assert_eq!(ring.get_by_index(1).map(|r| r.text.as_str()), Some("second"));
assert_eq!(ring.get_by_index(2).map(|r| r.text.as_str()), Some("first"));
}
#[test]
fn test_get_by_index_u8_max() {
let ring = HistoryRing::new();
assert!(ring.get_by_index(u8::MAX).is_none());
}
#[test]
fn test_default_capacity_is_256() {
let ring = HistoryRing::new();
assert_eq!(ring.capacity(), 256);
}
#[test]
fn test_expanded_capacity_holds_more_than_10() {
let mut ring = HistoryRing::new();
for i in 0..20 {
ring.push(content(&format!("entry-{i}")));
}
assert_eq!(ring.len(), 20);
assert_eq!(ring.get_by_index(0).map(|r| r.text.as_str()), Some("entry-19"));
assert_eq!(ring.get_by_index(19).map(|r| r.text.as_str()), Some("entry-0"));
}
#[test]
fn test_expanded_capacity_evicts_at_256() {
let mut ring = HistoryRing::new();
for i in 0..257 {
ring.push(content(&format!("e{i}")));
}
assert_eq!(ring.len(), 256);
assert_eq!(ring.get_by_index(0).map(|r| r.text.as_str()), Some("e256"));
assert_eq!(ring.get_by_index(255).map(|r| r.text.as_str()), Some("e1"));
}