cfgmatic-source 5.0.1

Configuration sources (file, env, memory) for cfgmatic framework
Documentation
//! Tests for [`FileSource`].
//!
//! Test coverage:
//! - File loading
//! - Format detection
//! - Error handling
//! - Builder pattern

use cfgmatic_source::prelude::*;
use serde::Deserialize;
use std::io::Write;
use tempfile::NamedTempFile;

#[derive(Debug, Clone, Deserialize, PartialEq)]
struct TestConfig {
    name: String,
    value: i32,
}

fn create_temp_file(content: &str, extension: &str) -> NamedTempFile {
    let mut file = NamedTempFile::with_suffix(extension).expect("Failed to create temp file");
    file.write_all(content.as_bytes())
        .expect("Failed to write to temp file");
    file
}

#[test]
fn test_file_source_loads_toml_file() {
    // Arrange
    let content = r#"
name = "test"
value = 42
"#;
    let file = create_temp_file(content, ".toml");

    // Act
    let source = FileSource::new(file.path());
    let raw = source.load_raw().expect("Failed to load file");
    let raw_content = raw.as_str().expect("Failed to get string");
    let format = source.detect_format().expect("Failed to detect format");

    // Assert
    let config: TestConfig = format
        .parse_as(raw_content.as_ref())
        .expect("Failed to parse");
    assert_eq!(config.name, "test");
    assert_eq!(config.value, 42);
}

#[test]
fn test_file_source_loads_json_file() {
    // Arrange
    let content = r#"{"name": "test", "value": 42}"#;
    let file = create_temp_file(content, ".json");

    // Act
    let source = FileSource::new(file.path());
    let raw = source.load_raw().expect("Failed to load file");
    let raw_content = raw.as_str().expect("Failed to get string");
    let format = source.detect_format().expect("Failed to detect format");

    // Assert
    let config: TestConfig = format
        .parse_as(raw_content.as_ref())
        .expect("Failed to parse");
    assert_eq!(config.name, "test");
    assert_eq!(config.value, 42);
}

#[test]
fn test_file_source_returns_error_for_missing_file() {
    // Arrange
    let source = FileSource::new("/nonexistent/path/config.toml");

    // Act
    let result = source.load_raw();

    // Assert
    assert!(result.is_err());
}

#[test]
fn test_file_source_detects_format_from_extension() {
    // Arrange
    let content = r#"{"name": "test"}"#;
    let file = create_temp_file(content, ".json");

    // Act
    let source = FileSource::new(file.path());

    // Assert
    assert_eq!(source.detect_format(), Some(Format::Json));
}

#[test]
fn test_file_source_builder() {
    // Arrange
    let content = r#"name = "test""#;
    let file = create_temp_file(content, ".toml");

    // Act
    let source = FileSource::builder()
        .path(file.path())
        .build()
        .expect("Failed to build");

    // Assert
    let raw = source.load_raw().expect("Failed to load");
    let raw_content = raw.as_str().expect("Failed to get string");
    assert!(!raw_content.is_empty());
}

#[test]
fn test_file_source_metadata() {
    // Arrange
    let content = "name = \"test\"";
    let file = create_temp_file(content, ".toml");
    let source = FileSource::new(file.path());

    // Act
    let metadata = source.metadata();

    // Assert
    assert_eq!(source.kind(), SourceKind::File);
    assert!(metadata.path.is_some());
}