Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
179 changes: 147 additions & 32 deletions units/tests/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,11 @@ struct Structs {
k: locktime::relative::NumberOf512Seconds,
l: locktime::relative::NumberOfBlocks,
m: pow::CompactTarget,
n: sequence::Sequence,
o: time::BlockTime,
p: weight::Weight,
n: pow::Target,
o: pow::Work,
p: sequence::Sequence,
q: time::BlockTime,
r: weight::Weight,
}

impl Structs {
Expand All @@ -78,9 +80,11 @@ impl Structs {
k: relative::NumberOf512Seconds::MAX,
l: relative::NumberOfBlocks::MAX,
m: pow::CompactTarget::from_consensus(u32::MAX),
n: sequence::Sequence::MAX,
o: BlockTime::from_u32(u32::MAX),
p: Weight::MAX,
n: pow::Target::MAX,
o: pow::Work::from_be_bytes([0xff; 32]),
p: sequence::Sequence::MAX,
q: BlockTime::from_u32(u32::MAX),
r: Weight::MAX,
}
}
}
Expand Down Expand Up @@ -114,8 +118,11 @@ struct CommonTraits {
k: locktime::relative::NumberOf512Seconds,
l: locktime::relative::NumberOfBlocks,
m: pow::CompactTarget,
n: time::BlockTime,
o: weight::Weight,
n: pow::Target,
o: pow::Work,
p: sequence::Sequence,
q: time::BlockTime,
r: weight::Weight,
}

