saphyr-serde/parser/tests/issues.rs

305 lines
9.7 KiB
Rust

use saphyr_parser::{Event, Parser, ScanError, TScalarStyle};
/// Run the parser through the string.
///
/// The parser is run through both the `StrInput` and `BufferedInput` variants. The resulting
/// events are then compared and must match.
///
/// # Returns
/// This function returns the events if parsing succeeds, the error the parser returned otherwise.
///
/// # Panics
/// This function panics if there is a mismatch between the 2 parser invocations with the different
/// input traits.
fn run_parser(input: &str) -> Result<Vec<Event>, ScanError> {
let mut str_events = vec![];
let mut str_error = None;
let mut iter_events = vec![];
let mut iter_error = None;
for x in Parser::new_from_str(input) {
match x {
Ok(event) => str_events.push(event),
Err(e) => {
str_error = Some(e);
break;
}
}
}
for x in Parser::new_from_iter(input.chars()) {
match x {
Ok(event) => iter_events.push(event),
Err(e) => {
iter_error = Some(e);
break;
}
}
}
// eprintln!("str_events");
// for x in &str_events {
// eprintln!("\t{x:?}");
// }
// eprintln!("iter_events");
// for x in &iter_events {
// eprintln!("\t{x:?}");
// }
assert_eq!(str_events, iter_events);
assert_eq!(str_error, iter_error);
if let Some(err) = str_error {
Err(err)
} else {
Ok(str_events.into_iter().map(|x| x.0).collect())
}
}
#[test]
#[allow(clippy::too_many_lines)]
fn test_issue1() {
// https://github.com/saphyr-rs/saphyr-parser/issues/1
// Implicit mappings with a nested flow sequence prematurely end the mapping.
//
// [a: [42]]
// ^ This closing sequence character
// ^ is interpreted as closing this sequence, where the implicit mapping starts.
//
// The current implementation does not allow for nested implicit mapping:
//
// [a: [b: c]]
// ^ this implicit mapping would be ignored
let reference = r"
- a:
- 42
";
let expected = [
Event::StreamStart,
Event::DocumentStart(false),
Event::SequenceStart(0, None),
Event::MappingStart(0, None),
Event::Scalar("a".to_string(), TScalarStyle::Plain, 0, None),
Event::SequenceStart(0, None),
Event::Scalar("42".to_string(), TScalarStyle::Plain, 0, None),
Event::SequenceEnd,
Event::MappingEnd,
Event::SequenceEnd,
Event::DocumentEnd,
Event::StreamEnd,
];
assert_eq!(run_parser(reference).unwrap(), expected);
assert_eq!(run_parser("[{a: [42]}]").unwrap(), expected);
assert_eq!(run_parser("[a: [42]]").unwrap(), expected);
// Other test cases derived from the bug
// Implicit mapping in a complex key.
assert_eq!(
run_parser("[foo: [bar]]: baz").unwrap(),
[
Event::StreamStart,
Event::DocumentStart(false),
Event::MappingStart(0, None),
Event::SequenceStart(0, None),
Event::MappingStart(0, None),
Event::Scalar("foo".to_string(), TScalarStyle::Plain, 0, None),
Event::SequenceStart(0, None),
Event::Scalar("bar".to_string(), TScalarStyle::Plain, 0, None),
Event::SequenceEnd,
Event::MappingEnd,
Event::SequenceEnd,
Event::Scalar("baz".to_string(), TScalarStyle::Plain, 0, None),
Event::MappingEnd,
Event::DocumentEnd,
Event::StreamEnd,
]
);
// Implicit mappings with implicit null keys
assert_eq!(
run_parser("[:]").unwrap(),
[
Event::StreamStart,
Event::DocumentStart(false),
Event::SequenceStart(0, None),
Event::MappingStart(0, None),
Event::Scalar("~".to_string(), TScalarStyle::Plain, 0, None),
Event::Scalar("~".to_string(), TScalarStyle::Plain, 0, None),
Event::MappingEnd,
Event::SequenceEnd,
Event::DocumentEnd,
Event::StreamEnd,
]
);
// Nested implicit mappings with implicit null keys
assert_eq!(
run_parser("[: [:]]").unwrap(),
[
Event::StreamStart,
Event::DocumentStart(false),
Event::SequenceStart(0, None),
Event::MappingStart(0, None),
Event::Scalar("~".to_string(), TScalarStyle::Plain, 0, None),
Event::SequenceStart(0, None),
Event::MappingStart(0, None),
Event::Scalar("~".to_string(), TScalarStyle::Plain, 0, None),
Event::Scalar("~".to_string(), TScalarStyle::Plain, 0, None),
Event::MappingEnd,
Event::SequenceEnd,
Event::MappingEnd,
Event::SequenceEnd,
Event::DocumentEnd,
Event::StreamEnd,
]
);
// Interleaved nested implicit and non-implicit mappings.
assert_eq!(
run_parser("[a: [ [b:]]]").unwrap(),
// ^ ^ ^ has an implicit mapping
// | ` has no implicit mapping
// ` has an implicit mapping
// We must make sure that the `MappingEnd` events are correctly issued for the first and
// third nested sequences, but not the second.
[
Event::StreamStart,
Event::DocumentStart(false),
Event::SequenceStart(0, None),
Event::MappingStart(0, None),
Event::Scalar("a".to_string(), TScalarStyle::Plain, 0, None),
Event::SequenceStart(0, None),
// No `MappingStart` here.
Event::SequenceStart(0, None),
Event::MappingStart(0, None),
Event::Scalar("b".to_string(), TScalarStyle::Plain, 0, None),
Event::Scalar("~".to_string(), TScalarStyle::Plain, 0, None),
Event::MappingEnd,
Event::SequenceEnd,
// No `MappingEnd` here.
Event::SequenceEnd,
Event::MappingEnd,
Event::SequenceEnd,
Event::DocumentEnd,
Event::StreamEnd,
]
);
// There needs to be a space between a `:` in a flow sequence and the value.
assert!(run_parser("[:[:]]").is_err());
assert!(run_parser("[a:[42]]").is_err());
// Double-quoted keys may have a value without a space for JSON-compatibility.
assert_eq!(
run_parser(r#"["a":[]]"#).unwrap(),
[
Event::StreamStart,
Event::DocumentStart(false),
Event::SequenceStart(0, None),
Event::MappingStart(0, None),
Event::Scalar("a".to_string(), TScalarStyle::DoubleQuoted, 0, None),
Event::SequenceStart(0, None),
Event::SequenceEnd,
Event::MappingEnd,
Event::SequenceEnd,
Event::DocumentEnd,
Event::StreamEnd,
]
);
}
#[test]
fn test_pr12() {
assert_eq!(
run_parser("---\n- |\n a").unwrap(),
[
Event::StreamStart,
Event::DocumentStart(true),
Event::SequenceStart(0, None),
Event::Scalar("a\n".to_string(), TScalarStyle::Literal, 0, None),
Event::SequenceEnd,
Event::DocumentEnd,
Event::StreamEnd,
]
);
}
#[test]
fn test_issue14() {
// The following input creates an infinite loop.
// https://github.com/saphyr-rs/saphyr/issues/14
let s = "{---";
let Err(error) = run_parser(s) else { panic!() };
assert_eq!(
error.info(),
"while parsing a flow mapping, did not find expected ',' or '}'"
);
assert_eq!(
error.to_string(),
"while parsing a flow mapping, did not find expected ',' or '}' at byte 4 line 2 column 1"
);
}
#[test]
fn test_issue14_v2() {
let s = "{...";
let Err(error) = run_parser(s) else { panic!() };
assert_eq!(error.info(), "unexpected end of plain scalar");
assert_eq!(
error.to_string(),
"unexpected end of plain scalar at byte 1 line 1 column 2"
);
}
#[test]
fn test_issue13() {
// The following input creates an infinite loop.
// https://github.com/saphyr-rs/saphyr/issues/13
let s = r"---
array:
- object:
array:
- object:
array:
- text: >-
Line 1
Line 2
...";
assert_eq!(
run_parser(s).unwrap(),
[
Event::StreamStart,
Event::DocumentStart(true),
Event::MappingStart(0, None),
Event::Scalar("array".to_string(), TScalarStyle::Plain, 0, None),
Event::SequenceStart(0, None),
Event::MappingStart(0, None),
Event::Scalar("object".to_string(), TScalarStyle::Plain, 0, None),
Event::MappingStart(0, None),
Event::Scalar("array".to_string(), TScalarStyle::Plain, 0, None),
Event::SequenceStart(0, None),
Event::MappingStart(0, None),
Event::Scalar("object".to_string(), TScalarStyle::Plain, 0, None),
Event::MappingStart(0, None),
Event::Scalar("array".to_string(), TScalarStyle::Plain, 0, None),
Event::SequenceStart(0, None),
Event::MappingStart(0, None),
Event::Scalar("text".to_string(), TScalarStyle::Plain, 0, None),
Event::Scalar("Line 1 Line 2".to_string(), TScalarStyle::Folded, 0, None),
Event::MappingEnd,
Event::SequenceEnd,
Event::MappingEnd,
Event::MappingEnd,
Event::SequenceEnd,
Event::MappingEnd,
Event::MappingEnd,
Event::SequenceEnd,
Event::MappingEnd,
Event::DocumentEnd,
Event::StreamEnd
]
);
}