#![expect(clippy::tests_outside_test_module, reason = "tests directory")]
mod errors {
use assert2::{check, let_assert};
use token_string::{Builder, MAX_LENGTH, TkStrError, TokenString};
#[test]
fn too_many() {
let_assert!(Ok(s1) = TokenString::try_from("Hello"));
let_assert!(Ok(s2) = TokenString::try_from(", "));
let_assert!(Ok(s3) = TokenString::try_from("world"));
let_assert!(Ok(s4) = TokenString::try_from("!"));
let mut builder = Builder::<'_, 3>::new(&s1);
let_assert!(Ok(_) = builder.concat_checked(&s2));
let_assert!(Ok(_) = builder.concat_checked(&s3));
let_assert!(Err(e) = builder.concat_checked(&s4));
check!(e == TkStrError::TooMany(3));
}
#[test]
fn too_big() {
let_assert!(Ok(s1) = TokenString::try_from("Hello"));
let_assert!(Ok(s2) = TokenString::try_from(", "));
let_assert!(Ok(s3) = TokenString::try_from("world"));
let big = vec![b'1'; MAX_LENGTH].into_boxed_slice();
let_assert!(Ok(s4) = TokenString::try_from(&*big));
let mut builder = Builder::<'_, 4>::new(&s1);
let_assert!(Ok(_) = builder.concat_checked(&s2));
let_assert!(Ok(_) = builder.concat_checked(&s3));
let_assert!(Err(e) = builder.concat_checked(&s4));
check!(e == TkStrError::TooBig(65547));
}
#[test]
fn too_many_panic() {
let_assert!(Ok(s1) = TokenString::try_from("Hello"));
let_assert!(Ok(s2) = TokenString::try_from(", "));
let_assert!(Ok(s3) = TokenString::try_from("world"));
let_assert!(Ok(s4) = TokenString::try_from("!"));
let_assert!(
Err(panics) = std::panic::catch_unwind(|| {
let mut builder = Builder::<'_, 3>::new(&s1);
let_assert!(Ok(_) = builder.concat_checked(&s2));
let_assert!(Ok(_) = builder.concat_checked(&s3));
let _c = builder.concat_unchecked(&s4);
})
);
let_assert!(Some(msg) = panics.downcast_ref::<&str>());
check!(
msg == &"more strings concatenated than reserved space in Builder"
);
}
#[test]
fn not_zero_panic() {
let_assert!(Ok(s1) = TokenString::try_from("Hello"));
let_assert!(
Err(panics) = std::panic::catch_unwind(|| {
let mut _builder = Builder::<'_, 0>::new(&s1);
})
);
let_assert!(Some(msg) = panics.downcast_ref::<&str>());
check!(msg == &"the number of elements must not be 0");
}
}
mod func {
use assert2::{check, let_assert};
use token_string::{Builder, Collect as _, Concat as _, TokenString};
#[test]
fn concat_collect() {
let_assert!(Ok(s1) = TokenString::try_from("Hello"));
let_assert!(Ok(s2) = TokenString::try_from(", "));
let_assert!(Ok(s3) = TokenString::try_from("world"));
let_assert!(Ok(s4) = TokenString::try_from("!"));
let mut builder = Builder::<'_, 4>::new(&s1);
let builder_2 = builder.concat(&s2).concat(&s3).concat(&s4);
let_assert!(Ok(res) = builder_2.collect());
check!(&res == "Hello, world!");
}
#[test]
fn collect_unchecked_concat() {
let_assert!(Ok(s1) = TokenString::try_from("Hello"));
let_assert!(Ok(s2) = TokenString::try_from(", "));
let_assert!(Ok(s3) = TokenString::try_from("world"));
let_assert!(Ok(s4) = TokenString::try_from("!"));
let mut builder = Builder::<'_, 4>::new(&s1);
let builder_2 = builder
.concat_unchecked(&s2)
.concat_unchecked(&s3)
.concat_unchecked(&s4);
let_assert!(Ok(res) = builder_2.collect());
check!(&res == "Hello, world!");
}
#[test]
fn to_string() {
let_assert!(Ok(s1) = TokenString::try_from("Hello"));
let_assert!(Ok(s2) = TokenString::try_from(", "));
let_assert!(Ok(s3) = TokenString::try_from("world"));
let_assert!(Ok(s4) = TokenString::try_from("!"));
let mut builder = Builder::<'_, 4>::new(&s1);
let_assert!(
Ok(builder_2) = builder.concat(&s2).concat(&s3).concat(&s4)
);
check!(
builder_2.to_string()
== "Builder < 'Hello' + ', ' + 'world' + '!' >"
);
}
}
mod properties {
use assert2::let_assert;
use proptest::prelude::*;
use token_string::{Builder, TokenString};
fn vec_of_string(len: usize) -> impl Strategy<Value = Vec<String>> {
prop::collection::vec(".*", 1 .. len).prop_flat_map(Just)
}
proptest! {
#[test]
fn concat_2(a in ".*", b in ".*") {
let_assert!(Ok(s1) = TokenString::try_from(&a));
let_assert!(Ok(s2) = TokenString::try_from(&b));
let mut builder = Builder::<'_, 2>::new(&s1);
let_assert!(Ok(c) = builder.concat_checked(&s2));
let_assert!(Ok(res) = c.collect_checked());
let mut exp = a;
exp.push_str(&b);
prop_assert!(res == exp);
}
#[test]
#[cfg_attr(miri, ignore)] fn concat_many(v in vec_of_string(100)) {
let strings: Vec<TokenString> = v.iter()
.map(|s| {TokenString::from_str_unchecked(s)}).collect();
let mut builder = Builder::<'_, 100>::new(&strings[0]);
let mut exp = strings[0].as_string();
for s in strings.iter().skip(1) {
let_assert!(Ok(_c) = builder.concat_checked(s));
exp.push_str(s.as_str());
}
let_assert!(Ok(res) = builder.collect_checked());
prop_assert!(res == exp);
}
}
}