2020-05-21 18:17:55 +00:00
|
|
|
use tui::{
|
|
|
|
backend::TestBackend,
|
|
|
|
buffer::Buffer,
|
|
|
|
layout::Alignment,
|
|
|
|
widgets::{Block, Borders, Paragraph, Text},
|
|
|
|
Terminal,
|
|
|
|
};
|
2018-12-07 19:29:22 +00:00
|
|
|
|
2020-02-23 14:46:30 +00:00
|
|
|
const SAMPLE_STRING: &str = "The library is based on the principle of immediate rendering with \
|
2018-12-08 17:28:25 +00:00
|
|
|
intermediate buffers. This means that at each new frame you should build all widgets that are \
|
|
|
|
supposed to be part of the UI. While providing a great flexibility for rich and \
|
|
|
|
interactive UI, this may introduce overhead for highly dynamic content.";
|
2018-12-07 19:29:22 +00:00
|
|
|
|
2018-12-08 17:28:25 +00:00
|
|
|
#[test]
|
2020-05-21 18:42:34 +00:00
|
|
|
fn widgets_paragraph_can_wrap_its_content() {
|
2020-05-21 18:17:55 +00:00
|
|
|
let test_case = |alignment, expected| {
|
2018-12-08 17:28:25 +00:00
|
|
|
let backend = TestBackend::new(20, 10);
|
|
|
|
let mut terminal = Terminal::new(backend).unwrap();
|
2018-12-07 19:29:22 +00:00
|
|
|
|
2018-12-08 17:28:25 +00:00
|
|
|
terminal
|
2020-06-15 20:57:23 +00:00
|
|
|
.draw(|f| {
|
2018-12-08 17:28:25 +00:00
|
|
|
let size = f.size();
|
|
|
|
let text = [Text::raw(SAMPLE_STRING)];
|
2019-12-15 20:38:18 +00:00
|
|
|
let paragraph = Paragraph::new(text.iter())
|
2018-12-08 17:28:25 +00:00
|
|
|
.block(Block::default().borders(Borders::ALL))
|
|
|
|
.alignment(alignment)
|
2019-12-15 20:38:18 +00:00
|
|
|
.wrap(true);
|
|
|
|
f.render_widget(paragraph, size);
|
2018-12-08 17:28:25 +00:00
|
|
|
})
|
|
|
|
.unwrap();
|
2020-05-21 18:17:55 +00:00
|
|
|
terminal.backend().assert_buffer(&expected);
|
2018-12-08 17:28:25 +00:00
|
|
|
};
|
2018-12-07 19:29:22 +00:00
|
|
|
|
2020-05-21 18:17:55 +00:00
|
|
|
test_case(
|
|
|
|
Alignment::Left,
|
2018-12-08 17:28:25 +00:00
|
|
|
Buffer::with_lines(vec![
|
|
|
|
"┌──────────────────┐",
|
|
|
|
"│The library is │",
|
|
|
|
"│based on the │",
|
|
|
|
"│principle of │",
|
|
|
|
"│immediate │",
|
|
|
|
"│rendering with │",
|
|
|
|
"│intermediate │",
|
|
|
|
"│buffers. This │",
|
|
|
|
"│means that at each│",
|
|
|
|
"└──────────────────┘",
|
2020-05-21 18:17:55 +00:00
|
|
|
]),
|
2018-12-08 17:28:25 +00:00
|
|
|
);
|
2020-05-21 18:17:55 +00:00
|
|
|
test_case(
|
|
|
|
Alignment::Right,
|
2018-12-08 17:28:25 +00:00
|
|
|
Buffer::with_lines(vec![
|
|
|
|
"┌──────────────────┐",
|
|
|
|
"│ The library is│",
|
|
|
|
"│ based on the│",
|
|
|
|
"│ principle of│",
|
|
|
|
"│ immediate│",
|
|
|
|
"│ rendering with│",
|
|
|
|
"│ intermediate│",
|
|
|
|
"│ buffers. This│",
|
|
|
|
"│means that at each│",
|
|
|
|
"└──────────────────┘",
|
2020-05-21 18:17:55 +00:00
|
|
|
]),
|
2018-12-08 17:28:25 +00:00
|
|
|
);
|
2020-05-21 18:17:55 +00:00
|
|
|
test_case(
|
|
|
|
Alignment::Center,
|
2018-12-08 17:28:25 +00:00
|
|
|
Buffer::with_lines(vec![
|
|
|
|
"┌──────────────────┐",
|
|
|
|
"│ The library is │",
|
|
|
|
"│ based on the │",
|
|
|
|
"│ principle of │",
|
|
|
|
"│ immediate │",
|
|
|
|
"│ rendering with │",
|
|
|
|
"│ intermediate │",
|
|
|
|
"│ buffers. This │",
|
|
|
|
"│means that at each│",
|
|
|
|
"└──────────────────┘",
|
2020-05-21 18:17:55 +00:00
|
|
|
]),
|
2018-12-08 17:28:25 +00:00
|
|
|
);
|
2018-12-07 19:29:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2020-05-21 18:42:34 +00:00
|
|
|
fn widgets_paragraph_renders_double_width_graphemes() {
|
2018-12-07 19:29:22 +00:00
|
|
|
let backend = TestBackend::new(10, 10);
|
|
|
|
let mut terminal = Terminal::new(backend).unwrap();
|
|
|
|
|
2019-11-05 07:08:14 +00:00
|
|
|
let s = "コンピュータ上で文字を扱う場合、典型的には文字による通信を行う場合にその両端点では、";
|
2018-12-07 19:29:22 +00:00
|
|
|
terminal
|
2020-06-15 20:57:23 +00:00
|
|
|
.draw(|f| {
|
2018-12-07 19:29:22 +00:00
|
|
|
let size = f.size();
|
|
|
|
let text = [Text::raw(s)];
|
2019-12-15 20:38:18 +00:00
|
|
|
let paragraph = Paragraph::new(text.iter())
|
2018-12-07 19:29:22 +00:00
|
|
|
.block(Block::default().borders(Borders::ALL))
|
2019-12-15 20:38:18 +00:00
|
|
|
.wrap(true);
|
|
|
|
f.render_widget(paragraph, size);
|
2018-12-07 19:29:22 +00:00
|
|
|
})
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
let expected = Buffer::with_lines(vec![
|
|
|
|
"┌────────┐",
|
2018-12-14 17:33:05 +00:00
|
|
|
"│コンピュ│",
|
|
|
|
"│ータ上で│",
|
|
|
|
"│文字を扱│",
|
|
|
|
"│う場合、│",
|
|
|
|
"│典型的に│",
|
|
|
|
"│は文字に│",
|
|
|
|
"│よる通信│",
|
|
|
|
"│を行う場│",
|
2018-12-07 19:29:22 +00:00
|
|
|
"└────────┘",
|
|
|
|
]);
|
2020-05-21 18:17:55 +00:00
|
|
|
terminal.backend().assert_buffer(&expected);
|
2018-12-07 19:29:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2020-05-21 18:42:34 +00:00
|
|
|
fn widgets_paragraph_renders_mixed_width_graphemes() {
|
2018-12-07 19:29:22 +00:00
|
|
|
let backend = TestBackend::new(10, 7);
|
|
|
|
let mut terminal = Terminal::new(backend).unwrap();
|
|
|
|
|
|
|
|
let s = "aコンピュータ上で文字を扱う場合、";
|
|
|
|
terminal
|
2020-06-15 20:57:23 +00:00
|
|
|
.draw(|f| {
|
2018-12-07 19:29:22 +00:00
|
|
|
let size = f.size();
|
|
|
|
let text = [Text::raw(s)];
|
2019-12-15 20:38:18 +00:00
|
|
|
let paragraph = Paragraph::new(text.iter())
|
2018-12-07 19:29:22 +00:00
|
|
|
.block(Block::default().borders(Borders::ALL))
|
2019-12-15 20:38:18 +00:00
|
|
|
.wrap(true);
|
|
|
|
f.render_widget(paragraph, size);
|
2018-12-07 19:29:22 +00:00
|
|
|
})
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
let expected = Buffer::with_lines(vec![
|
|
|
|
// The internal width is 8 so only 4 slots for double-width characters.
|
|
|
|
"┌────────┐",
|
2018-12-14 17:33:05 +00:00
|
|
|
"│aコンピ │", // Here we have 1 latin character so only 3 double-width ones can fit.
|
|
|
|
"│ュータ上│",
|
|
|
|
"│で文字を│",
|
|
|
|
"│扱う場合│",
|
|
|
|
"│、 │",
|
2018-12-07 19:29:22 +00:00
|
|
|
"└────────┘",
|
|
|
|
]);
|
2020-05-21 18:17:55 +00:00
|
|
|
terminal.backend().assert_buffer(&expected);
|
2018-12-07 19:29:22 +00:00
|
|
|
}
|
2020-07-06 21:47:52 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn widgets_paragraph_can_scroll_horizontally() {
|
|
|
|
let test_case = |alignment, scroll, expected| {
|
|
|
|
let backend = TestBackend::new(20, 10);
|
|
|
|
let mut terminal = Terminal::new(backend).unwrap();
|
|
|
|
|
|
|
|
terminal
|
|
|
|
.draw(|f| {
|
|
|
|
let size = f.size();
|
|
|
|
let text = [Text::raw(
|
|
|
|
"段落现在可以水平滚动了!
|
|
|
|
Paragraph can scroll horizontally!
|
|
|
|
Short line
|
|
|
|
",
|
|
|
|
)];
|
|
|
|
let paragraph = Paragraph::new(text.iter())
|
|
|
|
.block(Block::default().borders(Borders::ALL))
|
|
|
|
.alignment(alignment)
|
|
|
|
.scroll(scroll);
|
|
|
|
f.render_widget(paragraph, size);
|
|
|
|
})
|
|
|
|
.unwrap();
|
|
|
|
terminal.backend().assert_buffer(&expected);
|
|
|
|
};
|
|
|
|
|
|
|
|
test_case(
|
|
|
|
Alignment::Left,
|
|
|
|
(0, 7),
|
|
|
|
Buffer::with_lines(vec![
|
|
|
|
"┌──────────────────┐",
|
|
|
|
"│在可以水平滚动了!│",
|
|
|
|
"│ph can scroll hori│",
|
|
|
|
"│ine │",
|
|
|
|
"│ │",
|
|
|
|
"│ │",
|
|
|
|
"│ │",
|
|
|
|
"│ │",
|
|
|
|
"│ │",
|
|
|
|
"└──────────────────┘",
|
|
|
|
]),
|
|
|
|
);
|
|
|
|
// only support Alignment::Left
|
|
|
|
test_case(
|
|
|
|
Alignment::Right,
|
|
|
|
(0, 7),
|
|
|
|
Buffer::with_lines(vec![
|
|
|
|
"┌──────────────────┐",
|
|
|
|
"│段落现在可以水平滚│",
|
|
|
|
"│Paragraph can scro│",
|
|
|
|
"│ Short line│",
|
|
|
|
"│ │",
|
|
|
|
"│ │",
|
|
|
|
"│ │",
|
|
|
|
"│ │",
|
|
|
|
"│ │",
|
|
|
|
"└──────────────────┘",
|
|
|
|
]),
|
|
|
|
);
|
|
|
|
}
|