use pvlib::shading::*;
#[test]
fn test_ground_angle_zero_height() {
let psi = ground_angle(30.0, 0.5, 0.0);
assert!((psi - 0.0).abs() < 1e-6, "Ground angle at slant_height=0 should be 0, got {}", psi);
}
#[test]
fn test_ground_angle_increases_with_height() {
let psi_low = ground_angle(30.0, 0.5, 0.2);
let psi_high = ground_angle(30.0, 0.5, 0.8);
assert!(psi_high > psi_low, "Ground angle should increase with slant height");
}
#[test]
fn test_ground_angle_increases_with_gcr() {
let psi_low = ground_angle(30.0, 0.3, 0.5);
let psi_high = ground_angle(30.0, 0.7, 0.5);
assert!(psi_high > psi_low, "Ground angle should increase with GCR");
}
#[test]
fn test_masking_angle_bottom() {
let ma_bottom = masking_angle(30.0, 0.5, 0.0);
let ma_top = masking_angle(30.0, 0.5, 0.9);
assert!(ma_bottom > ma_top, "Masking angle should be larger at bottom of row");
}
#[test]
fn test_masking_angle_top() {
let ma = masking_angle(30.0, 0.5, 1.0);
assert!((ma - 0.0).abs() < 1e-6, "Masking angle at top of row should be 0, got {}", ma);
}
#[test]
fn test_masking_angle_zero_gcr() {
let ma = masking_angle(30.0, 0.0, 0.0);
assert_eq!(ma, 0.0, "Masking angle with zero GCR should be 0");
}
#[test]
fn test_masking_angle_passias_zero_tilt() {
let ma = masking_angle_passias(0.0, 0.5);
assert!((ma - 0.0).abs() < 0.01, "Passias masking angle at tilt=0 should be ~0, got {}", ma);
}
#[test]
fn test_masking_angle_passias_positive() {
let ma = masking_angle_passias(30.0, 0.5);
assert!(ma > 0.0, "Passias masking angle should be positive for tilted rows, got {}", ma);
}
#[test]
fn test_masking_angle_passias_increases_with_gcr() {
let ma_low = masking_angle_passias(30.0, 0.3);
let ma_high = masking_angle_passias(30.0, 0.7);
assert!(ma_high > ma_low, "Passias masking angle should increase with GCR");
}
#[test]
fn test_psza_sun_overhead() {
let psza = projected_solar_zenith_angle(0.0, 180.0, 0.0, 180.0);
assert!((psza - 0.0).abs() < 1e-6, "PSZA should be 0 when sun is overhead, got {}", psza);
}
#[test]
fn test_psza_sun_along_axis() {
let psza = projected_solar_zenith_angle(30.0, 180.0, 0.0, 180.0);
assert!(psza.abs() < 1.0, "PSZA should be near 0 when sun is along axis, got {}", psza);
}
#[test]
fn test_psza_sun_perpendicular_to_axis() {
let psza = projected_solar_zenith_angle(30.0, 90.0, 0.0, 180.0);
assert!(psza.abs() > 10.0, "PSZA should be significant when sun is perpendicular to axis, got {}", psza);
}
#[test]
fn test_shaded_fraction_no_shade() {
let sf = shaded_fraction1d(10.0, 180.0, 90.0, 30.0, 2.0, 10.0, 0.0, 0.0, 0.0);
assert!((sf - 0.0).abs() < 0.1, "Should have minimal shading with wide pitch, got {}", sf);
}
#[test]
fn test_shaded_fraction_clamped() {
let sf = shaded_fraction1d(80.0, 135.0, 90.0, 30.0, 2.0, 3.0, 0.0, 0.0, 0.0);
assert!((0.0..=1.0).contains(&sf), "Shaded fraction should be in [0,1], got {}", sf);
}
#[test]
fn test_shaded_fraction_reference_value() {
let sf = shaded_fraction1d(80.0, 135.0, 90.0, 30.0, 2.0, 3.0, 0.0, 0.05, 0.0);
assert!((sf - 0.4776).abs() < 0.01,
"Should match Python reference ~0.4776, got {}", sf);
}
#[test]
fn test_sky_diffuse_passias_zero_angle() {
let loss = sky_diffuse_passias(0.0);
assert!((loss - 0.0).abs() < 1e-6, "No masking angle should mean no loss, got {}", loss);
}
#[test]
fn test_sky_diffuse_passias_increases_with_angle() {
let loss_10 = sky_diffuse_passias(10.0);
let loss_30 = sky_diffuse_passias(30.0);
assert!(loss_30 > loss_10, "Larger masking angle should mean more loss");
}
#[test]
fn test_sky_diffuse_pass_zero_angle() {
let pass = sky_diffuse_pass_equation(0.0);
assert!((pass - 1.0).abs() < 1e-6, "No masking should pass all sky diffuse");
}