css_parse/
test_helpers.rs1#[macro_export]
28macro_rules! assert_parse {
29 ($atomset: path, $ty: ty, $str: literal, $($ast: pat)+) => {
30 let source_text = $str;
31 let bump = ::bumpalo::Bump::default();
32 let lexer = css_lexer::Lexer::new(&$atomset, &source_text);
33 let mut parser = $crate::Parser::new(&bump, &source_text, lexer);
34 let result = parser.parse_entirely::<$ty>().with_trivia();
35 if !result.errors.is_empty() {
36 panic!("\n\nParse failed. ({:?}) saw error {:?}", source_text, result.errors[0]);
37 }
38 let mut actual = ::bumpalo::collections::String::new_in(&bump);
39 {
40 let mut write_sink = $crate::CursorWriteSink::new(&source_text, &mut actual);
41 let mut ordered_sink = $crate::CursorOrderedSink::new(&bump, &mut write_sink);
42 use $crate::ToCursors;
43 result.to_cursors(&mut ordered_sink);
44 }
45 if source_text.trim() != actual.trim() {
46 panic!("\n\nParse failed: did not match expected format:\n\n parser input: {:?}\n parser output: {:?}\n", source_text, actual);
47 }
48 #[allow(clippy::redundant_pattern_matching)] if !matches!(result.output, Some($($ast)|+)) {
50 panic!(
51 "\n\nParse succeeded but struct did not match given match pattern:\n\n input: {:?}\n match pattern: {}\n parsed struct: {:#?}\n",
52 source_text,
53 stringify!($($ast)|+),
54 result.output.unwrap(),
55 );
56 }
57 };
58 ($atomset: path, $ty: ty, $str: literal) => {
59 assert_parse!($atomset, $ty, $str, _);
60 };
61}
62#[cfg(test)]
63pub(crate) use assert_parse;
64
65#[macro_export]
77macro_rules! assert_parse_error {
78 ($atomset: path, $ty: ty, $str: literal) => {
79 let source_text = $str;
80 let bump = ::bumpalo::Bump::default();
81 let lexer = css_lexer::Lexer::new(&$atomset, source_text);
82 let mut parser = $crate::Parser::new(&bump, source_text, lexer);
83 let result = parser.parse::<$ty>();
84 if parser.at_end() {
85 if let Ok(result) = result {
86 let mut actual = ::bumpalo::collections::String::new_in(&bump);
87 {
88 let mut write_sink = $crate::CursorWriteSink::new(&source_text, &mut actual);
89 let mut ordered_sink = $crate::CursorOrderedSink::new(&bump, &mut write_sink);
90 use $crate::ToCursors;
91 result.to_cursors(&mut ordered_sink);
92 }
93 panic!("\n\nExpected errors but it passed without error.\n\n parser input: {:?}\n parser output: {:?}\n expected: (Error)", source_text, actual);
94 }
95 }
96 };
97}
98#[cfg(test)]
99pub(crate) use assert_parse_error;
100
101#[macro_export]
115macro_rules! assert_parse_span {
116 ($atomset: path, $ty: ty, $str: literal) => {
117 let expected = $str;
118 let source_text = expected.lines().find(|line| !line.trim().is_empty()).unwrap_or("");
119 let bump = ::bumpalo::Bump::default();
120 let lexer = css_lexer::Lexer::new(&$atomset, source_text);
121 let mut parser = $crate::Parser::new(&bump, source_text, lexer);
122 let result = parser.parse::<$ty>();
123 match result {
124 Ok(result) => {
125 use $crate::ToSpan;
126 let span = result.to_span();
127 let indent = &source_text[0..span.start().into()];
128 if indent.trim().len() > 0 {
129 panic!(
130 "\n\nParse on {}:{} succeeded but has non-whitespace leading text: {}\n",
131 file!(),
132 line!(),
133 indent
134 );
135 }
136 let actual = format!("\n{}{}\n{}{}\n", indent, source_text, indent, "^".repeat(span.len() as usize));
137 if expected.trim() != actual.trim() {
138 panic!(
139 "\n\nParse on {}:{} succeeded but span ({}) differs:\n\n expected: {}\n actual: {}\n",
140 file!(),
141 line!(),
142 span,
143 expected,
144 actual,
145 );
146 }
147 }
148 Err(err) => {
149 panic!("\n\nParse on {}:{} failed. ({:?}) saw error {:?}", file!(), line!(), source_text, err);
150 }
151 }
152 };
153}
154#[cfg(test)]
155pub(crate) use assert_parse_span;