use assert_cmd::cargo;
use predicates::prelude::*;
fn setup_project(temp: &tempfile::TempDir) -> std::path::PathBuf {
cargo::cargo_bin_cmd!("forte")
.args(["init", "my-app"])
.current_dir(temp)
.assert()
.success();
temp.path().join("my-app")
}
#[test]
fn test_add_page_creates_files() {
let temp = tempfile::tempdir().unwrap();
let project_dir = setup_project(&temp);
cargo::cargo_bin_cmd!("forte")
.args(["add", "page", "about"])
.current_dir(&project_dir)
.assert()
.success()
.stdout(predicate::str::contains("Created page 'about'"));
assert!(project_dir.join("rs/src/pages/about/mod.rs").exists());
assert!(project_dir.join("fe/src/pages/about/page.tsx").exists());
let backend_content =
std::fs::read_to_string(project_dir.join("rs/src/pages/about/mod.rs")).unwrap();
assert!(backend_content.contains("pub async fn handler"));
assert!(backend_content.contains("pub enum Props"));
let frontend_content =
std::fs::read_to_string(project_dir.join("fe/src/pages/about/page.tsx")).unwrap();
assert!(frontend_content.contains("AboutPage"));
assert!(frontend_content.contains("Props"));
}
#[test]
fn test_add_page_nested_path() {
let temp = tempfile::tempdir().unwrap();
let project_dir = setup_project(&temp);
cargo::cargo_bin_cmd!("forte")
.args(["add", "page", "product/detail"])
.current_dir(&project_dir)
.assert()
.success();
assert!(
project_dir
.join("rs/src/pages/product/detail/mod.rs")
.exists()
);
assert!(
project_dir
.join("fe/src/pages/product/detail/page.tsx")
.exists()
);
}
#[test]
fn test_add_page_dynamic_route() {
let temp = tempfile::tempdir().unwrap();
let project_dir = setup_project(&temp);
cargo::cargo_bin_cmd!("forte")
.args(["add", "page", "product/[id]"])
.current_dir(&project_dir)
.assert()
.success();
assert!(
project_dir
.join("rs/src/pages/product/[id]/mod.rs")
.exists()
);
assert!(
project_dir
.join("fe/src/pages/product/[id]/page.tsx")
.exists()
);
let backend_content =
std::fs::read_to_string(project_dir.join("rs/src/pages/product/[id]/mod.rs")).unwrap();
assert!(backend_content.contains("pub struct PathParams"));
assert!(backend_content.contains("pub id: String"));
}
#[test]
fn test_add_page_fails_outside_project() {
let temp = tempfile::tempdir().unwrap();
cargo::cargo_bin_cmd!("forte")
.args(["add", "page", "about"])
.current_dir(&temp)
.assert()
.failure()
.stderr(predicate::str::contains("Not a Forte project"));
}
#[test]
fn test_add_page_fails_if_exists() {
let temp = tempfile::tempdir().unwrap();
let project_dir = setup_project(&temp);
cargo::cargo_bin_cmd!("forte")
.args(["add", "page", "about"])
.current_dir(&project_dir)
.assert()
.success();
cargo::cargo_bin_cmd!("forte")
.args(["add", "page", "about"])
.current_dir(&project_dir)
.assert()
.failure()
.stderr(predicate::str::contains("already exists"));
}
#[test]
fn test_add_action_creates_files() {
let temp = tempfile::tempdir().unwrap();
let project_dir = setup_project(&temp);
cargo::cargo_bin_cmd!("forte")
.args(["add", "action", "user/login"])
.current_dir(&project_dir)
.assert()
.success()
.stdout(predicate::str::contains("Created action 'user/login'"));
assert!(project_dir.join("rs/src/actions/user/login.rs").exists());
assert!(
!project_dir.join("fe/src/actions/user/login.ts").exists(),
"forte add action must not write a frontend wrapper; codegen generates it"
);
let backend_content =
std::fs::read_to_string(project_dir.join("rs/src/actions/user/login.rs")).unwrap();
assert!(backend_content.contains("pub async fn handler"));
assert!(backend_content.contains("pub struct Input"));
assert!(backend_content.contains("pub enum Output"));
}
#[test]
fn test_add_action_simple_path() {
let temp = tempfile::tempdir().unwrap();
let project_dir = setup_project(&temp);
cargo::cargo_bin_cmd!("forte")
.args(["add", "action", "subscribe"])
.current_dir(&project_dir)
.assert()
.success();
assert!(project_dir.join("rs/src/actions/subscribe.rs").exists());
assert!(!project_dir.join("fe/src/actions/subscribe.ts").exists());
let backend_content =
std::fs::read_to_string(project_dir.join("rs/src/actions/subscribe.rs")).unwrap();
assert!(backend_content.contains("pub struct Input"));
assert!(backend_content.contains("pub enum Output"));
}
#[test]
fn test_add_action_fails_outside_project() {
let temp = tempfile::tempdir().unwrap();
cargo::cargo_bin_cmd!("forte")
.args(["add", "action", "test"])
.current_dir(&temp)
.assert()
.failure()
.stderr(predicate::str::contains("Not a Forte project"));
}
#[test]
fn test_add_action_fails_if_exists() {
let temp = tempfile::tempdir().unwrap();
let project_dir = setup_project(&temp);
cargo::cargo_bin_cmd!("forte")
.args(["add", "action", "test"])
.current_dir(&project_dir)
.assert()
.success();
cargo::cargo_bin_cmd!("forte")
.args(["add", "action", "test"])
.current_dir(&project_dir)
.assert()
.failure()
.stderr(predicate::str::contains("already exists"));
}