#![cfg_attr(nightly, feature(error_generic_member_access))]

mod common;

use common::*;
use error_stack::{bail, ensure};

#[test]
fn bail() {
    let report = capture_error(|| bail!(RootError)).attach(PrintableA(0));
    assert!(report.contains::<RootError>());
    assert!(report.contains::<PrintableA>());
    assert!(!report.contains::<PrintableB>());
    assert_eq!(report.current_context(), &RootError);
    assert_eq!(report.frames().count(), expect_count(2));
    assert_eq!(
        remove_builtin_messages(messages(&report)),
        remove_builtin_messages(["printable A", "root error"])
    );

    let report = capture_error(|| bail!(report)).attach(PrintableB(0));
    assert!(report.contains::<RootError>());
    assert!(report.contains::<PrintableA>());
    assert!(report.contains::<PrintableB>());
    assert_eq!(report.current_context(), &RootError);
    assert_eq!(report.frames().count(), expect_count(3));
    assert_eq!(
        remove_builtin_messages(messages(&report)),
        remove_builtin_messages(["printable B", "printable A", "root error"])
    );
}

#[test]
fn ensure() {
    capture_ok(|| {
        ensure!(true, RootError);
        Ok(())
    });
    let report = capture_error(|| {
        ensure!(false, RootError);
        Ok(())
    })
    .attach(PrintableA(0));
    assert!(report.contains::<RootError>());
    assert!(report.contains::<PrintableA>());
    assert!(!report.contains::<PrintableB>());
    assert_eq!(report.current_context(), &RootError);
    assert_eq!(report.frames().count(), expect_count(2));
    assert_eq!(
        remove_builtin_messages(messages(&report)),
        remove_builtin_messages(["printable A", "root error"])
    );

    let report = capture_error(|| {
        ensure!(false, report);
        Ok(())
    })
    .attach(PrintableB(0));
    assert!(report.contains::<RootError>());
    assert!(report.contains::<PrintableA>());
    assert!(report.contains::<PrintableB>());
    assert_eq!(report.current_context(), &RootError);
    assert_eq!(report.frames().count(), expect_count(3));
    assert_eq!(
        remove_builtin_messages(messages(&report)),
        remove_builtin_messages(["printable B", "printable A", "root error"])
    );
}
