use edtf_core::{is_valid, level, Edtf, IntervalEndpoint, Precision, SetKind};
fn assert_level(s: &str, want: u8) {
assert_eq!(level(s), Some(want), "level of {s:?}");
}
fn assert_invalid(s: &str) {
assert!(!is_valid(s), "{s:?} should be invalid");
}
#[test]
fn level0_dates_and_datetimes() {
assert_level("1985-04-12", 0);
assert_level("1985-04", 0);
assert_level("1985", 0);
assert_level("0000", 0); assert_level("2000-02-29", 0); assert_level("1985-04-12T23:20:30", 0);
assert_level("1985-04-12T23:59:60Z", 0); assert_level("1985-04-12T23:20:30+14:00", 0);
}
#[test]
fn level1_features() {
assert_level("-1985", 1);
assert_level("-0001", 1); assert_level("Y170000002", 1);
assert_level("Y-170000002", 1);
assert_level("2001-21", 1);
assert_level("2001-24", 1);
assert_level("1985-04-12?", 1);
assert_level("1985-04?", 1);
assert_level("1985~", 1);
assert_level("1985%", 1);
assert_level("1985-04-XX", 1);
assert_level("1985-XX-XX", 1);
assert_level("2004-XX", 1);
assert_level("201X", 1);
assert_level("20XX", 1);
assert_level("1985-04-12/..", 1);
assert_level("../1985-04-12", 1);
assert_level("1986-04/", 1);
assert_level("/1985", 1);
assert_level("1984?/2004%", 1);
assert_level("../1985-04-12?", 1);
assert_level("1985-04-12~/", 1);
}
#[test]
fn level2_features() {
assert_level("Y-17E7", 2);
assert_level("Y3388E2S3", 2);
assert_level("1950S2", 2);
assert_level("Y171010000S3", 2);
assert_level("2001-34", 2); assert_level("2001-41", 2); assert_level("2004-06~-11", 2);
assert_level("2004?-06-11", 2);
assert_level("?2004-06-~11", 2);
assert_level("2004-%06-11", 2);
assert_level("2004-06?-~11", 2); assert_level("156X-12-25", 2);
assert_level("XXXX-12-XX", 2);
assert_level("1XXX-XX", 2);
assert_level("1560-X2", 2);
assert_level("XXXX", 2);
assert_level("2XXX", 2);
assert_level("1XX3", 2);
assert_level("{1960,1961-12}", 2);
assert_level("[1667,1760-12]", 2);
assert_level("[..1984]", 2);
assert_level("[1984..]", 2);
assert_level("[1670..1672]", 2);
assert_level("{..1983-12-31,1984-10-10..1984-11-01,1984-11-05..}", 2);
assert_level("2004-06-~01/2004-06-~20", 2);
assert_level("..2004-06-01/2004-06-20..", 2);
assert_level("2004-06-XX/2004-07-03", 2); }
#[test]
fn calendar_validation() {
assert_invalid("1985-02-30");
assert_invalid("1985-04-31");
assert_invalid("2001-02-29"); assert_invalid("1900-02-29"); assert!(is_valid("2000-02-29")); assert!(is_valid("1985-0X-31")); assert_invalid("1985-02-3X"); assert_invalid("X900-02-29"); assert!(is_valid("XXXX-02-29")); assert_invalid("1985-00");
assert_invalid("1985-13");
assert_invalid("2004-20"); assert_invalid("1985-04-00");
assert_invalid("1985-04-32");
assert_invalid("2001-21-05"); }
#[test]
fn reject_list_not_edtf() {
assert_invalid("19850412"); assert_invalid("1985-102"); assert_invalid("1985-W15"); assert_invalid("P1Y2M"); assert_invalid("R12/1985/1990"); assert_invalid("1985Y4M12D"); assert_invalid("198"); assert_invalid("19"); assert_invalid("2018-01-15/02-20"); assert_invalid("1985-4-12"); assert_invalid("1985-04-12T23:20"); assert_invalid("1985-04-12T24:00:00"); assert_invalid("1985-04-12T23:20:30+15:00"); assert_invalid("1985-04-12T23:20:30-00:00"); assert_invalid("1985-04-12T23:20:30-00");
assert_invalid("hello");
assert_invalid("");
assert_invalid("1985 -04"); assert_invalid("..1984"); }
#[test]
fn decisions() {
assert_invalid("Y1985"); assert_invalid("Y-1985");
assert_invalid("Y12E2"); assert_invalid("-0000"); assert_invalid("../.."); assert_invalid("/");
assert_invalid("../");
assert_invalid("/..");
assert_invalid("1950S0"); assert_invalid("1950S5");
assert!(is_valid("1950S4"));
assert_invalid("195XS2"); assert_invalid("-12345"); assert!(is_valid("-1985-04-12")); assert_level("-1985-04-12", 1);
assert_invalid("Y20000-04");
assert_invalid("Y08470847E1S9");
assert_invalid("Y-01694194E1S9");
assert_invalid("Y018470");
assert_invalid("Y012E3");
assert!(is_valid("Y8470847E1S8"));
assert_invalid("{}");
assert_invalid("{1960,}");
assert_invalid("{1960, 1961}"); assert_invalid("[..]");
assert_invalid("1985-04-12/1985-04-12T10:00:00"); }
#[test]
fn model_accessors() {
let d = match Edtf::parse("2004-06~-11").unwrap() {
Edtf::Date(d) => d,
other => panic!("expected date, got {other:?}"),
};
assert!(d.year.qualifier.approximate);
assert!(d.month.unwrap().qualifier.approximate);
assert!(!d.day.unwrap().qualifier.is_qualified());
assert_eq!(d.precision(), Precision::Day);
assert_eq!(d.year.value(), Some(2004));
let season = match Edtf::parse("2001-21").unwrap() {
Edtf::Date(d) => d,
other => panic!("expected date, got {other:?}"),
};
assert_eq!(season.precision(), Precision::Season);
let iv = match Edtf::parse("1985-04-12/..").unwrap() {
Edtf::Interval(iv) => iv,
other => panic!("expected interval, got {other:?}"),
};
assert!(matches!(iv.end, IntervalEndpoint::Open));
let set = match Edtf::parse("[1667,1760-12]").unwrap() {
Edtf::Set(s) => s,
other => panic!("expected set, got {other:?}"),
};
assert_eq!(set.kind, SetKind::OneMember);
assert_eq!(set.elements.len(), 2);
}
#[test]
fn error_offsets_point_at_the_problem() {
fn offset_of(s: &str) -> usize {
Edtf::parse(s).unwrap_err().offset
}
assert_eq!(offset_of("1985-13"), 5); assert_eq!(offset_of("1985-02-30"), 8); assert_eq!(offset_of("1985-04-12T25:00:00"), 11); assert_eq!(offset_of("1985-04-12T23:20:30+15:00"), 19); assert_eq!(offset_of("1985 -04"), 4); assert_eq!(offset_of("2004/2003"), 5); assert_eq!(offset_of("{1960,1985-00}"), 11); assert_eq!(offset_of("../1985-13"), 8); }