use lazy_static::lazy_static;
use std::{sync::Mutex, thread::sleep, time::Duration};
use kdb_store::StoreFactory as _;
use crate::{Connection, Value, ValueHash};
lazy_static! {
static ref TEST_MUTEX: Mutex<()> = Mutex::new(());
}
pub(crate) async fn wait_for_connection(c: &impl Connection)
{
for _ in 0..30
{
if c.is_connected().await
{
break;
}
sleep(Duration::from_secs(1));
}
}
pub(crate) fn create_store_configuration() -> kdb_store::StoreConfiguration
{
kdb_store::StoreConfiguration::new().set_temporary_store()
}
pub(crate) struct StoreGuard<'a>
{
#[allow(unused)]
guard: std::sync::MutexGuard<'a, ()>,
store: kdb_store::BoxedStore,
}
impl<'a> StoreGuard<'a>
{
pub(crate) fn start(&mut self) -> kdb_store::Result<()>
{
self.store.start()
}
}
impl<'a> Drop for StoreGuard<'a>
{
fn drop(&mut self)
{
if let Err(e) = self.store.stop()
{
eprintln!("failed to stop store in Drop: {e}");
}
}
}
pub(crate) fn create_store<'a>(config: kdb_store::StoreConfiguration) -> StoreGuard<'a>
{
let guard = crate::test::TEST_MUTEX.lock().unwrap();
if pathsearch::find_executable_in_path("kdb").is_some()
{
StoreGuard {
guard,
store: Box::new(kdb_store::ProcessStore::new(config).unwrap()),
}
}
else
{
StoreGuard {
guard,
store: Box::new(kdb_store::DockerStore::new(config).unwrap()),
}
}
}
pub(crate) fn validate_agent_0(agent_0: crate::ValueHash)
{
assert_eq!(agent_0.len(), 3);
let object_uri = agent_0.get("object_uri").unwrap();
assert_eq!(
object_uri,
&Value::from_uri_value(
"http://www.w3.org/2001/XMLSchema#anyURI",
"http://example.org/agent/0"
)
);
let type_uri = agent_0.get("type_uri").unwrap();
assert_eq!(
type_uri,
&Value::from_uri_value(
"http://www.w3.org/2001/XMLSchema#anyURI",
"http://askco.re/agent#uav"
)
);
let properties_value = agent_0.get("properties").unwrap();
assert_eq!(
properties_value.datatype_ref(),
"http://askco.re/datatype#valuehash"
);
let properties_map: ValueHash = properties_value.clone().try_into().unwrap();
assert_eq!(
properties_map
.get("http://askco.re/agent#agent_type")
.unwrap(),
&Value::from_uri_value(
"http://www.w3.org/2001/XMLSchema#anyURI",
"http://askco.re/agent#uav"
)
);
assert_eq!(
properties_map.get("http://askco.re/agent#frame").unwrap(),
&Value::from("agent0")
);
assert_eq!(
properties_map
.get("http://xmlns.com/foaf/0.1/name")
.unwrap(),
&Value::from("test agent")
);
}
pub(crate) fn validate_dataset_0(dataset_0: crate::ValueHash)
{
assert_eq!(dataset_0.len(), 3);
let object_uri = dataset_0.get("object_uri").unwrap();
assert_eq!(
object_uri,
&Value::from_uri_value(
"http://www.w3.org/2001/XMLSchema#anyURI",
"http://example.org/dataset/0"
)
);
let type_uri = dataset_0.get("type_uri").unwrap();
assert_eq!(
type_uri,
&Value::from_uri_value(
"http://www.w3.org/2001/XMLSchema#anyURI",
"http://askco.re/dataset#point_cloud_dataset"
)
);
let properties_value = dataset_0.get("properties").unwrap();
assert_eq!(
properties_value.datatype_ref(),
"http://askco.re/datatype#valuehash"
);
let properties_map: ValueHash = properties_value.clone().try_into().unwrap();
assert_eq!(
properties_map
.get("http://askco.re/dataset#content_type")
.unwrap(),
&Value::from_uri_value(
"http://www.w3.org/2001/XMLSchema#anyURI",
"http://askco.re/sensing#point_cloud"
)
);
let point_density = properties_map
.get("http://askco.re/sensing#point_density")
.unwrap();
let point_density_map: ValueHash = point_density.clone().try_into().unwrap();
assert_eq!(
point_density_map.get("unit").unwrap(),
&Value::from("point/m^2")
);
assert_eq!(
point_density_map.get("value").unwrap(),
&Value::from(10_i64)
);
let geometry = properties_map
.get("http://www.opengis.net/ont/geosparql#hasGeometry")
.unwrap();
assert_eq!(
geometry.datatype_ref(),
"http://www.opengis.net/ont/geosparql#Geometry"
);
let geometry_hash: ValueHash = geometry.clone().try_into().unwrap();
assert_eq!(geometry_hash.get("type").unwrap(), &Value::from("Polygon"));
let coordinates_value = geometry_hash.get("coordinates").unwrap();
assert_eq!(
coordinates_value.datatype_ref(),
"http://askco.re/datatype#valuelist"
);
let rings: Vec<Value> = coordinates_value.clone().try_into().unwrap();
assert_eq!(rings.len(), 1, "Expected exactly one polygon ring");
let ring: Vec<Value> = rings[0].clone().try_into().unwrap();
assert_eq!(ring.len(), 5, "Polygon must have 5 points (closed)");
let expected_coords = vec![
(30_i64, 10_i64),
(40_i64, 40_i64),
(20_i64, 40_i64),
(10_i64, 20_i64),
(30_i64, 10_i64), ];
for (idx, ((exp_x, exp_y), coord)) in expected_coords.into_iter().zip(ring.iter()).enumerate()
{
let point: Vec<Value> = coord.clone().try_into().unwrap();
assert_eq!(point.len(), 2, "Point {} must have 2 coordinates", idx);
assert_eq!(point[0], Value::from(exp_x), "X mismatch at point {}", idx);
assert_eq!(point[1], Value::from(exp_y), "Y mismatch at point {}", idx);
}
}