diff --git a/Cargo.toml b/Cargo.toml index 8892415d..91807557 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -109,6 +109,7 @@ env_logger = "0.7" electrsd = "0.21" # Move back to importing from rust-bitcoin once https://github.com/rust-bitcoin/rust-bitcoin/pull/1342 is released base64 = "^0.13" +assert_matches = "1.5.0" [[example]] name = "compact_filters_balance" diff --git a/src/blockchain/compact_filters/sync.rs b/src/blockchain/compact_filters/sync.rs index a67b5705..ba4e0045 100644 --- a/src/blockchain/compact_filters/sync.rs +++ b/src/blockchain/compact_filters/sync.rs @@ -136,7 +136,7 @@ impl CfSync { let resp = peer.get_cf_headers(0x00, start_height as u32, stop_hash)?; - assert!(resp.previous_filter_header == checkpoint); + assert_eq!(resp.previous_filter_header, checkpoint); status = self.cf_store .advance_to_cf_headers(index, checkpoint, resp.filter_hashes)?; diff --git a/src/database/sqlite.rs b/src/database/sqlite.rs index 9bcfca83..fc715085 100644 --- a/src/database/sqlite.rs +++ b/src/database/sqlite.rs @@ -1137,12 +1137,10 @@ pub mod test { let child: u32 = row.get(1).unwrap(); let count: usize = row.get(2).unwrap(); - assert!( - count == 1, + assert_eq!( + count, 1, "keychain={}, child={}, count={}", - keychain, - child, - count + keychain, child, count ); } } diff --git a/src/descriptor/checksum.rs b/src/descriptor/checksum.rs index 6be3a244..b4ba0e8f 100644 --- a/src/descriptor/checksum.rs +++ b/src/descriptor/checksum.rs @@ -133,6 +133,7 @@ pub fn get_checksum(desc: &str) -> Result { mod test { use super::*; use crate::descriptor::calc_checksum; + use assert_matches::assert_matches; // test calc_checksum() function; it should return the same value as Bitcoin Core #[test] @@ -155,16 +156,16 @@ mod test { assert_eq!(calc_checksum(desc).unwrap(), "lasegmfs"); let desc = "wpkh(tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N/1/2/*)#tqz0nc26"; - assert!(matches!( - calc_checksum(desc).err(), - Some(DescriptorError::InvalidDescriptorChecksum) - )); + assert_matches!( + calc_checksum(desc), + Err(DescriptorError::InvalidDescriptorChecksum) + ); let desc = "pkh(tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/44'/1'/0'/0/*)#lasegmsf"; - assert!(matches!( - calc_checksum(desc).err(), - Some(DescriptorError::InvalidDescriptorChecksum) - )); + assert_matches!( + calc_checksum(desc), + Err(DescriptorError::InvalidDescriptorChecksum) + ); } #[test] @@ -172,9 +173,9 @@ mod test { let sparkle_heart = unsafe { std::str::from_utf8_unchecked(&[240, 159, 146, 150]) }; let invalid_desc = format!("wpkh(tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcL{}fjdi5qUvw3VDfgYiH5mNsj5izuiu2N/1/2/*)", sparkle_heart); - assert!(matches!( - calc_checksum(&invalid_desc).err(), - Some(DescriptorError::InvalidDescriptorCharacter(invalid_char)) if invalid_char == sparkle_heart.as_bytes()[0] - )); + assert_matches!( + calc_checksum(&invalid_desc), + Err(DescriptorError::InvalidDescriptorCharacter(invalid_char)) if invalid_char == sparkle_heart.as_bytes()[0] + ); } } diff --git a/src/descriptor/mod.rs b/src/descriptor/mod.rs index 233e8d19..b307bbf1 100644 --- a/src/descriptor/mod.rs +++ b/src/descriptor/mod.rs @@ -581,6 +581,7 @@ impl DescriptorMeta for ExtendedDescriptor { mod test { use std::str::FromStr; + use assert_matches::assert_matches; use bitcoin::consensus::encode::deserialize; use bitcoin::hashes::hex::FromHex; use bitcoin::secp256k1::Secp256k1; @@ -763,17 +764,11 @@ mod test { let desc = "wpkh(tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N/1/2/*)#67ju93jw" .into_wallet_descriptor(&secp, Network::Testnet); - assert!(matches!( - desc.err(), - Some(DescriptorError::InvalidDescriptorChecksum) - )); + assert_matches!(desc, Err(DescriptorError::InvalidDescriptorChecksum)); let desc = "wpkh(tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N/1/2/*)#67ju93jw" .into_wallet_descriptor(&secp, Network::Testnet); - assert!(matches!( - desc.err(), - Some(DescriptorError::InvalidDescriptorChecksum) - )); + assert_matches!(desc, Err(DescriptorError::InvalidDescriptorChecksum)); } // test IntoWalletDescriptor trait from &str with keys from right and wrong network @@ -807,17 +802,11 @@ mod test { let desc = "wpkh(tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N/1/2/*)" .into_wallet_descriptor(&secp, Network::Bitcoin); - assert!(matches!( - desc.err(), - Some(DescriptorError::Key(KeyError::InvalidNetwork)) - )); + assert_matches!(desc, Err(DescriptorError::Key(KeyError::InvalidNetwork))); let desc = "wpkh(tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/1/2/*)" .into_wallet_descriptor(&secp, Network::Bitcoin); - assert!(matches!( - desc.err(), - Some(DescriptorError::Key(KeyError::InvalidNetwork)) - )); + assert_matches!(desc, Err(DescriptorError::Key(KeyError::InvalidNetwork))); } // test IntoWalletDescriptor trait from the output of the descriptor!() macro @@ -851,11 +840,7 @@ mod test { let descriptor = "wpkh(tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/0'/1/2/*)"; let result = into_wallet_descriptor_checked(descriptor, &secp, Network::Testnet); - assert!(result.is_err()); - assert!(matches!( - result.unwrap_err(), - DescriptorError::HardenedDerivationXpub - )); + assert_matches!(result, Err(DescriptorError::HardenedDerivationXpub)); let descriptor = "wsh(multi(2,tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/0/*,tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/0/*))"; let result = into_wallet_descriptor_checked(descriptor, &secp, Network::Testnet); diff --git a/src/descriptor/policy.rs b/src/descriptor/policy.rs index 964ec291..f481f988 100644 --- a/src/descriptor/policy.rs +++ b/src/descriptor/policy.rs @@ -1139,6 +1139,7 @@ mod test { use crate::descriptor::policy::SatisfiableItem::{EcdsaSignature, Multisig, Thresh}; use crate::keys::{DescriptorKey, IntoDescriptorKey}; use crate::wallet::signer::SignersContainer; + use assert_matches::assert_matches; use bitcoin::secp256k1::Secp256k1; use bitcoin::util::bip32; use bitcoin::Network; @@ -1182,8 +1183,8 @@ mod test { .unwrap() .unwrap(); - assert!(matches!(&policy.item, EcdsaSignature(PkOrF::Fingerprint(f)) if f == &fingerprint)); - assert!(matches!(&policy.contribution, Satisfaction::None)); + assert_matches!(&policy.item, EcdsaSignature(PkOrF::Fingerprint(f)) if f == &fingerprint); + assert_matches!(&policy.contribution, Satisfaction::None); let desc = descriptor!(wpkh(prvkey)).unwrap(); let (wallet_desc, keymap) = desc @@ -1195,10 +1196,8 @@ mod test { .unwrap() .unwrap(); - assert!(matches!(&policy.item, EcdsaSignature(PkOrF::Fingerprint(f)) if f == &fingerprint)); - assert!( - matches!(&policy.contribution, Satisfaction::Complete {condition} if condition.csv == None && condition.timelock == None) - ); + assert_matches!(&policy.item, EcdsaSignature(PkOrF::Fingerprint(f)) if f == &fingerprint); + assert_matches!(&policy.contribution, Satisfaction::Complete {condition} if condition.csv == None && condition.timelock == None); } // 2 pub keys descriptor, required 2 prv keys @@ -1217,19 +1216,16 @@ mod test { .unwrap() .unwrap(); - assert!( - matches!(&policy.item, Multisig { keys, threshold } if threshold == &2usize + assert_matches!(&policy.item, Multisig { keys, threshold } if threshold == &2usize && keys[0] == PkOrF::Fingerprint(fingerprint0) - && keys[1] == PkOrF::Fingerprint(fingerprint1)) + && keys[1] == PkOrF::Fingerprint(fingerprint1) ); // TODO should this be "Satisfaction::None" since we have no prv keys? // TODO should items and conditions not be empty? - assert!( - matches!(&policy.contribution, Satisfaction::Partial { n, m, items, conditions, ..} if n == &2usize + assert_matches!(&policy.contribution, Satisfaction::Partial { n, m, items, conditions, ..} if n == &2usize && m == &2usize && items.is_empty() && conditions.is_empty() - ) ); } @@ -1248,18 +1244,15 @@ mod test { .extract_policy(&signers_container, BuildSatisfaction::None, &secp) .unwrap() .unwrap(); - assert!( - matches!(&policy.item, Multisig { keys, threshold } if threshold == &2usize + assert_matches!(&policy.item, Multisig { keys, threshold } if threshold == &2usize && keys[0] == PkOrF::Fingerprint(fingerprint0) - && keys[1] == PkOrF::Fingerprint(fingerprint1)) + && keys[1] == PkOrF::Fingerprint(fingerprint1) ); - assert!( - matches!(&policy.contribution, Satisfaction::Partial { n, m, items, conditions, ..} if n == &2usize + assert_matches!(&policy.contribution, Satisfaction::Partial { n, m, items, conditions, ..} if n == &2usize && m == &2usize && items.len() == 1 && conditions.contains_key(&0) - ) ); } @@ -1281,18 +1274,15 @@ mod test { .unwrap() .unwrap(); - assert!( - matches!(&policy.item, Multisig { keys, threshold } if threshold == &1 + assert_matches!(&policy.item, Multisig { keys, threshold } if threshold == &1 && keys[0] == PkOrF::Fingerprint(fingerprint0) - && keys[1] == PkOrF::Fingerprint(fingerprint1)) + && keys[1] == PkOrF::Fingerprint(fingerprint1) ); - assert!( - matches!(&policy.contribution, Satisfaction::PartialComplete { n, m, items, conditions, .. } if n == &2 + assert_matches!(&policy.contribution, Satisfaction::PartialComplete { n, m, items, conditions, .. } if n == &2 && m == &1 && items.len() == 2 && conditions.contains_key(&vec![0]) && conditions.contains_key(&vec![1]) - ) ); } @@ -1313,18 +1303,15 @@ mod test { .unwrap() .unwrap(); - assert!( - matches!(&policy.item, Multisig { keys, threshold } if threshold == &2 + assert_matches!(&policy.item, Multisig { keys, threshold } if threshold == &2 && keys[0] == PkOrF::Fingerprint(fingerprint0) - && keys[1] == PkOrF::Fingerprint(fingerprint1)) + && keys[1] == PkOrF::Fingerprint(fingerprint1) ); - assert!( - matches!(&policy.contribution, Satisfaction::PartialComplete { n, m, items, conditions, .. } if n == &2 + assert_matches!(&policy.contribution, Satisfaction::PartialComplete { n, m, items, conditions, .. } if n == &2 && m == &2 && items.len() == 2 && conditions.contains_key(&vec![0,1]) - ) ); } @@ -1345,8 +1332,8 @@ mod test { .unwrap() .unwrap(); - assert!(matches!(&policy.item, EcdsaSignature(PkOrF::Fingerprint(f)) if f == &fingerprint)); - assert!(matches!(&policy.contribution, Satisfaction::None)); + assert_matches!(&policy.item, EcdsaSignature(PkOrF::Fingerprint(f)) if f == &fingerprint); + assert_matches!(&policy.contribution, Satisfaction::None); let desc = descriptor!(wpkh(prvkey)).unwrap(); let (wallet_desc, keymap) = desc @@ -1358,10 +1345,8 @@ mod test { .unwrap() .unwrap(); - assert!(matches!(policy.item, EcdsaSignature(PkOrF::Fingerprint(f)) if f == fingerprint)); - assert!( - matches!(policy.contribution, Satisfaction::Complete {condition} if condition.csv == None && condition.timelock == None) - ); + assert_matches!(policy.item, EcdsaSignature(PkOrF::Fingerprint(f)) if f == fingerprint); + assert_matches!(policy.contribution, Satisfaction::Complete {condition} if condition.csv == None && condition.timelock == None); } // single key, 1 prv and 1 pub key descriptor, required 1 prv keys @@ -1382,18 +1367,15 @@ mod test { .unwrap() .unwrap(); - assert!( - matches!(policy.item, Multisig { keys, threshold } if threshold == 1 + assert_matches!(policy.item, Multisig { keys, threshold } if threshold == 1 && keys[0] == PkOrF::Fingerprint(fingerprint0) - && keys[1] == PkOrF::Fingerprint(fingerprint1)) + && keys[1] == PkOrF::Fingerprint(fingerprint1) ); - assert!( - matches!(policy.contribution, Satisfaction::PartialComplete { n, m, items, conditions, .. } if n == 2 + assert_matches!(policy.contribution, Satisfaction::PartialComplete { n, m, items, conditions, .. } if n == 2 && m == 1 && items.len() == 2 && conditions.contains_key(&vec![0]) && conditions.contains_key(&vec![1]) - ) ); } @@ -1425,18 +1407,14 @@ mod test { .unwrap() .unwrap(); - assert!( - matches!(&policy.item, Thresh { items, threshold } if items.len() == 3 && threshold == &2) - ); + assert_matches!(&policy.item, Thresh { items, threshold } if items.len() == 3 && threshold == &2); - assert!( - matches!(&policy.contribution, Satisfaction::PartialComplete { n, m, items, conditions, .. } if n == &3 + assert_matches!(&policy.contribution, Satisfaction::PartialComplete { n, m, items, conditions, .. } if n == &3 && m == &2 && items.len() == 3 && conditions.get(&vec![0,1]).unwrap().iter().next().unwrap().csv.is_none() && conditions.get(&vec![0,2]).unwrap().iter().next().unwrap().csv == Some(Sequence(sequence)) && conditions.get(&vec![1,2]).unwrap().iter().next().unwrap().csv == Some(Sequence(sequence)) - ) ); } @@ -1599,11 +1577,9 @@ mod test { .unwrap(); //println!("{}", serde_json::to_string(&policy_alice_psbt).unwrap()); - assert!( - matches!(&policy_alice_psbt.satisfaction, Satisfaction::Partial { n, m, items, .. } if n == &2 + assert_matches!(&policy_alice_psbt.satisfaction, Satisfaction::Partial { n, m, items, .. } if n == &2 && m == &2 && items == &vec![0] - ) ); let psbt = Psbt::from_str(BOB_SIGNED_PSBT).unwrap(); @@ -1613,11 +1589,9 @@ mod test { .unwrap(); //println!("{}", serde_json::to_string(&policy_bob_psbt).unwrap()); - assert!( - matches!(&policy_bob_psbt.satisfaction, Satisfaction::Partial { n, m, items, .. } if n == &2 + assert_matches!(&policy_bob_psbt.satisfaction, Satisfaction::Partial { n, m, items, .. } if n == &2 && m == &2 && items == &vec![1] - ) ); let psbt = Psbt::from_str(ALICE_BOB_SIGNED_PSBT).unwrap(); @@ -1625,11 +1599,9 @@ mod test { .extract_policy(&signers_container, BuildSatisfaction::Psbt(&psbt), &secp) .unwrap() .unwrap(); - assert!( - matches!(&policy_alice_bob_psbt.satisfaction, Satisfaction::PartialComplete { n, m, items, .. } if n == &2 + assert_matches!(&policy_alice_bob_psbt.satisfaction, Satisfaction::PartialComplete { n, m, items, .. } if n == &2 && m == &2 && items == &vec![0, 1] - ) ); } @@ -1673,11 +1645,9 @@ mod test { .extract_policy(&signers_container, build_sat, &secp) .unwrap() .unwrap(); - assert!( - matches!(&policy.satisfaction, Satisfaction::Partial { n, m, items, .. } if n == &3 + assert_matches!(&policy.satisfaction, Satisfaction::Partial { n, m, items, .. } if n == &3 && m == &2 && items.is_empty() - ) ); //println!("{}", serde_json::to_string(&policy).unwrap()); @@ -1691,11 +1661,9 @@ mod test { .extract_policy(&signers_container, build_sat_expired, &secp) .unwrap() .unwrap(); - assert!( - matches!(&policy_expired.satisfaction, Satisfaction::Partial { n, m, items, .. } if n == &3 + assert_matches!(&policy_expired.satisfaction, Satisfaction::Partial { n, m, items, .. } if n == &3 && m == &2 && items == &vec![0] - ) ); //println!("{}", serde_json::to_string(&policy_expired).unwrap()); @@ -1711,11 +1679,9 @@ mod test { .extract_policy(&signers_container, build_sat_expired_signed, &secp) .unwrap() .unwrap(); - assert!( - matches!(&policy_expired_signed.satisfaction, Satisfaction::PartialComplete { n, m, items, .. } if n == &3 + assert_matches!(&policy_expired_signed.satisfaction, Satisfaction::PartialComplete { n, m, items, .. } if n == &3 && m == &2 && items == &vec![0, 1] - ) ); //println!("{}", serde_json::to_string(&policy_expired_signed).unwrap()); } @@ -1790,12 +1756,8 @@ mod test { .unwrap() .unwrap(); - assert!( - matches!(policy.item, SatisfiableItem::Thresh { ref items, threshold: 1 } if items.len() == 2) - ); - assert!( - matches!(policy.contribution, Satisfaction::PartialComplete { n: 2, m: 1, items, .. } if items == vec![1]) - ); + assert_matches!(policy.item, SatisfiableItem::Thresh { ref items, threshold: 1 } if items.len() == 2); + assert_matches!(policy.contribution, Satisfaction::PartialComplete { n: 2, m: 1, items, .. } if items == vec![1]); let alice_sig = SatisfiableItem::SchnorrSignature(PkOrF::Fingerprint(alice_fing)); let bob_sig = SatisfiableItem::SchnorrSignature(PkOrF::Fingerprint(bob_fing)); @@ -1887,19 +1849,11 @@ mod test { .unwrap() .unwrap(); - assert!( - matches!(policy_unsigned.item, SatisfiableItem::Thresh { ref items, threshold: 1 } if items.len() == 2) - ); - assert!( - matches!(policy_unsigned.satisfaction, Satisfaction::Partial { n: 2, m: 1, items, .. } if items.is_empty()) - ); + assert_matches!(policy_unsigned.item, SatisfiableItem::Thresh { ref items, threshold: 1 } if items.len() == 2); + assert_matches!(policy_unsigned.satisfaction, Satisfaction::Partial { n: 2, m: 1, items, .. } if items.is_empty()); - assert!( - matches!(policy_signed.item, SatisfiableItem::Thresh { ref items, threshold: 1 } if items.len() == 2) - ); - assert!( - matches!(policy_signed.satisfaction, Satisfaction::PartialComplete { n: 2, m: 1, items, .. } if items == vec![0, 1]) - ); + assert_matches!(policy_signed.item, SatisfiableItem::Thresh { ref items, threshold: 1 } if items.len() == 2); + assert_matches!(policy_signed.satisfaction, Satisfaction::PartialComplete { n: 2, m: 1, items, .. } if items == vec![0, 1]); let satisfied_items = match policy_signed.item { SatisfiableItem::Thresh { items, .. } => items, diff --git a/src/descriptor/template.rs b/src/descriptor/template.rs index ddf57952..3bd2c59e 100644 --- a/src/descriptor/template.rs +++ b/src/descriptor/template.rs @@ -483,6 +483,7 @@ mod test { use super::*; use crate::descriptor::{DescriptorError, DescriptorMeta}; use crate::keys::ValidNetworks; + use assert_matches::assert_matches; use bitcoin::network::constants::Network::Regtest; use miniscript::descriptor::{DescriptorPublicKey, KeyMap}; use miniscript::Descriptor; @@ -501,9 +502,9 @@ mod test { if let ExtendedDescriptor::Pkh(pkh) = xdesc.0 { let path: Vec = pkh.into_inner().full_derivation_path().into(); let purpose = path.get(0).unwrap(); - assert!(matches!(purpose, Hardened { index: 44 })); + assert_matches!(purpose, Hardened { index: 44 }); let coin_type = path.get(1).unwrap(); - assert!(matches!(coin_type, Hardened { index: 0 })); + assert_matches!(coin_type, Hardened { index: 0 }); } let tprvkey = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap(); @@ -515,9 +516,9 @@ mod test { if let ExtendedDescriptor::Pkh(pkh) = tdesc.0 { let path: Vec = pkh.into_inner().full_derivation_path().into(); let purpose = path.get(0).unwrap(); - assert!(matches!(purpose, Hardened { index: 44 })); + assert_matches!(purpose, Hardened { index: 44 }); let coin_type = path.get(1).unwrap(); - assert!(matches!(coin_type, Hardened { index: 1 })); + assert_matches!(coin_type, Hardened { index: 1 }); } } diff --git a/src/lib.rs b/src/lib.rs index 1a644ebd..23c4e34d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -256,6 +256,9 @@ pub extern crate rusqlite; #[macro_use] pub mod testutils; +#[cfg(test)] +extern crate assert_matches; + #[allow(unused_imports)] #[macro_use] pub(crate) mod error; diff --git a/src/testutils/configurable_blockchain_tests.rs b/src/testutils/configurable_blockchain_tests.rs index 8662844d..423c55d0 100644 --- a/src/testutils/configurable_blockchain_tests.rs +++ b/src/testutils/configurable_blockchain_tests.rs @@ -23,7 +23,7 @@ pub trait ConfigurableBlockchainTester: Sized { None } - /// Runs all avaliable tests. + /// Runs all available tests. fn run(&self) { let test_client = &mut TestClient::default(); diff --git a/src/wallet/coin_selection.rs b/src/wallet/coin_selection.rs index 30d07c15..8482f96a 100644 --- a/src/wallet/coin_selection.rs +++ b/src/wallet/coin_selection.rs @@ -102,11 +102,11 @@ use crate::{error::Error, Utxo}; use bitcoin::consensus::encode::serialize; use bitcoin::Script; +#[cfg(test)] +use assert_matches::assert_matches; use rand::seq::SliceRandom; #[cfg(not(test))] use rand::thread_rng; -#[cfg(test)] -use rand::{rngs::StdRng, SeedableRng}; use std::collections::HashMap; use std::convert::TryInto; @@ -671,6 +671,7 @@ impl BranchAndBoundCoinSelection { optional_utxos.shuffle(&mut thread_rng()); #[cfg(test)] { + use rand::{rngs::StdRng, SeedableRng}; let seed = [0; 32]; let mut rng: StdRng = SeedableRng::from_seed(seed); optional_utxos.shuffle(&mut rng); @@ -1522,24 +1523,22 @@ mod test { let database = MemoryDatabase::default(); let drain_script = Script::default(); - let err = BranchAndBoundCoinSelection::default() - .coin_select( - &database, - vec![], - utxos, - FeeRate::from_sat_per_vb(10.0), - 500_000, - &drain_script, - ) - .unwrap_err(); + let selection = BranchAndBoundCoinSelection::default().coin_select( + &database, + vec![], + utxos, + FeeRate::from_sat_per_vb(10.0), + 500_000, + &drain_script, + ); - assert!(matches!( - err, - Error::InsufficientFunds { + assert_matches!( + selection, + Err(Error::InsufficientFunds { available: 300_000, .. - } - )); + }) + ); } #[test] @@ -1552,24 +1551,22 @@ mod test { .into_iter() .partition(|u| matches!(u, WeightedUtxo { utxo, .. } if utxo.txout().value < 1000)); - let err = BranchAndBoundCoinSelection::default() - .coin_select( - &database, - required, - optional, - FeeRate::from_sat_per_vb(10.0), - 500_000, - &drain_script, - ) - .unwrap_err(); + let selection = BranchAndBoundCoinSelection::default().coin_select( + &database, + required, + optional, + FeeRate::from_sat_per_vb(10.0), + 500_000, + &drain_script, + ); - assert!(matches!( - err, - Error::InsufficientFunds { + assert_matches!( + selection, + Err(Error::InsufficientFunds { available: 300_010, .. - } - )); + }) + ); } #[test] @@ -1578,23 +1575,21 @@ mod test { let database = MemoryDatabase::default(); let drain_script = Script::default(); - let err = BranchAndBoundCoinSelection::default() - .coin_select( - &database, - utxos, - vec![], - FeeRate::from_sat_per_vb(10_000.0), - 500_000, - &drain_script, - ) - .unwrap_err(); + let selection = BranchAndBoundCoinSelection::default().coin_select( + &database, + utxos, + vec![], + FeeRate::from_sat_per_vb(10_000.0), + 500_000, + &drain_script, + ); - assert!(matches!( - err, - Error::InsufficientFunds { + assert_matches!( + selection, + Err(Error::InsufficientFunds { available: 300_010, .. - } - )); + }) + ); } } diff --git a/src/wallet/mod.rs b/src/wallet/mod.rs index 1a2a4f6a..f65440e1 100644 --- a/src/wallet/mod.rs +++ b/src/wallet/mod.rs @@ -1851,6 +1851,7 @@ pub fn get_funded_wallet( #[cfg(test)] pub(crate) mod test { + use assert_matches::assert_matches; use bitcoin::{util::psbt, Network, PackedLockTime, Sequence}; use crate::database::Database; @@ -4425,11 +4426,9 @@ pub(crate) mod test { result.is_err(), "Signing should have failed because the TX uses non-standard sighashes" ); - assert!( - matches!( - result.unwrap_err(), - Error::Signer(SignerError::NonStandardSighash) - ), + assert_matches!( + result, + Err(Error::Signer(SignerError::NonStandardSighash)), "Signing failed with the wrong error type" ); @@ -4912,16 +4911,10 @@ pub(crate) mod test { ..Default::default() }, ); - assert!( - result.is_err(), - "Signing should have failed because the witness_utxo is missing" - ); - assert!( - matches!( - result.unwrap_err(), - Error::Signer(SignerError::MissingWitnessUtxo) - ), - "Signing failed with the wrong error type" + assert_matches!( + result, + Err(Error::Signer(SignerError::MissingWitnessUtxo)), + "Signing should have failed with the correct error because the witness_utxo is missing" ); // restore the witness_utxo @@ -4935,9 +4928,9 @@ pub(crate) mod test { }, ); - assert!(result.is_ok(), "Signing should have worked"); - assert!( - result.unwrap(), + assert_matches!( + result, + Ok(true), "Should finalize the input since we can produce signatures" ); } @@ -5262,11 +5255,9 @@ pub(crate) mod test { result.is_err(), "Signing should have failed because the TX uses non-standard sighashes" ); - assert!( - matches!( - result.unwrap_err(), - Error::Signer(SignerError::NonStandardSighash) - ), + assert_matches!( + result, + Err(Error::Signer(SignerError::NonStandardSighash)), "Signing failed with the wrong error type" ); @@ -5282,11 +5273,9 @@ pub(crate) mod test { result.is_err(), "Signing should have failed because the witness_utxo is missing" ); - assert!( - matches!( - result.unwrap_err(), - Error::Signer(SignerError::MissingWitnessUtxo) - ), + assert_matches!( + result, + Err(Error::Signer(SignerError::MissingWitnessUtxo)), "Signing failed with the wrong error type" ); @@ -5367,26 +5356,26 @@ pub(crate) mod test { builder .add_recipient(addr.script_pubkey(), balance.immature / 2) .current_height(confirmation_time); - assert!(matches!( - builder.finish().unwrap_err(), - Error::InsufficientFunds { + assert_matches!( + builder.finish(), + Err(Error::InsufficientFunds { needed: _, available: 0 - } - )); + }) + ); // Still unspendable... let mut builder = wallet.build_tx(); builder .add_recipient(addr.script_pubkey(), balance.immature / 2) .current_height(not_yet_mature_time); - assert!(matches!( - builder.finish().unwrap_err(), - Error::InsufficientFunds { + assert_matches!( + builder.finish(), + Err(Error::InsufficientFunds { needed: _, available: 0 - } - )); + }) + ); // ...Now the coinbase is mature :) let sync_time = SyncTime { @@ -5428,10 +5417,7 @@ pub(crate) mod test { builder.add_recipient(addr.script_pubkey(), 0); - assert!(matches!( - builder.finish().unwrap_err(), - Error::OutputBelowDustLimit(0) - )); + assert_matches!(builder.finish(), Err(Error::OutputBelowDustLimit(0))); let mut builder = wallet.build_tx(); diff --git a/src/wallet/signer.rs b/src/wallet/signer.rs index 84d38826..ab6c4355 100644 --- a/src/wallet/signer.rs +++ b/src/wallet/signer.rs @@ -998,6 +998,7 @@ mod signers_container_tests { use crate::descriptor; use crate::descriptor::IntoWalletDescriptor; use crate::keys::{DescriptorKey, IntoDescriptorKey}; + use assert_matches::assert_matches; use bitcoin::secp256k1::{All, Secp256k1}; use bitcoin::util::bip32; use bitcoin::Network; @@ -1067,17 +1068,17 @@ mod signers_container_tests { signers.add_external(id2.clone(), SignerOrdering(2), signer2.clone()); signers.add_external(id3.clone(), SignerOrdering(3), signer3.clone()); - assert!(matches!(signers.find(id1), Some(signer) if is_equal(signer, &signer1))); - assert!(matches!(signers.find(id2), Some(signer) if is_equal(signer, &signer2))); - assert!(matches!(signers.find(id3.clone()), Some(signer) if is_equal(signer, &signer3))); + assert_matches!(signers.find(id1), Some(signer) if is_equal(signer, &signer1)); + assert_matches!(signers.find(id2), Some(signer) if is_equal(signer, &signer2)); + assert_matches!(signers.find(id3.clone()), Some(signer) if is_equal(signer, &signer3)); // The `signer4` has the same ID as `signer3` but lower ordering. // It should be found by `id3` instead of `signer3`. signers.add_external(id3.clone(), SignerOrdering(2), signer4.clone()); - assert!(matches!(signers.find(id3), Some(signer) if is_equal(signer, &signer4))); + assert_matches!(signers.find(id3), Some(signer) if is_equal(signer, &signer4)); // Can't find anything with ID that doesn't exist - assert!(matches!(signers.find(id_nonexistent), None)); + assert_matches!(signers.find(id_nonexistent), None); } #[derive(Debug, Clone, Copy)] diff --git a/src/wallet/verify.rs b/src/wallet/verify.rs index 084388b9..2fd865a1 100644 --- a/src/wallet/verify.rs +++ b/src/wallet/verify.rs @@ -108,6 +108,7 @@ impl_error!(bitcoinconsensus::Error, Consensus, VerifyError); mod test { use super::*; use crate::database::{BatchOperations, MemoryDatabase}; + use assert_matches::assert_matches; use bitcoin::consensus::encode::deserialize; use bitcoin::hashes::hex::FromHex; use bitcoin::{Transaction, Txid}; @@ -137,9 +138,7 @@ mod test { } let result = verify_tx(&signed_tx, &database, &blockchain); - assert!(result.is_err(), "Should fail with missing input tx"); - assert!( - matches!(result, Err(VerifyError::MissingInputTx(txid)) if txid == prev_tx.txid()), + assert_matches!(result, Err(VerifyError::MissingInputTx(txid)) if txid == prev_tx.txid(), "Error should be a `MissingInputTx` error" ); @@ -147,9 +146,9 @@ mod test { database.set_raw_tx(&prev_tx).unwrap(); let result = verify_tx(&unsigned_tx, &database, &blockchain); - assert!(result.is_err(), "Should fail since the TX is unsigned"); - assert!( - matches!(result, Err(VerifyError::Consensus(_))), + assert_matches!( + result, + Err(VerifyError::Consensus(_)), "Error should be a `Consensus` error" );