units: Fix up the api test

A lot has changed over the last few months. Fix up the API integration
test to match the current state of the crate.
This commit is contained in:
Tobin C. Harding 2025-06-18 10:45:01 +10:00
parent a6ab5c9fd0
commit 2b07f59545
No known key found for this signature in database
GPG Key ID: 0AEF0A899E41F7DD
1 changed files with 99 additions and 86 deletions

View File

@ -12,39 +12,49 @@
#[cfg(feature = "arbitrary")] #[cfg(feature = "arbitrary")]
use arbitrary::{Arbitrary, Unstructured}; use arbitrary::{Arbitrary, Unstructured};
// These imports test "typical" usage by user code. // These imports test "typical" usage by user code.
use bitcoin_units::locktime::{absolute, relative}; // Typical usage is `absolute::Height`. use bitcoin_units::locktime::{absolute, relative}; // Typical usage is `absolute::LockTime`.
use bitcoin_units::{ use bitcoin_units::{
amount, block, fee_rate, locktime, parse, weight, Amount, BlockHeight, BlockInterval, BlockMtp, amount, block, fee_rate, locktime, parse, time, weight, Amount, BlockHeight,
BlockMtpInterval, BlockTime, CheckedSum, FeeRate, SignedAmount, Weight, BlockHeightInterval, BlockMtp, BlockMtpInterval, BlockTime, CheckedSum, FeeRate, MathOp,
NumOpResult, SignedAmount, Weight,
}; };
/// A struct that includes all public non-error enums. /// A struct that includes all public non-error enums.
#[derive(Debug)] // All public types implement Debug (C-DEBUG). #[derive(Debug)] // All public types implement Debug (C-DEBUG).
struct Enums { struct Enums {
a: amount::Denomination, a: amount::Denomination,
b: NumOpResult<Amount>,
c: MathOp,
} }
impl Enums { impl Enums {
fn new() -> Self { Self { a: amount::Denomination::Bitcoin } } fn new() -> Self {
Self {
a: amount::Denomination::Bitcoin,
b: NumOpResult::Valid(Amount::MAX),
c: MathOp::Add,
}
}
} }
/// A struct that includes all public non-error structs. /// A struct that includes all public non-error structs.
#[derive(Debug)] // All public types implement Debug (C-DEBUG). #[derive(Debug)] // All public types implement Debug (C-DEBUG).
struct Structs { struct Structs {
a: Amount, // Full path to show alphabetic sort order.
a: amount::Amount,
b: amount::Display, b: amount::Display,
c: SignedAmount, c: amount::SignedAmount,
d: BlockHeight, d: block::BlockHeight,
e: BlockInterval, e: block::BlockHeightInterval,
f: FeeRate, f: block::BlockMtp,
g: absolute::Height, g: block::BlockMtpInterval,
h: absolute::MedianTimePast, h: fee_rate::FeeRate,
i: relative::Height, i: locktime::absolute::Height,
j: relative::Time, j: locktime::absolute::MedianTimePast,
k: Weight, k: locktime::relative::NumberOf512Seconds,
l: BlockTime, l: locktime::relative::NumberOfBlocks,
m: BlockMtp, m: time::BlockTime,
n: BlockMtpInterval, n: weight::Weight,
} }
impl Structs { impl Structs {
@ -54,16 +64,16 @@ impl Structs {
b: Amount::MAX.display_in(amount::Denomination::Bitcoin), b: Amount::MAX.display_in(amount::Denomination::Bitcoin),
c: SignedAmount::MAX, c: SignedAmount::MAX,
d: BlockHeight::MAX, d: BlockHeight::MAX,
e: BlockInterval::MAX, e: BlockHeightInterval::MAX,
f: FeeRate::MAX, f: BlockMtp::MAX,
g: absolute::Height::MAX, g: BlockMtpInterval::MAX,
h: absolute::MedianTimePast::MAX, h: FeeRate::MAX,
i: relative::Height::MAX, i: absolute::Height::MAX,
j: relative::Time::MAX, j: absolute::MedianTimePast::MAX,
k: Weight::MAX, k: relative::NumberOf512Seconds::MAX,
l: BlockTime::from_u32(u32::MAX), l: relative::NumberOfBlocks::MAX,
m: BlockMtp::MAX, m: BlockTime::from_u32(u32::MAX),
n: BlockMtpInterval::MAX, n: Weight::MAX,
} }
} }
} }
@ -83,19 +93,21 @@ impl Types {
// C-COMMON-TRAITS excluding `Default` and `Display`. `Display` is done in `./str.rs`. // C-COMMON-TRAITS excluding `Default` and `Display`. `Display` is done in `./str.rs`.
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
struct CommonTraits { struct CommonTraits {
a: Amount, // Full path to show alphabetic sort order.
c: SignedAmount, a: amount::Amount,
d: BlockHeight, // b: amount::Display,
e: BlockInterval, c: amount::SignedAmount,
f: FeeRate, d: block::BlockHeight,
g: absolute::Height, e: block::BlockHeightInterval,
h: absolute::MedianTimePast, f: block::BlockMtp,
i: relative::Height, g: block::BlockMtpInterval,
j: relative::Time, h: fee_rate::FeeRate,
k: Weight, i: locktime::absolute::Height,
l: BlockTime, j: locktime::absolute::MedianTimePast,
m: BlockMtp, k: locktime::relative::NumberOf512Seconds,
n: BlockMtpInterval, l: locktime::relative::NumberOfBlocks,
m: time::BlockTime,
n: weight::Weight,
} }
/// A struct that includes all types that implement `Default`. /// A struct that includes all types that implement `Default`.
@ -103,10 +115,10 @@ struct CommonTraits {
struct Default { struct Default {
a: Amount, a: Amount,
b: SignedAmount, b: SignedAmount,
c: BlockInterval, c: BlockHeightInterval,
d: relative::Height, d: BlockMtpInterval,
e: relative::Time, e: relative::NumberOf512Seconds,
f: BlockMtpInterval, f: relative::NumberOfBlocks,
} }
/// A struct that includes all public error types. /// A struct that includes all public error types.
@ -124,28 +136,18 @@ struct Errors {
i: amount::PossiblyConfusingDenominationError, i: amount::PossiblyConfusingDenominationError,
j: amount::TooPreciseError, j: amount::TooPreciseError,
k: amount::UnknownDenominationError, k: amount::UnknownDenominationError,
l: amount::InputTooLargeError, l: block::TooBigForRelativeHeightError,
m: amount::InvalidCharacterError, #[cfg(feature = "serde")]
n: amount::MissingDenominationError, m: fee_rate::serde::OverflowError,
o: amount::MissingDigitsError, n: locktime::absolute::ConversionError,
p: amount::OutOfRangeError, o: locktime::absolute::ParseHeightError,
q: amount::ParseAmountError, p: locktime::absolute::ParseTimeError,
r: amount::ParseDenominationError, q: locktime::relative::InvalidHeightError,
s: amount::ParseError, r: locktime::relative::InvalidTimeError,
t: amount::PossiblyConfusingDenominationError, s: locktime::relative::TimeOverflowError,
u: amount::TooPreciseError, t: parse::ParseIntError,
v: amount::UnknownDenominationError, u: parse::PrefixedHexError,
w: block::TooBigForRelativeHeightError, v: parse::UnprefixedHexError,
x: locktime::absolute::ConversionError,
y: locktime::absolute::Height,
z: locktime::absolute::ParseHeightError,
aa: locktime::absolute::ParseTimeError,
ab: locktime::relative::TimeOverflowError,
ac: locktime::relative::InvalidHeightError,
ad: locktime::relative::InvalidTimeError,
ae: parse::ParseIntError,
af: parse::PrefixedHexError,
ag: parse::UnprefixedHexError,
} }
#[test] #[test]
@ -156,8 +158,8 @@ fn api_can_use_modules_from_crate_root() {
#[test] #[test]
fn api_can_use_types_from_crate_root() { fn api_can_use_types_from_crate_root() {
use bitcoin_units::{ use bitcoin_units::{
Amount, BlockHeight, BlockInterval, BlockMtp, BlockMtpInterval, BlockTime, FeeRate, Amount, BlockHeight, BlockHeightInterval, BlockInterval, BlockMtp, BlockMtpInterval,
SignedAmount, Weight, BlockTime, FeeRate, MathOp, NumOpError, NumOpResult, SignedAmount, Weight,
}; };
} }
@ -173,11 +175,15 @@ fn api_can_use_all_types_from_module_amount() {
#[test] #[test]
fn api_can_use_all_types_from_module_block() { fn api_can_use_all_types_from_module_block() {
use bitcoin_units::block::{BlockHeight, BlockHeightInterval, TooBigForRelativeHeightError}; use bitcoin_units::block::{
BlockHeight, BlockHeightInterval, BlockMtp, BlockMtpInterval, TooBigForRelativeHeightError,
};
} }
#[test] #[test]
fn api_can_use_all_types_from_module_fee_rate() { fn api_can_use_all_types_from_module_fee_rate() {
#[cfg(feature = "serde")]
use bitcoin_units::fee_rate::serde::OverflowError;
use bitcoin_units::fee_rate::FeeRate; use bitcoin_units::fee_rate::FeeRate;
} }
@ -190,7 +196,10 @@ fn api_can_use_all_types_from_module_locktime_absolute() {
#[test] #[test]
fn api_can_use_all_types_from_module_locktime_relative() { fn api_can_use_all_types_from_module_locktime_relative() {
use bitcoin_units::locktime::relative::{Height, Time, TimeOverflowError}; use bitcoin_units::locktime::relative::{
Height, InvalidHeightError, InvalidTimeError, NumberOf512Seconds, NumberOfBlocks, Time,
TimeOverflowError,
};
} }
#[test] #[test]
@ -262,10 +271,10 @@ fn regression_default() {
let want = Default { let want = Default {
a: Amount::ZERO, a: Amount::ZERO,
b: SignedAmount::ZERO, b: SignedAmount::ZERO,
c: BlockInterval::ZERO, c: BlockHeightInterval::ZERO,
d: relative::Height::ZERO, d: BlockMtpInterval::ZERO,
e: relative::Time::ZERO, e: relative::NumberOf512Seconds::ZERO,
f: BlockMtpInterval::ZERO, f: relative::NumberOfBlocks::ZERO,
}; };
assert_eq!(got, want); assert_eq!(got, want);
} }
@ -279,7 +288,7 @@ fn dyn_compatible() {
// These traits are explicitly not dyn compatible. // These traits are explicitly not dyn compatible.
// b: Box<dyn amount::serde::SerdeAmount>, // b: Box<dyn amount::serde::SerdeAmount>,
// c: Box<dyn amount::serde::SerdeAmountForOpt>, // c: Box<dyn amount::serde::SerdeAmountForOpt>,
// d: Box<dyn parse::Integer>, // d: Box<dyn parse::Integer>, // Because of core::num::ParseIntError
} }
} }
@ -300,16 +309,16 @@ impl<'a> Arbitrary<'a> for Structs {
b: Amount::MAX.display_in(amount::Denomination::Bitcoin), b: Amount::MAX.display_in(amount::Denomination::Bitcoin),
c: SignedAmount::arbitrary(u)?, c: SignedAmount::arbitrary(u)?,
d: BlockHeight::arbitrary(u)?, d: BlockHeight::arbitrary(u)?,
e: BlockInterval::arbitrary(u)?, e: BlockHeightInterval::arbitrary(u)?,
f: FeeRate::arbitrary(u)?, f: BlockMtp::arbitrary(u)?,
g: absolute::Height::arbitrary(u)?, g: BlockMtpInterval::arbitrary(u)?,
h: absolute::MedianTimePast::arbitrary(u)?, h: FeeRate::arbitrary(u)?,
i: relative::Height::arbitrary(u)?, i: absolute::Height::arbitrary(u)?,
j: relative::Time::arbitrary(u)?, j: absolute::MedianTimePast::arbitrary(u)?,
k: Weight::arbitrary(u)?, k: relative::NumberOf512Seconds::arbitrary(u)?,
l: BlockTime::arbitrary(u)?, l: relative::NumberOfBlocks::arbitrary(u)?,
m: BlockMtp::arbitrary(u)?, m: BlockTime::arbitrary(u)?,
n: BlockMtpInterval::arbitrary(u)?, n: Weight::arbitrary(u)?,
}; };
Ok(a) Ok(a)
} }
@ -318,7 +327,11 @@ impl<'a> Arbitrary<'a> for Structs {
#[cfg(feature = "arbitrary")] #[cfg(feature = "arbitrary")]
impl<'a> Arbitrary<'a> for Enums { impl<'a> Arbitrary<'a> for Enums {
fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> { fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
let a = Enums { a: amount::Denomination::arbitrary(u)? }; let a = Enums {
a: amount::Denomination::arbitrary(u)?,
b: NumOpResult::<Amount>::arbitrary(u)?,
c: MathOp::arbitrary(u)?,
};
Ok(a) Ok(a)
} }
} }