mod test_utils;
use anyhow::{Context, Result};
use std::fs;
use std::path::PathBuf;
use test_utils::{copy_dir_all, run_command, unique_tmp_dir, write_to_file};
fn setup(system: &str, scheme_name: &str) -> Result<(String, String, String, String)> {
let config_file_path: PathBuf =
PathBuf::from(format!("./tests/fixtures/templates/{system}-config.yaml"));
let scheme_file_path: PathBuf = PathBuf::from(format!(
"./tests/fixtures/schemes/{system}/{scheme_name}.yaml",
));
let template_file_path: PathBuf = PathBuf::from(format!(
"./tests/fixtures/templates/{system}-template.mustache",
));
let template_rendered_path_fixture: PathBuf = PathBuf::from(format!(
"./tests/fixtures/rendered/{system}-{scheme_name}.md",
));
Ok((
fs::read_to_string(&config_file_path).context(format!(
"Unable to get contents of config: {}",
config_file_path.display()
))?,
fs::read_to_string(&scheme_file_path).context(format!(
"Unable to get contents of scheme: {}",
scheme_file_path.display()
))?,
fs::read_to_string(&template_file_path).context(format!(
"Unable to get contents of template: {}",
template_file_path.display()
))?,
fs::read_to_string(&template_rendered_path_fixture).context(format!(
"Unable to get contents of rendered file: {}",
template_rendered_path_fixture.display()
))?,
))
}
#[test]
fn test_operation_build_quiet_flag() -> Result<()> {
let scheme_name = "silk-light";
let system = "base16";
let tmp_dir = unique_tmp_dir("operation_build_quiet_flag")?;
let template_theme_path = tmp_dir.join("template");
let template_templates_path = template_theme_path.join("templates");
let template_config_path = template_templates_path.join("config.yaml");
let template_mustache_path = template_templates_path.join("base16-template.mustache");
let schemes_path = tmp_dir.join("schemes");
let scheme_file_path = schemes_path.join(format!("{}.yaml", &scheme_name));
let themes_path = template_theme_path.join("output-themes");
let rendered_theme_path = themes_path.join(format!("base16-{}.md", &scheme_name));
let (
config_file_content,
scheme_file_content,
template_file_content,
template_rendered_content_fixture,
) = setup(system, scheme_name)?;
fs::create_dir_all(&template_templates_path)?;
fs::create_dir_all(&schemes_path)?;
write_to_file(&scheme_file_path, &scheme_file_content)?;
write_to_file(&template_config_path, &config_file_content)?;
write_to_file(&template_mustache_path, &template_file_content)?;
let (stdout, stderr) = run_command(&[
format!("--schemes-dir={}", schemes_path.display()),
"build".to_string(),
template_theme_path.display().to_string(),
"--quiet".to_string(),
])
.expect("Unable to run command");
let rendered_content = fs::read_to_string(rendered_theme_path)?;
assert_eq!(rendered_content, template_rendered_content_fixture);
assert!(
stderr.is_empty(),
"stderr does not contain the expected output"
);
assert!(
stdout.is_empty(),
"stdout does not contain the exptected output"
);
Ok(())
}
#[test]
fn test_operation_build_with_sync() -> Result<()> {
let tmp_dir = unique_tmp_dir("operation_build_with_sync")?;
let expected_output = "schemes installed";
let expected_schemes_path = tmp_dir.join("schemes");
let expected_git_clone_str = format!("Cloning into '{}/schemes'", tmp_dir.display());
fs::create_dir_all(&tmp_dir)?;
let (stdout, stderr) = run_command(&[
format!("--data-dir={}", tmp_dir.display()),
"build".to_string(),
"nonexistent-template".to_string(),
"--sync".to_string(),
])
.expect("Unable to run command");
let is_schemes_dir_empty = fs::read_dir(&expected_schemes_path)?.next().is_none();
assert!(
stdout.contains(expected_output),
"stdout does not contain the expected output"
);
assert!(
stderr.contains(&expected_git_clone_str),
"stderr does not contain the expected output"
);
assert!(expected_schemes_path.exists() && !is_schemes_dir_empty,);
Ok(())
}
#[test]
fn test_operation_build_base16() -> Result<()> {
let scheme_name = "silk-light";
let system = "base16";
let tmp_dir = unique_tmp_dir("operation_build_base16")?;
let template_theme_path = tmp_dir.join("template");
let template_templates_path = template_theme_path.join("templates");
let template_config_path = template_templates_path.join("config.yaml");
let template_mustache_path = template_templates_path.join("base16-template.mustache");
let schemes_path = tmp_dir.join("schemes");
let scheme_file_path = schemes_path.join(format!("{}.yaml", &scheme_name));
let themes_path = template_theme_path.join("output-themes");
let rendered_theme_path = themes_path.join(format!("base16-{}.md", &scheme_name));
let hidden_yaml_path = schemes_path.join(".hidden.yaml");
let base24_schemes_path = schemes_path.join("base24");
let base24_scheme_content = fs::read_to_string(PathBuf::from(
"./tests/fixtures/schemes/base24/dracula.yaml",
))?;
let base24_scheme_file_path: PathBuf = schemes_path.join("base24/dracula.yaml");
let base24_theme_output_file = themes_path.join("base24-dracula.md");
let (
base16_config_file_content,
base16_scheme_file_content,
base16_template_file_content,
base16_template_rendered_content_fixture,
) = setup(system, scheme_name)?;
fs::create_dir_all(&template_templates_path)?;
fs::create_dir_all(&schemes_path)?;
fs::create_dir_all(&base24_schemes_path)?;
write_to_file(&scheme_file_path, &base16_scheme_file_content)?;
write_to_file(&base24_scheme_file_path, &base24_scheme_content)?;
write_to_file(&hidden_yaml_path, "content: invalid")?;
write_to_file(&template_config_path, &base16_config_file_content)?;
write_to_file(&template_mustache_path, &base16_template_file_content)?;
let (stdout, stderr) = run_command(&[
"build".to_string(),
template_theme_path.display().to_string(),
format!("--schemes-dir={}", schemes_path.display()),
"--ignore=**/.*".to_string(),
])
.expect("Unable to run command");
let rendered_content = fs::read_to_string(rendered_theme_path)?;
assert_eq!(rendered_content, base16_template_rendered_content_fixture);
assert!(
stderr.is_empty(),
"stderr does not contain the expected output"
);
assert!(
!&base24_theme_output_file.is_file(),
"file should not exist: {}",
base24_theme_output_file.display()
);
assert!(
&hidden_yaml_path.is_file(),
"file does not exist: {}",
hidden_yaml_path.display()
);
assert!(
stdout.contains("✔ Successfully generated \"base16\" themes for \"base16-template\""),
"stdout does not contain the exptected output"
);
Ok(())
}
#[test]
fn test_operation_build_base24() -> Result<()> {
let scheme_name = "dracula";
let system = "base24";
let tmp_dir = unique_tmp_dir("operation_build_base24")?;
let template_theme_path = tmp_dir.join("template");
let template_templates_path = template_theme_path.join("templates");
let template_config_path = template_templates_path.join("config.yaml");
let template_mustache_path = template_templates_path.join("base24-template.mustache");
let schemes_path = tmp_dir.join("schemes");
let scheme_file_path = schemes_path.join(format!("{}.yaml", &scheme_name));
let themes_path = template_theme_path.join("output-themes");
let output_extension = "-custom-extension";
let rendered_theme_path =
themes_path.join(format!("base24-{}{}", &scheme_name, &output_extension));
let (
base24_config_file_content,
base24_scheme_file_content,
base24_template_file_content,
base24_template_rendered_content_fixture,
) = setup(system, scheme_name)?;
fs::create_dir_all(&template_templates_path)?;
fs::create_dir_all(&schemes_path)?;
write_to_file(&scheme_file_path, &base24_scheme_file_content)?;
write_to_file(&template_config_path, &base24_config_file_content)?;
write_to_file(&template_mustache_path, &base24_template_file_content)?;
let (stdout, stderr) = run_command(&[
"build".to_string(),
template_theme_path.display().to_string(),
format!("--schemes-dir={}", schemes_path.display()),
])
.expect("Unable to run command");
let rendered_content = fs::read_to_string(rendered_theme_path)?;
assert_eq!(rendered_content, base24_template_rendered_content_fixture);
assert!(
stderr.is_empty(),
"stderr does not contain the expected output"
);
assert!(
stdout.contains("✔ Successfully generated \"base24\" themes for \"base24-template\""),
"stdout does not contain the exptected output"
);
Ok(())
}
#[test]
fn test_operation_build_mixed() -> Result<()> {
let base16_scheme_name = "silk-light";
let base24_scheme_name = "dracula";
let tmp_dir = unique_tmp_dir("operation_build_mixed")?;
let template_theme_path = tmp_dir.join("template");
let template_templates_path = template_theme_path.join("templates");
let template_config_path = template_templates_path.join("config.yaml");
let base24_template_mustache_path = template_templates_path.join("mixed-template.mustache");
let schemes_path = tmp_dir.join("schemes");
let base16_schemes_path = schemes_path.join("base16");
let base24_schemes_path = schemes_path.join("base24");
let base16_scheme_file_path = base16_schemes_path.join(format!("{}.yaml", &base16_scheme_name));
let base24_scheme_file_path = base24_schemes_path.join(format!("{}.yaml", &base24_scheme_name));
let themes_path = template_theme_path.join("output-themes");
let base16_rendered_theme_path = themes_path.join(format!("base16-{}.md", &base16_scheme_name));
let base24_rendered_theme_path = themes_path.join(format!("base24-{}.md", &base24_scheme_name));
let base16_template_rendered_content_fixture = fs::read_to_string(format!(
"./tests/fixtures/rendered/base16-mixed-{base16_scheme_name}.md",
))?;
let (_, base16_scheme_file_content, _, _) = setup("base16", base16_scheme_name)?;
let (
_,
base24_scheme_file_content,
base24_template_file_content,
base24_template_rendered_content_fixture,
) = setup("base24", base24_scheme_name)?;
fs::create_dir_all(&template_templates_path)?;
fs::create_dir_all(&base16_schemes_path)?;
fs::create_dir_all(&base24_schemes_path)?;
write_to_file(&base16_scheme_file_path, &base16_scheme_file_content)?;
write_to_file(&base24_scheme_file_path, &base24_scheme_file_content)?;
write_to_file(
&template_config_path,
fs::read_to_string("./tests/fixtures/templates/mixed-config.yaml")?.as_str(),
)?;
write_to_file(
&base24_template_mustache_path,
&base24_template_file_content,
)?;
let (stdout, stderr) = run_command(&[
"build".to_string(),
template_theme_path.display().to_string(),
format!("--schemes-dir={}", &schemes_path.display()),
])
.expect("Unable to run command");
let base16_rendered_content = fs::read_to_string(base16_rendered_theme_path)?;
let base24_rendered_content = fs::read_to_string(base24_rendered_theme_path)?;
assert_eq!(
base16_rendered_content,
base16_template_rendered_content_fixture
);
assert_eq!(
base24_rendered_content,
base24_template_rendered_content_fixture
);
assert!(
stderr.is_empty(),
"stderr does not contain the expected output"
);
assert!(
stdout
.contains("✔ Successfully generated \"base16, base24\" themes for \"mixed-template\""),
"stdout does not contain the exptected output"
);
Ok(())
}
#[test]
fn test_operation_build_multi_ignore_input() -> Result<()> {
let scheme_name = "silk-light";
let system = "base16";
let tmp_dir = unique_tmp_dir("operation_build_multi_ignore_input")?;
let template_theme_path = tmp_dir.join("template");
let template_templates_path = template_theme_path.join("templates");
let template_config_path = template_templates_path.join("config.yaml");
let template_mustache_path = template_templates_path.join("base16-template.mustache");
let schemes_path = tmp_dir.join("schemes");
let scheme_file_path = schemes_path.join(format!("{}.yaml", &scheme_name));
let themes_path = template_theme_path.join("output-themes");
let rendered_theme_path = themes_path.join(format!("base16-{}.md", &scheme_name));
let hidden_yaml_path = schemes_path.join(".hidden.yaml");
let readme_path = schemes_path.join("README.md");
let changelog_path = schemes_path.join("CHANGELOG.md");
let (
base16_config_file_content,
base16_scheme_file_content,
base16_template_file_content,
base16_template_rendered_content_fixture,
) = setup(system, scheme_name)?;
fs::create_dir_all(&template_templates_path)?;
fs::create_dir_all(&schemes_path)?;
write_to_file(&scheme_file_path, &base16_scheme_file_content)?;
write_to_file(&hidden_yaml_path, "content: invalid")?;
write_to_file(&readme_path, "Some readme content")?;
write_to_file(&changelog_path, "Some changelog content")?;
write_to_file(&template_config_path, &base16_config_file_content)?;
write_to_file(&template_mustache_path, &base16_template_file_content)?;
let (stdout, stderr) = run_command(&[
"build".to_string(),
template_theme_path.display().to_string(),
format!("--schemes-dir={}", schemes_path.display()),
"--ignore=**/.*".to_string(),
"--ignore=**/*.md".to_string(),
])
.expect("Unable to run command");
let rendered_content = fs::read_to_string(rendered_theme_path)?;
assert_eq!(rendered_content, base16_template_rendered_content_fixture);
assert!(
stderr.is_empty(),
"stderr does not contain the expected output"
);
assert!(
&hidden_yaml_path.is_file(),
"file does not exist: {}",
hidden_yaml_path.display()
);
assert!(
&readme_path.is_file(),
"file does not exist: {}",
readme_path.display()
);
assert!(
&changelog_path.is_file(),
"file does not exist: {}",
changelog_path.display()
);
assert!(
stdout.contains("✔ Successfully generated \"base16\" themes for \"base16-template\""),
"stdout does not contain the exptected output"
);
Ok(())
}
#[test]
fn test_operation_build_listbase16() -> Result<()> {
let tmp_dir = unique_tmp_dir("operation_build_listbase16")?;
let template_theme_path = tmp_dir.join("template");
let template_templates_path = template_theme_path.join("templates");
let schemes_path = tmp_dir.join("schemes");
let rendered_list_theme_path = PathBuf::from("./tests/fixtures/rendered/list.md");
let rendered_listbase16_theme_path = PathBuf::from("./tests/fixtures/rendered/listbase16.md");
let rendered_listbase24_theme_path = PathBuf::from("./tests/fixtures/rendered/listbase24.md");
fs::create_dir_all(&template_templates_path)?;
fs::copy(
"./tests/fixtures/templates/list-config.yaml",
template_theme_path.join("templates/config.yaml"),
)?;
fs::copy(
"./tests/fixtures/templates/list-template.mustache",
template_theme_path.join("templates/list.mustache"),
)?;
copy_dir_all("./tests/fixtures/schemes", &schemes_path)?;
let (stdout, stderr) = run_command(&[
"build".to_string(),
template_theme_path.display().to_string(),
format!("--schemes-dir={}", schemes_path.display()),
])
.expect("Unable to run command");
let rendered_list_content = fs::read_to_string(rendered_list_theme_path)?;
let rendered_listbase16_content = fs::read_to_string(rendered_listbase16_theme_path)?;
let rendered_listbase24_content = fs::read_to_string(rendered_listbase24_theme_path)?;
let expected_list_content = fs::read_to_string("./tests/fixtures/rendered/list.md")?;
let expected_listbase16_content =
fs::read_to_string("./tests/fixtures/rendered/listbase16.md")?;
let expected_listbase24_content =
fs::read_to_string("./tests/fixtures/rendered/listbase24.md")?;
assert_eq!(rendered_list_content, expected_list_content);
assert_eq!(rendered_listbase16_content, expected_listbase16_content);
assert_eq!(rendered_listbase24_content, expected_listbase24_content);
assert!(
stderr.is_empty(),
"stderr does not contain the expected output"
);
let expected_output = "✔ Successfully generated \"base16, base24\" list";
assert!(
stdout.contains(expected_output),
"stdout does not contain the exptected output"
);
Ok(())
}
#[test]
fn test_operation_build_listtinted8() -> Result<()> {
let tmp_dir = unique_tmp_dir("operation_build_listtinted8")?;
let template_theme_path = tmp_dir.join("template");
let template_templates_path = template_theme_path.join("templates");
let schemes_path = tmp_dir.join("schemes");
let rendered_list_theme_path = PathBuf::from("./tests/fixtures/rendered/list-tinted8.md");
fs::create_dir_all(&template_templates_path)?;
fs::copy(
"./tests/fixtures/templates/list-tinted8-config.yaml",
template_theme_path.join("templates/config.yaml"),
)?;
fs::copy(
"./tests/fixtures/templates/list-tinted8-template.mustache",
template_theme_path.join("templates/list.mustache"),
)?;
copy_dir_all("./tests/fixtures/schemes", &schemes_path)?;
let (stdout, stderr) = run_command(&[
"build".to_string(),
template_theme_path.display().to_string(),
format!("--schemes-dir={}", schemes_path.display()),
])
.expect("Unable to run command");
let rendered_list_content = fs::read_to_string(rendered_list_theme_path)?;
let expected_list_content = fs::read_to_string(template_theme_path.join("tinted8-list.txt"))?;
assert_eq!(rendered_list_content, expected_list_content);
assert!(
stderr.is_empty(),
"stderr does not contain the expected output"
);
let expected_output = "✔ Successfully generated \"tinted8\" list";
assert!(
stdout.contains(expected_output),
"stdout does not contain the exptected output"
);
Ok(())
}
#[test]
fn test_operation_build_invalid_system() -> Result<()> {
let system = "invalid-system";
let tmp_dir = unique_tmp_dir("operation_build_invalid_system")?;
let template_theme_path = tmp_dir.join("template");
let template_templates_path = template_theme_path.join("templates");
let template_config_path = template_templates_path.join("config.yaml");
let schemes_path = tmp_dir.join("schemes");
let base16_config_file_content = format!(
r"
invalid:
filename: output-themes/{{ scheme-system }}-{{ scheme-slug }}.md
supported-systems: [{system}]",
);
fs::create_dir_all(&template_templates_path)?;
fs::create_dir_all(&schemes_path)?;
write_to_file(&template_config_path, &base16_config_file_content)?;
let (stdout, stderr) = run_command(&[
"build".to_string(),
template_theme_path.display().to_string(),
format!("--schemes-dir={}", schemes_path.display()),
])
.expect("Unable to run command");
assert!(
stderr.contains("Error: E305: Template config missing or invalid"),
"stderr does not contain the expected output"
);
assert!(
stdout.is_empty(),
"stdout does not contain the exptected output"
);
Ok(())
}
#[test]
fn test_operation_build_base16_missing_base00() -> Result<()> {
let scheme_name = "invalid";
let system = "base16";
let tmp_dir = unique_tmp_dir("operation_build_base16_missing_base00")?;
let template_theme_path = tmp_dir.join("template");
let template_templates_path = template_theme_path.join("templates");
let template_config_path = template_templates_path.join("config.yaml");
let template_mustache_path = template_templates_path.join("base16-template.mustache");
let schemes_path = tmp_dir.join("schemes");
let scheme_file_path = schemes_path.join(format!("{}.yaml", &scheme_name));
let scheme_file_content = r#"
system: "base16"
name: "UwUnicorn"
author: "Fernando Marques (https://github.com/RakkiUwU) and Gabriel Fontes (https://github.com/Misterio77)"
variant: "dark"
palette:
base01: "2f2a3f"
base02: "46354a"
base03: "6c3cb2"
base04: "7e5f83"
base05: "eed5d9"
base06: "d9c2c6"
base07: "e4ccd0"
base08: "877bb6"
base09: "de5b44"
base0A: "a84a73"
base0B: "c965bf"
base0C: "9c5fce"
base0D: "6a9eb5"
base0E: "78a38f"
base0F: "a3a079"
"#;
fs::create_dir_all(&template_templates_path)?;
fs::create_dir_all(&schemes_path)?;
write_to_file(&scheme_file_path, scheme_file_content)?;
let base16_config_file_content = fs::read_to_string(PathBuf::from(format!(
"./tests/fixtures/templates/{system}-config.yaml",
)))?;
let base16_template_file_content = fs::read_to_string(PathBuf::from(format!(
"./tests/fixtures/templates/{system}-template.mustache",
)))?;
write_to_file(&template_config_path, &base16_config_file_content)?;
write_to_file(&template_mustache_path, &base16_template_file_content)?;
let (stdout, stderr) = run_command(&[
"build".to_string(),
template_theme_path.display().to_string(),
format!("--schemes-dir={}", schemes_path.display()),
])
.expect("Unable to run command");
assert!(
stderr.contains("base16 scheme does not contain the required palette properties"),
"stderr does not contain the expected output"
);
assert!(
stdout.is_empty(),
"stdout does not contain the exptected output"
);
Ok(())
}
#[test]
fn test_operation_build_invalid_base16() -> Result<()> {
let scheme_name = "invalid";
let system = "base16";
let tmp_dir = unique_tmp_dir("operation_build_invalid_base16")?;
let template_theme_path = tmp_dir.join("template");
let template_templates_path = template_theme_path.join("templates");
let template_config_path = template_templates_path.join("config.yaml");
let template_mustache_path = template_templates_path.join("base16-template.mustache");
let schemes_path = tmp_dir.join("schemes");
let scheme_file_path = schemes_path.join(format!("{}.yaml", &scheme_name));
fs::create_dir_all(&template_templates_path)?;
fs::create_dir_all(&schemes_path)?;
write_to_file(&scheme_file_path, "content: invalid")?;
let base16_config_file_content = fs::read_to_string(PathBuf::from(format!(
"./tests/fixtures/templates/{system}-config.yaml",
)))?;
let base16_template_file_content = fs::read_to_string(PathBuf::from(format!(
"./tests/fixtures/templates/{system}-template.mustache",
)))?;
write_to_file(&template_config_path, &base16_config_file_content)?;
write_to_file(&template_mustache_path, &base16_template_file_content)?;
let (stdout, stderr) = run_command(&[
"build".to_string(),
template_theme_path.display().to_string(),
format!("--schemes-dir={}", schemes_path.display()),
])
.expect("Unable to run command");
assert!(
stderr.contains("E111: Missing required field `system`"),
"stderr does not contain the expected output"
);
assert!(
stdout.is_empty(),
"stdout does not contain the exptected output"
);
Ok(())
}
#[test]
fn test_operation_build_with_deprecated_config_properties() -> Result<()> {
let system = "base16";
let scheme_name = "silk-light";
let tmp_dir = unique_tmp_dir("operation_build_with_deprecated_config_properties")?;
let template_theme_path = tmp_dir.join("template");
let template_templates_path = template_theme_path.join("templates");
let template_config_path = template_templates_path.join("config.yaml");
let schemes_path = tmp_dir.join("schemes");
let scheme_file_path = schemes_path.join(format!("{}.yaml", &scheme_name));
let template_mustache_path = template_templates_path.join("base16-template.mustache");
let themes_path = template_theme_path.join("output-themes");
let rendered_theme_path = themes_path.join(format!("{}-{}.md", &system, &scheme_name));
let base16_config_file_content = r"
base16-template:
output: output-themes
extension: .md";
let (_, scheme_file_content, template_file_content, base16_template_rendered_content_fixture) =
setup(system, scheme_name)?;
fs::create_dir_all(&template_templates_path)?;
fs::create_dir_all(&schemes_path)?;
write_to_file(&template_config_path, base16_config_file_content)?;
write_to_file(&template_mustache_path, &template_file_content)?;
write_to_file(&scheme_file_path, &scheme_file_content)?;
let (stdout, stderr) = run_command(&[
"build".to_string(),
template_theme_path.display().to_string(),
format!("--schemes-dir={}", schemes_path.display()),
])
.expect("Unable to run command");
let rendered_content = fs::read_to_string(rendered_theme_path)?;
assert_eq!(rendered_content, base16_template_rendered_content_fixture);
assert!(
stderr.is_empty(),
"stderr does not contain the expected output"
);
assert!(
stdout.contains(
"Warning: \"output\" is a deprecated config property, use \"filename\" instead."
),
"stdout does not contain the exptected output"
);
assert!(
stdout.contains(
"Warning: \"extension\" is a deprecated config property, use \"filename\" instead."
),
"stdout does not contain the exptected output"
);
Ok(())
}