#![allow(
clippy::unwrap_in_result,
reason = "unwraps are allowed anywhere in tests"
)]
#![allow(
clippy::indexing_slicing,
reason = "unwraps are allowed anywhere in tests"
)]
#![allow(clippy::panic_in_result_fn, reason = "tests are allowed to panic")]
use std::assert_matches;
use super::{Code, Warning};
use crate::{
json,
schema::{self, Integrity},
warning::test::VerdictTestExt as _,
FromSchema as _, Verdict,
};
impl Code {
pub fn from_alpha_3_str(code: &str) -> Self {
let bytes = code.as_bytes();
let [a, b, c] = bytes else {
panic!(
"Unable to parse currency code. Expected a length of 3 chars. It has length: `{}`",
code.len()
);
};
let triplet: [u8; 3] = [
a.to_ascii_uppercase(),
b.to_ascii_uppercase(),
c.to_ascii_uppercase(),
];
let Some(code) = Code::from_alpha_3(triplet) else {
panic!("Unknown currency code `{code}`");
};
code
}
}
#[test]
fn should_create_currency_without_issue() {
const CURRENCY: &str = r#""EUR""#;
let (code, warnings) = parse_code(CURRENCY).unwrap().into_parts();
assert_eq!(Code::Eur, code);
assert!(warnings.is_empty(), "{:#?}", warnings.path_id_map());
}
#[test]
fn should_raise_currency_content_issue() {
const CURRENCY: &str = r#""VVV""#;
let error = parse_code(CURRENCY).unwrap_only_error();
assert_matches!(error.into_warning(), Warning::InvalidCode);
}
#[test]
fn should_raise_currency_case_issue() {
const CURRENCY: &str = r#""eur""#;
let (code, warnings) = parse_code(CURRENCY).unwrap().into_parts();
let warnings = warnings.path_map();
let warnings = &*warnings["$.currency"];
assert_eq!(code, Code::Eur);
assert_matches!(warnings, [Warning::PreferUpperCase]);
}
#[test]
fn should_raise_currency_xts_issue() {
const CURRENCY: &str = r#""xts""#;
let (code, warnings) = parse_code(CURRENCY).unwrap().into_parts();
let warnings = warnings.path_map();
let warnings = &*warnings["$.currency"];
assert_eq!(code, Code::Xts);
assert_matches!(
warnings,
[Warning::PreferUpperCase, Warning::InvalidCodeXTS]
);
}
#[test]
fn should_raise_currency_xxx_issue() {
const CURRENCY: &str = r#""xxx""#;
let (code, warnings) = parse_code(CURRENCY).unwrap().into_parts();
let warnings = warnings.path_map();
let warnings = &*warnings["$.currency"];
assert_eq!(code, Code::Xxx);
assert_matches!(
warnings,
[Warning::PreferUpperCase, Warning::InvalidCodeXXX]
);
}
const TARIFF: &str = r#"{
"currency": {CURRENCY},
"elements": [
{"price_components": [{"price": 0.25, "step_size": 1, "type": "ENERGY"}]}
],
"id": "ID",
"last_updated": "2024-01-01T00:00:00Z"
}"#;
#[track_caller]
fn parse_code(currency: &str) -> Verdict<Code, Warning> {
let src = TARIFF.replace("{CURRENCY}", currency);
let doc = json::parse(src.as_str().into()).unwrap();
let tariff = schema::v211::build_tariff(&doc).ignore_warnings();
let Integrity::Ok(currency) = &tariff.currency else {
panic!("currency should be built: {:?}", tariff.currency);
};
Code::from_schema(currency)
}