use core::ops::Bound; #[test] pub fn should_have_format_macro() { let result = stroka::format!("{0} + {0} = {1}", 1, 2); assert_eq!(result, "1 + 1 = 2"); } #[test] pub fn should_not_reserve_within_sso_capacity() { const MAX_CAP: usize = core::mem::size_of::() * 2 - 2; let mut stroka = stroka::String::new(); for idx in 0..=MAX_CAP { stroka.reserve(idx); assert!(!stroka.is_alloc()); } } #[test] pub fn should_push_various_chunks() { let chunks = [ '1', '2', '3', '4', '5', '6', '7', '8', '9' ]; let mut expected_string = String::new(); let mut stroka: stroka::String = chunks.iter().collect(); assert_eq!(stroka, "123456789"); expected_string.push_str("123456789"); for idx in 1..chunks.len() { let text: String = chunks[..idx].iter().collect(); expected_string.push_str(&text); stroka.push_str(&text); } assert_eq!(stroka, expected_string); for ch in chunks { expected_string.push(ch); stroka.push(ch); } assert_eq!(stroka, expected_string); stroka.push_str("ロりr"); expected_string.push_str("ロりr"); assert_eq!(stroka, expected_string); stroka.push('ロ'); expected_string.push('ロ'); assert_eq!(stroka, expected_string); stroka.clear(); } #[test] pub fn should_remove_from_sso_string() { const TEXT: &str = "1単語8"; let mut stroka = stroka::String::new_str(TEXT); assert!(!stroka.is_alloc()); assert_eq!(stroka, TEXT); stroka.remove(1); assert_eq!(stroka, "1語8"); stroka.remove(4); assert_eq!(stroka, "1語"); stroka.remove(0); assert_eq!(stroka, "語"); stroka.remove(0); assert_eq!(stroka, ""); } #[test] pub fn should_drain_from_sso_string() { const TEXT: &str = "1単語8"; let mut stroka = stroka::String::new_str(TEXT); assert!(!stroka.is_alloc()); let chars = stroka.drain(..1).collect::>(); assert_eq!(chars, ['1']); assert_eq!(stroka, "単語8"); let chars = stroka.drain(stroka.len()-1..).collect::>(); assert_eq!(chars, ['8']); assert_eq!(stroka, "単語"); let chars = stroka.drain(..).collect::>(); assert_eq!(chars, ['単', '語']); assert_eq!(stroka, ""); let chars = stroka.drain(..).collect::>(); assert_eq!(chars, []); assert_eq!(stroka, ""); stroka.push_str(TEXT); assert_eq!(stroka, "1単語8"); let chars = stroka.drain(1..stroka.len()-1).collect::>(); assert_eq!(chars, ['単', '語']); assert_eq!(stroka, "18"); let chars = stroka.drain(..).collect::>(); assert_eq!(chars, ['1', '8']); assert_eq!(stroka, ""); } #[test] #[should_panic] pub fn should_panic_on_non_char_bound_remove_from_sso_string() { const TEXT: &str = "1単語8"; let mut stroka = stroka::String::new_str(TEXT); stroka.remove(2); } #[test] #[should_panic] pub fn should_panic_on_remove_from_outside_of_sso_string() { const TEXT: &str = "1単語8"; let mut stroka = stroka::String::new_str(TEXT); stroka.remove(usize::max_value()); } #[test] pub fn should_remove_from_heap_string() { const TEXT: &str = "123456789単語123456789"; let mut stroka = stroka::String::new_str(TEXT); assert!(stroka.is_alloc()); assert_eq!(stroka, TEXT); stroka.remove(1); assert_eq!(stroka, "13456789単語123456789"); stroka.remove(8); assert_eq!(stroka, "13456789語123456789"); stroka.remove(19); assert_eq!(stroka, "13456789語12345678"); stroka.remove(0); assert_eq!(stroka, "3456789語12345678"); stroka.remove(6); assert_eq!(stroka, "345678語12345678"); stroka.remove(6); assert_eq!(stroka, "34567812345678"); } #[test] pub fn should_drain_from_heap_string() { const TEXT: &str = "123456789単語123456789"; let mut stroka = stroka::String::new_str(TEXT); assert!(stroka.is_alloc()); let chars = stroka.drain(..1).collect::>(); assert_eq!(chars, ['1']); assert_eq!(stroka, "23456789単語123456789"); let chars = stroka.drain(stroka.len()-1..).collect::>(); assert_eq!(chars, ['9']); assert_eq!(stroka, "23456789単語12345678"); let chars = stroka.drain(8..14).collect::>(); assert_eq!(chars, ['単', '語']); assert_eq!(stroka, "2345678912345678"); let chars = stroka.drain(..8).collect::>(); assert_eq!(chars, ['2', '3', '4', '5', '6', '7', '8', '9']); assert_eq!(stroka, "12345678"); let chars = stroka.drain(..).collect::>(); assert_eq!(chars, ['1', '2', '3', '4', '5', '6', '7', '8']); assert_eq!(stroka, ""); let chars = stroka.drain(..).collect::>(); assert_eq!(chars, []); assert_eq!(stroka, ""); } #[test] #[should_panic] pub fn should_panic_on_non_char_bound_remove_from_heap_string() { const TEXT: &str = "123456789単語123456789"; let mut stroka = stroka::String::new_str(TEXT); stroka.remove(10); } #[test] #[should_panic] pub fn should_panic_on_remove_from_outside_of_heap_string() { const TEXT: &str = "123456789単語123456789"; let mut stroka = stroka::String::new_str(TEXT); stroka.remove(usize::max_value()); } #[test] pub fn should_insert_at_any_valid_position() { const TEXT: &str = "1単語8"; let mut stroka = stroka::String::new(); stroka.insert_str(0, TEXT); assert_eq!(stroka, TEXT); stroka.insert_str(1, TEXT); assert_eq!(stroka, "11単語8単語8"); stroka.insert_str(stroka.len(), TEXT); assert_eq!(stroka, "11単語8単語81単語8"); stroka.insert_str(stroka.len() - 1, TEXT); assert_eq!(stroka, "11単語8単語81単語1単語88"); stroka.insert(2, '-'); assert_eq!(stroka, "11-単語8単語81単語1単語88"); stroka.insert(0, '-'); assert_eq!(stroka, "-11-単語8単語81単語1単語88"); stroka.insert(stroka.len(), '-'); assert_eq!(stroka, "-11-単語8単語81単語1単語88-"); stroka.insert(stroka.len() - 2, '+'); assert_eq!(stroka, "-11-単語8単語81単語1単語8+8-"); } #[test] pub fn should_retain_within_sso() { const TEXT: &str = "1--単語8-"; let mut stroka = stroka::String::new_sso(TEXT); assert!(!stroka.is_alloc()); stroka.retain(|ch| ch.len_utf8() == 1); assert_eq!(stroka, "1--8-"); stroka.retain(|ch| ch != '-'); assert_eq!(stroka, "18"); } #[test] pub fn should_retain_within_heap() { const TEXT: &str = "-1++1-単語8単語81単語1単語8+8-++"; let mut stroka = stroka::String::new_str(TEXT); assert!(stroka.is_alloc()); assert_eq!(stroka.len(), TEXT.len()); stroka.retain(|ch| ch.len_utf8() == 1); assert_eq!(stroka, "-1++1-88118+8-++"); stroka.retain(|ch| ch != '+'); assert_eq!(stroka, "-11-881188-"); } #[test] #[should_panic] pub fn should_panic_on_insert_outside_of_bound() { const TEXT: &str = "123456789単語123456789"; let mut stroka = stroka::String::new_str(TEXT); stroka.insert_str(usize::max_value(), TEXT); } #[test] pub fn should_replace_range_within_heap_string() { use core::ops::Bound; const TEXT: &str = "123456789単語123456789"; let mut stroka = stroka::String::new_str(TEXT); assert!(stroka.is_alloc()); stroka.replace_range((Bound::Included(0), Bound::Included(1)), "21"); assert_eq!(stroka, "213456789単語123456789"); stroka.replace_range((Bound::Included(9), Bound::Excluded(15)), "--"); assert_eq!(stroka, "213456789--123456789"); stroka.replace_range((Bound::Excluded(0), Bound::Included(1)), "+"); assert_eq!(stroka, "2+3456789--123456789"); } #[test] pub fn should_remove_range_within_heap_string() { use core::ops::Bound; const TEXT: &str = "123456789単語123456789"; let mut stroka = stroka::String::new_str(TEXT); assert!(stroka.is_alloc()); stroka.remove_range((Bound::Included(0), Bound::Included(1))); assert_eq!(stroka, "3456789単語123456789"); stroka.remove_range((Bound::Included(7), Bound::Excluded(13))); assert_eq!(stroka, "3456789123456789"); stroka.remove_range((Bound::Included(stroka.len()), Bound::Unbounded)); assert_eq!(stroka, "3456789123456789"); stroka.remove_range((Bound::Excluded(stroka.len() - 1), Bound::Unbounded)); assert_eq!(stroka, "3456789123456789"); stroka.remove_range((Bound::Included(stroka.len() - 1), Bound::Unbounded)); assert_eq!(stroka, "345678912345678"); stroka.remove_range(..); assert_eq!(stroka, ""); } #[test] pub fn should_remove_range_within_sso_string() { const TEXT: &str = "1単語9"; let mut stroka = stroka::String::new_str(TEXT); assert!(!stroka.is_alloc()); stroka.remove_range(stroka.len()-1..); assert_eq!(stroka, "1単語"); stroka.remove_range(1..=3); assert_eq!(stroka, "1語"); stroka.remove_range(1..=3); assert_eq!(stroka, "1"); stroka.remove_range(..); assert_eq!(stroka, ""); stroka.remove_range(..); assert_eq!(stroka, ""); stroka.push_str(TEXT); assert_eq!(stroka, "1単語9"); stroka.remove_range(1..stroka.len()-1); assert_eq!(stroka, "19"); } #[test] pub fn should_replace_range_within_sso_string() { const TEXT: &str = "1単語8"; let mut stroka = stroka::String::new_str(TEXT); assert!(!stroka.is_alloc()); stroka.replace_range((Bound::Included(0), Bound::Excluded(1)), "3"); assert_eq!(stroka, "3単語8"); stroka.replace_range((Bound::Unbounded, Bound::Excluded(1)), "44"); assert_eq!(stroka, "44単語8"); stroka.replace_range((Bound::Included(0), Bound::Included(1)), "5"); assert_eq!(stroka, "5単語8"); stroka.replace_range((Bound::Included(0), Bound::Excluded(4)), "--"); assert_eq!(stroka, "--語8"); stroka.replace_range((Bound::Excluded(0), Bound::Included(4)), "++"); assert_eq!(stroka, "-++8"); let new = ".".repeat(stroka.capacity()); stroka.replace_range((Bound::Included(0), Bound::Excluded(stroka.len())), &new); assert!(!stroka.is_alloc()); assert_eq!(stroka, new); let new = "+".repeat(stroka.capacity()); stroka.replace_range((Bound::Included(0), Bound::Excluded(stroka.len())), &new); assert!(!stroka.is_alloc()); assert_eq!(stroka, new); let new = "-".repeat(stroka.capacity()); stroka.replace_range((Bound::Excluded(0), Bound::Unbounded), &new); assert!(stroka.is_alloc()); assert_eq!(stroka, format!("+{}", new)); } #[test] #[should_panic] pub fn should_panic_on_reverse_replace_range() { const TEXT: &str = "12345"; let mut stroka = stroka::String::new_str(TEXT); stroka.replace_range((Bound::Included(3), Bound::Excluded(1)), "3"); }