test(chain): introduce proptest for CheckPoint::range
Ensure that `CheckPoint::range` returns expected values by comparing against values returned from a primitive approach. I think it is a good idea to start writing proptests for this crate.
This commit is contained in:
parent
62619d3a4a
commit
446b045161
1
.github/workflows/cont_integration.yml
vendored
1
.github/workflows/cont_integration.yml
vendored
@ -33,6 +33,7 @@ jobs:
|
|||||||
cargo update -p zstd-sys --precise "2.0.8+zstd.1.5.5"
|
cargo update -p zstd-sys --precise "2.0.8+zstd.1.5.5"
|
||||||
cargo update -p time --precise "0.3.20"
|
cargo update -p time --precise "0.3.20"
|
||||||
cargo update -p home --precise "0.5.5"
|
cargo update -p home --precise "0.5.5"
|
||||||
|
cargo update -p proptest --precise "1.2.0"
|
||||||
- name: Build
|
- name: Build
|
||||||
run: cargo build ${{ matrix.features }}
|
run: cargo build ${{ matrix.features }}
|
||||||
- name: Test
|
- name: Test
|
||||||
|
@ -75,6 +75,8 @@ cargo update -p time --precise "0.3.20"
|
|||||||
cargo update -p jobserver --precise "0.1.26"
|
cargo update -p jobserver --precise "0.1.26"
|
||||||
# home 0.5.9 has MSRV 1.70.0
|
# home 0.5.9 has MSRV 1.70.0
|
||||||
cargo update -p home --precise "0.5.5"
|
cargo update -p home --precise "0.5.5"
|
||||||
|
# proptest 1.4.0 has MSRV 1.65.0
|
||||||
|
cargo update -p proptest --precise "1.2.0"
|
||||||
```
|
```
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
@ -23,6 +23,7 @@ miniscript = { version = "10.0.0", optional = true, default-features = false }
|
|||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
rand = "0.8"
|
rand = "0.8"
|
||||||
|
proptest = "1.2.0"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["std"]
|
default = ["std"]
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
use std::ops::{Bound, RangeBounds};
|
||||||
|
|
||||||
use bdk_chain::{
|
use bdk_chain::{
|
||||||
local_chain::{
|
local_chain::{
|
||||||
AlterCheckPointError, ApplyHeaderError, CannotConnectError, ChangeSet, CheckPoint,
|
AlterCheckPointError, ApplyHeaderError, CannotConnectError, ChangeSet, CheckPoint,
|
||||||
@ -6,6 +8,7 @@ use bdk_chain::{
|
|||||||
BlockId,
|
BlockId,
|
||||||
};
|
};
|
||||||
use bitcoin::{block::Header, hashes::Hash, BlockHash};
|
use bitcoin::{block::Header, hashes::Hash, BlockHash};
|
||||||
|
use proptest::prelude::*;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod common;
|
mod common;
|
||||||
@ -725,3 +728,48 @@ fn local_chain_apply_header_connected_to() {
|
|||||||
assert_eq!(result, exp_result, "[{}:{}] unexpected result", i, t.name);
|
assert_eq!(result, exp_result, "[{}:{}] unexpected result", i, t.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn generate_height_range_bounds(
|
||||||
|
height_upper_bound: u32,
|
||||||
|
) -> impl Strategy<Value = (Bound<u32>, Bound<u32>)> {
|
||||||
|
fn generate_height_bound(height_upper_bound: u32) -> impl Strategy<Value = Bound<u32>> {
|
||||||
|
prop_oneof![
|
||||||
|
(0..height_upper_bound).prop_map(Bound::Included),
|
||||||
|
(0..height_upper_bound).prop_map(Bound::Excluded),
|
||||||
|
Just(Bound::Unbounded),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
(
|
||||||
|
generate_height_bound(height_upper_bound),
|
||||||
|
generate_height_bound(height_upper_bound),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn generate_checkpoints(max_height: u32, max_count: usize) -> impl Strategy<Value = CheckPoint> {
|
||||||
|
proptest::collection::btree_set(1..max_height, 0..max_count).prop_map(|mut heights| {
|
||||||
|
heights.insert(0); // must have genesis
|
||||||
|
CheckPoint::from_block_ids(heights.into_iter().map(|height| {
|
||||||
|
let hash = bitcoin::hashes::Hash::hash(height.to_le_bytes().as_slice());
|
||||||
|
BlockId { height, hash }
|
||||||
|
}))
|
||||||
|
.expect("blocks must be in order as it comes from btreeset")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
proptest! {
|
||||||
|
#![proptest_config(ProptestConfig {
|
||||||
|
..Default::default()
|
||||||
|
})]
|
||||||
|
|
||||||
|
/// Ensure that [`CheckPoint::range`] returns the expected checkpoint heights by comparing it
|
||||||
|
/// against a more primitive approach.
|
||||||
|
#[test]
|
||||||
|
fn checkpoint_range(
|
||||||
|
range in generate_height_range_bounds(21_000),
|
||||||
|
cp in generate_checkpoints(21_000, 2100)
|
||||||
|
) {
|
||||||
|
let exp_heights = cp.iter().map(|cp| cp.height()).filter(|h| range.contains(h)).collect::<Vec<u32>>();
|
||||||
|
let heights = cp.range(range).map(|cp| cp.height()).collect::<Vec<u32>>();
|
||||||
|
prop_assert_eq!(heights, exp_heights);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user