diff --git a/hermes/crates/cbork/cddl-parser/src/grammar/cddl_test.pest b/hermes/crates/cbork/cddl-parser/src/grammar/cddl_test.pest index 41fd784fd..4eb04bda5 100644 --- a/hermes/crates/cbork/cddl-parser/src/grammar/cddl_test.pest +++ b/hermes/crates/cbork/cddl-parser/src/grammar/cddl_test.pest @@ -3,40 +3,99 @@ // Test Expressions ONLY TO Be USED by Unit Tests. // Extends `cddl.pest` with rules needed to properly check sub-rules. -// cspell: words intfloat hexfloat +// cspell: words intfloat hexfloat groupname assignt +// cspell: words assigng genericparm genericarg rangeop ctlop +// cspell: words grpchoice grpent memberkey bareword optcom -/// Test Expression for the S Rule. +/// Test Expression for the `rule` Rule. +rule_TEST = ${ SOI ~ rule ~ EOI } + +/// Test Expression for the `typename` Rule. +typename_TEST = ${ SOI ~ typename ~ EOI } + +/// Test Expression for the `groupname` Rule. +groupname_TEST = ${ SOI ~ groupname ~ EOI } + +/// Test Expression for the `assignt` Rule. +assignt_TEST = ${ SOI ~ assignt ~ EOI } + +/// Test Expression for the `assigng` Rule. +assigng_TEST = ${ SOI ~ assigng ~ EOI } + +/// Test Expression for the `genericparm` Rule. +genericparm_TEST = ${ SOI ~ genericparm ~ EOI } + +/// Test Expression for the `genericarg` Rule. +genericarg_TEST = ${ SOI ~ genericarg ~ EOI } + +/// Test Expression for the `type` Rule. +type_TEST = ${ SOI ~ type ~ EOI } + +/// Test Expression for the `type1` Rule. +type1_TEST = ${ SOI ~ type1 ~ EOI } + +/// Test Expression for the `type2` Rule. +type2_TEST = ${ SOI ~ type2 ~ EOI } + +/// Test Expression for the `rangeop` Rule. +rangeop_TEST = ${ SOI ~ rangeop ~ EOI } + +/// Test Expression for the `ctlop` Rule. +ctlop_TEST = ${ SOI ~ ctlop ~ EOI } + +/// Test Expression for the `group` Rule. +group_TEST = ${ SOI ~ group ~ EOI } + +/// Test Expression for the `grpchoice` Rule. +grpchoice_TEST = ${ SOI ~ grpchoice ~ EOI } + +/// Test Expression for the `grpent` Rule. +grpent_TEST = ${ SOI ~ grpent ~ EOI } + +/// Test Expression for the `memberkey` Rule. +memberkey_TEST = ${ SOI ~ memberkey ~ EOI } + +/// Test Expression for the `bareword` Rule. +bareword_TEST = ${ SOI ~ bareword ~ EOI } + +/// Test Expression for the `optcom` Rule. +optcom_TEST = ${ SOI ~ optcom ~ EOI } + +/// Test Expression for the `occur` Rule. +occur_TEST = ${ SOI ~ occur ~ EOI } + +/// Test Expression for the `S` Rule. S_TEST = ${ SOI ~ S ~ EOI } -/// Test Expression for the COMMENT Rule. +/// Test Expression for the `COMMENT` Rule. COMMENT_TEST = { SOI ~ COMMENT* ~ EOI } /// Test expression for the URL_BASE64 Rule. URL_BASE64_TEST = { SOI ~ URL_BASE64 ~ EOI } -/// Test expression to the id Rule. +/// Test expression to the `id` Rule. id_TEST = ${ SOI ~ id ~ EOI} -/// Test expression to the bytes Rule. +/// Test expression to the `bytes` Rule. bytes_TEST = ${ SOI ~ bytes ~ EOI} -/// Test expression to the text Rule. +/// Test expression to the `text` Rule. text_TEST = ${ SOI ~ text ~ EOI} -/// Test expression to the uint Rule. +/// Test expression to the `uint` Rule. uint_TEST = ${ SOI ~ uint ~ EOI} -/// Test expression to the int Rule. +/// Test expression to the `int` Rule. int_TEST = ${ SOI ~ int ~ EOI} -/// Test expression to the intfloat Rule. +/// Test expression to the `intfloat` Rule. intfloat_TEST = ${ SOI ~ intfloat ~ EOI} -/// Test expression to the hexfloat Rule. +/// Test expression to the `hexfloat` Rule. hexfloat_TEST = ${ SOI ~ hexfloat ~ EOI} -/// Test expression to the number Rule. +/// Test expression to the `number` Rule. number_TEST = ${ SOI ~ number ~ EOI} -/// Test expression to the value Rule. +/// Test expression to the `value` Rule. value_TEST = ${ SOI ~ value ~ EOI} \ No newline at end of file diff --git a/hermes/crates/cbork/cddl-parser/src/grammar/rfc_8610.pest b/hermes/crates/cbork/cddl-parser/src/grammar/rfc_8610.pest index 0c3f32926..4a609ca51 100644 --- a/hermes/crates/cbork/cddl-parser/src/grammar/rfc_8610.pest +++ b/hermes/crates/cbork/cddl-parser/src/grammar/rfc_8610.pest @@ -1,77 +1,79 @@ //! CDDL Grammar adapted from RFC8610 Appendix B //! https://www.rfc-editor.org/rfc/rfc8610#appendix-B -// cspell: words assignt groupname grpent genericparm assigng +// cspell: words assignt groupname grpent genericparm assigng optcom // cspell: words genericarg rangeop ctlop grpchoice memberkey bareword hexfloat intfloat // cspell: words SCHAR BCHAR PCHAR SESC FFFD Characterset Visiable -cddl = { +cddl = ${ SOI - ~ S ~ rule+ + ~ S ~ (rule ~ S)+ ~ EOI } -rule = { - ( typename ~ assignt ~ type) - | ( groupname ~ assigng ~ grpent) +// ----------------------------------------------------------------------------- +// Rules +rule = ${ + (typename ~ genericparm? ~ S ~ assignt ~ S ~ type) + | (groupname ~ genericparm? ~ S ~ assigng ~ S ~ grpent) } -typename = ${ id ~ genericparm? } -groupname = ${ id ~ genericparm? } +typename = { id } +groupname = { id } assignt = { "=" | "/=" } assigng = { "=" | "//=" } -genericparm = { "<" ~ id ~ ( "," ~ id )* ~ ">" } -genericarg = { "<" ~ type1 ~ ( "," ~ type1)* ~ ">" } - -type = { type1 ~ ( S ~ "/" ~ type1)* } +genericparm = ${ "<" ~ S ~ id ~ S ~ ("," ~ S ~ id ~ S)* ~ ">" } +genericarg = ${ "<" ~ S ~ type1 ~ S ~ ("," ~ S ~ type1 ~ S)* ~ ">" } -type1 = { type2 ~ ( S ~ ( rangeop | ctlop ) ~ type2)? } - -typename_arg = ${ typename ~ genericarg? } -groupname_arg = ${ groupname ~ genericarg? } +// ----------------------------------------------------------------------------- +// Type Declaration +type = ${ type1 ~ (S ~ "/" ~ S ~ type1)* } -tag6 = ${ "#" ~ "6" ~ ("." ~ uint)? ~ "(" ~ S ~ type ~ S ~ ")" } -tag_generic = ${ "#" ~ ASCII_DIGIT ~ ("." ~ uint)? } +type1 = ${ type2 ~ (S ~ (rangeop | ctlop) ~ S ~ type2)? } -type2 = { +type2 = ${ value - | typename_arg - | ( "(" ~ type ~ ")" ) - | ( "{" ~ group ~ "}" ) - | ( "[" ~ group ~ "]" ) - | ( "~" ~ typename_arg ) - | ( "&" ~ "(" ~ group ~ ")" ) - | ( "&" ~ groupname_arg ) - | tag6 - | tag_generic + | typename ~ genericarg? + | ("(" ~ S ~ type ~ S ~ ")") + | ("{" ~ S ~ group ~ S ~ "}") + | ("[" ~ S ~ group ~ S ~ "]") + | ("~" ~ S ~ typename ~ genericarg?) + | ("&" ~ S ~ "(" ~ S ~ group ~ S ~ ")") + | ("&" ~ S ~ groupname ~ genericarg?) + | ("#" ~ "6" ~ ("." ~ uint)? ~ "(" ~ S ~ type ~ S ~ ")") + | ("#" ~ ASCII_DIGIT ~ ("." ~ uint)?) | "#" } rangeop = { "..." | ".." } ctlop = ${ "." ~ id } -group = { grpchoice ~ ( S ~ "//" ~ grpchoice)* } +// ----------------------------------------------------------------------------- +// Group Elements +group = ${ grpchoice ~ (S ~ "//" ~ S ~ grpchoice)* } -grpchoice = { ( grpent ~ ","? )* } +grpchoice = ${ (grpent ~ optcom)* } grpent = ${ - ( (occur ~ S)? ~ (memberkey ~ S)? ~ type ) - | ( (occur ~ S)? ~ groupname ~ genericarg? ) - | ( (occur ~ S)? ~ "(" ~ S ~ group ~ S ~ ")" ) + ((occur ~ S)? ~ (memberkey ~ S)? ~ type) + | ((occur ~ S)? ~ groupname ~ genericarg?) + | ((occur ~ S)? ~ "(" ~ S ~ group ~ S ~ ")") } -memberkey = { - ( type1 ~ "^"? ~ "=>" ) - | ( bareword ~ ":" ) - | ( value ~ ":" ) +memberkey = ${ + (type1 ~ S ~ ("^" ~ S)? ~ "=>") + | ((value | bareword) ~ S ~ ":") } bareword = { id } +/// Optional Comma - Note eligible for producing pairs as this might be useful for linting +optcom = { S ~ ("," ~ S)? } + occur = { - ( uint? ~ "*" ~ uint? ) + (uint? ~ "*" ~ uint?) | "+" | "?" } @@ -82,7 +84,7 @@ occur = { /// All Literal Values value = { number | text | bytes } -/// Literal Numbers - A float if it has fraction or exponent; int otherwise +/// Literal Numbers - A float if it has fraction or exponent; int otherwise number = { hexfloat | intfloat } /// Hex floats of the form -0x123.abc0p+12 @@ -103,16 +105,16 @@ int = ${ "-"? ~ uint } /// Unsigned Integers uint = ${ - ( ASCII_NONZERO_DIGIT ~ ASCII_DIGIT* ) - | ( "0x" ~ ASCII_HEX_DIGIT+ ) - | ( "0b" ~ ASCII_BIN_DIGIT+ ) + (ASCII_NONZERO_DIGIT ~ ASCII_DIGIT*) + | ("0x" ~ ASCII_HEX_DIGIT+) + | ("0b" ~ ASCII_BIN_DIGIT+) | "0" } /// Literal Text text = ${ "\"" ~ SCHAR* ~ "\"" } -/// Literal Bytes - Note CDDL Spec incorrectly defines b64''. +/// Literal Bytes. bytes = ${ bytes_hex | bytes_b64 | bytes_text } bytes_hex = ${ "h" ~ "'" ~ HEX_PAIR* ~ "'" } bytes_b64 = ${ "b64" ~ "'" ~ URL_BASE64 ~ "'" } @@ -121,13 +123,8 @@ bytes_text = ${ "'" ~ BCHAR* ~ "'" } // ----------------------------------------------------------------------------- // Simple multiple character sequences -/// identifier, called the `name` in the CDDL spec. -id = ${ - group_socket | - type_socket | - name -} - +/// identifier, called the `name` in the CDDL spec. +id = ${ group_socket | type_socket | name } /// Special form of a name that represents a Group Socket. group_socket = ${ "$$" ~ ( ( "-" | "." )* ~ NAME_END )* } /// Special form of a name that represents a Type Socket. @@ -146,11 +143,10 @@ URL_BASE64 = _{ S ~ ( URL_BASE64_ALPHA ~ S)* ~ URL_BASE64_PAD? } // ----------------------------------------------------------------------------- // Characters, Whitespace and Comments -S = _{ WHITESPACE* } +S = _{ (COMMENT | WHITESPACE)* } WHITESPACE = _{ " " | "\t" | NEWLINE } -COMMENT = _{ ";" ~ (PCHAR | "\t")* ~ NEWLINE } +COMMENT = { ";" ~ (PCHAR | "\t")* ~ NEWLINE } -// URL Base64 Characterset. URL_BASE64_ALPHA = _{ ASCII_ALPHA | ASCII_DIGIT | "-" | "_" } // Optional Padding that goes at the end of Base64. URL_BASE64_PAD = _{ "~" } @@ -177,7 +173,7 @@ BCHAR = _{ BCHAR_ASCII_VISIBLE | UNICODE_CHAR | SESC | NEWLINE } /// Escaping code to allow invalid characters to be used in text or byte strings. SESC = ${ "\\" ~ (ASCII_VISIBLE | UNICODE_CHAR) } -/// All Visiable Ascii characters. +/// All Visible Ascii characters. ASCII_VISIBLE = _{ ' '..'~' } /// Ascii subset valid for text strings. @@ -187,4 +183,4 @@ SCHAR_ASCII_VISIBLE = _{ ' '..'!' | '#'..'[' | ']'..'~' } BCHAR_ASCII_VISIBLE = _{ ' '..'&' | '('..'[' | ']'..'~' } /// Valid non ascii unicode Characters -UNICODE_CHAR = _{ '\u{80}'..'\u{10FFFD}' } +UNICODE_CHAR = _{ '\u{80}'..'\u{10FFFD}' } \ No newline at end of file diff --git a/hermes/crates/cbork/cddl-parser/src/grammar/rfc_9615.pest b/hermes/crates/cbork/cddl-parser/src/grammar/rfc_9165.pest similarity index 100% rename from hermes/crates/cbork/cddl-parser/src/grammar/rfc_9615.pest rename to hermes/crates/cbork/cddl-parser/src/grammar/rfc_9165.pest diff --git a/hermes/crates/cbork/cddl-parser/src/lib.rs b/hermes/crates/cbork/cddl-parser/src/lib.rs index 241283f85..6f67d1123 100644 --- a/hermes/crates/cbork/cddl-parser/src/lib.rs +++ b/hermes/crates/cbork/cddl-parser/src/lib.rs @@ -20,12 +20,12 @@ pub mod rfc_8610 { pub struct RFC8610Parser; } -pub mod rfc_9615 { +pub mod rfc_9165 { pub use pest::Parser; #[derive(pest_derive::Parser)] #[grammar = "grammar/rfc_8610.pest"] - #[grammar = "grammar/rfc_9615.pest"] + #[grammar = "grammar/rfc_9165.pest"] pub struct RFC8610Parser; } @@ -34,7 +34,7 @@ pub mod cddl { #[derive(pest_derive::Parser)] #[grammar = "grammar/rfc_8610.pest"] - #[grammar = "grammar/rfc_9615.pest"] + #[grammar = "grammar/rfc_9165.pest"] #[grammar = "grammar/cddl_modules.pest"] pub struct RFC8610Parser; } @@ -45,7 +45,7 @@ pub mod cddl_test { // Parser with DEBUG rules. These rules are only used in tests. #[derive(pest_derive::Parser)] #[grammar = "grammar/rfc_8610.pest"] - #[grammar = "grammar/rfc_9615.pest"] + #[grammar = "grammar/rfc_9165.pest"] #[grammar = "grammar/cddl_modules.pest"] #[grammar = "grammar/cddl_test.pest"] // Ideally this would only be used in tests. pub struct CDDLTestParser; @@ -55,9 +55,9 @@ pub mod cddl_test { pub enum Extension { /// RFC8610 ONLY limited parser. RFC8610Parser, - /// RFC8610 and RFC9615 limited parser. - RFC9615Parser, - /// RFC8610, RFC9615, and CDDL modules. + /// RFC8610 and RFC9165 limited parser. + RFC9165Parser, + /// RFC8610, RFC9165, and CDDL modules. CDDLParser, } @@ -68,7 +68,7 @@ pub const POSTLUDE: &str = include_str!("grammar/postlude.cddl"); #[derive(Debug)] pub enum AST<'a> { RFC8610(Pairs<'a, rfc_8610::Rule>), - RFC9615(Pairs<'a, rfc_9615::Rule>), + RFC9165(Pairs<'a, rfc_9165::Rule>), CDDL(Pairs<'a, cddl::Rule>), } @@ -77,8 +77,8 @@ pub enum AST<'a> { pub enum CDDLErrorType { /// An error related to RFC 8610 extension. RFC8610(Error), - /// An error related to RFC 9615 extension. - RFC9615(Error), + /// An error related to RFC 9165 extension. + RFC9165(Error), /// An error related to CDDL modules extension. CDDL(Error), } @@ -116,7 +116,7 @@ pub struct CDDLError(CDDLErrorType); /// ``` pub fn parse_cddl<'a>( input: &'a mut String, extension: &Extension, -) -> Result>, Box> { +) -> Result, Box> { input.push_str("\n\n"); input.push_str(POSTLUDE); @@ -126,10 +126,10 @@ pub fn parse_cddl<'a>( .map(AST::RFC8610) .map_err(CDDLErrorType::RFC8610) }, - Extension::RFC9615Parser => { - rfc_9615::RFC8610Parser::parse(rfc_9615::Rule::cddl, input) - .map(AST::RFC9615) - .map_err(CDDLErrorType::RFC9615) + Extension::RFC9165Parser => { + rfc_9165::RFC8610Parser::parse(rfc_9165::Rule::cddl, input) + .map(AST::RFC9165) + .map_err(CDDLErrorType::RFC9165) }, Extension::CDDLParser => { cddl::RFC8610Parser::parse(cddl::Rule::cddl, input) @@ -138,12 +138,7 @@ pub fn parse_cddl<'a>( }, }; - result.map(Box::new).map_err(|e| { - println!("{e:?}"); - println!("{e}"); - - Box::new(CDDLError::from(e)) - }) + result.map_err(|e| Box::new(CDDLError::from(e))) } #[cfg(test)] diff --git a/hermes/crates/cbork/cddl-parser/tests/byte_sequences.rs b/hermes/crates/cbork/cddl-parser/tests/byte_sequences.rs index d17203754..5df53da86 100644 --- a/hermes/crates/cbork/cddl-parser/tests/byte_sequences.rs +++ b/hermes/crates/cbork/cddl-parser/tests/byte_sequences.rs @@ -1,91 +1,24 @@ -// cspell: words hexpair rstuvw abcdefghijklmnopqrstuvwyz rstuvw +// cspell: words hexpair rstuvw abcdefghijklmnopqrstuvwyz rstuvw Xhhb Bhcm -use cddl_parser::{ - self, - cddl_test::{CDDLTestParser, Parser, Rule}, -}; +use cddl_parser::cddl_test::Rule; + +mod common; +use common::byte_sequences::*; #[test] /// Test if the `HEX_PAIR` rule passes properly. fn check_hexpair() { - let hex_pairs = vec!["00", "ab", "de", "0f", "f0"]; - - let not_hex_pairs = vec!["0", " 0", "0 ", "az", "0p"]; - - for hp in hex_pairs { - let parse = CDDLTestParser::parse(Rule::HEX_PAIR, hp); - assert!(parse.is_ok()); - } - - for hp in not_hex_pairs { - let parse = CDDLTestParser::parse(Rule::HEX_PAIR, hp); - assert!(parse.is_err()); - } + common::check_tests_rule(Rule::HEX_PAIR, HEXPAIR_PASSES, HEXPAIR_FAILS); } #[test] /// Test if the `URL_BASE64` rule passes properly. fn check_url_base64() { - let tests = vec![ - "abcdefghijklmnopq rstuvw yz01\t23456789-_ABCDEFGHIJKLMNOPQRSTUVWXYZ~", - "abcdefghijklmnopqrstuvwyz0123456789-_ABCDEFGHIJKLMNOPQRSTUVWXYZ", - ]; - - let fails = vec![ - "abcdefghijklmnopq # rstuvw yz01\t23456789-_ABCDEFGHIJKLMNOPQRSTUVWXYZ~ ", - "abcdefghijklmnopq $ rstuvw yz01\t23456789-_ABCDEFGHIJKLMNOPQRSTUVWXYZ~\t", - "abcdefghijklmnopq % rstuvw yz01\t23456789-_ABCDEFGHIJKLMNOPQRSTUVWXYZ~\n", - "abcdefghijklmnopq ^ rstuvw yz01\t23456789-_ABCDEFGHIJKLMNOPQRSTUVWXYZ~\r", - "abcdefghijklmnopq & rstuvw yz01\t23456789-_ABCDEFGHIJKLMNOPQRSTUVWXYZ~\r\n", - ]; - - for test in tests { - let parse = CDDLTestParser::parse(Rule::URL_BASE64_TEST, test); - assert!(parse.is_ok()); - } - - for test in fails { - let parse = CDDLTestParser::parse(Rule::URL_BASE64_TEST, test); - assert!(parse.is_err()); - } + common::check_tests_rule(Rule::URL_BASE64_TEST, URL_BASE64_PASSES, URL_BASE64_FAILS); } #[test] /// Test if the `bytes` rule passes properly. fn check_bytes() { - let test = vec![ - "h''", - "b64''", - "''", - "h'00'", - "h'00112233445566778899aabbccddeeff0123456789abcdef'", - "h'0 1 2 3 4 5 6 7 8 9 a b c d e f'", - "h' 0 1 2 3 4 5\r 6 7 \n 8 9 a\r\n\t b c d e f'", - "b64'abcdefghijklmnopq rstuvw yz01\t23456789-_ABCDEFGHIJKLMNOPQRSTUVWXYZ~'", - "b64'abcdefghijklmnopq rstuvw yz01\t23456789-_ABCDEFGHIJKLMNOPQRSTUVWXYZ'", - "''", - "'text\n that gets converted \\\' into a byte string...'", - ]; - - let fail = vec![ - "h64", - "b64", - "\"\"", - "h ''", - "b64 ''", - "h'001'", - "b64'abcdefghijklmnopq # rstuvw yz01\t23456789-_ABCDEFGHIJKLMNOPQRSTUVWXYZ~'", - "b64'abcdefghijklmnopq & rstuvw yz01\t23456789-_ABCDEFGHIJKLMNOPQRSTUVWXYZ'", - "'\u{7}'", - ]; - - for test in test { - let parse = CDDLTestParser::parse(Rule::bytes_TEST, test); - assert!(parse.is_ok()); - } - - for test in fail { - let parse = CDDLTestParser::parse(Rule::bytes_TEST, test); - assert!(parse.is_err()); - } + common::check_tests_rule(Rule::bytes_TEST, BYTES_PASSES, BYTES_FAILS); } diff --git a/hermes/crates/cbork/cddl-parser/tests/cddl.rs b/hermes/crates/cbork/cddl-parser/tests/cddl.rs new file mode 100644 index 000000000..628ac0acb --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/cddl.rs @@ -0,0 +1,52 @@ +use std::{ffi::OsStr, fs, io::Result}; + +use cddl_parser::{parse_cddl, Extension}; + +#[test] +/// # Panics +fn parse_cddl_files() { + let entries = fs::read_dir("tests/cddl").expect("`tests/cddl` directory must exist"); + + let mut file_paths: Vec<_> = entries + .filter_map(Result::ok) + .filter_map(|x| x.path().is_file().then_some(x.path())) + .collect(); + + file_paths.sort(); + + let valid_file_paths = file_paths.iter().filter(|p| { + p.file_name() + .and_then(OsStr::to_str) + .map(|p| p.starts_with("valid")) + .is_some_and(|p| p) + }); + let invalid_file_paths = file_paths.iter().filter(|p| { + p.file_name() + .and_then(OsStr::to_str) + .map(|p| p.starts_with("invalid")) + .is_some_and(|p| p) + }); + + // test for valid files + let mut err_messages = vec![]; + for file_path in valid_file_paths { + let mut content = fs::read_to_string(file_path).expect("failed to read a file"); + + if let Err(e) = parse_cddl(&mut content, &Extension::CDDLParser) { + err_messages.push(format!("{}) {file_path:?} {e}", err_messages.len() + 1)); + } + } + + // test for invalid files + for file_path in invalid_file_paths { + let mut content = fs::read_to_string(file_path).expect("failed to read a file"); + + let result = parse_cddl(&mut content, &Extension::CDDLParser); + + assert!(result.is_err(), "{:?} is expected to fail", &file_path); + } + + // summary + let err_msg = err_messages.join("\n\n"); + assert!(err_msg.is_empty(), "{err_msg}"); +} diff --git a/hermes/crates/cbork/cddl-parser/tests/cddl/invalid_rfc8610_sample_1.cddl b/hermes/crates/cbork/cddl-parser/tests/cddl/invalid_rfc8610_sample_1.cddl new file mode 100644 index 000000000..f0b22f1e4 --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/cddl/invalid_rfc8610_sample_1.cddl @@ -0,0 +1 @@ +parentheses_mismatch = ( int \ No newline at end of file diff --git a/hermes/crates/cbork/cddl-parser/tests/cddl/invalid_rfc8610_sample_2.cddl b/hermes/crates/cbork/cddl-parser/tests/cddl/invalid_rfc8610_sample_2.cddl new file mode 100644 index 000000000..e05f50fdf --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/cddl/invalid_rfc8610_sample_2.cddl @@ -0,0 +1,4 @@ +; cspell: words tstr + +sample = { + tstr => tstr \ No newline at end of file diff --git a/hermes/crates/cbork/cddl-parser/tests/cddl/invalid_rfc8610_sample_3.cddl b/hermes/crates/cbork/cddl-parser/tests/cddl/invalid_rfc8610_sample_3.cddl new file mode 100644 index 000000000..cc09425d0 --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/cddl/invalid_rfc8610_sample_3.cddl @@ -0,0 +1,5 @@ +; cspell: words tstr + +sample = ; comment here { + tstr => tstr +} \ No newline at end of file diff --git a/hermes/crates/cbork/cddl-parser/tests/cddl/invalid_rfc8610_sample_4.cddl b/hermes/crates/cbork/cddl-parser/tests/cddl/invalid_rfc8610_sample_4.cddl new file mode 100644 index 000000000..615c9c7f3 --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/cddl/invalid_rfc8610_sample_4.cddl @@ -0,0 +1,2 @@ +outer = { inner: int } +incorrectly_nested = outer inner: int \ No newline at end of file diff --git a/hermes/crates/cbork/cddl-parser/tests/cddl/invalid_rfc8610_sample_5.cddl b/hermes/crates/cbork/cddl-parser/tests/cddl/invalid_rfc8610_sample_5.cddl new file mode 100644 index 000000000..494d46c73 --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/cddl/invalid_rfc8610_sample_5.cddl @@ -0,0 +1 @@ +missing_definition \ No newline at end of file diff --git a/hermes/crates/cbork/cddl-parser/tests/cddl/invalid_rfc8610_sample_6.cddl b/hermes/crates/cbork/cddl-parser/tests/cddl/invalid_rfc8610_sample_6.cddl new file mode 100644 index 000000000..6120ddd74 --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/cddl/invalid_rfc8610_sample_6.cddl @@ -0,0 +1 @@ +invalid_char = int & \ No newline at end of file diff --git a/hermes/crates/cbork/cddl-parser/tests/cddl/invalid_rfc8610_sample_7.cddl b/hermes/crates/cbork/cddl-parser/tests/cddl/invalid_rfc8610_sample_7.cddl new file mode 100644 index 000000000..a89f99313 --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/cddl/invalid_rfc8610_sample_7.cddl @@ -0,0 +1 @@ +empty_rule = \ No newline at end of file diff --git a/hermes/crates/cbork/cddl-parser/tests/cddl/invalid_rfc8610_sample_8.cddl b/hermes/crates/cbork/cddl-parser/tests/cddl/invalid_rfc8610_sample_8.cddl new file mode 100644 index 000000000..0ad76396f --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/cddl/invalid_rfc8610_sample_8.cddl @@ -0,0 +1 @@ +unexpected_token = % \ No newline at end of file diff --git a/hermes/crates/cbork/cddl-parser/tests/cddl/invalid_rfc8610_sample_9.cddl b/hermes/crates/cbork/cddl-parser/tests/cddl/invalid_rfc8610_sample_9.cddl new file mode 100644 index 000000000..ebad7d015 --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/cddl/invalid_rfc8610_sample_9.cddl @@ -0,0 +1,2 @@ +missing_group_open int +missing_group_close = int \ No newline at end of file diff --git a/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_arrays.cddl b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_arrays.cddl new file mode 100644 index 000000000..04465a589 --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_arrays.cddl @@ -0,0 +1,11 @@ +; 3.4. Arrays + +; cspell: words tstr + +unlimited-people = [* person] +one-or-two-people = [1*2 person] +at-least-two-people = [2* person] +person = ( + name: tstr, + age: uint, +) \ No newline at end of file diff --git a/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_ctrl_bits.cddl b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_ctrl_bits.cddl new file mode 100644 index 000000000..096b876e7 --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_ctrl_bits.cddl @@ -0,0 +1,19 @@ +; 3.8.2. Control Operator .bits + +; cspell: words tcpflagbytes rwxbits + +tcpflagbytes = bstr .bits flags +flags = &( + fin: 8, + syn: 9, + rst: 10, + psh: 11, + ack: 12, + urg: 13, + ece: 14, + cwr: 15, + ns: 0, +) / (4..7) ; data offset bits + +rwxbits = uint .bits rwx +rwx = &(r: 2, w: 1, x: 0) \ No newline at end of file diff --git a/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_ctrl_ord.cddl b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_ctrl_ord.cddl new file mode 100644 index 000000000..3cc737c91 --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_ctrl_ord.cddl @@ -0,0 +1,8 @@ +; 3.8.6. Control Operators .lt, .le, .gt, .ge, .eq, .ne, and .default + +speed = number .ge 0 ; unit: m/s + +timer = { + time: uint, + ? displayed-step: (number .gt 0) .default 1 +} \ No newline at end of file diff --git a/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_ctrl_regexp.cddl b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_ctrl_regexp.cddl new file mode 100644 index 000000000..04c4f6a61 --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_ctrl_regexp.cddl @@ -0,0 +1,7 @@ +; 3.8.3. Control Operator .regexp + +; cspell: words tstr + +nai = tstr .regexp "[A-Za-z0-9]+@[A-Za-z0-9]+(\\.[A-Za-z0-9]+)+" + +; "N1@CH57HF.4Znqe0.dYJRN.igjf" should pass this regexp \ No newline at end of file diff --git a/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_ctrl_size.cddl b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_ctrl_size.cddl new file mode 100644 index 000000000..6a2b27601 --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_ctrl_size.cddl @@ -0,0 +1,8 @@ +; 3.8.1. Control Operator .size + +full-address = [[+ label], ip4, ip6] +ip4 = bstr .size 4 +ip6 = bstr .size 16 +label = bstr .size (1..63) + +audio_sample = uint .size 3 ; 24-bit, equivalent to 0...16777216 \ No newline at end of file diff --git a/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_ctrl_within_and.cddl b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_ctrl_within_and.cddl new file mode 100644 index 000000000..d34003df0 --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_ctrl_within_and.cddl @@ -0,0 +1,9 @@ +; 3.8.5. Control Operators .within and .and + +message = $message .within message-structure +message-structure = [message_type, *message_option] +message_type = 0..255 +message_option = any + +$message /= [3, dough: text, topping: [* text]] +$message /= [4, noodles: text, sauce: text, parmesan: bool] \ No newline at end of file diff --git a/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_cuts_in_maps.cddl b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_cuts_in_maps.cddl new file mode 100644 index 000000000..e2b49c184 --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_cuts_in_maps.cddl @@ -0,0 +1,8 @@ +; 3.5.4. Cuts in Maps + +; cspell: words tstr + +extensible-map-example = { + ? "optional-key" => int, + * tstr => any +} \ No newline at end of file diff --git a/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_cuts_in_maps_alt_1.cddl b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_cuts_in_maps_alt_1.cddl new file mode 100644 index 000000000..ac73c3649 --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_cuts_in_maps_alt_1.cddl @@ -0,0 +1,8 @@ +; 3.5.4. Cuts in Maps + +; cspell: words tstr + +extensible-map-example = { + ? "optional-key" ^ => int, + * tstr => any +} \ No newline at end of file diff --git a/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_cuts_in_maps_alt_2.cddl b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_cuts_in_maps_alt_2.cddl new file mode 100644 index 000000000..1283a7c7d --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_cuts_in_maps_alt_2.cddl @@ -0,0 +1,8 @@ +; 3.5.4. Cuts in Maps + +; cspell: words tstr + +extensible-map-example = { + ? "optional-key": int, + * tstr => any +} \ No newline at end of file diff --git a/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_cuts_in_maps_alt_3.cddl b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_cuts_in_maps_alt_3.cddl new file mode 100644 index 000000000..f8e239051 --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_cuts_in_maps_alt_3.cddl @@ -0,0 +1,8 @@ +; 3.5.4. Cuts in Maps + +; cspell: words tstr + +extensible-map-example = { + ? optional-key: int, + * tstr => any +} \ No newline at end of file diff --git a/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_example_array_object.cddl b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_example_array_object.cddl new file mode 100644 index 000000000..0590259b7 --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_example_array_object.cddl @@ -0,0 +1,10 @@ +root = [2*2 { + precision: text, + Latitude: float, + Longitude: float, + Address: text, + City: text, + State: text, + Zip: text, + Country: text +}] \ No newline at end of file diff --git a/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_example_nested_object.cddl b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_example_nested_object.cddl new file mode 100644 index 000000000..6f36f7942 --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_example_nested_object.cddl @@ -0,0 +1,22 @@ +root = { image } + +image = ( + Image: { + size, + Title: text, + thumbnail, + IDs: [* int] + } +) + +size = ( + Width: 0..1280 + Height: 0..1024 +) + +thumbnail = ( + Thumbnail: { + size, + Url: ~uri + } +) \ No newline at end of file diff --git a/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_example_nested_object_compact.cddl b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_example_nested_object_compact.cddl new file mode 100644 index 000000000..1b00b80bb --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_example_nested_object_compact.cddl @@ -0,0 +1,12 @@ +root = { + Image: { + size, Title: text, + Thumbnail: { size, Url: ~uri }, + IDs: [* int] + } +} + +size = ( + Width: 0..1280, + Height: 0..1024, +) \ No newline at end of file diff --git a/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_generics.cddl b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_generics.cddl new file mode 100644 index 000000000..a541cd121 --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_generics.cddl @@ -0,0 +1,4 @@ +; 3.10. Generics + +messages = message<"reboot", "now"> / message<"sleep", 1..100> +message = {type: t, value: v} \ No newline at end of file diff --git a/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_group_to_choice.cddl b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_group_to_choice.cddl new file mode 100644 index 000000000..e172f919f --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_group_to_choice.cddl @@ -0,0 +1,13 @@ +; 2.2.2.2. Turning a Group into a Choice + +; cspell: words basecolors + +terminal-color = &basecolors +basecolors = ( + black: 0, red: 1, green: 2, yellow: 3, + blue: 4, magenta: 5, cyan: 6, white: 7, +) +extended-color = &( + basecolors, + orange: 8, pink: 9, purple: 10, brown: 11, +) \ No newline at end of file diff --git a/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_non_deterministic_order.cddl b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_non_deterministic_order.cddl new file mode 100644 index 000000000..9c8738ba3 --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_non_deterministic_order.cddl @@ -0,0 +1,13 @@ +; 3.5.3. Non-deterministic Order + +labeled-values = { + ? fritz: number, + * label => value +} +label = text +value = number + +do-not-do-this = { + int => int, + int => 6, +} \ No newline at end of file diff --git a/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_occurence.cddl b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_occurence.cddl new file mode 100644 index 000000000..10327de08 --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_occurence.cddl @@ -0,0 +1,7 @@ +; 3.2. Occurrence + +apartment = { + kitchen: size, + * bedroom: size, +} +size = float ; in m2 \ No newline at end of file diff --git a/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_op_precedence.cddl b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_op_precedence.cddl new file mode 100644 index 000000000..39c494fc8 --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_op_precedence.cddl @@ -0,0 +1,21 @@ +; 3.11. Operator Precedence + +t = [group1] +group1 = (a / b // c / d) +a = 1 b = 2 c = 3 d = 4 + +t = {group2} +group2 = (? ab: a / b // cd: c / d) +a = 1 b = 2 c = 3 d = 4 + +t = [group3] +group3 = (+ a / b / c) +a = 1 b = 2 c = 3 + +t = [group4] +group4 = (+ a // b / c) +a = 1 b = 2 c = 3 + +t = [group4a] +group4a = ((+ a) // (b / c)) +a = 1 b = 2 c = 3 \ No newline at end of file diff --git a/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_ranges.cddl b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_ranges.cddl new file mode 100644 index 000000000..f7190a325 --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_ranges.cddl @@ -0,0 +1,16 @@ +; 2.2.2.1. Ranges + +device-address = byte +max-byte = 255 +byte = 0..max-byte ; inclusive range +first-non-byte = 256 +byte1 = 0...first-non-byte ; byte1 is equivalent to byte + +int-range = 0..10 ; only integers match +float-range = 0.0..10.0 ; only floats match +BAD-range1 = 0..10.0 ; NOT DEFINED +BAD-range2 = 0.0..10 ; NOT DEFINED +numeric-range = int-range / float-range + +non-range-expression = min..max +range-expression = min .. max \ No newline at end of file diff --git a/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_represenation_types.cddl b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_represenation_types.cddl new file mode 100644 index 000000000..dfd0f4069 --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_represenation_types.cddl @@ -0,0 +1,12 @@ +; 2.2.3. Representation Types + +; cspell: words cbor tstr + +my_breakfast = #6.55799(breakfast) ; cbor-any is too general! +breakfast = cereal / porridge +cereal = #6.998(tstr) +porridge = #6.999([liquid, solid]) +liquid = milk / water +milk = 0 +water = 1 +solid = tstr \ No newline at end of file diff --git a/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_reputon_compact.cddl b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_reputon_compact.cddl new file mode 100644 index 000000000..350acd521 --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_reputon_compact.cddl @@ -0,0 +1,19 @@ +; cspell: words reputons reputon + +reputation-object = { + application: text + reputons: [* reputon] +} + +reputon = { + rater: text + assertion: text + rated: text + rating: float16 + ? confidence: float16 + ? normal-rating: float16 + ? sample-size: uint + ? generated: uint + ? expires: uint + * text => any +} \ No newline at end of file diff --git a/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_reputon_full.cddl b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_reputon_full.cddl new file mode 100644 index 000000000..9fdf25462 --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_reputon_full.cddl @@ -0,0 +1,40 @@ +; cspell: words reputons reputon + +reputation-object = { + reputation-context, + reputon-list +} + +reputation-context = ( + application: text +) + +reputon-list = ( + reputons: reputon-array +) + +reputon-array = [* reputon] + +reputon = { + rater-value, + assertion-value, + rated-value, + rating-value, + ? conf-value, + ? normal-value, + ? sample-value, + ? gen-value, + ? expire-value, + * ext-value, +} + +rater-value = ( rater: text ) +assertion-value = ( assertion: text ) +rated-value = ( rated: text ) +rating-value = ( rating: float16 ) +conf-value = ( confidence: float16 ) +normal-value = ( normal-rating: float16 ) +sample-value = ( sample-size: uint ) +gen-value = ( generated: uint ) +expire-value = ( expires: uint ) +ext-value = ( text => any ) diff --git a/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_simple_1.cddl b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_simple_1.cddl new file mode 100644 index 000000000..a3a5a0160 --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_simple_1.cddl @@ -0,0 +1,9 @@ +; Figure 1: Using a Group Directly in a Map + +; cspell: words tstr + +person = { + age: int, + name: tstr, + employer: tstr, +} \ No newline at end of file diff --git a/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_simple_2.cddl b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_simple_2.cddl new file mode 100644 index 000000000..73da918a3 --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_simple_2.cddl @@ -0,0 +1,9 @@ +; Figure 2: A Basic Group + +; cspell: words tstr + +pii = ( + age: int, + name: tstr, + employer: tstr, +) \ No newline at end of file diff --git a/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_simple_3.cddl b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_simple_3.cddl new file mode 100644 index 000000000..cb53425a1 --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_simple_3.cddl @@ -0,0 +1,13 @@ +; Figure 3: Using a Group by Name + +; cspell: words tstr + +person = { + pii +} + +pii = ( + age: int, + name: tstr, + employer: tstr, +) \ No newline at end of file diff --git a/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_simple_4.cddl b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_simple_4.cddl new file mode 100644 index 000000000..d787a8838 --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_simple_4.cddl @@ -0,0 +1,9 @@ +; Figure 4: Using a Parenthesized Group in a Map + +; cspell: words tstr + +person = {( + age: int, + name: tstr, + employer: tstr, +)} \ No newline at end of file diff --git a/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_simple_5.cddl b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_simple_5.cddl new file mode 100644 index 000000000..deae51f7e --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_simple_5.cddl @@ -0,0 +1,15 @@ +; Figure 5: Maps with Copy/Paste + +; cspell: words tstr + +person = { + age: int, + name: tstr, + employer: tstr, +} + +dog = { + age: int, + name: tstr, + leash-length: float, +} \ No newline at end of file diff --git a/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_simple_6.cddl b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_simple_6.cddl new file mode 100644 index 000000000..1be65c13e --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_simple_6.cddl @@ -0,0 +1,18 @@ +; Figure 6: Using a Group for Factorization + +; cspell: words tstr + +person = { + identity, + employer: tstr, +} + +dog = { + identity, + leash-length: float, +} + +identity = ( + age: int, + name: tstr, +) \ No newline at end of file diff --git a/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_simple_7.cddl b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_simple_7.cddl new file mode 100644 index 000000000..0bf9dba22 --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_simple_7.cddl @@ -0,0 +1,17 @@ +; 2.2.2. Choices + +; cspell: words tstr + +attire = "bow tie" / "necktie" / "Internet attire" +protocol = 6 / 17 + +address = { delivery } + +delivery = ( +street: tstr, ? number: uint, city // +po-box: uint, city // +per-pickup: true ) + +city = ( +name: tstr, zip-code: uint +) \ No newline at end of file diff --git a/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_simple_8.cddl b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_simple_8.cddl new file mode 100644 index 000000000..d55779ca6 --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_simple_8.cddl @@ -0,0 +1,9 @@ +; 2.2.2. Choices + +; cspell: words tstr + +attire /= "swimwear" + +delivery //= ( +lat: float, long: float, drone-type: tstr +) \ No newline at end of file diff --git a/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_simple_9.cddl b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_simple_9.cddl new file mode 100644 index 000000000..517e44c45 --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_simple_9.cddl @@ -0,0 +1,9 @@ +; cspell: words tstr bareword + +; This is a comment +person = { g } + +g = ( + "name": tstr, + age: int, ; "age" is a bareword +) \ No newline at end of file diff --git a/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_socket_plug.cddl b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_socket_plug.cddl new file mode 100644 index 000000000..e42eac779 --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_socket_plug.cddl @@ -0,0 +1,15 @@ +; 3.9. Socket/Plug + +tcp-header = {seq: uint, ack: uint, * $$tcp-option} + +; later, in a different file + +$$tcp-option //= ( +sack: [+(left: uint, right: uint)] +) + +; and, maybe in another file + +$$tcp-option //= ( + sack-permitted: true +) \ No newline at end of file diff --git a/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_socket_plug_ext.cddl b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_socket_plug_ext.cddl new file mode 100644 index 000000000..70d981cc1 --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_socket_plug_ext.cddl @@ -0,0 +1,28 @@ +; 3.9. Socket/Plug + +; cspell: words tstr personaldata shoesize + +PersonalData = { + ? displayName: tstr, + NameComponents, + ? age: uint, + * $$personaldata-extensions +} + +NameComponents = ( + ? firstName: tstr, + ? familyName: tstr, +) + +; The above already works as is. +; But then, we can add later: + +$$personaldata-extensions //= ( + favorite-salsa: tstr, +) + +; and again, somewhere else: + +$$personaldata-extensions //= ( + shoesize: uint, +) \ No newline at end of file diff --git a/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_structs.cddl b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_structs.cddl new file mode 100644 index 000000000..f58d9f46a --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_structs.cddl @@ -0,0 +1,32 @@ +; 3.5.1. Structs + +; cspell: words tstr + +Geography = [ + city : tstr, + gpsCoordinates : GpsCoordinates, +] + +GpsCoordinates = { + longitude : uint, ; degrees, scaled by 10^7 + latitude : uint, ; degrees, scaled by 10^7 +} + +located-samples = { + sample-point: int, + samples: [+ float], + * equipment-type => equipment-tolerances, +} +equipment-type = [name: tstr, manufacturer: tstr] +equipment-tolerances = [+ [float, float]] + +PersonalData = { + ? displayName: tstr, + NameComponents, + ? age: uint, +} + +NameComponents = ( + ? firstName: tstr, + ? familyName: tstr, +) \ No newline at end of file diff --git a/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_structs_alt.cddl b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_structs_alt.cddl new file mode 100644 index 000000000..4787b9674 --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_structs_alt.cddl @@ -0,0 +1,18 @@ +; 3.5.1. Structs + +; cspell: words tstr + +Geography = [ + city : tstr, + gpsCoordinates : GpsCoordinates, +] + +GpsCoordinates = { + longitude : uint, ; degrees, scaled by 10^7 + latitude : uint, ; degrees, scaled by 10^7 +} + +located-samples = { + "sample-point" => int, + "samples" => [+ float], +} \ No newline at end of file diff --git a/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_tables.cddl b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_tables.cddl new file mode 100644 index 000000000..bce2eab8c --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_tables.cddl @@ -0,0 +1,10 @@ +; 3.5.2. Tables + +; cspell: words tstr tostring mynumber + +square-roots = {* x => y} +x = int +y = float + +tostring = {* mynumber => tstr} +mynumber = int / float \ No newline at end of file diff --git a/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_tags.cddl b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_tags.cddl new file mode 100644 index 000000000..471f76cd8 --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_tags.cddl @@ -0,0 +1,9 @@ +; 3.6. Tags + +; cspell: words biguint buuid tstr + +biguint = #6.2(bstr) + +buuid = #6.37(bstr) + +my_uri = #6.32(tstr) / tstr \ No newline at end of file diff --git a/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_unwrapping.cddl b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_unwrapping.cddl new file mode 100644 index 000000000..0d7fe9aaa --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_unwrapping.cddl @@ -0,0 +1,27 @@ +; 3.7. Unwrapping + +basic-header-group = ( + field1: int, + field2: text, +) + +basic-header = [ basic-header-group ] + +advanced-header = [ + basic-header-group, + field3: bytes, + field4: number, ; as in the tagged type "time" +] + +; Unwrapping simplifies this to: + +basic-header = [ + field1: int, + field2: text, +] + +advanced-header = [ + ~basic-header, + field3: bytes, + field4: ~time, +] \ No newline at end of file diff --git a/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_unwrapping_alt.cddl b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_unwrapping_alt.cddl new file mode 100644 index 000000000..24813ddb7 --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/cddl/valid_rfc8610_unwrapping_alt.cddl @@ -0,0 +1,12 @@ +; Unwrapping simplifies this to: + +basic-header = [ + field1: int, + field2: text, +] + +advanced-header = [ + ~basic-header, + field3: bytes, + field4: ~time, +] diff --git a/hermes/crates/cbork/cddl-parser/tests/character_sets.rs b/hermes/crates/cbork/cddl-parser/tests/character_sets.rs index b713355ef..77b4682ec 100644 --- a/hermes/crates/cbork/cddl-parser/tests/character_sets.rs +++ b/hermes/crates/cbork/cddl-parser/tests/character_sets.rs @@ -44,7 +44,7 @@ fn check_bchar() { for x in ('\u{0}'..='\u{ff}').map(char::from) { let test = format!("{x}"); let parse = CDDLTestParser::parse(Rule::BCHAR, &test); - if x != '\n' && x != '\r' && x < ' ' || x == '\u{27}' || x == '\u{5c}' || x == '\u{7f}' { + if !matches!(x, '\n' | '\r') && x < ' ' || matches!(x, '\t' | '\'' | '\\' | '\u{7f}') { assert!(parse.is_err()); } else { assert!(parse.is_ok()); diff --git a/hermes/crates/cbork/cddl-parser/tests/comments.rs b/hermes/crates/cbork/cddl-parser/tests/comments.rs index eb3328df2..f819072ab 100644 --- a/hermes/crates/cbork/cddl-parser/tests/comments.rs +++ b/hermes/crates/cbork/cddl-parser/tests/comments.rs @@ -1,55 +1,21 @@ -use cddl_parser::{ - self, - cddl_test::{CDDLTestParser, Parser, Rule}, -}; +use cddl_parser::{self, cddl_test::Rule}; + +mod common; +use common::comments::*; #[test] /// Test if the `COMMENT` rule passes properly. fn check_comment() { - let comment1 = "; A Comment \n"; - let comment2 = "; And another\r"; - let comment3 = ";more\r\n"; - let not_comment = "not a comment\n"; - - let parse = CDDLTestParser::parse(Rule::COMMENT, comment1); - assert!(parse.is_ok()); - - let parse = CDDLTestParser::parse(Rule::COMMENT, comment2); - assert!(parse.is_ok()); - - let parse = CDDLTestParser::parse(Rule::COMMENT, comment3); - assert!(parse.is_ok()); - - let parse = CDDLTestParser::parse(Rule::COMMENT, not_comment); - assert!(parse.is_err()); + common::check_tests_rule(Rule::COMMENT_TEST, COMMENT_PASSES, COMMENT_FAILS); } #[test] /// Test if the `COMMENT` rule passes properly with whitespace. -/// This uses a special rule in the Grammar to test whitespace exhaustively. +/// This uses a special rule in the Grammar to test whitespace exhaustively. fn check_whitespace_comments() { - let tests = vec![ - " ", - " ", - " \t \t", - " \t \r \n \r\n ", - "; A Comment\r", - " \t ; A Comment \n", - "; One Comment\n; Two Comments\n", - "; One Comment \n; Two Comments\r; Another Comment\r\n", - "\t; One Comment \n\t; Two Comments\r; Another Comment\r\n", - "\t; A Comment \n ; Another Comment \t \r\n \t ; A Final Comment \r\n", - ]; - - let fails = vec!["not a comment"]; - - for test in tests { - let parse = CDDLTestParser::parse(Rule::COMMENT_TEST, test); - assert!(parse.is_ok()); - } - - for test in fails { - let parse = CDDLTestParser::parse(Rule::COMMENT_TEST, test); - assert!(parse.is_err()); - } + common::check_tests_rule( + Rule::COMMENT_TEST, + WHITESPACE_COMMENT_PASSES, + WHITESPACE_COMMENT_FAILS, + ); } diff --git a/hermes/crates/cbork/cddl-parser/tests/common/byte_sequences.rs b/hermes/crates/cbork/cddl-parser/tests/common/byte_sequences.rs new file mode 100644 index 000000000..afd944b15 --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/common/byte_sequences.rs @@ -0,0 +1,49 @@ +// cspell: words HEXPAIR rstuvw abcdefghijklmnopqrstuvwyz Xhhb Bhcm + +#![allow(dead_code)] // TODO: find a way to remove this. + +pub(crate) const HEXPAIR_PASSES: &[&str] = &["00", "ab", "de", "0f", "f0"]; + +pub(crate) const HEXPAIR_FAILS: &[&str] = &["0", " 0", "0 ", "az", "0p"]; + +pub(crate) const URL_BASE64_PASSES: &[&str] = &[ + "abcdefghijklmnopq rstuvw yz01\t23456789-_ABCDEFGHIJKLMNOPQRSTUVWXYZ~", + "abcdefghijklmnopqrstuvwyz0123456789-_ABCDEFGHIJKLMNOPQRSTUVWXYZ", +]; + +pub(crate) const URL_BASE64_FAILS: &[&str] = &[ + "abcdefghijklmnopq # rstuvw yz01\t23456789-_ABCDEFGHIJKLMNOPQRSTUVWXYZ~ ", + "abcdefghijklmnopq $ rstuvw yz01\t23456789-_ABCDEFGHIJKLMNOPQRSTUVWXYZ~\t", + "abcdefghijklmnopq % rstuvw yz01\t23456789-_ABCDEFGHIJKLMNOPQRSTUVWXYZ~\n", + "abcdefghijklmnopq ^ rstuvw yz01\t23456789-_ABCDEFGHIJKLMNOPQRSTUVWXYZ~\r", + "abcdefghijklmnopq & rstuvw yz01\t23456789-_ABCDEFGHIJKLMNOPQRSTUVWXYZ~\r\n", +]; + +pub(crate) const BYTES_PASSES: &[&str] = &[ + "h''", + "b64''", + "''", + "h'00'", + "h'63666F6FF6'", + "h'68656c6c6f20776f726c64'", + "h'4 86 56c 6c6f'", + "h' 20776 f726c64'", + "h'00112233445566778899aabbccddeeff0123456789abcdef'", + "h'0 1 2 3 4 5 6 7 8 9 a b c d e f'", + "h' 0 1 2 3 4 5\r 6 7 \n 8 9 a\r\n\t b c d e f'", + "h'0 \n\n\r f'", + "b64'aHR0cHM6Ly93d3cuZXhhbXBsZS5jb20vcGFnZT9wYXJhbTE9dmFsdWUxJnBhcmFtMj12YWx1ZTI~'", + "'text\n that gets converted \\\' into a byte string...'", +]; + +pub(crate) const BYTES_FAILS: &[&str] = &[ + "h64", + "b64", + "\"\"", + "h ''", + "b64 ''", + "h'001'", + "b64'abcdefghijklmnopq # rstuvw yz01\t23456789-_ABCDEFGHIJKLMNOPQRSTUVWXYZ~'", + "b64'abcdefghijklmnopq & rstuvw yz01\t23456789-_ABCDEFGHIJKLMNOPQRSTUVWXYZ'", + "'\u{7}'", +]; diff --git a/hermes/crates/cbork/cddl-parser/tests/common/comments.rs b/hermes/crates/cbork/cddl-parser/tests/common/comments.rs new file mode 100644 index 000000000..7ffcaad81 --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/common/comments.rs @@ -0,0 +1,20 @@ +#![allow(dead_code)] // TODO: find a way to remove this. + +pub(crate) const COMMENT_PASSES: &[&str] = &["; A Comment \n", "; And another\r", ";more\r\n"]; + +pub(crate) const COMMENT_FAILS: &[&str] = &["not a comment\n"]; + +pub(crate) const WHITESPACE_COMMENT_PASSES: &[&str] = &[ + " ", + " ", + " \t \t", + " \t \r \n \r\n ", + "; A Comment\r", + " \t ; A Comment \n", + "; One Comment\n; Two Comments\n", + "; One Comment \n; Two Comments\r; Another Comment\r\n", + "\t; One Comment \n\t; Two Comments\r; Another Comment\r\n", + "\t; A Comment \n ; Another Comment \t \r\n \t ; A Final Comment \r\n", +]; + +pub(crate) const WHITESPACE_COMMENT_FAILS: &[&str] = &["not a comment"]; diff --git a/hermes/crates/cbork/cddl-parser/tests/common/group_elements.rs b/hermes/crates/cbork/cddl-parser/tests/common/group_elements.rs new file mode 100644 index 000000000..e6fa05672 --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/common/group_elements.rs @@ -0,0 +1,114 @@ +// cspell: words OPTCOM MEMBERKEY bareword tstr GRPENT GRPCHOICE + +#![allow(dead_code)] // TODO: find a way to remove this. + +pub(crate) const OCCUR_PASSES: &[&str] = &[ + "*", + "+", + "?", + "5*10", + "0x1*0b110", + "*20", + "5*10", + "0x1*0b110", + "0*5", + "5*", + "*5", + "0b110*", + "0x1*", +]; + +pub(crate) const OCCUR_FAILS: &[&str] = &[ + "5**10", + "5 * 10", + "5\t\n*\n10", + "++", + "??", + // Fail cases for uint + "0123", // Leading zero is not allowed for decimal + "0xG", // Invalid hex digit + "0b123", // Invalid binary digit + "0*5*", // Multiple '*' not allowed + "0x1*0b110*", + "0x", + "0b", +]; + +pub(crate) const OPTCOM_PASSES: &[&str] = &["", ",", " ,", " , ", "\n,\n", "\n"]; + +pub(crate) const OPTCOM_FAILS: &[&str] = &[",,"]; + +pub(crate) const MEMBERKEY_PASSES: &[&str] = &[ + // bareword + "foo:", + "foo-bar:", + "foo_bar:", + "foo :", + // values + "\"foo\":", + "1:", + "0x123:", + "1.1:", + "-1:", + "b64'1234':", + "h'1234':", + "h'12 34\n':", + // type1 + "tstr =>", + "id =>", + "# =>", + "1..2 =>", + "1...2 =>", + "\"foo\" =>", + "\"foo\" ^=>", + "\"foo\"^ =>", + "\"foo\" ^ =>", + "1 =>", + "0x123 =>", + "1.1 =>", + "-1 =>", + "b64'1234' =>", + "h'1234' =>", + "h'12 34\n' =>", +]; + +pub(crate) const MEMBERKEY_FAILS: &[&str] = &["#:", "foo::"]; + +pub(crate) const GRPENT_PASSES: &[&str] = &[ + "foo: 1", + "foo: 1", + "foo-bar:\t\n1", + "foo :\n1", + "foo: #", + "tstr => any", + "tstr => { foo: bar }", + "tstr => { foo: bar, baz }", + "tstr => [foo: bar, baz]", +]; + +pub(crate) const GRPENT_FAILS: &[&str] = &["tstr => (foo: bar)"]; + +pub(crate) const GRPCHOICE_PASSES: &[&str] = &[ + "foo: 1", + "foo: 1, bar: 2", + "foo: 1, bar: 2,", + "foo: 1\nbar: 2", + "foo: 1 bar: 2", + "foo => 1 bar: 2", + "foo => 1, bar => 2", + "foo => 1, bar: 2", + "foo => 1bar: 2", +]; + +pub(crate) const GRPCHOICE_FAILS: &[&str] = &["foo: ,", "foo:", "foo: bar: 2", "foo => bar: 2"]; + +pub(crate) const GROUP_PASSES: &[&str] = &[ + "(foo: 1)", + "(foo: 1) // (bar: 2)", + "(foo: 1) // (bar: 2)", + "(street: tstr, ? number: uint, city // po-box: uint, city // per-pickup: true)", + "(+ a // b / c)", + "((+ a) // (b / c))", +]; + +pub(crate) const GROUP_FAILS: &[&str] = &["(foo: 1) / (bar: 2)"]; diff --git a/hermes/crates/cbork/cddl-parser/tests/common/identifiers.rs b/hermes/crates/cbork/cddl-parser/tests/common/identifiers.rs new file mode 100644 index 000000000..65e186bb6 --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/common/identifiers.rs @@ -0,0 +1,40 @@ +// cspell: words aname groupsocket typesocket + +#![allow(dead_code)] // TODO: find a way to remove this. + +pub(crate) const ID_PASSES: &[&str] = &[ + "$", + "@", + "_", + "a", + "z", + "A", + "Z", + "$$", + "@@", + "__", + "a$", + "a@", + "a_", + "$0", + "@9", + "_a", + "abc", + "aname", + "@aname", + "_aname", + "$aname", + "a$name", + "a.name", + "@a.name", + "$a.name", + "_a.name", + "$$", + "$$groupsocket", + "$", + "$typesocket", +]; + +pub(crate) const ID_FAILS: &[&str] = &[ + "aname.", "aname-", "aname%", "a%name4", "a^name5", "a name", "", +]; diff --git a/hermes/crates/cbork/cddl-parser/tests/common/literal_values.rs b/hermes/crates/cbork/cddl-parser/tests/common/literal_values.rs new file mode 100644 index 000000000..2289ed8d9 --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/common/literal_values.rs @@ -0,0 +1,106 @@ +// cspell: words xdog INTFLOAT HEXFLOAT xabcp defp + +#![allow(dead_code)] // TODO: find a way to remove this. + +pub(crate) const UINT_PASSES: &[&str] = &[ + "10", + "101", + "2034", + "30456", + "123456789", + "0x123456789abcdefABCDEF", + "0b0001110101010101", + "0", +]; + +pub(crate) const UINT_FAILS: &[&str] = &[" a ", "zz", "0123zzz", "0xdog", "0b777"]; + +pub(crate) const INT_PASSES: &[&str] = &[ + "10", + "101", + "2034", + "30456", + "123456789", + "0x123456789abcdefABCDEF", + "0b0001110101010101", + "0", + "-10", + "-101", + "-2034", + "-30456", + "-123456789", + "-0x123456789abcdefABCDEF", + "-0b0001110101010101", + "-0", +]; + +pub(crate) const INT_FAILS: &[&str] = &[" a ", "zz", "0123zzz", "0xdog", "0b777"]; + +pub(crate) const INTFLOAT_PASSES: &[&str] = &[ + "10", + "101", + "2034", + "30456", + "123456789", + "0", + "-10", + "-101", + "-2034", + "-30456", + "-123456789", + "123.456", + "123.456", + "123e+789", + "123e-789", + "123.456e+789", + "123.456e-789", +]; + +pub(crate) const INTFLOAT_FAILS: &[&str] = &[" a ", "zz", "0123zzz", "0xdog", "0b777"]; + +pub(crate) const HEXFLOAT_PASSES: &[&str] = &[ + "0xabcp+123", + "-0xabcp+123", + "0xabcp-123", + "-0xabcp-123", + "0xabc.defp+123", + "-0xabc.defp+123", + "0xabc.defp-123", + "-0xabc.defp-123", +]; + +pub(crate) const HEXFLOAT_FAILS: &[&str] = &[" a ", "zz", "0123zzz", "0xdog", "0b777"]; + +pub(crate) const NUMBER_PASSES: &[&str] = &[ + "0xabcp+123", + "-0xabcp+123", + "0xabcp-123", + "-0xabcp-123", + "0xabc.defp+123", + "-0xabc.defp+123", + "0xabc.defp-123", + "-0xabc.defp-123", + "10", + "101", + "2034", + "30456", + "123456789", + "0", + "-10", + "-101", + "-2034", + "-30456", + "-123456789", + "123.456", + "123.456", + "123e+789", + "123e-789", + "123.456e+789", + "123.456e-789", +]; + +pub(crate) const NUMBER_FAILS: &[&str] = &[" a ", "zz", "0123zzz", "0xdog", "0b777"]; + +pub(crate) const VALUE_PASSES: &[&str] = &[]; + +pub(crate) const VALUE_FAILS: &[&str] = &[]; diff --git a/hermes/crates/cbork/cddl-parser/tests/common/mod.rs b/hermes/crates/cbork/cddl-parser/tests/common/mod.rs new file mode 100644 index 000000000..fd6dbb23e --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/common/mod.rs @@ -0,0 +1,26 @@ +use cddl_parser::{ + self, + cddl_test::{CDDLTestParser, Parser, Rule}, +}; + +pub(crate) mod byte_sequences; +pub(crate) mod comments; +pub(crate) mod group_elements; +pub(crate) mod identifiers; +pub(crate) mod literal_values; +pub(crate) mod rules; +pub(crate) mod text_sequences; +pub(crate) mod type_declarations; + +/// # Panics +pub(crate) fn check_tests_rule(rule_type: Rule, passes: &[&str], fails: &[&str]) { + for test in passes { + let parse = CDDLTestParser::parse(rule_type, test); + assert!(parse.is_ok()); + } + + for test in fails { + let parse = CDDLTestParser::parse(rule_type, test); + assert!(parse.is_err()); + } +} diff --git a/hermes/crates/cbork/cddl-parser/tests/common/rules.rs b/hermes/crates/cbork/cddl-parser/tests/common/rules.rs new file mode 100644 index 000000000..c8eeb071c --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/common/rules.rs @@ -0,0 +1,59 @@ +// cspell: words GENERICARG bigfloat GENERICPARM ASSIGNG ASSIGNT GROUPNAME tstr + +#![allow(dead_code)] // TODO: find a way to remove this. + +use super::identifiers::{ID_FAILS, ID_PASSES}; + +pub(crate) const GENERICARG_PASSES: &[&str] = &[ + "", + "<{ foo: bar }>", + "<{ h'1234': uint }>", + "<1...10>", + "<\n1...10\t>", + "<{ foo: bar }, { foo: baz }>", + "<{ foo: bar }, 1..10>", +]; + +pub(crate) const GENERICARG_FAILS: &[&str] = + &["", "<>", "", "<( foo: bar )>", ""]; + +pub(crate) const GENERICPARM_PASSES: &[&str] = + &["", "", "", ""]; + +pub(crate) const GENERICPARM_FAILS: &[&str] = &[ + "", + "<>", + "", + "<{ foo: bar }>", + "<{ h'1234': uint }>", + "<1...10>", + "<\n1...10\t>", +]; + +pub(crate) const ASSIGNG_PASSES: &[&str] = &["=", "//="]; + +pub(crate) const ASSIGNG_FAILS: &[&str] = &["==", "/="]; + +pub(crate) const ASSIGNT_PASSES: &[&str] = &["=", "/="]; + +pub(crate) const ASSIGNT_FAILS: &[&str] = &["==", "//="]; + +pub(crate) const TYPENAME_PASSES: &[&str] = ID_PASSES; + +pub(crate) const TYPENAME_FAILS: &[&str] = ID_FAILS; + +pub(crate) const GROUPNAME_PASSES: &[&str] = ID_PASSES; + +pub(crate) const GROUPNAME_FAILS: &[&str] = ID_FAILS; + +pub(crate) const RULE_GROUP_PASSES: &[&str] = &[ + "foo = (bar: baz)", + "t //= (foo: bar)", + "t //= foo", + "t //= foo", + "t //= foo: bar", + "t //= 2*2 foo: bar", + "delivery //= ( lat: float, long: float, drone-type: tstr )", +]; + +pub(crate) const RULE_GROUP_FAILS: &[&str] = &["foo = bar: baz", "t /= (foo: bar)"]; diff --git a/hermes/crates/cbork/cddl-parser/tests/common/text_sequences.rs b/hermes/crates/cbork/cddl-parser/tests/common/text_sequences.rs new file mode 100644 index 000000000..b38ae82f5 --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/common/text_sequences.rs @@ -0,0 +1,6 @@ +#![allow(dead_code)] // TODO: find a way to remove this. + +pub(crate) const S_PASSES: &[&str] = &[" ", " ", " \t \t", " \t \r \n \r\n "]; +pub(crate) const S_FAILS: &[&str] = &[" a ", "zz", " \t d \t", " \t \r \n \t \r\n x"]; +pub(crate) const TEXT_PASSES: &[&str] = &[r#""""#, r#""abc""#, "\"abc\\n\""]; +pub(crate) const TEXT_FAILS: &[&str] = &["", "''", "\"abc\n\""]; diff --git a/hermes/crates/cbork/cddl-parser/tests/common/type_declarations.rs b/hermes/crates/cbork/cddl-parser/tests/common/type_declarations.rs new file mode 100644 index 000000000..5b77dd881 --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/common/type_declarations.rs @@ -0,0 +1,112 @@ +// cspell: words CTLOP aname groupsocket typesocket RANGEOP tstr + +#![allow(dead_code)] // TODO: find a way to remove this. + +pub(crate) const CTLOP_PASSES: &[&str] = &[ + ".$", + ".@", + "._", + ".a", + ".z", + ".A", + ".Z", + ".$$", + ".@@", + ".__", + ".a$", + ".a@", + ".a_", + ".$0", + ".@9", + "._a", + ".abc", + ".aname", + ".@aname", + "._aname", + ".$aname", + ".a$name", + ".a.name", + ".@a.name", + ".$a.name", + "._a.name", + ".$$", + ".$$groupsocket", + ".$", + ".$typesocket", +]; + +pub(crate) const CTLOP_FAILS: &[&str] = &[ + "aname.", ".", "..", "aname.", "aname-", "aname%", "a%name4", "a^name5", "a name", "", +]; + +pub(crate) const RANGEOP_PASSES: &[&str] = &["..", "..."]; + +pub(crate) const RANGEOP_FAILS: &[&str] = &[".", "", "....", ".. .", ". .."]; + +pub(crate) const TYPE2_PASSES: &[&str] = &[ + "#", + "#1", + "#1.1", + "#1.1", + "#6", + "#6.11", + "#6.11(tstr)", + "#6.11(\tstr\n)", + "#6.11({ foo })", + "#6.11([ foo ])", + "#6.11(#3.1)", + "&foo", + "& foo", + "&((+ a) // (b / c))", + "&\t( foo: bar )", + "~foo", + "~ foo", + "foo", + "[ foo bar ]", + "{ foo bar }", + "(a)", + "(a / b)", + "(#)", + "((a))", + "1", + "h'1111'", + "true", + "foo", +]; + +pub(crate) const TYPE2_FAILS: &[&str] = &[ + "", + "##", + "#1.", + "#6.11 (tstr)", + "#6.11(( foo: uint ))", + "&", + "& foo ", + "(foo bar)", +]; + +pub(crate) const TYPE1_PASSES: &[&str] = &[ + "1..2", + "1 .. 2", + "1\t..\n2", + "1...2", + "0..10.0", // BAD range 1 + "0.0..10", // BAD range 2 + "0..max-byte", + "min-type..max-byte", + "1.0..2.0", + "1.0...2.0", + "foo.bar", +]; + +pub(crate) const TYPE1_FAILS: &[&str] = &[""]; + +pub(crate) const TYPE_PASSES: &[&str] = &[ + "1 / 2", + "1\n/\t2", + "1 / 2 / 3 / 4", + "1 / (2 / (3 / 4))", + "# / #", +]; + +pub(crate) const TYPE_FAILS: &[&str] = &["", "1 \\ 2", "1 // 2", "1 2", "1 / 2 3"]; diff --git a/hermes/crates/cbork/cddl-parser/tests/group_elements.rs b/hermes/crates/cbork/cddl-parser/tests/group_elements.rs new file mode 100644 index 000000000..0fa4296de --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/group_elements.rs @@ -0,0 +1,56 @@ +// cspell: words OPTCOM MEMBERKEY bareword tstr GRPENT GRPCHOICE +// cspell: words optcom memberkey grpent grpchoice + +use cddl_parser::{self, cddl_test::Rule}; + +mod common; +use common::{group_elements::*, identifiers::*}; + +#[test] +/// Test if the `occur` rule passes properly. +/// This uses a special rule in the Grammar to test `occur` exhaustively. +fn check_occur() { + common::check_tests_rule(Rule::occur_TEST, OCCUR_PASSES, OCCUR_FAILS); +} + +#[test] +/// Test if the `bareword` rule passes properly. +/// This uses a special rule in the Grammar to test `bareword` exhaustively. +fn check_bareword() { + common::check_tests_rule(Rule::bareword_TEST, ID_PASSES, ID_FAILS); +} + +#[test] +/// Test if the `optcom` rule passes properly. +/// This uses a special rule in the Grammar to test `optcom` exhaustively. +fn check_optcom() { + common::check_tests_rule(Rule::optcom_TEST, OPTCOM_PASSES, OPTCOM_FAILS); +} + +#[test] +/// Test if the `memberkey` rule passes properly. +/// This uses a special rule in the Grammar to test `memberkey` exhaustively. +fn check_memberkey() { + common::check_tests_rule(Rule::memberkey_TEST, MEMBERKEY_PASSES, MEMBERKEY_FAILS); +} + +#[test] +/// Test if the `grpent` rule passes properly. +/// This uses a special rule in the Grammar to test `grpent` exhaustively. +fn check_grpent() { + common::check_tests_rule(Rule::grpent_TEST, GRPENT_PASSES, GRPENT_FAILS); +} + +#[test] +/// Test if the `grpchoice` rule passes properly. +/// This uses a special rule in the Grammar to test `grpchoice` exhaustively. +fn check_grpchoice() { + common::check_tests_rule(Rule::grpchoice_TEST, GRPCHOICE_PASSES, GRPCHOICE_FAILS); +} + +#[test] +/// Test if the `group` rule passes properly. +/// This uses a special rule in the Grammar to test `group` exhaustively. +fn check_group() { + common::check_tests_rule(Rule::group_TEST, GROUP_PASSES, GROUP_FAILS); +} diff --git a/hermes/crates/cbork/cddl-parser/tests/identifiers.rs b/hermes/crates/cbork/cddl-parser/tests/identifiers.rs index dc69d9f13..c4f3e7dfa 100644 --- a/hermes/crates/cbork/cddl-parser/tests/identifiers.rs +++ b/hermes/crates/cbork/cddl-parser/tests/identifiers.rs @@ -5,6 +5,9 @@ use cddl_parser::{ cddl_test::{CDDLTestParser, Parser, Rule}, }; +mod common; +use common::identifiers::*; + #[test] /// Check if the name components pass properly. fn check_name_characters() { @@ -13,7 +16,7 @@ fn check_name_characters() { let parse_start = CDDLTestParser::parse(Rule::NAME_START, &test); let parse_end = CDDLTestParser::parse(Rule::NAME_END, &test); - if x.is_ascii_alphabetic() || x == '@' || x == '_' || x == '$' { + if x.is_ascii_alphabetic() || matches!(x, '@' | '_' | '$') { assert!(parse_start.is_ok()); assert!(parse_end.is_ok()); } else if x.is_ascii_digit() { @@ -29,50 +32,5 @@ fn check_name_characters() { #[test] /// Test if the `id` rule passes properly. fn check_id() { - let test = vec![ - "$", - "@", - "_", - "a", - "z", - "A", - "Z", - "$$", - "@@", - "__", - "a$", - "a@", - "a_", - "$0", - "@9", - "_a", - "abc", - "aname", - "@aname", - "_aname", - "$aname", - "a$name", - "a.name", - "@a.name", - "$a.name", - "_a.name", - "$$", - "$$groupsocket", - "$", - "$typesocket", - ]; - - let fail = vec![ - "aname.", "aname-", "aname%", "a%name4", "a^name5", "a name", "", - ]; - - for test in test { - let parse = CDDLTestParser::parse(Rule::id_TEST, test); - assert!(parse.is_ok()); - } - - for test in fail { - let parse = CDDLTestParser::parse(Rule::id_TEST, test); - assert!(parse.is_err()); - } + common::check_tests_rule(Rule::id_TEST, ID_PASSES, ID_FAILS); } diff --git a/hermes/crates/cbork/cddl-parser/tests/literal_values.rs b/hermes/crates/cbork/cddl-parser/tests/literal_values.rs index c2492e76d..c29fcedeb 100644 --- a/hermes/crates/cbork/cddl-parser/tests/literal_values.rs +++ b/hermes/crates/cbork/cddl-parser/tests/literal_values.rs @@ -1,237 +1,57 @@ // cspell: words xdog intfloat hexfloat xabcp defp rstuvw -use cddl_parser::{ - self, - cddl_test::{CDDLTestParser, Parser, Rule}, -}; +use std::ops::Deref; -/// Note, the `text`, `bytes` and `id` tests are elsewhere. +use cddl_parser::{self, cddl_test::Rule}; + +mod common; +use common::{byte_sequences::*, literal_values::*, text_sequences::*}; #[test] /// Test if the `uint` rule passes properly. fn check_uint() { - let tests = vec![ - "10", - "101", - "2034", - "30456", - "123456789", - "0x123456789abcdefABCDEF", - "0b0001110101010101", - "0", - ]; - - let fails = vec![" a ", "zz", "0123zzz", "0xdog", "0b777"]; - - for test in tests { - let parse = CDDLTestParser::parse(Rule::uint_TEST, test); - assert!(parse.is_ok()); - } - - for test in fails { - let parse = CDDLTestParser::parse(Rule::uint_TEST, test); - assert!(parse.is_err()); - } + common::check_tests_rule(Rule::uint_TEST, UINT_PASSES, UINT_FAILS); } #[test] /// Test if the `uint` rule passes properly. fn check_int() { - let tests = vec![ - "10", - "101", - "2034", - "30456", - "123456789", - "0x123456789abcdefABCDEF", - "0b0001110101010101", - "0", - "-10", - "-101", - "-2034", - "-30456", - "-123456789", - "-0x123456789abcdefABCDEF", - "-0b0001110101010101", - "-0", - ]; - - let fails = vec![" a ", "zz", "0123zzz", "0xdog", "0b777"]; - - for test in tests { - let parse = CDDLTestParser::parse(Rule::int_TEST, test); - assert!(parse.is_ok()); - } - - for test in fails { - let parse = CDDLTestParser::parse(Rule::int_TEST, test); - assert!(parse.is_err()); - } + common::check_tests_rule(Rule::int_TEST, INT_PASSES, INT_FAILS); } #[test] /// Test if the `uint` rule passes properly. fn check_intfloat() { - let tests = vec![ - "10", - "101", - "2034", - "30456", - "123456789", - "0", - "-10", - "-101", - "-2034", - "-30456", - "-123456789", - "123.456", - "123.456", - "123e+789", - "123e-789", - "123.456e+789", - "123.456e-789", - ]; - - let fails = vec![" a ", "zz", "0123zzz", "0xdog", "0b777"]; - - for test in tests { - let parse = CDDLTestParser::parse(Rule::intfloat_TEST, test); - assert!(parse.is_ok()); - } - - for test in fails { - let parse = CDDLTestParser::parse(Rule::intfloat_TEST, test); - assert!(parse.is_err()); - } + common::check_tests_rule(Rule::intfloat_TEST, INTFLOAT_PASSES, INTFLOAT_FAILS); } #[test] /// Test if the `uint` rule passes properly. fn check_hexfloat() { - let tests = vec![ - "0xabcp+123", - "-0xabcp+123", - "0xabcp-123", - "-0xabcp-123", - "0xabc.defp+123", - "-0xabc.defp+123", - "0xabc.defp-123", - "-0xabc.defp-123", - ]; - - let fails = vec![" a ", "zz", "0123zzz", "0xdog", "0b777"]; - - for test in tests { - let parse = CDDLTestParser::parse(Rule::hexfloat_TEST, test); - assert!(parse.is_ok()); - } - - for test in fails { - let parse = CDDLTestParser::parse(Rule::hexfloat_TEST, test); - assert!(parse.is_err()); - } + common::check_tests_rule(Rule::hexfloat_TEST, HEXFLOAT_PASSES, HEXFLOAT_FAILS); } #[test] /// Test if the `number` rule passes properly. fn check_number() { - let tests = vec![ - "0xabcp+123", - "-0xabcp+123", - "0xabcp-123", - "-0xabcp-123", - "0xabc.defp+123", - "-0xabc.defp+123", - "0xabc.defp-123", - "-0xabc.defp-123", - "10", - "101", - "2034", - "30456", - "123456789", - "0", - "-10", - "-101", - "-2034", - "-30456", - "-123456789", - "123.456", - "123.456", - "123e+789", - "123e-789", - "123.456e+789", - "123.456e-789", - ]; - - let fails = vec![" a ", "zz", "0123zzz", "0xdog", "0b777"]; - - for test in tests { - let parse = CDDLTestParser::parse(Rule::number_TEST, test); - assert!(parse.is_ok()); - } - - for test in fails { - let parse = CDDLTestParser::parse(Rule::number_TEST, test); - assert!(parse.is_err()); - } + common::check_tests_rule(Rule::number_TEST, NUMBER_PASSES, NUMBER_FAILS); } #[test] /// Test if the `uint` rule passes properly. fn check_value() { - let tests = vec![ - "0xabcp+123", - "-0xabcp+123", - "0xabcp-123", - "-0xabcp-123", - "0xabc.defp+123", - "-0xabc.defp+123", - "0xabc.defp-123", - "-0xabc.defp-123", - "10", - "101", - "2034", - "30456", - "123456789", - "0", - "-10", - "-101", - "-2034", - "-30456", - "-123456789", - "123.456", - "123.456", - "123e+789", - "123e-789", - "123.456e+789", - "123.456e-789", - // Ideally we would define these somewhere central and just use them where needed. - "h''", - "b64''", - "''", - "h'00'", - "h'00112233445566778899aabbccddeeff0123456789abcdef'", - "h'0 1 2 3 4 5 6 7 8 9 a b c d e f'", - "h' 0 1 2 3 4 5\r 6 7 \n 8 9 a\r\n\t b c d e f'", - "b64'abcdefghijklmnopq rstuvw yz01\t23456789-_ABCDEFGHIJKLMNOPQRSTUVWXYZ~'", - "b64'abcdefghijklmnopq rstuvw yz01\t23456789-_ABCDEFGHIJKLMNOPQRSTUVWXYZ'", - "''", - "'text\n that gets converted \\\' into a byte string...'", - // Ideally we would define these somewhere central and just use them where needed. - r#""""#, - r#""abc""#, - "\"abc\\n\"", - ]; - - let fails = vec![" a ", "zz", "0123zzz", "0xdog", "0b777"]; - - for test in tests { - let parse = CDDLTestParser::parse(Rule::value_TEST, test); - assert!(parse.is_ok()); - } - - for test in fails { - let parse = CDDLTestParser::parse(Rule::value_TEST, test); - assert!(parse.is_err()); - } + let passes: Vec<_> = VALUE_PASSES + .iter() + .chain(NUMBER_PASSES) + .chain(BYTES_PASSES) + .chain(TEXT_PASSES) + .map(Deref::deref) + .collect(); + let fails: Vec<_> = VALUE_FAILS + .iter() + .chain(NUMBER_FAILS) + .map(Deref::deref) + .collect(); + + common::check_tests_rule(Rule::value_TEST, &passes, &fails); } diff --git a/hermes/crates/cbork/cddl-parser/tests/rules.rs b/hermes/crates/cbork/cddl-parser/tests/rules.rs new file mode 100644 index 000000000..79a999e63 --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/rules.rs @@ -0,0 +1,87 @@ +// cspell: words GENERICARG bigfloat ASSIGNG GROUPNAME tstr genericarg GENERICARG +// cspell: words assigng assignt ASSIGNT GENERICPARM genericparm + +use cddl_parser::{ + self, + cddl_test::{CDDLTestParser, Parser, Rule}, +}; + +mod common; +use common::{rules::*, type_declarations::*}; + +#[test] +/// Test if the `genericarg` rule passes properly. +/// This uses a special rule in the Grammar to test `genericarg` exhaustively. +fn check_genericarg() { + common::check_tests_rule(Rule::genericarg_TEST, GENERICARG_PASSES, GENERICARG_FAILS); +} + +#[test] +/// Test if the `genericparm` rule passes properly. +/// This uses a special rule in the Grammar to test `genericparm` exhaustively. +fn check_genericparm() { + common::check_tests_rule( + Rule::genericparm_TEST, + GENERICPARM_PASSES, + GENERICPARM_FAILS, + ); +} + +#[test] +/// Test if the `assigng` rule passes properly. +/// This uses a special rule in the Grammar to test `assigng` exhaustively. +fn check_assigng() { + common::check_tests_rule(Rule::assigng_TEST, ASSIGNG_PASSES, ASSIGNG_FAILS); +} + +#[test] +/// Test if the `assignt` rule passes properly. +/// This uses a special rule in the Grammar to test `assignt` exhaustively. +fn check_assignt() { + common::check_tests_rule(Rule::assignt_TEST, ASSIGNT_PASSES, ASSIGNT_FAILS); +} + +#[test] +/// Test if the `typename` rule passes properly. +/// This uses a special rule in the Grammar to test `typename` exhaustively. +fn check_typename() { + common::check_tests_rule(Rule::typename_TEST, TYPENAME_PASSES, TYPENAME_FAILS); +} + +#[test] +/// Test if the `groupname` rule passes properly. +/// This uses a special rule in the Grammar to test `groupname` exhaustively. +fn check_groupname() { + common::check_tests_rule(Rule::groupname_TEST, GROUPNAME_PASSES, GROUPNAME_FAILS); +} + +#[test] +/// Test if the `rule` rule passes properly for type variant. +fn check_rule_type_composition() { + for (i, test_i) in [TYPENAME_PASSES, TYPENAME_FAILS] + .into_iter() + .flatten() + .enumerate() + { + for (j, test_j) in [ASSIGNT_PASSES].into_iter().flatten().enumerate() { + for (k, test_k) in [TYPE_PASSES, TYPE_FAILS].into_iter().flatten().enumerate() { + let input = [test_i.to_owned(), test_j.to_owned(), test_k.to_owned()].join(" "); + let parse = CDDLTestParser::parse(Rule::rule_TEST, &input); + if (0..TYPENAME_PASSES.len()).contains(&i) + && (0..ASSIGNT_PASSES.len()).contains(&j) + && (0..TYPE_PASSES.len()).contains(&k) + { + assert!(parse.is_ok()); + } else { + assert!(parse.is_err()); + } + } + } + } +} + +#[test] +/// Test if the `rule` rule passes properly for group variant. +fn check_rule_group() { + common::check_tests_rule(Rule::rule_TEST, RULE_GROUP_PASSES, RULE_GROUP_FAILS); +} diff --git a/hermes/crates/cbork/cddl-parser/tests/text_sequences.rs b/hermes/crates/cbork/cddl-parser/tests/text_sequences.rs index 5fe8ca665..bd96aa657 100644 --- a/hermes/crates/cbork/cddl-parser/tests/text_sequences.rs +++ b/hermes/crates/cbork/cddl-parser/tests/text_sequences.rs @@ -1,41 +1,17 @@ -use cddl_parser::{ - self, - cddl_test::{CDDLTestParser, Parser, Rule}, -}; +use cddl_parser::{self, cddl_test::Rule}; + +mod common; +use common::text_sequences::*; #[test] /// Test if the `S` rule passes properly. -/// This uses a special rule in the Grammar to test whitespace exhaustively. +/// This uses a special rule in the Grammar to test whitespace exhaustively. fn check_s() { - let tests = vec![" ", " ", " \t \t", " \t \r \n \r\n "]; - - let fails = vec![" a ", "zz", " \t d \t", " \t \r \n \t \r\n x"]; - - for test in tests { - let parse = CDDLTestParser::parse(Rule::S_TEST, test); - assert!(parse.is_ok()); - } - - for test in fails { - let parse = CDDLTestParser::parse(Rule::S_TEST, test); - assert!(parse.is_err()); - } + common::check_tests_rule(Rule::S_TEST, S_PASSES, S_FAILS); } #[test] /// Test if the `text` rule passes properly. fn check_text() { - let test = vec![r#""""#, r#""abc""#, "\"abc\\n\""]; - - let fail = vec!["", "''", "\"abc\n\""]; - - for test in test { - let parse = CDDLTestParser::parse(Rule::text_TEST, test); - assert!(parse.is_ok()); - } - - for test in fail { - let parse = CDDLTestParser::parse(Rule::text_TEST, test); - assert!(parse.is_err()); - } + common::check_tests_rule(Rule::text_TEST, TEXT_PASSES, TEXT_FAILS); } diff --git a/hermes/crates/cbork/cddl-parser/tests/type_declarations.rs b/hermes/crates/cbork/cddl-parser/tests/type_declarations.rs new file mode 100644 index 000000000..571b95621 --- /dev/null +++ b/hermes/crates/cbork/cddl-parser/tests/type_declarations.rs @@ -0,0 +1,89 @@ +// cspell: words CTLOP aname groupsocket typesocket RANGEOP tstr ctlop +// cspell: words rangeop RANGEOP + +use cddl_parser::{ + self, + cddl_test::{CDDLTestParser, Parser, Rule}, +}; + +mod common; +use common::type_declarations::*; + +#[test] +/// Test if the `ctlop` rule passes properly. +/// This uses a special rule in the Grammar to test `ctlop` exhaustively. +fn check_ctlop() { + common::check_tests_rule(Rule::ctlop_TEST, CTLOP_PASSES, CTLOP_FAILS); +} + +#[test] +/// Test if the `rangeop` rule passes properly. +/// This uses a special rule in the Grammar to test `rangeop` exhaustively. +fn check_rangeop() { + common::check_tests_rule(Rule::rangeop_TEST, RANGEOP_PASSES, RANGEOP_FAILS); +} + +#[test] +/// Test if the `type2` rule passes properly. +/// This uses a special rule in the Grammar to test `type2` exhaustively. +fn check_type2() { + common::check_tests_rule(Rule::type2_TEST, TYPE2_PASSES, TYPE2_FAILS); +} + +#[test] +/// Test if the `type1` rule passes properly. +/// This uses a special rule in the Grammar to test `type1` exhaustively. +fn check_type1() { + common::check_tests_rule(Rule::type1_TEST, TYPE1_PASSES, TYPE1_FAILS); +} + +#[test] +/// Test if the `type1` rule passes properly based on composition of type2 test cases. +fn check_type1_composition() { + let j_len = CTLOP_PASSES.len() + RANGEOP_PASSES.len(); + for (i, test_i) in [TYPE2_PASSES, TYPE_FAILS].into_iter().flatten().enumerate() { + for (j, test_j) in [CTLOP_PASSES, RANGEOP_PASSES] + .into_iter() + .flatten() + .enumerate() + { + for (k, test_k) in [TYPE2_PASSES, TYPE_FAILS].into_iter().flatten().enumerate() { + let input = [test_i.to_owned(), test_j.to_owned(), test_k.to_owned()].join(" "); + let parse = CDDLTestParser::parse(Rule::type1_TEST, &input); + if (0..TYPE2_PASSES.len()).contains(&i) + && (0..j_len).contains(&j) + && (0..TYPE2_PASSES.len()).contains(&k) + { + assert!(parse.is_ok()); + } else { + assert!(parse.is_err()); + } + } + } + } +} + +#[test] +/// Test if the `type` rule passes properly. +/// This uses a special rule in the Grammar to test `type` exhaustively. +fn check_type() { + common::check_tests_rule(Rule::type_TEST, TYPE_PASSES, TYPE_FAILS); +} + +#[test] +/// Test if the `type` rule passes properly based on composition of type2 test cases. +fn check_type_composition() { + // type2 composition testing + for (i, test_i) in [TYPE2_PASSES, TYPE_FAILS].into_iter().flatten().enumerate() { + for (j, test_j) in [TYPE2_PASSES, TYPE_FAILS].into_iter().flatten().enumerate() { + let input = [test_i.to_owned(), "/", test_j.to_owned()].join(" "); + let parse = CDDLTestParser::parse(Rule::type_TEST, &input); + + if (0..TYPE2_PASSES.len()).contains(&i) && (0..TYPE2_PASSES.len()).contains(&j) { + assert!(parse.is_ok()); + } else { + assert!(parse.is_err()); + } + } + } +}