diff --git a/src/lib.rs b/src/lib.rs index e85eb2d..a1a0496 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,6 +8,9 @@ use serde::{Deserialize, Serialize}; pub mod parser; +#[cfg(test)] +mod parser_tests; + /// Re-export of `encoding_rs` as encodings to simplify usage #[cfg(feature = "encodings")] pub use encoding_rs as encodings; @@ -188,8 +191,8 @@ pub enum AttributeValueType { #[derive(Clone, Debug, PartialEq, Getters, Serialize, Deserialize)] pub struct ValDescription { - id: f64, - description: String, + pub id: f64, + pub description: String, } // FIXME: not used! @@ -544,225 +547,3 @@ impl<'a> TryFrom<&'a str> for Dbc { Ok(dbc) } } - -#[cfg(test)] -mod tests { - - use super::*; - - const SAMPLE_DBC: &str = r#" -VERSION "0.1" -NS_ : - NS_DESC_ - CM_ - BA_DEF_ - BA_ - VAL_ - CAT_DEF_ - CAT_ - FILTER - BA_DEF_DEF_ - EV_DATA_ - ENVVAR_DATA_ - SGTYPE_ - SGTYPE_VAL_ - BA_DEF_SGTYPE_ - BA_SGTYPE_ - SIG_TYPE_REF_ - VAL_TABLE_ - SIG_GROUP_ - SIG_VALTYPE_ - SIGTYPE_VALTYPE_ - BO_TX_BU_ - BA_DEF_REL_ - BA_REL_ - BA_DEF_DEF_REL_ - BU_SG_REL_ - BU_EV_REL_ - BU_BO_REL_ - SG_MUL_VAL_ -BS_: -BU_: PC -BO_ 2000 WebData_2000: 4 Vector__XXX - SG_ Signal_8 : 24|8@1+ (1,0) [0|255] "" Vector__XXX - SG_ Signal_7 : 16|8@1+ (1,0) [0|255] "" Vector__XXX - SG_ Signal_6 : 8|8@1+ (1,0) [0|255] "" Vector__XXX - SG_ Signal_5 : 0|8@1+ (1,0) [0|255] "" Vector__XXX -BO_ 1840 WebData_1840: 4 PC - SG_ Signal_4 : 24|8@1+ (1,0) [0|255] "" Vector__XXX - SG_ Signal_3 : 16|8@1+ (1,0) [0|255] "" Vector__XXX - SG_ Signal_2 : 8|8@1+ (1,0) [0|255] "" Vector__XXX - SG_ Signal_1 : 0|8@1+ (1,0) [0|0] "" Vector__XXX - -BO_ 3040 WebData_3040: 8 Vector__XXX - SG_ Signal_6 m2 : 0|4@1+ (1,0) [0|15] "" Vector__XXX - SG_ Signal_5 m3 : 16|8@1+ (1,0) [0|255] "kmh" Vector__XXX - SG_ Signal_4 m3 : 8|8@1+ (1,0) [0|255] "" Vector__XXX - SG_ Signal_3 m3 : 0|4@1+ (1,0) [0|3] "" Vector__XXX - SG_ Signal_2 m1 : 3|12@0+ (1,0) [0|4095] "Byte" Vector__XXX - SG_ Signal_1 m0 : 0|4@1+ (1,0) [0|7] "Byte" Vector__XXX - SG_ Switch M : 4|4@1+ (1,0) [0|3] "" Vector__XXX - -EV_ Environment1: 0 [0|220] "" 0 6 DUMMY_NODE_VECTOR0 DUMMY_NODE_VECTOR2; -EV_ Environment2: 0 [0|177] "" 0 7 DUMMY_NODE_VECTOR1 DUMMY_NODE_VECTOR2; -ENVVAR_DATA_ SomeEnvVarData: 399; - -CM_ BO_ 1840 "Some Message comment"; -CM_ SG_ 1840 Signal_4 "asaklfjlsdfjlsdfgls -HH?=(%)/&KKDKFSDKFKDFKSDFKSDFNKCnvsdcvsvxkcv"; -CM_ SG_ 5 TestSigLittleUnsigned1 "asaklfjlsdfjlsdfgls -=0943503450KFSDKFKDFKSDFKSDFNKCnvsdcvsvxkcv"; - -BA_DEF_DEF_ "BusType" "AS"; - -BA_ "Attr" BO_ 4358435 283; -BA_ "Attr" BO_ 56949545 344; - -VAL_ 2000 Signal_3 255 "NOP"; - -SIG_VALTYPE_ 2000 Signal_8 : 1; -"#; - - #[test] - fn dbc_definition_test() { - match Dbc::try_from(SAMPLE_DBC) { - Ok(dbc_content) => println!("DBC Content{dbc_content:#?}"), - Err(e) => { - match e { - Error::Nom(nom::Err::Incomplete(needed)) => { - eprintln!("Error incomplete input, needed: {needed:?}"); - } - Error::Nom(nom::Err::Error(error)) => { - eprintln!("Nom Error: {error:?}"); - } - Error::Nom(nom::Err::Failure(ctx)) => eprintln!("Failure {ctx:?}"), - Error::Incomplete(dbc, remaining) => eprintln!( - "Not all data in buffer was read {dbc:#?}, remaining unparsed: {remaining}", - ), - Error::MultipleMultiplexors => eprintln!("Multiple multiplexors defined"), - } - panic!("Failed to read DBC"); - } - } - } - - #[test] - fn lookup_signal_comment() { - let dbc_content = Dbc::try_from(SAMPLE_DBC).expect("Failed to parse DBC"); - let comment = dbc_content - .signal_comment(MessageId::Standard(1840), "Signal_4") - .expect("Signal comment missing"); - assert_eq!( - "asaklfjlsdfjlsdfgls\nHH?=(%)/&KKDKFSDKFKDFKSDFKSDFNKCnvsdcvsvxkcv", - comment - ); - } - - #[test] - fn lookup_signal_comment_none_when_missing() { - let dbc_content = Dbc::try_from(SAMPLE_DBC).expect("Failed to parse DBC"); - let comment = dbc_content.signal_comment(MessageId::Standard(1840), "Signal_2"); - assert_eq!(None, comment); - } - - #[test] - fn lookup_message_comment() { - let dbc_content = Dbc::try_from(SAMPLE_DBC).expect("Failed to parse DBC"); - let comment = dbc_content - .message_comment(MessageId::Standard(1840)) - .expect("Message comment missing"); - assert_eq!("Some Message comment", comment); - } - - #[test] - fn lookup_message_comment_none_when_missing() { - let dbc_content = Dbc::try_from(SAMPLE_DBC).expect("Failed to parse DBC"); - let comment = dbc_content.message_comment(MessageId::Standard(2000)); - assert_eq!(None, comment); - } - - #[test] - fn lookup_value_descriptions_for_signal() { - let dbc_content = Dbc::try_from(SAMPLE_DBC).expect("Failed to parse DBC"); - let val_descriptions = dbc_content - .value_descriptions_for_signal(MessageId::Standard(2000), "Signal_3") - .expect("Message comment missing"); - - let exp = vec![ValDescription { - id: 255.0, - description: "NOP".to_string(), - }]; - assert_eq!(exp, val_descriptions); - } - - #[test] - fn lookup_value_descriptions_for_signal_none_when_missing() { - let dbc_content = Dbc::try_from(SAMPLE_DBC).expect("Failed to parse DBC"); - let val_descriptions = - dbc_content.value_descriptions_for_signal(MessageId::Standard(2000), "Signal_2"); - assert_eq!(None, val_descriptions); - } - - #[test] - fn lookup_extended_value_type_for_signal() { - let dbc_content = Dbc::try_from(SAMPLE_DBC).expect("Failed to parse DBC"); - let extended_value_type = - dbc_content.extended_value_type_for_signal(MessageId::Standard(2000), "Signal_8"); - assert_eq!( - extended_value_type, - Some(&SignalExtendedValueType::IEEEfloat32Bit) - ); - } - - #[test] - fn lookup_extended_value_type_for_signal_none_when_missing() { - let dbc_content = Dbc::try_from(SAMPLE_DBC).expect("Failed to parse DBC"); - let extended_value_type = - dbc_content.extended_value_type_for_signal(MessageId::Standard(2000), "Signal_1"); - assert_eq!(extended_value_type, None); - } - - #[test] - fn lookup_signal_by_name() { - let dbc_content = Dbc::try_from(SAMPLE_DBC).expect("Failed to parse DBC"); - let signal = dbc_content.signal_by_name(MessageId::Standard(2000), "Signal_8"); - assert!(signal.is_some()); - } - - #[test] - fn lookup_signal_by_name_none_when_missing() { - let dbc_content = Dbc::try_from(SAMPLE_DBC).expect("Failed to parse DBC"); - let signal = dbc_content.signal_by_name(MessageId::Standard(2000), "Signal_25"); - assert_eq!(signal, None); - } - - #[test] - fn lookup_multiplex_indicator_switch() { - let dbc_content = Dbc::try_from(SAMPLE_DBC).expect("Failed to parse DBC"); - let multiplexor_switch = dbc_content.message_multiplexor_switch(MessageId::Standard(3040)); - assert!(multiplexor_switch.is_ok()); - assert!(multiplexor_switch.as_ref().unwrap().is_some()); - assert_eq!(multiplexor_switch.unwrap().unwrap().name(), "Switch"); - } - - #[test] - fn lookup_multiplex_indicator_switch_none_when_missing() { - let dbc_content = Dbc::try_from(SAMPLE_DBC).expect("Failed to parse DBC"); - let multiplexor_switch = dbc_content.message_multiplexor_switch(MessageId::Standard(1840)); - assert!(multiplexor_switch.unwrap().is_none()); - } - - #[test] - fn extended_message_id_raw() { - let message_id = MessageId::Extended(2); - assert_eq!(message_id.raw(), 2 | 1 << 31); - let message_id = MessageId::Extended(2 ^ 29); - assert_eq!(message_id.raw(), 2 ^ 29 | 1 << 31); - } - - #[test] - fn standard_message_id_raw() { - let message_id = MessageId::Standard(2); - assert_eq!(message_id.raw(), 2); - } -} diff --git a/src/parser.rs b/src/parser.rs index 4f3e678..ed69d62 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -119,17 +119,17 @@ fn brk_close(s: &str) -> IResult<&str, char> { /// A valid `C_identifier`. `C_identifier`s start with an alpha character or an underscore /// and may further consist of alphanumeric characters and underscore -fn c_ident(s: &str) -> IResult<&str, String> { +pub(crate) fn c_ident(s: &str) -> IResult<&str, String> { let (s, head) = take_while1(is_c_ident_head).parse(s)?; let (s, remaining) = take_while(is_c_string_char).parse(s)?; Ok((s, [head, remaining].concat())) } -fn c_ident_vec(s: &str) -> IResult<&str, Vec> { +pub(crate) fn c_ident_vec(s: &str) -> IResult<&str, Vec> { separated_list0(comma, c_ident).parse(s) } -fn char_string(s: &str) -> IResult<&str, &str> { +pub(crate) fn char_string(s: &str) -> IResult<&str, &str> { let (s, _) = quote(s)?; let (s, optional_char_string_value) = opt(escaped( take_till1(is_quote_or_escape_character), @@ -151,11 +151,11 @@ fn big_endian(s: &str) -> IResult<&str, ByteOrder> { map(char('0'), |_| ByteOrder::BigEndian).parse(s) } -fn byte_order(s: &str) -> IResult<&str, ByteOrder> { +pub(crate) fn byte_order(s: &str) -> IResult<&str, ByteOrder> { alt((little_endian, big_endian)).parse(s) } -fn message_id(s: &str) -> IResult<&str, MessageId> { +pub(crate) fn message_id(s: &str) -> IResult<&str, MessageId> { let (s, parsed_value) = complete::u32(s)?; if parsed_value & (1 << 31) != 0 { @@ -175,7 +175,7 @@ fn unsigned(s: &str) -> IResult<&str, ValueType> { map(char('+'), |_| ValueType::Unsigned).parse(s) } -fn value_type(s: &str) -> IResult<&str, ValueType> { +pub(crate) fn value_type(s: &str) -> IResult<&str, ValueType> { alt((signed, unsigned)).parse(s) } @@ -208,11 +208,11 @@ fn plain(s: &str) -> IResult<&str, MultiplexIndicator> { Ok((s, MultiplexIndicator::Plain)) } -fn multiplexer_indicator(s: &str) -> IResult<&str, MultiplexIndicator> { +pub(crate) fn multiplexer_indicator(s: &str) -> IResult<&str, MultiplexIndicator> { alt((multiplexer, multiplexor, multiplexor_and_multiplexed, plain)).parse(s) } -fn version(s: &str) -> IResult<&str, Version> { +pub(crate) fn version(s: &str) -> IResult<&str, Version> { let (s, _) = multispace0(s)?; let (s, _) = tag("VERSION").parse(s)?; let (s, _) = ms1(s)?; @@ -232,7 +232,7 @@ fn bit_timing(s: &str) -> IResult<&str, Vec> { Ok((s, baudrates.unwrap_or_default())) } -fn signal(s: &str) -> IResult<&str, Signal> { +pub(crate) fn signal(s: &str) -> IResult<&str, Signal> { let (s, _) = multispace0(s)?; let (s, _) = tag("SG_").parse(s)?; let (s, _) = ms1(s)?; @@ -282,7 +282,7 @@ fn signal(s: &str) -> IResult<&str, Signal> { )) } -fn message(s: &str) -> IResult<&str, Message> { +pub(crate) fn message(s: &str) -> IResult<&str, Message> { let (s, _) = multispace0(s)?; let (s, _) = tag("BO_").parse(s)?; let (s, _) = ms1(s)?; @@ -307,7 +307,7 @@ fn message(s: &str) -> IResult<&str, Message> { )) } -fn attribute_default(s: &str) -> IResult<&str, AttributeDefault> { +pub(crate) fn attribute_default(s: &str) -> IResult<&str, AttributeDefault> { let (s, _) = multispace0(s)?; let (s, _) = tag("BA_DEF_DEF_").parse(s)?; let (s, _) = ms1(s)?; @@ -402,7 +402,7 @@ fn comment_plain(s: &str) -> IResult<&str, Comment> { )) } -fn comment(s: &str) -> IResult<&str, Comment> { +pub(crate) fn comment(s: &str) -> IResult<&str, Comment> { let (s, _) = multispace0(s)?; let (s, _) = tag("CM_").parse(s)?; let (s, _) = ms1(s)?; @@ -419,7 +419,7 @@ fn comment(s: &str) -> IResult<&str, Comment> { Ok((s, comment)) } -fn value_description(s: &str) -> IResult<&str, ValDescription> { +pub(crate) fn value_description(s: &str) -> IResult<&str, ValDescription> { let (s, a) = double(s)?; let (s, _) = ms1(s)?; let (s, b) = char_string(s)?; @@ -473,7 +473,7 @@ fn value_description_for_env_var(s: &str) -> IResult<&str, ValueDescription> { )) } -fn value_descriptions(s: &str) -> IResult<&str, ValueDescription> { +pub(crate) fn value_descriptions(s: &str) -> IResult<&str, ValueDescription> { let (s, _) = multispace0(s)?; let (s, vd) = alt((value_description_for_signal, value_description_for_env_var)).parse(s)?; let (s, _) = line_ending(s)?; @@ -536,7 +536,7 @@ fn access_node(s: &str) -> IResult<&str, AccessNode> { } /// Environment Variable Definitions -fn environment_variable(s: &str) -> IResult<&str, EnvironmentVariable> { +pub(crate) fn environment_variable(s: &str) -> IResult<&str, EnvironmentVariable> { let (s, _) = multispace0(s)?; let (s, _) = tag("EV_").parse(s)?; let (s, _) = ms1(s)?; @@ -578,7 +578,7 @@ fn environment_variable(s: &str) -> IResult<&str, EnvironmentVariable> { )) } -fn environment_variable_data(s: &str) -> IResult<&str, EnvironmentVariableData> { +pub(crate) fn environment_variable_data(s: &str) -> IResult<&str, EnvironmentVariableData> { let (s, _) = multispace0(s)?; let (s, _) = tag("ENVVAR_DATA_").parse(s)?; let (s, _) = ms1(s)?; @@ -597,7 +597,7 @@ fn environment_variable_data(s: &str) -> IResult<&str, EnvironmentVariableData> )) } -fn signal_type(s: &str) -> IResult<&str, SignalType> { +pub(crate) fn signal_type(s: &str) -> IResult<&str, SignalType> { let (s, _) = multispace0(s)?; let (s, _) = tag("SGTYPE_").parse(s)?; let (s, _) = ms1(s)?; @@ -664,7 +664,7 @@ fn attribute_value_charstr(s: &str) -> IResult<&str, AttributeValue> { map(char_string, |x| AttributeValue::String(x.to_string())).parse(s) } -fn attribute_value(s: &str) -> IResult<&str, AttributeValue> { +pub(crate) fn attribute_value(s: &str) -> IResult<&str, AttributeValue> { alt(( // attribute_value_uint64, // attribute_value_int64, @@ -728,7 +728,7 @@ fn raw_attribute_value(s: &str) -> IResult<&str, AttributeValuedForObjectType> { map(attribute_value, AttributeValuedForObjectType::Raw).parse(s) } -fn attribute_value_for_object(s: &str) -> IResult<&str, AttributeValueForObject> { +pub(crate) fn attribute_value_for_object(s: &str) -> IResult<&str, AttributeValueForObject> { let (s, _) = multispace0(s)?; let (s, _) = tag("BA_").parse(s)?; let (s, _) = ms1(s)?; @@ -794,7 +794,7 @@ fn attribute_definition_plain(s: &str) -> IResult<&str, AttributeDefinition> { Ok((s, AttributeDefinition::Plain(plain.to_string()))) } -fn attribute_definition(s: &str) -> IResult<&str, AttributeDefinition> { +pub(crate) fn attribute_definition(s: &str) -> IResult<&str, AttributeDefinition> { let (s, _) = multispace0(s)?; let (s, _) = tag("BA_DEF_").parse(s)?; let (s, _) = ms1(s)?; @@ -819,7 +819,7 @@ fn symbol(s: &str) -> IResult<&str, Symbol> { Ok((s, Symbol(symbol))) } -fn new_symbols(s: &str) -> IResult<&str, Vec> { +pub(crate) fn new_symbols(s: &str) -> IResult<&str, Vec> { let (s, _) = multispace0(s)?; let (s, _) = tag("NS_ :").parse(s)?; let (s, _) = space0(s)?; @@ -829,7 +829,7 @@ fn new_symbols(s: &str) -> IResult<&str, Vec> { } /// Network node -fn node(s: &str) -> IResult<&str, Node> { +pub(crate) fn node(s: &str) -> IResult<&str, Node> { let (s, _) = multispace0(s)?; let (s, _) = tag("BU_:").parse(s)?; let (s, li) = opt(preceded(ms1, separated_list0(ms1, c_ident))).parse(s)?; @@ -861,7 +861,7 @@ fn signal_type_ref(s: &str) -> IResult<&str, SignalTypeRef> { )) } -fn value_table(s: &str) -> IResult<&str, ValueTable> { +pub(crate) fn value_table(s: &str) -> IResult<&str, ValueTable> { let (s, _) = multispace0(s)?; let (s, _) = tag("VAL_TABLE_").parse(s)?; let (s, _) = ms1(s)?; @@ -892,7 +892,7 @@ fn extended_multiplex_mapping(s: &str) -> IResult<&str, ExtendedMultiplexMapping )) } -fn extended_multiplex(s: &str) -> IResult<&str, ExtendedMultiplex> { +pub(crate) fn extended_multiplex(s: &str) -> IResult<&str, ExtendedMultiplex> { let (s, _) = multispace0(s)?; let (s, _) = tag("SG_MUL_VAL_").parse(s)?; let (s, _) = ms1(s)?; @@ -935,7 +935,9 @@ fn signal_extended_value_type(s: &str) -> IResult<&str, SignalExtendedValueType> .parse(s) } -fn signal_extended_value_type_list(s: &str) -> IResult<&str, SignalExtendedValueTypeList> { +pub(crate) fn signal_extended_value_type_list( + s: &str, +) -> IResult<&str, SignalExtendedValueTypeList> { let (s, _) = multispace0(s)?; let (s, _) = tag("SIG_VALTYPE_").parse(s)?; let (s, _) = ms1(s)?; @@ -974,7 +976,7 @@ fn message_transmitters(s: &str) -> IResult<&str, Vec> { separated_list0(comma, transmitter).parse(s) } -fn message_transmitter(s: &str) -> IResult<&str, MessageTransmitter> { +pub(crate) fn message_transmitter(s: &str) -> IResult<&str, MessageTransmitter> { let (s, _) = multispace0(s)?; let (s, _) = tag("BO_TX_BU_").parse(s)?; let (s, _) = ms1(s)?; @@ -994,7 +996,7 @@ fn message_transmitter(s: &str) -> IResult<&str, MessageTransmitter> { )) } -fn signal_groups(s: &str) -> IResult<&str, SignalGroups> { +pub(crate) fn signal_groups(s: &str) -> IResult<&str, SignalGroups> { let (s, _) = multispace0(s)?; let (s, _) = tag("SIG_GROUP_").parse(s)?; let (s, _) = ms1(s)?; @@ -1092,658 +1094,3 @@ pub fn dbc(s: &str) -> IResult<&str, Dbc> { }, )) } - -#[cfg(test)] -#[allow(clippy::needless_raw_string_hashes)] -mod tests { - use super::*; - - #[test] - fn c_ident_test() { - let def = "EALL_DUSasb18 "; - let (_, val) = c_ident(def).unwrap(); - assert_eq!(val, "EALL_DUSasb18"); - - let def = "_EALL_DUSasb18 "; - let (_, val) = c_ident(def).unwrap(); - assert_eq!(val, "_EALL_DUSasb18"); - - // identifiers must not start with digits - let def = "3EALL_DUSasb18 "; - assert!(c_ident(def).is_err()); - } - - #[test] - fn c_ident_vec_test() { - let def = "FZHL_DUSasb18 "; - let (_, val) = c_ident_vec(def).unwrap(); - assert_eq!(val, vec!("FZHL_DUSasb18".to_string())); - - let def = "FZHL_DUSasb19,xkask_3298 "; - let (_, val) = c_ident_vec(def).unwrap(); - assert_eq!( - val, - vec!["FZHL_DUSasb19".to_string(), "xkask_3298".to_string()], - ); - } - - #[test] - fn char_string_test() { - let def = "\"ab\x00\x7f\""; - let (_, val) = char_string(def).unwrap(); - assert_eq!(val, "ab\x00\x7f"); - } - - #[test] - fn signal_test() { - let def = r#" -SG_ NAME : 3|2@1- (1,0) [0|0] "x" UFA -"#; - let _signal = signal(def.trim_start()).unwrap(); - } - - #[test] - fn byte_order_test() { - let (_, val) = byte_order("0").expect("parse big endian"); - assert_eq!(val, ByteOrder::BigEndian); - - let (_, val) = byte_order("1").expect("parse little endian"); - assert_eq!(val, ByteOrder::LittleEndian); - } - - #[test] - fn multiplexer_indicator_test() { - let (_, val) = multiplexer_indicator(" m34920 eol").expect("parse multiplexer"); - assert_eq!(val, MultiplexIndicator::MultiplexedSignal(34920)); - - let (_, val) = multiplexer_indicator(" M eol").expect("parse multiplexor"); - assert_eq!(val, MultiplexIndicator::Multiplexor); - - let (_, val) = multiplexer_indicator(" eol").expect("parse plain"); - assert_eq!(val, MultiplexIndicator::Plain); - - let (_, val) = multiplexer_indicator(" m8M eol").expect("parse multiplexer"); - assert_eq!(val, MultiplexIndicator::MultiplexorAndMultiplexedSignal(8)); - } - - #[test] - fn value_type_test() { - let (_, val) = value_type("- ").expect("parse value type"); - assert_eq!(ValueType::Signed, val); - - let (_, val) = value_type("+ ").expect("parse value type"); - assert_eq!(ValueType::Unsigned, val); - } - - #[test] - fn message_definition_test() { - signal("\r\n\r\nSG_ BasL2 : 3|2@0- (1,0) [0|0] \"x\" DFA_FUS\r\n").expect("Failed"); - - let def = r#" -BO_ 1 MCA_A1: 6 MFA -SG_ ABC_1 : 9|2@1+ (1,0) [0|0] "x" XYZ_OUS -SG_ BasL2 : 3|2@0- (1,0) [0|0] "x" DFA_FUS - x"#; - let (_, _val) = message(def.trim_start()).expect("parse message definition"); - } - - #[test] - fn signal_comment_test() { - let def = r#" -CM_ SG_ 193 KLU_R_X "This is a signal comment test"; -"#; - let exp = Comment::Signal { - message_id: MessageId::Standard(193), - name: "KLU_R_X".to_string(), - comment: "This is a signal comment test".to_string(), - }; - let (_, val) = comment(def.trim_start()).expect("parse signal comment definition"); - assert_eq!(val, exp); - } - - #[test] - fn message_definition_comment_test() { - let def = r#" -CM_ BO_ 34544 "Some Message comment"; -"#; - let exp = Comment::Message { - id: MessageId::Standard(34544), - comment: "Some Message comment".to_string(), - }; - let (_, val) = - comment(def.trim_start()).expect("parse message definition comment definition"); - assert_eq!(val, exp); - } - - #[test] - fn node_comment_test() { - let def = r#" -CM_ BU_ network_node "Some network node comment"; -"#; - let exp = Comment::Node { - name: "network_node".to_string(), - comment: "Some network node comment".to_string(), - }; - let (_, val) = comment(def.trim_start()).expect("parse node comment definition"); - assert_eq!(val, exp); - } - - #[test] - fn env_var_comment_test() { - let def = r#" -CM_ EV_ ENVXYZ "Some env var name comment"; -"#; - let exp = Comment::EnvVar { - name: "ENVXYZ".to_string(), - comment: "Some env var name comment".to_string(), - }; - let (_, val) = comment(def.trim_start()).expect("parse env var comment definition"); - assert_eq!(val, exp); - } - - #[test] - fn signal_comment_with_escaped_characters_test() { - let def = r#" -CM_ SG_ 2147548912 FooBar "Foo\\ \n \"Bar\""; -"#; - let exp = Comment::Signal { - message_id: MessageId::Extended(65264), - name: "FooBar".to_string(), - comment: r#"Foo\\ \n \"Bar\""#.to_string(), - }; - let (_, val) = comment(def.trim_start()).expect("parse signal comment definition"); - assert_eq!(val, exp); - } - - #[test] - fn empty_signal_comment_test() { - let def = r#" -CM_ SG_ 2147548912 FooBar ""; -"#; - let exp = Comment::Signal { - message_id: MessageId::Extended(65264), - name: "FooBar".to_string(), - comment: String::new(), - }; - let (_, val) = comment(def.trim_start()).expect("parse signal comment definition"); - assert_eq!(val, exp); - } - - #[test] - fn value_description_for_signal_test() { - let def = r#" -VAL_ 837 UF_HZ_OI 255 "NOP"; -"#; - let exp = ValueDescription::Signal { - message_id: MessageId::Standard(837), - name: "UF_HZ_OI".to_string(), - value_descriptions: vec![ValDescription { - id: 255.0, - description: "NOP".to_string(), - }], - }; - let (_, val) = value_descriptions(def.trim_start()).expect("parse value desc for signal"); - assert_eq!(val, exp); - } - - #[test] - fn value_description_for_env_var_test() { - let def = r#" -VAL_ MY_ENV_VAR 255 "NOP"; -"#; - let exp = ValueDescription::EnvironmentVariable { - name: "MY_ENV_VAR".to_string(), - value_descriptions: vec![ValDescription { - id: 255.0, - description: "NOP".to_string(), - }], - }; - let (_, val) = value_descriptions(def.trim_start()).expect("parse value desc for env var"); - assert_eq!(val, exp); - } - - #[test] - fn environment_variable_test() { - let def = r#" -EV_ IUV: 0 [-22|20] "mm" 3 7 DUMMY_NODE_VECTOR0 VECTOR_XXX; -"#; - let exp = EnvironmentVariable { - name: "IUV".to_string(), - typ: EnvType::Float, - min: -22, - max: 20, - unit: "mm".to_string(), - initial_value: 3.0, - ev_id: 7, - access_type: AccessType::DummyNodeVector0, - access_nodes: vec![AccessNode::VectorXXX], - }; - let (_, val) = environment_variable(def.trim_start()).expect("parse environment variable"); - assert_eq!(val, exp); - } - - #[test] - fn network_node_attribute_value_test() { - let def = r#" -BA_ "AttrName" BU_ NodeName 12; -"#; - let exp = AttributeValueForObject { - name: "AttrName".to_string(), - value: AttributeValuedForObjectType::NetworkNode( - "NodeName".to_string(), - AttributeValue::Double(12.0), - ), - }; - let (_, val) = attribute_value_for_object(def.trim_start()).unwrap(); - assert_eq!(val, exp); - } - - #[test] - fn message_definition_attribute_value_test() { - let def = r#" -BA_ "AttrName" BO_ 298 13; -"#; - let exp = AttributeValueForObject { - name: "AttrName".to_string(), - value: AttributeValuedForObjectType::MessageDefinition( - MessageId::Standard(298), - Some(AttributeValue::Double(13.0)), - ), - }; - let (_, val) = attribute_value_for_object(def.trim_start()).unwrap(); - assert_eq!(val, exp); - } - - #[test] - fn signal_attribute_value_test() { - let def = r#" -BA_ "AttrName" SG_ 198 SGName 13; -"#; - let exp = AttributeValueForObject { - name: "AttrName".to_string(), - value: AttributeValuedForObjectType::Signal( - MessageId::Standard(198), - "SGName".to_string(), - AttributeValue::Double(13.0), - ), - }; - let (_, val) = attribute_value_for_object(def.trim_start()).unwrap(); - assert_eq!(val, exp); - } - - #[test] - fn env_var_attribute_value_test() { - let def = r#" -BA_ "AttrName" EV_ EvName "CharStr"; -"#; - let exp = AttributeValueForObject { - name: "AttrName".to_string(), - value: AttributeValuedForObjectType::EnvVariable( - "EvName".to_string(), - AttributeValue::String("CharStr".to_string()), - ), - }; - let (_, val) = attribute_value_for_object(def.trim_start()).unwrap(); - assert_eq!(val, exp); - } - - #[test] - fn raw_attribute_value_test() { - let def = r#" -BA_ "AttrName" "RAW"; -"#; - let exp = AttributeValueForObject { - name: "AttrName".to_string(), - value: AttributeValuedForObjectType::Raw(AttributeValue::String("RAW".to_string())), - }; - let (_, val) = attribute_value_for_object(def.trim_start()).unwrap(); - assert_eq!(val, exp); - } - - #[test] - fn new_symbols_test() { - let def = r#" -NS_ : - NS_DESC_ - CM_ - BA_DEF_ - - "#; - let exp = vec![ - Symbol("NS_DESC_".to_string()), - Symbol("CM_".to_string()), - Symbol("BA_DEF_".to_string()), - ]; - let (_, val) = new_symbols(def.trim_start()).unwrap(); - assert_eq!(val, exp); - } - - #[test] - fn network_node_test() { - let def = r#" -BU_: ZU XYZ ABC OIU -"#; - let exp = Node(vec![ - "ZU".to_string(), - "XYZ".to_string(), - "ABC".to_string(), - "OIU".to_string(), - ]); - let (_, val) = node(def.trim_start()).unwrap(); - assert_eq!(val, exp); - } - - #[test] - fn empty_network_node_test() { - let def = r#" -BU_: -"#; - let (_, val) = node(def.trim_start()).unwrap(); - assert_eq!(val, Node(vec![])); - } - - #[test] - fn envvar_data_test() { - let def = r#" -ENVVAR_DATA_ SomeEnvVarData: 399; -"#; - let exp = EnvironmentVariableData { - env_var_name: "SomeEnvVarData".to_string(), - data_size: 399, - }; - let (_, val) = environment_variable_data(def.trim_start()).unwrap(); - assert_eq!(val, exp); - } - - #[test] - fn signal_type_test() { - let def = r#" -SGTYPE_ signal_type_name: 1024@1+ (5,2) [1|3] "unit" 2.0 val_table; -"#; - - let exp = SignalType { - name: "signal_type_name".to_string(), - signal_size: 1024, - byte_order: ByteOrder::LittleEndian, - value_type: ValueType::Unsigned, - factor: 5.0, - offset: 2.0, - min: 1.0, - max: 3.0, - unit: "unit".to_string(), - default_value: 2.0, - value_table: "val_table".to_string(), - }; - - let (_, val) = signal_type(def.trim_start()).unwrap(); - assert_eq!(val, exp); - } - - #[test] - fn signal_groups_test() { - let def = r#" -SIG_GROUP_ 23 X_3290 1 : A_b XY_Z; -"#; - - let exp = SignalGroups { - message_id: MessageId::Standard(23), - name: "X_3290".to_string(), - repetitions: 1, - signal_names: vec!["A_b".to_string(), "XY_Z".to_string()], - }; - - let (_, val) = signal_groups(def.trim_start()).unwrap(); - assert_eq!(val, exp); - } - - #[test] - fn attribute_default_test() { - let def = r#" -BA_DEF_DEF_ "ZUV" "OAL"; -"#; - let exp = AttributeDefault { - name: "ZUV".to_string(), - value: AttributeValue::String("OAL".to_string()), - }; - let (_, val) = attribute_default(def.trim_start()).unwrap(); - assert_eq!(val, exp); - } - - #[test] - fn attribute_value_f64_test() { - let def = "80.0"; - let (_, val) = attribute_value(def.trim_start()).unwrap(); - assert_eq!(val, AttributeValue::Double(80.0)); - } - - #[test] - fn attribute_definition_bo_test() { - let def_bo = r#" -BA_DEF_ BO_ "BaDef1BO" INT 0 1000000; -"#; - let (_, val) = attribute_definition(def_bo).unwrap(); - let exp = AttributeDefinition::Message(r#""BaDef1BO" INT 0 1000000"#.to_string()); - assert_eq!(val, exp); - } - - #[test] - fn attribute_definition_bu_test() { - let def = r#" -BA_DEF_ BU_ "BuDef1BO" INT 0 1000000; -"#; - let (_, val) = attribute_definition(def.trim_start()).unwrap(); - let exp = AttributeDefinition::Node(r#""BuDef1BO" INT 0 1000000"#.to_string()); - assert_eq!(val, exp); - } - - #[test] - fn attribute_definition_sg_test() { - let def = r#" -BA_DEF_ SG_ "SgDef1BO" INT 0 1000000; -"#; - let (_, val) = attribute_definition(def.trim_start()).unwrap(); - let exp = AttributeDefinition::Signal(r#""SgDef1BO" INT 0 1000000"#.to_string()); - assert_eq!(val, exp); - } - - #[test] - fn attribute_definition_ev_test() { - let def_env_var = r#" -BA_DEF_ EV_ "EvDef1BO" INT 0 1000000; -"#; - let (_, val) = attribute_definition(def_env_var).unwrap(); - let exp = - AttributeDefinition::EnvironmentVariable(r#""EvDef1BO" INT 0 1000000"#.to_string()); - assert_eq!(val, exp); - } - - #[test] - fn version_test() { - let def = r#" -VERSION "HNPBNNNYNNNNNNNNNNNNNNNNNNNNNNNNYNYYYYYYYY>4>%%%/4>'%**4YYY///" -"#; - let exp = - Version("HNPBNNNYNNNNNNNNNNNNNNNNNNNNNNNNYNYYYYYYYY>4>%%%/4>'%**4YYY///".to_string()); - let (_, val) = version(def.trim_start()).unwrap(); - assert_eq!(val, exp); - } - - #[test] - fn message_transmitters_test() { - let def = r#" -BO_TX_BU_ 12345 : XZY,ABC; -"#; - let exp = MessageTransmitter { - message_id: MessageId::Standard(12345), - transmitter: vec![ - Transmitter::NodeName("XZY".to_string()), - Transmitter::NodeName("ABC".to_string()), - ], - }; - let (_, val) = message_transmitter(def.trim_start()).unwrap(); - assert_eq!(val, exp); - - // Same as above, but without space before the colon - let def = r#" -BO_TX_BU_ 12345 :XZY,ABC; -"#; - let (_, val) = message_transmitter(def.trim_start()).unwrap(); - assert_eq!(val, exp); - } - - #[test] - fn value_description_test() { - let def = r#" -2 "ABC" -"#; - let exp = ValDescription { - id: 2f64, - description: "ABC".to_string(), - }; - let (_, val) = value_description(def.trim_start()).unwrap(); - assert_eq!(val, exp); - } - - #[test] - fn val_table_test() { - let def = r#" -VAL_TABLE_ Tst 2 "ABC" 1 "Test A" ; -"#; - let exp = ValueTable { - name: "Tst".to_string(), - descriptions: vec![ - ValDescription { - id: 2f64, - description: "ABC".to_string(), - }, - ValDescription { - id: 1f64, - description: "Test A".to_string(), - }, - ], - }; - let (_, val) = value_table(def.trim_start()).unwrap(); - assert_eq!(val, exp); - } - - #[test] - fn val_table_no_space_preceding_comma_test() { - let def = r#" -VAL_TABLE_ Tst 2 "ABC"; -"#; - let exp = ValueTable { - name: "Tst".to_string(), - descriptions: vec![ValDescription { - id: 2f64, - description: "ABC".to_string(), - }], - }; - let (_, val) = value_table(def.trim_start()).unwrap(); - assert_eq!(val, exp); - } - - #[test] - fn extended_multiplex_test() { - // simple mapping - let def = r#" -SG_MUL_VAL_ 2147483650 muxed_A_1 MUX_A 1-1; -"#; - let exp = ExtendedMultiplex { - message_id: MessageId::Extended(2), - signal_name: "muxed_A_1".to_string(), - multiplexor_signal_name: "MUX_A".to_string(), - mappings: vec![ExtendedMultiplexMapping { - min_value: 1, - max_value: 1, - }], - }; - let (_, val) = extended_multiplex(def.trim_start()).unwrap(); - assert_eq!(val, exp); - } - - #[test] - fn extended_multiplex_range_test() { - // range mapping - let def = r#" -SG_MUL_VAL_ 2147483650 muxed_A_1 MUX_A 1568-2568; -"#; - let exp = ExtendedMultiplex { - message_id: MessageId::Extended(2), - signal_name: "muxed_A_1".to_string(), - multiplexor_signal_name: "MUX_A".to_string(), - mappings: vec![ExtendedMultiplexMapping { - min_value: 1568, - max_value: 2568, - }], - }; - let (_, val) = extended_multiplex(def.trim_start()).unwrap(); - assert_eq!(val, exp); - } - - #[test] - fn extended_multiplex_mult_test() { - // multiple mappings - let def = r#" -SG_MUL_VAL_ 2147483650 muxed_B_5 MUX_B 5-5, 16-24; -"#; - let exp = ExtendedMultiplex { - message_id: MessageId::Extended(2), - signal_name: "muxed_B_5".to_string(), - multiplexor_signal_name: "MUX_B".to_string(), - mappings: vec![ - ExtendedMultiplexMapping { - min_value: 5, - max_value: 5, - }, - ExtendedMultiplexMapping { - min_value: 16, - max_value: 24, - }, - ], - }; - let (_, val) = extended_multiplex(def.trim_start()).unwrap(); - assert_eq!(val, exp); - } - - #[test] - fn sig_val_type_test() { - let def = r#" -SIG_VALTYPE_ 2000 Signal_8 : 1; -"#; - let exp = SignalExtendedValueTypeList { - message_id: MessageId::Standard(2000), - signal_name: "Signal_8".to_string(), - signal_extended_value_type: SignalExtendedValueType::IEEEfloat32Bit, - }; - - let (_, val) = signal_extended_value_type_list(def.trim_start()).unwrap(); - assert_eq!(val, exp); - } - - #[test] - fn standard_message_id_test() { - let (_, val) = message_id("2").unwrap(); - assert_eq!(val, MessageId::Standard(2)); - } - - #[test] - fn extended_low_message_id_test() { - let s = (2u32 | 1 << 31).to_string(); - let (_, val) = message_id(&s).unwrap(); - assert_eq!(val, MessageId::Extended(2)); - } - - #[test] - fn extended_message_id_test() { - let s = (0x1FFF_FFFF_u32 | 1 << 31).to_string(); - let (_, val) = message_id(&s).unwrap(); - assert_eq!(val, MessageId::Extended(0x1FFF_FFFF)); - } - - #[test] - fn extended_message_id_test_max_29bit() { - let s = u32::MAX.to_string(); - let (_, val) = message_id(&s).unwrap(); - assert_eq!(val, MessageId::Extended(0x1FFF_FFFF)); - } -} diff --git a/src/parser_tests.rs b/src/parser_tests.rs new file mode 100644 index 0000000..5bef189 --- /dev/null +++ b/src/parser_tests.rs @@ -0,0 +1,650 @@ +#![allow(clippy::needless_raw_string_hashes)] + +use crate::parser::*; +use crate::*; + +#[test] +fn c_ident_test() { + let def = "EALL_DUSasb18 "; + let (_, val) = c_ident(def).unwrap(); + assert_eq!(val, "EALL_DUSasb18"); + + let def = "_EALL_DUSasb18 "; + let (_, val) = c_ident(def).unwrap(); + assert_eq!(val, "_EALL_DUSasb18"); + + // identifiers must not start with digits + let def = "3EALL_DUSasb18 "; + assert!(c_ident(def).is_err()); +} + +#[test] +fn c_ident_vec_test() { + let def = "FZHL_DUSasb18 "; + let (_, val) = c_ident_vec(def).unwrap(); + assert_eq!(val, vec!("FZHL_DUSasb18".to_string())); + + let def = "FZHL_DUSasb19,xkask_3298 "; + let (_, val) = c_ident_vec(def).unwrap(); + assert_eq!( + val, + vec!["FZHL_DUSasb19".to_string(), "xkask_3298".to_string()], + ); +} + +#[test] +fn char_string_test() { + let def = "\"ab\x00\x7f\""; + let (_, val) = char_string(def).unwrap(); + assert_eq!(val, "ab\x00\x7f"); +} + +#[test] +fn signal_test() { + let def = r#" +SG_ NAME : 3|2@1- (1,0) [0|0] "x" UFA +"#; + let _signal = signal(def.trim_start()).unwrap(); +} + +#[test] +fn byte_order_test() { + let (_, val) = byte_order("0").expect("parse big endian"); + assert_eq!(val, ByteOrder::BigEndian); + + let (_, val) = byte_order("1").expect("parse little endian"); + assert_eq!(val, ByteOrder::LittleEndian); +} + +#[test] +fn multiplexer_indicator_test() { + let (_, val) = multiplexer_indicator(" m34920 eol").expect("parse multiplexer"); + assert_eq!(val, MultiplexIndicator::MultiplexedSignal(34920)); + + let (_, val) = multiplexer_indicator(" M eol").expect("parse multiplexor"); + assert_eq!(val, MultiplexIndicator::Multiplexor); + + let (_, val) = multiplexer_indicator(" eol").expect("parse plain"); + assert_eq!(val, MultiplexIndicator::Plain); + + let (_, val) = multiplexer_indicator(" m8M eol").expect("parse multiplexer"); + assert_eq!(val, MultiplexIndicator::MultiplexorAndMultiplexedSignal(8)); +} + +#[test] +fn value_type_test() { + let (_, val) = value_type("- ").expect("parse value type"); + assert_eq!(ValueType::Signed, val); + + let (_, val) = value_type("+ ").expect("parse value type"); + assert_eq!(ValueType::Unsigned, val); +} + +#[test] +fn message_definition_test() { + signal("\r\n\r\nSG_ BasL2 : 3|2@0- (1,0) [0|0] \"x\" DFA_FUS\r\n").expect("Failed"); + + let def = r#" +BO_ 1 MCA_A1: 6 MFA +SG_ ABC_1 : 9|2@1+ (1,0) [0|0] "x" XYZ_OUS +SG_ BasL2 : 3|2@0- (1,0) [0|0] "x" DFA_FUS + x"#; + let (_, _val) = message(def.trim_start()).expect("parse message definition"); +} + +#[test] +fn signal_comment_test() { + let def = r#" +CM_ SG_ 193 KLU_R_X "This is a signal comment test"; +"#; + let exp = Comment::Signal { + message_id: MessageId::Standard(193), + name: "KLU_R_X".to_string(), + comment: "This is a signal comment test".to_string(), + }; + let (_, val) = comment(def.trim_start()).expect("parse signal comment definition"); + assert_eq!(val, exp); +} + +#[test] +fn message_definition_comment_test() { + let def = r#" +CM_ BO_ 34544 "Some Message comment"; +"#; + let exp = Comment::Message { + id: MessageId::Standard(34544), + comment: "Some Message comment".to_string(), + }; + let (_, val) = comment(def.trim_start()).expect("parse message definition comment definition"); + assert_eq!(val, exp); +} + +#[test] +fn node_comment_test() { + let def = r#" +CM_ BU_ network_node "Some network node comment"; +"#; + let exp = Comment::Node { + name: "network_node".to_string(), + comment: "Some network node comment".to_string(), + }; + let (_, val) = comment(def.trim_start()).expect("parse node comment definition"); + assert_eq!(val, exp); +} + +#[test] +fn env_var_comment_test() { + let def = r#" +CM_ EV_ ENVXYZ "Some env var name comment"; +"#; + let exp = Comment::EnvVar { + name: "ENVXYZ".to_string(), + comment: "Some env var name comment".to_string(), + }; + let (_, val) = comment(def.trim_start()).expect("parse env var comment definition"); + assert_eq!(val, exp); +} + +#[test] +fn signal_comment_with_escaped_characters_test() { + let def = r#" +CM_ SG_ 2147548912 FooBar "Foo\\ \n \"Bar\""; +"#; + let exp = Comment::Signal { + message_id: MessageId::Extended(65264), + name: "FooBar".to_string(), + comment: r#"Foo\\ \n \"Bar\""#.to_string(), + }; + let (_, val) = comment(def.trim_start()).expect("parse signal comment definition"); + assert_eq!(val, exp); +} + +#[test] +fn empty_signal_comment_test() { + let def = r#" +CM_ SG_ 2147548912 FooBar ""; +"#; + let exp = Comment::Signal { + message_id: MessageId::Extended(65264), + name: "FooBar".to_string(), + comment: String::new(), + }; + let (_, val) = comment(def.trim_start()).expect("parse signal comment definition"); + assert_eq!(val, exp); +} + +#[test] +fn value_description_for_signal_test() { + let def = r#" +VAL_ 837 UF_HZ_OI 255 "NOP"; +"#; + let exp = ValueDescription::Signal { + message_id: MessageId::Standard(837), + name: "UF_HZ_OI".to_string(), + value_descriptions: vec![ValDescription { + id: 255.0, + description: "NOP".to_string(), + }], + }; + let (_, val) = value_descriptions(def.trim_start()).expect("parse value desc for signal"); + assert_eq!(val, exp); +} + +#[test] +fn value_description_for_env_var_test() { + let def = r#" +VAL_ MY_ENV_VAR 255 "NOP"; +"#; + let exp = ValueDescription::EnvironmentVariable { + name: "MY_ENV_VAR".to_string(), + value_descriptions: vec![ValDescription { + id: 255.0, + description: "NOP".to_string(), + }], + }; + let (_, val) = value_descriptions(def.trim_start()).expect("parse value desc for env var"); + assert_eq!(val, exp); +} + +#[test] +fn environment_variable_test() { + let def = r#" +EV_ IUV: 0 [-22|20] "mm" 3 7 DUMMY_NODE_VECTOR0 VECTOR_XXX; +"#; + let exp = EnvironmentVariable { + name: "IUV".to_string(), + typ: EnvType::Float, + min: -22, + max: 20, + unit: "mm".to_string(), + initial_value: 3.0, + ev_id: 7, + access_type: AccessType::DummyNodeVector0, + access_nodes: vec![AccessNode::VectorXXX], + }; + let (_, val) = environment_variable(def.trim_start()).expect("parse environment variable"); + assert_eq!(val, exp); +} + +#[test] +fn network_node_attribute_value_test() { + let def = r#" +BA_ "AttrName" BU_ NodeName 12; +"#; + let exp = AttributeValueForObject { + name: "AttrName".to_string(), + value: AttributeValuedForObjectType::NetworkNode( + "NodeName".to_string(), + AttributeValue::Double(12.0), + ), + }; + let (_, val) = attribute_value_for_object(def.trim_start()).unwrap(); + assert_eq!(val, exp); +} + +#[test] +fn message_definition_attribute_value_test() { + let def = r#" +BA_ "AttrName" BO_ 298 13; +"#; + let exp = AttributeValueForObject { + name: "AttrName".to_string(), + value: AttributeValuedForObjectType::MessageDefinition( + MessageId::Standard(298), + Some(AttributeValue::Double(13.0)), + ), + }; + let (_, val) = attribute_value_for_object(def.trim_start()).unwrap(); + assert_eq!(val, exp); +} + +#[test] +fn signal_attribute_value_test() { + let def = r#" +BA_ "AttrName" SG_ 198 SGName 13; +"#; + let exp = AttributeValueForObject { + name: "AttrName".to_string(), + value: AttributeValuedForObjectType::Signal( + MessageId::Standard(198), + "SGName".to_string(), + AttributeValue::Double(13.0), + ), + }; + let (_, val) = attribute_value_for_object(def.trim_start()).unwrap(); + assert_eq!(val, exp); +} + +#[test] +fn env_var_attribute_value_test() { + let def = r#" +BA_ "AttrName" EV_ EvName "CharStr"; +"#; + let exp = AttributeValueForObject { + name: "AttrName".to_string(), + value: AttributeValuedForObjectType::EnvVariable( + "EvName".to_string(), + AttributeValue::String("CharStr".to_string()), + ), + }; + let (_, val) = attribute_value_for_object(def.trim_start()).unwrap(); + assert_eq!(val, exp); +} + +#[test] +fn raw_attribute_value_test() { + let def = r#" +BA_ "AttrName" "RAW"; +"#; + let exp = AttributeValueForObject { + name: "AttrName".to_string(), + value: AttributeValuedForObjectType::Raw(AttributeValue::String("RAW".to_string())), + }; + let (_, val) = attribute_value_for_object(def.trim_start()).unwrap(); + assert_eq!(val, exp); +} + +#[test] +fn new_symbols_test() { + let def = r#" +NS_ : + NS_DESC_ + CM_ + BA_DEF_ + + "#; + let exp = vec![ + Symbol("NS_DESC_".to_string()), + Symbol("CM_".to_string()), + Symbol("BA_DEF_".to_string()), + ]; + let (_, val) = new_symbols(def.trim_start()).unwrap(); + assert_eq!(val, exp); +} + +#[test] +fn network_node_test() { + let def = r#" +BU_: ZU XYZ ABC OIU +"#; + let exp = Node(vec![ + "ZU".to_string(), + "XYZ".to_string(), + "ABC".to_string(), + "OIU".to_string(), + ]); + let (_, val) = node(def.trim_start()).unwrap(); + assert_eq!(val, exp); +} + +#[test] +fn empty_network_node_test() { + let def = r#" +BU_: +"#; + let (_, val) = node(def.trim_start()).unwrap(); + assert_eq!(val, Node(vec![])); +} + +#[test] +fn envvar_data_test() { + let def = r#" +ENVVAR_DATA_ SomeEnvVarData: 399; +"#; + let exp = EnvironmentVariableData { + env_var_name: "SomeEnvVarData".to_string(), + data_size: 399, + }; + let (_, val) = environment_variable_data(def.trim_start()).unwrap(); + assert_eq!(val, exp); +} + +#[test] +fn signal_type_test() { + let def = r#" +SGTYPE_ signal_type_name: 1024@1+ (5,2) [1|3] "unit" 2.0 val_table; +"#; + + let exp = SignalType { + name: "signal_type_name".to_string(), + signal_size: 1024, + byte_order: ByteOrder::LittleEndian, + value_type: ValueType::Unsigned, + factor: 5.0, + offset: 2.0, + min: 1.0, + max: 3.0, + unit: "unit".to_string(), + default_value: 2.0, + value_table: "val_table".to_string(), + }; + + let (_, val) = signal_type(def.trim_start()).unwrap(); + assert_eq!(val, exp); +} + +#[test] +fn signal_groups_test() { + let def = r#" +SIG_GROUP_ 23 X_3290 1 : A_b XY_Z; +"#; + + let exp = SignalGroups { + message_id: MessageId::Standard(23), + name: "X_3290".to_string(), + repetitions: 1, + signal_names: vec!["A_b".to_string(), "XY_Z".to_string()], + }; + + let (_, val) = signal_groups(def.trim_start()).unwrap(); + assert_eq!(val, exp); +} + +#[test] +fn attribute_default_test() { + let def = r#" +BA_DEF_DEF_ "ZUV" "OAL"; +"#; + let exp = AttributeDefault { + name: "ZUV".to_string(), + value: AttributeValue::String("OAL".to_string()), + }; + let (_, val) = attribute_default(def.trim_start()).unwrap(); + assert_eq!(val, exp); +} + +#[test] +fn attribute_value_f64_test() { + let def = "80.0"; + let (_, val) = attribute_value(def.trim_start()).unwrap(); + assert_eq!(val, AttributeValue::Double(80.0)); +} + +#[test] +fn attribute_definition_bo_test() { + let def_bo = r#" +BA_DEF_ BO_ "BaDef1BO" INT 0 1000000; +"#; + let (_, val) = attribute_definition(def_bo).unwrap(); + let exp = AttributeDefinition::Message(r#""BaDef1BO" INT 0 1000000"#.to_string()); + assert_eq!(val, exp); +} + +#[test] +fn attribute_definition_bu_test() { + let def = r#" +BA_DEF_ BU_ "BuDef1BO" INT 0 1000000; +"#; + let (_, val) = attribute_definition(def.trim_start()).unwrap(); + let exp = AttributeDefinition::Node(r#""BuDef1BO" INT 0 1000000"#.to_string()); + assert_eq!(val, exp); +} + +#[test] +fn attribute_definition_sg_test() { + let def = r#" +BA_DEF_ SG_ "SgDef1BO" INT 0 1000000; +"#; + let (_, val) = attribute_definition(def.trim_start()).unwrap(); + let exp = AttributeDefinition::Signal(r#""SgDef1BO" INT 0 1000000"#.to_string()); + assert_eq!(val, exp); +} + +#[test] +fn attribute_definition_ev_test() { + let def_env_var = r#" +BA_DEF_ EV_ "EvDef1BO" INT 0 1000000; +"#; + let (_, val) = attribute_definition(def_env_var).unwrap(); + let exp = AttributeDefinition::EnvironmentVariable(r#""EvDef1BO" INT 0 1000000"#.to_string()); + assert_eq!(val, exp); +} + +#[test] +fn version_test() { + let def = r#" +VERSION "HNPBNNNYNNNNNNNNNNNNNNNNNNNNNNNNYNYYYYYYYY>4>%%%/4>'%**4YYY///" +"#; + let exp = Version("HNPBNNNYNNNNNNNNNNNNNNNNNNNNNNNNYNYYYYYYYY>4>%%%/4>'%**4YYY///".to_string()); + let (_, val) = version(def.trim_start()).unwrap(); + assert_eq!(val, exp); +} + +#[test] +fn message_transmitters_test() { + let def = r#" +BO_TX_BU_ 12345 : XZY,ABC; +"#; + let exp = MessageTransmitter { + message_id: MessageId::Standard(12345), + transmitter: vec![ + Transmitter::NodeName("XZY".to_string()), + Transmitter::NodeName("ABC".to_string()), + ], + }; + let (_, val) = message_transmitter(def.trim_start()).unwrap(); + assert_eq!(val, exp); + + // Same as above, but without space before the colon + let def = r#" +BO_TX_BU_ 12345 :XZY,ABC; +"#; + let (_, val) = message_transmitter(def.trim_start()).unwrap(); + assert_eq!(val, exp); +} + +#[test] +fn value_description_test() { + let def = r#" +2 "ABC" +"#; + let exp = ValDescription { + id: 2f64, + description: "ABC".to_string(), + }; + let (_, val) = value_description(def.trim_start()).unwrap(); + assert_eq!(val, exp); +} + +#[test] +fn val_table_test() { + let def = r#" +VAL_TABLE_ Tst 2 "ABC" 1 "Test A" ; +"#; + let exp = ValueTable { + name: "Tst".to_string(), + descriptions: vec![ + ValDescription { + id: 2f64, + description: "ABC".to_string(), + }, + ValDescription { + id: 1f64, + description: "Test A".to_string(), + }, + ], + }; + let (_, val) = value_table(def.trim_start()).unwrap(); + assert_eq!(val, exp); +} + +#[test] +fn val_table_no_space_preceding_comma_test() { + let def = r#" +VAL_TABLE_ Tst 2 "ABC"; +"#; + let exp = ValueTable { + name: "Tst".to_string(), + descriptions: vec![ValDescription { + id: 2f64, + description: "ABC".to_string(), + }], + }; + let (_, val) = value_table(def.trim_start()).unwrap(); + assert_eq!(val, exp); +} + +#[test] +fn extended_multiplex_test() { + // simple mapping + let def = r#" +SG_MUL_VAL_ 2147483650 muxed_A_1 MUX_A 1-1; +"#; + let exp = ExtendedMultiplex { + message_id: MessageId::Extended(2), + signal_name: "muxed_A_1".to_string(), + multiplexor_signal_name: "MUX_A".to_string(), + mappings: vec![ExtendedMultiplexMapping { + min_value: 1, + max_value: 1, + }], + }; + let (_, val) = extended_multiplex(def.trim_start()).unwrap(); + assert_eq!(val, exp); +} + +#[test] +fn extended_multiplex_range_test() { + // range mapping + let def = r#" +SG_MUL_VAL_ 2147483650 muxed_A_1 MUX_A 1568-2568; +"#; + let exp = ExtendedMultiplex { + message_id: MessageId::Extended(2), + signal_name: "muxed_A_1".to_string(), + multiplexor_signal_name: "MUX_A".to_string(), + mappings: vec![ExtendedMultiplexMapping { + min_value: 1568, + max_value: 2568, + }], + }; + let (_, val) = extended_multiplex(def.trim_start()).unwrap(); + assert_eq!(val, exp); +} + +#[test] +fn extended_multiplex_mult_test() { + // multiple mappings + let def = r#" +SG_MUL_VAL_ 2147483650 muxed_B_5 MUX_B 5-5, 16-24; +"#; + let exp = ExtendedMultiplex { + message_id: MessageId::Extended(2), + signal_name: "muxed_B_5".to_string(), + multiplexor_signal_name: "MUX_B".to_string(), + mappings: vec![ + ExtendedMultiplexMapping { + min_value: 5, + max_value: 5, + }, + ExtendedMultiplexMapping { + min_value: 16, + max_value: 24, + }, + ], + }; + let (_, val) = extended_multiplex(def.trim_start()).unwrap(); + assert_eq!(val, exp); +} + +#[test] +fn sig_val_type_test() { + let def = r#" +SIG_VALTYPE_ 2000 Signal_8 : 1; +"#; + let exp = SignalExtendedValueTypeList { + message_id: MessageId::Standard(2000), + signal_name: "Signal_8".to_string(), + signal_extended_value_type: SignalExtendedValueType::IEEEfloat32Bit, + }; + + let (_, val) = signal_extended_value_type_list(def.trim_start()).unwrap(); + assert_eq!(val, exp); +} + +#[test] +fn standard_message_id_test() { + let (_, val) = message_id("2").unwrap(); + assert_eq!(val, MessageId::Standard(2)); +} + +#[test] +fn extended_low_message_id_test() { + let s = (2u32 | 1 << 31).to_string(); + let (_, val) = message_id(&s).unwrap(); + assert_eq!(val, MessageId::Extended(2)); +} + +#[test] +fn extended_message_id_test() { + let s = (0x1FFF_FFFF_u32 | 1 << 31).to_string(); + let (_, val) = message_id(&s).unwrap(); + assert_eq!(val, MessageId::Extended(0x1FFF_FFFF)); +} + +#[test] +fn extended_message_id_test_max_29bit() { + let s = u32::MAX.to_string(); + let (_, val) = message_id(&s).unwrap(); + assert_eq!(val, MessageId::Extended(0x1FFF_FFFF)); +} diff --git a/tests/parsing.rs b/tests/parsing.rs new file mode 100644 index 0000000..09b544c --- /dev/null +++ b/tests/parsing.rs @@ -0,0 +1,217 @@ +use can_dbc::{Dbc, Error, MessageId, SignalExtendedValueType, ValDescription}; + +const SAMPLE_DBC: &str = r#" +VERSION "0.1" +NS_ : + NS_DESC_ + CM_ + BA_DEF_ + BA_ + VAL_ + CAT_DEF_ + CAT_ + FILTER + BA_DEF_DEF_ + EV_DATA_ + ENVVAR_DATA_ + SGTYPE_ + SGTYPE_VAL_ + BA_DEF_SGTYPE_ + BA_SGTYPE_ + SIG_TYPE_REF_ + VAL_TABLE_ + SIG_GROUP_ + SIG_VALTYPE_ + SIGTYPE_VALTYPE_ + BO_TX_BU_ + BA_DEF_REL_ + BA_REL_ + BA_DEF_DEF_REL_ + BU_SG_REL_ + BU_EV_REL_ + BU_BO_REL_ + SG_MUL_VAL_ +BS_: +BU_: PC +BO_ 2000 WebData_2000: 4 Vector__XXX + SG_ Signal_8 : 24|8@1+ (1,0) [0|255] "" Vector__XXX + SG_ Signal_7 : 16|8@1+ (1,0) [0|255] "" Vector__XXX + SG_ Signal_6 : 8|8@1+ (1,0) [0|255] "" Vector__XXX + SG_ Signal_5 : 0|8@1+ (1,0) [0|255] "" Vector__XXX +BO_ 1840 WebData_1840: 4 PC + SG_ Signal_4 : 24|8@1+ (1,0) [0|255] "" Vector__XXX + SG_ Signal_3 : 16|8@1+ (1,0) [0|255] "" Vector__XXX + SG_ Signal_2 : 8|8@1+ (1,0) [0|255] "" Vector__XXX + SG_ Signal_1 : 0|8@1+ (1,0) [0|0] "" Vector__XXX + +BO_ 3040 WebData_3040: 8 Vector__XXX + SG_ Signal_6 m2 : 0|4@1+ (1,0) [0|15] "" Vector__XXX + SG_ Signal_5 m3 : 16|8@1+ (1,0) [0|255] "kmh" Vector__XXX + SG_ Signal_4 m3 : 8|8@1+ (1,0) [0|255] "" Vector__XXX + SG_ Signal_3 m3 : 0|4@1+ (1,0) [0|3] "" Vector__XXX + SG_ Signal_2 m1 : 3|12@0+ (1,0) [0|4095] "Byte" Vector__XXX + SG_ Signal_1 m0 : 0|4@1+ (1,0) [0|7] "Byte" Vector__XXX + SG_ Switch M : 4|4@1+ (1,0) [0|3] "" Vector__XXX + +EV_ Environment1: 0 [0|220] "" 0 6 DUMMY_NODE_VECTOR0 DUMMY_NODE_VECTOR2; +EV_ Environment2: 0 [0|177] "" 0 7 DUMMY_NODE_VECTOR1 DUMMY_NODE_VECTOR2; +ENVVAR_DATA_ SomeEnvVarData: 399; + +CM_ BO_ 1840 "Some Message comment"; +CM_ SG_ 1840 Signal_4 "asaklfjlsdfjlsdfgls +HH?=(%)/&KKDKFSDKFKDFKSDFKSDFNKCnvsdcvsvxkcv"; +CM_ SG_ 5 TestSigLittleUnsigned1 "asaklfjlsdfjlsdfgls +=0943503450KFSDKFKDFKSDFKSDFNKCnvsdcvsvxkcv"; + +BA_DEF_DEF_ "BusType" "AS"; + +BA_ "Attr" BO_ 4358435 283; +BA_ "Attr" BO_ 56949545 344; + +VAL_ 2000 Signal_3 255 "NOP"; + +SIG_VALTYPE_ 2000 Signal_8 : 1; +"#; + +#[test] +fn dbc_definition_test() { + match Dbc::try_from(SAMPLE_DBC) { + Ok(dbc_content) => println!("DBC Content{dbc_content:#?}"), + Err(e) => { + match e { + Error::Nom(nom::Err::Incomplete(needed)) => { + eprintln!("Error incomplete input, needed: {needed:?}"); + } + Error::Nom(nom::Err::Error(error)) => { + eprintln!("Nom Error: {error:?}"); + } + Error::Nom(nom::Err::Failure(ctx)) => eprintln!("Failure {ctx:?}"), + Error::Incomplete(dbc, remaining) => eprintln!( + "Not all data in buffer was read {dbc:#?}, remaining unparsed: {remaining}", + ), + Error::MultipleMultiplexors => eprintln!("Multiple multiplexors defined"), + } + panic!("Failed to read DBC"); + } + } +} + +#[test] +fn lookup_signal_comment() { + let dbc_content = Dbc::try_from(SAMPLE_DBC).expect("Failed to parse DBC"); + let comment = dbc_content + .signal_comment(MessageId::Standard(1840), "Signal_4") + .expect("Signal comment missing"); + assert_eq!( + "asaklfjlsdfjlsdfgls\nHH?=(%)/&KKDKFSDKFKDFKSDFKSDFNKCnvsdcvsvxkcv", + comment + ); +} + +#[test] +fn lookup_signal_comment_none_when_missing() { + let dbc_content = Dbc::try_from(SAMPLE_DBC).expect("Failed to parse DBC"); + let comment = dbc_content.signal_comment(MessageId::Standard(1840), "Signal_2"); + assert_eq!(None, comment); +} + +#[test] +fn lookup_message_comment() { + let dbc_content = Dbc::try_from(SAMPLE_DBC).expect("Failed to parse DBC"); + let comment = dbc_content + .message_comment(MessageId::Standard(1840)) + .expect("Message comment missing"); + assert_eq!("Some Message comment", comment); +} + +#[test] +fn lookup_message_comment_none_when_missing() { + let dbc_content = Dbc::try_from(SAMPLE_DBC).expect("Failed to parse DBC"); + let comment = dbc_content.message_comment(MessageId::Standard(2000)); + assert_eq!(None, comment); +} + +#[test] +fn lookup_value_descriptions_for_signal() { + let dbc_content = Dbc::try_from(SAMPLE_DBC).expect("Failed to parse DBC"); + let val_descriptions = dbc_content + .value_descriptions_for_signal(MessageId::Standard(2000), "Signal_3") + .expect("Message comment missing"); + + let exp = vec![ValDescription { + id: 255.0, + description: "NOP".to_string(), + }]; + assert_eq!(exp, val_descriptions); +} + +#[test] +fn lookup_value_descriptions_for_signal_none_when_missing() { + let dbc_content = Dbc::try_from(SAMPLE_DBC).expect("Failed to parse DBC"); + let val_descriptions = + dbc_content.value_descriptions_for_signal(MessageId::Standard(2000), "Signal_2"); + assert_eq!(None, val_descriptions); +} + +#[test] +fn lookup_extended_value_type_for_signal() { + let dbc_content = Dbc::try_from(SAMPLE_DBC).expect("Failed to parse DBC"); + let extended_value_type = + dbc_content.extended_value_type_for_signal(MessageId::Standard(2000), "Signal_8"); + assert_eq!( + extended_value_type, + Some(&SignalExtendedValueType::IEEEfloat32Bit) + ); +} + +#[test] +fn lookup_extended_value_type_for_signal_none_when_missing() { + let dbc_content = Dbc::try_from(SAMPLE_DBC).expect("Failed to parse DBC"); + let extended_value_type = + dbc_content.extended_value_type_for_signal(MessageId::Standard(2000), "Signal_1"); + assert_eq!(extended_value_type, None); +} + +#[test] +fn lookup_signal_by_name() { + let dbc_content = Dbc::try_from(SAMPLE_DBC).expect("Failed to parse DBC"); + let signal = dbc_content.signal_by_name(MessageId::Standard(2000), "Signal_8"); + assert!(signal.is_some()); +} + +#[test] +fn lookup_signal_by_name_none_when_missing() { + let dbc_content = Dbc::try_from(SAMPLE_DBC).expect("Failed to parse DBC"); + let signal = dbc_content.signal_by_name(MessageId::Standard(2000), "Signal_25"); + assert_eq!(signal, None); +} + +#[test] +fn lookup_multiplex_indicator_switch() { + let dbc_content = Dbc::try_from(SAMPLE_DBC).expect("Failed to parse DBC"); + let multiplexor_switch = dbc_content.message_multiplexor_switch(MessageId::Standard(3040)); + assert!(multiplexor_switch.is_ok()); + assert!(multiplexor_switch.as_ref().unwrap().is_some()); + assert_eq!(multiplexor_switch.unwrap().unwrap().name(), "Switch"); +} + +#[test] +fn lookup_multiplex_indicator_switch_none_when_missing() { + let dbc_content = Dbc::try_from(SAMPLE_DBC).expect("Failed to parse DBC"); + let multiplexor_switch = dbc_content.message_multiplexor_switch(MessageId::Standard(1840)); + assert!(multiplexor_switch.unwrap().is_none()); +} + +#[test] +fn extended_message_id_raw() { + let message_id = MessageId::Extended(2); + assert_eq!(message_id.raw(), 2 | 1 << 31); + let message_id = MessageId::Extended(2 ^ 29); + assert_eq!(message_id.raw(), 2 ^ 29 | 1 << 31); +} + +#[test] +fn standard_message_id_raw() { + let message_id = MessageId::Standard(2); + assert_eq!(message_id.raw(), 2); +}