#![cfg_attr(coverage_nightly, coverage(off))]
#[cfg(test)]
mod tests {
use serial_test::serial;
use std::process::Command;
#[test]
#[ignore] #[serial]
fn test_cargo_build_has_single_correct_binary() {
let output = Command::new("cargo")
.args(["metadata", "--format-version", "1", "--no-deps"])
.output()
.expect("Failed to run cargo metadata");
let metadata: serde_json::Value =
serde_json::from_slice(&output.stdout).expect("Failed to parse cargo metadata");
let package_name = metadata["packages"][0]["name"].as_str().unwrap();
assert_eq!(package_name, "pmat", "Package name must be 'pmat'");
let targets = metadata["packages"][0]["targets"].as_array().unwrap();
let binaries: Vec<&str> = targets
.iter()
.filter(|t| {
t["kind"]
.as_array()
.unwrap()
.contains(&serde_json::Value::String("bin".to_string()))
})
.map(|t| t["name"].as_str().unwrap())
.collect();
let main_binaries: Vec<_> = binaries
.iter()
.filter(|&&name| name == "pmat")
.copied()
.collect();
assert_eq!(
main_binaries.len(),
1,
"There should be exactly one main binary target"
);
assert_eq!(main_binaries[0], "pmat", "Binary name must be 'pmat'");
if binaries.contains(&"generate-installer") {
assert!(binaries.len() <= 2, "Too many binaries: {binaries:?}");
}
}
#[test]
fn test_no_old_package_references() {
let output = Command::new("grep")
.args([
"-r",
"mcp_template_server",
"src/",
"--include=*.rs",
"--exclude=build_naming_validation.rs",
])
.output()
.expect("Failed to run grep");
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(
stdout.is_empty(),
"Found references to old package name in source files:\n{stdout}"
);
}
#[test]
fn test_no_old_binary_references_in_workflows() {
let old_binary_names = vec![
"mcp_server_stateless",
"mcp-template-server",
"mcp_template_server",
];
for old_name in &old_binary_names {
let output = Command::new("grep")
.args([
"-r",
old_name,
"../.github/workflows/",
"--include=*.yml",
"--include=*.yaml",
])
.output()
.expect("Failed to run grep");
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(
stdout.is_empty(),
"Found references to old binary name '{old_name}' in GitHub Actions workflows:\n{stdout}"
);
}
}
#[test]
#[ignore = "e2e test - requires binary build"]
fn test_correct_binary_name_in_workflows() {
let output = Command::new("grep")
.args([
"-r",
"pmat",
"../.github/workflows/",
"--include=*.yml",
"--include=*.yaml",
])
.output()
.expect("Failed to run grep");
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(
!stdout.is_empty(),
"No references to 'pmat' found in GitHub Actions workflows. Workflows should use the correct binary name."
);
}
#[test]
fn test_no_wrong_repo_urls_in_workflows() {
let wrong_urls = vec![
"pragmatic-ai-labs/pmat",
"paiml/mcp-template-server",
"pragmatic-ai-labs/mcp-template-server",
];
for wrong_url in &wrong_urls {
let output = Command::new("grep")
.args([
"-r",
wrong_url,
"../.github/workflows/",
"--include=*.yml",
"--include=*.yaml",
])
.output()
.expect("Failed to run grep");
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(
stdout.is_empty(),
"Found references to incorrect repository URL '{wrong_url}' in workflows:\n{stdout}\nShould be 'paiml/pmat'"
);
}
}
#[test]
#[ignore = "e2e test - requires binary build"]
fn test_workspace_aware_cargo_commands_in_makefile() {
let makefile_content =
std::fs::read_to_string("../Makefile").expect("Failed to read root Makefile");
let workspace_sensitive_commands = vec![
"cargo audit",
"cargo outdated",
"cargo update",
"cargo upgrade",
];
for (line_num, line) in makefile_content.lines().enumerate() {
let trimmed = line.trim();
if trimmed.starts_with('#') || trimmed.is_empty() {
continue;
}
for cmd in &workspace_sensitive_commands {
if trimmed.contains(cmd)
&& !trimmed.contains("cd ..")
&& !trimmed.contains("--manifest-path")
{
let is_workspace_aware = line.contains("cd ..")
|| line.contains("$(PWD)/..")
|| line.contains("--manifest-path");
assert!(
is_workspace_aware,
"Line {} in server/Makefile contains '{}' without workspace context.\n\
This command needs to run from workspace root.\n\
Found: {}\n\
Fix: Prepend with 'cd .. &&' or use '--manifest-path'",
line_num + 1,
cmd,
line.trim()
);
}
}
}
}
#[test]
#[ignore] #[serial]
fn test_cargo_lock_only_in_root() {
use std::env;
let current_dir = env::current_dir().expect("Failed to get current directory");
if current_dir.ends_with("server") {
assert!(
!std::path::Path::new("Cargo.lock").exists(),
"Cargo.lock found in server/ directory. It should only exist in the workspace root!"
);
assert!(
std::path::Path::new("../Cargo.lock").exists(),
"Cargo.lock not found in workspace root directory!"
);
} else {
assert!(
!std::path::Path::new("server/Cargo.lock").exists(),
"Cargo.lock found in server/ directory. It should only exist in the workspace root!"
);
assert!(
std::path::Path::new("Cargo.lock").exists(),
"Cargo.lock not found in workspace root directory!"
);
}
}
#[test]
#[ignore] #[serial]
fn test_build_script_workspace_aware() {
let build_script = std::fs::read_to_string("build.rs").expect("Failed to read build.rs");
if build_script.contains("\"Cargo.lock\"") {
assert!(
build_script.contains("../Cargo.lock")
|| build_script.contains("Path::new(\"../Cargo.lock\")"),
"build.rs references Cargo.lock but doesn't handle workspace structure.\n\
The build script should check if ../Cargo.lock exists for workspace builds."
);
}
}
}