// file: crates/ksp-offchain-transport-lib/tests/release_completeness.rs // version: 1 #![warn(missing_docs)] #![deny(unreachable_pub)] #![forbid(unsafe_code)] //! Release-level completeness canaries for the eight-provider SOL/USD V1 contract. #[test] fn pre_010_exact_eight_provider_inventory_and_semantics_are_stable() -> ksp_core_lib::Result<()> { let setups = match all_disabled_setups() { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; let service = match ksp_offchain_transport_lib::MarketPriceService::new(setups) { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; let registry = service.registry(); assert_eq!(registry.len(), 8); let expected = [ ( "birdeye", ksp_offchain_transport_lib::MarketPriceSemantics::SolanaSpot, ksp_offchain_transport_lib::MarketPriceProviderAuthMode::RequiredApiKey, ), ( "coinbase_exchange", ksp_offchain_transport_lib::MarketPriceSemantics::ExchangeLastTrade, ksp_offchain_transport_lib::MarketPriceProviderAuthMode::None, ), ( "coingecko", ksp_offchain_transport_lib::MarketPriceSemantics::AggregatedMarket, ksp_offchain_transport_lib::MarketPriceProviderAuthMode::None, ), ( "coinmarketcap", ksp_offchain_transport_lib::MarketPriceSemantics::AggregatedMarket, ksp_offchain_transport_lib::MarketPriceProviderAuthMode::None, ), ( "coinpaprika", ksp_offchain_transport_lib::MarketPriceSemantics::AggregatedMarket, ksp_offchain_transport_lib::MarketPriceProviderAuthMode::None, ), ("dexscreener", ksp_offchain_transport_lib::MarketPriceSemantics::DexPairUsd, ksp_offchain_transport_lib::MarketPriceProviderAuthMode::None), ("jupiter", ksp_offchain_transport_lib::MarketPriceSemantics::SolanaHeuristic, ksp_offchain_transport_lib::MarketPriceProviderAuthMode::None), ("kraken", ksp_offchain_transport_lib::MarketPriceSemantics::ExchangeLastTrade, ksp_offchain_transport_lib::MarketPriceProviderAuthMode::None), ]; for (entry, (provider_id, semantics, auth_mode)) in registry.entries().iter().zip(expected) { assert_eq!(entry.descriptor().id().as_str(), provider_id); assert_eq!(entry.descriptor().semantics(), semantics); assert_eq!(entry.descriptor().auth_mode(), auth_mode); assert!(entry.descriptor().supports_sol_usd()); assert_eq!(entry.state().availability(), ksp_offchain_transport_lib::MarketPriceProviderAvailability::Disabled); } return std::result::Result::Ok(()); } #[test] fn pre_010_evolutive_public_enums_are_non_exhaustive() -> std::io::Result<()> { let root = crate_root(); let provider = match std::fs::read_to_string(root.join("src/market_price_provider.rs")) { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; for enum_name in [ "MarketPricePair", "MarketPriceSemantics", "MarketPriceProviderAuthMode", "MarketPriceProviderRateLimitScope", "MarketPriceProviderRateLimitKind", "MarketPriceProviderQuotaPeriod", "MarketPriceProviderQuotaUnit", "MarketPriceProviderAvailability", ] { assert_non_exhaustive(provider.as_str(), enum_name); } let coingecko = match std::fs::read_to_string(root.join("src/market_price_coingecko.rs")) { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; assert_non_exhaustive(coingecko.as_str(), "MarketPriceCoinGeckoAccessMode"); let coinmarketcap = match std::fs::read_to_string(root.join("src/market_price_coinmarketcap.rs")) { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; assert_non_exhaustive(coinmarketcap.as_str(), "MarketPriceCoinMarketCapAccessMode"); let jupiter = match std::fs::read_to_string(root.join("src/market_price_jupiter.rs")) { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; assert_non_exhaustive(jupiter.as_str(), "MarketPriceJupiterAccessMode"); let service = match std::fs::read_to_string(root.join("src/market_price_service.rs")) { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; assert_non_exhaustive(service.as_str(), "MarketPriceProviderSetup"); return std::result::Result::Ok(()); } fn all_disabled_setups() -> ksp_core_lib::Result> { let birdeye = match ksp_offchain_transport_lib::MarketPriceBirdeyeSettings::new(false, std::option::Option::None) { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; let coinbase = match ksp_offchain_transport_lib::MarketPriceCoinbaseExchangeSettings::new(false) { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; let coingecko = match ksp_offchain_transport_lib::MarketPriceCoinGeckoSettings::keyless(false) { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; let coinmarketcap = match ksp_offchain_transport_lib::MarketPriceCoinMarketCapSettings::keyless(false) { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; let coinpaprika = match ksp_offchain_transport_lib::MarketPriceCoinPaprikaSettings::new(false) { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; let dexscreener = match ksp_offchain_transport_lib::MarketPriceDexScreenerSettings::new(false, std::option::Option::None) { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; let jupiter = match ksp_offchain_transport_lib::MarketPriceJupiterSettings::keyless(false) { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; let kraken = match ksp_offchain_transport_lib::MarketPriceKrakenSettings::new(false) { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; return std::result::Result::Ok(std::vec![ ksp_offchain_transport_lib::MarketPriceProviderSetup::Birdeye(birdeye), ksp_offchain_transport_lib::MarketPriceProviderSetup::CoinbaseExchange(coinbase), ksp_offchain_transport_lib::MarketPriceProviderSetup::CoinGecko(coingecko), ksp_offchain_transport_lib::MarketPriceProviderSetup::CoinMarketCap(coinmarketcap), ksp_offchain_transport_lib::MarketPriceProviderSetup::CoinPaprika(coinpaprika), ksp_offchain_transport_lib::MarketPriceProviderSetup::DexScreener(dexscreener), ksp_offchain_transport_lib::MarketPriceProviderSetup::Jupiter(jupiter), ksp_offchain_transport_lib::MarketPriceProviderSetup::Kraken(kraken), ]); } fn assert_non_exhaustive(source: &str, enum_name: &str) { let marker = std::format!("pub enum {enum_name}"); let position = source.find(marker.as_str()); assert!(position.is_some(), "public enum must remain present: {enum_name}"); if let std::option::Option::Some(position) = position { let start = position.saturating_sub(256); assert!(source[start..position].contains("#[non_exhaustive]"), "evolutive public enum must be non_exhaustive: {enum_name}"); } } fn crate_root() -> std::path::PathBuf { return std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")); }