#![allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)]
use jcs_admit::{Error, Options, DEFAULT_MAX_DEPTH, MAX_SUPPORTED_DEPTH};
const SMALL_STACK: usize = 1 << 20;
fn nest(depth: usize) -> Vec<u8> {
let mut v = vec![b'['; depth];
v.resize(depth * 2, b']');
v
}
fn on_a_small_stack<T: Send + 'static>(f: impl FnOnce() -> T + Send + 'static) -> T {
std::thread::Builder::new()
.stack_size(SMALL_STACK)
.spawn(f)
.expect("spawn")
.join()
.expect("the worker must return a value, not die")
}
#[test]
fn a_document_nested_to_the_ceiling_is_canonicalized_on_a_small_stack() {
let doc = nest(MAX_SUPPORTED_DEPTH);
let opts = Options::rfc8785().max_depth(MAX_SUPPORTED_DEPTH);
let got = on_a_small_stack(move || jcs_admit::admit_with(&doc, &opts).map(|b| b.len()));
assert_eq!(
got,
Ok(MAX_SUPPORTED_DEPTH * 2),
"the ceiling must be usable in {SMALL_STACK} bytes of stack"
);
}
#[test]
fn an_uncapped_request_is_refused_on_a_small_stack_rather_than_aborting() {
let doc = nest(200_000);
let opts = Options::rfc8785().max_depth(usize::MAX).max_bytes(None);
let got = on_a_small_stack(move || jcs_admit::admit_with(&doc, &opts));
assert!(
matches!(got, Err(Error::TooDeep { .. })),
"must refuse, got {:?}",
got.map(|b| b.len())
);
}
const _: () = assert!(
DEFAULT_MAX_DEPTH == 128,
"the default cap is normative in an upstream specification proposal"
);
const _: () = assert!(
DEFAULT_MAX_DEPTH < MAX_SUPPORTED_DEPTH,
"the default must leave room to be raised"
);