open-standards/eoc/eoc-rs/crates/eoc-carbon/tests/demand_shift.rs
Transaction Science 781c331288 ingest batch 5 (salvage): 2 crates from 9-agent dispatch (session-limit hit mid-batch)
OpenPay (1 crate)
  op-revrec      ASC 606 / IFRS 15 revenue recognition (5-step model,
                 multi-element allocation, deferred revenue ledger,
                 variable consideration with constraint, principal vs agent,
                 contract modifications, multi-currency translation)
                 27 tests across 6 FASB worked examples + SaaS lifecycle.

EOC (1 crate)
  eoc-carbon     Carbon intensity → joules → gCO2e accounting.
                 Electricity Maps, WattTime, CO2 Signal adapters; IEA
                 baseline fallback; PUE tables (AWS/GCP/Azure); region-aware
                 scheduling + demand shifting; SCI-for-AI bridge into eoc-eval.
                 21 tests passing.

Seven other crates (op-dispute-evidence, op-ewallets-asia, smart-byte-zk,
smart-byte-atproto, smart-byte-edv, eoc-agent, eoc-rag) were scoped in this
batch but the parallel agents hit session-limit before completing. They are
deferred to a follow-up batch.

Co-Authored-By: Claude Opus 4.7 <[email protected]>
2026-05-24 09:28:38 -04:00

33 lines
1.2 KiB
Rust

//! Queue background work for the lowest-intensity window inside a 12h horizon.
use chrono::{Duration, Utc};
use eoc_carbon::intensity::ForecastPoint;
use eoc_carbon::scheduler::DemandShifter;
#[test]
fn shifts_to_greenest_window_in_next_12h() {
let now = Utc::now();
// 12 hourly points; minimum at hour 8.
let curve: Vec<ForecastPoint> = (1..=12)
.map(|h| ForecastPoint {
at: now + Duration::hours(h),
g_co2e_per_kwh: if h == 8 { 90.0 } else { 300.0 + (h as f64) * 5.0 },
})
.collect();
let d = DemandShifter::new(Duration::hours(12));
let decision = d.pick_window(&curve, now).expect("ok");
assert_eq!(decision.g_co2e_per_kwh, 90.0);
assert_eq!(decision.at, now + Duration::hours(8));
}
#[test]
fn ignores_points_outside_horizon() {
let now = Utc::now();
let curve = vec![
ForecastPoint { at: now + Duration::hours(2), g_co2e_per_kwh: 400.0 },
ForecastPoint { at: now + Duration::hours(20), g_co2e_per_kwh: 50.0 }, // outside 12h
];
let d = DemandShifter::new(Duration::hours(12));
let decision = d.pick_window(&curve, now).expect("ok");
assert_eq!(decision.g_co2e_per_kwh, 400.0);
}