| use tui::backend::TestBackend; |
| use tui::buffer::Buffer; |
| use tui::layout::Constraint; |
| use tui::widgets::{Block, Borders, Row, Table}; |
| use tui::Terminal; |
| |
| #[test] |
| fn widgets_table_column_spacing_can_be_changed() { |
| let test_case = |column_spacing, expected| { |
| let backend = TestBackend::new(30, 10); |
| let mut terminal = Terminal::new(backend).unwrap(); |
| |
| terminal |
| .draw(|f| { |
| let size = f.size(); |
| let table = Table::new( |
| ["Head1", "Head2", "Head3"].iter(), |
| vec![ |
| Row::Data(["Row11", "Row12", "Row13"].iter()), |
| Row::Data(["Row21", "Row22", "Row23"].iter()), |
| Row::Data(["Row31", "Row32", "Row33"].iter()), |
| Row::Data(["Row41", "Row42", "Row43"].iter()), |
| ] |
| .into_iter(), |
| ) |
| .block(Block::default().borders(Borders::ALL)) |
| .widths(&[ |
| Constraint::Length(5), |
| Constraint::Length(5), |
| Constraint::Length(5), |
| ]) |
| .column_spacing(column_spacing); |
| f.render_widget(table, size); |
| }) |
| .unwrap(); |
| terminal.backend().assert_buffer(&expected); |
| }; |
| |
| // no space between columns |
| test_case( |
| 0, |
| Buffer::with_lines(vec![ |
| "┌────────────────────────────┐", |
| "│Head1Head2Head3 │", |
| "│ │", |
| "│Row11Row12Row13 │", |
| "│Row21Row22Row23 │", |
| "│Row31Row32Row33 │", |
| "│Row41Row42Row43 │", |
| "│ │", |
| "│ │", |
| "└────────────────────────────┘", |
| ]), |
| ); |
| |
| // one space between columns |
| test_case( |
| 1, |
| Buffer::with_lines(vec![ |
| "┌────────────────────────────┐", |
| "│Head1 Head2 Head3 │", |
| "│ │", |
| "│Row11 Row12 Row13 │", |
| "│Row21 Row22 Row23 │", |
| "│Row31 Row32 Row33 │", |
| "│Row41 Row42 Row43 │", |
| "│ │", |
| "│ │", |
| "└────────────────────────────┘", |
| ]), |
| ); |
| |
| // enough space to just not hide the third column |
| test_case( |
| 6, |
| Buffer::with_lines(vec![ |
| "┌────────────────────────────┐", |
| "│Head1 Head2 Head3 │", |
| "│ │", |
| "│Row11 Row12 Row13 │", |
| "│Row21 Row22 Row23 │", |
| "│Row31 Row32 Row33 │", |
| "│Row41 Row42 Row43 │", |
| "│ │", |
| "│ │", |
| "└────────────────────────────┘", |
| ]), |
| ); |
| |
| // enough space to hide part of the third column |
| test_case( |
| 7, |
| Buffer::with_lines(vec![ |
| "┌────────────────────────────┐", |
| "│Head1 Head2 Head│", |
| "│ │", |
| "│Row11 Row12 Row1│", |
| "│Row21 Row22 Row2│", |
| "│Row31 Row32 Row3│", |
| "│Row41 Row42 Row4│", |
| "│ │", |
| "│ │", |
| "└────────────────────────────┘", |
| ]), |
| ); |
| } |
| |
| #[test] |
| fn widgets_table_columns_widths_can_use_fixed_length_constraints() { |
| let test_case = |widths, expected| { |
| let backend = TestBackend::new(30, 10); |
| let mut terminal = Terminal::new(backend).unwrap(); |
| |
| terminal |
| .draw(|f| { |
| let size = f.size(); |
| let table = Table::new( |
| ["Head1", "Head2", "Head3"].iter(), |
| vec![ |
| Row::Data(["Row11", "Row12", "Row13"].iter()), |
| Row::Data(["Row21", "Row22", "Row23"].iter()), |
| Row::Data(["Row31", "Row32", "Row33"].iter()), |
| Row::Data(["Row41", "Row42", "Row43"].iter()), |
| ] |
| .into_iter(), |
| ) |
| .block(Block::default().borders(Borders::ALL)) |
| .widths(widths); |
| f.render_widget(table, size); |
| }) |
| .unwrap(); |
| terminal.backend().assert_buffer(&expected); |
| }; |
| |
| // columns of zero width show nothing |
| test_case( |
| &[ |
| Constraint::Length(0), |
| Constraint::Length(0), |
| Constraint::Length(0), |
| ], |
| Buffer::with_lines(vec![ |
| "┌────────────────────────────┐", |
| "│ │", |
| "│ │", |
| "│ │", |
| "│ │", |
| "│ │", |
| "│ │", |
| "│ │", |
| "│ │", |
| "└────────────────────────────┘", |
| ]), |
| ); |
| |
| // columns of 1 width trim |
| test_case( |
| &[ |
| Constraint::Length(1), |
| Constraint::Length(1), |
| Constraint::Length(1), |
| ], |
| Buffer::with_lines(vec![ |
| "┌────────────────────────────┐", |
| "│H H H │", |
| "│ │", |
| "│R R R │", |
| "│R R R │", |
| "│R R R │", |
| "│R R R │", |
| "│ │", |
| "│ │", |
| "└────────────────────────────┘", |
| ]), |
| ); |
| |
| // columns of large width just before pushing a column off |
| test_case( |
| &[ |
| Constraint::Length(8), |
| Constraint::Length(8), |
| Constraint::Length(8), |
| ], |
| Buffer::with_lines(vec![ |
| "┌────────────────────────────┐", |
| "│Head1 Head2 Head3 │", |
| "│ │", |
| "│Row11 Row12 Row13 │", |
| "│Row21 Row22 Row23 │", |
| "│Row31 Row32 Row33 │", |
| "│Row41 Row42 Row43 │", |
| "│ │", |
| "│ │", |
| "└────────────────────────────┘", |
| ]), |
| ); |
| } |
| |
| #[test] |
| fn widgets_table_columns_widths_can_use_percentage_constraints() { |
| let test_case = |widths, expected| { |
| let backend = TestBackend::new(30, 10); |
| let mut terminal = Terminal::new(backend).unwrap(); |
| |
| terminal |
| .draw(|f| { |
| let size = f.size(); |
| let table = Table::new( |
| ["Head1", "Head2", "Head3"].iter(), |
| vec![ |
| Row::Data(["Row11", "Row12", "Row13"].iter()), |
| Row::Data(["Row21", "Row22", "Row23"].iter()), |
| Row::Data(["Row31", "Row32", "Row33"].iter()), |
| Row::Data(["Row41", "Row42", "Row43"].iter()), |
| ] |
| .into_iter(), |
| ) |
| .block(Block::default().borders(Borders::ALL)) |
| .widths(widths) |
| .column_spacing(0); |
| f.render_widget(table, size); |
| }) |
| .unwrap(); |
| terminal.backend().assert_buffer(&expected); |
| }; |
| |
| // columns of zero width show nothing |
| test_case( |
| &[ |
| Constraint::Percentage(0), |
| Constraint::Percentage(0), |
| Constraint::Percentage(0), |
| ], |
| Buffer::with_lines(vec![ |
| "┌────────────────────────────┐", |
| "│ │", |
| "│ │", |
| "│ │", |
| "│ │", |
| "│ │", |
| "│ │", |
| "│ │", |
| "│ │", |
| "└────────────────────────────┘", |
| ]), |
| ); |
| |
| // columns of not enough width trims the data |
| test_case( |
| &[ |
| Constraint::Percentage(10), |
| Constraint::Percentage(10), |
| Constraint::Percentage(10), |
| ], |
| Buffer::with_lines(vec![ |
| "┌────────────────────────────┐", |
| "│HeaHeaHea │", |
| "│ │", |
| "│RowRowRow │", |
| "│RowRowRow │", |
| "│RowRowRow │", |
| "│RowRowRow │", |
| "│ │", |
| "│ │", |
| "└────────────────────────────┘", |
| ]), |
| ); |
| |
| // columns of large width just before pushing a column off |
| test_case( |
| &[ |
| Constraint::Percentage(30), |
| Constraint::Percentage(30), |
| Constraint::Percentage(30), |
| ], |
| Buffer::with_lines(vec![ |
| "┌────────────────────────────┐", |
| "│Head1 Head2 Head3 │", |
| "│ │", |
| "│Row11 Row12 Row13 │", |
| "│Row21 Row22 Row23 │", |
| "│Row31 Row32 Row33 │", |
| "│Row41 Row42 Row43 │", |
| "│ │", |
| "│ │", |
| "└────────────────────────────┘", |
| ]), |
| ); |
| |
| // percentages summing to 100 should give equal widths |
| test_case( |
| &[Constraint::Percentage(50), Constraint::Percentage(50)], |
| Buffer::with_lines(vec![ |
| "┌────────────────────────────┐", |
| "│Head1 Head2 │", |
| "│ │", |
| "│Row11 Row12 │", |
| "│Row21 Row22 │", |
| "│Row31 Row32 │", |
| "│Row41 Row42 │", |
| "│ │", |
| "│ │", |
| "└────────────────────────────┘", |
| ]), |
| ); |
| } |
| |
| #[test] |
| fn widgets_table_columns_widths_can_use_mixed_constraints() { |
| let test_case = |widths, expected| { |
| let backend = TestBackend::new(30, 10); |
| let mut terminal = Terminal::new(backend).unwrap(); |
| |
| terminal |
| .draw(|f| { |
| let size = f.size(); |
| let table = Table::new( |
| ["Head1", "Head2", "Head3"].iter(), |
| vec![ |
| Row::Data(["Row11", "Row12", "Row13"].iter()), |
| Row::Data(["Row21", "Row22", "Row23"].iter()), |
| Row::Data(["Row31", "Row32", "Row33"].iter()), |
| Row::Data(["Row41", "Row42", "Row43"].iter()), |
| ] |
| .into_iter(), |
| ) |
| .block(Block::default().borders(Borders::ALL)) |
| .widths(widths); |
| f.render_widget(table, size); |
| }) |
| .unwrap(); |
| terminal.backend().assert_buffer(&expected); |
| }; |
| |
| // columns of zero width show nothing |
| test_case( |
| &[ |
| Constraint::Percentage(0), |
| Constraint::Length(0), |
| Constraint::Percentage(0), |
| ], |
| Buffer::with_lines(vec![ |
| "┌────────────────────────────┐", |
| "│ │", |
| "│ │", |
| "│ │", |
| "│ │", |
| "│ │", |
| "│ │", |
| "│ │", |
| "│ │", |
| "└────────────────────────────┘", |
| ]), |
| ); |
| |
| // columns of not enough width trims the data |
| test_case( |
| &[ |
| Constraint::Percentage(10), |
| Constraint::Length(20), |
| Constraint::Percentage(10), |
| ], |
| Buffer::with_lines(vec![ |
| "┌────────────────────────────┐", |
| "│Hea Head2 Hea│", |
| "│ │", |
| "│Row Row12 Row│", |
| "│Row Row22 Row│", |
| "│Row Row32 Row│", |
| "│Row Row42 Row│", |
| "│ │", |
| "│ │", |
| "└────────────────────────────┘", |
| ]), |
| ); |
| |
| // columns of large width just before pushing a column off |
| test_case( |
| &[ |
| Constraint::Percentage(30), |
| Constraint::Length(10), |
| Constraint::Percentage(30), |
| ], |
| Buffer::with_lines(vec![ |
| "┌────────────────────────────┐", |
| "│Head1 Head2 Head3 │", |
| "│ │", |
| "│Row11 Row12 Row13 │", |
| "│Row21 Row22 Row23 │", |
| "│Row31 Row32 Row33 │", |
| "│Row41 Row42 Row43 │", |
| "│ │", |
| "│ │", |
| "└────────────────────────────┘", |
| ]), |
| ); |
| |
| // columns of large size (>100% total) hide the last column |
| test_case( |
| &[ |
| Constraint::Percentage(60), |
| Constraint::Length(10), |
| Constraint::Percentage(60), |
| ], |
| Buffer::with_lines(vec![ |
| "┌────────────────────────────┐", |
| "│Head1 Head2 │", |
| "│ │", |
| "│Row11 Row12 │", |
| "│Row21 Row22 │", |
| "│Row31 Row32 │", |
| "│Row41 Row42 │", |
| "│ │", |
| "│ │", |
| "└────────────────────────────┘", |
| ]), |
| ); |
| } |