/// A struct that includes all types that implement `Default`.
Expand All @@ -133,6 +140,7 @@ struct Default {
// These derives are the policy of `rust-bitcoin` not Rust API guidelines.
#[derive(Debug, Clone, PartialEq, Eq)] // All public types implement Debug (C-DEBUG).
struct Errors {
a: amount::error::BadPositionError,
b: amount::error::InvalidCharacterError,
c: amount::error::MissingDenominationError,
d: amount::error::MissingDigitsError,
Expand All @@ -147,17 +155,25 @@ struct Errors {
#[cfg(feature = "serde")]
m: fee_rate::serde::OverflowError,
n: locktime::absolute::ConversionError,
o: locktime::absolute::ParseHeightError,
p: locktime::absolute::ParseTimeError,
q: locktime::relative::InvalidHeightError,
r: locktime::relative::InvalidTimeError,
s: locktime::relative::TimeOverflowError,
t: parse_int::ParseIntError,
u: parse_int::PrefixedHexError,
v: parse_int::UnprefixedHexError,
#[cfg(feature = "encoding")]
w: pow::CompactTargetDecoderError,
x: result::NumOpError,
o: locktime::absolute::IncompatibleHeightError,
p: locktime::absolute::IncompatibleTimeError,
q: locktime::absolute::ParseHeightError,
r: locktime::absolute::ParseTimeError,
s: locktime::relative::DisabledLockTimeError,
t: locktime::relative::IncompatibleHeightError,
u: locktime::relative::IncompatibleTimeError,
v: locktime::relative::InvalidHeightError,
w: locktime::relative::InvalidTimeError,
x: locktime::relative::IsSatisfiedByError,
y: locktime::relative::IsSatisfiedByHeightError,
z: locktime::relative::IsSatisfiedByTimeError,
aa: locktime::relative::TimeOverflowError,
ab: parse_int::ParseIntError,
ac: parse_int::PrefixedHexError,
ad: parse_int::UnprefixedHexError,
ae: pow::ParseTargetError,
af: pow::ParseWorkError,
ag: result::NumOpError,
}

/// A struct that includes all public decoder types.
Expand All @@ -180,8 +196,9 @@ struct DecoderErrors {
a: amount::error::AmountDecoderError,
b: block::BlockHeightDecoderError,
c: locktime::absolute::LockTimeDecoderError,
d: sequence::SequenceDecoderError,
e: time::BlockTimeDecoderError,
d: pow::CompactTargetDecoderError,
e: sequence::SequenceDecoderError,
f: time::BlockTimeDecoderError,
}

/// C-DEBUG-NONEMPTY: Tests that all public non-error types have non-empty Debug.
Expand Down Expand Up @@ -232,6 +249,10 @@ fn c_debug_nonempty() {
assert!(!debug.is_empty());
let debug = format!("{:?}", t.b.p);
assert!(!debug.is_empty());
let debug = format!("{:?}", t.b.q);
assert!(!debug.is_empty());
let debug = format!("{:?}", t.b.r);
assert!(!debug.is_empty());
}

/// C-SEND-SYNC: Tests that all public types implement `Send` + `Sync`.
Expand All @@ -247,6 +268,14 @@ fn c_send_sync() {
// Error types should implement the Send and Sync traits (C-GOOD-ERR).
assert_send::<Errors>();
assert_sync::<Errors>();

#[cfg(feature = "encoding")]
{
assert_send::<Decoders>();
assert_sync::<Decoders>();
assert_send::<DecoderErrors>();
assert_sync::<DecoderErrors>();
}
}

/// C-GOOD-ERR: Tests that all public error types implement Display.
Expand All @@ -256,6 +285,7 @@ fn c_good_err_display() {

fn assert_display<T: fmt::Display>() {}

assert_display::<amount::error::BadPositionError>();
assert_display::<amount::error::InvalidCharacterError>();
assert_display::<amount::error::MissingDenominationError>();
assert_display::<amount::error::MissingDigitsError>();
Expand All @@ -270,17 +300,87 @@ fn c_good_err_display() {
#[cfg(feature = "serde")]
assert_display::<fee_rate::serde::OverflowError>();
assert_display::<locktime::absolute::ConversionError>();
assert_display::<locktime::absolute::IncompatibleHeightError>();
assert_display::<locktime::absolute::IncompatibleTimeError>();
assert_display::<locktime::absolute::ParseHeightError>();
assert_display::<locktime::absolute::ParseTimeError>();
assert_display::<locktime::relative::DisabledLockTimeError>();
assert_display::<locktime::relative::IncompatibleHeightError>();
assert_display::<locktime::relative::IncompatibleTimeError>();
assert_display::<locktime::relative::InvalidHeightError>();
assert_display::<locktime::relative::InvalidTimeError>();
assert_display::<locktime::relative::IsSatisfiedByError>();
assert_display::<locktime::relative::IsSatisfiedByHeightError>();
assert_display::<locktime::relative::IsSatisfiedByTimeError>();
assert_display::<locktime::relative::TimeOverflowError>();
assert_display::<parse_int::ParseIntError>();
assert_display::<parse_int::PrefixedHexError>();
assert_display::<parse_int::UnprefixedHexError>();
#[cfg(feature = "encoding")]
assert_display::<pow::CompactTargetDecoderError>();
assert_display::<pow::ParseTargetError>();
assert_display::<pow::ParseWorkError>();
assert_display::<result::NumOpError>();

#[cfg(feature = "encoding")]
{
assert_display::<amount::error::AmountDecoderError>();
assert_display::<block::BlockHeightDecoderError>();
assert_display::<locktime::absolute::LockTimeDecoderError>();
assert_display::<pow::CompactTargetDecoderError>();
assert_display::<sequence::SequenceDecoderError>();
assert_display::<time::BlockTimeDecoderError>();
}
}

/// C-GOOD-ERR: Tests that all public error types implement `std::error::Error`.
#[test]
#[cfg(feature = "std")]
fn c_good_err_error() {
fn assert_error<T: std::error::Error>() {}

assert_error::<amount::error::BadPositionError>();
assert_error::<amount::error::InvalidCharacterError>();
assert_error::<amount::error::MissingDenominationError>();
assert_error::<amount::error::MissingDigitsError>();
assert_error::<amount::error::OutOfRangeError>();
assert_error::<amount::error::ParseAmountError>();
assert_error::<amount::error::ParseDenominationError>();
assert_error::<amount::error::ParseError>();
assert_error::<amount::error::PossiblyConfusingDenominationError>();
assert_error::<amount::error::TooPreciseError>();
assert_error::<amount::error::UnknownDenominationError>();
assert_error::<block::TooBigForRelativeHeightError>();
#[cfg(feature = "serde")]
assert_error::<fee_rate::serde::OverflowError>();
assert_error::<locktime::absolute::ConversionError>();
assert_error::<locktime::absolute::IncompatibleHeightError>();
assert_error::<locktime::absolute::IncompatibleTimeError>();
assert_error::<locktime::absolute::ParseHeightError>();
assert_error::<locktime::absolute::ParseTimeError>();
assert_error::<locktime::relative::DisabledLockTimeError>();
assert_error::<locktime::relative::IncompatibleHeightError>();
assert_error::<locktime::relative::IncompatibleTimeError>();
assert_error::<locktime::relative::InvalidHeightError>();
assert_error::<locktime::relative::InvalidTimeError>();
assert_error::<locktime::relative::IsSatisfiedByError>();
assert_error::<locktime::relative::IsSatisfiedByHeightError>();
assert_error::<locktime::relative::IsSatisfiedByTimeError>();
assert_error::<locktime::relative::TimeOverflowError>();
assert_error::<parse_int::ParseIntError>();
assert_error::<parse_int::PrefixedHexError>();
assert_error::<parse_int::UnprefixedHexError>();
assert_error::<pow::ParseTargetError>();
assert_error::<pow::ParseWorkError>();
assert_error::<result::NumOpError>();

#[cfg(feature = "encoding")]
{
assert_error::<amount::error::AmountDecoderError>();
assert_error::<block::BlockHeightDecoderError>();
assert_error::<locktime::absolute::LockTimeDecoderError>();
assert_error::<pow::CompactTargetDecoderError>();
assert_error::<sequence::SequenceDecoderError>();
assert_error::<time::BlockTimeDecoderError>();
}
}

/// C-OBJECT: Tests that traits are object-safe where appropriate.
Expand All @@ -301,10 +401,20 @@ fn c_object() {
fn c_serde() {
fn assert_serde<T: serde::Serialize + for<'de> serde::Deserialize<'de>>() {}

assert_serde::<absolute::Height>();
assert_serde::<absolute::LockTime>();
assert_serde::<absolute::MedianTimePast>();
assert_serde::<relative::LockTime>();
assert_serde::<relative::NumberOf512Seconds>();
assert_serde::<relative::NumberOfBlocks>();
assert_serde::<BlockHeight>();
assert_serde::<BlockHeightInterval>();
assert_serde::<BlockMtp>();
assert_serde::<BlockMtpInterval>();
assert_serde::<BlockTime>();
assert_serde::<pow::CompactTarget>();
assert_serde::<pow::Target>();
assert_serde::<pow::Work>();
assert_serde::<Weight>();
assert_serde::<Sequence>();
}
Expand Down Expand Up @@ -380,7 +490,7 @@ fn p_consistent_exports_crate_modules() {
fn p_consistent_exports_crate_types() {
use bitcoin_units::{
Amount, BlockHeight, BlockHeightInterval, BlockMtp, BlockMtpInterval, BlockTime,
CompactTarget, FeeRate, NumOpResult, Sequence, SignedAmount, Weight,
CompactTarget, FeeRate, NumOpResult, Sequence, SignedAmount, Target, Weight, Work,
};
}

Expand Down Expand Up @@ -454,12 +564,14 @@ fn p_consistent_exports_locktime_absolute() {
#[test]
fn p_consistent_exports_locktime_relative() {
use bitcoin_units::locktime::relative::error::{
DisabledLockTimeError as _, InvalidHeightError as _, InvalidTimeError as _,
TimeOverflowError as _,
DisabledLockTimeError as _, IncompatibleHeightError as _, IncompatibleTimeError as _,
InvalidHeightError as _, InvalidTimeError as _, IsSatisfiedByError as _,
IsSatisfiedByHeightError as _, IsSatisfiedByTimeError as _, TimeOverflowError as _,
};
use bitcoin_units::locktime::relative::{
DisabledLockTimeError, InvalidHeightError, InvalidTimeError, NumberOf512Seconds,
NumberOfBlocks, TimeOverflowError,
DisabledLockTimeError, IncompatibleHeightError, IncompatibleTimeError, InvalidHeightError,
InvalidTimeError, IsSatisfiedByError, IsSatisfiedByHeightError, IsSatisfiedByTimeError,
NumberOf512Seconds, NumberOfBlocks, TimeOverflowError,
};
}

Expand All @@ -478,7 +590,8 @@ fn p_consistent_exports_result() {
/// P-CONSISTENT-EXPORTS: Tests that all types can be imported from the `pow` module.
#[test]
fn p_consistent_exports_pow() {
use bitcoin_units::pow::CompactTarget;
use bitcoin_units::pow::error::{ParseTargetError as _, ParseWorkError as _};
use bitcoin_units::pow::{CompactTarget, ParseTargetError, ParseWorkError, Target, Work};
#[cfg(feature = "encoding")]
use bitcoin_units::pow::{
CompactTargetDecoder, CompactTargetDecoderError, CompactTargetEncoder,
Expand Down Expand Up @@ -552,9 +665,11 @@ impl<'a> Arbitrary<'a> for Structs {
k: relative::NumberOf512Seconds::arbitrary(u)?,
l: relative::NumberOfBlocks::arbitrary(u)?,
m: pow::CompactTarget::from_consensus(u.int_in_range(0..=u32::MAX)?),
n: sequence::Sequence::arbitrary(u)?,
o: BlockTime::arbitrary(u)?,
p: Weight::arbitrary(u)?,
n: pow::Target::arbitrary(u)?,
o: pow::Work::arbitrary(u)?,
p: sequence::Sequence::arbitrary(u)?,
q: BlockTime::arbitrary(u)?,
r: Weight::arbitrary(u)?,
};
Ok(a)
}
Expand Down