use mockforge_core::generate_config::{BarrelType, OutputConfig};
use mockforge_core::output_control::{
apply_banner, apply_extension, apply_file_naming_template, build_file_naming_context,
process_generated_file, BarrelGenerator, GeneratedFile,
};
use mockforge_openapi::OpenApiSpec;
use std::collections::HashMap;
use std::path::{Path, PathBuf};
#[test]
fn test_clean_option_in_config() {
let config = OutputConfig {
clean: true,
..Default::default()
};
assert!(config.clean);
}
#[test]
fn test_barrel_type_defaults_to_none() {
let config = OutputConfig::default();
assert_eq!(config.barrel_type, BarrelType::None);
}
#[test]
fn test_barrel_type_index() {
let config = OutputConfig {
barrel_type: BarrelType::Index,
..Default::default()
};
assert_eq!(config.barrel_type, BarrelType::Index);
}
#[test]
fn test_extension_override() {
let config = OutputConfig {
extension: Some("ts".to_string()),
..Default::default()
};
assert_eq!(config.extension, Some("ts".to_string()));
}
#[test]
fn test_banner_template() {
let config = OutputConfig {
banner: Some("Generated by {{generator}}\nSource: {{source}}".to_string()),
..Default::default()
};
assert!(config.banner.is_some());
}
#[test]
fn test_file_naming_template() {
let config = OutputConfig {
file_naming_template: Some("{{name}}_{{tag}}".to_string()),
..Default::default()
};
assert!(config.file_naming_template.is_some());
}
#[test]
fn test_apply_banner_with_placeholders() {
let content = "export const test = 1;";
let banner = "Generated by {{generator}}\nSource: {{source}}\nTimestamp: {{timestamp}}";
let source = Some(Path::new("api.yaml"));
let result = apply_banner(content, banner, source);
assert!(result.contains("MockForge"));
assert!(result.contains("api.yaml"));
assert!(result.contains("export const test"));
assert!(result.contains("//")); }
#[test]
fn test_apply_banner_without_source() {
let content = "export const test = 1;";
let banner = "Generated by {{generator}}";
let result = apply_banner(content, banner, None);
assert!(result.contains("MockForge"));
assert!(result.contains("export const test"));
}
#[test]
fn test_apply_extension() {
let path = Path::new("output/file.js");
let new_path = apply_extension(path, Some("ts"));
assert_eq!(new_path, PathBuf::from("output/file.ts"));
}
#[test]
fn test_apply_extension_none() {
let path = Path::new("output/file.js");
let new_path = apply_extension(path, None);
assert_eq!(new_path, path);
}
#[test]
fn test_apply_file_naming_template() {
let template = "{{name}}_{{tag}}";
let mut context = HashMap::new();
context.insert("name", "user");
context.insert("tag", "api");
let result = apply_file_naming_template(template, &context);
assert_eq!(result, "user_api");
}
#[test]
fn test_apply_file_naming_template_missing_placeholder() {
let template = "{{name}}_{{tag}}";
let mut context = HashMap::new();
context.insert("name", "user");
let result = apply_file_naming_template(template, &context);
assert_eq!(result, "user_{{tag}}"); }
#[test]
fn test_process_generated_file_with_extension() {
let file = GeneratedFile {
path: PathBuf::from("output.rs"),
content: "pub struct Test {};".to_string(),
extension: "rs".to_string(),
exportable: false,
};
let config = OutputConfig {
extension: Some("ts".to_string()),
..Default::default()
};
let processed = process_generated_file(file, &config, None, None);
assert_eq!(processed.extension, "ts");
}
#[test]
fn test_process_generated_file_with_banner() {
let file = GeneratedFile {
path: PathBuf::from("output.ts"),
content: "export const test = 1;".to_string(),
extension: "ts".to_string(),
exportable: true,
};
let config = OutputConfig {
banner: Some("Generated by {{generator}}".to_string()),
..Default::default()
};
let processed = process_generated_file(file, &config, Some(Path::new("api.yaml")), None);
assert!(processed.content.contains("MockForge"));
assert!(processed.content.contains("export const test"));
}
#[test]
fn test_generate_index_file() {
let output_dir = Path::new("/tmp/test");
let files = vec![
GeneratedFile {
path: PathBuf::from("types.ts"),
content: "export type User = {};".to_string(),
extension: "ts".to_string(),
exportable: true,
},
GeneratedFile {
path: PathBuf::from("client.ts"),
content: "export const client = {};".to_string(),
extension: "ts".to_string(),
exportable: true,
},
GeneratedFile {
path: PathBuf::from("README.md"),
content: "# Documentation".to_string(),
extension: "md".to_string(),
exportable: false, },
];
let result =
BarrelGenerator::generate_barrel_files(output_dir, &files, BarrelType::Index).unwrap();
assert_eq!(result.len(), 1);
assert!(result[0].0.ends_with("index.ts"));
assert!(result[0].1.contains("export * from './types'"));
assert!(result[0].1.contains("export * from './client'"));
assert!(!result[0].1.contains("README")); }
#[test]
fn test_generate_index_file_empty() {
let output_dir = Path::new("/tmp/test");
let files: Vec<GeneratedFile> = vec![];
let result =
BarrelGenerator::generate_barrel_files(output_dir, &files, BarrelType::Index).unwrap();
assert_eq!(result.len(), 1);
assert!(result[0].1.contains("No exportable files found"));
}
#[test]
fn test_generate_barrel_files_none() {
let output_dir = Path::new("/tmp/test");
let files = vec![GeneratedFile {
path: PathBuf::from("test.ts"),
content: "export const test = 1;".to_string(),
extension: "ts".to_string(),
exportable: true,
}];
let result =
BarrelGenerator::generate_barrel_files(output_dir, &files, BarrelType::None).unwrap();
assert_eq!(result.len(), 0);
}
#[test]
fn test_generate_barrel_files_index() {
let output_dir = Path::new("/tmp/test");
let files = vec![
GeneratedFile {
path: PathBuf::from("types.ts"),
content: "export type User = {};".to_string(),
extension: "ts".to_string(),
exportable: true,
},
GeneratedFile {
path: PathBuf::from("client.ts"),
content: "export const client = {};".to_string(),
extension: "ts".to_string(),
exportable: true,
},
];
let result =
BarrelGenerator::generate_barrel_files(output_dir, &files, BarrelType::Index).unwrap();
assert_eq!(result.len(), 1);
assert!(result[0].0.ends_with("index.ts"));
}
#[test]
fn test_generate_barrel_files_barrel() {
let output_dir = Path::new("/tmp/test");
let files = vec![
GeneratedFile {
path: PathBuf::from("api/types.ts"),
content: "export type User = {};".to_string(),
extension: "ts".to_string(),
exportable: true,
},
GeneratedFile {
path: PathBuf::from("api/client.ts"),
content: "export const client = {};".to_string(),
extension: "ts".to_string(),
exportable: true,
},
GeneratedFile {
path: PathBuf::from("utils/helpers.ts"),
content: "export const helper = {};".to_string(),
extension: "ts".to_string(),
exportable: true,
},
];
let result =
BarrelGenerator::generate_barrel_files(output_dir, &files, BarrelType::Barrel).unwrap();
assert!(result.len() >= 2);
let api_barrel = result
.iter()
.find(|(path, _)| path.to_string_lossy().contains("api/index.ts"))
.expect("Should have api/index.ts");
assert!(api_barrel.1.contains("export * from './types'"));
assert!(api_barrel.1.contains("export * from './client'"));
assert!(!api_barrel.1.contains("./api/types")); }
#[test]
fn test_process_generated_file_with_naming_template() {
let file = GeneratedFile {
path: PathBuf::from("user.ts"),
content: "export const user = {};".to_string(),
extension: "ts".to_string(),
exportable: true,
};
let config = OutputConfig {
file_naming_template: Some("{{name}}_{{tag}}".to_string()),
..Default::default()
};
let processed = process_generated_file(file, &config, None, None);
assert!(processed.path.to_string_lossy().contains("user_api"));
}
#[test]
fn test_build_file_naming_context() {
let openapi_spec = r#"
openapi: 3.0.0
info:
title: Test API
version: 1.0.0
paths:
/users:
get:
operationId: getUsers
tags:
- users
summary: Get all users
responses:
'200':
description: Success
/users/{id}:
get:
operationId: getUserById
tags:
- users
summary: Get user by ID
responses:
'200':
description: Success
components:
schemas:
User:
type: object
"#;
let spec = OpenApiSpec::from_string(openapi_spec, Some("yaml")).unwrap();
let context = build_file_naming_context(&spec);
let user_context = context.get_context_for_name("getUsers");
assert_eq!(user_context.get("tag"), Some(&"users"));
assert_eq!(user_context.get("operation"), Some(&"get"));
let schema_context = context.get_context_for_name("User");
assert_eq!(schema_context.get("tag"), Some(&"schemas"));
}
#[test]
fn test_process_generated_file_with_openapi_context() {
let openapi_spec = r#"
openapi: 3.0.0
info:
title: Test API
version: 1.0.0
paths:
/users:
get:
operationId: getUsers
tags:
- users
responses:
'200':
description: Success
"#;
let spec = OpenApiSpec::from_string(openapi_spec, Some("yaml")).unwrap();
let naming_context = build_file_naming_context(&spec);
let file = GeneratedFile {
path: PathBuf::from("getUsers.ts"),
content: "export const getUsers = () => {};".to_string(),
extension: "ts".to_string(),
exportable: true,
};
let config = OutputConfig {
file_naming_template: Some("{{tag}}_{{name}}".to_string()),
..Default::default()
};
let processed = process_generated_file(file, &config, None, Some(&naming_context));
assert!(processed.path.to_string_lossy().contains("users_getUsers"));
}