use blvm_protocol::features::{ActivationMethod, FeatureActivation, FeatureRegistry};
use blvm_protocol::ProtocolVersion;
#[test]
fn test_feature_activation_height_based() {
let feature = FeatureActivation {
feature_name: "test_feature".to_string(),
activation_height: Some(100),
activation_timestamp: None,
activation_method: ActivationMethod::HeightBased,
bip_number: None,
};
assert!(!feature.is_active_at(99, 0));
assert!(feature.is_active_at(100, 0));
assert!(feature.is_active_at(101, 0));
assert!(feature.is_active_at(1000, 0));
}
#[test]
fn test_feature_activation_timestamp_based() {
let feature = FeatureActivation {
feature_name: "test_feature".to_string(),
activation_height: None,
activation_timestamp: Some(1000),
activation_method: ActivationMethod::Timestamp,
bip_number: None,
};
assert!(!feature.is_active_at(0, 999));
assert!(feature.is_active_at(0, 1000));
assert!(feature.is_active_at(0, 1001));
assert!(feature.is_active_at(0, 10000));
}
#[test]
fn test_feature_activation_always_active() {
let feature = FeatureActivation {
feature_name: "test_feature".to_string(),
activation_height: None,
activation_timestamp: None,
activation_method: ActivationMethod::AlwaysActive,
bip_number: None,
};
assert!(feature.is_active_at(0, 0));
assert!(feature.is_active_at(100, 1000));
assert!(feature.is_active_at(u64::MAX, u64::MAX));
}
#[test]
fn test_feature_activation_hard_fork() {
let feature = FeatureActivation {
feature_name: "test_feature".to_string(),
activation_height: None,
activation_timestamp: None,
activation_method: ActivationMethod::HardFork,
bip_number: None,
};
assert!(feature.is_active_at(0, 0));
assert!(feature.is_active_at(100, 1000));
}
#[test]
fn test_feature_activation_bip9() {
let feature = FeatureActivation {
feature_name: "test_feature".to_string(),
activation_height: Some(100),
activation_timestamp: Some(1000),
activation_method: ActivationMethod::BIP9,
bip_number: Some(141),
};
assert!(!feature.is_active_at(99, 999));
assert!(feature.is_active_at(100, 999));
assert!(feature.is_active_at(99, 1000));
assert!(feature.is_active_at(100, 1000));
}
#[test]
fn test_feature_registry_for_protocol() {
let mainnet = FeatureRegistry::for_protocol(ProtocolVersion::BitcoinV1);
let testnet = FeatureRegistry::for_protocol(ProtocolVersion::Testnet3);
let regtest = FeatureRegistry::for_protocol(ProtocolVersion::Regtest);
assert!(!mainnet.features.is_empty());
assert!(!testnet.features.is_empty());
assert!(!regtest.features.is_empty());
assert_eq!(mainnet.protocol_version, ProtocolVersion::BitcoinV1);
assert_eq!(testnet.protocol_version, ProtocolVersion::Testnet3);
assert_eq!(regtest.protocol_version, ProtocolVersion::Regtest);
}
#[test]
fn test_feature_registry_is_feature_active() {
let registry = FeatureRegistry::for_protocol(ProtocolVersion::BitcoinV1);
let segwit_active = registry.is_feature_active("segwit", 500_000, 1_500_000_000);
let _ = segwit_active;
assert!(!registry.is_feature_active("nonexistent_feature", 0, 0));
}
#[test]
fn test_feature_registry_get_feature() {
let registry = FeatureRegistry::for_protocol(ProtocolVersion::BitcoinV1);
let segwit = registry.get_feature("segwit");
let _ = segwit;
assert!(registry.get_feature("nonexistent_feature").is_none());
}
#[test]
fn test_feature_registry_list_features() {
let registry = FeatureRegistry::for_protocol(ProtocolVersion::BitcoinV1);
let features = registry.list_features();
assert!(!features.is_empty());
for feature in &features {
assert!(!feature.is_empty());
}
}
#[test]
fn test_feature_context_creation() {
let registry = FeatureRegistry::for_protocol(ProtocolVersion::BitcoinV1);
let context = registry.create_context(500_000, 1_500_000_000);
assert!(context.active_features().len() >= 0);
}
#[test]
fn test_feature_activation_edge_cases() {
let feature = FeatureActivation {
feature_name: "test".to_string(),
activation_height: None,
activation_timestamp: None,
activation_method: ActivationMethod::HeightBased,
bip_number: None,
};
assert!(!feature.is_active_at(0, 0));
assert!(!feature.is_active_at(u64::MAX, u64::MAX));
}
#[test]
fn test_feature_activation_timestamp_edge_cases() {
let feature = FeatureActivation {
feature_name: "test".to_string(),
activation_height: None,
activation_timestamp: None,
activation_method: ActivationMethod::Timestamp,
bip_number: None,
};
assert!(!feature.is_active_at(0, 0));
assert!(!feature.is_active_at(0, u64::MAX));
}
#[test]
fn test_feature_activation_boundary_values() {
let feature = FeatureActivation {
feature_name: "test".to_string(),
activation_height: Some(100),
activation_timestamp: None,
activation_method: ActivationMethod::HeightBased,
bip_number: None,
};
assert!(!feature.is_active_at(99, 0)); assert!(feature.is_active_at(100, 0)); assert!(feature.is_active_at(101, 0));
assert!(feature.is_active_at(u64::MAX, 0));
}
#[test]
fn test_feature_activation_multiple_methods() {
let height_feature = FeatureActivation {
feature_name: "height".to_string(),
activation_height: Some(100),
activation_timestamp: None,
activation_method: ActivationMethod::HeightBased,
bip_number: None,
};
let timestamp_feature = FeatureActivation {
feature_name: "timestamp".to_string(),
activation_height: None,
activation_timestamp: Some(1000),
activation_method: ActivationMethod::Timestamp,
bip_number: None,
};
assert!(height_feature.is_active_at(100, 999));
assert!(!timestamp_feature.is_active_at(100, 999));
assert!(!height_feature.is_active_at(99, 1000));
assert!(timestamp_feature.is_active_at(99, 1000));
}