diff --git a/src/payload/checkpoint.rs b/src/payload/checkpoint.rs index db3b496..32a80c9 100644 --- a/src/payload/checkpoint.rs +++ b/src/payload/checkpoint.rs @@ -517,3 +517,70 @@ impl Display for Checkpoint

{ } } } + +#[cfg(test)] +mod tests { + use { + rblib::{prelude::*, test_utils::BlockContextMocked}, + std::time::Instant, + }; + + #[test] + fn test_barrier_depth_and_is_barrier() { + let (block, _) = BlockContext::::mocked(); + + let checkpoint = block.start(); + + // Expected: initial checkpoint is depth 0 and is barrier + assert_eq!(checkpoint.depth(), 0); + assert!(checkpoint.is_barrier()); + assert!(checkpoint.prev().is_none()); + } + + #[test] + fn test_named_barrier_and_prev_depth() { + // Outline: + // 1. create initial checkpoint (depth 0) + // 2. create named barrier on top + // 3. verify new depth is 1, prev is initial, and is_named_barrier returns + // true + let root = { + let (block, _) = BlockContext::::mocked(); + + let cp = block.start(); + cp + }; + + let named = root.named_barrier("sequencer-synced"); + assert_eq!(named.depth(), root.depth() + 1); + assert!(named.is_named_barrier("sequencer-synced")); + assert!(matches!(named.prev(), Some(_))); + assert_eq!(named.prev().unwrap().depth(), root.depth()); + } + + #[test] + fn test_created_at() { + let (block, _) = BlockContext::::mocked(); + + let checkpoint = block.start(); + + let now = Instant::now(); + assert!(checkpoint.created_at() <= now); + } + + #[test] + fn test_iter() { + let (block, _) = BlockContext::::mocked(); + + let checkpoint = block.start(); + + let checkpoint2 = checkpoint.barrier(); + let checkpoint3 = checkpoint2.barrier(); + + let history: Vec<_> = checkpoint3.into_iter().collect(); + assert_eq!(history.len(), 3); + assert_eq!(history[0].depth(), 2); + assert_eq!(history[1].depth(), 1); + assert_eq!(history[2].depth(), 0); + } +} diff --git a/src/payload/ext/checkpoint.rs b/src/payload/ext/checkpoint.rs index 882e69a..a13265d 100644 --- a/src/payload/ext/checkpoint.rs +++ b/src/payload/ext/checkpoint.rs @@ -311,3 +311,108 @@ impl CheckpointExt

for Checkpoint

{ self.root().created_at() } } + +#[cfg(test)] +mod tests { + use { + crate::alloy::primitives::Address, + alloy_origin::primitives::{TxHash, U256}, + rblib::{prelude::*, test_utils::BlockContextMocked}, + std::{ + thread, + time::{Duration, Instant}, + }, + }; + + #[test] + fn test_is_empty_and_root() { + let (block, _) = BlockContext::::mocked(); + let root = block.start(); + let mid = root.barrier(); + let leaf = mid.barrier(); + + assert!(root.is_empty()); + assert_eq!(leaf.root(), root); + } + + #[test] + fn test_gas_used_and_cumulative_gas_used() { + let (block, _) = BlockContext::::mocked(); + let cp = block.start(); + assert_eq!(cp.gas_used(), 0); + assert_eq!(cp.cumulative_gas_used(), 0); + } + + #[test] + fn test_effective_tip_and_blob_gas() { + let (block, _) = BlockContext::::mocked(); + let cp = block.start(); + assert_eq!(cp.effective_tip_per_gas(), 0); + assert!(!cp.has_blobs()); + assert_eq!(cp.blob_gas_used(), Some(0)); + assert_eq!(cp.cumulative_blob_gas_used(), 0); + } + + #[test] + fn test_to_between_linear_history() { + let (block, _) = BlockContext::::mocked(); + let a = block.start(); + let b = a.barrier(); + let c = b.barrier(); + + let span1 = c.to(&a).unwrap(); + let span2 = a.to(&c).unwrap(); + + assert_eq!(span1.len(), 3); + assert_eq!(span2.len(), 3); + } + + #[test] + fn test_balance_and_nonce_defaults() { + let (block, _) = BlockContext::::mocked(); + let cp = block.start(); + + let addr = Address::ZERO; + assert_eq!(cp.balance_of(addr).unwrap(), U256::ZERO); + assert_eq!(cp.nonce_of(addr).unwrap(), 0); + } + + #[test] + fn test_signers_and_nonces_are_empty() { + let (block, _) = BlockContext::::mocked(); + let cp = block.start(); + + assert!(cp.signers().is_empty()); + assert!(cp.nonces().is_empty()); + } + + #[test] + fn test_hash_and_is_bundle_and_has_failures_defaults() { + let (block, _) = BlockContext::::mocked(); + let cp = block.start(); + + assert_eq!(cp.hash(), None); + assert!(!cp.is_bundle()); + assert!(!cp.has_failures()); + assert_eq!(cp.failed_txs().count(), 0); + } + + #[test] + fn test_contains_is_false_without_txs() { + let (block, _) = BlockContext::::mocked(); + let cp = block.start(); + + let fake_hash = TxHash::repeat_byte(0x42); + assert!(!cp.contains(fake_hash)); + } + + #[test] + fn test_history_timestamps() { + let (block, _) = BlockContext::::mocked(); + let cp1 = block.start(); + thread::sleep(Duration::from_millis(5)); + let cp2 = cp1.barrier(); + assert!(cp2.building_since() <= Instant::now()); + assert!(cp2.building_since() >= cp1.created_at()); + } +}