From bad5b4754a03f8d7008d998aa7ff806d242df3b0 Mon Sep 17 00:00:00 2001 From: Yuval Shavit Date: Sat, 8 Jun 2024 18:59:15 -0400 Subject: [PATCH] add pad_to tests Also get rid of the Paddable trait, which was really causing more noise than is worth it. --- src/fmt_md.rs | 9 +++-- src/fmt_str.rs | 100 +++++++++++++++++++++++++++++++++++-------------- 2 files changed, 77 insertions(+), 32 deletions(-) diff --git a/src/fmt_md.rs b/src/fmt_md.rs index f65c992..9cc16eb 100644 --- a/src/fmt_md.rs +++ b/src/fmt_md.rs @@ -1,12 +1,13 @@ -use crate::fmt_str::{pad_to, standard_align}; -use crate::output::Block::Inlined; -use crate::output::{Block, Output}; -use crate::tree::{CodeVariant, Inline, InlineVariant, MdqNode, SpanVariant}; use std::borrow::Borrow; use std::cmp::max; use std::fmt::Alignment; use std::io::Write; +use crate::fmt_str::{pad_to, standard_align}; +use crate::output::Block::Inlined; +use crate::output::{Block, Output}; +use crate::tree::{CodeVariant, Inline, InlineVariant, MdqNode, SpanVariant}; + pub fn write_md(out: &mut Output, nodes: &[N]) where N: Borrow, diff --git a/src/fmt_str.rs b/src/fmt_str.rs index 852562c..7bee3c2 100644 --- a/src/fmt_str.rs +++ b/src/fmt_str.rs @@ -1,12 +1,15 @@ -use crate::output::Output; -use markdown::mdast::AlignKind; use std::borrow::Borrow; use std::fmt::Alignment; +use std::io::Write; + +use markdown::mdast::AlignKind; -pub fn pad_to(output: &mut W, input: &str, min_width: usize, alignment: A) +use crate::output::Output; + +pub fn pad_to(output: &mut Output, input: &str, min_width: usize, alignment: A) where A: ToAlignment, - W: Paddable, + W: Write, { if input.len() >= min_width { return output.write_str(input); @@ -17,17 +20,17 @@ where match standard_align(alignment) { Alignment::Left => { output.write_str(input); - (0..padding).for_each(|_| output.write_ch(' ')); + (0..padding).for_each(|_| output.write_char(' ')); } Alignment::Center => { let left_pad = padding / 2; // round down let right_pad = padding - left_pad; - (0..left_pad).for_each(|_| output.write_ch(' ')); + (0..left_pad).for_each(|_| output.write_char(' ')); output.write_str(input); - (0..right_pad).for_each(|_| output.write_ch(' ')); + (0..right_pad).for_each(|_| output.write_char(' ')); } Alignment::Right => { - (0..padding).for_each(|_| output.write_ch(' ')); + (0..padding).for_each(|_| output.write_char(' ')); output.write_str(input); } } @@ -46,6 +49,12 @@ pub trait ToAlignment { fn to_alignment(&self) -> Alignment; } +impl ToAlignment for Alignment { + fn to_alignment(&self) -> Alignment { + *self + } +} + impl ToAlignment for &AlignKind { fn to_alignment(&self) -> Alignment { match self { @@ -66,37 +75,72 @@ impl> ToAlignment for Option { } } -pub trait Paddable { - fn write_ch(&mut self, ch: char); - fn write_str(&mut self, string: &str); -} +#[cfg(test)] +mod test { + use super::*; -impl Paddable for Output { - fn write_ch(&mut self, ch: char) { - self.write_char(ch); + #[test] + fn left_pad() { + assert_eq!( + "a ", + output_and_get(|out| pad_to(out, "a", 5, Alignment::Left)) + ); } - fn write_str(&mut self, string: &str) { - Output::write_str(self, string); // writing it in UFCS format so it's clear it's not infinite recursion + #[test] + fn right_pad() { + assert_eq!( + " a", + output_and_get(|out| pad_to(out, "a", 5, Alignment::Right)) + ); } -} -#[cfg(test)] -mod test { - use super::*; + /// center pad, with the same amount of padding on each side + #[test] + fn center_pad_even() { + assert_eq!( + " a ", + output_and_get(|out| pad_to(out, "a", 5, Alignment::Center)) + ); + } + /// center pad, with different amount of padding on each side #[test] - fn todo() { - todo!("write a test!") + fn center_pad_uneven() { + assert_eq!( + " ab ", + output_and_get(|out| pad_to(out, "ab", 5, Alignment::Center)) + ); } - impl Paddable for String { - fn write_ch(&mut self, ch: char) { - self.push(ch); + #[test] + fn string_already_right_size() { + for align in [Alignment::Left, Alignment::Center, Alignment::Right] { + assert_eq!( + "abcde", + output_and_get(|out| pad_to(out, "abcde", 5, align)) + ); } + } - fn write_str(&mut self, string: &str) { - self.push_str(string); + #[test] + fn string_already_too_big() { + for align in [Alignment::Left, Alignment::Center, Alignment::Right] { + assert_eq!( + "abcdef", + output_and_get(|out| pad_to(out, "abcdef", 3, align)) + ); } } + + fn output_and_get(action: F) -> String + where + F: FnOnce(&mut Output>), + { + let vec = Vec::with_capacity(16); + let mut output = Output::new(vec); + action(&mut output); + let vec = output.take_underlying().unwrap(); + String::from_utf8(vec).unwrap() + } }