#![allow(
    clippy::indexing_slicing,
    reason = "unwraps are allowed anywhere in tests"
)]

use std::assert_matches;

use super::Weekday;
use crate::{
    enumeration::WarningKind,
    json::{self, FromJson as _},
    test,
    warning::test::VerdictTestExt as _,
};

#[test]
fn should_create_from_json() {
    const JSON: &str = r#""MONDAY""#;

    test::setup();

    let doc = json::parse(JSON.into()).unwrap();
    let day = Weekday::from_json(doc.root()).unwrap().unwrap();
    assert_matches!(day, Weekday::Monday);
}

#[test]
fn should_fail_on_type_from_json() {
    const JSON: &str = "[]";

    test::setup();

    let doc = json::parse(JSON.into()).unwrap();
    let error = Weekday::from_json(doc.root()).unwrap_only_error();
    let warning = error.into_warning();
    assert_matches!(warning.kind(), WarningKind::InvalidType { .. });
    assert_matches!(warning.type_name(), "Weekday");
}

#[test]
fn should_fail_on_value_from_json() {
    const JSON: &str = r#""MOONDAY""#;

    test::setup();

    let doc = json::parse(JSON.into()).unwrap();
    let error = Weekday::from_json(doc.root()).unwrap_only_error();
    let warning = error.into_warning();
    assert_matches!(warning.kind(), WarningKind::InvalidVariant);
    assert_matches!(warning.type_name(), "Weekday");
}
#[test]
fn should_warn_about_case_from_json() {
    const JSON: &str = r#""sunday""#;

    test::setup();

    let doc = json::parse(JSON.into()).unwrap();
    let (day, warnings) = Weekday::from_json(doc.root()).unwrap().into_parts();
    let warnings = warnings.into_path_as_str_map();
    let warnings = &*warnings["$"];

    assert_matches!(day, Weekday::Sunday);
    let [warning] = &warnings else {
        panic!("Expected one warning.");
    };
    assert_matches!(warning.kind(), WarningKind::PreferUpperCase);
    assert_matches!(warning.type_name(), "Weekday");
}
