mod util;
extern crate buttplug;
use buttplug::{
client::{ButtplugClient, ButtplugClientError, ButtplugClientEvent, VibrateCommand},
connector::{
ButtplugConnector,
ButtplugConnectorError,
ButtplugConnectorResultFuture,
ButtplugInProcessClientConnector,
},
core::{
errors::{ButtplugDeviceError, ButtplugError},
messages::{ButtplugCurrentSpecClientMessage, ButtplugCurrentSpecServerMessage},
},
device::{Endpoint, DeviceImplCommand, DeviceWriteCmd},
server::ButtplugServerOptions,
test::check_test_recv_value,
util::async_manager,
};
use futures::{future::BoxFuture, StreamExt};
use futures_timer::Delay;
use std::time::Duration;
use tokio::sync::mpsc::Sender;
use util::DelayDeviceCommunicationManager;
#[derive(Default)]
struct ButtplugFailingConnector {}
impl ButtplugConnector<ButtplugCurrentSpecClientMessage, ButtplugCurrentSpecServerMessage>
for ButtplugFailingConnector
{
fn connect(
&mut self,
_: Sender<ButtplugCurrentSpecServerMessage>,
) -> BoxFuture<'static, Result<(), ButtplugConnectorError>> {
ButtplugConnectorError::ConnectorNotConnected.into()
}
fn disconnect(&self) -> ButtplugConnectorResultFuture {
ButtplugConnectorError::ConnectorNotConnected.into()
}
fn send(&self, _msg: ButtplugCurrentSpecClientMessage) -> ButtplugConnectorResultFuture {
panic!("Should never be called")
}
}
#[cfg(feature = "server")]
#[test]
fn test_failing_connection() {
async_manager::block_on(async {
let client = ButtplugClient::new("Test Client");
assert!(client
.connect(ButtplugFailingConnector::default())
.await
.is_err());
});
}
#[cfg(feature = "server")]
#[test]
fn test_disconnect_status() {
async_manager::block_on(async {
let client = ButtplugClient::new("Test Client");
client
.connect(ButtplugInProcessClientConnector::default())
.await
.unwrap();
assert!(client.disconnect().await.is_ok());
assert!(!client.connected());
});
}
#[cfg(feature = "server")]
#[test]
fn test_double_disconnect() {
async_manager::block_on(async {
let client = ButtplugClient::new("Test Client");
client
.connect(ButtplugInProcessClientConnector::default())
.await
.unwrap();
assert!(client.disconnect().await.is_ok());
assert!(client.disconnect().await.is_err());
});
}
#[cfg(feature = "server")]
#[test]
fn test_connect_init() {
async_manager::block_on(async {
let client = ButtplugClient::new("Test Client");
client
.connect(ButtplugInProcessClientConnector::default())
.await
.unwrap();
assert_eq!(client.server_name(), Some("Buttplug Server".to_owned()));
});
}
#[cfg(feature = "server")]
#[test]
fn test_client_connected_status() {
async_manager::block_on(async {
let client = ButtplugClient::new("Test Client");
assert!(!client.connected());
client
.connect(ButtplugInProcessClientConnector::default())
.await
.unwrap();
assert!(client.connected());
client.disconnect().await.unwrap();
assert!(!client.connected());
});
}
#[cfg(feature = "server")]
#[test]
fn test_start_scanning() {
async_manager::block_on(async {
let connector = ButtplugInProcessClientConnector::default();
let test_mgr_helper = connector.server_ref().add_test_comm_manager().unwrap();
test_mgr_helper.add_ble_device("Massage Demo").await;
let client = ButtplugClient::new("Test Client");
client.connect(connector).await.unwrap();
assert!(client.start_scanning().await.is_ok());
});
}
#[cfg(feature = "server")]
#[test]
#[ignore]
fn test_stop_scanning_when_not_scanning() {
async_manager::block_on(async {
let connector = ButtplugInProcessClientConnector::default();
connector
.server_ref()
.add_comm_manager::<DelayDeviceCommunicationManager>()
.unwrap();
let client = ButtplugClient::new("Test Client");
client.connect(connector).await.unwrap();
let should_be_err = client.stop_scanning().await;
if let Err(ButtplugClientError::ButtplugError(bp_err)) = should_be_err {
assert!(matches!(
bp_err,
ButtplugError::ButtplugDeviceError(ButtplugDeviceError::DeviceScanningAlreadyStopped)
));
} else {
panic!("Should've thrown error!");
}
assert!(client.stop_scanning().await.is_err());
});
}
#[cfg(feature = "server")]
#[test]
fn test_start_scanning_when_already_scanning() {
async_manager::block_on(async {
let connector = ButtplugInProcessClientConnector::default();
connector
.server_ref()
.add_comm_manager::<DelayDeviceCommunicationManager>()
.unwrap();
let client = ButtplugClient::new("Test Client");
client.connect(connector).await.unwrap();
assert!(client.start_scanning().await.is_ok());
assert!(client.start_scanning().await.is_err());
});
}
#[cfg(feature = "server")]
#[test]
fn test_client_scanning_finished() {
async_manager::block_on(async {
let connector = ButtplugInProcessClientConnector::default();
connector
.server_ref()
.add_comm_manager::<DelayDeviceCommunicationManager>()
.unwrap();
let client = ButtplugClient::new("Test Client");
let mut recv = client.event_stream();
client.connect(connector).await.unwrap();
assert!(client.start_scanning().await.is_ok());
assert!(client.stop_scanning().await.is_ok());
assert!(matches!(
recv.next().await.unwrap(),
ButtplugClientEvent::ScanningFinished
));
});
}
#[cfg(feature = "server")]
#[test]
fn test_client_ping() {
async_manager::block_on(async {
let mut options = ButtplugServerOptions::default();
options.max_ping_time = 200;
let connector = ButtplugInProcessClientConnector::new_with_options(&options).unwrap();
let client = ButtplugClient::new("Test Client");
client.connect(connector).await.unwrap();
assert!(client.ping().await.is_ok());
Delay::new(Duration::from_millis(800)).await;
assert!(client.ping().await.is_err());
});
}
#[cfg(feature = "server")]
#[test]
fn test_stop_all_devices_and_device_command_range() {
async_manager::block_on(async {
let connector = ButtplugInProcessClientConnector::default();
let test_mgr_helper = connector.server_ref().add_test_comm_manager().unwrap();
let test_device = test_mgr_helper.add_ble_device("Massage Demo").await;
let client = ButtplugClient::new("Test Client");
let mut event_stream = client.event_stream();
client.connect(connector).await.unwrap();
assert!(client.start_scanning().await.is_ok());
while let Some(event) = event_stream.next().await {
if let ButtplugClientEvent::DeviceAdded(dev) = event {
assert!(dev.vibrate(VibrateCommand::Speed(0.5)).await.is_ok());
let command_receiver = test_device.get_endpoint_receiver(&Endpoint::Tx).unwrap();
check_test_recv_value(
&command_receiver,
DeviceImplCommand::Write(DeviceWriteCmd::new(Endpoint::Tx, vec![0xF1, 64], false)),
);
check_test_recv_value(
&command_receiver,
DeviceImplCommand::Write(DeviceWriteCmd::new(Endpoint::Tx, vec![0xF2, 64], false)),
);
assert!(dev.vibrate(VibrateCommand::Speed(1.0)).await.is_ok());
check_test_recv_value(
&command_receiver,
DeviceImplCommand::Write(DeviceWriteCmd::new(Endpoint::Tx, vec![0xF1, 127], false)),
);
check_test_recv_value(
&command_receiver,
DeviceImplCommand::Write(DeviceWriteCmd::new(Endpoint::Tx, vec![0xF2, 127], false)),
);
assert!(client.stop_all_devices().await.is_ok());
check_test_recv_value(
&command_receiver,
DeviceImplCommand::Write(DeviceWriteCmd::new(Endpoint::Tx, vec![0xF1, 0], false)),
);
check_test_recv_value(
&command_receiver,
DeviceImplCommand::Write(DeviceWriteCmd::new(Endpoint::Tx, vec![0xF2, 0], false)),
);
break;
}
}
assert!(client.stop_all_devices().await.is_ok());
});
}