move and turn into spans

This commit is contained in:
Jana Dönszelmann 2026-04-01 14:01:08 +02:00
parent bedaa49754
commit 9f401bda53
No known key found for this signature in database
13 changed files with 1262 additions and 774 deletions

View file

@ -0,0 +1,190 @@
use super::ast::*;
use crate::format_debug_output::{Config, into_spans};
use crate::format_debug_output::{ast::*, parse_input};
use proptest::prelude::*;
use proptest::proptest;
proptest! {
#[test]
fn proptest_from_segments(original in Segments::arb(Token::arb())) {
let stringified = original.to_string();
let parsed = parse_input(&stringified).unwrap();
let stringified_again = parsed.to_string();
assert_eq!(stringified, stringified_again, "parsed: `{parsed:#?}`");
}
#[test]
fn proptest_from_random_text(original in ".*") {
let parsed = parse_input(&original).unwrap();
let stringified_again = parsed.to_string();
assert_eq!(original, stringified_again, "parsed: `{parsed:#?}`");
}
#[test]
fn proptest_into_spans(original in Segments::arb(Token::arb())) {
let stringified = original.to_string();
let spans = into_spans(original, Config {collapse_space: false});
let spans_concatenated = spans.into_iter().map(|i| i.text).collect::<String>();
assert_eq!(stringified, spans_concatenated);
}
}
impl AnyString<'static> {
#[cfg(test)]
fn arb() -> impl Strategy<Value = Self> {
let prefix = "\\w*";
let ty = any::<QuoteType>();
let contents = "\\w*";
let num_hashtags = 0usize..3;
let suffix = "\\w*";
(prefix, ty, contents, num_hashtags, suffix).prop_map(
|(prefix, ty, contents, num_hashtags, suffix)| Self {
prefix: prefix.into(),
ty,
contents: contents.into(),
num_hashtags,
suffix: suffix.into(),
},
)
}
}
impl PathSegment<'static> {
#[cfg(test)]
fn arb() -> impl Strategy<Value = Self> {
(any::<PathSep>(), "\\w*").prop_map(|(leading_separator, segment)| Self {
leading_separator,
segment: segment.into(),
})
}
}
impl FileLocation<'static> {
#[cfg(test)]
fn arb() -> impl Strategy<Value = Self> {
use proptest::option::*;
("[0-9]{0,4}", of("[0-9]{0,4}")).prop_map(|(line, offset)| Self {
line: line.into(),
offset: offset.map(Into::into),
})
}
}
impl Space<'static> {
#[cfg(test)]
fn arb() -> impl Strategy<Value = Self> {
" *".prop_map(|spaces| Self(spaces.into()))
}
}
impl FileName<'static> {
#[cfg(test)]
fn arb() -> impl Strategy<Value = Self> {
use proptest::option::*;
(
any::<PathSep>(),
"\\w*",
of(".{0,3}"),
of(FileLocation::arb()),
)
.prop_map(
|(leading_separator, segment, ext_excluding_dot, location)| Self {
leading_separator,
segment: segment.into(),
ext_excluding_dot: ext_excluding_dot.map(Into::into),
location,
},
)
}
}
impl Path<'static> {
#[cfg(test)]
fn arb() -> impl Strategy<Value = Self> {
use proptest::{char::*, collection::*, option::*};
(
of(range('A', 'Z')),
vec(PathSegment::arb(), 0..3),
FileName::arb(),
)
.prop_map(|(drive_excluding_colon, segments, filename)| Self {
drive_excluding_colon,
segments,
filename,
})
}
}
impl Number<'static> {
#[cfg(test)]
fn arb() -> impl Strategy<Value = Self> {
prop_oneof![
any::<i64>().prop_map(|number| Self(number.to_string().into())),
any::<f64>().prop_map(|number| Self(number.to_string().into()))
]
}
}
impl Atom<'static> {
#[cfg(test)]
fn arb() -> impl Strategy<Value = Self> {
"[a-zA-Z]+".prop_map(|i| Self::Text(i.into()))
}
}
impl Token<'static> {
#[cfg(test)]
fn arb() -> impl Strategy<Value = Self> {
let leaf = prop_oneof![
Just(Self::True),
Just(Self::False),
Just(Self::None),
Path::arb().prop_map(Self::Path),
AnyString::arb().prop_map(Self::String),
Number::arb().prop_map(Self::Number),
Atom::arb().prop_map(Self::Atom),
];
leaf.prop_recursive(4, 64, 16, |token| {
Delimited::arb(token).prop_map(Self::Delimited).boxed()
})
}
}
impl Delimited<'static> {
#[cfg(test)]
fn arb(token: impl Strategy<Value = Token<'static>>) -> impl Strategy<Value = Self> {
(Atom::arb(), any::<Delimiter>(), Segments::arb(token)).prop_map(
|(prefix, delimiter, contents)| Self {
prefix,
delimiter,
contents,
},
)
}
}
impl Segment<'static> {
#[cfg(test)]
fn arb(token: impl Strategy<Value = Token<'static>>) -> impl Strategy<Value = Self> {
(Space::arb(), token).prop_map(|(leading_space, token)| Self {
leading_space,
token,
})
}
}
impl Segments<'static> {
#[cfg(test)]
fn arb(token: impl Strategy<Value = Token<'static>>) -> impl Strategy<Value = Self> {
use proptest::collection::*;
(vec(Segment::arb(token), 1..10), Space::arb()).prop_map(|(segments, trailing_space)| {
Self {
segments,
trailing_space,
}
})
}
}