#![allow(clippy::unwrap_used)]
use std::{
fs,
path::{Path, PathBuf},
};
use tempfile::TempDir;
fn compile_schema(toml_path: &Path) -> Result<String, String> {
let cli_path = env!("CARGO_BIN_EXE_fraiseql-cli");
let output = std::process::Command::new(cli_path)
.arg("compile")
.arg(toml_path)
.current_dir(toml_path.parent().unwrap())
.output()
.map_err(|e| format!("Failed to run fraiseql-cli: {}", e))?;
if !output.status.success() {
let stderr = String::from_utf8_lossy(&output.stderr);
return Err(format!("Compilation failed: {}", stderr));
}
Ok(String::from_utf8_lossy(&output.stdout).to_string())
}
#[test]
fn test_ecommerce_example_compiles() {
let ecommerce_path = PathBuf::from("examples/ecommerce/fraiseql.toml");
if !ecommerce_path.exists() {
println!("Skipping test - examples not found");
return;
}
let output = compile_schema(&ecommerce_path).expect("Failed to compile ecommerce example");
assert!(output.contains("Schema compiled successfully"), "Expected success message");
assert!(output.contains("Types: 8"), "Expected 8 types");
assert!(output.contains("Queries: 12"), "Expected 12 queries");
assert!(output.contains("Mutations: 8"), "Expected 8 mutations");
}
#[test]
fn test_saas_example_compiles() {
let saas_path = PathBuf::from("examples/saas/fraiseql.toml");
if !saas_path.exists() {
println!("Skipping test - examples not found");
return;
}
let output = compile_schema(&saas_path).expect("Failed to compile saas example");
assert!(output.contains("Schema compiled successfully"), "Expected success message");
assert!(output.contains("Types: 8"), "Expected 8 types");
assert!(output.contains("Queries: 11"), "Expected 11 queries");
assert!(output.contains("Mutations: 8"), "Expected 8 mutations");
}
#[test]
fn test_multitenant_example_compiles() {
let multitenant_path = PathBuf::from("examples/multitenant/fraiseql.toml");
if !multitenant_path.exists() {
println!("Skipping test - examples not found");
return;
}
let output = compile_schema(&multitenant_path).expect("Failed to compile multitenant example");
assert!(output.contains("Schema compiled successfully"), "Expected success message");
assert!(output.contains("Types: 3"), "Expected 3 types");
assert!(output.contains("Queries: 3"), "Expected 3 queries");
assert!(output.contains("Mutations: 2"), "Expected 2 mutations");
}
#[test]
fn test_domain_discovery_simple() {
let temp_dir = TempDir::new().expect("Failed to create temp dir");
let temp_path = temp_dir.path();
fs::create_dir(temp_path.join("schema")).expect("Failed to create schema dir");
fs::create_dir(temp_path.join("schema/users")).expect("Failed to create users domain");
let types_json = r#"{
"types": [
{
"name": "User",
"fields": [
{"name": "id", "type": "ID", "nullable": false},
{"name": "name", "type": "String", "nullable": false}
],
"description": "User type"
}
],
"queries": [
{
"name": "getUser",
"return_type": "User",
"return_array": false,
"description": "Get user by ID"
}
],
"mutations": []
}"#;
fs::write(temp_path.join("schema/users/types.json"), types_json)
.expect("Failed to write types.json");
let toml_content = r#"[schema]
name = "test"
version = "1.0.0"
database_target = "postgresql"
[database]
url = "postgresql://localhost/test"
pool_max = 20
ssl_mode = "prefer"
connect_timeout_ms = 5000
[domain_discovery]
enabled = true
root_dir = "schema"
"#;
fs::write(temp_path.join("fraiseql.toml"), toml_content).expect("Failed to write TOML");
let output = compile_schema(&temp_path.join("fraiseql.toml"))
.expect("Failed to compile simple domain schema");
assert!(output.contains("Schema compiled successfully"), "Expected success");
assert!(output.contains("Types: 1"), "Expected 1 type");
assert!(output.contains("Queries: 1"), "Expected 1 query");
}
#[test]
fn test_domain_discovery_multiple_domains() {
let temp_dir = TempDir::new().expect("Failed to create temp dir");
let temp_path = temp_dir.path();
fs::create_dir(temp_path.join("schema")).expect("Failed to create schema dir");
fs::create_dir(temp_path.join("schema/users")).expect("Failed to create users domain");
fs::create_dir(temp_path.join("schema/posts")).expect("Failed to create posts domain");
let users_json = r#"{
"types": [
{
"name": "User",
"fields": [
{"name": "id", "type": "ID", "nullable": false},
{"name": "name", "type": "String", "nullable": false}
],
"description": "User type"
}
],
"queries": [
{
"name": "getUser",
"return_type": "User",
"return_array": false
}
],
"mutations": []
}"#;
fs::write(temp_path.join("schema/users/types.json"), users_json)
.expect("Failed to write users types.json");
let posts_json = r#"{
"types": [
{
"name": "Post",
"fields": [
{"name": "id", "type": "ID", "nullable": false},
{"name": "title", "type": "String", "nullable": false},
{"name": "userId", "type": "ID", "nullable": false}
],
"description": "Blog post"
}
],
"queries": [
{
"name": "getPost",
"return_type": "Post",
"return_array": false
},
{
"name": "listPosts",
"return_type": "Post",
"return_array": true
}
],
"mutations": []
}"#;
fs::write(temp_path.join("schema/posts/types.json"), posts_json)
.expect("Failed to write posts types.json");
let toml_content = r#"[schema]
name = "test"
version = "1.0.0"
database_target = "postgresql"
[database]
url = "postgresql://localhost/test"
pool_max = 20
ssl_mode = "prefer"
connect_timeout_ms = 5000
[domain_discovery]
enabled = true
root_dir = "schema"
"#;
fs::write(temp_path.join("fraiseql.toml"), toml_content).expect("Failed to write TOML");
let output = compile_schema(&temp_path.join("fraiseql.toml"))
.expect("Failed to compile multi-domain schema");
assert!(output.contains("Schema compiled successfully"), "Expected success");
assert!(output.contains("Types: 2"), "Expected 2 types (User, Post)");
assert!(output.contains("Queries: 3"), "Expected 3 queries");
}
#[test]
fn test_cross_domain_references() {
let temp_dir = TempDir::new().expect("Failed to create temp dir");
let temp_path = temp_dir.path();
fs::create_dir(temp_path.join("schema")).expect("Failed to create schema dir");
fs::create_dir(temp_path.join("schema/users")).expect("Failed to create users domain");
fs::create_dir(temp_path.join("schema/posts")).expect("Failed to create posts domain");
let users_json = r#"{
"types": [
{
"name": "User",
"fields": [
{"name": "id", "type": "ID", "nullable": false},
{"name": "email", "type": "String", "nullable": false}
]
}
],
"queries": [],
"mutations": []
}"#;
fs::write(temp_path.join("schema/users/types.json"), users_json)
.expect("Failed to write users types.json");
let posts_json = r#"{
"types": [
{
"name": "Post",
"fields": [
{"name": "id", "type": "ID", "nullable": false},
{"name": "title", "type": "String", "nullable": false},
{"name": "authorId", "type": "ID", "nullable": false}
]
}
],
"queries": [
{
"name": "getUserPosts",
"return_type": "Post",
"return_array": true,
"description": "Get all posts by user (cross-domain reference to User)"
}
],
"mutations": []
}"#;
fs::write(temp_path.join("schema/posts/types.json"), posts_json)
.expect("Failed to write posts types.json");
let toml_content = r#"[schema]
name = "test"
version = "1.0.0"
database_target = "postgresql"
[database]
url = "postgresql://localhost/test"
pool_max = 20
ssl_mode = "prefer"
connect_timeout_ms = 5000
[domain_discovery]
enabled = true
root_dir = "schema"
"#;
fs::write(temp_path.join("fraiseql.toml"), toml_content).expect("Failed to write TOML");
let output = compile_schema(&temp_path.join("fraiseql.toml"))
.expect("Failed to compile cross-domain schema");
assert!(output.contains("Schema compiled successfully"), "Expected success");
assert!(output.contains("Types: 2"), "Expected 2 types");
assert!(output.contains("Queries: 1"), "Expected 1 query");
}
#[test]
fn test_domain_discovery_disabled() {
let temp_dir = TempDir::new().expect("Failed to create temp dir");
let temp_path = temp_dir.path();
fs::create_dir(temp_path.join("schema")).expect("Failed to create schema dir");
fs::create_dir(temp_path.join("schema/users")).expect("Failed to create users domain");
let types_json = r#"{
"types": [
{
"name": "User",
"fields": [
{"name": "id", "type": "ID", "nullable": false}
]
}
],
"queries": [],
"mutations": []
}"#;
fs::write(temp_path.join("schema/users/types.json"), types_json)
.expect("Failed to write types.json");
let toml_content = r#"[schema]
name = "test"
version = "1.0.0"
database_target = "postgresql"
[database]
url = "postgresql://localhost/test"
pool_max = 20
ssl_mode = "prefer"
connect_timeout_ms = 5000
[domain_discovery]
enabled = false
root_dir = "schema"
"#;
fs::write(temp_path.join("fraiseql.toml"), toml_content).expect("Failed to write TOML");
let output = compile_schema(&temp_path.join("fraiseql.toml"))
.expect("Failed to compile with disabled discovery");
assert!(output.contains("Schema compiled successfully"), "Expected success");
assert!(output.contains("Types: 0"), "Expected 0 types (discovery disabled)");
}