//! Hostile input: nothing panics, caps error or flag truncation. use notescraft_knowledge::caps::{MAX_NOTE_BYTES, MAX_PASSAGE_CHARS, MAX_PASSAGES_PER_NOTE}; use notescraft_knowledge::tokens::query_terms; use notescraft_knowledge::{Error, Index, chunk, slice}; #[test] fn huge_note_is_an_error_not_a_crash() { let big = "word ".repeat(MAX_NOTE_BYTES / 4); assert!(matches!(chunk(&big), Err(Error::NoteTooLarge { .. }))); let mut i = Index::default(); assert!(i.update("big.md", &big).is_err()); assert_eq!(i.note_count(), 0); } #[test] fn big_but_allowed_note_is_truncated_with_flag() { let text = "lorem ipsum dolor\n\n".repeat(MAX_NOTE_BYTES / 19); let c = chunk(&text).unwrap(); assert!(c.truncated); assert_eq!(c.passages.len(), MAX_PASSAGES_PER_NOTE); } #[test] fn single_unbreakable_line_splits() { let text = "x".repeat(MAX_NOTE_BYTES); let c = chunk(&text).unwrap(); assert!(c.truncated); assert!(c.passages.iter().all(|p| p.end - p.start <= MAX_PASSAGE_CHARS)); } #[test] fn binary_ish_text() { let junk: String = (0u32..20_000).map(|n| char::from_u32(n % 0x300).unwrap_or('\0')).collect(); let mut i = Index::default(); let _ = i.update("bin.md", &junk); let _ = i.update("nul.md", &"\0\u{1}\u{7f}\r\r\n---\n```\n".repeat(500)); assert!(i.search(&query_terms(&junk), 5).is_ok()); } #[test] fn hundred_thousand_headings() { let text = "# h\n".repeat(100_000); let c = chunk(&text).unwrap(); assert!(c.truncated); let deep = "###### a\n".repeat(50_000) + &"# b\n".repeat(50_000); assert!(chunk(&deep).is_ok()); } #[test] fn unclosed_fence_and_frontmatter() { assert!(chunk(&format!("---\n{}", "k: v\n".repeat(10_000))).is_ok()); assert!(chunk(&format!("```\n{}", "code\n\n".repeat(10_000))).is_ok()); } #[test] fn invalid_ranges_and_emoji_boundaries() { let s = "a😀b"; assert!(matches!(slice(s, 3, 1), Err(Error::InvalidRange { .. }))); assert!(matches!(slice(s, 0, usize::MAX), Err(Error::InvalidRange { .. }))); assert_eq!(slice(s, 2, 3), Err(Error::NotCharBoundary)); let text = "😀".repeat(5_000); for p in chunk(&text).unwrap().passages { assert!(slice(&text, p.start, p.end).is_ok()); } } #[test] fn giant_query_is_capped() { let q = "w ".repeat(1_000_000); let mut i = Index::default(); i.update("a.md", "ww").unwrap(); assert!(i.search(&query_terms(&q), 5).is_ok()); }