yfinance-rs 0.9.1

Ergonomic Rust client for Yahoo Finance, supporting historical prices, real-time streaming, options, fundamentals, and more.
Documentation
//! Test/recording helpers for persisting HTTP fixtures.
//! Compiled only when the `test-mode` feature is enabled.

use std::fs;
use std::io::{self, Write};
use std::path::{Path, PathBuf};

pub fn get_fixture_dir() -> PathBuf {
    std::env::var("YF_FIXDIR").map_or_else(
        |_| Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/fixtures"),
        PathBuf::from,
    )
}

pub fn record_fixture(
    endpoint: &str,
    symbol: &str,
    ext: &str,
    body: &str,
) -> Result<(), std::io::Error> {
    let dir = get_fixture_dir();
    if !dir.exists() {
        fs::create_dir_all(&dir)?;
    }
    let filename = format!("{endpoint}_{symbol}.{ext}");
    let path = dir.join(filename);

    let mut file = fs::File::create(&path)?;
    write_fixture_body(&mut file, ext, body)?;

    crate::core::logging::trace_debug!(path = %path.display(), "wrote test fixture");
    Ok(())
}

fn write_fixture_body<W: Write>(writer: &mut W, ext: &str, body: &str) -> io::Result<()> {
    if ext.eq_ignore_ascii_case("json")
        && let Ok(value) = serde_json::from_str::<serde_json::Value>(body)
    {
        serde_json::to_writer_pretty(&mut *writer, &value).map_err(io::Error::other)?;
        writer.write_all(b"\n")?;
        return Ok(());
    }

    writer.write_all(body.as_bytes())
}

#[cfg(test)]
mod tests {
    use super::write_fixture_body;

    fn fixture_body(ext: &str, body: &str) -> String {
        let mut bytes = Vec::new();
        write_fixture_body(&mut bytes, ext, body).unwrap();
        String::from_utf8(bytes).unwrap()
    }

    #[test]
    fn fixture_body_prettifies_valid_json() {
        assert_eq!(
            fixture_body("json", r#"{"a":1,"b":[true]}"#),
            "{\n  \"a\": 1,\n  \"b\": [\n    true\n  ]\n}\n"
        );
    }

    #[test]
    fn fixture_body_leaves_invalid_json_raw() {
        assert_eq!(
            fixture_body("json", "<html>oops</html>"),
            "<html>oops</html>"
        );
    }

    #[test]
    fn fixture_body_leaves_non_json_raw() {
        assert_eq!(fixture_body("b64", "abc123"), "abc123");
    }
}