use crate::common::{ManifestBuilder, TestProject};
use anyhow::Result;
#[tokio::test]
async fn test_literal_blocks_preserve_template_syntax() -> Result<()> {
agpm_cli::test_utils::init_test_logging(None);
let project = TestProject::new().await?;
let test_repo = project.create_source_repo("test-source").await?;
test_repo
.add_resource(
"agents",
"literal-test",
r#"---
agpm:
templating: true
---
# Agent with Literal Blocks
This template shows how to preserve template syntax:
```literal
{{ agpm.resource.name }}
{{ agpm.resource.install_path }}
{% for dep in agpm.deps.agents %}
- {{ dep.name }}
{% endfor %}
```
The syntax above should appear literally in the output."#,
)
.await?;
test_repo.commit_all("Add agent with literal blocks")?;
test_repo.tag_version("v1.0.0")?;
let repo_url = test_repo.bare_file_url(project.sources_path()).await?;
let manifest = ManifestBuilder::new()
.add_source("test-source", &repo_url)
.add_agent("literal-agent", |d| {
d.source("test-source").path("agents/literal-test.md").version("v1.0.0")
})
.build();
project.write_manifest(&manifest).await?;
let output = project.run_agpm(&["install"])?;
assert!(output.success);
let installed_path = project.project_path().join(".claude/agents/agpm/literal-test.md");
let content = tokio::fs::read_to_string(&installed_path).await?;
assert!(content.contains("```\n{{ agpm.resource.name }}"));
assert!(content.contains("{{ agpm.resource.install_path }}"));
assert!(content.contains("{% for dep in agpm.deps.agents %}"));
assert!(content.contains("{% endfor %}\n```"));
assert!(!content.contains("__AGPM_LITERAL_BLOCK_"));
Ok(())
}
#[tokio::test]
async fn test_template_error_messages_are_clear() -> Result<()> {
agpm_cli::test_utils::init_test_logging(None);
let project = TestProject::new().await?;
let test_repo = project.create_source_repo("test-source").await?;
test_repo
.add_resource(
"agents",
"syntax-error",
r#"---
agpm:
templating: true
---
# Agent with Syntax Error
This template has broken syntax:
{{ variable_with_no_closing_brace
Another line here."#,
)
.await?;
test_repo.commit_all("Add agent with syntax error")?;
test_repo.tag_version("v1.0.0")?;
let repo_url = test_repo.bare_file_url(project.sources_path()).await?;
let manifest = ManifestBuilder::new()
.add_source("test-source", &repo_url)
.add_agent("broken-agent", |d| {
d.source("test-source").path("agents/syntax-error.md").version("v1.0.0")
})
.build();
project.write_manifest(&manifest).await?;
let result = project.run_agpm(&["install"])?;
assert!(!result.success, "Install should fail due to template syntax error");
let stderr = &result.stderr;
assert!(
stderr.contains("Template syntax error") || stderr.contains("failed to render"),
"Error should mention template syntax issue: {}",
stderr
);
assert!(!stderr.contains("__tera_one_off"), "Error should not expose internal template names");
Ok(())
}
#[tokio::test]
async fn test_disabled_templating_preserves_syntax() -> Result<()> {
agpm_cli::test_utils::init_test_logging(None);
let project = TestProject::new().await?;
let test_repo = project.create_source_repo("test-source").await?;
test_repo
.add_resource(
"agents",
"no-template",
r#"---
title: No Template Agent
---
# Agent Without Template Processing
This content should not be processed:
{{ agpm.resource.name }}
{{ undefined.variable }}
{% if condition %}{% endif %}
All template syntax should remain exactly as written."#,
)
.await?;
test_repo.commit_all("Add agent without templating")?;
test_repo.tag_version("v1.0.0")?;
let repo_url = test_repo.bare_file_url(project.sources_path()).await?;
let manifest = ManifestBuilder::new()
.add_source("test-source", &repo_url)
.add_agent("no-template-agent", |d| {
d.source("test-source").path("agents/no-template.md").version("v1.0.0")
})
.build();
project.write_manifest(&manifest).await?;
let output = project.run_agpm(&["install"])?;
assert!(output.success);
let installed_path = project.project_path().join(".claude/agents/agpm/no-template.md");
let content = tokio::fs::read_to_string(&installed_path).await?;
assert!(content.contains("{{ agpm.resource.name }}"));
assert!(content.contains("{{ undefined.variable }}"));
assert!(content.contains("{% if condition %}{% endif %}"));
Ok(())
}