saphyr-serde/parser/tests/basic.rs

366 lines
8.6 KiB
Rust
Raw Normal View History

#![allow(clippy::bool_assert_comparison)]
#![allow(clippy::float_cmp)]
use saphyr_parser::{Event, Parser, ScanError, TScalarStyle};
/// Run the parser through the string.
///
/// # Returns
/// This functions returns the events if parsing succeeds, the error the parser returned otherwise.
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]
fn test_fail() {
let s = "
# syntax error
scalar
key: [1, 2]]
key1:a2
";
let Err(error) = run_parser(s) else { panic!() };
assert_eq!(
error.info(),
"mapping values are not allowed in this context"
);
assert_eq!(
error.to_string(),
2021-08-18 02:07:07 +00:00
"mapping values are not allowed in this context at byte 26 line 4 column 4"
);
}
#[test]
fn test_empty_doc() {
assert_eq!(
run_parser("").unwrap(),
[Event::StreamStart, Event::StreamEnd]
);
assert_eq!(
run_parser("---").unwrap(),
[
Event::StreamStart,
Event::DocumentStart(true),
Event::Scalar("~".to_string(), TScalarStyle::Plain, 0, None),
Event::DocumentEnd,
Event::StreamEnd,
]
);
}
#[test]
fn test_utf() {
assert_eq!(
run_parser("a: 你好").unwrap(),
[
Event::StreamStart,
Event::DocumentStart(false),
Event::MappingStart(0, None),
Event::Scalar("a".to_string(), TScalarStyle::Plain, 0, None),
Event::Scalar("你好".to_string(), TScalarStyle::Plain, 0, None),
Event::MappingEnd,
Event::DocumentEnd,
Event::StreamEnd,
]
);
}
#[test]
fn test_comments() {
let s = "
# This is a comment
a: b # This is another comment
##
#
";
assert_eq!(
run_parser(s).unwrap(),
[
Event::StreamStart,
Event::DocumentStart(false),
Event::MappingStart(0, None),
Event::Scalar("a".to_string(), TScalarStyle::Plain, 0, None),
Event::Scalar("b".to_string(), TScalarStyle::Plain, 0, None),
Event::MappingEnd,
Event::DocumentEnd,
Event::StreamEnd,
]
);
}
#[test]
fn test_quoting() {
let s = "
- plain
- 'squote'
- \"dquote\"
";
assert_eq!(
run_parser(s).unwrap(),
[
Event::StreamStart,
Event::DocumentStart(false),
Event::SequenceStart(0, None),
Event::Scalar("plain".to_string(), TScalarStyle::Plain, 0, None),
Event::Scalar("squote".to_string(), TScalarStyle::SingleQuoted, 0, None),
Event::Scalar("dquote".to_string(), TScalarStyle::DoubleQuoted, 0, None),
Event::SequenceEnd,
Event::DocumentEnd,
Event::StreamEnd,
]
);
}
#[test]
fn test_multi_doc() {
let s = "
a scalar
---
a scalar
---
a scalar
";
assert_eq!(
run_parser(s).unwrap(),
[
Event::StreamStart,
Event::DocumentStart(false),
Event::Scalar("a scalar".to_string(), TScalarStyle::Plain, 0, None),
Event::DocumentEnd,
Event::DocumentStart(true),
Event::Scalar("a scalar".to_string(), TScalarStyle::Plain, 0, None),
Event::DocumentEnd,
Event::DocumentStart(true),
Event::Scalar("a scalar".to_string(), TScalarStyle::Plain, 0, None),
Event::DocumentEnd,
Event::StreamEnd,
]
);
}
#[test]
fn test_github_27() {
// https://github.com/chyh1990/yaml-rust/issues/27
assert_eq!(
run_parser("&a").unwrap(),
[
Event::StreamStart,
Event::DocumentStart(false),
Event::Scalar(String::new(), TScalarStyle::Plain, 1, None),
Event::DocumentEnd,
Event::StreamEnd,
]
);
}
#[test]
fn test_bad_hyphen() {
// See: https://github.com/chyh1990/yaml-rust/issues/23
assert!(run_parser("{-").is_err());
}
#[test]
fn test_issue_65() {
// See: https://github.com/chyh1990/yaml-rust/issues/65
let b = "\n\"ll\\\"ll\\\r\n\"ll\\\"ll\\\r\r\r\rU\r\r\rU";
assert!(run_parser(b).is_err());
}
#[test]
fn test_issue_65_mwe() {
// A MWE for `test_issue_65`. The error over there is that there is invalid trailing content
// after a double quoted string.
let b = r#""foo" l"#;
assert!(run_parser(b).is_err());
}
2024-04-16 10:03:42 +00:00
#[test]
fn test_comment_after_tag() {
// https://github.com/Ethiraric/yaml-rust2/issues/21#issuecomment-2053513507
let s = "
%YAML 1.2
# This is a comment
--- #-------
foobar";
assert_eq!(
run_parser(s).unwrap(),
[
Event::StreamStart,
Event::DocumentStart(true),
2024-04-16 10:03:42 +00:00
Event::Scalar("foobar".to_string(), TScalarStyle::Plain, 0, None),
Event::DocumentEnd,
Event::StreamEnd,
]
);
}
#[test]
fn test_large_block_scalar_indent() {
// https://github.com/Ethiraric/yaml-rust2/issues/29
// https://github.com/saphyr-rs/saphyr-parser/issues/2
// Tests the `loop` fallback of `skip_block_scalar_indent`. The indent in the YAML string must
// be greater than `BUFFER_LEN - 2`. The second line is further indented with spaces, and the
// resulting string should be "a\n b".
let s = "
a: |-
a
b
";
assert_eq!(
run_parser(s).unwrap(),
[
Event::StreamStart,
Event::DocumentStart(false),
Event::MappingStart(0, None),
Event::Scalar("a".to_string(), TScalarStyle::Plain, 0, None),
Event::Scalar("a\n b".to_string(), TScalarStyle::Literal, 0, None),
Event::MappingEnd,
Event::DocumentEnd,
2024-04-16 10:03:42 +00:00
Event::StreamEnd,
]
);
}
#[test]
fn test_bad_docstart() {
run_parser("---This used to cause an infinite loop").unwrap();
assert_eq!(
run_parser("----").unwrap(),
[
Event::StreamStart,
Event::DocumentStart(false),
Event::Scalar("----".to_string(), TScalarStyle::Plain, 0, None),
Event::DocumentEnd,
Event::StreamEnd,
]
);
assert_eq!(
run_parser("--- #comment").unwrap(),
[
Event::StreamStart,
Event::DocumentStart(true),
Event::Scalar("~".to_string(), TScalarStyle::Plain, 0, None),
Event::DocumentEnd,
Event::StreamEnd,
]
);
assert_eq!(
run_parser("---- #comment").unwrap(),
[
Event::StreamStart,
Event::DocumentStart(false),
Event::Scalar("----".to_string(), TScalarStyle::Plain, 0, None),
Event::DocumentEnd,
Event::StreamEnd,
]
);
}
#[test]
fn test_indentation_equality() {
let four_spaces = run_parser(
2024-02-13 22:10:17 +00:00
r"
hash:
with:
indentations
2024-02-13 22:10:17 +00:00
",
)
.unwrap();
let two_spaces = run_parser(
2024-02-13 22:10:17 +00:00
r"
hash:
with:
indentations
2024-02-13 22:10:17 +00:00
",
)
.unwrap();
let one_space = run_parser(
2024-02-13 22:10:17 +00:00
r"
hash:
with:
indentations
2024-02-13 22:10:17 +00:00
",
)
.unwrap();
let mixed_spaces = run_parser(
2024-02-13 22:10:17 +00:00
r"
hash:
with:
indentations
2024-02-13 22:10:17 +00:00
",
)
.unwrap();
for (((a, b), c), d) in four_spaces
.iter()
.zip(two_spaces.iter())
.zip(one_space.iter())
.zip(mixed_spaces.iter())
{
assert!(a == b);
assert!(a == c);
assert!(a == d);
}
}
#[test]
fn test_recursion_depth_check_objects() {
let s = "{a:".repeat(10_000) + &"}".repeat(10_000);
assert!(run_parser(&s).is_err());
}
#[test]
fn test_recursion_depth_check_arrays() {
let s = "[".repeat(10_000) + &"]".repeat(10_000);
assert!(run_parser(&s).is_err());
}