Split core and TUI crates
This commit is contained in:
182
crates/tele-tui/src/bin/tele-tui-test-fixture.rs
Normal file
182
crates/tele-tui/src/bin/tele-tui-test-fixture.rs
Normal file
@@ -0,0 +1,182 @@
|
||||
use std::io;
|
||||
use std::time::Duration;
|
||||
|
||||
use crossterm::{
|
||||
event::{
|
||||
self, DisableBracketedPaste, DisableMouseCapture, EnableBracketedPaste, EnableMouseCapture,
|
||||
Event, KeyCode, KeyEvent, KeyModifiers,
|
||||
},
|
||||
execute,
|
||||
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
|
||||
};
|
||||
use ratatui::{backend::CrosstermBackend, Terminal};
|
||||
use tele_tui::{
|
||||
app::{App, AppScreen},
|
||||
input::handle_main_input,
|
||||
test_support::{
|
||||
app_builder::TestAppBuilder,
|
||||
fake_tdclient::FakeTdClient,
|
||||
test_data::{TestChatBuilder, TestMessageBuilder},
|
||||
},
|
||||
};
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> io::Result<()> {
|
||||
let scenario = parse_scenario();
|
||||
let mut app = build_app(&scenario);
|
||||
|
||||
enable_raw_mode()?;
|
||||
let mut stdout = io::stdout();
|
||||
execute!(stdout, EnterAlternateScreen, EnableMouseCapture, EnableBracketedPaste)?;
|
||||
|
||||
let backend = CrosstermBackend::new(stdout);
|
||||
let mut terminal = Terminal::new(backend)?;
|
||||
let result = run_fixture(&mut terminal, &mut app).await;
|
||||
|
||||
disable_raw_mode()?;
|
||||
execute!(
|
||||
terminal.backend_mut(),
|
||||
LeaveAlternateScreen,
|
||||
DisableMouseCapture,
|
||||
DisableBracketedPaste
|
||||
)?;
|
||||
terminal.show_cursor()?;
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
fn parse_scenario() -> String {
|
||||
let mut args = std::env::args().skip(1);
|
||||
while let Some(arg) = args.next() {
|
||||
if arg == "--scenario" {
|
||||
return args.next().unwrap_or_else(|| "inbox".to_string());
|
||||
}
|
||||
}
|
||||
"inbox".to_string()
|
||||
}
|
||||
|
||||
async fn run_fixture(
|
||||
terminal: &mut Terminal<CrosstermBackend<io::Stdout>>,
|
||||
app: &mut App<FakeTdClient>,
|
||||
) -> io::Result<()> {
|
||||
loop {
|
||||
if app.needs_redraw {
|
||||
terminal.draw(|f| tele_tui::ui::render(f, app))?;
|
||||
app.needs_redraw = false;
|
||||
}
|
||||
|
||||
if event::poll(Duration::from_millis(16))? {
|
||||
match event::read()? {
|
||||
Event::Key(key) => {
|
||||
if key.code == KeyCode::Char('c')
|
||||
&& key.modifiers.contains(KeyModifiers::CONTROL)
|
||||
{
|
||||
return Ok(());
|
||||
}
|
||||
if key.code == KeyCode::F(10) {
|
||||
return Ok(());
|
||||
}
|
||||
handle_main_input(app, normalize_fixture_key(key)).await;
|
||||
app.needs_redraw = true;
|
||||
}
|
||||
Event::Resize(_, _) => {
|
||||
app.needs_redraw = true;
|
||||
}
|
||||
Event::Paste(text) => {
|
||||
for ch in text.chars() {
|
||||
handle_main_input(
|
||||
app,
|
||||
KeyEvent::new(KeyCode::Char(ch), KeyModifiers::NONE),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
app.needs_redraw = true;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn normalize_fixture_key(key: KeyEvent) -> KeyEvent {
|
||||
match (key.code, key.modifiers) {
|
||||
(KeyCode::Char('/'), KeyModifiers::NONE) => {
|
||||
KeyEvent::new(KeyCode::Char('s'), KeyModifiers::CONTROL)
|
||||
}
|
||||
(KeyCode::Char('j' | 'm'), modifiers) if modifiers.contains(KeyModifiers::CONTROL) => {
|
||||
KeyEvent::new(KeyCode::Enter, KeyModifiers::NONE)
|
||||
}
|
||||
_ => key,
|
||||
}
|
||||
}
|
||||
|
||||
fn build_app(scenario: &str) -> App<FakeTdClient> {
|
||||
match scenario {
|
||||
"open-chat" => TestAppBuilder::new()
|
||||
.screen(AppScreen::Main)
|
||||
.with_chats(sample_chats())
|
||||
.selected_chat(102)
|
||||
.with_messages(102, sample_messages())
|
||||
.build(),
|
||||
"compose-draft" => TestAppBuilder::new()
|
||||
.screen(AppScreen::Main)
|
||||
.with_chats(sample_chats())
|
||||
.selected_chat(102)
|
||||
.message_input("hello from e2e")
|
||||
.with_messages(102, sample_messages())
|
||||
.build(),
|
||||
"inbox" => TestAppBuilder::new()
|
||||
.screen(AppScreen::Main)
|
||||
.with_chats(sample_chats())
|
||||
.with_messages(101, mom_messages())
|
||||
.with_messages(102, sample_messages())
|
||||
.with_messages(103, boss_messages())
|
||||
.build(),
|
||||
other => {
|
||||
eprintln!("unknown scenario: {other}");
|
||||
std::process::exit(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn sample_chats() -> Vec<tele_tui::tdlib::ChatInfo> {
|
||||
vec![
|
||||
TestChatBuilder::new("Mom", 101)
|
||||
.last_message("Dinner at 7?")
|
||||
.unread_count(2)
|
||||
.build(),
|
||||
TestChatBuilder::new("Work Group", 102)
|
||||
.last_message("Standup notes are ready")
|
||||
.unread_mentions(1)
|
||||
.build(),
|
||||
TestChatBuilder::new("Boss", 103)
|
||||
.last_message("Please review the deck")
|
||||
.build(),
|
||||
]
|
||||
}
|
||||
|
||||
fn sample_messages() -> Vec<tele_tui::tdlib::MessageInfo> {
|
||||
vec![
|
||||
TestMessageBuilder::new("Morning, team", 201)
|
||||
.sender("Alice")
|
||||
.build(),
|
||||
TestMessageBuilder::new("Standup notes are ready", 202)
|
||||
.sender("Bob")
|
||||
.build(),
|
||||
TestMessageBuilder::new("Thanks, I will review them after lunch", 203)
|
||||
.outgoing()
|
||||
.build(),
|
||||
]
|
||||
}
|
||||
|
||||
fn mom_messages() -> Vec<tele_tui::tdlib::MessageInfo> {
|
||||
vec![TestMessageBuilder::new("Dinner at 7?", 301)
|
||||
.sender("Mom")
|
||||
.build()]
|
||||
}
|
||||
|
||||
fn boss_messages() -> Vec<tele_tui::tdlib::MessageInfo> {
|
||||
vec![TestMessageBuilder::new("Please review the deck", 401)
|
||||
.sender("Boss")
|
||||
.build()]
|
||||
}
|
||||
Reference in New Issue
Block a user