use super::*;
#[test]
fn append_position_hint_branch_root_forks_at_parent_depth() {
let forked = AppendPositionHint::branch_root(5, 9);
assert_eq!(forked.lane, 5, "lane is the first argument");
assert_eq!(
forked.depth, 9,
"branch_root keeps the parent depth verbatim"
);
assert!(
forked.branch_root,
"PROPERTY: branch_root() must flag a new branch"
);
let flat = AppendPositionHint::new(5, 9);
assert!(
!flat.branch_root,
"PROPERTY: new() must leave branch_root clear"
);
}
#[test]
fn causation_ref_absolute_typed_erases_to_absolute_variant() {
let reference = CausationRef::absolute_typed(CausationId::from(0x00C0_FFEE_u128));
assert_eq!(
reference,
CausationRef::Absolute(0x00C0_FFEE),
"PROPERTY: absolute_typed must wrap the id in the Absolute variant"
);
}
#[test]
fn compaction_config_default_seeds_two_segment_floor() {
assert_eq!(
CompactionConfig::default().min_segments,
2,
"PROPERTY: the default compaction floor is 2 sealed segments"
);
}
#[test]
fn append_options_setters_wire_exactly_their_field() {
let opts = AppendOptions::default()
.with_cas(11)
.with_flags(0b0000_0101)
.with_idempotency(IdempotencyKey::from(0x1234_u128));
assert_eq!(
opts.expected_sequence,
Some(11),
"with_cas sets expected_sequence"
);
assert_eq!(opts.flags, 0b0000_0101, "with_flags sets flags");
assert_eq!(
opts.idempotency_key,
Some(IdempotencyKey::from(0x1234_u128)),
"with_idempotency sets the key"
);
}
#[test]
fn receipt_extension_key_composes_prefix_dot_field() {
struct AcmeNamespace;
impl ReceiptExtensionNamespace for AcmeNamespace {
const PREFIX: &'static str = "acme";
}
let key = ReceiptExtensionKey::<AcmeNamespace>::new("thing").expect("valid composed key");
assert_eq!(
key.as_key().as_str(),
"acme.thing",
"PROPERTY: the composed key is `<prefix>.<field>`"
);
}
#[test]
fn signing_downgrade_round_trips_through_the_reserved_extension_slot() {
let body = SigningDowngradeBody::cover_build_failed("cover boom");
let encoded = body.encode_extension().expect("encode downgrade body");
let mut extensions = BTreeMap::new();
extensions.insert(signing_downgrade_extension_key(), encoded);
let receipt = AppendReceipt {
event_id: EventId::from_u128(1),
global_sequence: 0,
disk_pos: DiskPos::new(0, 0, 0),
content_hash: [0u8; 32],
key_id: [0u8; 32],
signature: None,
extensions,
};
let decoded = receipt
.signing_downgrade()
.expect("PROPERTY: a present downgrade extension must decode");
assert_eq!(
decoded.schema_version, SIGNING_DOWNGRADE_SCHEMA_VERSION,
"PROPERTY: the decoded body carries the current schema version"
);
assert!(
matches!(
decoded.reason,
SigningDowngradeReason::CoverBuildFailed { encoding_error }
if encoding_error == "cover boom"
),
"PROPERTY: the decoded reason must preserve the cover-build failure text"
);
let bare = AppendReceipt {
event_id: EventId::from_u128(2),
global_sequence: 1,
disk_pos: DiskPos::new(0, 0, 0),
content_hash: [0u8; 32],
key_id: [0u8; 32],
signature: None,
extensions: BTreeMap::new(),
};
assert!(
bare.signing_downgrade().is_none(),
"PROPERTY: no downgrade extension means signing_downgrade() is None"
);
}