use core::str::FromStr;
use beancount_types::AccountTemplate;
use miette::Diagnostic;
use snafu::Snafu;
#[derive(Clone, Debug)]
struct AnySelector(String);
impl FromStr for AnySelector {
type Err = NeverSelectorError;
fn from_str(value: &str) -> Result<Self, Self::Err> {
Ok(Self(value.into()))
}
}
#[derive(Debug, Diagnostic, Snafu)]
enum NeverSelectorError {}
#[derive(Clone, Copy, Debug)]
struct NoSelector();
impl FromStr for NoSelector {
type Err = SelectorError;
fn from_str(selector: &str) -> Result<Self, Self::Err> {
SelectorSnafu { selector }.fail()
}
}
#[derive(Debug, Diagnostic, Snafu)]
struct SelectorError {
selector: String,
}
#[test]
fn parsing_empty_template_fails() {
let template = AccountTemplate::<AnySelector>::parse("").unwrap_err();
insta::assert_debug_snapshot!(template);
}
#[test]
fn parsing_only_base_account_works() {
let template = AccountTemplate::<AnySelector>::parse("Assets:Banking").unwrap();
insta::assert_debug_snapshot!(template);
}
#[test]
fn parsing_base_account_and_trailing_selector_works() {
let template = AccountTemplate::<AnySelector>::parse("Assets:Banking:{institution}").unwrap();
insta::assert_debug_snapshot!(template);
}
#[test]
fn parsing_base_account_and_multiple_trailing_selectors_works() {
let template =
AccountTemplate::<AnySelector>::parse("Assets:Banking:{institution}:{account}:{position}")
.unwrap();
insta::assert_debug_snapshot!(template);
}
#[test]
fn parsing_base_account_and_mixed_trailing_selectors_and_literals_works() {
let template = AccountTemplate::<AnySelector>::parse(
"Assets:Banking:{institution}:{account}:Stocks:{position}",
)
.unwrap();
insta::assert_debug_snapshot!(template);
}
#[test]
fn parsing_fails_for_invalid_literals() {
let template = AccountTemplate::<AnySelector>::parse(
"Assets:Banking:{institution}:Main Account:stocks:{position}",
)
.unwrap_err();
insta::assert_debug_snapshot!(template);
}
#[test]
fn parsing_fails_for_invalid_selectors() {
let template = AccountTemplate::<NoSelector>::parse(
"Assets:Banking:{institution}:{account}:Stocks:{position}",
)
.unwrap_err();
insta::assert_debug_snapshot!(template);
}
#[test]
fn parsing_fails_for_invalid_base_account() {
let template =
AccountTemplate::<AnySelector>::parse("Assets:Banking:Bank of America:{account}")
.unwrap_err();
insta::assert_debug_snapshot!(template);
}
#[test]
fn multiple_parsing_errors_are_reported_in_bulk() {
let template =
AccountTemplate::<AnySelector>::parse("Assets:Banking:Bank of America:{account}:cash:{po")
.unwrap_err();
insta::assert_debug_snapshot!(template);
}