forked from lavina/lavina
1
0
Fork 0
lavina/src/projections/irc/test.rs

145 lines
4.4 KiB
Rust

use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader};
use tokio::net::tcp::{ReadHalf, WriteHalf};
use tokio::net::TcpStream;
use crate::prelude::*;
struct TestScope<'a> {
reader: BufReader<ReadHalf<'a>>,
writer: WriteHalf<'a>,
buffer: Vec<u8>,
}
impl<'a> TestScope<'a> {
async fn send(&mut self, str: &(impl AsRef<str> + ?Sized)) -> Result<()> {
self.writer.write_all(str.as_ref().as_bytes()).await?;
self.writer.flush().await?;
Ok(())
}
async fn expect(&mut self, str: &(impl AsRef<str> + ?Sized)) -> Result<()> {
let len = self.reader.read_until(b'\n', &mut self.buffer).await?;
assert_eq!(std::str::from_utf8(&self.buffer[0..len])?, str.as_ref());
self.buffer.clear();
Ok(())
}
}
async fn init_client(stream: &mut TcpStream) -> Result<TestScope> {
let (reader, writer) = stream.split();
let reader = BufReader::new(reader);
let buffer = vec![];
Ok(TestScope {
reader,
writer,
buffer,
})
}
macro_rules! send {
($scope: expr, $($arg:tt),*) => {{
$scope.send(&format!($($arg,)*)).await?;
}};
}
macro_rules! expect {
($scope: expr, $($arg:tt),*) => {{
$scope.expect(&format!($($arg,)*)).await?;
}};
}
async fn registration(scope: &mut TestScope<'_>, nickname: &str) -> Result<()> {
expect!(scope, ":irc.localhost NOTICE * :Welcome to my server!\n");
send!(scope, "NICK {nickname}\n");
send!(scope, "USER UserName 0 * :Real Name\n");
expect!(
scope,
":irc.localhost 001 {nickname} :Welcome to Kek Server\n"
);
expect!(
scope,
":irc.localhost 002 {nickname} :Welcome to Kek Server\n"
);
expect!(
scope,
":irc.localhost 003 {nickname} :Welcome to Kek Server\n"
);
expect!(scope, ":irc.localhost 004 {nickname} irc.localhost kek-0.1.alpha.3 DGMQRSZagiloswz CFILPQbcefgijklmnopqrstvz bkloveqjfI\n");
expect!(
scope,
":irc.localhost 005 {nickname} CHANTYPES=# :are supported by this server\n"
);
Ok(())
}
async fn join(scope: &mut TestScope<'_>, nickname: &str) -> Result<()> {
send!(scope, "JOIN #channol\n");
expect!(scope, ":{nickname} JOIN #channol\n");
expect!(
scope,
":irc.localhost 332 {nickname} #channol :chan topic lol\n"
);
expect!(
scope,
":irc.localhost 353 {nickname} = #channol :{nickname}\n"
);
expect!(
scope,
":irc.localhost 366 {nickname} #channol :End of /NAMES list\n"
);
Ok(())
}
#[tokio::test]
async fn test_registration() -> Result<()> {
let mut stream = TcpStream::connect("127.0.0.1:6667").await?;
let mut scope = init_client(&mut stream).await?;
registration(&mut scope, "NickName").await?;
join(&mut scope, "NickName").await?;
Ok(())
}
#[tokio::test]
async fn test_two_connections_one_player() -> Result<()> {
let mut stream1 = TcpStream::connect("127.0.0.1:6667").await?;
let mut scope1 = init_client(&mut stream1).await?;
let mut stream2 = TcpStream::connect("127.0.0.1:6667").await?;
let mut scope2 = init_client(&mut stream2).await?;
registration(&mut scope1, "NickName").await?;
registration(&mut scope2, "NickName").await?;
join(&mut scope1, "NickName").await?;
join(&mut scope2, "NickName").await?;
send!(scope1, "PRIVMSG #channol :Chmoki vsem v etam chati!\n");
expect!(
scope2,
":NickName PRIVMSG #channol :Chmoki vsem v etam chati!\n"
);
send!(scope2, "PRIVMSG #channol :I tebe privetiki\n");
expect!(scope1, ":NickName PRIVMSG #channol :I tebe privetiki\n");
Ok(())
}
#[tokio::test]
async fn test_two_players() -> Result<()> {
let mut stream1 = TcpStream::connect("127.0.0.1:6667").await?;
let mut scope1 = init_client(&mut stream1).await?;
let mut stream2 = TcpStream::connect("127.0.0.1:6667").await?;
let mut scope2 = init_client(&mut stream2).await?;
registration(&mut scope1, "NickName1").await?;
registration(&mut scope2, "NickName2").await?;
join(&mut scope1, "NickName1").await?;
join(&mut scope2, "NickName2").await?;
send!(scope1, "PRIVMSG #channol :Chmoki vsem v etam chati!\n");
expect!(
scope2,
":NickName1 PRIVMSG #channol :Chmoki vsem v etam chati!\n"
);
send!(scope2, "PRIVMSG #channol :I tebe privetiki\n");
expect!(scope1, ":NickName2 PRIVMSG #channol :I tebe privetiki\n");
Ok(())
}