use cfgmatic_source::prelude::*;
use serde::Deserialize;
use std::io::Write;
use tempfile::NamedTempFile;
#[derive(Debug, Clone, Deserialize, PartialEq)]
struct AppConfig {
name: String,
version: String,
database: DatabaseConfig,
}
#[derive(Debug, Clone, Deserialize, PartialEq)]
struct DatabaseConfig {
host: String,
port: u16,
}
fn create_config_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");
file
}
#[test]
fn test_workflow_load_config_from_file() {
let toml_content = r#"
name = "my-app"
version = "1.0.0"
[database]
host = "localhost"
port = 5432
"#;
let file = create_config_file(toml_content, ".toml");
let source = FileSource::new(file.path());
let raw = source.load_raw().expect("Failed to load");
let content = raw.as_str().expect("Failed to get string");
let format = source.detect_format().unwrap_or(Format::Toml);
let config: AppConfig = format.parse_as(content.as_ref()).expect("Failed to parse");
assert_eq!(config.name, "my-app");
assert_eq!(config.version, "1.0.0");
assert_eq!(config.database.host, "localhost");
assert_eq!(config.database.port, 5432);
}
#[test]
fn test_workflow_composite_source() {
let base_config = r#"{"name": "base-app", "version": "0.1.0", "database": {"host": "localhost", "port": 5432}}"#;
let file = create_config_file(base_config, ".json");
let override_config = serde_json::json!({"name": "override-app"});
let memory_source = MemorySource::from_json(override_config);
let file_source = FileSource::new(file.path());
let composite = CompositeSource::builder()
.add_with_priority(memory_source, SourcePriority::HIGH)
.add_with_priority(file_source, SourcePriority::LOWEST)
.build();
let raw = composite.load_raw().expect("Failed to load composite");
let content = raw.as_str().expect("Failed to get string");
assert!(!content.is_empty());
}
#[test]
fn test_workflow_memory_source_full_config() {
let json_content = r#"{
"name": "test-app",
"version": "2.0.0",
"database": {
"host": "db.example.com",
"port": 3306
}
}"#;
let value: serde_json::Value = serde_json::from_str(json_content).expect("Invalid JSON");
let source = MemorySource::from_json(value);
let raw = source.load_raw().expect("Failed to load");
let content = raw.as_str().expect("Failed to get string");
let config: AppConfig = Format::Json
.parse_as(content.as_ref())
.expect("Failed to parse");
assert_eq!(config.name, "test-app");
assert_eq!(config.version, "2.0.0");
assert_eq!(config.database.host, "db.example.com");
assert_eq!(config.database.port, 3306);
}
#[test]
fn test_workflow_chain_operations() {
let content = r#"{"name": "chain-test"}"#;
let value: serde_json::Value = serde_json::from_str(content).expect("Invalid JSON");
let source = MemorySource::from_json(value);
let raw = source.load_raw().expect("Failed to load");
let content = raw.as_str().expect("Failed to get string");
let result: serde_json::Value = Format::Json
.parse_as(content.as_ref())
.expect("Failed to parse");
assert_eq!(result["name"], "chain-test");
}
#[derive(Debug, Clone, Deserialize, PartialEq)]
struct SimpleConfig {
name: String,
}
#[test]
fn test_workflow_multiple_formats() {
let json_content = r#"{"name": "json-app"}"#;
let toml_value: serde_json::Value = serde_json::json!({"name": "toml-app"});
let json_value: serde_json::Value = serde_json::from_str(json_content).expect("Invalid JSON");
let toml_source = MemorySource::from_json(toml_value);
let json_source = MemorySource::from_json(json_value);
let toml_raw = toml_source.load_raw().expect("Failed to load TOML");
let json_raw = json_source.load_raw().expect("Failed to load JSON");
let toml_content = toml_raw.as_str().expect("Failed to get string");
let json_parsed = json_raw.as_str().expect("Failed to get string");
let toml_config: SimpleConfig = Format::Json
.parse_as(toml_content.as_ref())
.expect("Failed to parse TOML");
let json_config: SimpleConfig = Format::Json
.parse_as(json_parsed.as_ref())
.expect("Failed to parse JSON");
assert_eq!(toml_config.name, "toml-app");
assert_eq!(json_config.name, "json-app");
}