From 8aebca5611cd7e604fee2c69758ab577dabb5116 Mon Sep 17 00:00:00 2001 From: Andriy Massimilla Date: Wed, 16 Oct 2024 11:37:41 -0400 Subject: [PATCH] Validate default values for slots --- cli/src/check.rs | 19 ++++++++++++++-- src/core/slot.rs | 24 ++++++++++++++++++++ tests/data/bad_default_slot_val/spackle.toml | 21 +++++++++++++++++ tests/data/bad_default_slot_val/test.j2 | 3 +++ 4 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 tests/data/bad_default_slot_val/spackle.toml create mode 100644 tests/data/bad_default_slot_val/test.j2 diff --git a/cli/src/check.rs b/cli/src/check.rs index 80f5033..36d3a5d 100644 --- a/cli/src/check.rs +++ b/cli/src/check.rs @@ -3,6 +3,7 @@ use std::{error::Error, path::PathBuf, process::exit, time::Instant}; use colored::Colorize; use spackle::core::{ config::Config, + slot, template::{self, ValidateError}, }; @@ -19,7 +20,7 @@ pub fn run(project_dir: &PathBuf, config: &Config) { match e { ValidateError::TeraError(e) => { eprintln!( - " {}\n {}\n", + "{}\n{}\n", "❌ Error validating template files".bright_red(), e.to_string().red() ); @@ -27,7 +28,7 @@ pub fn run(project_dir: &PathBuf, config: &Config) { ValidateError::RenderError(e) => { for (templ, e) in e { eprintln!( - " {}\n {}\n", + "{}\n{}\n", format!("❌ Template {} has errors", templ.bright_red().bold()) .bright_red(), e.source().map(|e| e.to_string()).unwrap_or_default().red() @@ -41,6 +42,20 @@ pub fn run(project_dir: &PathBuf, config: &Config) { } } + match slot::validate(&config.slots) { + Ok(()) => { + println!(" 👌 {}\n", "Slot data is valid".bright_green()); + } + Err(e) => { + eprintln!( + "{}\n{}\n", + "❌ Error validating slot configuration".bright_red(), + e.to_string().red() + ); + exit(1); + } + } + print_elapsed_time(start_time); } diff --git a/src/core/slot.rs b/src/core/slot.rs index 70ae6bd..d20c067 100644 --- a/src/core/slot.rs +++ b/src/core/slot.rs @@ -76,6 +76,30 @@ impl Slot { } } +pub fn validate(slots: &Vec) -> Result<(), Error> { + for slot in slots { + if let Some(default_value) = &slot.default { + match slot.r#type { + SlotType::String => { + // String always valid, no need to check + } + SlotType::Number => { + if default_value.parse::().is_err() { + return Err(Error::TypeMismatch(slot.key.clone(), "number".to_string())); + } + } + SlotType::Boolean => { + if default_value.parse::().is_err() { + return Err(Error::TypeMismatch(slot.key.clone(), "boolean".to_string())); + } + } + } + } + } + + Ok(()) +} + pub fn validate_data(data: &HashMap, slots: &Vec) -> Result<(), Error> { for entry in data.iter() { // Check if the data is assigned to a slot diff --git a/tests/data/bad_default_slot_val/spackle.toml b/tests/data/bad_default_slot_val/spackle.toml new file mode 100644 index 0000000..258ff10 --- /dev/null +++ b/tests/data/bad_default_slot_val/spackle.toml @@ -0,0 +1,21 @@ + +[[slots]] +key = "default_string" +type = "String" +name = "Default string" +description = "Default string" +default = "default" + +[[slots]] +key = "default_number" +type = "Number" +name = "Default number" +description = "Default number" +default = "notanumber" + +[[slots]] +key = "default_boolean" +type = "Boolean" +name = "Default boolean" +description = "Default boolean" +default = "invalid" diff --git a/tests/data/bad_default_slot_val/test.j2 b/tests/data/bad_default_slot_val/test.j2 new file mode 100644 index 0000000..5a4168e --- /dev/null +++ b/tests/data/bad_default_slot_val/test.j2 @@ -0,0 +1,3 @@ +{{ default_string }} +{{ default_number }} +{{ default_boolean }} \ No newline at end of file