summaryrefslogtreecommitdiffstats
path: root/third_party/rust/litrs/src/test_util.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/litrs/src/test_util.rs')
-rw-r--r--third_party/rust/litrs/src/test_util.rs128
1 files changed, 128 insertions, 0 deletions
diff --git a/third_party/rust/litrs/src/test_util.rs b/third_party/rust/litrs/src/test_util.rs
new file mode 100644
index 0000000000..fd284e984e
--- /dev/null
+++ b/third_party/rust/litrs/src/test_util.rs
@@ -0,0 +1,128 @@
+use crate::*;
+use std::fmt::{Debug, Display};
+
+
+#[track_caller]
+pub(crate) fn assert_parse_ok_eq<T: PartialEq + Debug + Display>(
+ input: &str,
+ result: Result<T, ParseError>,
+ expected: T,
+ parse_method: &str,
+) {
+ match result {
+ Ok(actual) if actual == expected => {
+ if actual.to_string() != input {
+ panic!(
+ "formatting does not yield original input `{}`: {:?}",
+ input,
+ actual,
+ );
+ }
+ }
+ Ok(actual) => {
+ panic!(
+ "unexpected parsing result (with `{}`) for `{}`:\nactual: {:?}\nexpected: {:?}",
+ parse_method,
+ input,
+ actual,
+ expected,
+ );
+ }
+ Err(e) => {
+ panic!(
+ "expected `{}` to be parsed (with `{}`) successfully, but it failed: {:?}",
+ input,
+ parse_method,
+ e,
+ );
+ }
+ }
+}
+
+// This is not ideal, but to perform this check we need `proc-macro2`. So we
+// just don't do anything if that feature is not enabled.
+#[cfg(not(feature = "proc-macro2"))]
+pub(crate) fn assert_roundtrip<T>(_: T, _: &str) {}
+
+#[cfg(feature = "proc-macro2")]
+#[track_caller]
+pub(crate) fn assert_roundtrip<T>(ours: T, input: &str)
+where
+ T: std::convert::TryFrom<proc_macro2::Literal> + fmt::Debug + PartialEq + Clone,
+ proc_macro2::Literal: From<T>,
+ <T as std::convert::TryFrom<proc_macro2::Literal>>::Error: std::fmt::Display,
+{
+ let pm_lit = input.parse::<proc_macro2::Literal>()
+ .expect("failed to parse input as proc_macro2::Literal");
+ let t_name = std::any::type_name::<T>();
+
+ // Unfortunately, `proc_macro2::Literal` does not implement `PartialEq`, so
+ // this is the next best thing.
+ if proc_macro2::Literal::from(ours.clone()).to_string() != pm_lit.to_string() {
+ panic!(
+ "Converting {} to proc_macro2::Literal has unexpected result:\
+ \nconverted: {:?}\nexpected: {:?}",
+ t_name,
+ proc_macro2::Literal::from(ours),
+ pm_lit,
+ );
+ }
+
+ match T::try_from(pm_lit) {
+ Err(e) => {
+ panic!("Trying to convert proc_macro2::Literal to {} results in error: {}", t_name, e);
+ }
+ Ok(res) => {
+ if res != ours {
+ panic!(
+ "Converting proc_macro2::Literal to {} has unexpected result:\
+ \nactual: {:?}\nexpected: {:?}",
+ t_name,
+ res,
+ ours,
+ );
+ }
+ }
+ }
+}
+
+macro_rules! assert_err {
+ ($ty:ident, $input:literal, $kind:ident, $( $span:tt )+ ) => {
+ assert_err_single!($ty::parse($input), $kind, $($span)+);
+ assert_err_single!($crate::Literal::parse($input), $kind, $($span)+);
+ };
+}
+
+macro_rules! assert_err_single {
+ ($expr:expr, $kind:ident, $( $span:tt )+ ) => {
+ let res = $expr;
+ let err = match res {
+ Err(e) => e,
+ Ok(v) => panic!(
+ "Expected `{}` to return an error, but it returned Ok({:?})",
+ stringify!($expr),
+ v,
+ ),
+ };
+ if err.kind != $crate::err::ParseErrorKind::$kind {
+ panic!(
+ "Expected error kind {} for `{}` but got {:?}",
+ stringify!($kind),
+ stringify!($expr),
+ err.kind,
+ )
+ }
+ let expected_span = assert_err_single!(@span $($span)+);
+ if err.span != expected_span {
+ panic!(
+ "Expected error span {:?} for `{}` but got {:?}",
+ expected_span,
+ stringify!($expr),
+ err.span,
+ )
+ }
+ };
+ (@span $start:literal .. $end:literal) => { Some($start .. $end) };
+ (@span $at:literal) => { Some($at.. $at + 1) };
+ (@span None) => { None };
+}