pub mod common;
use nodedb_array::types::cell_value::value::CellValue;
use nodedb_array::types::coord::value::CoordValue;
use nodedb_lite::sync::array::inbound::outcome::InboundOutcome;
#[tokio::test(flavor = "multi_thread")]
async fn basic_put_cell_roundtrip() {
let harness = common::SyncHarness::new_in_memory().await;
harness.create_array("grid").await;
let schema_hlc = harness.schema_hlc("grid");
let rep = common::replica(1);
let op = common::put_op("grid", 5, 42.0, 1_000, schema_hlc, rep);
let outcome = harness.deliver(&op);
assert_eq!(
outcome,
InboundOutcome::Applied,
"op must be Applied on first delivery"
);
harness.flush("grid").await;
let val = harness.read_coord("grid", 5, i64::MAX).await;
assert!(val.is_some(), "cell must be readable after inbound apply");
assert_eq!(
val.unwrap(),
CellValue::Float64(42.0),
"value must match the emitted Put"
);
}
#[tokio::test(flavor = "multi_thread")]
async fn basic_idempotent_redelivery() {
let harness = common::SyncHarness::new_in_memory().await;
harness.create_array("idem").await;
let schema_hlc = harness.schema_hlc("idem");
let rep = common::replica(1);
let op = common::put_op("idem", 3, 7.0, 500, schema_hlc, rep);
let first = harness.deliver(&op);
assert_eq!(first, InboundOutcome::Applied);
let second = harness.deliver(&op);
assert_eq!(
second,
InboundOutcome::Idempotent,
"re-delivering the same op must be Idempotent"
);
}
#[tokio::test(flavor = "multi_thread")]
async fn basic_outbound_feeds_inbound() {
let sender = common::make_outbound_harness().await;
sender
.schemas
.put_schema("shared", &common::simple_schema("shared"))
.await
.expect("put_schema");
sender
.outbound
.emit_put(
"shared",
vec![CoordValue::Int64(10)],
vec![CellValue::Float64(99.0)],
0,
i64::MAX,
)
.await
.expect("emit_put");
let receiver = common::SyncHarness::new_in_memory().await;
receiver.create_array("shared").await;
let ops = sender
.outbound
.pending()
.drain_batch(1)
.await
.expect("drain_batch");
assert_eq!(ops.len(), 1, "one op must be pending after emit_put");
for op in &ops {
let outcome = receiver.deliver(op);
assert_eq!(outcome, InboundOutcome::Applied);
}
receiver.flush("shared").await;
let val = receiver.read_coord("shared", 10, i64::MAX).await;
assert!(val.is_some(), "receiver must see the value after apply");
assert_eq!(val.unwrap(), CellValue::Float64(99.0));
}