diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/renderer.rs | 23 | ||||
| -rw-r--r-- | src/util/fence.rs | 78 | ||||
| -rw-r--r-- | src/util/mod.rs | 1 |
3 files changed, 83 insertions, 19 deletions
diff --git a/src/renderer.rs b/src/renderer.rs index 6f13f59..d9cf7b4 100644 --- a/src/renderer.rs +++ b/src/renderer.rs @@ -7,7 +7,9 @@ use std::{ use crate::{ logger::Logger, normalizer::NormalizedPath, - util::{language::detect_language, path_display::display_path}, + util::{ + fence::generate_outer_backticks, language::detect_language, path_display::display_path, + }, }; const DEFAULT_MAX_FILE_SIZE: u64 = 1_000_000; @@ -81,7 +83,7 @@ impl<W: Write> Renderer<W> { fn write_file(&mut self, filename: &Path, contents: &str) -> std::io::Result<()> { let name = display_path(filename); - let fence = outer_backticks(contents); + let fence = generate_outer_backticks(contents); let language = detect_language(filename, contents); self.log_file_render(filename); writeln!(self.output)?; @@ -131,23 +133,6 @@ impl<W: Write> Renderer<W> { } } -fn outer_backticks(contents: &str) -> String { - let mut max_ticks = 0; - let mut current_count = 0; - for char in contents.chars() { - if char == '`' { - current_count += 1; - if current_count > max_ticks { - max_ticks = current_count; - } - } else { - current_count = 0; - } - } - let fence_len = std::cmp::max(3, max_ticks + 1); - "`".repeat(fence_len) -} - fn human_readable_size(bytes: u64) -> String { const UNITS: [&str; 5] = ["B", "KiB", "MiB", "GiB", "TiB"]; diff --git a/src/util/fence.rs b/src/util/fence.rs new file mode 100644 index 0000000..16f398a --- /dev/null +++ b/src/util/fence.rs @@ -0,0 +1,78 @@ +pub fn generate_outer_backticks(contents: impl AsRef<[u8]>) -> String { + let bytes = contents.as_ref(); + let mut max_ticks = 0; + let mut current_count = 0; + for &byte in bytes { + if byte == b'`' { + current_count += 1; + if current_count > max_ticks { + max_ticks = current_count; + } + } else { + current_count = 0; + } + } + let fence_len = std::cmp::max(3, max_ticks + 1); + "`".repeat(fence_len) +} + +#[cfg(test)] +mod tests { + use super::generate_outer_backticks; + + #[test] + fn empty_content_returns_three_backticks() { + assert_eq!(generate_outer_backticks(b""), "```"); + assert_eq!(generate_outer_backticks(""), "```"); + } + + #[test] + fn content_without_backticks_returns_three_backticks() { + assert_eq!(generate_outer_backticks(b"no backticks here"), "```"); + assert_eq!(generate_outer_backticks("hello world"), "```"); + } + + #[test] + fn single_backtick_returns_three_backticks() { + assert_eq!(generate_outer_backticks(b"`"), "```"); + assert_eq!(generate_outer_backticks("a ` b"), "```"); + } + + #[test] + fn two_consecutive_backticks_returns_three_backticks() { + assert_eq!(generate_outer_backticks(b"``"), "```"); + assert_eq!(generate_outer_backticks("a `` b"), "```"); + } + + #[test] + fn three_consecutive_backticks_returns_four_backticks() { + assert_eq!(generate_outer_backticks(b"```"), "````"); + assert_eq!(generate_outer_backticks("a ``` b"), "````"); + } + + #[test] + fn four_consecutive_backticks_returns_five_backticks() { + assert_eq!(generate_outer_backticks(b"````"), "`````"); + assert_eq!(generate_outer_backticks("a ```` b"), "`````"); + } + + #[test] + fn long_run_of_backticks_returns_run_plus_one() { + let run = 10; + let input = "`".repeat(run); + let expected = "`".repeat(run + 1); + assert_eq!(generate_outer_backticks(&input), expected); + } + + #[test] + fn maximum_run_across_multiple_groups() { + let input = "``` and then ````` and then ``"; // longest run is 5 + assert_eq!(generate_outer_backticks(input), "``````"); // 5+1 = 6 + } + + #[test] + fn backticks_at_start_or_end_handled_correctly() { + assert_eq!(generate_outer_backticks("````start"), "`````"); + assert_eq!(generate_outer_backticks("end`````"), "``````"); + } +} diff --git a/src/util/mod.rs b/src/util/mod.rs index 5595a45..24ba6fc 100644 --- a/src/util/mod.rs +++ b/src/util/mod.rs @@ -1,2 +1,3 @@ +pub mod fence; pub mod language; pub mod path_display; |
