use ::boxen::{
BorderStyle, BoxenOptions, Color, Float, Spacing, TextAlignment, TitleAlignment, boxen,
builder, double_box, round_box, simple_box,
};
#[test]
fn test_typescript_default_single_border() {
let result = boxen("Hello", None).unwrap();
assert!(result.contains("┌"));
assert!(result.contains("┐"));
assert!(result.contains("└"));
assert!(result.contains("┘"));
assert!(result.contains("│"));
assert!(result.contains("─"));
assert!(result.contains("Hello"));
assert_eq!(result.lines().count(), 3);
let lines: Vec<&str> = result.lines().collect();
assert!(lines[1].contains("Hello"));
assert!(lines[1].starts_with("│"));
assert!(lines[1].ends_with("│"));
}
#[test]
fn test_typescript_padding_asymmetric_behavior() {
let options = BoxenOptions {
padding: Spacing::from(1),
..Default::default()
};
let result = boxen("Test", Some(options)).unwrap();
let lines: Vec<&str> = result.lines().collect();
assert_eq!(lines.len(), 5);
let content_line = lines.iter().find(|line| line.contains("Test")).unwrap();
assert!(content_line.contains(" Test "));
}
#[test]
fn test_typescript_padding_object_behavior() {
let options = BoxenOptions {
padding: Spacing::from((1, 2, 3, 4)), width: Some(20),
..Default::default()
};
let result = boxen("Test", Some(options)).unwrap();
let lines: Vec<&str> = result.lines().collect();
assert_eq!(lines.len(), 7);
assert!(
lines[1]
.trim_start_matches('│')
.trim_end_matches('│')
.trim()
.is_empty()
);
let content_line = lines.iter().find(|line| line.contains("Test")).unwrap();
assert!(content_line.contains(" Test "));
}
#[test]
fn test_typescript_title_truncation() {
let long_title = "This is a very long title that should be truncated";
let options = BoxenOptions {
title: Some(long_title.to_string()),
width: Some(20),
..Default::default()
};
let result = boxen("Content", Some(options)).unwrap();
let first_line = result.lines().next().unwrap();
println!(
"First line: '{}' (length: {})",
first_line,
first_line.len()
);
assert!(first_line.len() <= 30); assert!(result.contains("Content"));
assert!(first_line.contains("This is"));
}
#[test]
fn test_typescript_title_alignment_behavior() {
let title = "Title";
let alignments = [
(TitleAlignment::Left, "┌Title"),
(TitleAlignment::Center, "Title"), (TitleAlignment::Right, "Title┐"),
];
for (alignment, _expected_pattern) in &alignments {
let options = BoxenOptions {
title: Some(title.to_string()),
title_alignment: *alignment,
width: Some(20),
..Default::default()
};
let result = boxen("Content", Some(options)).unwrap();
let first_line = result.lines().next().unwrap();
match alignment {
TitleAlignment::Left => assert!(first_line.starts_with("┌Title")),
TitleAlignment::Right => assert!(first_line.ends_with("Title┐")),
TitleAlignment::Center => {
let title_pos = first_line.find("Title").unwrap();
let line_center = first_line.len() / 2;
let title_center = title_pos + title.len() / 2;
let diff = title_center.abs_diff(line_center);
assert!(diff <= 2);
}
}
}
}
#[test]
fn test_typescript_text_alignment_behavior() {
let multiline_text = "Left\nCenter\nRight";
let alignments = [
TextAlignment::Left,
TextAlignment::Center,
TextAlignment::Right,
];
for alignment in &alignments {
let options = BoxenOptions {
text_alignment: *alignment,
width: Some(20),
..Default::default()
};
let result = boxen(multiline_text, Some(options)).unwrap();
let lines: Vec<&str> = result.lines().collect();
let content_lines: Vec<&str> = lines
.iter()
.filter(|line| {
line.contains("Left") || line.contains("Center") || line.contains("Right")
})
.copied()
.collect();
assert_eq!(content_lines.len(), 3);
for content_line in &content_lines {
match alignment {
TextAlignment::Left => {
let inner = content_line.trim_start_matches('│').trim_end_matches('│');
let trimmed = inner.trim_start();
assert!(
inner.len() - trimmed.len() <= 1,
"Too much left padding for left alignment"
);
}
TextAlignment::Right => {
let inner = content_line.trim_start_matches('│').trim_end_matches('│');
let trimmed = inner.trim_end();
assert!(
inner.len() - trimmed.len() <= 1,
"Too much right padding for right alignment"
);
}
TextAlignment::Center => {
let inner_content = content_line.trim_start_matches('│').trim_end_matches('│');
let _text_part = inner_content.trim();
let left_spaces = inner_content.len() - inner_content.trim_start().len();
let right_spaces = inner_content.len() - inner_content.trim_end().len();
let diff = left_spaces.abs_diff(right_spaces);
assert!(diff <= 1);
}
}
}
}
}
#[test]
fn test_typescript_multiline_handling() {
let multiline = "Line 1\nLine 2\nLine 3";
let result = boxen(multiline, None).unwrap();
let lines: Vec<&str> = result.lines().collect();
assert_eq!(lines.len(), 5);
assert!(lines[1].contains("Line 1"));
assert!(lines[2].contains("Line 2"));
assert!(lines[3].contains("Line 3"));
for i in lines.iter().take(3 + 1).skip(1) {
assert!(i.starts_with("│"));
assert!(i.ends_with("│"));
}
}
#[test]
fn test_typescript_empty_text_handling() {
let result = boxen("", None).unwrap();
let lines: Vec<&str> = result.lines().collect();
assert_eq!(lines.len(), 3);
assert!(lines[1].starts_with("│"));
assert!(lines[1].ends_with("│"));
let content = lines[1].trim_start_matches('│').trim_end_matches('│');
assert!(content.trim().is_empty());
}
#[test]
fn test_typescript_width_constraint_behavior() {
let long_text = "This is a very long line that should be wrapped when width is constrained";
let options = BoxenOptions {
width: Some(30),
..Default::default()
};
let result = boxen(long_text, Some(options)).unwrap();
let lines: Vec<&str> = result.lines().collect();
assert!(lines.len() > 3);
for line in &lines {
assert!(line.len() <= 100); }
let full_output = result.replace('\n', " ");
assert!(full_output.contains("This"));
assert!(full_output.contains("very"));
assert!(full_output.contains("long"));
assert!(full_output.contains("wrapped"));
}
#[test]
fn test_typescript_height_constraint_behavior() {
let many_lines = (0..20)
.map(|i| format!("Line {i}"))
.collect::<Vec<_>>()
.join("\n");
let options = BoxenOptions {
height: Some(8), ..Default::default()
};
let result = boxen(&many_lines, Some(options)).unwrap();
let lines: Vec<&str> = result.lines().collect();
assert!(lines.len() <= 8);
assert!(result.contains("Line 0"));
assert!(!result.contains("Line 15"));
}
#[test]
fn test_typescript_color_application() {
let options = BoxenOptions {
border_color: Some(Color::Named("red".to_string())),
background_color: Some(Color::Named("blue".to_string())),
..Default::default()
};
let result = boxen("Colored text", Some(options)).unwrap();
assert!(result.contains("\x1b["));
assert!(result.contains("Colored text"));
assert!(result.contains("┌") || result.contains("│"));
}
#[test]
fn test_typescript_float_positioning() {
let floats = [Float::Left, Float::Center, Float::Right];
for float_pos in &floats {
let options = BoxenOptions {
float: *float_pos,
width: Some(20),
..Default::default()
};
let result = boxen("Float test", Some(options)).unwrap();
let lines: Vec<&str> = result.lines().collect();
assert!(lines.len() >= 3);
assert!(result.contains("Float test"));
match float_pos {
Float::Left => {
for line in &lines {
if line.contains("┌") || line.contains("│") || line.contains("└") {
assert!(!line.starts_with(' '));
}
}
}
Float::Right => {
let first_line = lines[0];
if first_line.contains("┌") {
assert!(first_line.starts_with(' ') || first_line.len() >= 20);
}
}
Float::Center => {
let first_line = lines[0];
if first_line.contains("┌") {
assert!(first_line.starts_with(' ') || first_line.len() >= 20);
}
}
}
}
}
#[test]
fn test_typescript_margin_behavior() {
let options = BoxenOptions {
margin: Spacing::from(2),
..Default::default()
};
let result = boxen("Margin test", Some(options)).unwrap();
let lines: Vec<&str> = result.lines().collect();
assert!(lines.len() > 3);
assert!(lines[0].trim().is_empty());
assert!(lines[1].trim().is_empty());
assert!(lines[lines.len() - 1].trim().is_empty());
assert!(lines[lines.len() - 2].trim().is_empty());
assert!(result.contains("Margin test"));
}
#[test]
fn test_typescript_no_border_behavior() {
let options = BoxenOptions {
border_style: BorderStyle::None,
padding: Spacing::from(1),
..Default::default()
};
let result = boxen("No border", Some(options)).unwrap();
assert!(!result.contains("┌"));
assert!(!result.contains("│"));
assert!(!result.contains("└"));
assert!(result.contains("No border"));
let lines: Vec<&str> = result.lines().collect();
assert!(lines.len() > 1);
}
#[test]
fn test_typescript_builder_equivalence() {
let text = "Equivalence test";
let options = BoxenOptions {
border_style: BorderStyle::Double,
padding: Spacing::from(1),
text_alignment: TextAlignment::Center,
title: Some("Test".to_string()),
width: Some(30),
border_color: Some(Color::Named("blue".to_string())),
..Default::default()
};
let options_result = boxen(text, Some(options)).unwrap();
let builder_result = builder()
.border_style(BorderStyle::Double)
.padding(1)
.text_alignment(TextAlignment::Center)
.title("Test")
.width(30)
.border_color("blue")
.render(text)
.unwrap();
assert_eq!(options_result, builder_result);
}
#[test]
fn test_typescript_convenience_functions_behavior() {
let text = "Convenience test";
let simple = simple_box(text);
let manual = boxen(text, None).unwrap();
assert_eq!(simple, manual);
let double = double_box(text);
let manual_double = boxen(
text,
Some(BoxenOptions {
border_style: BorderStyle::Double,
..Default::default()
}),
)
.unwrap();
assert_eq!(double, manual_double);
let round = round_box(text);
let manual_round = boxen(
text,
Some(BoxenOptions {
border_style: BorderStyle::Round,
..Default::default()
}),
)
.unwrap();
assert_eq!(round, manual_round);
}