use std::ops::Deref; use protocol::bridge_engine::TableState; use rand::{random, thread_rng, Rng}; use server::{ error::BridgeError, table::{DbTable, InMemoryTable, Table}, }; use tracing::info; use uuid::Uuid; mod common; async fn table_basic_test(mut table: Box) -> Result<(), anyhow::Error> where T: Table + Send, { assert!(matches!(table.state(), TableState::Unknown)); table = table.set_board(0, random()).await?; assert!(matches!(table.state(), TableState::Game(_))); while matches!(table.state(), TableState::Game(_)) { table = server::table::advance_play(table).await?; } assert!(matches!(table.state(), TableState::Result(_))); table = table.set_board(1, random()).await?; assert!(matches!(table.state(), TableState::Game(_))); Ok(()) } async fn advance_table(table: Box) -> Result, BridgeError> where T: Table + Send, { let board_number = table.board_number() + 1; match table.state() { TableState::Unknown => panic!("unexpected state"), TableState::Game(_) => server::table::advance_play(table).await, TableState::Result(_) => table.set_board(board_number, random()).await, } } #[tokio::test] #[ignore] async fn in_memory_table() -> Result<(), anyhow::Error> { common::test_setup(); table_basic_test(Box::new(InMemoryTable::new())).await?; Ok(()) } #[tokio::test] #[ignore] async fn db_table() -> Result<(), anyhow::Error> { let db = common::TestDb::new().await; table_basic_test(Box::new( DbTable::new(db.db().clone(), Uuid::new_v4(), InMemoryTable::new()) .await?, )) .await?; Ok(()) } // Table testing: // Creating a table for a specific owner. // Recreating a table with the same owner should return the same table. #[tokio::test] #[ignore] async fn db_table_idempotent() -> Result<(), anyhow::Error> { let db = common::TestDb::new().await; let uuid = Uuid::new_v4(); let table1 = Box::new( DbTable::new(db.db().clone(), uuid, InMemoryTable::new()).await?, ); let table2 = Box::new( DbTable::new(db.db().clone(), uuid, InMemoryTable::new()).await?, ); assert_eq!(table1.state(), table2.state()); Ok(()) } #[tokio::test] #[ignore] async fn db_table_persistence() -> Result<(), anyhow::Error> { let db = common::TestDb::new().await; let id = Uuid::new_v4(); let create_table = { || async { let db = db.db().clone(); Box::new(DbTable::new(db, id, InMemoryTable::new()).await.unwrap()) } }; let mut table = create_table().await; table = table.set_board(1, random()).await?; assert_eq!(table.state(), create_table().await.state()); for i in 0..(thread_rng().gen_range(0..200)) { info!("move {i}"); table = advance_table(table).await?; assert_eq!(table.state(), create_table().await.state()); } Ok(()) }