mod common;
use std::thread;
use common::*;
use oc2_hlapi_v2::client::{Device, DeviceBase, HlapiClientError};
use oc2_hlapi_v2::devices::GenericDevice;
use serde_json::json;
#[test]
fn wrappers_know_their_type_and_uuid() {
assert_eq!(Redstone::TYPE, "redstone");
assert_eq!(Storage::TYPE, "storage");
assert_eq!(GenericDevice::TYPE, "");
let (client, _s) = client_silent();
let d = Redstone::new(client, id(77)).unwrap();
assert_eq!(d.uuid(), id(77));
assert_eq!(d.uuid_base(), id(77));
}
#[test]
fn typed_wrapper_methods_send_the_right_calls() {
let (client, s) = client_serving(|req, _, host| {
let reply = match req["data"]["name"].as_str().unwrap() {
"getInput" => result_reply(req, 1, json!(11)),
_ => empty_result_reply(req, 1),
};
host.reply(&reply);
});
let d = Redstone::new(client, id(4)).unwrap();
assert_eq!(d.get_input("left").unwrap(), 11);
d.set_output("back", 15).unwrap();
let reqs = s.requests();
assert_eq!(reqs[0]["data"]["name"], "getInput");
assert_eq!(reqs[0]["data"]["parameters"], json!(["left"]));
assert_eq!(reqs[1]["data"]["name"], "setOutput");
assert_eq!(reqs[1]["data"]["parameters"], json!(["back", 15]));
assert_eq!(reqs[1]["data"]["deviceId"], json!(id(4)));
}
#[test]
fn generic_device_call_matches_the_trait_method() {
let (client, s) = client_serving(|req, _, host| host.reply(&result_reply(req, 1, json!("ok"))));
let d = GenericDevice::new(client, id(3)).unwrap();
let inherent: (String, _) = d.call("m", &[&1], &[]).unwrap();
let via_trait: (String, _) = DeviceBase::call(&d, "m", &[&1], &[]).unwrap();
assert_eq!(inherent.0, via_trait.0);
let reqs = s.requests();
assert_eq!(reqs[0]["data"], reqs[1]["data"]);
}
#[test]
fn list_methods_returns_the_hosts_description() {
let (client, s) = client_serving(|req, _, host| {
host.reply(&json!({
"type": "methods", "id": req["id"], "gen": 1,
"data": [{
"name": "getInput", "returnType": "int", "description": "d",
"parameters": [{"name": "side", "type": "string"}],
}, {"name": "other"}],
}));
});
let d = Redstone::new(client, id(4)).unwrap();
let methods = d.list_methods().unwrap();
assert_eq!(methods.len(), 2);
assert_eq!(methods[0].name, "getInput");
assert_eq!(methods[0].return_type.as_deref(), Some("int"));
assert_eq!(
methods[0].parameters.as_ref().unwrap()[0].name.as_deref(),
Some("side")
);
let req = &s.requests()[0];
assert_eq!(req["type"], "methods");
assert_eq!(req["data"], json!(id(4)));
}
#[test]
fn list_methods_errors() {
let (client, _s) =
client_serving(|req, _, host| host.reply(&error_reply(req, 1, "no such device")));
let err = Redstone::new(client, id(4))
.unwrap()
.list_methods()
.unwrap_err();
assert!(matches!(&err, HlapiClientError::Hlapi(m) if m == "no such device"));
let (client, _s) = client_serving(|req, _, host| host.reply(&result_reply(req, 1, json!(1))));
let err = Redstone::new(client, id(4))
.unwrap()
.list_methods()
.unwrap_err();
assert!(
matches!(err, HlapiClientError::UnexpectedResponseType),
"{err:?}"
);
}
#[test]
fn wrappers_are_cheap_handles_on_the_same_connection() {
let (client, s) = client_serving(simple_host);
let a = Redstone::new(client.clone(), id(1)).unwrap();
let b = a.clone();
let handle = thread::spawn(move || b.get_input("left").unwrap());
assert_eq!(a.get_input("right").unwrap(), 7);
assert_eq!(handle.join().unwrap(), 7);
assert_eq!(s.total(), 2);
assert!(format!("{a:?}").contains("Redstone"));
}
#[test]
fn the_client_of_a_found_wrapper_is_the_client_that_found_it() {
let (client, s) = client_serving(simple_host);
let d: Redstone = client.find_device_by_type().unwrap().unwrap();
d.get_input("left").unwrap();
assert_eq!(s.count("list"), 1);
assert_eq!(s.count("invoke"), 1);
assert_eq!(d.client().list_devices().unwrap().len(), 2);
assert_eq!(s.count("list"), 1, "shared cache");
}