use super::*;
#[test]
fn vs16_widens_preceding_char() {
let mut screen = make_screen(24, 80);
screen.text('\u{2744}');
assert!(
!screen.cell(0, 0).unwrap().is_wide(),
"bare snowflake (no VS16) should still render width 1"
);
assert_eq!(screen.cursor(), Position { row: 0, col: 1 });
screen.text('\u{fe0f}');
assert!(
screen.cell(0, 0).unwrap().is_wide(),
"VS16 should retroactively widen the preceding snowflake"
);
assert!(
screen.cell(0, 1).unwrap().is_wide_continuation(),
"col 1 must become the wide continuation slot once VS16 widens col 0"
);
assert_eq!(screen.cursor(), Position { row: 0, col: 2 });
assert!(
screen.cell(0, 0).unwrap().contents().contains('\u{fe0f}'),
"VS16 selector must be retained in the cell contents for downstream rendering"
);
}
#[test]
fn vs16_emoji_then_text() {
let mut screen = make_screen(24, 80);
screen.text('\u{2744}');
screen.text('\u{fe0f}');
screen.text('X');
assert_eq!(screen.cursor(), Position { row: 0, col: 3 });
assert_eq!(screen.cell(0, 2).unwrap().contents(), "X");
}
#[test]
fn vs16_via_parser() {
let mut parser = crate::Parser::new(TerminalSize { rows: 24, cols: 80 }, 0);
process(&mut parser, "❄\u{fe0f}X".as_bytes());
let screen = parser.screen();
let c0 = screen.cell(0, 0).unwrap();
let c1 = screen.cell(0, 1).unwrap();
assert!(c0.is_wide(), "snowflake+VS16 should be wide");
assert!(c1.is_wide_continuation());
assert_eq!(screen.cell(0, 2).unwrap().contents(), "X");
assert_eq!(screen.cursor(), Position { row: 0, col: 3 });
}
#[test]
fn starship_prompt_with_emoji() {
let mut parser = crate::Parser::new(TerminalSize { rows: 24, cols: 80 }, 0);
let prompt = b"\x1b[J\x1b[1;36mtastty\x1b[0m on \x1b[1;35m\xee\x82\xa0 main\x1b[0m \x1b[1;31m[!]\x1b[0m via \x1b[1;34m\xe2\x9d\x84\xef\xb8\x8f (tastty-env)\x1b[0m \r\n\x1b[1;32m\xe2\x9d\xaf\x1b[0m ";
process(&mut parser, prompt);
let screen = parser.screen();
let mut found_snowflake = false;
for col in 0..80 {
let cell = screen.cell(0, col).unwrap();
if cell.has_contents() && cell.contents().starts_with('\u{2744}') {
assert!(cell.is_wide(), "snowflake+VS16 at col {col} should be wide");
let next = screen.cell(0, col + 1).unwrap();
assert!(
next.is_wide_continuation(),
"col {} should be wide continuation",
col + 1
);
found_snowflake = true;
break;
}
}
assert!(found_snowflake, "should find snowflake in prompt");
let r1c0 = screen.cell(1, 0).unwrap();
assert_eq!(r1c0.contents(), "\u{276f}");
process(&mut parser, b"\x1b[2J\x1b[H");
process(&mut parser, prompt);
let screen = parser.screen();
let mut found_snowflake = false;
for col in 0..80 {
let cell = screen.cell(0, col).unwrap();
if cell.has_contents() && cell.contents().starts_with('\u{2744}') {
assert!(
cell.is_wide(),
"after redraw: snowflake at col {col} should be wide"
);
let next = screen.cell(0, col + 1).unwrap();
assert!(
next.is_wide_continuation(),
"after redraw: col {} should be wide continuation",
col + 1
);
found_snowflake = true;
break;
}
}
assert!(found_snowflake, "should find snowflake after redraw");
let last_content_col = (0..80u16)
.rev()
.find(|&col| screen.cell(0, col).unwrap().has_contents())
.unwrap();
let last_cell = screen.cell(0, last_content_col).unwrap();
assert!(
last_cell.contents() == " "
|| last_cell.contents() == ")"
|| last_cell.is_wide_continuation(),
"last content at col {last_content_col} should not be a ghost: {:?}",
last_cell.contents()
);
}
#[test]
fn nerd_font_git_branch_width() {
let mut parser = crate::Parser::new(TerminalSize { rows: 24, cols: 80 }, 0);
process(&mut parser, "\u{e0a0}X".as_bytes());
let screen = parser.screen();
let c0 = screen.cell(0, 0).unwrap();
let c1 = screen.cell(0, 1).unwrap();
assert_eq!(c0.contents(), "\u{e0a0}");
assert!(!c0.is_wide());
assert_eq!(c1.contents(), "X");
}