use std::assert_matches;

use crate::json;

use super::ReasonableLen;

#[test]
fn should_allow_reasonable_cdr_str() {
    const JSON: &str = include_str!("../cdr.json");

    let _cdr = json::parse_object(JSON).expect("Unable to parse CDR JSON");
}

#[test]
fn should_forbid_unreasonable_cdr_str() {
    let json = unreasonable_string();

    let error = json::parse_object(&json)
        .expect_err("The `String` is so large it should fail the `ReasonableStr` checks");
    assert_matches!(error, json::ParseError::SizeExceedsMax);
}

#[test]
fn should_allow_reasonable_tariff_str() {
    const JSON: &str = include_str!("../tariff.json");

    let _tariff = json::parse_object(JSON).expect("Unable to parse tariff JSON");
}

#[test]
fn should_forbid_unreasonable_tariff_str() {
    let json = unreasonable_string();
    // Create a 2 megabytes `String` from a 32 bit fragment `str`.
    let error = json::parse_object(&json)
        .expect_err("The `String` is so large it should fail the `ReasonableStr` checks");
    assert_matches!(error, json::ParseError::SizeExceedsMax);
}

fn unreasonable_string() -> String {
    const TOKEN: &str = "This is an unreasonable size for an input str.";
    const FACTOR: usize = ReasonableLen::MAX_STR_INPUT_LEN / TOKEN.len();

    let s = str::repeat(TOKEN, FACTOR + 1);

    assert!(
        s.len() >= ReasonableLen::MAX_STR_INPUT_LEN,
        "The test `String` len `{}` should be greater than or equal to the `ReasonableStr` max `{}`",
        s.len(),
        ReasonableLen::MAX_STR_INPUT_LEN
    );

    s
}
