use super::super::super::{
GenerateOptions, GenerateProgress, WriteOutcome, generate, generate_with_options,
generate_with_options_and_progress,
};
use super::super::{make_temp_dir, write_custom_files_job_config};
use std::fs;
#[test]
fn generate_skips_when_generation_contract_is_unchanged_by_default() {
let temp_dir = make_temp_dir("pipeline-generate-skip-default");
let config_path = temp_dir.join("numi.toml");
let files_root = temp_dir.join("Resources/Fixtures");
let template_path = temp_dir.join("Templates/files.jinja");
let generated_path = temp_dir.join("Generated/Files.swift");
fs::create_dir_all(&files_root).expect("files directory should exist");
fs::create_dir_all(
template_path
.parent()
.expect("template path should have parent"),
)
.expect("template dir should exist");
fs::write(files_root.join("faq.pdf"), "faq").expect("faq file should be written");
fs::write(
&template_path,
"{{ modules[0].entries[0].properties.fileName }}\n",
)
.expect("template should be written");
write_custom_files_job_config(&config_path, None);
let first = generate(&config_path, None).expect("initial generation should succeed");
assert_eq!(first.jobs[0].outcome, WriteOutcome::Created);
assert_eq!(
fs::read_to_string(&generated_path).expect("generated file should exist"),
"faq.pdf\n"
);
let second = generate(&config_path, None).expect("second generation should succeed");
assert_eq!(second.jobs[0].outcome, WriteOutcome::Skipped);
assert_eq!(
fs::read_to_string(&generated_path).expect("generated file should remain"),
"faq.pdf\n"
);
fs::remove_dir_all(temp_dir).expect("temp dir should be removed");
}
#[test]
fn generate_rerenders_when_only_job_variables_change() {
let temp_dir = make_temp_dir("pipeline-generate-variable-change");
let config_path = temp_dir.join("numi.toml");
let files_root = temp_dir.join("Resources/Fixtures");
let template_path = temp_dir.join("Templates/files.jinja");
let generated_path = temp_dir.join("Generated/Files.swift");
fs::create_dir_all(&files_root).expect("files directory should exist");
fs::create_dir_all(
template_path
.parent()
.expect("template path should have parent"),
)
.expect("template dir should exist");
fs::write(files_root.join("faq.pdf"), "faq").expect("faq file should be written");
fs::write(&template_path, "{{ variables.enum_name }}\n").expect("template should be written");
fs::write(
&config_path,
r#"
version = 1
[jobs.files]
output = "Generated/Files.swift"
[[jobs.files.inputs]]
type = "files"
path = "Resources/Fixtures"
[jobs.files.template]
path = "Templates/files.jinja"
[jobs.files.variables]
enum_name = "FilesV1"
"#,
)
.expect("config should be written");
let first = generate(&config_path, None).expect("initial generation should succeed");
assert_eq!(first.jobs[0].outcome, WriteOutcome::Created);
assert_eq!(
fs::read_to_string(&generated_path).expect("generated file should exist"),
"FilesV1\n"
);
fs::write(
&config_path,
r#"
version = 1
[jobs.files]
output = "Generated/Files.swift"
[[jobs.files.inputs]]
type = "files"
path = "Resources/Fixtures"
[jobs.files.template]
path = "Templates/files.jinja"
[jobs.files.variables]
enum_name = "FilesV2"
"#,
)
.expect("config should be rewritten");
let second = generate(&config_path, None).expect("second generation should succeed");
assert_eq!(second.jobs[0].outcome, WriteOutcome::Updated);
assert_eq!(
fs::read_to_string(&generated_path).expect("generated file should update"),
"FilesV2\n"
);
fs::remove_dir_all(temp_dir).expect("temp dir should be removed");
}
#[test]
fn generate_respects_job_incremental_opt_out_and_rerenders() {
let temp_dir = make_temp_dir("pipeline-generate-opt-out");
let config_path = temp_dir.join("numi.toml");
let files_root = temp_dir.join("Resources/Fixtures");
let template_path = temp_dir.join("Templates/files.jinja");
let generated_path = temp_dir.join("Generated/Files.swift");
fs::create_dir_all(&files_root).expect("files directory should exist");
fs::create_dir_all(
template_path
.parent()
.expect("template path should have parent"),
)
.expect("template dir should exist");
fs::write(files_root.join("faq.pdf"), "faq").expect("faq file should be written");
fs::write(
&template_path,
"{{ modules[0].entries[0].properties.fileName }}\n",
)
.expect("template should be written");
write_custom_files_job_config(&config_path, Some(false));
let first = generate(&config_path, None).expect("initial generation should succeed");
assert_eq!(first.jobs[0].outcome, WriteOutcome::Created);
let second = generate(&config_path, None).expect("second generation should rerender");
assert_eq!(second.jobs[0].outcome, WriteOutcome::Unchanged);
assert_eq!(
fs::read_to_string(&generated_path).expect("generated file should remain"),
"faq.pdf\n"
);
fs::remove_dir_all(temp_dir).expect("temp dir should be removed");
}
#[test]
fn generate_options_override_job_incremental_setting() {
let temp_dir = make_temp_dir("pipeline-generate-options-override");
let config_path = temp_dir.join("numi.toml");
let files_root = temp_dir.join("Resources/Fixtures");
let template_path = temp_dir.join("Templates/files.jinja");
let generated_path = temp_dir.join("Generated/Files.swift");
fs::create_dir_all(&files_root).expect("files directory should exist");
fs::create_dir_all(
template_path
.parent()
.expect("template path should have parent"),
)
.expect("template dir should exist");
fs::write(files_root.join("faq.pdf"), "faq").expect("faq file should be written");
fs::write(
&template_path,
"{{ modules[0].entries[0].properties.fileName }}\n",
)
.expect("template should be written");
write_custom_files_job_config(&config_path, Some(false));
let first = generate(&config_path, None).expect("initial generation should succeed");
assert_eq!(first.jobs[0].outcome, WriteOutcome::Created);
let second = generate_with_options(
&config_path,
None,
GenerateOptions {
incremental: Some(true),
parse_cache: None,
force_regenerate: false,
workspace_manifest_path: None,
},
)
.expect("second generation should honor the explicit override");
assert_eq!(second.jobs[0].outcome, WriteOutcome::Skipped);
assert_eq!(
fs::read_to_string(&generated_path).expect("generated file should remain"),
"faq.pdf\n"
);
fs::remove_dir_all(temp_dir).expect("temp dir should be removed");
}
#[test]
fn generate_refresh_bypasses_generation_skip() {
let temp_dir = make_temp_dir("pipeline-generate-refresh");
let config_path = temp_dir.join("numi.toml");
let files_root = temp_dir.join("Resources/Fixtures");
let template_path = temp_dir.join("Templates/files.jinja");
let generated_path = temp_dir.join("Generated/Files.swift");
fs::create_dir_all(&files_root).expect("files directory should exist");
fs::create_dir_all(
template_path
.parent()
.expect("template path should have parent"),
)
.expect("template dir should exist");
fs::write(files_root.join("faq.pdf"), "faq").expect("faq file should be written");
fs::write(
&template_path,
"{{ modules[0].entries[0].properties.fileName }}\n",
)
.expect("template should be written");
write_custom_files_job_config(&config_path, Some(true));
let first = generate(&config_path, None).expect("initial generation should succeed");
assert_eq!(first.jobs[0].outcome, WriteOutcome::Created);
let second = generate_with_options(
&config_path,
None,
GenerateOptions {
incremental: Some(true),
parse_cache: None,
force_regenerate: false,
workspace_manifest_path: None,
},
)
.expect("second generation should skip");
assert_eq!(second.jobs[0].outcome, WriteOutcome::Skipped);
let third = generate_with_options(
&config_path,
None,
GenerateOptions {
incremental: Some(true),
parse_cache: Some(true),
force_regenerate: true,
workspace_manifest_path: None,
},
)
.expect("force regenerate should rerender");
assert_eq!(third.jobs[0].outcome, WriteOutcome::Unchanged);
assert_eq!(
fs::read_to_string(&generated_path).expect("generated file should remain"),
"faq.pdf\n"
);
}
#[test]
fn generate_reports_job_started_before_generating() {
let temp_dir = make_temp_dir("pipeline-generate-progress");
let config_path = temp_dir.join("numi.toml");
let files_root = temp_dir.join("Resources/Fixtures");
let template_path = temp_dir.join("Templates/files.jinja");
fs::create_dir_all(&files_root).expect("files directory should exist");
fs::create_dir_all(
template_path
.parent()
.expect("template path should have parent"),
)
.expect("template dir should exist");
fs::write(files_root.join("faq.pdf"), "faq").expect("faq file should be written");
fs::write(
&template_path,
"{{ modules[0].entries[0].properties.fileName }}\n",
)
.expect("template should be written");
write_custom_files_job_config(&config_path, Some(false));
let mut events = Vec::new();
let report = generate_with_options_and_progress(
&config_path,
None,
GenerateOptions::default(),
|progress| events.push(progress.clone()),
)
.expect("generation should succeed");
assert_eq!(report.jobs[0].outcome, WriteOutcome::Created);
assert_eq!(
events,
vec![GenerateProgress::JobStarted {
job_name: "files".to_string(),
}]
);
fs::remove_dir_all(temp_dir).expect("temp dir should be removed");
}