Skip to content

Commit

Permalink
Testing improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
DanielT committed Aug 16, 2024
1 parent 8a14be9 commit bbcef5c
Show file tree
Hide file tree
Showing 7 changed files with 260 additions and 22 deletions.
6 changes: 6 additions & 0 deletions autosar-data-specification/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -979,6 +979,10 @@ mod test {
AutosarVersion::from_str("AUTOSAR_00051.xsd").unwrap(),
AutosarVersion::Autosar_00051
);
assert_eq!(
AutosarVersion::from_str("AUTOSAR_00052.xsd").unwrap(),
AutosarVersion::Autosar_00052
);

// do all the version descriptions exist & make sense?
assert!(AutosarVersion::Autosar_4_0_1.describe().starts_with("AUTOSAR"));
Expand All @@ -1000,6 +1004,7 @@ mod test {
assert!(AutosarVersion::Autosar_00049.describe().starts_with("AUTOSAR"));
assert!(AutosarVersion::Autosar_00050.describe().starts_with("AUTOSAR"));
assert!(AutosarVersion::Autosar_00051.describe().starts_with("AUTOSAR"));
assert!(AutosarVersion::Autosar_00052.describe().starts_with("AUTOSAR"));

// do all the xsd file names exist?
assert!(AutosarVersion::Autosar_4_0_1.filename().ends_with(".xsd"));
Expand All @@ -1021,6 +1026,7 @@ mod test {
assert!(AutosarVersion::Autosar_00049.filename().ends_with(".xsd"));
assert!(AutosarVersion::Autosar_00050.filename().ends_with(".xsd"));
assert!(AutosarVersion::Autosar_00051.filename().ends_with(".xsd"));
assert!(AutosarVersion::Autosar_00052.filename().ends_with(".xsd"));

// to_string() should give the same result as describe()
assert_eq!(
Expand Down
73 changes: 55 additions & 18 deletions autosar-data/src/autosarmodel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,6 @@ impl AutosarModel {
///
/// # Errors
///
/// - [`AutosarDataError::IoErrorOpen`]: The file could not be opened
/// - [`AutosarDataError::IoErrorRead`]: There was an error while reading the file
/// - [`AutosarDataError::DuplicateFilenameError`]: The model already contains a file with this filename
/// - [`AutosarDataError::OverlappingDataError`]: The new data contains Autosar paths that are already defined by the existing data
Expand All @@ -457,23 +456,10 @@ impl AutosarModel {
strict: bool,
) -> Result<(ArxmlFile, Vec<AutosarDataError>), AutosarDataError> {
let filename_buf = filename.as_ref().to_path_buf();
let mut file = match File::open(filename) {
Ok(file) => file,
Err(error) => {
return Err(AutosarDataError::IoErrorOpen {
filename: filename_buf,
ioerror: error,
})
}
};

let filesize = file.metadata().unwrap().len();
let mut buffer = Vec::with_capacity(filesize as usize);
file.read_to_end(&mut buffer)
.map_err(|err| AutosarDataError::IoErrorRead {
filename: filename_buf.clone(),
ioerror: err,
})?;
let buffer = std::fs::read(&filename_buf).map_err(|err| AutosarDataError::IoErrorRead {
filename: filename_buf.clone(),
ioerror: err,
})?;

self.load_buffer(&buffer, &filename_buf, strict)
}
Expand Down Expand Up @@ -1208,6 +1194,42 @@ mod test {
let result = model.load_buffer(ERRFILE2, "test2", true);
let error = result.unwrap_err();
assert!(matches!(error, AutosarDataError::InvalidFileMerge { .. }));

// diverging files, where each file uses a different element from a Choice set.
// In this case the COMPU-SCALE in ERRFILE3 uses COMPU-CONST while ERRFILE4 uses COMPU-RATIONAL-COEFFS.
// This is not permitted, because the COMPU-SCALE can only contain one or the other.
const ERRFILE3: &[u8] = r#"<?xml version="1.0" encoding="utf-8"?>
<AUTOSAR xsi:schemaLocation="http://autosar.org/schema/r4.0 AUTOSAR_00050.xsd" xmlns="http://autosar.org/schema/r4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<AR-PACKAGES><AR-PACKAGE><SHORT-NAME>Package</SHORT-NAME>
<ELEMENTS>
<COMPU-METHOD><SHORT-NAME>compu</SHORT-NAME>
<COMPU-INTERNAL-TO-PHYS>
<COMPU-SCALES>
<COMPU-SCALE><COMPU-CONST></COMPU-CONST></COMPU-SCALE>
</COMPU-SCALES>
</COMPU-INTERNAL-TO-PHYS>
</COMPU-METHOD>
</ELEMENTS>
</AR-PACKAGE></AR-PACKAGES></AUTOSAR>"#.as_bytes();
const ERRFILE4: &[u8] = r#"<?xml version="1.0" encoding="utf-8"?>
<AUTOSAR xsi:schemaLocation="http://autosar.org/schema/r4.0 AUTOSAR_00050.xsd" xmlns="http://autosar.org/schema/r4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<AR-PACKAGES><AR-PACKAGE><SHORT-NAME>Package</SHORT-NAME>
<ELEMENTS>
<COMPU-METHOD><SHORT-NAME>compu</SHORT-NAME>
<COMPU-INTERNAL-TO-PHYS>
<COMPU-SCALES>
<COMPU-SCALE><COMPU-RATIONAL-COEFFS></COMPU-RATIONAL-COEFFS></COMPU-SCALE>
</COMPU-SCALES>
</COMPU-INTERNAL-TO-PHYS>
</COMPU-METHOD>
</ELEMENTS>
</AR-PACKAGE></AR-PACKAGES></AUTOSAR>"#.as_bytes();
let model = AutosarModel::new();
let result = model.load_buffer(ERRFILE3, "test3", true);
assert!(result.is_ok());
let result = model.load_buffer(ERRFILE4, "test4", true);
let error = result.unwrap_err();
assert!(matches!(error, AutosarDataError::InvalidFileMerge { .. }));
}

#[test]
Expand Down Expand Up @@ -1415,7 +1437,22 @@ mod test {
#[test]
fn write() {
let model = AutosarModel::default();
// write an empty model, it does nothing since there are no files
model.write().unwrap();

let dir = tempdir().unwrap();
let filename = dir.path().with_file_name("new.arxml");
model.create_file(&filename, AutosarVersion::LATEST).unwrap();
model.write().unwrap();
assert!(filename.exists());

let filename = PathBuf::from("nonexistent/dir/some_file.arxml");
let model = AutosarModel::default();
// creating an ArxmlFile with a non-existent directory is not an error
model.create_file(&filename, AutosarVersion::LATEST).unwrap();
// the write operation will fail, because the directory does not exist
let result = model.write();
assert!(result.is_err());
}

#[test]
Expand Down
64 changes: 64 additions & 0 deletions autosar-data/src/chardata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,14 @@ mod test {
let data = CharacterData::String("-55".to_string());
let result = data.parse_integer::<i32>().unwrap();
assert_eq!(result, -55);

let data = CharacterData::UnsignedInteger(0);
let result = data.parse_integer::<u32>().unwrap();
assert_eq!(result, 0);

let data = CharacterData::Float(0.0);
let result = data.parse_integer::<u32>();
assert!(result.is_none());
}

#[test]
Expand All @@ -635,6 +643,11 @@ mod test {
let result = data.parse_float();
assert!(result.is_none());

// zero
let data = CharacterData::String("0".to_string());
let result = data.parse_float().unwrap();
assert_eq!(result, 0.0);

// hex (> 32 bits)
let data = CharacterData::String("0xFFFFFFFFF".to_string());
let result = data.parse_float().unwrap();
Expand Down Expand Up @@ -694,6 +707,57 @@ mod test {
let data = CharacterData::String("0777".to_string());
let result = data.parse_float().unwrap();
assert_eq!(result, 511.0);

// integer value
let data = CharacterData::UnsignedInteger(0);
let result = data.parse_float().unwrap();
assert_eq!(result, 0.0);

// float value
let data = CharacterData::Float(5.0);
let result = data.parse_float().unwrap();
assert_eq!(result, 5.0);

// enum value
let data = CharacterData::Enum(EnumItem::Abstract);
let result = data.parse_float();
assert!(result.is_none());
}

#[test]
fn ordering() {
let enum1 = CharacterData::Enum(EnumItem::Abstract);
let enum2 = CharacterData::Enum(EnumItem::default);
assert!(enum1 < enum2);

let string1 = CharacterData::String("abcdef".to_string());
let string2 = CharacterData::String("text".to_string());
assert!(string1 < string2);

let integer1 = CharacterData::UnsignedInteger(123);
let integer2 = CharacterData::UnsignedInteger(456);
assert!(integer1 < integer2);

let float1 = CharacterData::Float(1.23);
let float2 = CharacterData::Float(4.56);
assert!(float1 < float2);

// for unequal data types, the order is (arbitrarily) defined as enum < string < unsigned integer < float
assert!(enum1 < string1);
assert!(enum1 < integer1);
assert!(enum1 < float1);
assert!(string1 > enum1);
assert!(string1 < integer1);
assert!(string1 < float1);
assert!(integer1 > enum1);
assert!(integer1 > string1);
assert!(integer1 < float1);
assert!(float1 > enum1);
assert!(float1 > string1);
assert!(float1 > integer1);

// PartialOrd
assert!(enum1.partial_cmp(&enum2).unwrap() == std::cmp::Ordering::Less);
}

#[test]
Expand Down
43 changes: 39 additions & 4 deletions autosar-data/src/element.rs
Original file line number Diff line number Diff line change
Expand Up @@ -878,7 +878,12 @@ impl Element {
/// The operation was aborted to avoid a deadlock, but can be retried.
/// - [`AutosarDataError::IncorrectContentType`]: Cannot set character data on an element which does not contain character data
pub fn set_character_data<T: Into<CharacterData>>(&self, value: T) -> Result<(), AutosarDataError> {
let mut chardata: CharacterData = value.into();
let chardata: CharacterData = value.into();
self.set_character_data_internal(chardata)
}

// internal function to set the character data - separated out since it doesn't need to be generic
fn set_character_data_internal(&self, mut chardata: CharacterData) -> Result<(), AutosarDataError> {
let elemtype = self.elemtype();
if elemtype.content_mode() == ContentMode::Characters || elemtype.content_mode() == ContentMode::Mixed {
if let Some(cdata_spec) = elemtype.chardata_spec() {
Expand Down Expand Up @@ -2149,9 +2154,6 @@ impl Element {
/// - [`AutosarDataError::NoFilesInModel`]: The operation cannot be completed because the model does not contain any files
pub fn min_version(&self) -> Result<AutosarVersion, AutosarDataError> {
let (_, files) = self.file_membership()?;
if files.is_empty() {
return Err(AutosarDataError::NoFilesInModel);
}
let mut ver = AutosarVersion::LATEST;
for f in files.iter().filter_map(WeakArxmlFile::upgrade) {
if f.version() < ver {
Expand Down Expand Up @@ -2562,6 +2564,13 @@ mod test {

let named_parent = el_system.named_parent().unwrap().unwrap();
assert_eq!(named_parent, el_ar_package);

let named_parent = el_autosar.named_parent().unwrap();
assert!(named_parent.is_none());

// trying to get the named parent of a removed element should fail
el_autosar.remove_sub_element(el_ar_packages).unwrap();
assert!(el_ar_package.named_parent().is_err());
}

#[test]
Expand Down Expand Up @@ -3443,6 +3452,7 @@ mod test {
#[test]
fn serialize() {
const FILEBUF: &str = r#"<?xml version="1.0" encoding="utf-8"?>
<!--comment-->
<AUTOSAR xsi:schemaLocation="http://autosar.org/schema/r4.0 AUTOSAR_00050.xsd" xmlns="http://autosar.org/schema/r4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<AR-PACKAGES>
<AR-PACKAGE>
Expand All @@ -3459,6 +3469,7 @@ mod test {
.unwrap();
model.files().next().unwrap();
let el_autosar = model.root_element();
el_autosar.set_comment(Some("comment".to_string()));

let mut outstring = String::from(r#"<?xml version="1.0" encoding="utf-8"?>"#);
el_autosar.serialize_internal(&mut outstring, 0, false, &None);
Expand Down Expand Up @@ -3800,6 +3811,28 @@ mod test {
assert!(el_ar_package.remove_from_file(&file2).is_err());
}

#[test]
fn comment() {
let model = AutosarModel::new();
model.create_file("test", AutosarVersion::LATEST).unwrap();
let el_autosar = model.root_element();

// initially there is no comment
assert!(el_autosar.comment().is_none());

// set and get a comment
el_autosar.set_comment(Some("comment".to_string()));
assert_eq!(el_autosar.comment().unwrap(), "comment");

// set a new comment containing "--" which is a forbidden sequence in XML comments
el_autosar.set_comment(Some("comment--".to_string()));
assert_eq!(el_autosar.comment().unwrap(), "comment__");

// remove the comment
el_autosar.set_comment(None);
assert!(el_autosar.comment().is_none());
}

#[test]
fn min_version() {
let model = AutosarModel::new();
Expand Down Expand Up @@ -3850,10 +3883,12 @@ mod test {
let ec_elem = ElementContent::Element(model.root_element());
assert_eq!(format!("{:?}", model.root_element()), format!("{ec_elem:?}"));
assert_eq!(ec_elem.unwrap_element(), Some(model.root_element()));
assert!(ec_elem.unwrap_cdata().is_none());
let cdata = CharacterData::String("test".to_string());
let ec_chars = ElementContent::CharacterData(cdata.clone());
assert_eq!(format!("{cdata:?}"), format!("{ec_chars:?}"));
assert_eq!(ec_chars.unwrap_cdata(), Some(cdata));
assert!(ec_chars.unwrap_element().is_none());
}

#[test]
Expand Down
5 changes: 5 additions & 0 deletions autosar-data/src/elementraw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1126,6 +1126,11 @@ impl ElementRaw {
version: AutosarVersion,
) -> Result<(), AutosarDataError> {
let chardata: CharacterData = value.into();
self.set_character_data_internal(chardata, version)
}

// set the character data of this element - separated out since this part is not generic
fn set_character_data_internal(&mut self, chardata: CharacterData, version: AutosarVersion) -> Result<(), AutosarDataError> {
if self.elemtype.content_mode() == ContentMode::Characters
|| (self.elemtype.content_mode() == ContentMode::Mixed && self.content.len() <= 1)
{
Expand Down
24 changes: 24 additions & 0 deletions autosar-data/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -520,4 +520,28 @@ mod test {

assert!(check_buffer(header.as_bytes()));
}

#[test]
fn attribute_order() {
// attribute ordering: first by name, then by value
let a1 = Attribute {
attrname: AttributeName::Uuid,
content: CharacterData::String("Value1".to_string()),
};

let a2 = Attribute {
attrname: AttributeName::Uuid,
content: CharacterData::String("Value2".to_string()),
};
assert!(a1 < a2);

let a3 = Attribute {
attrname: AttributeName::T,
content: CharacterData::String("xyz".to_string()),
};
assert!(a3 < a1);

// PartialOrd
assert!(a1.partial_cmp(&a2) == Some(std::cmp::Ordering::Less));
}
}
Loading

0 comments on commit bbcef5c

Please sign in to comment.