**Progress: 1,178 → 57 test errors (95% reduction)** ## Status Summary - ✅ Production code: Compiles cleanly (0 errors) - ⚠️ Test code: 57 errors remain (massive improvement) - ⚙️ All services build successfully - 📊 Warning count: 253 (target: <20) - AGENTS WILL FIX ## Remaining Test Errors (57 total) ### Primary Issues: 1. 23× E0308 mismatched types 2. 17× E0433 undeclared Decimal 3. 15× E0433 compliance module not found 4. 6× E0624 private method access 5. Various import and type issues ## Next Phase: Wave 33-2 Launch 10+ parallel agents to: - Fix remaining 57 test compilation errors - Reduce 253 warnings to <20 - Achieve 95% test coverage - Ensure all tests pass 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
182 lines
4.8 KiB
Rust
182 lines
4.8 KiB
Rust
//! Test utilities for trading service tests
|
|
//!
|
|
//! Provides configurable test data fixtures and environment variable support
|
|
//! to avoid hardcoded production symbols in tests.
|
|
|
|
use std::env;
|
|
|
|
/// Default test symbols to use when environment variables are not set
|
|
pub const DEFAULT_TEST_SYMBOLS: &[&str] = &[
|
|
"TEST_EQUITY_001",
|
|
"TEST_EQUITY_002",
|
|
"TEST_EQUITY_003",
|
|
"TEST_EQUITY_004",
|
|
"TEST_EQUITY_005",
|
|
];
|
|
|
|
/// Test configuration for symbols and other test data
|
|
#[derive(Debug, Clone)]
|
|
pub struct TestConfig {
|
|
pub symbols: Vec<String>,
|
|
pub default_account: String,
|
|
pub default_strategy: String,
|
|
}
|
|
|
|
impl Default for TestConfig {
|
|
fn default() -> Self {
|
|
Self {
|
|
symbols: DEFAULT_TEST_SYMBOLS.iter().map(|s| s.to_string()).collect(),
|
|
default_account: "test_account".to_string(),
|
|
default_strategy: "test_strategy".to_string(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl TestConfig {
|
|
/// Create a new test configuration with environment variable overrides
|
|
pub fn new() -> Self {
|
|
let mut config = Self::default();
|
|
|
|
// Override symbols from environment if provided
|
|
if let Ok(symbols_env) = env::var("FOXHUNT_TEST_SYMBOLS") {
|
|
config.symbols = symbols_env
|
|
.split(',')
|
|
.map(|s| s.trim().to_string())
|
|
.filter(|s| !s.is_empty())
|
|
.collect();
|
|
}
|
|
|
|
// Override account from environment if provided
|
|
if let Ok(account_env) = env::var("FOXHUNT_TEST_ACCOUNT") {
|
|
config.default_account = account_env;
|
|
}
|
|
|
|
// Override strategy from environment if provided
|
|
if let Ok(strategy_env) = env::var("FOXHUNT_TEST_STRATEGY") {
|
|
config.default_strategy = strategy_env;
|
|
}
|
|
|
|
config
|
|
}
|
|
|
|
/// Get primary test symbol
|
|
pub fn primary_symbol(&self) -> &str {
|
|
&self.symbols[0]
|
|
}
|
|
|
|
/// Get secondary test symbol
|
|
pub fn secondary_symbol(&self) -> &str {
|
|
&self.symbols[1]
|
|
}
|
|
|
|
/// Get tertiary test symbol
|
|
pub fn tertiary_symbol(&self) -> &str {
|
|
&self.symbols[2]
|
|
}
|
|
|
|
/// Get all test symbols
|
|
pub fn all_symbols(&self) -> &[String] {
|
|
&self.symbols
|
|
}
|
|
|
|
/// Get a subset of symbols for testing
|
|
pub fn symbol_subset(&self, count: usize) -> Vec<String> {
|
|
self.symbols.iter().take(count).cloned().collect()
|
|
}
|
|
}
|
|
|
|
/// Test fixtures for consistent test data
|
|
pub struct TestFixtures {
|
|
pub config: TestConfig,
|
|
}
|
|
|
|
impl Default for TestFixtures {
|
|
fn default() -> Self {
|
|
Self::new()
|
|
}
|
|
}
|
|
|
|
impl TestFixtures {
|
|
/// Create new test fixtures
|
|
pub fn new() -> Self {
|
|
Self {
|
|
config: TestConfig::new(),
|
|
}
|
|
}
|
|
|
|
/// Create a test order ID
|
|
pub fn test_order_id(&self, suffix: &str) -> String {
|
|
format!("test_order_{}", suffix)
|
|
}
|
|
|
|
/// Create test prices for a given symbol
|
|
pub fn test_prices(&self, symbol: &str) -> (f64, f64) {
|
|
// Generate deterministic but varied prices based on symbol hash
|
|
let hash = symbol.chars().map(|c| c as u32).sum::<u32>();
|
|
let base_price = 100.0 + (hash % 100) as f64;
|
|
(base_price, base_price + 5.0)
|
|
}
|
|
|
|
/// Create test quantities
|
|
pub fn test_quantities(&self) -> (f64, f64) {
|
|
(100.0, 50.0)
|
|
}
|
|
}
|
|
|
|
/// Macro to get test config for consistent usage across tests
|
|
#[macro_export]
|
|
macro_rules! test_config {
|
|
() => {
|
|
$crate::test_utils::TestConfig::new()
|
|
};
|
|
}
|
|
|
|
/// Macro to get test fixtures for consistent usage across tests
|
|
#[macro_export]
|
|
macro_rules! test_fixtures {
|
|
() => {
|
|
$crate::test_utils::TestFixtures::new()
|
|
};
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_config_creation() {
|
|
let config = TestConfig::new();
|
|
assert!(!config.symbols.is_empty());
|
|
assert!(!config.default_account.is_empty());
|
|
assert!(!config.default_strategy.is_empty());
|
|
}
|
|
|
|
#[test]
|
|
fn test_symbol_access() {
|
|
let config = TestConfig::new();
|
|
assert_eq!(config.primary_symbol(), config.symbols[0]);
|
|
assert_eq!(config.secondary_symbol(), config.symbols[1]);
|
|
assert_eq!(config.tertiary_symbol(), config.symbols[2]);
|
|
}
|
|
|
|
#[test]
|
|
fn test_fixtures_creation() {
|
|
let fixtures = TestFixtures::new();
|
|
let order_id = fixtures.test_order_id("123");
|
|
assert!(order_id.contains("test_order_123"));
|
|
|
|
let (price1, price2) = fixtures.test_prices("TEST_SYMBOL");
|
|
assert!(price1 > 0.0);
|
|
assert!(price2 > price1);
|
|
}
|
|
|
|
#[test]
|
|
fn test_symbol_subset() {
|
|
let config = TestConfig::new();
|
|
let subset = config.symbol_subset(2);
|
|
assert_eq!(subset.len(), 2);
|
|
assert_eq!(subset[0], config.symbols[0]);
|
|
assert_eq!(subset[1], config.symbols[1]);
|
|
}
|
|
}
|