Skip to content

Commit

Permalink
add test case invalid xml
Browse files Browse the repository at this point in the history
  • Loading branch information
JR-1991 committed Jan 13, 2025
1 parent 3972091 commit 2300db6
Show file tree
Hide file tree
Showing 3 changed files with 161 additions and 0 deletions.
107 changes: 107 additions & 0 deletions src/validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ use crate::{
datamodel::DataModel,
markdown::position::Position,
object::{Enumeration, Object},
xmltype::XMLType,
};
use colored::Colorize;
use log::error;
Expand Down Expand Up @@ -417,6 +418,17 @@ impl Validator {
for dtype in &attribute.dtypes {
self.check_attr_dtype(attribute, types, object, dtype);
}

if let Some(xml_option) = &attribute.xml {
match xml_option {
XMLType::Attribute { name, .. } => {
self.validate_xml_attribute_option(name, &object.name, &attribute.name);
}
XMLType::Element { name, .. } => {
self.validate_xml_element_option(name, &object.name, &attribute.name);
}
}
}
}

/// Checks the data type of attribute.
Expand Down Expand Up @@ -502,6 +514,101 @@ impl Validator {
}
}

/// Validates an XML element option string.
///
/// # Arguments
///
/// * `option` - The XML element option string to validate. Can contain multiple comma-separated values.
///
/// Checks that:
/// - The option string is not empty
/// - Each comma-separated value contains no special characters
fn validate_xml_element_option(
&mut self,
option: &str,
object_name: &str,
attribute_name: &str,
) {
let option = option.trim();
if option.is_empty() {
self.add_error(ValidationError {
message: "XML option is not defined.".into(),
object: Some(object_name.to_string()),
attribute: Some(attribute_name.to_string()),
location: "Global".into(),
error_type: ErrorType::GlobalError,
positions: vec![],
});
}

let options = option.split(',').map(|s| s.trim()).collect::<Vec<_>>();
for opt in options {
if contains_special_characters(opt.trim()).is_err() {
self.add_error(ValidationError {
message: format!("XML option '{}' contains special characters.", opt),
object: Some(object_name.to_string()),
attribute: Some(attribute_name.to_string()),
location: "Global".into(),
error_type: ErrorType::GlobalError,
positions: vec![],
});
}
}
}

/// Validates an XML attribute option string.
///
/// # Arguments
///
/// * `option` - The XML attribute option string to validate. Can contain multiple comma-separated values.
/// * `object_name` - The name of the object containing this attribute
/// * `attribute_name` - The name of the attribute being validated
///
/// Checks that:
/// - The option string is not empty
/// - Each comma-separated value contains no special characters
///
/// # Errors
///
/// Adds validation errors to the validator if:
/// - The option string is empty
/// - Any of the comma-separated values contain special characters
fn validate_xml_attribute_option(
&mut self,
option: &str,
object_name: &str,
attribute_name: &str,
) {
let option = option.trim();
if option.is_empty() {
self.add_error(ValidationError {
message: "XML attribute option is not defined.".into(),
object: Some(object_name.to_string()),
attribute: Some(attribute_name.to_string()),
location: "Global".into(),
error_type: ErrorType::GlobalError,
positions: vec![],
});
}

let options = option.split(',').map(|s| s.trim()).collect::<Vec<_>>();
for opt in options {
if contains_special_characters(opt).is_err() {
self.add_error(ValidationError {
message: format!(
"XML attribute option '{}' contains special characters.",
opt
),
object: Some(object_name.to_string()),
attribute: Some(attribute_name.to_string()),
location: "Global".into(),
error_type: ErrorType::GlobalError,
positions: vec![],
});
}
}
}

/// Extracts the type names from the data model.
///
/// # Arguments
Expand Down
37 changes: 37 additions & 0 deletions tests/data/model_invalid_xml_option.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
id-field: true
repo: "https://www.github.com/my/repo/"
prefix: "tst"
prefixes:
schema: http://schema.org/
nsmap:
tst: http://example.com/test/
---

### Test

- __empty_attribute__
- Type: string
- Term: schema:hello
- Description: The name of the test.
- XML: @
- __empty_element__
- Type: string
- Term: schema:hello
- Description: The name of the test.
- XML:
- __special_character_element__
- Type: string
- Term: schema:hello
- Description: The name of the test.
- XML: schema:hello
- __special_character_attribute__
- Type: string
- Term: schema:hello
- Description: The name of the test.
- XML: @schema:hello
- __multiple_types__
- Type: string, float
- Term: schema:hello
- Description: The name of the test.
- XML: fine, bad:
17 changes: 17 additions & 0 deletions tests/integration_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,23 @@ mod tests {
DataModel::from_markdown(path).expect("Could not parse markdown");
}

#[test]
fn test_invalid_xml_option() {
let path = Path::new("tests/data/model_invalid_xml_option.md");
let result = DataModel::from_markdown(path);

if let Err(e) = result {
assert_eq!(
e.errors.len(),
5,
"Expected 5 errors, got {}",
e.errors.len()
);
} else {
panic!("Expected error, but got success");
}
}

#[test]
fn test_multiple_types() {
let path = Path::new("tests/data/model_multiple_types.md");
Expand Down

0 comments on commit 2300db6

Please sign in to comment.